From 99e771a223dfcff09fa35269b6a6effb8d1fc87e Mon Sep 17 00:00:00 2001 From: Andrea Rigoni Date: Mon, 3 Nov 2014 10:27:52 +0000 Subject: [PATCH] [uLib Geometry] non working version! + adds ProgrammableAccessor + renaming of some Image structures ... --- AUTHORS | 8 + CMake/FindEigen3.cmake | 81 + CMake/FindGEANT4.cmake | 63 + CMake/FindGEANT4VMC.cmake | 97 + CMake/FindROOT.cmake | 279 + CMake/FindROOTv6.cmake | 164 + CMake/FindReadLine.cmake | 23 + CMake/FindVTK.cmake | 141 + CMake/FinduLib.cmake | 62 + CMake/clean-all.cmake | 11 + CMake/rmake.in | 47 + CMake/uLibCommon.cmake | 64 + CMake/uLibConfigHeader.cmake | 57 + CMake/uLibDebugMacro.cmake | 54 + CMake/uLibFindDependencies.cmake | 122 + CMake/uLibGenerateRMake.cmake | 47 + CMake/uLibMacros.cmake | 12 + CMake/uLibTargetMacros.cmake | 186 + CMakeConfig.in.h | 128 + CMakeLists.txt | 234 + CMakePkgConfig.pc.in | 13 + ChangeLog | 0 Common.am | 54 + Makefile.am | 52 + NEWS | 0 README | 2 + SCRATCH.org | 14 + bootstrap | 21 + configure.ac | 210 + libmutom-0.2.pc.in | 11 + m4/boost.m4 | 1186 +++++ m4/geant4.bkp | 361 ++ m4/geant4.m4 | 64 + m4/openmp.m4 | 98 + m4/root.m4 | 125 + m4/vtk.m4 | 166 + m4/zeromq.m4 | 90 + src/Core/Archives.cpp | 92 + src/Core/Archives.h | 784 +++ src/Core/Array.h | 72 + src/Core/CMakeLists.txt | 46 + src/Core/Collection.h | 101 + src/Core/CommaInitializer.h | 89 + src/Core/Debug.cpp | 31 + src/Core/Debug.h | 148 + src/Core/DebugArchives.cpp | 52 + src/Core/DebugArchives.h | 289 + src/Core/Export.h | 117 + src/Core/Flags.h | 54 + src/Core/Function.h | 160 + src/Core/Macros.h | 173 + src/Core/Makefile.am | 41 + src/Core/Mpl.h | 139 + src/Core/Object.cpp | 227 + src/Core/Object.h | 222 + src/Core/ObjectProps.h | 278 + src/Core/Options.cpp | 87 + src/Core/Options.h | 179 + src/Core/ProgrammableAccessor.h | 140 + src/Core/Serializable.cpp | 95 + src/Core/Serializable.h | 412 ++ src/Core/Signal.cpp | 28 + src/Core/Signal.h | 168 + src/Core/Singleton.h | 46 + src/Core/SmartPointer.h | 114 + src/Core/StaticInterface.h | 77 + src/Core/String.h | 21 + src/Core/StringReader.h | 94 + src/Core/Types.h | 278 + src/Core/Uuid.cpp | 45 + src/Core/Uuid.h | 163 + src/Core/Vector.h | 195 + src/Core/testing/BoostAccumulatorTest.cpp | 88 + src/Core/testing/BoostTest.cpp | 64 + src/Core/testing/CMakeLists.txt | 34 + src/Core/testing/CommaInitTest.cpp | 57 + src/Core/testing/DebugTTreeDumpTest.cpp | 118 + src/Core/testing/DreadDiamondParameters.cpp | 80 + src/Core/testing/Flags.h | 76 + src/Core/testing/FunctionTest.cpp | 57 + src/Core/testing/Makefile.am | 38 + src/Core/testing/ObjectCopyTest.cpp | 50 + src/Core/testing/ObjectFlagsTest.cpp | 69 + src/Core/testing/ObjectMock/Makefile.am | 11 + src/Core/testing/ObjectMock/Ob.cpp | 59 + src/Core/testing/ObjectMock/Ob.h | 181 + src/Core/testing/ObjectMock/Ob1.cpp | 80 + src/Core/testing/ObjectMock/Ob1.h | 122 + src/Core/testing/ObjectMock/Ob2.cpp | 73 + src/Core/testing/ObjectMock/Ob2.h | 135 + src/Core/testing/ObjectMock/main.cpp | 174 + .../testing/ObjectMock/testing-prototype.h | 37 + src/Core/testing/ObjectParametersTest.cpp | 61 + src/Core/testing/ObjectPropableTest.cpp | 237 + src/Core/testing/OptionsTest.cpp | 72 + src/Core/testing/PropertiesTest.cpp | 96 + .../testing/SerializeDreadDiamondTest.cpp | 114 + src/Core/testing/SerializeMock/Makefile.am | 13 + src/Core/testing/SerializeMock/Ob.cpp | 103 + src/Core/testing/SerializeMock/Ob.h | 112 + src/Core/testing/SerializeMock/Ob1.cpp | 52 + src/Core/testing/SerializeMock/Ob1.h | 45 + src/Core/testing/SerializeMock/main.cpp | 111 + src/Core/testing/SerializeTest.cpp | 249 + src/Core/testing/SignalMock/Makefile.am | 11 + src/Core/testing/SignalMock/Ob.cpp | 104 + src/Core/testing/SignalMock/Ob.h | 348 ++ src/Core/testing/SignalMock/Ob1.cpp | 55 + src/Core/testing/SignalMock/Ob1.h | 68 + src/Core/testing/SignalMock/Ob2.cpp | 44 + src/Core/testing/SignalMock/Ob2.h | 57 + src/Core/testing/SignalMock/main.cpp | 180 + src/Core/testing/SignalMock/main2.cpp | 169 + src/Core/testing/SignalMock/test1.cpp | 216 + .../testing/SignalMock/testing-prototype.h | 37 + src/Core/testing/SignalTest.cpp | 115 + src/Core/testing/SmartPointerTest.cpp | 94 + src/Core/testing/SmartVectorTest.cpp | 120 + src/Core/testing/StaticInterfaceTest.cpp | 112 + .../testing/TypeIntrospectionTraversal.cpp | 52 + src/Core/testing/UuidTest.cpp | 45 + src/Core/testing/VectorTest.cpp | 84 + src/Core/testing/testing-prototype.h | 37 + src/Detectors/CMakeLists.txt | 38 + src/Detectors/ChamberHitEvent.h | 56 + src/Detectors/DetectorChamber.h | 48 + src/Detectors/ExperimentFitEvent.h | 48 + src/Detectors/GeantEvent.h | 69 + src/Detectors/HierarchicalEncoding.h | 41 + src/Detectors/Hit.h | 70 + src/Detectors/HitMC.h | 67 + src/Detectors/LinearFit.h | 73 + src/Detectors/Makefile.am | 25 + src/Detectors/Matter.h | 71 + src/Detectors/MuonError.h | 58 + src/Detectors/MuonEvent.h | 75 + src/Detectors/MuonScatter.h | 81 + src/Detectors/Scene.cpp | 75 + src/Detectors/Scene.h | 52 + src/Detectors/Solid.cpp | 114 + src/Detectors/Solid.h | 86 + src/Detectors/testing/CMakeLists.txt | 18 + src/Detectors/testing/GDMLSolidTest.cpp | 72 + .../testing/HierarchicalEncodingTest.cpp | 50 + src/Detectors/testing/Makefile.am | 16 + src/Detectors/testing/testing-prototype.h | 37 + src/Gui/Qt/QVTKViewport2/Makefile.am | 35 + src/Gui/Qt/QVTKViewport2/QVTKViewport2.pro | 18 + .../Qt/QVTKViewport2/QVTKViewport2.pro.user | 453 ++ src/Gui/Qt/QVTKViewport2/main.cpp | 38 + src/Gui/Qt/QVTKViewport2/vtkviewport.cpp | 41 + src/Gui/Qt/QVTKViewport2/vtkviewport.h | 49 + src/Gui/Qt/QVTKViewport2/vtkviewport.ui | 32 + src/Makefile.am | 3 + src/Math/Accumulator.h | 334 ++ src/Math/BitCode.h | 259 + src/Math/CMakeLists.txt | 54 + src/Math/ContainerBox.h | 95 + src/Math/DataSet.h | 77 + src/Math/Dense.cpp | 64 + src/Math/Dense.h | 364 ++ src/Math/Geometry.h | 60 + src/Math/ImageData.cpp | 0 src/Math/ImageData.h | 54 + src/Math/ImageMap.cpp | 80 + src/Math/ImageMap.h | 95 + src/Math/ImageSpace.cpp | 87 + src/Math/ImageSpace.h | 67 + src/Math/Line.h | 69 + src/Math/Makefile.am | 42 + src/Math/Polydata.h | 48 + src/Math/Quote.h | 49 + src/Math/StructuredData.cpp | 80 + src/Math/StructuredData.h | 101 + src/Math/StructuredGrid.cpp | 87 + src/Math/StructuredGrid.h | 65 + src/Math/Transform.h | 141 + src/Math/TriangleMesh.cpp | 69 + src/Math/TriangleMesh.h | 59 + src/Math/Utils.h | 50 + src/Math/VectorSpace.h | 70 + src/Math/VoxImage.cpp | 192 + src/Math/VoxImage.h | 286 + src/Math/VoxImageFilter.h | 129 + src/Math/VoxImageFilter.hpp | 302 ++ src/Math/VoxImageFilter2ndStat.hpp | 83 + src/Math/VoxImageFilterABTrim.hpp | 179 + src/Math/VoxImageFilterBilateral.hpp | 152 + src/Math/VoxImageFilterCustom.hpp | 88 + src/Math/VoxImageFilterLinear.hpp | 69 + src/Math/VoxImageFilterMedian.hpp | 75 + src/Math/VoxImageFilterThreshold.hpp | 78 + src/Math/VoxImageFilterUser.cpp | 35 + src/Math/VoxRaytracer.cpp | 202 + src/Math/VoxRaytracer.h | 86 + src/Math/testing/AccumulatorTest.cpp | 108 + src/Math/testing/BitCodeTest.cpp | 19 + src/Math/testing/CMakeLists.txt | 19 + src/Math/testing/ContainerBoxTest.cpp | 95 + src/Math/testing/GeometryTest.cpp | 99 + src/Math/testing/Makefile.am | 28 + src/Math/testing/MathVectorTest.cpp | 120 + src/Math/testing/PolicyTest.cpp | 78 + src/Math/testing/StructuredDataTest.cpp | 129 + src/Math/testing/StructuredGridTest.cpp | 72 + src/Math/testing/TriangleMeshTest.cpp | 52 + src/Math/testing/VoxImageCopyTest.cpp | 77 + src/Math/testing/VoxImageFilterTest.cpp | 150 + src/Math/testing/VoxImageTest.cpp | 107 + src/Math/testing/VoxRaytracerTest.cpp | 151 + src/Math/testing/testing-prototype.h | 37 + src/ParticlePhysics/Geant/Makefile.am | 14 + .../MuonTomography/DetectorChamber.h | 47 + .../MuonTomography/DriftDetector.h | 53 + src/ParticlePhysics/MuonTomography/Hit.h | 65 + .../MuonTomography/Makefile.am | 11 + .../MuonTomography/MuonScatter.h | 89 + src/Root/CMakeLists.txt | 39 + src/Root/Linkdef.h | 79 + src/Root/Makefile.am | 20 + src/Root/RootHitMC.h | 50 + src/Root/RootHitRaw.h | 71 + src/Root/RootMathDense.h | 68 + src/Root/RootMuonScatter.cpp | 75 + src/Root/RootMuonScatter.h | 66 + src/Root/TestTObject.cpp | 31 + src/Root/TestTObject.h | 47 + src/Root/testing/CMakeLists.txt | 15 + src/Root/testing/Makefile.am | 20 + src/Root/testing/RootDebugTest.cpp | 122 + src/Vtk/CMakeLists.txt | 39 + src/Vtk/Makefile.am | 34 + src/Vtk/Vtk.am | 93 + src/Vtk/testing/CMakeLists.txt | 13 + src/Vtk/testing/Makefile.am | 21 + src/Vtk/testing/testVtkWriter.cpp | 95 + src/Vtk/testing/testing-prototype.h | 41 + src/Vtk/testing/vtkContainerBoxTest.cpp | 53 + src/Vtk/testing/vtkMuonScatter.cpp | 62 + src/Vtk/testing/vtkStructuredGridTest.cpp | 51 + src/Vtk/testing/vtkTriangleMeshTest.cpp | 75 + src/Vtk/testing/vtkViewerTest.cpp | 71 + src/Vtk/testing/vtkVoxImageTest.cpp | 102 + src/Vtk/testing/vtkVoxRaytracerTest.cpp | 156 + src/Vtk/uLibVtkInterface.cxx | 238 + src/Vtk/uLibVtkInterface.h | 124 + src/Vtk/uLibVtkViewer.cpp | 190 + src/Vtk/uLibVtkViewer.h | 90 + src/Vtk/vtkContainerBox.cpp | 158 + src/Vtk/vtkContainerBox.h | 57 + src/Vtk/vtkHLineRepresentation.h | 52 + src/Vtk/vtkMuonContainerScattering.cpp | 35 + src/Vtk/vtkMuonContainerScattering.h | 77 + src/Vtk/vtkMuonEvent.cxx | 214 + src/Vtk/vtkMuonEvent.h | 74 + src/Vtk/vtkMuonScatter.cxx | 238 + src/Vtk/vtkMuonScatter.h | 76 + src/Vtk/vtkPolydata.h | 49 + src/Vtk/vtkStructuredGrid.cpp | 195 + src/Vtk/vtkStructuredGrid.h | 67 + src/Vtk/vtkTriangleMesh.cpp | 227 + src/Vtk/vtkTriangleMesh.h | 69 + src/Vtk/vtkVoxImage.cpp | 391 ++ src/Vtk/vtkVoxImage.h | 88 + src/Vtk/vtkVoxRaytracerRepresentation.cpp | 459 ++ src/Vtk/vtkVoxRaytracerRepresentation.h | 101 + src/Vtk/vtkuLibProp.h | 51 + src/cwchar.h | 37 + src/ltk/CMakeLists.txt | 12 + src/ltk/DenseMatrix.h | 111 + src/ltk/Makefile.am | 6 + src/ltk/Object.c | 18 + src/ltk/Object.h | 78 + src/ltk/Vector.h | 195 + src/ltk/container.h | 43 + src/ltk/ltk.h | 32 + src/ltk/ltk_bridge/ltkb.c | 339 ++ src/ltk/ltk_bridge/ltkb_test.c | 40 + src/ltk/ltk_bridge/setup.sh | 21 + src/ltk/ltkdebug.c | 4 + src/ltk/ltkdebug.h | 105 + src/ltk/ltkmacros.h | 61 + src/ltk/ltktypes.h | 127 + src/ltk/main.C | 35 + src/ltk/main.c | 72 + src/ltk/templates.c | 92 + src/ltk/templates.h | 303 ++ src/ltk/test_comma.h | 117 + src/ltk/testing/Makefile.am | 37 + src/ltk/testing/Object-cc.cpp | 40 + src/ltk/testing/Object.c | 11 + src/ltk/testing/Vector-cc.cpp | 79 + src/ltk/testing/Vector.c | 14 + src/ltk/testing/testing-prototype.h | 37 + src/utils/copyrights/cr_update.py | 45 + src/utils/copyrights/newcr.txt | 27 + src/utils/copyrights/oldcr.txt | 24 + src/utils/make_recipe/CMakeLists.txt | 37 + src/utils/make_recipe/main.cpp | 137 + src/utils/make_recipe/src/CMake | 1 + src/utils/make_recipe/src/CMakeLists.txt | 104 + src/utils/make_recipe/src/main.cpp | 36 + src/utils/moc/Makefile | 24 + src/utils/moc/moc_actions.h | 92 + src/utils/moc/parse.y | 1257 +++++ src/utils/moc/sample.cpp | 51 + src/utils/moc/scan.l | 252 + test.cpp | 10 + tmp/BuildTruck/BuildTruck.cpp | 154 + tmp/BuildTruck/Makefile.am | 11 + tmp/BuildTruck/objects/acciaio1.stl | Bin 0 -> 78284 bytes tmp/BuildTruck/objects/acciaio2.stl | Bin 0 -> 221884 bytes tmp/BuildTruck/objects/carrozzeria.stl | Bin 0 -> 143884 bytes tmp/BuildTruck/objects/container.stl | Bin 0 -> 479184 bytes tmp/BuildTruck/objects/fusto.stl | Bin 0 -> 22484 bytes tmp/BuildTruck/objects/gomma.stl | Bin 0 -> 324284 bytes tmp/BuildTruck/objects/maniglieria.stl | Bin 0 -> 89684 bytes tmp/BuildTruck/objects/telaio.stl | Bin 0 -> 17684 bytes tmp/BuildTruck/objects/truck.blend | Bin 0 -> 2693248 bytes tmp/BuildTruck/objects/truck.blend1 | Bin 0 -> 2327160 bytes tmp/BuildTruck/objects/truck.blend2 | Bin 0 -> 1948576 bytes tmp/BuildTruck/objects/truck1.blend | Bin 0 -> 4604232 bytes tmp/BuildTruck/objects/truck1.blend1 | Bin 0 -> 4615792 bytes tmp/BuildTruck/objects/truck1r.blend | Bin 0 -> 4618700 bytes tmp/BuildTruck/objects/vetro.stl | Bin 0 -> 6434 bytes tmp/CodeLoop/.deps/main.Po | 253 + tmp/CodeLoop/AUTHORS | 1 + tmp/CodeLoop/CMake/FindEigen3.cmake | 81 + tmp/CodeLoop/CMake/FindGEANT4.cmake | 63 + tmp/CodeLoop/CMake/FindGEANT4VMC.cmake | 97 + tmp/CodeLoop/CMake/FindROOT.cmake | 270 + tmp/CodeLoop/CMake/FindVTK.cmake | 141 + tmp/CodeLoop/CMakeCache.txt | 325 ++ tmp/CodeLoop/CMakeLists.txt | 87 + tmp/CodeLoop/COPYING | 674 +++ tmp/CodeLoop/ChangeLog | 1 + tmp/CodeLoop/INSTALL | 370 ++ tmp/CodeLoop/Makefile | 225 + tmp/CodeLoop/Makefile.am | 23 + tmp/CodeLoop/Makefile.in | 825 +++ tmp/CodeLoop/ManageFilename.cpp | 19 + tmp/CodeLoop/ManageFilename.h | 24 + tmp/CodeLoop/NEWS | 1 + tmp/CodeLoop/Project.ede | 14 + tmp/CodeLoop/README | 1 + tmp/CodeLoop/TMP_loop.config | 1 + tmp/CodeLoop/TMP_loop.creator | 1 + tmp/CodeLoop/TMP_loop.creator.user | 200 + tmp/CodeLoop/TMP_loop.files | 5 + tmp/CodeLoop/TMP_loop.includes | 2 + tmp/CodeLoop/aclocal.m4 | 1143 ++++ tmp/CodeLoop/autom4te.cache/output.0 | 4436 ++++++++++++++++ tmp/CodeLoop/autom4te.cache/output.1 | 4667 +++++++++++++++++ tmp/CodeLoop/autom4te.cache/output.2 | 4667 +++++++++++++++++ tmp/CodeLoop/autom4te.cache/requests | 223 + tmp/CodeLoop/autom4te.cache/traces.0 | 783 +++ tmp/CodeLoop/autom4te.cache/traces.1 | 353 ++ tmp/CodeLoop/autom4te.cache/traces.2 | 887 ++++ tmp/CodeLoop/cmake_install.cmake | 72 + tmp/CodeLoop/config.h | 25 + tmp/CodeLoop/config.h.in | 25 + tmp/CodeLoop/config.log | 334 ++ tmp/CodeLoop/config.status | 1178 +++++ tmp/CodeLoop/configure | 4667 +++++++++++++++++ tmp/CodeLoop/configure.ac | 21 + tmp/CodeLoop/depcomp | 708 +++ tmp/CodeLoop/install-sh | 527 ++ tmp/CodeLoop/loop | Bin 0 -> 708896 bytes tmp/CodeLoop/main.cpp | 39 + tmp/CodeLoop/missing | 331 ++ .../CMakeDirectoryInformation.cmake | 16 + .../ManageFilename.dir/CXX.includecache | 30 + .../ManageFilename.dir/DependInfo.cmake | 24 + .../CMakeFiles/ManageFilename.dir/build.make | 131 + .../ManageFilename.dir/cmake_clean.cmake | 11 + .../ManageFilename.dir/depend.internal | 10 + .../CMakeFiles/ManageFilename.dir/depend.make | 10 + .../CMakeFiles/ManageFilename.dir/flags.make | 8 + .../CMakeFiles/ManageFilename.dir/link.txt | 1 + .../ManageFilename.dir/progress.make | 3 + tmp/CodeLoop/src/CMakeFiles/progress.marks | 1 + tmp/CodeLoop/src/CMakeLists.txt | 14 + tmp/CodeLoop/src/Makefile | 239 + tmp/CodeLoop/src/ManageFilename.cpp | 19 + tmp/CodeLoop/src/ManageFilename.h | 24 + tmp/CodeLoop/src/SourceLists.txt | 8 + tmp/CodeLoop/src/Test.cpp | 17 + tmp/CodeLoop/src/Test.h | 24 + tmp/CodeLoop/src/cmake_install.cmake | 50 + tmp/CodeLoop/src/test.m4 | 3 + tmp/CodeLoop/src/test.sh | 5 + tmp/CodeLoop/stamp-h | 1 + tmp/CodeLoop/stamp-h1 | 1 + tmp/c_vtable/Object.c | 5 + tmp/c_vtable/Object.h | 138 + tmp/c_vtable/Project.ede | 15 + tmp/c_vtable/Vector.c | 3 + tmp/c_vtable/Vector.h | 89 + tmp/c_vtable/main.c | 42 + uLibConfig.cmake.in | 19 + uLibConfigVersion.cmake.in | 11 + ulib.h | 1 + vtk_test.cpp | 39 + 403 files changed, 61684 insertions(+) create mode 100644 AUTHORS create mode 100644 CMake/FindEigen3.cmake create mode 100644 CMake/FindGEANT4.cmake create mode 100644 CMake/FindGEANT4VMC.cmake create mode 100644 CMake/FindROOT.cmake create mode 100644 CMake/FindROOTv6.cmake create mode 100644 CMake/FindReadLine.cmake create mode 100644 CMake/FindVTK.cmake create mode 100644 CMake/FinduLib.cmake create mode 100644 CMake/clean-all.cmake create mode 100644 CMake/rmake.in create mode 100644 CMake/uLibCommon.cmake create mode 100644 CMake/uLibConfigHeader.cmake create mode 100644 CMake/uLibDebugMacro.cmake create mode 100644 CMake/uLibFindDependencies.cmake create mode 100644 CMake/uLibGenerateRMake.cmake create mode 100644 CMake/uLibMacros.cmake create mode 100644 CMake/uLibTargetMacros.cmake create mode 100644 CMakeConfig.in.h create mode 100644 CMakeLists.txt create mode 100644 CMakePkgConfig.pc.in create mode 100644 ChangeLog create mode 100644 Common.am create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 SCRATCH.org create mode 100755 bootstrap create mode 100644 configure.ac create mode 100644 libmutom-0.2.pc.in create mode 100644 m4/boost.m4 create mode 100644 m4/geant4.bkp create mode 100644 m4/geant4.m4 create mode 100644 m4/openmp.m4 create mode 100644 m4/root.m4 create mode 100644 m4/vtk.m4 create mode 100644 m4/zeromq.m4 create mode 100644 src/Core/Archives.cpp create mode 100644 src/Core/Archives.h create mode 100644 src/Core/Array.h create mode 100644 src/Core/CMakeLists.txt create mode 100644 src/Core/Collection.h create mode 100644 src/Core/CommaInitializer.h create mode 100644 src/Core/Debug.cpp create mode 100644 src/Core/Debug.h create mode 100644 src/Core/DebugArchives.cpp create mode 100644 src/Core/DebugArchives.h create mode 100644 src/Core/Export.h create mode 100644 src/Core/Flags.h create mode 100644 src/Core/Function.h create mode 100644 src/Core/Macros.h create mode 100644 src/Core/Makefile.am create mode 100644 src/Core/Mpl.h create mode 100644 src/Core/Object.cpp create mode 100644 src/Core/Object.h create mode 100644 src/Core/ObjectProps.h create mode 100644 src/Core/Options.cpp create mode 100644 src/Core/Options.h create mode 100644 src/Core/ProgrammableAccessor.h create mode 100644 src/Core/Serializable.cpp create mode 100644 src/Core/Serializable.h create mode 100644 src/Core/Signal.cpp create mode 100644 src/Core/Signal.h create mode 100644 src/Core/Singleton.h create mode 100644 src/Core/SmartPointer.h create mode 100644 src/Core/StaticInterface.h create mode 100644 src/Core/String.h create mode 100644 src/Core/StringReader.h create mode 100644 src/Core/Types.h create mode 100644 src/Core/Uuid.cpp create mode 100644 src/Core/Uuid.h create mode 100644 src/Core/Vector.h create mode 100644 src/Core/testing/BoostAccumulatorTest.cpp create mode 100644 src/Core/testing/BoostTest.cpp create mode 100644 src/Core/testing/CMakeLists.txt create mode 100755 src/Core/testing/CommaInitTest.cpp create mode 100644 src/Core/testing/DebugTTreeDumpTest.cpp create mode 100644 src/Core/testing/DreadDiamondParameters.cpp create mode 100644 src/Core/testing/Flags.h create mode 100644 src/Core/testing/FunctionTest.cpp create mode 100644 src/Core/testing/Makefile.am create mode 100644 src/Core/testing/ObjectCopyTest.cpp create mode 100644 src/Core/testing/ObjectFlagsTest.cpp create mode 100644 src/Core/testing/ObjectMock/Makefile.am create mode 100644 src/Core/testing/ObjectMock/Ob.cpp create mode 100644 src/Core/testing/ObjectMock/Ob.h create mode 100644 src/Core/testing/ObjectMock/Ob1.cpp create mode 100644 src/Core/testing/ObjectMock/Ob1.h create mode 100644 src/Core/testing/ObjectMock/Ob2.cpp create mode 100644 src/Core/testing/ObjectMock/Ob2.h create mode 100644 src/Core/testing/ObjectMock/main.cpp create mode 100644 src/Core/testing/ObjectMock/testing-prototype.h create mode 100644 src/Core/testing/ObjectParametersTest.cpp create mode 100644 src/Core/testing/ObjectPropableTest.cpp create mode 100644 src/Core/testing/OptionsTest.cpp create mode 100644 src/Core/testing/PropertiesTest.cpp create mode 100644 src/Core/testing/SerializeDreadDiamondTest.cpp create mode 100644 src/Core/testing/SerializeMock/Makefile.am create mode 100644 src/Core/testing/SerializeMock/Ob.cpp create mode 100644 src/Core/testing/SerializeMock/Ob.h create mode 100644 src/Core/testing/SerializeMock/Ob1.cpp create mode 100644 src/Core/testing/SerializeMock/Ob1.h create mode 100644 src/Core/testing/SerializeMock/main.cpp create mode 100644 src/Core/testing/SerializeTest.cpp create mode 100644 src/Core/testing/SignalMock/Makefile.am create mode 100644 src/Core/testing/SignalMock/Ob.cpp create mode 100644 src/Core/testing/SignalMock/Ob.h create mode 100644 src/Core/testing/SignalMock/Ob1.cpp create mode 100644 src/Core/testing/SignalMock/Ob1.h create mode 100644 src/Core/testing/SignalMock/Ob2.cpp create mode 100644 src/Core/testing/SignalMock/Ob2.h create mode 100644 src/Core/testing/SignalMock/main.cpp create mode 100644 src/Core/testing/SignalMock/main2.cpp create mode 100644 src/Core/testing/SignalMock/test1.cpp create mode 100644 src/Core/testing/SignalMock/testing-prototype.h create mode 100644 src/Core/testing/SignalTest.cpp create mode 100644 src/Core/testing/SmartPointerTest.cpp create mode 100644 src/Core/testing/SmartVectorTest.cpp create mode 100644 src/Core/testing/StaticInterfaceTest.cpp create mode 100644 src/Core/testing/TypeIntrospectionTraversal.cpp create mode 100644 src/Core/testing/UuidTest.cpp create mode 100644 src/Core/testing/VectorTest.cpp create mode 100644 src/Core/testing/testing-prototype.h create mode 100644 src/Detectors/CMakeLists.txt create mode 100644 src/Detectors/ChamberHitEvent.h create mode 100644 src/Detectors/DetectorChamber.h create mode 100644 src/Detectors/ExperimentFitEvent.h create mode 100644 src/Detectors/GeantEvent.h create mode 100644 src/Detectors/HierarchicalEncoding.h create mode 100644 src/Detectors/Hit.h create mode 100644 src/Detectors/HitMC.h create mode 100644 src/Detectors/LinearFit.h create mode 100644 src/Detectors/Makefile.am create mode 100644 src/Detectors/Matter.h create mode 100644 src/Detectors/MuonError.h create mode 100644 src/Detectors/MuonEvent.h create mode 100644 src/Detectors/MuonScatter.h create mode 100644 src/Detectors/Scene.cpp create mode 100644 src/Detectors/Scene.h create mode 100644 src/Detectors/Solid.cpp create mode 100644 src/Detectors/Solid.h create mode 100644 src/Detectors/testing/CMakeLists.txt create mode 100644 src/Detectors/testing/GDMLSolidTest.cpp create mode 100644 src/Detectors/testing/HierarchicalEncodingTest.cpp create mode 100644 src/Detectors/testing/Makefile.am create mode 100644 src/Detectors/testing/testing-prototype.h create mode 100644 src/Gui/Qt/QVTKViewport2/Makefile.am create mode 100644 src/Gui/Qt/QVTKViewport2/QVTKViewport2.pro create mode 100644 src/Gui/Qt/QVTKViewport2/QVTKViewport2.pro.user create mode 100644 src/Gui/Qt/QVTKViewport2/main.cpp create mode 100644 src/Gui/Qt/QVTKViewport2/vtkviewport.cpp create mode 100644 src/Gui/Qt/QVTKViewport2/vtkviewport.h create mode 100644 src/Gui/Qt/QVTKViewport2/vtkviewport.ui create mode 100644 src/Makefile.am create mode 100644 src/Math/Accumulator.h create mode 100644 src/Math/BitCode.h create mode 100644 src/Math/CMakeLists.txt create mode 100644 src/Math/ContainerBox.h create mode 100644 src/Math/DataSet.h create mode 100644 src/Math/Dense.cpp create mode 100644 src/Math/Dense.h create mode 100644 src/Math/Geometry.h create mode 100644 src/Math/ImageData.cpp create mode 100644 src/Math/ImageData.h create mode 100644 src/Math/ImageMap.cpp create mode 100644 src/Math/ImageMap.h create mode 100644 src/Math/ImageSpace.cpp create mode 100644 src/Math/ImageSpace.h create mode 100644 src/Math/Line.h create mode 100644 src/Math/Makefile.am create mode 100644 src/Math/Polydata.h create mode 100644 src/Math/Quote.h create mode 100644 src/Math/StructuredData.cpp create mode 100644 src/Math/StructuredData.h create mode 100644 src/Math/StructuredGrid.cpp create mode 100644 src/Math/StructuredGrid.h create mode 100644 src/Math/Transform.h create mode 100644 src/Math/TriangleMesh.cpp create mode 100644 src/Math/TriangleMesh.h create mode 100644 src/Math/Utils.h create mode 100644 src/Math/VectorSpace.h create mode 100644 src/Math/VoxImage.cpp create mode 100644 src/Math/VoxImage.h create mode 100644 src/Math/VoxImageFilter.h create mode 100644 src/Math/VoxImageFilter.hpp create mode 100644 src/Math/VoxImageFilter2ndStat.hpp create mode 100644 src/Math/VoxImageFilterABTrim.hpp create mode 100644 src/Math/VoxImageFilterBilateral.hpp create mode 100644 src/Math/VoxImageFilterCustom.hpp create mode 100644 src/Math/VoxImageFilterLinear.hpp create mode 100644 src/Math/VoxImageFilterMedian.hpp create mode 100644 src/Math/VoxImageFilterThreshold.hpp create mode 100644 src/Math/VoxImageFilterUser.cpp create mode 100644 src/Math/VoxRaytracer.cpp create mode 100644 src/Math/VoxRaytracer.h create mode 100644 src/Math/testing/AccumulatorTest.cpp create mode 100644 src/Math/testing/BitCodeTest.cpp create mode 100644 src/Math/testing/CMakeLists.txt create mode 100644 src/Math/testing/ContainerBoxTest.cpp create mode 100644 src/Math/testing/GeometryTest.cpp create mode 100644 src/Math/testing/Makefile.am create mode 100644 src/Math/testing/MathVectorTest.cpp create mode 100644 src/Math/testing/PolicyTest.cpp create mode 100644 src/Math/testing/StructuredDataTest.cpp create mode 100644 src/Math/testing/StructuredGridTest.cpp create mode 100644 src/Math/testing/TriangleMeshTest.cpp create mode 100644 src/Math/testing/VoxImageCopyTest.cpp create mode 100644 src/Math/testing/VoxImageFilterTest.cpp create mode 100644 src/Math/testing/VoxImageTest.cpp create mode 100644 src/Math/testing/VoxRaytracerTest.cpp create mode 100644 src/Math/testing/testing-prototype.h create mode 100644 src/ParticlePhysics/Geant/Makefile.am create mode 100644 src/ParticlePhysics/MuonTomography/DetectorChamber.h create mode 100644 src/ParticlePhysics/MuonTomography/DriftDetector.h create mode 100644 src/ParticlePhysics/MuonTomography/Hit.h create mode 100644 src/ParticlePhysics/MuonTomography/Makefile.am create mode 100644 src/ParticlePhysics/MuonTomography/MuonScatter.h create mode 100644 src/Root/CMakeLists.txt create mode 100644 src/Root/Linkdef.h create mode 100644 src/Root/Makefile.am create mode 100644 src/Root/RootHitMC.h create mode 100644 src/Root/RootHitRaw.h create mode 100644 src/Root/RootMathDense.h create mode 100644 src/Root/RootMuonScatter.cpp create mode 100644 src/Root/RootMuonScatter.h create mode 100644 src/Root/TestTObject.cpp create mode 100644 src/Root/TestTObject.h create mode 100644 src/Root/testing/CMakeLists.txt create mode 100644 src/Root/testing/Makefile.am create mode 100644 src/Root/testing/RootDebugTest.cpp create mode 100644 src/Vtk/CMakeLists.txt create mode 100644 src/Vtk/Makefile.am create mode 100644 src/Vtk/Vtk.am create mode 100644 src/Vtk/testing/CMakeLists.txt create mode 100644 src/Vtk/testing/Makefile.am create mode 100644 src/Vtk/testing/testVtkWriter.cpp create mode 100644 src/Vtk/testing/testing-prototype.h create mode 100644 src/Vtk/testing/vtkContainerBoxTest.cpp create mode 100644 src/Vtk/testing/vtkMuonScatter.cpp create mode 100644 src/Vtk/testing/vtkStructuredGridTest.cpp create mode 100644 src/Vtk/testing/vtkTriangleMeshTest.cpp create mode 100644 src/Vtk/testing/vtkViewerTest.cpp create mode 100644 src/Vtk/testing/vtkVoxImageTest.cpp create mode 100644 src/Vtk/testing/vtkVoxRaytracerTest.cpp create mode 100644 src/Vtk/uLibVtkInterface.cxx create mode 100644 src/Vtk/uLibVtkInterface.h create mode 100644 src/Vtk/uLibVtkViewer.cpp create mode 100644 src/Vtk/uLibVtkViewer.h create mode 100644 src/Vtk/vtkContainerBox.cpp create mode 100644 src/Vtk/vtkContainerBox.h create mode 100644 src/Vtk/vtkHLineRepresentation.h create mode 100644 src/Vtk/vtkMuonContainerScattering.cpp create mode 100644 src/Vtk/vtkMuonContainerScattering.h create mode 100644 src/Vtk/vtkMuonEvent.cxx create mode 100644 src/Vtk/vtkMuonEvent.h create mode 100644 src/Vtk/vtkMuonScatter.cxx create mode 100644 src/Vtk/vtkMuonScatter.h create mode 100644 src/Vtk/vtkPolydata.h create mode 100644 src/Vtk/vtkStructuredGrid.cpp create mode 100644 src/Vtk/vtkStructuredGrid.h create mode 100644 src/Vtk/vtkTriangleMesh.cpp create mode 100644 src/Vtk/vtkTriangleMesh.h create mode 100644 src/Vtk/vtkVoxImage.cpp create mode 100644 src/Vtk/vtkVoxImage.h create mode 100644 src/Vtk/vtkVoxRaytracerRepresentation.cpp create mode 100644 src/Vtk/vtkVoxRaytracerRepresentation.h create mode 100644 src/Vtk/vtkuLibProp.h create mode 100644 src/cwchar.h create mode 100644 src/ltk/CMakeLists.txt create mode 100644 src/ltk/DenseMatrix.h create mode 100644 src/ltk/Makefile.am create mode 100644 src/ltk/Object.c create mode 100644 src/ltk/Object.h create mode 100644 src/ltk/Vector.h create mode 100644 src/ltk/container.h create mode 100644 src/ltk/ltk.h create mode 100644 src/ltk/ltk_bridge/ltkb.c create mode 100644 src/ltk/ltk_bridge/ltkb_test.c create mode 100755 src/ltk/ltk_bridge/setup.sh create mode 100644 src/ltk/ltkdebug.c create mode 100755 src/ltk/ltkdebug.h create mode 100644 src/ltk/ltkmacros.h create mode 100644 src/ltk/ltktypes.h create mode 100644 src/ltk/main.C create mode 100644 src/ltk/main.c create mode 100644 src/ltk/templates.c create mode 100644 src/ltk/templates.h create mode 100644 src/ltk/test_comma.h create mode 100644 src/ltk/testing/Makefile.am create mode 100644 src/ltk/testing/Object-cc.cpp create mode 100644 src/ltk/testing/Object.c create mode 100644 src/ltk/testing/Vector-cc.cpp create mode 100644 src/ltk/testing/Vector.c create mode 100644 src/ltk/testing/testing-prototype.h create mode 100644 src/utils/copyrights/cr_update.py create mode 100644 src/utils/copyrights/newcr.txt create mode 100644 src/utils/copyrights/oldcr.txt create mode 100644 src/utils/make_recipe/CMakeLists.txt create mode 100644 src/utils/make_recipe/main.cpp create mode 120000 src/utils/make_recipe/src/CMake create mode 100644 src/utils/make_recipe/src/CMakeLists.txt create mode 100644 src/utils/make_recipe/src/main.cpp create mode 100644 src/utils/moc/Makefile create mode 100644 src/utils/moc/moc_actions.h create mode 100644 src/utils/moc/parse.y create mode 100644 src/utils/moc/sample.cpp create mode 100644 src/utils/moc/scan.l create mode 100644 test.cpp create mode 100644 tmp/BuildTruck/BuildTruck.cpp create mode 100644 tmp/BuildTruck/Makefile.am create mode 100644 tmp/BuildTruck/objects/acciaio1.stl create mode 100644 tmp/BuildTruck/objects/acciaio2.stl create mode 100644 tmp/BuildTruck/objects/carrozzeria.stl create mode 100644 tmp/BuildTruck/objects/container.stl create mode 100644 tmp/BuildTruck/objects/fusto.stl create mode 100644 tmp/BuildTruck/objects/gomma.stl create mode 100644 tmp/BuildTruck/objects/maniglieria.stl create mode 100644 tmp/BuildTruck/objects/telaio.stl create mode 100644 tmp/BuildTruck/objects/truck.blend create mode 100644 tmp/BuildTruck/objects/truck.blend1 create mode 100644 tmp/BuildTruck/objects/truck.blend2 create mode 100644 tmp/BuildTruck/objects/truck1.blend create mode 100644 tmp/BuildTruck/objects/truck1.blend1 create mode 100644 tmp/BuildTruck/objects/truck1r.blend create mode 100644 tmp/BuildTruck/objects/vetro.stl create mode 100644 tmp/CodeLoop/.deps/main.Po create mode 100644 tmp/CodeLoop/AUTHORS create mode 100644 tmp/CodeLoop/CMake/FindEigen3.cmake create mode 100644 tmp/CodeLoop/CMake/FindGEANT4.cmake create mode 100644 tmp/CodeLoop/CMake/FindGEANT4VMC.cmake create mode 100644 tmp/CodeLoop/CMake/FindROOT.cmake create mode 100644 tmp/CodeLoop/CMake/FindVTK.cmake create mode 100644 tmp/CodeLoop/CMakeCache.txt create mode 100644 tmp/CodeLoop/CMakeLists.txt create mode 100644 tmp/CodeLoop/COPYING create mode 100644 tmp/CodeLoop/ChangeLog create mode 100644 tmp/CodeLoop/INSTALL create mode 100644 tmp/CodeLoop/Makefile create mode 100644 tmp/CodeLoop/Makefile.am create mode 100644 tmp/CodeLoop/Makefile.in create mode 100644 tmp/CodeLoop/ManageFilename.cpp create mode 100644 tmp/CodeLoop/ManageFilename.h create mode 100644 tmp/CodeLoop/NEWS create mode 100644 tmp/CodeLoop/Project.ede create mode 100644 tmp/CodeLoop/README create mode 100644 tmp/CodeLoop/TMP_loop.config create mode 100644 tmp/CodeLoop/TMP_loop.creator create mode 100644 tmp/CodeLoop/TMP_loop.creator.user create mode 100644 tmp/CodeLoop/TMP_loop.files create mode 100644 tmp/CodeLoop/TMP_loop.includes create mode 100644 tmp/CodeLoop/aclocal.m4 create mode 100644 tmp/CodeLoop/autom4te.cache/output.0 create mode 100644 tmp/CodeLoop/autom4te.cache/output.1 create mode 100644 tmp/CodeLoop/autom4te.cache/output.2 create mode 100644 tmp/CodeLoop/autom4te.cache/requests create mode 100644 tmp/CodeLoop/autom4te.cache/traces.0 create mode 100644 tmp/CodeLoop/autom4te.cache/traces.1 create mode 100644 tmp/CodeLoop/autom4te.cache/traces.2 create mode 100644 tmp/CodeLoop/cmake_install.cmake create mode 100644 tmp/CodeLoop/config.h create mode 100644 tmp/CodeLoop/config.h.in create mode 100644 tmp/CodeLoop/config.log create mode 100755 tmp/CodeLoop/config.status create mode 100755 tmp/CodeLoop/configure create mode 100644 tmp/CodeLoop/configure.ac create mode 100644 tmp/CodeLoop/depcomp create mode 100644 tmp/CodeLoop/install-sh create mode 100755 tmp/CodeLoop/loop create mode 100644 tmp/CodeLoop/main.cpp create mode 100644 tmp/CodeLoop/missing create mode 100644 tmp/CodeLoop/src/CMakeFiles/CMakeDirectoryInformation.cmake create mode 100644 tmp/CodeLoop/src/CMakeFiles/ManageFilename.dir/CXX.includecache create mode 100644 tmp/CodeLoop/src/CMakeFiles/ManageFilename.dir/DependInfo.cmake create mode 100644 tmp/CodeLoop/src/CMakeFiles/ManageFilename.dir/build.make create mode 100644 tmp/CodeLoop/src/CMakeFiles/ManageFilename.dir/cmake_clean.cmake create mode 100644 tmp/CodeLoop/src/CMakeFiles/ManageFilename.dir/depend.internal create mode 100644 tmp/CodeLoop/src/CMakeFiles/ManageFilename.dir/depend.make create mode 100644 tmp/CodeLoop/src/CMakeFiles/ManageFilename.dir/flags.make create mode 100644 tmp/CodeLoop/src/CMakeFiles/ManageFilename.dir/link.txt create mode 100644 tmp/CodeLoop/src/CMakeFiles/ManageFilename.dir/progress.make create mode 100644 tmp/CodeLoop/src/CMakeFiles/progress.marks create mode 100644 tmp/CodeLoop/src/CMakeLists.txt create mode 100644 tmp/CodeLoop/src/Makefile create mode 100644 tmp/CodeLoop/src/ManageFilename.cpp create mode 100644 tmp/CodeLoop/src/ManageFilename.h create mode 100644 tmp/CodeLoop/src/SourceLists.txt create mode 100644 tmp/CodeLoop/src/Test.cpp create mode 100644 tmp/CodeLoop/src/Test.h create mode 100644 tmp/CodeLoop/src/cmake_install.cmake create mode 100644 tmp/CodeLoop/src/test.m4 create mode 100644 tmp/CodeLoop/src/test.sh create mode 100644 tmp/CodeLoop/stamp-h create mode 100644 tmp/CodeLoop/stamp-h1 create mode 100644 tmp/c_vtable/Object.c create mode 100644 tmp/c_vtable/Object.h create mode 100644 tmp/c_vtable/Project.ede create mode 100644 tmp/c_vtable/Vector.c create mode 100644 tmp/c_vtable/Vector.h create mode 100644 tmp/c_vtable/main.c create mode 100644 uLibConfig.cmake.in create mode 100644 uLibConfigVersion.cmake.in create mode 100644 ulib.h create mode 100644 vtk_test.cpp diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..129c2ad --- /dev/null +++ b/AUTHORS @@ -0,0 +1,8 @@ +/** + * CMT - Written and Mantained by: + * + * A. Rigoni ( andrea.rigoni@pd.infn.it ) + * M. Furlan ( matteo.furlan@pd.infn.it ) + * S. Vanini ( sara.vanini@pd.infn.it ) + * + **/ diff --git a/CMake/FindEigen3.cmake b/CMake/FindEigen3.cmake new file mode 100644 index 0000000..9c546a0 --- /dev/null +++ b/CMake/FindEigen3.cmake @@ -0,0 +1,81 @@ +# - Try to find Eigen3 lib +# +# This module supports requiring a minimum version, e.g. you can do +# find_package(Eigen3 3.1.2) +# to require version 3.1.2 or newer of Eigen3. +# +# Once done this will define +# +# EIGEN3_FOUND - system has eigen lib with correct version +# EIGEN3_INCLUDE_DIR - the eigen include directory +# EIGEN3_VERSION - eigen version + +# Copyright (c) 2006, 2007 Montel Laurent, +# Copyright (c) 2008, 2009 Gael Guennebaud, +# Copyright (c) 2009 Benoit Jacob +# Redistribution and use is allowed according to the terms of the 2-clause BSD license. + +if(NOT Eigen3_FIND_VERSION) + if(NOT Eigen3_FIND_VERSION_MAJOR) + set(Eigen3_FIND_VERSION_MAJOR 2) + endif(NOT Eigen3_FIND_VERSION_MAJOR) + if(NOT Eigen3_FIND_VERSION_MINOR) + set(Eigen3_FIND_VERSION_MINOR 91) + endif(NOT Eigen3_FIND_VERSION_MINOR) + if(NOT Eigen3_FIND_VERSION_PATCH) + set(Eigen3_FIND_VERSION_PATCH 0) + endif(NOT Eigen3_FIND_VERSION_PATCH) + + set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") +endif(NOT Eigen3_FIND_VERSION) + +macro(_eigen3_check_version) + file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) + + string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") + set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") + set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") + set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") + + set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) + if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + set(EIGEN3_VERSION_OK FALSE) + else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + set(EIGEN3_VERSION_OK TRUE) + endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + + if(NOT EIGEN3_VERSION_OK) + + message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " + "but at least version ${Eigen3_FIND_VERSION} is required") + endif(NOT EIGEN3_VERSION_OK) +endmacro(_eigen3_check_version) + +if (EIGEN3_INCLUDE_DIR) + + # in cache already + _eigen3_check_version() + set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) + +else (EIGEN3_INCLUDE_DIR) + + find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library + PATHS + ${CMAKE_INSTALL_PREFIX}/include + ${KDE4_INCLUDE_DIR} + PATH_SUFFIXES eigen3 eigen + ) + + if(EIGEN3_INCLUDE_DIR) + _eigen3_check_version() + endif(EIGEN3_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) + + mark_as_advanced(EIGEN3_INCLUDE_DIR) + +endif(EIGEN3_INCLUDE_DIR) + diff --git a/CMake/FindGEANT4.cmake b/CMake/FindGEANT4.cmake new file mode 100644 index 0000000..b351c08 --- /dev/null +++ b/CMake/FindGEANT4.cmake @@ -0,0 +1,63 @@ +# - Try to find GEANT4 +# Once done this will define +# +# GEANT4_FOUND - system has GEANT4 +# GEANT4_INCLUDE_DIR - the GEANT4 include directory +# GEANT4_LIBRARIES - The libraries needed to use GEANT4 +# GEANT4_DEFINITIONS - Compiler switches required for using GEANT4 +# + +if (GEANT4_INCLUDE_DIR AND GEANT4_LIBRARY_DIR) + SET (GEANT4_INCLUDE_DIR GEANT4_INCLUDE_DIR-NOTFOUND) + SET (GEANT4_LIB_DIR GEANT4_LIB_DIR-NOTFOUND) + SET (GEANT4_PLISTS_LIB_DIR GEANT4_PLISTS_LIB_DIR-NOTFOUND) + SET (GEANT4_DIR GEANT4_DIR-NOTFOUND) +endif (GEANT4_INCLUDE_DIR AND GEANT4_LIBRARY_DIR) + +MESSAGE(STATUS "Looking for GEANT4...") + +FIND_PATH(GEANT4_DIR NAMES env.sh PATHS + ${SIMPATH}/transport/geant4 + ${SIMPATH}/transport/geant4/source + NO_DEFAULT_PATH +) + +FIND_PATH(GEANT4_INCLUDE_DIR NAMES G4Event.hh PATHS + ${SIMPATH}/transport/geant4/include + NO_DEFAULT_PATH +) + +SET(GEANT4_INCLUDE_DIR +${SIMPATH}/transport/geant4/include +${SIMPATH}/transport/geant4/source/interfaces/common/include +${SIMPATH}/transport/geant4/physics_lists/hadronic/Packaging/include +${SIMPATH}/transport/geant4/physics_lists/hadronic/QGSP/include +) + +FIND_PATH(GEANT4_LIB_DIR NAMES libG4baryons.so libG4baryons.dylib PATHS + ${SIMPATH}/transport/geant4/lib/Linux-g++ + ${SIMPATH}/transport/geant4/lib/Linux-icc + ${SIMPATH}/transport/geant4/lib + NO_DEFAULT_PATH +) + +IF (GEANT4_LIB_DIR) + SET(GEANT4_LIBRARY_DIR ${GEANT4_LIB_DIR}) +ENDIF (GEANT4_LIB_DIR) + +if (GEANT4_INCLUDE_DIR AND GEANT4_LIBRARY_DIR) + set(GEANT4_FOUND TRUE) +endif (GEANT4_INCLUDE_DIR AND GEANT4_LIBRARY_DIR) + +if (GEANT4_FOUND) + if (NOT GEANT4_FIND_QUIETLY) + MESSAGE(STATUS "Looking for GEANT4... - found ${GEANT4_LIBRARY_DIR}") +# message(STATUS "Found ${GEANT4_LIBRARY_DIR}") + endif (NOT GEANT4_FIND_QUIETLY) + SET(LD_LIBRARY_PATH ${LD_LIBRARY_PATH} ${GEANT4_LIBRARY_DIR}) +else (GEANT4_FOUND) + if (GEANT4_FIND_REQUIRED) + message(FATAL_ERROR "Looking for GEANT4... - Not found") + endif (GEANT4_FIND_REQUIRED) +endif (GEANT4_FOUND) + diff --git a/CMake/FindGEANT4VMC.cmake b/CMake/FindGEANT4VMC.cmake new file mode 100644 index 0000000..5dec1b5 --- /dev/null +++ b/CMake/FindGEANT4VMC.cmake @@ -0,0 +1,97 @@ +# - Try to find GEANT4VMC +# Once done this will define +# +# GEANT4VMC_FOUND - system has GEANT3 +# GEANT4VMC_INCLUDE_DIR - the GEANT3 include directory +# GEANT4VMC_LIBRARIES - The libraries needed to use GEANT3 +# GEANT4VMC_DEFINITIONS - Compiler switches required for using GEANT3 +# + +if (GEANT4VMC_INCLUDE_DIR AND GEANT4VMC_LIBRARY_DIR) + SET (GEANT4VMC_INCLUDE_DIR GEANT4VMC_INCLUDE_DIR-NOTFOUND) + SET (GEANT4VMC_LIB_DIR GEANT4VMC_LIB_DIR-NOTFOUND) + SET (GEANT4VMC_PLISTS_LIB_DIR GEANT4VMC_PLISTS_LIB_DIR-NOTFOUND) +endif (GEANT4VMC_INCLUDE_DIR AND GEANT4VMC_LIBRARY_DIR) + +MESSAGE(STATUS "Looking for GEANT4VMC...") + +FIND_PATH(GEANT4VMC_INCLUDE_DIR NAMES TG4G3Units.h PATHS + ${SIMPATH}/transport/geant4_vmc/include + NO_DEFAULT_PATH +) + +set(GEANT4VMC_INCLUDE_DIR +${SIMPATH}/transport/geant4_vmc/source/global/include +${SIMPATH}/transport/geant4_vmc/source/geometry/include +${SIMPATH}/transport/geant4_vmc/source/digits+hits/include +${SIMPATH}/transport/geant4_vmc/source/physics/include +${SIMPATH}/transport/geant4_vmc/source/event/include +${SIMPATH}/transport/geant4_vmc/source/run/include +${SIMPATH}/transport/geant4_vmc/source/interfaces/include +${SIMPATH}/transport/geant4_vmc/source/visualization/include +${SIMPATH}/transport/geant4_vmc/include +${SIMPATH}/transport/vgm/packages/BaseVGM/include +${SIMPATH}/transport/vgm/packages/ClhepVGM/include +${SIMPATH}/transport/vgm/packages/Geant4GM/include +${SIMPATH}/transport/vgm/packages/RootGM/include +${SIMPATH}/transport/vgm/packages/VGM/include +${SIMPATH}/transport/vgm/packages/XmlVGM/include +) + + +FIND_PATH(GEANT4VMC_LIBRARY_DIR NAMES libgeant4vmc.so libgeant4vmc.dylib PATHS + ${SIMPATH}/transport/geant4_vmc/lib/tgt_linux + ${SIMPATH}/transport/geant4_vmc/lib/tgt_linuxicc + ${SIMPATH}/transport/geant4_vmc/lib/tgt_linuxx8664gcc + ${SIMPATH}/transport/geant4_vmc/lib + NO_DEFAULT_PATH +) + +# check for existence of header file, which is needed in CbmRunConfiguration +# The file is only present in old versions of VMC +FIND_FILE(GEANT4_MODULAR_PHYSICS_LIST TG4ModularPhysicsList.h PATHS + ${GEANT4VMC_INCLUDE_DIR} + NO_DEFAULT_PATH +) + +if (GEANT4VMC_INCLUDE_DIR AND GEANT4VMC_LIBRARY_DIR) + if (NOT GEANT4VMC_FIND_QUIETLY) + MESSAGE(STATUS "Looking for GEANT4VMC... - found ${GEANT4VMC_LIBRARY_DIR}") + endif (NOT GEANT4VMC_FIND_QUIETLY) +else (GEANT4VMC_INCLUDE_DIR AND GEANT4VMC_LIBRARY_DIR) + if (GEANT4VMC_FIND_REQUIRED) + message(FATAL_ERROR "Looking for GEANT4VMC... - Not found ") + endif (GEANT4VMC_FIND_REQUIRED) +endif (GEANT4VMC_INCLUDE_DIR AND GEANT4VMC_LIBRARY_DIR) + + +MESSAGE(STATUS "Looking for VGM...") + +FIND_PATH(VGM_LIBRARY_DIR NAMES libBaseVGM.so libBaseVGM.dylib PATHS + ${SIMPATH}/transport/vgm/lib/Linux-g++ + ${SIMPATH}/transport/vgm.2.08.04/lib/Linux-g++ + ${SIMPATH}/transport/vgm/lib/Linux-icc + ${SIMPATH}/transport/vgm/lib + NO_DEFAULT_PATH +) + +if (VGM_LIBRARY_DIR) + if (NOT GEANT4VMC_FIND_QUIETLY) + MESSAGE(STATUS "Looking for VGM... - found ${VGM_LIBRARY_DIR}") + endif (NOT GEANT4VMC_FIND_QUIETLY) +else (VGM_LIBRARY_DIR) + if (GEANT4VMC_FIND_REQUIRED) + message(FATAL_ERROR "Looking for VGM... - Not found ") + endif (GEANT4VMC_FIND_REQUIRED) +endif (VGM_LIBRARY_DIR) + + +if (GEANT4VMC_INCLUDE_DIR AND GEANT4VMC_LIBRARY_DIR AND VGM_LIBRARY_DIR) + set(GEANT4VMC_FOUND TRUE) +endif (GEANT4VMC_INCLUDE_DIR AND GEANT4VMC_LIBRARY_DIR AND VGM_LIBRARY_DIR) + +if (GEANT4VMC_FOUND) + SET(LD_LIBRARY_PATH ${LD_LIBRARY_PATH} ${GEANT4VMC_LIBRARY_DIR} + ${VGM_LIBRARY_DIR}) +endif (GEANT4VMC_FOUND) + diff --git a/CMake/FindROOT.cmake b/CMake/FindROOT.cmake new file mode 100644 index 0000000..34aed7c --- /dev/null +++ b/CMake/FindROOT.cmake @@ -0,0 +1,279 @@ +# - Find ROOT instalation +# This module tries to find the ROOT installation on your system. +# It tries to find the root-config script which gives you all the needed information. +# If the system variable ROOTSYS is set this is straight forward. +# If not the module uses the pathes given in ROOT_CONFIG_SEARCHPATH. +# If you need an other path you should add this path to this varaible. +# The root-config script is then used to detect basically everything else. +# This module defines a number of key variables and macros. + +# F.Uhlig@gsi.de (fairroot.gsi.de) + + +MESSAGE(STATUS "Looking for Root...") + +SET(ROOT_CONFIG_SEARCHPATH + /usr/local/bin + ${SIMPATH}/tools/root/bin + $ENV{ROOTSYS}/bin +) + +SET(ROOT_DEFINITIONS "") + +SET(ROOT_INSTALLED_VERSION_TOO_OLD FALSE) + +SET(ROOT_CONFIG_EXECUTABLE ROOT_CONFIG_EXECUTABLE-NOTFOUND) + +FIND_PROGRAM(ROOT_CONFIG_EXECUTABLE NAMES root-config PATHS + ${ROOT_CONFIG_SEARCHPATH} + NO_DEFAULT_PATH) + +IF (${ROOT_CONFIG_EXECUTABLE} MATCHES "ROOT_CONFIG_EXECUTABLE-NOTFOUND") + MESSAGE( FATAL_ERROR "ROOT not installed in the searchpath and ROOTSYS is not set. Please + set ROOTSYS or add the path to your ROOT installation in the Macro FindROOT.cmake in the + subdirectory cmake/modules.") +ELSE (${ROOT_CONFIG_EXECUTABLE} MATCHES "ROOT_CONFIG_EXECUTABLE-NOTFOUND") + STRING(REGEX REPLACE "(^.*)/bin/root-config" "\\1" test ${ROOT_CONFIG_EXECUTABLE}) + SET( ENV{ROOTSYS} ${test}) + set( ROOTSYS ${test}) +ENDIF (${ROOT_CONFIG_EXECUTABLE} MATCHES "ROOT_CONFIG_EXECUTABLE-NOTFOUND") + + +IF (ROOT_CONFIG_EXECUTABLE) + + SET(ROOT_FOUND FALSE) + + EXEC_PROGRAM(${ROOT_CONFIG_EXECUTABLE} ARGS "--version" OUTPUT_VARIABLE ROOTVERSION) + + MESSAGE(STATUS "Looking for Root... - found $ENV{ROOTSYS}/bin/root") + MESSAGE(STATUS "Looking for Root... - version ${ROOTVERSION} ") + + # we need at least version 5.00/00 + IF (NOT ROOT_MIN_VERSION) + SET(ROOT_MIN_VERSION "5.00/00") + ENDIF (NOT ROOT_MIN_VERSION) + + # now parse the parts of the user given version string into variables + STRING(REGEX REPLACE "^([0-9]+)\\.[0-9][0-9]+\\/[0-9][0-9]+" "\\1" req_root_major_vers "${ROOT_MIN_VERSION}") + STRING(REGEX REPLACE "^[0-9]+\\.([0-9][0-9])+\\/[0-9][0-9]+.*" "\\1" req_root_minor_vers "${ROOT_MIN_VERSION}") + STRING(REGEX REPLACE "^[0-9]+\\.[0-9][0-9]+\\/([0-9][0-9]+)" "\\1" req_root_patch_vers "${ROOT_MIN_VERSION}") + + # and now the version string given by qmake + STRING(REGEX REPLACE "^([0-9]+)\\.[0-9][0-9]+\\/[0-9][0-9]+.*" "\\1" found_root_major_vers "${ROOTVERSION}") + STRING(REGEX REPLACE "^[0-9]+\\.([0-9][0-9])+\\/[0-9][0-9]+.*" "\\1" found_root_minor_vers "${ROOTVERSION}") + STRING(REGEX REPLACE "^[0-9]+\\.[0-9][0-9]+\\/([0-9][0-9]+).*" "\\1" found_root_patch_vers "${ROOTVERSION}") + + IF (found_root_major_vers LESS 5) + MESSAGE( FATAL_ERROR "Invalid ROOT version \"${ROOTERSION}\", at least major version 4 is required, e.g. \"5.00/00\"") + ENDIF (found_root_major_vers LESS 5) + + # compute an overall version number which can be compared at once + MATH(EXPR req_vers "${req_root_major_vers}*10000 + ${req_root_minor_vers}*100 + ${req_root_patch_vers}") + MATH(EXPR found_vers "${found_root_major_vers}*10000 + ${found_root_minor_vers}*100 + ${found_root_patch_vers}") + + IF (found_vers LESS req_vers) + SET(ROOT_FOUND FALSE) + SET(ROOT_INSTALLED_VERSION_TOO_OLD TRUE) + ELSE (found_vers LESS req_vers) + SET(ROOT_FOUND TRUE) + ENDIF (found_vers LESS req_vers) + +ENDIF (ROOT_CONFIG_EXECUTABLE) + + +IF (ROOT_FOUND) + + # ask root-config for the library dir + # Set ROOT_LIBRARY_DIR + + EXEC_PROGRAM( ${ROOT_CONFIG_EXECUTABLE} + ARGS "--libdir" + OUTPUT_VARIABLE ROOT_LIBRARY_DIR_TMP ) + + IF(EXISTS "${ROOT_LIBRARY_DIR_TMP}") + SET(ROOT_LIBRARY_DIR ${ROOT_LIBRARY_DIR_TMP} ) + ELSE(EXISTS "${ROOT_LIBRARY_DIR_TMP}") + MESSAGE("Warning: ROOT_CONFIG_EXECUTABLE reported ${ROOT_LIBRARY_DIR_TMP} as library path,") + MESSAGE("Warning: but ${ROOT_LIBRARY_DIR_TMP} does NOT exist, ROOT must NOT be installed correctly.") + ENDIF(EXISTS "${ROOT_LIBRARY_DIR_TMP}") + + # ask root-config for the binary dir + EXEC_PROGRAM(${ROOT_CONFIG_EXECUTABLE} + ARGS "--bindir" + OUTPUT_VARIABLE root_bins ) + SET(ROOT_BINARY_DIR ${root_bins}) + + # ask root-config for the include dir + EXEC_PROGRAM( ${ROOT_CONFIG_EXECUTABLE} + ARGS "--incdir" + OUTPUT_VARIABLE root_headers ) + SET(ROOT_INCLUDE_DIR ${root_headers}) + # CACHE INTERNAL "") + + # ask root-config for the library varaibles + EXEC_PROGRAM( ${ROOT_CONFIG_EXECUTABLE} +# ARGS "--noldflags --noauxlibs --libs" + ARGS "--glibs" + OUTPUT_VARIABLE root_flags ) + +# STRING(REGEX MATCHALL "([^ ])+" root_libs_all ${root_flags}) +# STRING(REGEX MATCHALL "-L([^ ])+" root_library ${root_flags}) +# REMOVE_FROM_LIST(root_flags "${root_libs_all}" "${root_library}") + + SET(ROOT_LIBRARIES ${root_flags}) + + # Make variables changeble to the advanced user + MARK_AS_ADVANCED( ROOT_LIBRARY_DIR ROOT_INCLUDE_DIR ROOT_DEFINITIONS) + + # Set ROOT_INCLUDES + SET( ROOT_INCLUDES ${ROOT_INCLUDE_DIR}) + + SET(LD_LIBRARY_PATH ${LD_LIBRARY_PATH} ${ROOT_LIBRARY_DIR}) + + ####################################### + # + # Check the executables of ROOT + # ( rootcint ) + # + ####################################### + + FIND_PROGRAM(ROOT_CINT_EXECUTABLE + NAMES rootcint + PATHS ${ROOT_BINARY_DIR} + NO_DEFAULT_PATH + ) + +ENDIF (ROOT_FOUND) + + + + ########################################### + # + # Macros for building ROOT dictionary + # + ########################################### + +MACRO (ROOT_GENERATE_DICTIONARY_OLD ) + + set(INFILES "") + + foreach (_current_FILE ${ARGN}) + + IF (${_current_FILE} MATCHES "^.*\\.h$") + IF (${_current_FILE} MATCHES "^.*Link.*$") + set(LINKDEF_FILE ${_current_FILE}) + ELSE (${_current_FILE} MATCHES "^.*Link.*$") + set(INFILES ${INFILES} ${_current_FILE}) + ENDIF (${_current_FILE} MATCHES "^.*Link.*$") + ELSE (${_current_FILE} MATCHES "^.*\\.h$") + IF (${_current_FILE} MATCHES "^.*\\.cxx$") + set(OUTFILE ${_current_FILE}) + ELSE (${_current_FILE} MATCHES "^.*\\.cxx$") + set(INCLUDE_DIRS ${INCLUDE_DIRS} -I${_current_FILE}) + ENDIF (${_current_FILE} MATCHES "^.*\\.cxx$") + ENDIF (${_current_FILE} MATCHES "^.*\\.h$") + + endforeach (_current_FILE ${ARGN}) + +# MESSAGE("INFILES: ${INFILES}") +# MESSAGE("OutFILE: ${OUTFILE}") +# MESSAGE("LINKDEF_FILE: ${LINKDEF_FILE}") +# MESSAGE("INCLUDE_DIRS: ${INCLUDE_DIRS}") + + STRING(REGEX REPLACE "(^.*).cxx" "\\1.h" bla "${OUTFILE}") +# MESSAGE("BLA: ${bla}") + SET (OUTFILES ${OUTFILE} ${bla}) + + ADD_CUSTOM_COMMAND(OUTPUT ${OUTFILES} + COMMAND ${ROOT_CINT_EXECUTABLE} + ARGS -f ${OUTFILE} -c -DHAVE_CONFIG_H ${INCLUDE_DIRS} ${INFILES} ${LINKDEF_FILE} DEPENDS ${INFILES}) + +# MESSAGE("ROOT_CINT_EXECUTABLE has created the dictionary ${OUTFILE}") + +ENDMACRO (ROOT_GENERATE_DICTIONARY_OLD) + + ########################################### + # + # Macros for building ROOT dictionary + # + ########################################### + +MACRO (ROOT_GENERATE_DICTIONARY INFILES LINKDEF_FILE OUTFILE INCLUDE_DIRS_IN) + + set(INCLUDE_DIRS) + + foreach (_current_FILE ${INCLUDE_DIRS_IN}) + set(INCLUDE_DIRS ${INCLUDE_DIRS} -I${_current_FILE}) + endforeach (_current_FILE ${INCLUDE_DIRS_IN}) + + +# MESSAGE("INFILES: ${INFILES}") +# MESSAGE("OutFILE: ${OUTFILE}") +# MESSAGE("LINKDEF_FILE: ${LINKDEF_FILE}") +# MESSAGE("INCLUDE_DIRS: ${INCLUDE_DIRS}") + + STRING(REGEX REPLACE "^(.*)\\.(.*)$" "\\1.h" bla "${OUTFILE}") +# MESSAGE("BLA: ${bla}") + SET (OUTFILES ${OUTFILE} ${bla}) + + + if (CMAKE_SYSTEM_NAME MATCHES Linux) + ADD_CUSTOM_COMMAND(OUTPUT ${OUTFILES} + COMMAND LD_LIBRARY_PATH=${ROOT_LIBRARY_DIR} ROOTSYS=${ROOTSYS} ${ROOT_CINT_EXECUTABLE} + ARGS -f ${OUTFILE} -c -DHAVE_CONFIG_H ${INCLUDE_DIRS} ${INFILES} ${LINKDEF_FILE} DEPENDS ${INFILES} ${LINKDEF_FILE}) + else (CMAKE_SYSTEM_NAME MATCHES Linux) + if (CMAKE_SYSTEM_NAME MATCHES Darwin) + ADD_CUSTOM_COMMAND(OUTPUT ${OUTFILES} + COMMAND DYLD_LIBRARY_PATH=${ROOT_LIBRARY_DIR} ROOTSYS=${ROOTSYS} ${ROOT_CINT_EXECUTABLE} + ARGS -f ${OUTFILE} -c -DHAVE_CONFIG_H ${INCLUDE_DIRS} ${INFILES} ${LINKDEF_FILE} DEPENDS ${INFILES} ${LINKDEF_FILE}) + endif (CMAKE_SYSTEM_NAME MATCHES Darwin) + endif (CMAKE_SYSTEM_NAME MATCHES Linux) + +ENDMACRO (ROOT_GENERATE_DICTIONARY) + + + + + + + + + + +MACRO (GENERATE_ROOT_TEST_SCRIPT SCRIPT_FULL_NAME) + + get_filename_component(path_name ${SCRIPT_FULL_NAME} PATH) + get_filename_component(file_extension ${SCRIPT_FULL_NAME} EXT) + get_filename_component(file_name ${SCRIPT_FULL_NAME} NAME_WE) + set(shell_script_name "${file_name}.sh") + + #MESSAGE("PATH: ${path_name}") + #MESSAGE("Ext: ${file_extension}") + #MESSAGE("Name: ${file_name}") + #MESSAGE("Shell Name: ${shell_script_name}") + + string(REPLACE ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} new_path ${path_name} + ) + + #MESSAGE("New PATH: ${new_path}") + + file(MAKE_DIRECTORY ${new_path}/data) + + CONVERT_LIST_TO_STRING(${LD_LIBRARY_PATH}) + set(MY_LD_LIBRARY_PATH ${output}) + set(my_script_name ${SCRIPT_FULL_NAME}) + + if(CMAKE_SYSTEM MATCHES Darwin) + configure_file(${PROJECT_SOURCE_DIR}/cmake/scripts/root_macro_macos.sh.in + ${new_path}/${shell_script_name} + ) + else(CMAKE_SYSTEM MATCHES Darwin) + configure_file(${PROJECT_SOURCE_DIR}/cmake/scripts/root_macro.sh.in + ${new_path}/${shell_script_name} + ) + endif(CMAKE_SYSTEM MATCHES Darwin) + + EXEC_PROGRAM(/bin/chmod ARGS "u+x ${new_path}/${shell_script_name}") + +ENDMACRO (GENERATE_ROOT_TEST_SCRIPT) diff --git a/CMake/FindROOTv6.cmake b/CMake/FindROOTv6.cmake new file mode 100644 index 0000000..414d0a4 --- /dev/null +++ b/CMake/FindROOTv6.cmake @@ -0,0 +1,164 @@ +# - Finds ROOT instalation +# This module sets up ROOT information +# It defines: +# ROOT_FOUND If the ROOT is found +# ROOT_INCLUDE_DIR PATH to the include directory +# ROOT_LIBRARIES Most common libraries +# ROOT_LIBRARY_DIR PATH to the library directory +# +# Updated by K. Smith (ksmith37@nd.edu) to properly handle +# dependncies in ROOT_GENERATE_DICTIONARY + +set(ROOT_ROOTSYS $ENV{ROOTSYS} CACHE PATH "path of root installation") + + +unset(ROOT_CONFIG_EXECUTABLE CACHE) +find_program(ROOT_CONFIG_EXECUTABLE root-config + PATHS ${ROOT_ROOTSYS}/bin NO_DEFAULT_PATH) + +if(NOT ROOT_CONFIG_EXECUTABLE) + set(ROOT_FOUND FALSE) +else() + set(ROOT_FOUND TRUE) + + execute_process( + COMMAND ${ROOT_CONFIG_EXECUTABLE} --prefix + OUTPUT_VARIABLE ROOTSYS + OUTPUT_STRIP_TRAILING_WHITESPACE) + + execute_process( + COMMAND ${ROOT_CONFIG_EXECUTABLE} --version + OUTPUT_VARIABLE ROOT_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + + execute_process( + COMMAND ${ROOT_CONFIG_EXECUTABLE} --incdir + OUTPUT_VARIABLE ROOT_INCLUDE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE) + + execute_process( + COMMAND ${ROOT_CONFIG_EXECUTABLE} --libs + OUTPUT_VARIABLE ROOT_LIBRARIES + OUTPUT_STRIP_TRAILING_WHITESPACE) + + #set(ROOT_LIBRARIES ${ROOT_LIBRARIES} -lThread -lMinuit -lHtml -lVMC -lEG -lGeom -lTreePlayer -lXMLIO -lProof) + #set(ROOT_LIBRARIES ${ROOT_LIBRARIES} -lProofPlayer -lMLP -lSpectrum -lEve -lRGL -lGed -lXMLParser -lPhysics) + set(ROOT_LIBRARY_DIR ${ROOTSYS}/lib) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ROOT DEFAULT_MSG ROOT_CONFIG_EXECUTABLE + ROOTSYS ROOT_VERSION ROOT_INCLUDE_DIR ROOT_LIBRARIES ROOT_LIBRARY_DIR) + +mark_as_advanced(ROOT_CONFIG_EXECUTABLE) + +include(CMakeParseArguments) +unset(ROOT_CINT_EXECUTABLE CACHE) +find_program(ROOT_CINT_EXECUTABLE rootcint PATHS ${ROOT_ROOTSYS}/bin NO_DEFAULT_PATH ) +mark_as_advanced(ROOT_CINT_EXECUTABLE) + + +unset(ROOT_GENREFLEX_EXECUTABLE CACHE) +find_program(ROOT_GENREFLEX_EXECUTABLE genreflex PATHS ${ROOT_ROOTSYS}/bin NO_DEFAULT_PATH) +mark_as_advanced(ROOT_GENREFLEX_EXECUTABLE) + +find_package(GCCXML) + +include(uLibDebugMacro) +#---------------------------------------------------------------------------- +# function ROOT_GENERATE_DICTIONARY( dictionary +# header1 header2 ... +# LINKDEF linkdef1 ... +# OPTIONS opt1...) +function(ROOT_GENERATE_DICTIONARY dictionary) + CMAKE_PARSE_ARGUMENTS(ARG "" "" "LINKDEF;OPTIONS" "" ${ARGN}) + message(" -- generating rootcint dictionary --------------------------------------- ") + #---Get the list of include directories------------------ + get_directory_property(incdirs INCLUDE_DIRECTORIES) + set(includedirs) + foreach( d ${incdirs}) + set(includedirs ${includedirs} -I${d}) + endforeach() + #---Get the list of header files------------------------- + set(headerfiles) + foreach(fp ${ARG_UNPARSED_ARGUMENTS}) + find_file(headerFile ${fp} PATHS ${incdirs}) + set(headerfiles ${headerfiles} ${headerFile}) + debug(headerFile) + unset(headerFile CACHE) + endforeach() + #---Get LinkDef.h file------------------------------------ + set(linkdefs) + foreach( f ${ARG_LINKDEF}) + find_file(linkFile ${f} PATHS ${incdirs}) + set(linkdefs ${linkdefs} ${linkFile}) + debug(linkdefs) + unset(linkFile CACHE) + endforeach() + #---call rootcint------------------------------------------ + add_custom_command(OUTPUT ${dictionary}.cxx ${dictionary}.h + COMMAND ${ROOT_CINT_EXECUTABLE} -cint -f ${dictionary}.cxx + -c -p ${ARG_OPTIONS} ${includedirs} ${headerfiles} ${linkdefs} + DEPENDS ${headerfiles} ${linkdefs} VERBATIM) + message(" -- ---------------------------------------------------------------------- ") +endfunction() + +#---------------------------------------------------------------------------- +# function REFLEX_GENERATE_DICTIONARY(dictionary +# header1 header2 ... +# SELECTION selectionfile ... +# OPTIONS opt1...) +function(REFLEX_GENERATE_DICTIONARY dictionary) + CMAKE_PARSE_ARGUMENTS(ARG "" "" "SELECTION;OPTIONS" "" ${ARGN}) + #---Get the list of header files------------------------- + set(headerfiles) + foreach(fp ${ARG_UNPARSED_ARGUMENTS}) + file(GLOB files ${fp}) + if(files) + foreach(f ${files}) + set(headerfiles ${headerfiles} ${f}) + endforeach() + else() + set(headerfiles ${headerfiles} ${fp}) + endif() + endforeach() + #---Get Selection file------------------------------------ + if(IS_ABSOLUTE ${ARG_SELECTION}) + set(selectionfile ${ARG_SELECTION}) + else() + set(selectionfile ${CMAKE_CURRENT_SOURCE_DIR}/${ARG_SELECTION}) + endif() + #---Get the list of include directories------------------ + get_directory_property(incdirs INCLUDE_DIRECTORIES) + set(includedirs) + foreach( d ${incdirs}) + set(includedirs ${includedirs} -I${d}) + endforeach() + #---Get preprocessor definitions-------------------------- + get_directory_property(defs COMPILE_DEFINITIONS) + foreach( d ${defs}) + set(definitions ${definitions} -D${d}) + endforeach() + #---Nanes and others--------------------------------------- + set(gensrcdict ${dictionary}.cpp) + if(MSVC) + set(gccxmlopts "--gccxmlopt=\"--gccxml-compiler cl\"") + else() + #set(gccxmlopts "--gccxmlopt=\'--gccxml-cxxflags -m64 \'") + set(gccxmlopts) + endif() + #set(rootmapname ${dictionary}Dict.rootmap) + #set(rootmapopts --rootmap=${rootmapname} --rootmap-lib=${libprefix}${dictionary}Dict) + #---Check GCCXML and get path----------------------------- + if(GCCXML) + get_filename_component(gccxmlpath ${GCCXML} PATH) + else() + message(WARNING "GCCXML not found. Install and setup your environment to find 'gccxml' executable") + endif() + #---Actual command---------------------------------------- + add_custom_command(OUTPUT ${gensrcdict} ${rootmapname} + COMMAND ${GENREFLEX_EXECUTABLE} ${headerfiles} -o ${gensrcdict} ${gccxmlopts} ${rootmapopts} --select=${selectionfile} + --gccxmlpath=${gccxmlpath} ${ARG_OPTIONS} ${includedirs} ${definitions} + DEPENDS ${headerfiles} ${selectionfile}) +endfunction() + diff --git a/CMake/FindReadLine.cmake b/CMake/FindReadLine.cmake new file mode 100644 index 0000000..70ec5b8 --- /dev/null +++ b/CMake/FindReadLine.cmake @@ -0,0 +1,23 @@ +# Base Io build system +# Written by Jeremy Tregunna +# +# Find libreadline. + +FIND_PATH(READLINE_INCLUDE_DIR readline/readline.h readline/history.h) + +SET(READLINE_NAMES ${READLINE_NAMES} readline libreadline history libhistory) +FIND_LIBRARY(READLINE_LIBRARY NAMES ${READLINE_NAMES} PATH) + +IF(READLINE_INCLUDE_DIR AND READLINE_LIBRARY) + SET(READLINE_FOUND TRUE) +ENDIF(READLINE_INCLUDE_DIR AND READLINE_LIBRARY) + +IF(READLINE_FOUND) + IF(NOT Readline_FIND_QUIETLY) + MESSAGE(STATUS "Found Readline: ${READLINE_LIBRARY}") + ENDIF (NOT Readline_FIND_QUIETLY) +ELSE(READLINE_FOUND) + IF(Readline_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find readline") + ENDIF(Readline_FIND_REQUIRED) +ENDIF (READLINE_FOUND) diff --git a/CMake/FindVTK.cmake b/CMake/FindVTK.cmake new file mode 100644 index 0000000..6b1772f --- /dev/null +++ b/CMake/FindVTK.cmake @@ -0,0 +1,141 @@ +# - Find a VTK installation or build tree. +# The following variables are set if VTK is found. If VTK is not +# found, VTK_FOUND is set to false. +# VTK_FOUND - Set to true when VTK is found. +# VTK_USE_FILE - CMake file to use VTK. +# VTK_MAJOR_VERSION - The VTK major version number. +# VTK_MINOR_VERSION - The VTK minor version number +# (odd non-release). +# VTK_BUILD_VERSION - The VTK patch level +# (meaningless for odd minor). +# VTK_INCLUDE_DIRS - Include directories for VTK +# VTK_LIBRARY_DIRS - Link directories for VTK libraries +# VTK_KITS - List of VTK kits, in CAPS +# (COMMON,IO,) etc. +# VTK_LANGUAGES - List of wrapped languages, in CAPS +# (TCL, PYHTON,) etc. +# The following cache entries must be set by the user to locate VTK: +# VTK_DIR - The directory containing VTKConfig.cmake. +# This is either the root of the build tree, +# or the lib/vtk directory. This is the +# only cache entry. +# The following variables are set for backward compatibility and +# should not be used in new code: +# USE_VTK_FILE - The full path to the UseVTK.cmake file. +# This is provided for backward +# compatibility. Use VTK_USE_FILE +# instead. +# + +#============================================================================= +# Copyright 2001-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# Assume not found. +SET(VTK_FOUND 0) + +# VTK 4.0 did not provide VTKConfig.cmake. +IF("${VTK_FIND_VERSION}" VERSION_LESS 4.1) + SET(_VTK_40_ALLOW 1) + IF(VTK_FIND_VERSION) + SET(_VTK_40_ONLY 1) + ENDIF() +ENDIF() + +# Construct consitent error messages for use below. +SET(VTK_DIR_DESCRIPTION "directory containing VTKConfig.cmake. This is either the root of the build tree, or PREFIX/lib/vtk for an installation.") +IF(_VTK_40_ALLOW) + SET(VTK_DIR_DESCRIPTION "${VTK_DIR_DESCRIPTION} For VTK 4.0, this is the location of UseVTK.cmake. This is either the root of the build tree or PREFIX/include/vtk for an installation.") +ENDIF() +SET(VTK_DIR_MESSAGE "VTK not found. Set the VTK_DIR cmake cache entry to the ${VTK_DIR_DESCRIPTION}") + +# Check whether VTK 4.0 has already been found. +IF(_VTK_40_ALLOW AND VTK_DIR) + IF(EXISTS ${VTK_DIR}/UseVTK.cmake AND NOT EXISTS ${VTK_DIR}/VTKConfig.cmake) + SET(VTK_FOUND 1) + INCLUDE(UseVTKConfig40) # No VTKConfig; load VTK 4.0 settings. + ENDIF() +ENDIF() + +# Use the Config mode of the find_package() command to find VTKConfig. +# If this succeeds (possibly because VTK_DIR is already set), the +# command will have already loaded VTKConfig.cmake and set VTK_FOUND. +IF(NOT _VTK_40_ONLY AND NOT VTK_FOUND) + FIND_PACKAGE(VTK QUIET NO_MODULE) +ENDIF() + +# Special search for VTK 4.0. +IF(_VTK_40_ALLOW AND NOT VTK_DIR) + # Old scripts may set these directories in the CMakeCache.txt file. + # They can tell us where to find VTKConfig.cmake. + SET(VTK_DIR_SEARCH_LEGACY "") + IF(VTK_BINARY_PATH AND USE_BUILT_VTK) + SET(VTK_DIR_SEARCH_LEGACY ${VTK_DIR_SEARCH_LEGACY} ${VTK_BINARY_PATH}) + ENDIF(VTK_BINARY_PATH AND USE_BUILT_VTK) + IF(VTK_INSTALL_PATH AND USE_INSTALLED_VTK) + SET(VTK_DIR_SEARCH_LEGACY ${VTK_DIR_SEARCH_LEGACY} + ${VTK_INSTALL_PATH}/lib/vtk) + ENDIF(VTK_INSTALL_PATH AND USE_INSTALLED_VTK) + + # Look for UseVTK.cmake in build trees or under /include/vtk. + FIND_PATH(VTK_DIR + NAMES UseVTK.cmake + PATH_SUFFIXES vtk-4.0 vtk + HINTS $ENV{VTK_DIR} + + PATHS + + # Support legacy cache files. + ${VTK_DIR_SEARCH_LEGACY} + + # Read from the CMakeSetup registry entries. It is likely that + # VTK will have been recently built. + [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild1] + [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild2] + [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild3] + [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild4] + [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild5] + [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild6] + [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild7] + [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild8] + [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild9] + [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild10] + + # Help the user find it if we cannot. + DOC "The ${VTK_DIR_DESCRIPTION}" + ) + + IF(VTK_DIR) + IF(EXISTS ${VTK_DIR}/UseVTK.cmake AND NOT EXISTS ${VTK_DIR}/VTKConfig.cmake) + SET(VTK_FOUND 1) + INCLUDE(UseVTKConfig40) # No VTKConfig; load VTK 4.0 settings. + ELSE() + # We found the wrong version. Pretend we did not find it. + SET(VTK_DIR "VTK_DIR-NOTFOUND" CACHE PATH "The ${VTK_DIR_DESCRIPTION}" FORCE) + ENDIF() + ENDIF() +ENDIF() + +#----------------------------------------------------------------------------- +IF(VTK_FOUND) + # Set USE_VTK_FILE for backward-compatability. + SET(USE_VTK_FILE ${VTK_USE_FILE}) +ELSE(VTK_FOUND) + # VTK not found, explain to the user how to specify its location. + IF(VTK_FIND_REQUIRED) + MESSAGE(FATAL_ERROR ${VTK_DIR_MESSAGE}) + ELSE(VTK_FIND_REQUIRED) + IF(NOT VTK_FIND_QUIETLY) + MESSAGE(STATUS ${VTK_DIR_MESSAGE}) + ENDIF(NOT VTK_FIND_QUIETLY) + ENDIF(VTK_FIND_REQUIRED) +ENDIF(VTK_FOUND) diff --git a/CMake/FinduLib.cmake b/CMake/FinduLib.cmake new file mode 100644 index 0000000..63470df --- /dev/null +++ b/CMake/FinduLib.cmake @@ -0,0 +1,62 @@ +# - Finds ROOT instalation +# This module sets up ROOT information +# It defines: +# ULIB_FOUND If the uLib is found +# ULIB_INCLUDE_DIRS PATH to the include directory +# ULIB_LIBRARIES Most common libraries +# ULIB_LIBRARY_DIRS PATH to the library directory +# + +include(uLibFindDependencies) +include(uLibDebugMacro) + +## CONFIG FIND -------------------------------------------------------------- ## + +set(CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}/lib/cmake") +unset(ULIB_CONFIG) +find_package(ULIB ${ULIB_PACKAGE_VERSION} CONFIG + NAMES uLib + PATH_SUFFIXES ${ULIB_PACKAGE_NAME} +) + +debug(ULIB_CONFIG) +debug(ULIB_CONSIDERED_CONFIGS) +debug(ULIB_CONSIDERED_VERSIONS) +debug(ULIB_INCLUDE_DIRS) +debug(ULIB_LIBRARIES) + +if(ULIB_CONFIG) + set(ULIB_FOUND true) +endif() + +## MODULE FIND -------------------------------------------------------------- ## + +#find_path(uLib_INCLUDE_DIR +# NAMES ulib.h +# PATH_SUFFIXES mutom-0.2 +#) +#debug(uLib_INCLUDE_DIR) + +#find_file(uLib_USE_FILE +# NAMES uLib_exported_targets.cmake +# PATHS lib lib64 +# PATH_SUFFIXES mutom-0.2 +#) +#debug(uLib_USE_FILE) + +#find_library(uLib_LIBRARY +# NAMES libmutomCore.so +# PATH_SUFFIXES mutom-0.2 +# ) +#debug(uLib_LIBRARY) + +##set( uLib_PROCESS_INCLUDES uLib_INCLUDE_DIR ULIB_INCLUDE_DIRS ) +##set( uLib_PROCESS_LIBS uLib_LIBRARY ULIB_LIBRARIES ) +##libfind_process(uLib) + +#set( ULIB_INCLUDE_DIRS ${uLib_INCLUDE_DIR} ) +#set( ULIB_LIBRARIES ${uLib_LIBRARY} ) +#include(FindPackageHandleStandardArgs) +#find_package_handle_standard_args(uLib DEFAULT_MSG +# uLib_LIBRARY uLib_INCLUDE_DIR) +#mark_as_advanced(uLib_INCLUDE_DIR uLib_LIBRARY) diff --git a/CMake/clean-all.cmake b/CMake/clean-all.cmake new file mode 100644 index 0000000..dc152af --- /dev/null +++ b/CMake/clean-all.cmake @@ -0,0 +1,11 @@ +set(cmake_generated ${CMAKE_BINARY_DIR}/CMakeCache.txt + ${CMAKE_BINARY_DIR}/cmake_install.cmake + ${CMAKE_BINARY_DIR}/Makefile + ${CMAKE_BINARY_DIR}/CMakeFiles +) + +foreach(file ${cmake_generated}) + if (EXISTS ${file}) + file(REMOVE_RECURSE ${file}) + endif() +endforeach(file) diff --git a/CMake/rmake.in b/CMake/rmake.in new file mode 100644 index 0000000..0d16648 --- /dev/null +++ b/CMake/rmake.in @@ -0,0 +1,47 @@ +#!/bin/bash + +# CONNECTION ---------------------------------------------------------------- ## +USER=@REMOTE_BUILD_USER@ +MACHINES="@REMOTE_BUILD_MACHINES@" +SSH=@REMOTE_BUILD_SSHBIN@ +PORT=@REMOTE_BUILD_SSHPORT@ + +# BUILD --------------------------------------------------------------------- ## + +MAKE=@REMOTE_BUILD_MAKEBIN@ +BUILD_DIR=@REMOTE_BUILD_BULIDIR@ +SOURCE_DIR=@REMOTE_BUILD_SRCDIR@ +CURRENT_DIR=`pwd` +ARGS=$@ + + +# FIND RELATIVE PATH -------------------------------------------------------- ## + +function relpath { +# both $1 and $2 are absolute paths +# returns $2 relative to $1 +source=$1 +target=$2 +common_part=$source +back= +while [ "${target#$common_part}" = "${target}" ]; do + common_part=$(dirname $common_part) + back="../${back}" +done +echo ${back}${target#$common_part/} +} + +CURRENT_SRCDIR=$(cd -- ${CURRENT_DIR}/$(relpath $BUILD_DIR/ $SOURCE_DIR/)/ && pwd) + + + +for m in ${MACHINES}; do + echo "building into machine: ${m}" + echo "remote commands: --------------------------------------------------------------------------------------------------------------" + echo "source dir = ${SOURCE_DIR}" + echo "build dir = ${BUILD_DIR}" + echo "repath to LOCAL MACHINE source dir = ${CURRENT_SRCDIR}" + echo "${SSH} -p ${PORT} ${USER}@${m} ${MAKE} -C ${BUILD_DIR} ${ARGS} 3>&1 1>&2 2>&3 | sed -e 's|${SOURCE_DIR}|${CURRENT_SRCDIR}|g' 3>&1 1>&2 2>&3" + echo " ------------------------------------------------------------------------------------------------------------------------------" + ${SSH} -p ${PORT} ${USER}@${m} "${MAKE} -C ${BUILD_DIR} ${ARGS} 3>&1 1>&2 2>&3 | sed -e 's|${SOURCE_DIR}|${CURRENT_SRCDIR}|g'" 3>&1 1>&2 2>&3 +done diff --git a/CMake/uLibCommon.cmake b/CMake/uLibCommon.cmake new file mode 100644 index 0000000..ad120ad --- /dev/null +++ b/CMake/uLibCommon.cmake @@ -0,0 +1,64 @@ +include(uLibMacros) +include_guard(ULIB_COMMON_CMAKE) + +include(uLibDebugMacro) + +## DIRECTORIES -------------------------------------------------------------- ## + +set(ULIB_PARENT_PATH "${PROJECT_SOURCE_DIR}") +message(STATUS "Setting uLib parent path to: ${ULIB_PARENT_PATH}") + +## Build directories ## +set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib CACHE PATH "build path for lib") +mark_as_advanced(LIBRARY_OUTPUT_PATH) +set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin CACHE PATH "build path for binaries") +mark_as_advanced(EXECUTABLE_OUTPUT_PATH) + +## Install directories ## +set(PACKAGE_INSTALL_BIN_DIR bin CACHE PATH "Installation directory for executables") +set(PACKAGE_INSTALL_LIB_DIR lib/${PACKAGE_NAME} CACHE PATH "Installation directory for libraries") +set(PACKAGE_INSTALL_INC_DIR include/${PACKAGE_NAME} CACHE PATH "Installation directory for headers") +set(PACKAGE_INSTALL_DATA_DIR share/${PACKAGE_NAME} CACHE PATH "Installation directory for data files") +if(WIN32 AND NOT CYGWIN) + set(DEF_INSTALL_CMAKE_DIR CMake) +else() + set(DEF_INSTALL_CMAKE_DIR lib/cmake/${PACKAGE_NAME}) +endif() +set(PACKAGE_INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") + +# Make relative paths absolute (needed later on) +foreach(p LIB BIN INC DATA CMAKE) + set(var PACKAGE_INSTALL_${p}_DIR) + if(NOT IS_ABSOLUTE "${${var}}") + set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") + endif() + mark_as_advanced(PACKAGE_INSTALL_${p}_DIR) + debug(PACKAGE_INSTALL_${p}_DIR) +endforeach() + +# add the binary tree to the search path for include files +# so that we will find config.h +set(SRC_DIR ${PROJECT_SOURCE_DIR}/src) +include_directories(${PROJECT_BINARY_DIR}) +include_directories(${SRC_DIR}) + + +## GLOBAL OPTIONS ----------------------------------------------------------- ## + +# Set a default build type to RELEASE WITH DEBUG INFO if none was specified +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to 'Release' as none was specified.") + set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE) + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" + "MinSizeRel" "RelWithDebInfo") +endif() + +set(CMAKE_CXX_WARNING_OPTION "" CACHE STRING "Warning level -WAll to verbose all warnings") +set(CMAKE_VERBOSE_MAKEFILE FALSE CACHE STRING "Verbose compile output switch") + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x ${CMAKE_CXX_WARNING_OPTION}") + + + + diff --git a/CMake/uLibConfigHeader.cmake b/CMake/uLibConfigHeader.cmake new file mode 100644 index 0000000..363bbe3 --- /dev/null +++ b/CMake/uLibConfigHeader.cmake @@ -0,0 +1,57 @@ +include(uLibMacros) +include_guard(ULIB_CONFIG_HEADER_CMAKE) + + +## CONFIG ------------------------------------------------------------------- ## + +message("/////////// CONFIG HEADER //////////////") + +include(CheckIncludeFiles) +include(CheckFunctionExists) +include(CheckSymbolExists) + +## force to use PP variadics (FIX) ## +set(BOOST_PP_VARIADICS ON) + +message(STATUS "PROJECT NAME = ${PROJECT_NAME}") +message(STATUS "PACKAGE VERSION = ${PACKAGE_VERSION}") +message(STATUS "PACKAGE NAME = ${PACKAGE_NAME}") +execute_process(COMMAND "svnversion" + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE SVN_REVISION + OUTPUT_STRIP_TRAILING_WHITESPACE ) + +message(STATUS "SVN REVISION = ${SVN_REVISION}") + +CHECK_INCLUDE_FILES(inittypes.h HAVE_INITTYPES_H) +CHECK_INCLUDE_FILES(stdbool.h HAVE_STDBOOL_H) +CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H) +CHECK_INCLUDE_FILES(stdlib.h HAVE_STDLIB_H) + +CHECK_INCLUDE_FILES(dlfcn.h HAVE_DLFCN_H) +CHECK_INCLUDE_FILES(malloc.h HAVE_MALLOC_H) +CHECK_FUNCTION_EXISTS(malloc HAVE_MALLOC) +CHECK_INCLUDE_FILES(memory.h HAVE_MEMORY_H) + +CHECK_INCLUDE_FILES(math.h HAVE_MATH_H) +CHECK_FUNCTION_EXISTS(fsetround HAVE_FSETROUND) +CHECK_FUNCTION_EXISTS(floor HAVE_FLOOR) +CHECK_FUNCTION_EXISTS(pow HAVE_POW) +CHECK_FUNCTION_EXISTS(sqrt HAVE_SQRT) + +CHECK_FUNCTION_EXISTS(strdup HAVE_STRDUP) +CHECK_FUNCTION_EXISTS(strstr HAVE_STRSTR) +CHECK_INCLUDE_FILES(strings.h HAVE_STRINGS_H) +CHECK_INCLUDE_FILES(string.h HAVE_STRING_H) + +CHECK_INCLUDE_FILES(sys/stat.h HAVE_SYS_STAT_H) +CHECK_INCLUDE_FILES(sys/types.h HAVE_SYS_TYPES_H) +CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H) + +CHECK_INCLUDE_FILES(assert.h HAVE_ASSERT_H) + + +configure_file( + "${PROJECT_SOURCE_DIR}/CMakeConfig.in.h" + "${PROJECT_BINARY_DIR}/config.h" + ) diff --git a/CMake/uLibDebugMacro.cmake b/CMake/uLibDebugMacro.cmake new file mode 100644 index 0000000..1529ae3 --- /dev/null +++ b/CMake/uLibDebugMacro.cmake @@ -0,0 +1,54 @@ +include(uLibMacros) +include_guard(ULIB_DEBUG_MACRO_CMAKE) + + +set(CMAKE_CONFIGURE_DEBUG_ENABLE ON CACHE BOOL "cmake configure debugger") +set(CMAKE_CONFIGURE_DEBUG_LIST OFF CACHE BOOL "cmake debugger show list enable") +mark_as_advanced( + CMAKE_CONFIGURE_DEBUG_ENABLE + CMAKE_CONFIGURE_DEBUG_LIST +) + +macro(debug str) + if(CMAKE_CONFIGURE_DEBUG_ENABLE) + set(var ${${str}}) + list(LENGTH var len) + if((${len} GREATER 1) AND CMAKE_CONFIGURE_DEBUG_LIST) + message(STATUS "[DEBUG] [${str}] list: ") + foreach(item ${var}) + message(STATUS " -> ${item}") + endforeach() + else() + message(STATUS "[DEBUG] [${str}] ${var}") + endif() + endif() +endmacro() + +macro(debug_list str) + if(CMAKE_CONFIGURE_DEBUG_ENABLE) + set(var ${${str}}) + list(LENGTH var len) + if((${len} GREATER 1)) + message(STATUS "[DEBUG] [${str}] list: ") + foreach(item ${var}) + message(STATUS " -> ${item}") + endforeach() + else() + message(STATUS "[DEBUG] [${str}] ${var}") + endif() + endif() +endmacro() + +macro(debug_package str) + if(CMAKE_CONFIGURE_DEBUG_ENABLE) + set(have ${str}_FOUND) + if(${have}) + debug("${str}_INCLUDE_DIRS") + debug("${str}_LIBRARIES") + debug("${str}_LIBRARY_DIRS") + debug("${str}_DEFINITIONS") + else(${have}) + message(WARNING "package ${str} not found") + endif(${have}) + endif(CMAKE_CONFIGURE_DEBUG_ENABLE) +endmacro() diff --git a/CMake/uLibFindDependencies.cmake b/CMake/uLibFindDependencies.cmake new file mode 100644 index 0000000..828f3ec --- /dev/null +++ b/CMake/uLibFindDependencies.cmake @@ -0,0 +1,122 @@ +include(uLibMacros) +include_guard(ULIB_FIND_DEPENDENCIES_CMAKE) + +include(uLibDebugMacro) + +################################################################################ +## PKG FIND ## +message("/////////// LOOKING FOR EXTERNAL PACKAGES //////////////") + +## BOOST ## +message(STATUS "## BOOST ##") +set(Boost_USE_STATIC_LIBS OFF) +set(Boost_USE_MULTITHREADED ON) +set(Boost_USE_STATIC_RUNTIME OFF) + +find_package(Boost 1.45.0 COMPONENTS serialization signals program_options REQUIRED) +if(Boost_FOUND) + set(HAVE_BOOST true) +endif(Boost_FOUND) +include_directories(${Boost_INCLUDE_DIRS}) + +## OPEN MP ## +message(STATUS "## OPEN MP ##") +find_package(OpenMP) +option(OpenMP_ACTIVE "Activate OpenMP parallel compilation" ON) +if(OPENMP_FOUND AND OpenMP_ACTIVE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}" ) +endif(OPENMP_FOUND AND OpenMP_ACTIVE) + +## EIGEN ## +message(STATUS "## EIGEN ##") +# option(USE_EIGEN ON) ## REQUIRED +find_package(Eigen3 REQUIRED) +debug(EIGEN3_INCLUDE_DIR) +include_directories(${EIGEN3_INCLUDE_DIR}) + +## ROOT ## +message(STATUS "## ROOT ##") +option(ULIB_USE_ROOT "Activate use of Root integration" ON) +### <<<--- ROOT IS REQUIRED FOR THE MOMENT ### +#if(ULIB_USE_ROOT) +include(FindROOTv6) +find_package(ROOT REQUIRED) +if(ROOT_FOUND) + set(HAVE_ROOT true) + include_directories(${ROOT_INCLUDE_DIR}) + link_directories(${ROOT_LIBRARY_DIR}) + debug(ROOT_INCLUDE_DIR) + debug(ROOT_LIBRARY_DIR) + debug(ROOT_LIBRARIES) +else() + message(WARNING "Root not found") +endif(ROOT_FOUND) +#endif(ULIB_USE_ROOT) + + +## VTK ## +option(ULIB_USE_VTK "Activate use of Vtk Visual Pipelines" ON) +if(ULIB_USE_VTK) + message(STATUS "## VTK ##") + message(STATUS "Looking for VTK...") + set(VTK_DIR "PATH/TO/VTK/BUILD/DIRECTORY") + mark_as_advanced(VTK_DIR) + find_package(VTK REQUIRED) + include(${VTK_USE_FILE}) + #message(STATUS "VTK included libraries: ${VTK_LIBRARIES}") + debug(VTK_USE_FILE) + debug(VTK_INCLUDE_DIRS) + debug(VTK_LIBRARY_DIRS) + debug(VTK_LIBRARIES) +# get_directory_property(compile_def COMPILE_DEFINITIONS) +# debug(compile_def) +endif(ULIB_USE_VTK) + + +## GEANT ## +option(ULIB_USE_GEANT4 "Activate use of GEANT Integration" ON) +message(STATUS "## GEANT 4 ##") +#include(FindGEANT4) # disabled using system finder +find_package(Geant4) +set(GEANT4_FOUND Geant4_DIR) +if(GEANT4_FOUND AND ULIB_USE_GEANT4) + message(STATUS "Looking for Geant4... - Geant4 found in ${Geant4_DIR}") + set(HAVE_GEANT4 true) + include_directories(${Geant4_INCLUDE_DIRS}) # Add -I type paths + add_definitions(${Geant4_DEFINITIONS}) # Add -D type defs + debug_package(Geant4) +endif(GEANT4_FOUND AND ULIB_USE_GEANT4) + +## QT4 ## +option(ULIB_USE_QT4 "Activate use of Qt Framework" ON) +if(ULIB_USE_QT4) + message(STATUS "## QT4 ##") + find_package(Qt4) +# include_directories(${Qt4_INCLUDE_DIRS}) +# debug(Qt4_INCLUDE_DIRS) +endif(ULIB_USE_QT4) + +## QT5 ## +option(ULIB_USE_QT5 "Activate use of Qt Framework" ON) +if(ULIB_USE_QT5) + message(STATUS "## QT5 ##") + find_package(Qt5Widgets) +# include_directories(${Qt5_INCLUDE_DIRS}) +# debug(Qt5_INCLUDE_DIRS) +endif(ULIB_USE_QT5) + +## READLINE ## +message(STATUS "## READLINE ##") +find_package(ReadLine) +include_directories(${READLINE_INCLUDE_DIR}) +debug(READLINE_INCLUDE_DIR) + +## STD MATH REQUIRED ## +#message(STATUS "## STD MATH ##") +set(CMAKE_REQUIRED_INCLUDES CMAKE_REQUIRED_INCLUDES math.h) +set(CMAKE_REQUIRED_LIBRARIES CMAKE_REQUIRED_LIBRARIES m) + + + +################################################################################ diff --git a/CMake/uLibGenerateRMake.cmake b/CMake/uLibGenerateRMake.cmake new file mode 100644 index 0000000..962ce0b --- /dev/null +++ b/CMake/uLibGenerateRMake.cmake @@ -0,0 +1,47 @@ + + +include(uLibMacros) +include(uLibDebugMacro) + +## MAKE REMOTE -------------------------------------------------------------- ## + +#set(BUILD_REMOTE_MACHINES "10.62.19.4" CACHE STRING "remote build in cloud machine") +#set(BUILD_REMOTE_USER "rigoni" CACHE STRING "remote build user") +#set(BUILD_REMOTE_CMD "${SSH_COMMAND} ${BUILD_REMOTE_USER}@${BUILD_REMOTE_MACHINES} \"make -C \"") +#add_custom_target(cloud COMMAND ${SSH_COMMAND}) + + + +set(REMOTE_BUILD_USER "$ENV{USER}" CACHE STRING "ssh remote build user name") + +execute_process(COMMAND hostname -I OUTPUT_VARIABLE HOSTNAME_IP) +set(REMOTE_BUILD_MACHINES ${HOSTNAME_IP} CACHE STRING "ssh remote build machines") + +find_file(SSH_EXECUTABLE ssh PATHS /bin/local/bin /usr/bin /bin) +set(REMOTE_BUILD_SSHBIN ${SSH_EXECUTABLE} CACHE FILEPATH "ssh remote build command path") +set(REMOTE_BUILD_SSHPORT 22 CACHE STRING "ssh remote build port") + +find_file(MAKE_EXECUTABLE make PATHS /usr/local/bin /usr/bin /bin) +set(REMOTE_BUILD_MAKEBIN ${MAKE_EXECUTABLE} CACHE FILEPATH "ssh remote build make path") +set(REMOTE_BUILD_BULIDIR ${PROJECT_BINARY_DIR} CACHE PATH "ssh remote build build path") +set(REMOTE_BUILD_SRCDIR ${PROJECT_SOURCE_DIR} CACHE PATH "ssh remote build source path") + +message("remote build ----------------------------------------------------------") +debug(REMOTE_BUILD_USER) +debug(REMOTE_BUILD_MACHINES) +debug(REMOTE_BUILD_SSHBIN) +debug(REMOTE_BUILD_SSHPORT) +debug(REMOTE_BUILD_MAKEBIN) +message("-----------------------------------------------------------------------") + + +find_file(RMAKE_IN_FILE rmake.in PATHS ${CMAKE_MODULE_PATH}) +configure_file( + "${RMAKE_IN_FILE}" + "${PROJECT_BINARY_DIR}/CMake/rmake" @ONLY +) + +file(COPY "${PROJECT_BINARY_DIR}/CMake/rmake" + DESTINATION "${PROJECT_BINARY_DIR}" + FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ + GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) diff --git a/CMake/uLibMacros.cmake b/CMake/uLibMacros.cmake new file mode 100644 index 0000000..608dd7c --- /dev/null +++ b/CMake/uLibMacros.cmake @@ -0,0 +1,12 @@ +#if(ULIB_MACROS_CMAKE) +# return() +#endif() +#set(ULIB_MACROS_CMAKE 1) + + +function(include_guard var) + if(${var}) + return() + endif() + set(${var} 1) +endfunction() diff --git a/CMake/uLibTargetMacros.cmake b/CMake/uLibTargetMacros.cmake new file mode 100644 index 0000000..e954758 --- /dev/null +++ b/CMake/uLibTargetMacros.cmake @@ -0,0 +1,186 @@ + +include(uLibMacros) +include_guard(ULIB_TARGET_MACRO_CMAKE) + +## adds library target +macro(uLib_add_library name) + add_library(${name} ${ARGN}) + if(NOT ULIB_INSTALL_NO_LIBRARIES) + set_property(GLOBAL APPEND PROPERTY ULIB_TARGETS ${name}) + endif(NOT ULIB_INSTALL_NO_LIBRARIES) +endmacro(uLib_add_library) + +################################################################################ +## Add SHARED library target ## + +# HEADERS and SOURCES must be defined as list of library headers and sources +macro(uLib_add_shared_library name) + if(COMMAND cmake_policy) + # cmake_policy( SET CMP0022 NEW ) + endif(COMMAND cmake_policy) + + set(mname ${PACKAGE_LIBPREFIX}${name}) + + if(SOURCES) + uLib_add_library(${mname} SHARED ${SOURCES}) + set(shared ${ULIB_SHARED_LIBRARIES}) + list(APPEND shared ${mname}) + set(ULIB_SHARED_LIBRARIES ${shared} PARENT_SCOPE) + source_group("${project_name}\\${name}" FILES ${SOURCES}) + set_target_properties(${mname} PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_SOVERSION} + INTERFACE_LINK_LIBRARIES "${LIBRARIES}" + LINK_INTERFACE_LIBRARIES "${LIBRARIES}" ## <- ok for cmake from 2.12 ? + IMPORTED_LINK_INTERFACE_LIBRARIES "${LIBRARIES}" ## <- breaks cmake after 2.11 ? +# PUBLIC_HEADER "" + ) + debug(LIBRARIES) + + install(TARGETS ${mname} + EXPORT "${PROJECT_NAME}Targets" + RUNTIME DESTINATION ${PACKAGE_INSTALL_BIN_DIR} COMPONENT bin + LIBRARY DESTINATION ${PACKAGE_INSTALL_LIB_DIR} COMPONENT lib + # PUBLIC_HEADER DESTINATION ${PACKAGE_INSTALL_INC_DIR} COMPONENT dev + ) + endif(SOURCES) + + if(HEADERS) + foreach(header ${HEADERS}) + install(FILES ${header} DESTINATION ${PACKAGE_INSTALL_INC_DIR}/${name}) + endforeach(header) + endif(HEADERS) + +endmacro(uLib_add_shared_library) + + +################################################################################ +## Add Target ## + +macro(uLib_add_target name) + debug(${name}) + add_executable(${name} ${ARGN}) + set_property(GLOBAL APPEND PROPERTY ULIB_TARGETS ${name}) + + set(exported ${ULIB_EXPORTED_TARGETS}) + list(APPEND exported ${name}) + set(ULIB_EXPORTED_TARGETS ${exported} PARENT_SCOPE) + + install(TARGETS ${name} + EXPORT "${PROJECT_NAME}Targets" + RUNTIME DESTINATION ${PACKAGE_INSTALL_BIN_DIR} COMPONENT bin + ) +ENDMACRO(uLib_add_target) + + + +################################################################################ +## TESTS ## + +# TESTS and LIBRARIES must be defined +macro(uLib_add_tests name) + foreach(tn ${TESTS}) + add_executable(${tn} EXCLUDE_FROM_ALL ${tn}.cpp) + add_test(${tn} ${PACKAGE_INSTALL_BIN_DIR}/${tn}) + + # adds dependencies to all selected modules in uLib + # foreach(module ${ULIB_SELECTED_MODULES}) + # add_dependencies(${tn} ${project_name}${module}) + # endforeach(module) + + # adds libraries dependencies + foreach(library ${LIBRARIES}) + target_link_libraries(${tn} ${library}) + endforeach(library) + + endforeach(tn) + + # custom target to compile all tests + add_custom_target(all-${name}-tests) + add_dependencies(all-${name}-tests ${TESTS}) +endmacro(uLib_add_tests name) + + +################################################################################ +## UTILS ## + +# UTILS and LIBRARIES must be defined +macro(uLib_add_utils name) + foreach(tn ${UTILS}) + add_executable(${tn} ${tn}.cpp) + install(TARGETS ${tn} RUNTIME DESTINATION bin) + + # adds dependencies to all selected modules in uLib + # foreach(module ${ULIB_SELECTED_MODULES}) + # add_dependencies(${tn} ${project_name}${module}) + # endforeach(module) + + # adds libraries dependencies + foreach(library ${LIBRARIES}) + target_link_libraries(${tn} ${library}) + endforeach(library) + + endforeach(tn) + + # custom target to compile all tests + add_custom_target(all-${name}) + add_dependencies(all-${name} ${UTILS}) + +endmacro(uLib_add_utils name) + + + + + + +function(get_gcc_compile_flags target out_flags) + string(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" name) + set(flags "${${name}} ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_COMPILER_ARG1}") + get_target_property(value ${target} COMPILE_FLAGS) + if (value) + list(APPEND flags ${value}) + endif() + get_target_property(value ${target} TYPE) + get_target_property(value ${target} COMPILE_DEFINITIONS) + if (value) + foreach(item ${value}) + list(APPEND flags "-D${item}") + endforeach() + endif() + STRING(TOUPPER "COMPILE_DEFINITIONS_${CMAKE_BUILD_TYPE}" name) + get_target_property(value ${target} ${name}) + if (value) + foreach(item ${value}) + list(APPEND flags "-D${item}") + endforeach() + endif() + get_directory_property(value DEFINITIONS) + if (value) + list(APPEND flags ${value}) + endif() + get_directory_property(value INCLUDE_DIRECTORIES) + if (value) + foreach(item ${value}) + list(APPEND flags "-I${item}") + endforeach() + endif() + set(${out_flags} ${flags} PARENT_SCOPE) +endfunction() + +function(get_gcc_link_flags target out_flags) + set(flags) + get_target_property(value ${target} LINK_FLAGS_RELEASE) + if (value) + message(STATUS "-> ${flags}") + list(APPEND flags ${value}) + endif() + get_directory_property(value LINK_DIRECTORIES) + if (value) + message(STATUS "-> ${flags}") + foreach(item ${value}) + list(APPEND flags "-L${item}") + endforeach() + endif() + message(STATUS "-> ${flags}") + set(${out_flags} ${flags} PARENT_SCOPE) +endfunction() diff --git a/CMakeConfig.in.h b/CMakeConfig.in.h new file mode 100644 index 0000000..3080ed2 --- /dev/null +++ b/CMakeConfig.in.h @@ -0,0 +1,128 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +#ifndef HAVE_CONFIG_H +#define HAVE_CONFIG_H + +/* Compiler must have variadic macros */ +//#cmakedefine BOOST_PP_VARIADICS + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ASSERT_H + +/* Defined if the requested minimum BOOST version is satisfied */ +#cmakedefine HAVE_BOOST + +/* Define to 1 if you have */ +#cmakedefine HAVE_BOOST_ARCHIVE_TEXT_OARCHIVE_HPP + +/* Define to 1 if you have */ +#cmakedefine HAVE_BOOST_ARRAY_HPP + +/* Define to 1 if you have */ +#cmakedefine HAVE_BOOST_PROGRAM_OPTIONS_HPP + +/* Define to 1 if you have */ +#cmakedefine HAVE_BOOST_SIGNAL_HPP + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DLFCN_H + +/* Define to 1 if you have the `fesetround' function. */ +#cmakedefine HAVE_FESETROUND + +/* Define to 1 if you have the `floor' function. */ +#cmakedefine HAVE_FLOOR + +/* Having Geant4 installed */ +#cmakedefine HAVE_GEANT4 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H + +/* Define if you have libreadline */ +#cmakedefine HAVE_LIBREADLINE + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#cmakedefine HAVE_MALLOC + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H + +/* Define to 1 if you have the `pow' function. */ +#cmakedefine HAVE_POW + +/* Having root installed */ +#cmakedefine HAVE_ROOT + +/* Define to 1 if you have the `sqrt' function. */ +#cmakedefine HAVE_SQRT + +/* Define to 1 if stdbool.h conforms to C99. */ +#cmakedefine HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H + +/* Define to 1 if you have the `strdup' function. */ +#cmakedefine HAVE_STRDUP + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H + +/* Define to 1 if you have the `strstr' function. */ +#cmakedefine HAVE_STRSTR + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H + +/* Define to 1 if the system has the type `_Bool'. */ +#cmakedefine HAVE__BOOL + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#cmakedefine LT_OBJDIR + +/* Define to the address where bug reports for this package should be sent. */ +#cmakedefine PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@" + +/* Define to the full name and version of this package. */ +#cmakedefine PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#cmakedefine PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#cmakedefine PACKAGE_URL "@PACKAGE_URL@" + +/* Define to the version of this package. */ +#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@" + +/* Define to 1 if you have the ANSI C header files. */ +#cmakedefine STDC_HEADERS + +/* SVN revision number */ +#cmakedefine SVN_REVISION "@SVN_REVISION@" + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +#endif // HAVE_CONFIG_H diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f571e46 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,234 @@ + +################################################################################ +##### CMAKE LISTS ############################################################## +################################################################################ + +cmake_minimum_required (VERSION 2.6) + +execute_process(COMMAND "clear") +message("//////////////////////////////////////////////////////////////////////") +message("/////////////////// CMAKE PJOJECT CONFIGURATION //////////////////////") +message("//////////////////////////////////////////////////////////////////////") + +## -------------------------------------------------------------------------- ## + +project(uLib) + +# The version number. +set(PROJECT_VERSION_MAJOR 0) +set(PROJECT_VERSION_MINOR 2) +set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") +set(PROJECT_SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") + +set(PACKAGE_VERSION ${PROJECT_VERSION}) +set(PACKAGE_NAME "mutom-${PROJECT_VERSION}" CACHE STRING "name of the package defined inside code (config.h)") +set(PACKAGE_LIBPREFIX "mutom" CACHE STRING "suffix for each library component name") +set(PACKAGE_URL "http:://mutom.pd.infn.it" CACHE STRING "url of the project") +set(PACKAGE_AUTHOR "Andrea Rigoni Garola ") + + +## MACROS ------------------------------------------------------------------- ## + +set(ULIB_CMAKE_DIR "${PROJECT_SOURCE_DIR}/CMake") +set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH}) +message(STATUS "Module path: ${CMAKE_MODULE_PATH}") + +include(uLibMacros) +include(uLibDebugMacro) +include(uLibTargetMacros) +include(uLibGenerateRMake) + + + +## GLOBALS ------------------------------------------------------------------ ## + +include(uLibCommon) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ") ## Add flags here ## + +enable_testing() + +## FIND PACKAGES ------------------------------------------------------------ ## + +include(uLibFindDependencies) + + +## CONFIG ------------------------------------------------------------------- ## + +include(uLibConfigHeader) + +## ADD LIBRARIES SUBDIRECTORIES --------------------------------------------- ## + +## select modules ## +set(ULIB_SELECTED_MODULES + ltk + Core + Math + Detectors + Root +) + +## uLib_add_shared_library puts names there +set(ULIB_SHARED_LIBRARIES) + +if(ULIB_USE_VTK) + LIST(APPEND ULIB_SELECTED_MODULES Vtk) +endif(ULIB_USE_VTK) + +## this gets ulib modules into a variable ## +function(uLib_modules result) + set(out) + foreach(module ${ULIB_SELECTED_MODULES}) + list(APPEND out ${PACKAGE_LIBPREFIX}${module}) + endforeach(module) + set(${result} "${out}" PARENT_SCOPE) +endfunction() + + +## ENTERING MODULES SUBDIRECTORIES ## +message("/////////// SELECTED MODULES //////////////") +foreach(module ${ULIB_SELECTED_MODULES}) + message(STATUS "adding module: ${module}") + set( uLib-module ${module}) + include_directories(${SRC_DIR}/${module}) + add_subdirectory(${SRC_DIR}/${module}) +endforeach(module) + +## SINGLE LIBRARY LINKING ## (work in progress ... ) +option(ULIB_SINGLELIBRARY "Link everything to a single library" OFF) +if(ULIB_SINGLELIBRARY) +# set(modgrp) +# foreach(module ${ULIB_SELECTED_MODULES}) +# set(grpn srcgrp_${module}) +# list(APPEND modgrp ${grpn}) +# endforeach(module) +# add_library(${project_name} SHARED ${srcgrp_Core}) +endif(ULIB_SINGLELIBRARY) + +## UTILITIES ## +add_subdirectory("${SRC_DIR}/utils/make_recipe") + + +## PKG CONFIG compatible file ----------------------------------------------- ## + +set(PKGCONFIG_FILE_ENABLE OFF CACHE BOOL "enable pkg-config file") +if(PKGCONFIG_FILE_ENABLE) +message("/////////// PKG-CONFIG DISTILLER //////////////") +set(PKGCONFIG_FILE_DESTDIR "/lib/pkgconfig/" CACHE PATH "destination path for pkg-config file") +set(PKGCONFIG_LIBS) + +message(STATUS "[cflags] ${CMAKE_C_FLAGS}") +message(STATUS "[cxxflags] ${CMAKE_CXX_FLAGS}") + +foreach(module ${ULIB_SHARED_LIBRARIES}) +set(PKGCONFIG_LIBS "${PKGCONFIG_LIBS} ${CMAKE_LINK_LIBRARY_FLAG}${module}") +endforeach(module) +message(STATUS "[libs] ${PKGCONFIG_LIBS}") + +set(PKGCONFIG_FLAGS) +#add_custom_target(Dummy) + +# add the executable +uLib_add_target(Dummy test.cpp) +target_link_libraries(Dummy ${PACKAGE_LIBPREFIX}Core) +target_link_libraries(Dummy ${Boost_SERIALIZATION_LIBRARY}) +target_link_libraries(Dummy ${Boost_SIGNALS_LIBRARY}) +target_link_libraries(Dummy ${Boost_PROGRAM_OPTIONS_LIBRARY}) +target_link_libraries(Dummy ${Geant4_LIBRARIES}) +target_link_libraries(Dummy ${ROOT_LIBRARIES}) +target_link_libraries(Dummy ${VTK_LIBRARIES}) + +get_gcc_compile_flags(Dummy, gcc_flags_list) +foreach(item ${gcc_flags_list}) + message(STATUS "[gcc cflags] ${item}") + set(PKGCONFIG_FLAGS "${PKGCONFIG_FLAGS} ${item}") +endforeach(item) +message(STATUS "[includes] ${PKGCONFIG_FLAGS}") + +get_gcc_link_flags(Dummy, gcc_flags_list) +foreach(item ${gcc_flags_list}) + message(STATUS "[gcc libs] ${item}") +endforeach(item) + +configure_file( + "${PROJECT_SOURCE_DIR}/CMakePkgConfig.pc.in" + "${PROJECT_BINARY_DIR}/libmutom-${PACKAGE_VERSION}.pc" + ) +INSTALL_FILES(${PKGCONFIG_FILE_DESTDIR} FILES ${PROJECT_BINARY_DIR}/libmutom-${PACKAGE_VERSION}.pc) + +message("///////////////////////////////////////////") +endif(PKGCONFIG_FILE_ENABLE) + + + + + +## INSTALLS AND EXPORTS ----------------------------------------------------- ## + +#export(PACKAGE uLib) +export(PACKAGE ULIB) +export(TARGETS ${ULIB_SHARED_LIBRARIES} ${ULIB_EXPORTED_TARGETS} + FILE "${PROJECT_BINARY_DIR}/uLibTargets.cmake" ) +#export(TARGETS ${ULIB_EXPORTED_TARGETS} +# FILE "${PROJECT_BINARY_DIR}/uLibExeTargets.cmake" ) + + +# Create the FooBarConfig.cmake and FooBarConfigVersion files +file(RELATIVE_PATH REL_INCLUDE_DIR "${PACKAGE_INSTALL_CMAKE_DIR}" + "${PACKAGE_INSTALL_INC_DIR}") +# ... for the build tree +set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}") +configure_file(uLibConfig.cmake.in + "${PROJECT_BINARY_DIR}/uLibConfig.cmake" @ONLY) +# ... for the install tree +set(CONF_INCLUDE_DIRS "\${ULIB_CMAKE_DIR}/${REL_INCLUDE_DIR}") +configure_file(uLibConfig.cmake.in + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/uLibConfig.cmake" @ONLY) +# ... for both +configure_file(uLibConfigVersion.cmake.in + "${PROJECT_BINARY_DIR}/uLibConfigVersion.cmake" @ONLY) + +# Install the FooBarConfig.cmake and FooBarConfigVersion.cmake +install(FILES + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/uLibConfig.cmake" + "${PROJECT_BINARY_DIR}/uLibConfigVersion.cmake" + DESTINATION "${PACKAGE_INSTALL_CMAKE_DIR}" COMPONENT dev) + +# Install the export set for use with the install-tree +install(EXPORT "${PROJECT_NAME}Targets" DESTINATION + "${PACKAGE_INSTALL_CMAKE_DIR}" COMPONENT dev) + +install(FILES ${PROJECT_SOURCE_DIR}/ulib.h DESTINATION ${PACKAGE_INSTALL_INC_DIR}) + + + +## dummy main executable ---------------------------------------------------- ## + +# add the executable +add_executable(Coretest test.cpp) +target_link_libraries(Coretest ${PACKAGE_LIBPREFIX}Core) +#target_link_libraries(Coretest ${Boost_SERIALIZATION_LIBRARY}) +#target_link_libraries(Coretest ${Boost_SIGNALS_LIBRARY}) +#target_link_libraries(Coretest ${Boost_PROGRAM_OPTIONS_LIBRARY}) +#target_link_libraries(Coretest ${Geant4_LIBRARIES}) +#target_link_libraries(Coretest ${ROOT_LIBRARIES}) +#target_link_libraries(Coretest ${VTK_LIBRARIES}) + +#message( "---------------------------------------------------------------------" ) +#execute_process(COMMAND +# "ls" +## "cmake --find-package -DNAME=uLib -DLANGUAGE=C -DCOMPILER_ID=GNU -DMODE=COMPILE" +# ) +#message( "---------------------------------------------------------------------" ) + +## -------------------------------------------------------------------------- ## + + +# TODO clean also subdirectories +add_custom_target(clean-cmake-files + COMMAND ${CMAKE_COMMAND} -P ${ULIB_CMAKE_DIR}/clean-all.cmake +) + + + + + diff --git a/CMakePkgConfig.pc.in b/CMakePkgConfig.pc.in new file mode 100644 index 0000000..408288f --- /dev/null +++ b/CMakePkgConfig.pc.in @@ -0,0 +1,13 @@ + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Mutom Library (INFN) +Description: Library for Muon Tomography experiments. +Url: @PACKAGE_URL@ +Version: @PACKAGE_VERSION@ +Requires: eigen3 +Libs: -L${libdir} @PKGCONFIG_LIBS@ +Cflags: @CMAKE_C_FLAGS@ @CMAKE_CXX_FLAGS@ @PKGCONFIG_INCLUDES@ diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/Common.am b/Common.am new file mode 100644 index 0000000..6c97929 --- /dev/null +++ b/Common.am @@ -0,0 +1,54 @@ + + +if DEBUG +OPT = -D_DEBUG -g3 -O0 +OPT_LD = -no-install +else +OPT = -DNDEBUG -O3 +OPT_LD = +endif + +if PARAL_MP +OPEN_MP = -fopenmp +else +OPEN_MP = +endif + + + +# fix it with proper macro expansion +EIGEN = $(EIGEN3_CFLAGS) + +# Root Flags +ROOTCFLAGS = @ROOTCFLAGS@ +ROOTLDFLAGS = -L@ROOTLIBDIR@ + +# Boost required libraries +BOOST_FLAGS = $(BOOST_SERIALIZATION_LDFLAGS) $(BOOST_SIGNALS_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LDFLAGS) +BOOST_LIBS = $(BOOST_SERIALIZATION_LIBS) $(BOOST_SIGNALS_LIBS) $(BOOST_PROGRAM_OPTIONS_LIBS) + +ULIB_INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/src/ltk + +AM_CFLAGS = $(OPT) $(OPEN_MP) +AM_CXXFLAGS = -std=c++0x $(OPT) $(OPEN_MP) $(EIGEN) $(ROOTCFLAGS) $(GEANT4CFLAGS) $(BOOST_CPPFLAGS) $(ULIB_INCLUDES) $(QT4_CFLAGS) +AM_LDFLAGS = $(OPT_LD) $(ROOTLDFLAGS) # $(BOOST_FLAGS) + +AM_LIBS_ROOT = @ROOTLIBS@ +AM_LIBS_GEANT4 = $(GEANT4LIBS) +AM_LIBS_QT4 = $(QT4_LIBS) +AM_LIBS_BOOST = $(BOOST_LIBS) + +AM_LIBS_ALL = @LIBS@ \ + @LIBADD_DL@ \ + @LIBREADLINE@ \ + $(AM_LIBS_ROOT) \ + $(AM_LIBS_BOOST) \ + $(AM_LIBS_GEANT4) \ + $(AM_LIBS_QT4) + +AM_DEFAULT_SOURCE_EXT = .cpp + + +# clean_all: +# rm -f *~ *# *.vtk *.vti *.ply +# @echo "all cleaned up!" diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..01fbe1d --- /dev/null +++ b/Makefile.am @@ -0,0 +1,52 @@ +if ENABLE_VTK +VTK_SUBDIR = src/Vtk +VTK_CONLIB = src/Vtk/libconvtk.la +endif + +SUBDIRS = src $(VTK_SUBDIR) . + +ACLOCAL_AMFLAGS = -I m4 + +include Common.am + +if ENABLE_VTK +include src/Vtk/Vtk.am +endif + + +_uLib_SOURCES = + +library_includedir = $(includedir)/libmutom-${PACKAGE_VERSION}/ +library_include_HEADERS = config.h \ + ulib.h + + +bin_PROGRAMS = test +test_LDADD = libmutom-${PACKAGE_VERSION}.la $(AM_LIBS_BOOST) $(AM_LIBS_ROOT) + +if ENABLE_VTK +bin_PROGRAMS += vtk_test +vtk_test_LDADD = libmutom-${PACKAGE_VERSION}.la $(AM_LIBS_BOOST) $(AM_LIBS_ROOT) +endif + + +##PACKAGE_MAJOR=@PACKAGE_MAJOR@ +##PACKAGE_MINOR=@PACKAGE_MINOR@ + +LIBRARY_VERSION = 1:0:0 + +CONLIBS = src/Core/libmutomcore.la \ + src/Root/libmutomroot.la \ + src/Math/libmutommath.la \ + src/Detectors/libmutomdetectors.la + + +lib_LTLIBRARIES = libmutom-0.2.la +libmutom_0_2_la_SOURCES = ${_uLib_SOURCES} +libmutom_0_2_la_LDFLAGS = -version-info $(LIBRARY_VERSION) +libmutom_0_2_la_LIBADD = $(AM_LIBS_ALL) ${CONLIBS} ${VTK_CONLIB} +###libmutom_0_2_la_LDFLAGS = -release $(PACKAGE_VERSION) -version-info $(LIBRARY_VERSION) + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libmutom-${PACKAGE_VERSION}.pc + diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..4636cd2 --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +//////////////// mugraphix ////////////////////// + diff --git a/SCRATCH.org b/SCRATCH.org new file mode 100644 index 0000000..e9e3bcb --- /dev/null +++ b/SCRATCH.org @@ -0,0 +1,14 @@ + + #+TITLE: Documento Scratch per la raccolta delle idee: + + +* IDEAS + +** TODO Uso dell __atribute__ transparent_union per l'accesso trasparente ai membri della union data in un vettore. +L'accesso union dichiarato anonimo e' incompatibile con il c99 questo potrebbe sistemare la cosa? + +** TODO Uso dell __attribute__ packed per salvare lo spazio dedicato alle union per i bitfield dei flags + + + +* ISSUES diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..c98ad8a --- /dev/null +++ b/bootstrap @@ -0,0 +1,21 @@ +#! /bin/sh + +ROOTDIR=`root-config --prefix` + +if [ -e /usr/share/aclocal/root.m4 ] +then + ROOTM4=. +elif [ -e $ROOTDIR/build/misc/root.m4 ] +then + ROOTM4=$ROOTDIR/build/misc +fi + +aclocal -I ./m4 + +autoheader + +libtoolize + +automake --add-missing --gnu + +autoconf diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..a906e6c --- /dev/null +++ b/configure.ac @@ -0,0 +1,210 @@ + +######################## +## CONFIG FILE FOR AC ## +######################## + +# M4 PREABLE + +# uLib version: +m4_define([uLib_major_version], [0]) +m4_define([uLib_minor_version], [2]) +# if the minor version number is odd, then we want debugging. Otherwise +# we only want minimal debugging support. +##m4_define([IB_debug_default], +## [m4_if(m4_eval(IB_minor_version % 2), [1], [yes])]) + + +########### INIT ####################################### +AC_INIT([MuSteel uLib],[uLib_major_version.uLib_minor_version],[andrea.rigoni@pd.infn.it]) +AM_INIT_AUTOMAKE([subdir-objects]) + +##AC_PREREQ([2.67]) +AC_CONFIG_MACRO_DIR([m4]) + + +AC_CONFIG_SRCDIR([ulib.h]) +AC_CONFIG_HEADERS([config.h]) + +# Checks for programs. +CFLAGS="" +CXXFLAGS="" +AC_PROG_CC +AC_PROG_CXX + + +######### ROOT MACROS ################################### +AC_DEFINE([HAVE_ROOT], [no], [Having root installed]) +ROOT_PATH( [5.0] , [HAVE_ROOT=1], [HAVE_ROOT=0]) +AM_CONDITIONAL(HAVE_ROOT, [test HAVE_ROOT=1]) +AS_IF([test HAVE_ROOT=1],[AC_DEFINE([HAVE_ROOT],[1],[])] ) + +AC_DEFINE([HAVE_GEANT4], [no], [Having Geant4 installed]) +GEANT4_PATH( [9.6] , [HAVE_GEANT4=1], [HAVE_GEANT4=0]) +AM_CONDITIONAL(HAVE_GEANT4, [test HAVE_GEANT4]) +AS_IF([test HAVE_GEANT4=1],[AC_DEFINE([HAVE_GEANT4],[1],[])] ) + +######### LIBTOOL ######################################## +AC_PROG_LIBTOOL +LIBADD_DL="-ldl" +AC_SUBST(LIBADD_DL) + +AC_SEARCH_LIBS([strerror],[cposix]) + +LT_INIT() +AC_SUBST([LIBTOOL_DEPS]) + + + +######### CHECKS ######################################## +# Checks for header files. +AC_CHECK_HEADERS([stdlib.h string.h assert.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_INLINE +AC_TYPE_SIZE_T + +# Checks for library functions. +AC_FUNC_MALLOC +AC_CHECK_FUNCS([fesetround floor pow sqrt strdup strstr]) + +AC_SEARCH_LIBS([strerror],[cposix]) + +# Check for BOOST Libraries +BOOST_REQUIRE([1.34]) + +BOOST_ARRAY +# BOOST_DATE_TIME +BOOST_SERIALIZATION +BOOST_SIGNALS +BOOST_PROGRAM_OPTIONS(mt-p) + + +# Check for Vtk installation +AM_OPTIONS_VTK +AM_PATH_VTK([5.0],[HAVE_VTK=1],[HAVE_VTK=0]) +# AM_CONDITIONAL([HAVE_VTK], [test HAVE_VTK=1] ) # fix? +AM_CONDITIONAL([VTK_5_x], [1]) + + +PKG_CHECK_MODULES([EIGEN3],[eigen3 >= 0.1]) + +PKG_CHECK_MODULES(QT4, [QtCore QtGui >= 4.4.0], [ + AC_PATH_PROGS(MOC, [moc-qt4 moc], moc,`eval pkg-config --variable=exec_prefix QtCore`/bin) + AC_PATH_PROG(RCC, rcc, rcc,`eval pkg-config --variable=exec_prefix QtCore`/bin) + AC_PATH_PROGS(UIC, [uic-qt4 uic], uic,`eval pkg-config --variable=exec_prefix QtCore`/bin) +],[HAVE_QT=0]) + + +########## CONDITIONALS ################################## + + +# Configure script arguments +dnl declare --enable-* args and collect ac_help strings +AC_ARG_ENABLE(debug, + AS_HELP_STRING([--enable-debug=no/yes],[turn on debugging, default: no]), +[case "${enableval}" in + yes) debug=true ;; + no) debug=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;; +esac], + [debug=false]) + +AC_ARG_ENABLE(parallel, + AS_HELP_STRING([--enable-parallel=no/yes],[turn on openMP parallel processing, default: yes]), +[case "${enableval}" in + yes) parallel=true ;; + no) parallel=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-parallel]) ;; +esac], + [parallel=true]) + +AC_ARG_ENABLE(autovector, + AS_HELP_STRING([--enable-autovector=no/yes],[turn on gcc auto vectorize loops with simd instructions, default: no]), +[case "${enableval}" in + yes) autovector=true ;; + no) autovector=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-autovector]) ;; +esac], + [autovector=false]) + +AC_ARG_ENABLE(vtk, + AS_HELP_STRING([--enable-vtk=no/yes],[turn on vtk visualization wrappers, default: no]), +[case "${enableval}" in + yes) vtk=true ;; + no) vtk=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-vtk]) ;; +esac], + [vtk=false]) + + +AC_ARG_WITH([readline], +[AS_HELP_STRING([--with-readline], +[support fancy command line editing @<:@default=check@:>@])], +[], +[with_readline=check]) + +LIBREADLINE= +AS_IF([test "x$with_readline" != xno], +[AC_CHECK_LIB([readline], [main], +[AC_SUBST([LIBREADLINE], ["-lreadline -lncurses"]) +AC_DEFINE([HAVE_LIBREADLINE], [1], +[Define if you have libreadline]) +], +[if test "x$with_readline" != xcheck; then +AC_MSG_FAILURE( +[--with-readline was given, but test for readline failed]) +fi +], -lncurses)]) + +AM_CONDITIONAL(DEBUG, test x"$debug" = x"true") +AM_CONDITIONAL(PARAL_MP, test x"$parallel" = x"true") +AM_CONDITIONAL(SIMD_AUTOVECTOR, test x"$autovector" = x"true") +AM_CONDITIONAL(ENABLE_VTK, [test x"$vtk" = x"true"]) + + +SVN_REVISION=`svnversion .` +AC_SUBST(SVN_REVISION) +AC_DEFINE_UNQUOTED(SVN_REVISION,"$SVN_REVISION",[SVN revision number]) + +# Forcing variadic macro compiler feature (for gcc without cxx11 flag) +AC_DEFINE_UNQUOTED(BOOST_PP_VARIADICS,1,[Compiler must have variadic macros]) + + + +######### MAKEFILES ######################################### + + +AC_CONFIG_FILES([ + Makefile + src/Makefile + src/ltk/Makefile + src/ltk/testing/Makefile + src/Core/Makefile + src/Core/testing/Makefile + src/Core/testing/ObjectMock/Makefile + src/Core/testing/SignalMock/Makefile + src/Core/testing/SerializeMock/Makefile + src/Root/Makefile + src/Root/testing/Makefile + src/Math/Makefile + src/Math/testing/Makefile + src/Detectors/Makefile + src/Detectors/testing/Makefile + src/ParticlePhysics/MuonTomography/Makefile + src/ParticlePhysics/Geant/Makefile + src/Vtk/Makefile + src/Vtk/testing/Makefile + src/Gui/Qt/QVTKViewport2/Makefile + tmp/BuildTruck/Makefile + libmutom-0.2.pc + ]) +AC_OUTPUT + +# src/Vtk/Math/Makefile +# src/Vtk/Math/testing/Makefile +# src/Vtk/Detectors/Makefile +# src/Vtk/Detectors/testing/Makefile +# src/Vtk/ParticlePhysics/MuonTomography/Makefile +# src/Vtk/ParticlePhysics/Geant/Makefile + diff --git a/libmutom-0.2.pc.in b/libmutom-0.2.pc.in new file mode 100644 index 0000000..179a4f3 --- /dev/null +++ b/libmutom-0.2.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Mutom Library (INFN) +Description: Library for Muon Tomography experiments. +Requires: eigen3 +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lmutom-0.2 -lboost_program_options +Cflags: -I${includedir}/libmutom-@PACKAGE_VERSION@ -I${libdir}/libmutom-@PACKAGE_VERSION@/include diff --git a/m4/boost.m4 b/m4/boost.m4 new file mode 100644 index 0000000..35df3f7 --- /dev/null +++ b/m4/boost.m4 @@ -0,0 +1,1186 @@ +# boost.m4: Locate Boost headers and libraries for autoconf-based projects. +# Copyright (C) 2007, 2008, 2009, 2010, 2011 Benoit Sigoure +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Additional permission under section 7 of the GNU General Public +# License, version 3 ("GPLv3"): +# +# If you convey this file as part of a work that contains a +# configuration script generated by Autoconf, you may do so under +# terms of your choice. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +m4_define([_BOOST_SERIAL], [m4_translit([ +# serial 16 +], [# +], [])]) + +# Original sources can be found at http://github.com/tsuna/boost.m4 +# You can fetch the latest version of the script by doing: +# wget http://github.com/tsuna/boost.m4/raw/master/build-aux/boost.m4 + +# ------ # +# README # +# ------ # + +# This file provides several macros to use the various Boost libraries. +# The first macro is BOOST_REQUIRE. It will simply check if it's possible to +# find the Boost headers of a given (optional) minimum version and it will +# define BOOST_CPPFLAGS accordingly. It will add an option --with-boost to +# your configure so that users can specify non standard locations. +# If the user's environment contains BOOST_ROOT and --with-boost was not +# specified, --with-boost=$BOOST_ROOT is implicitly used. +# For more README and documentation, go to http://github.com/tsuna/boost.m4 +# Note: THESE MACROS ASSUME THAT YOU USE LIBTOOL. If you don't, don't worry, +# simply read the README, it will show you what to do step by step. + +m4_pattern_forbid([^_?(BOOST|Boost)_]) + + +# _BOOST_SED_CPP(SED-PROGRAM, PROGRAM, +# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# -------------------------------------------------------- +# Same as AC_EGREP_CPP, but leave the result in conftest.i. +# +# SED-PROGRAM is *not* overquoted, as in AC_EGREP_CPP. It is expanded +# in double-quotes, so escape your double quotes. +# +# It could be useful to turn this into a macro which extracts the +# value of any macro. +m4_define([_BOOST_SED_CPP], +[AC_LANG_PREPROC_REQUIRE()dnl +AC_REQUIRE([AC_PROG_SED])dnl +AC_LANG_CONFTEST([AC_LANG_SOURCE([[$2]])]) +AS_IF([dnl eval is necessary to expand ac_cpp. +dnl Ultrix and Pyramid sh refuse to redirect output of eval, so use subshell. +dnl Beware of Windows end-of-lines, for instance if we are running +dnl some Windows programs under Wine. In that case, boost/version.hpp +dnl is certainly using "\r\n", but the regular Unix shell will only +dnl strip `\n' with backquotes, not the `\r'. This results in +dnl boost_cv_lib_version='1_37\r' for instance, which breaks +dnl everything else. +dnl Cannot use 'dnl' after [$4] because a trailing dnl may break AC_CACHE_CHECK +(eval "$ac_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | + tr -d '\r' | + $SED -n -e "$1" >conftest.i 2>&1], + [$3], + [$4]) +rm -rf conftest* +])# AC_EGREP_CPP + + + +# BOOST_REQUIRE([VERSION], [ACTION-IF-NOT-FOUND]) +# ----------------------------------------------- +# Look for Boost. If version is given, it must either be a literal of the form +# "X.Y.Z" where X, Y and Z are integers (the ".Z" part being optional) or a +# variable "$var". +# Defines the value BOOST_CPPFLAGS. This macro only checks for headers with +# the required version, it does not check for any of the Boost libraries. +# On # success, defines HAVE_BOOST. On failure, calls the optional +# ACTION-IF-NOT-FOUND action if one was supplied. +# Otherwise aborts with an error message. +AC_DEFUN([BOOST_REQUIRE], +[AC_REQUIRE([AC_PROG_CXX])dnl +AC_REQUIRE([AC_PROG_GREP])dnl +echo "$as_me: this is boost.m4[]_BOOST_SERIAL" >&AS_MESSAGE_LOG_FD +boost_save_IFS=$IFS +boost_version_req=$1 +IFS=. +set x $boost_version_req 0 0 0 +IFS=$boost_save_IFS +shift +boost_version_req=`expr "$[1]" '*' 100000 + "$[2]" '*' 100 + "$[3]"` +boost_version_req_string=$[1].$[2].$[3] +AC_ARG_WITH([boost], + [AS_HELP_STRING([--with-boost=DIR], + [prefix of Boost $1 @<:@guess@:>@])])dnl +AC_ARG_VAR([BOOST_ROOT],[Location of Boost installation])dnl +# If BOOST_ROOT is set and the user has not provided a value to +# --with-boost, then treat BOOST_ROOT as if it the user supplied it. +if test x"$BOOST_ROOT" != x; then + if test x"$with_boost" = x; then + AC_MSG_NOTICE([Detected BOOST_ROOT; continuing with --with-boost=$BOOST_ROOT]) + with_boost=$BOOST_ROOT + else + AC_MSG_NOTICE([Detected BOOST_ROOT=$BOOST_ROOT, but overridden by --with-boost=$with_boost]) + fi +fi +AC_SUBST([DISTCHECK_CONFIGURE_FLAGS], + ["$DISTCHECK_CONFIGURE_FLAGS '--with-boost=$with_boost'"])dnl +boost_save_CPPFLAGS=$CPPFLAGS + AC_CACHE_CHECK([for Boost headers version >= $boost_version_req_string], + [boost_cv_inc_path], + [boost_cv_inc_path=no +AC_LANG_PUSH([C++])dnl +m4_pattern_allow([^BOOST_VERSION$])dnl + AC_LANG_CONFTEST([AC_LANG_PROGRAM([[#include +#if !defined BOOST_VERSION +# error BOOST_VERSION is not defined +#elif BOOST_VERSION < $boost_version_req +# error Boost headers version < $boost_version_req +#endif +]])]) + # If the user provided a value to --with-boost, use it and only it. + case $with_boost in #( + ''|yes) set x '' /opt/local/include /usr/local/include /opt/include \ + /usr/include C:/Boost/include;; #( + *) set x "$with_boost/include" "$with_boost";; + esac + shift + for boost_dir + do + # Without --layout=system, Boost (or at least some versions) installs + # itself in /include/boost-. This inner loop helps to + # find headers in such directories. + # + # Any ${boost_dir}/boost-x_xx directories are searched in reverse version + # order followed by ${boost_dir}. The final '.' is a sentinel for + # searching $boost_dir" itself. Entries are whitespace separated. + # + # I didn't indent this loop on purpose (to avoid over-indented code) + boost_layout_system_search_list=`cd "$boost_dir" 2>/dev/null \ + && ls -1 | "${GREP}" '^boost-' | sort -rn -t- -k2 \ + && echo .` + for boost_inc in $boost_layout_system_search_list + do + if test x"$boost_inc" != x.; then + boost_inc="$boost_dir/$boost_inc" + else + boost_inc="$boost_dir" # Uses sentinel in boost_layout_system_search_list + fi + if test x"$boost_inc" != x; then + # We are going to check whether the version of Boost installed + # in $boost_inc is usable by running a compilation that + # #includes it. But if we pass a -I/some/path in which Boost + # is not installed, the compiler will just skip this -I and + # use other locations (either from CPPFLAGS, or from its list + # of system include directories). As a result we would use + # header installed on the machine instead of the /some/path + # specified by the user. So in that precise case (trying + # $boost_inc), make sure the version.hpp exists. + # + # Use test -e as there can be symlinks. + test -e "$boost_inc/boost/version.hpp" || continue + CPPFLAGS="$CPPFLAGS -I$boost_inc" + fi + AC_COMPILE_IFELSE([], [boost_cv_inc_path=yes], [boost_cv_version=no]) + if test x"$boost_cv_inc_path" = xyes; then + if test x"$boost_inc" != x; then + boost_cv_inc_path=$boost_inc + fi + break 2 + fi + done + done +AC_LANG_POP([C++])dnl + ]) + case $boost_cv_inc_path in #( + no) + boost_errmsg="cannot find Boost headers version >= $boost_version_req_string" + m4_if([$2], [], [AC_MSG_ERROR([$boost_errmsg])], + [AC_MSG_NOTICE([$boost_errmsg])]) + $2 + ;;#( + yes) + BOOST_CPPFLAGS= + ;;#( + *) + AC_SUBST([BOOST_CPPFLAGS], ["-I$boost_cv_inc_path"])dnl + ;; + esac + if test x"$boost_cv_inc_path" != xno; then + AC_DEFINE([HAVE_BOOST], [1], + [Defined if the requested minimum BOOST version is satisfied]) + AC_CACHE_CHECK([for Boost's header version], + [boost_cv_lib_version], + [m4_pattern_allow([^BOOST_LIB_VERSION$])dnl + _BOOST_SED_CPP([/^boost-lib-version = /{s///;s/\"//g;p;q;}], + [#include +boost-lib-version = BOOST_LIB_VERSION], + [boost_cv_lib_version=`cat conftest.i`])]) + # e.g. "134" for 1_34_1 or "135" for 1_35 + boost_major_version=`echo "$boost_cv_lib_version" | sed 's/_//;s/_.*//'` + case $boost_major_version in #( + '' | *[[!0-9]]*) + AC_MSG_ERROR([invalid value: boost_major_version=$boost_major_version]) + ;; + esac +fi +CPPFLAGS=$boost_save_CPPFLAGS +])# BOOST_REQUIRE + +# BOOST_STATIC() +# -------------- +# Add the "--enable-static-boost" configure argument. If this argument is given +# on the command line, static versions of the libraries will be looked up. +AC_DEFUN([BOOST_STATIC], + [AC_ARG_ENABLE([static-boost], + [AS_HELP_STRING([--enable-static-boost], + [Prefer the static boost libraries over the shared ones [no]])], + [enable_static_boost=yes], + [enable_static_boost=no])])# BOOST_STATIC + +# BOOST_FIND_HEADER([HEADER-NAME], [ACTION-IF-NOT-FOUND], [ACTION-IF-FOUND]) +# -------------------------------------------------------------------------- +# Wrapper around AC_CHECK_HEADER for Boost headers. Useful to check for +# some parts of the Boost library which are only made of headers and don't +# require linking (such as Boost.Foreach). +# +# Default ACTION-IF-NOT-FOUND: Fail with a fatal error unless Boost couldn't be +# found in the first place, in which case by default a notice is issued to the +# user. Presumably if we haven't died already it's because it's OK to not have +# Boost, which is why only a notice is issued instead of a hard error. +# +# Default ACTION-IF-FOUND: define the preprocessor symbol HAVE_ in +# case of success # (where HEADER-NAME is written LIKE_THIS, e.g., +# HAVE_BOOST_FOREACH_HPP). +AC_DEFUN([BOOST_FIND_HEADER], +[AC_REQUIRE([BOOST_REQUIRE])dnl +if test x"$boost_cv_inc_path" = xno; then + m4_default([$2], [AC_MSG_NOTICE([Boost not available, not searching for $1])]) +else +AC_LANG_PUSH([C++])dnl +boost_save_CPPFLAGS=$CPPFLAGS +CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" +AC_CHECK_HEADER([$1], + [m4_default([$3], [AC_DEFINE(AS_TR_CPP([HAVE_$1]), [1], + [Define to 1 if you have <$1>])])], + [m4_default([$2], [AC_MSG_ERROR([cannot find $1])])]) +CPPFLAGS=$boost_save_CPPFLAGS +AC_LANG_POP([C++])dnl +fi +])# BOOST_FIND_HEADER + + +# BOOST_FIND_LIB([LIB-NAME], [PREFERRED-RT-OPT], [HEADER-NAME], [CXX-TEST], +# [CXX-PROLOGUE]) +# ------------------------------------------------------------------------- +# Look for the Boost library LIB-NAME (e.g., LIB-NAME = `thread', for +# libboost_thread). Check that HEADER-NAME works and check that +# libboost_LIB-NAME can link with the code CXX-TEST. The optional argument +# CXX-PROLOGUE can be used to include some C++ code before the `main' +# function. +# +# Invokes BOOST_FIND_HEADER([HEADER-NAME]) (see above). +# +# Boost libraries typically come compiled with several flavors (with different +# runtime options) so PREFERRED-RT-OPT is the preferred suffix. A suffix is one +# or more of the following letters: sgdpn (in that order). s = static +# runtime, d = debug build, g = debug/diagnostic runtime, p = STLPort build, +# n = (unsure) STLPort build without iostreams from STLPort (it looks like `n' +# must always be used along with `p'). Additionally, PREFERRED-RT-OPT can +# start with `mt-' to indicate that there is a preference for multi-thread +# builds. Some sample values for PREFERRED-RT-OPT: (nothing), mt, d, mt-d, gdp +# ... If you want to make sure you have a specific version of Boost +# (eg, >= 1.33) you *must* invoke BOOST_REQUIRE before this macro. +AC_DEFUN([BOOST_FIND_LIB], +[AC_REQUIRE([BOOST_REQUIRE])dnl +AC_REQUIRE([_BOOST_FIND_COMPILER_TAG])dnl +AC_REQUIRE([BOOST_STATIC])dnl +AC_REQUIRE([_BOOST_GUESS_WHETHER_TO_USE_MT])dnl +if test x"$boost_cv_inc_path" = xno; then + AC_MSG_NOTICE([Boost not available, not searching for the Boost $1 library]) +else +dnl The else branch is huge and wasn't intended on purpose. +AC_LANG_PUSH([C++])dnl +AS_VAR_PUSHDEF([Boost_lib], [boost_cv_lib_$1])dnl +AS_VAR_PUSHDEF([Boost_lib_LDFLAGS], [boost_cv_lib_$1_LDFLAGS])dnl +AS_VAR_PUSHDEF([Boost_lib_LDPATH], [boost_cv_lib_$1_LDPATH])dnl +AS_VAR_PUSHDEF([Boost_lib_LIBS], [boost_cv_lib_$1_LIBS])dnl +BOOST_FIND_HEADER([$3]) +boost_save_CPPFLAGS=$CPPFLAGS +CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" +# Now let's try to find the library. The algorithm is as follows: first look +# for a given library name according to the user's PREFERRED-RT-OPT. For each +# library name, we prefer to use the ones that carry the tag (toolset name). +# Each library is searched through the various standard paths were Boost is +# usually installed. If we can't find the standard variants, we try to +# enforce -mt (for instance on MacOSX, libboost_threads.dylib doesn't exist +# but there's -obviously- libboost_threads-mt.dylib). +AC_CACHE_CHECK([for the Boost $1 library], [Boost_lib], + [Boost_lib=no + case "$2" in #( + mt | mt-) boost_mt=-mt; boost_rtopt=;; #( + mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X$2" : 'Xmt-*\(.*\)'`;; #( + *) boost_mt=; boost_rtopt=$2;; + esac + if test $enable_static_boost = yes; then + boost_rtopt="s$boost_rtopt" + fi + # Find the proper debug variant depending on what we've been asked to find. + case $boost_rtopt in #( + *d*) boost_rt_d=$boost_rtopt;; #( + *[[sgpn]]*) # Insert the `d' at the right place (in between `sg' and `pn') + boost_rt_d=`echo "$boost_rtopt" | sed 's/\(s*g*\)\(p*n*\)/\1\2/'`;; #( + *) boost_rt_d='-d';; + esac + # If the PREFERRED-RT-OPT are not empty, prepend a `-'. + test -n "$boost_rtopt" && boost_rtopt="-$boost_rtopt" + $boost_guess_use_mt && boost_mt=-mt + # Look for the abs path the static archive. + # $libext is computed by Libtool but let's make sure it's non empty. + test -z "$libext" && + AC_MSG_ERROR([the libext variable is empty, did you invoke Libtool?]) + boost_save_ac_objext=$ac_objext + # Generate the test file. + AC_LANG_CONFTEST([AC_LANG_PROGRAM([#include <$3> +$5], [$4])]) +dnl Optimization hacks: compiling C++ is slow, especially with Boost. What +dnl we're trying to do here is guess the right combination of link flags +dnl (LIBS / LDFLAGS) to use a given library. This can take several +dnl iterations before it succeeds and is thus *very* slow. So what we do +dnl instead is that we compile the code first (and thus get an object file, +dnl typically conftest.o). Then we try various combinations of link flags +dnl until we succeed to link conftest.o in an executable. The problem is +dnl that the various TRY_LINK / COMPILE_IFELSE macros of Autoconf always +dnl remove all the temporary files including conftest.o. So the trick here +dnl is to temporarily change the value of ac_objext so that conftest.o is +dnl preserved accross tests. This is obviously fragile and I will burn in +dnl hell for not respecting Autoconf's documented interfaces, but in the +dnl mean time, it optimizes the macro by a factor of 5 to 30. +dnl Another small optimization: the first argument of AC_COMPILE_IFELSE left +dnl empty because the test file is generated only once above (before we +dnl start the for loops). + AC_COMPILE_IFELSE([], + [ac_objext=do_not_rm_me_plz], + [AC_MSG_ERROR([cannot compile a test that uses Boost $1])]) + ac_objext=$boost_save_ac_objext + boost_failed_libs= +# Don't bother to ident the 6 nested for loops, only the 2 innermost ones +# matter. +for boost_tag_ in -$boost_cv_lib_tag ''; do +for boost_ver_ in -$boost_cv_lib_version ''; do +for boost_mt_ in $boost_mt -mt ''; do +for boost_rtopt_ in $boost_rtopt '' -d; do + for boost_lib in \ + boost_$1$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ + boost_$1$boost_tag_$boost_rtopt_$boost_ver_ \ + boost_$1$boost_tag_$boost_mt_$boost_ver_ \ + boost_$1$boost_tag_$boost_ver_ + do + # Avoid testing twice the same lib + case $boost_failed_libs in #( + *@$boost_lib@*) continue;; + esac + # If with_boost is empty, we'll search in /lib first, which is not quite + # right so instead we'll try to a location based on where the headers are. + boost_tmp_lib=$with_boost + test x"$with_boost" = x && boost_tmp_lib=${boost_cv_inc_path%/include} + for boost_ldpath in "$boost_tmp_lib/lib" '' \ + /opt/local/lib* /usr/local/lib* /opt/lib* /usr/lib* \ + "$with_boost" C:/Boost/lib /lib* + do + test -e "$boost_ldpath" || continue + boost_save_LDFLAGS=$LDFLAGS + # Are we looking for a static library? + case $boost_ldpath:$boost_rtopt_ in #( + *?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) + Boost_lib_LIBS="$boost_ldpath/lib$boost_lib.$libext" + test -e "$Boost_lib_LIBS" || continue;; #( + *) # No: use -lboost_foo to find the shared library. + Boost_lib_LIBS="-l$boost_lib";; + esac + boost_save_LIBS=$LIBS + LIBS="$Boost_lib_LIBS $LIBS" + test x"$boost_ldpath" != x && LDFLAGS="$LDFLAGS -L$boost_ldpath" +dnl First argument of AC_LINK_IFELSE left empty because the test file is +dnl generated only once above (before we start the for loops). + _BOOST_AC_LINK_IFELSE([], + [Boost_lib=yes], [Boost_lib=no]) + ac_objext=$boost_save_ac_objext + LDFLAGS=$boost_save_LDFLAGS + LIBS=$boost_save_LIBS + if test x"$Boost_lib" = xyes; then + Boost_lib_LDFLAGS="-L$boost_ldpath -Wl,-R$boost_ldpath" + Boost_lib_LDPATH="$boost_ldpath" + break 6 + else + boost_failed_libs="$boost_failed_libs@$boost_lib@" + fi + done + done +done +done +done +done +rm -f conftest.$ac_objext +]) +case $Boost_lib in #( + no) _AC_MSG_LOG_CONFTEST + AC_MSG_ERROR([cannot find the flags to link with Boost $1]) + ;; +esac +AC_SUBST(AS_TR_CPP([BOOST_$1_LDFLAGS]), [$Boost_lib_LDFLAGS])dnl +AC_SUBST(AS_TR_CPP([BOOST_$1_LDPATH]), [$Boost_lib_LDPATH])dnl +AC_SUBST([BOOST_LDPATH], [$Boost_lib_LDPATH])dnl +AC_SUBST(AS_TR_CPP([BOOST_$1_LIBS]), [$Boost_lib_LIBS])dnl +CPPFLAGS=$boost_save_CPPFLAGS +AS_VAR_POPDEF([Boost_lib])dnl +AS_VAR_POPDEF([Boost_lib_LDFLAGS])dnl +AS_VAR_POPDEF([Boost_lib_LDPATH])dnl +AS_VAR_POPDEF([Boost_lib_LIBS])dnl +AC_LANG_POP([C++])dnl +fi +])# BOOST_FIND_LIB + + +# --------------------------------------- # +# Checks for the various Boost libraries. # +# --------------------------------------- # + +# List of boost libraries: http://www.boost.org/libs/libraries.htm +# The page http://beta.boost.org/doc/libs is useful: it gives the first release +# version of each library (among other things). + +# BOOST_DEFUN(LIBRARY, CODE) +# -------------------------- +# Define BOOST_ as a macro that runs CODE. +# +# Use indir to avoid the warning on underquoted macro name given to AC_DEFUN. +m4_define([BOOST_DEFUN], +[m4_indir([AC_DEFUN], + m4_toupper([BOOST_$1]), +[m4_pushdef([BOOST_Library], [$1])dnl +$2 +m4_popdef([BOOST_Library])dnl +]) +]) + +# BOOST_ARRAY() +# ------------- +# Look for Boost.Array +BOOST_DEFUN([Array], +[BOOST_FIND_HEADER([boost/array.hpp])]) + + +# BOOST_ASIO() +# ------------ +# Look for Boost.Asio (new in Boost 1.35). +BOOST_DEFUN([Asio], +[AC_REQUIRE([BOOST_SYSTEM])dnl +BOOST_FIND_HEADER([boost/asio.hpp])]) + + +# BOOST_BIND() +# ------------ +# Look for Boost.Bind +BOOST_DEFUN([Bind], +[BOOST_FIND_HEADER([boost/bind.hpp])]) + + +# BOOST_CHRONO() +# ------------------ +# Look for Boost.Chrono +BOOST_DEFUN([Chrono], +[# Do we have to check for Boost.System? This link-time dependency was +# added as of 1.35.0. If we have a version <1.35, we must not attempt to +# find Boost.System as it didn't exist by then. +if test $boost_major_version -ge 135; then +BOOST_SYSTEM([$1]) +fi # end of the Boost.System check. +boost_filesystem_save_LIBS=$LIBS +boost_filesystem_save_LDFLAGS=$LDFLAGS +m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl +LIBS="$LIBS $BOOST_SYSTEM_LIBS" +LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" +BOOST_FIND_LIB([chrono], [$1], + [boost/chrono.hpp], + [boost::chrono::thread_clock d;]) +if test $enable_static_boost = yes && test $boost_major_version -ge 135; then + AC_SUBST([BOOST_FILESYSTEM_LIBS], ["$BOOST_FILESYSTEM_LIBS $BOOST_SYSTEM_LIBS"]) +fi +LIBS=$boost_filesystem_save_LIBS +LDFLAGS=$boost_filesystem_save_LDFLAGS + +])# BOOST_CHRONO + + +# BOOST_CONVERSION() +# ------------------ +# Look for Boost.Conversion (cast / lexical_cast) +BOOST_DEFUN([Conversion], +[BOOST_FIND_HEADER([boost/cast.hpp]) +BOOST_FIND_HEADER([boost/lexical_cast.hpp]) +])# BOOST_CONVERSION + + +# BOOST_DATE_TIME([PREFERRED-RT-OPT]) +# ----------------------------------- +# Look for Boost.Date_Time. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Date_Time], +[BOOST_FIND_LIB([date_time], [$1], + [boost/date_time/posix_time/posix_time.hpp], + [boost::posix_time::ptime t;]) +])# BOOST_DATE_TIME + + +# BOOST_FILESYSTEM([PREFERRED-RT-OPT]) +# ------------------------------------ +# Look for Boost.Filesystem. For the documentation of PREFERRED-RT-OPT, see +# the documentation of BOOST_FIND_LIB above. +# Do not check for boost/filesystem.hpp because this file was introduced in +# 1.34. +BOOST_DEFUN([Filesystem], +[# Do we have to check for Boost.System? This link-time dependency was +# added as of 1.35.0. If we have a version <1.35, we must not attempt to +# find Boost.System as it didn't exist by then. +if test $boost_major_version -ge 135; then +BOOST_SYSTEM([$1]) +fi # end of the Boost.System check. +boost_filesystem_save_LIBS=$LIBS +boost_filesystem_save_LDFLAGS=$LDFLAGS +m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl +LIBS="$LIBS $BOOST_SYSTEM_LIBS" +LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" +BOOST_FIND_LIB([filesystem], [$1], + [boost/filesystem/path.hpp], [boost::filesystem::path p;]) +if test $enable_static_boost = yes && test $boost_major_version -ge 135; then + AC_SUBST([BOOST_FILESYSTEM_LIBS], ["$BOOST_FILESYSTEM_LIBS $BOOST_SYSTEM_LIBS"]) +fi +LIBS=$boost_filesystem_save_LIBS +LDFLAGS=$boost_filesystem_save_LDFLAGS +])# BOOST_FILESYSTEM + + +# BOOST_FOREACH() +# --------------- +# Look for Boost.Foreach +BOOST_DEFUN([Foreach], +[BOOST_FIND_HEADER([boost/foreach.hpp])]) + + +# BOOST_FORMAT() +# -------------- +# Look for Boost.Format +# Note: we can't check for boost/format/format_fwd.hpp because the header isn't +# standalone. It can't be compiled because it triggers the following error: +# boost/format/detail/config_macros.hpp:88: error: 'locale' in namespace 'std' +# does not name a type +BOOST_DEFUN([Format], +[BOOST_FIND_HEADER([boost/format.hpp])]) + + +# BOOST_FUNCTION() +# ---------------- +# Look for Boost.Function +BOOST_DEFUN([Function], +[BOOST_FIND_HEADER([boost/function.hpp])]) + + +# BOOST_GRAPH([PREFERRED-RT-OPT]) +# ------------------------------- +# Look for Boost.Graphs. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Graph], +[BOOST_FIND_LIB([graph], [$1], + [boost/graph/adjacency_list.hpp], [boost::adjacency_list<> g;]) +])# BOOST_GRAPH + + +# BOOST_IOSTREAMS([PREFERRED-RT-OPT]) +# ----------------------------------- +# Look for Boost.IOStreams. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([IOStreams], +[BOOST_FIND_LIB([iostreams], [$1], + [boost/iostreams/device/file_descriptor.hpp], + [boost::iostreams::file_descriptor fd; fd.close();]) +])# BOOST_IOSTREAMS + + +# BOOST_HASH() +# ------------ +# Look for Boost.Functional/Hash +BOOST_DEFUN([Hash], +[BOOST_FIND_HEADER([boost/functional/hash.hpp])]) + + +# BOOST_LAMBDA() +# -------------- +# Look for Boost.Lambda +BOOST_DEFUN([Lambda], +[BOOST_FIND_HEADER([boost/lambda/lambda.hpp])]) + + +# BOOST_LOG([PREFERRED-RT-OPT]) +# ----------------------------- +# Look for Boost.Log For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Log], +[BOOST_FIND_LIB([log], [$1], + [boost/log/core/core.hpp], + [boost::log::attribute a; a.get_value();]) +])# BOOST_LOG + + +# BOOST_LOG_SETUP([PREFERRED-RT-OPT]) +# ----------------------------------- +# Look for Boost.Log For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Log_Setup], +[AC_REQUIRE([BOOST_LOG])dnl +BOOST_FIND_LIB([log_setup], [$1], + [boost/log/utility/init/from_settings.hpp], + [boost::log::basic_settings bs; bs.empty();]) +])# BOOST_LOG_SETUP + + +# BOOST_MATH() +# ------------ +# Look for Boost.Math +# TODO: This library isn't header-only but it comes in multiple different +# flavors that don't play well with BOOST_FIND_LIB (e.g, libboost_math_c99, +# libboost_math_c99f, libboost_math_c99l, libboost_math_tr1, +# libboost_math_tr1f, libboost_math_tr1l). This macro must be fixed to do the +# right thing anyway. +BOOST_DEFUN([Math], +[BOOST_FIND_HEADER([boost/math/special_functions.hpp])]) + + +# BOOST_MULTIARRAY() +# ------------------ +# Look for Boost.MultiArray +BOOST_DEFUN([MultiArray], +[BOOST_FIND_HEADER([boost/multi_array.hpp])]) + + +# BOOST_NUMERIC_CONVERSION() +# -------------------------- +# Look for Boost.NumericConversion (policy-based numeric conversion) +BOOST_DEFUN([Numeric_Conversion], +[BOOST_FIND_HEADER([boost/numeric/conversion/converter.hpp]) +])# BOOST_NUMERIC_CONVERSION + + +# BOOST_OPTIONAL() +# ---------------- +# Look for Boost.Optional +BOOST_DEFUN([Optional], +[BOOST_FIND_HEADER([boost/optional.hpp])]) + + +# BOOST_PREPROCESSOR() +# -------------------- +# Look for Boost.Preprocessor +BOOST_DEFUN([Preprocessor], +[BOOST_FIND_HEADER([boost/preprocessor/repeat.hpp])]) + + +# BOOST_UNORDERED() +# ----------------- +# Look for Boost.Unordered +BOOST_DEFUN([Unordered], +[BOOST_FIND_HEADER([boost/unordered_map.hpp])]) + + +# BOOST_UUID() +# ------------ +# Look for Boost.Uuid +BOOST_DEFUN([Uuid], +[BOOST_FIND_HEADER([boost/uuid/uuid.hpp])]) + + +# BOOST_PROGRAM_OPTIONS([PREFERRED-RT-OPT]) +# ----------------------------------------- +# Look for Boost.Program_options. For the documentation of PREFERRED-RT-OPT, +# see the documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Program_Options], +[BOOST_FIND_LIB([program_options], [$1], + [boost/program_options.hpp], + [boost::program_options::options_description d("test");]) +])# BOOST_PROGRAM_OPTIONS + + + +# _BOOST_PYTHON_CONFIG(VARIABLE, FLAG) +# ------------------------------------ +# Save VARIABLE, and define it via `python-config --FLAG`. +# Substitute BOOST_PYTHON_VARIABLE. +m4_define([_BOOST_PYTHON_CONFIG], +[AC_SUBST([BOOST_PYTHON_$1], + [`python-config --$2 2>/dev/null`])dnl +boost_python_save_$1=$$1 +$1="$$1 $BOOST_PYTHON_$1"]) + + +# BOOST_PYTHON([PREFERRED-RT-OPT]) +# -------------------------------- +# Look for Boost.Python. For the documentation of PREFERRED-RT-OPT, +# see the documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Python], +[_BOOST_PYTHON_CONFIG([CPPFLAGS], [includes]) +_BOOST_PYTHON_CONFIG([LDFLAGS], [ldflags]) +_BOOST_PYTHON_CONFIG([LIBS], [libs]) +m4_pattern_allow([^BOOST_PYTHON_MODULE$])dnl +BOOST_FIND_LIB([python], [$1], + [boost/python.hpp], + [], [BOOST_PYTHON_MODULE(empty) {}]) +CPPFLAGS=$boost_python_save_CPPFLAGS +LDFLAGS=$boost_python_save_LDFLAGS +LIBS=$boost_python_save_LIBS +])# BOOST_PYTHON + + +# BOOST_REF() +# ----------- +# Look for Boost.Ref +BOOST_DEFUN([Ref], +[BOOST_FIND_HEADER([boost/ref.hpp])]) + + +# BOOST_REGEX([PREFERRED-RT-OPT]) +# ------------------------------- +# Look for Boost.Regex. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Regex], +[BOOST_FIND_LIB([regex], [$1], + [boost/regex.hpp], + [boost::regex exp("*"); boost::regex_match("foo", exp);]) +])# BOOST_REGEX + + +# BOOST_SERIALIZATION([PREFERRED-RT-OPT]) +# --------------------------------------- +# Look for Boost.Serialization. For the documentation of PREFERRED-RT-OPT, see +# the documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Serialization], +[BOOST_FIND_LIB([serialization], [$1], + [boost/archive/text_oarchive.hpp], + [std::ostream* o = 0; // Cheap way to get an ostream... + boost::archive::text_oarchive t(*o);]) +])# BOOST_SERIALIZATION + + +# BOOST_SIGNALS([PREFERRED-RT-OPT]) +# --------------------------------- +# Look for Boost.Signals. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Signals], +[BOOST_FIND_LIB([signals], [$1], + [boost/signal.hpp], + [boost::signal s;]) +])# BOOST_SIGNALS + + +# BOOST_SMART_PTR() +# ----------------- +# Look for Boost.SmartPtr +BOOST_DEFUN([Smart_Ptr], +[BOOST_FIND_HEADER([boost/scoped_ptr.hpp]) +BOOST_FIND_HEADER([boost/shared_ptr.hpp]) +]) + + +# BOOST_STATICASSERT() +# -------------------- +# Look for Boost.StaticAssert +BOOST_DEFUN([StaticAssert], +[BOOST_FIND_HEADER([boost/static_assert.hpp])]) + + +# BOOST_STRING_ALGO() +# ------------------- +# Look for Boost.StringAlgo +BOOST_DEFUN([String_Algo], +[BOOST_FIND_HEADER([boost/algorithm/string.hpp]) +]) + + +# BOOST_SYSTEM([PREFERRED-RT-OPT]) +# -------------------------------- +# Look for Boost.System. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. This library was introduced in Boost +# 1.35.0. +BOOST_DEFUN([System], +[BOOST_FIND_LIB([system], [$1], + [boost/system/error_code.hpp], + [boost::system::error_code e; e.clear();]) +])# BOOST_SYSTEM + + +# BOOST_TEST([PREFERRED-RT-OPT]) +# ------------------------------ +# Look for Boost.Test. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Test], +[m4_pattern_allow([^BOOST_CHECK$])dnl +BOOST_FIND_LIB([unit_test_framework], [$1], + [boost/test/unit_test.hpp], [BOOST_CHECK(2 == 2);], + [using boost::unit_test::test_suite; + test_suite* init_unit_test_suite(int argc, char ** argv) + { return NULL; }]) +])# BOOST_TEST + + +# BOOST_THREADS([PREFERRED-RT-OPT]) +# --------------------------------- +# Look for Boost.Thread. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +# FIXME: Provide an alias "BOOST_THREAD". +BOOST_DEFUN([Threads], +[dnl Having the pthread flag is required at least on GCC3 where +dnl boost/thread.hpp would complain if we try to compile without +dnl -pthread on GNU/Linux. +AC_REQUIRE([_BOOST_PTHREAD_FLAG])dnl +boost_threads_save_LIBS=$LIBS +boost_threads_save_LDFLAGS=$LDFLAGS +boost_threads_save_CPPFLAGS=$CPPFLAGS +# Link-time dependency from thread to system was added as of 1.49.0. +if test $boost_major_version -ge 149; then +BOOST_SYSTEM([$1]) +fi # end of the Boost.System check. +m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl +LIBS="$LIBS $BOOST_SYSTEM_LIBS $boost_cv_pthread_flag" +LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" +# Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3, +# boost/thread.hpp will trigger a #error if -pthread isn't used: +# boost/config/requires_threads.hpp:47:5: #error "Compiler threading support +# is not turned on. Please set the correct command line options for +# threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" +CPPFLAGS="$CPPFLAGS $boost_cv_pthread_flag" + +# When compiling for the Windows platform, the threads library is named +# differently. +case $host_os in + (*mingw*) + BOOST_FIND_LIB([thread_win32], [$1], + [boost/thread.hpp], [boost::thread t; boost::mutex m;]) + BOOST_THREAD_LDFLAGS=$BOOST_THREAD_WIN32_LDFLAGS + BOOST_THREAD_LDPATH=$BOOST_THREAD_WIN32_LDPATH + BOOST_THREAD_LIBS=$BOOST_THREAD_WIN32_LIBS + ;; + (*) + BOOST_FIND_LIB([thread], [$1], + [boost/thread.hpp], [boost::thread t; boost::mutex m;]) + ;; +esac + +BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS $BOOST_SYSTEM_LIBS $boost_cv_pthread_flag" +BOOST_THREAD_LDFLAGS="$BOOST_SYSTEM_LDFLAGS" +BOOST_CPPFLAGS="$BOOST_CPPFLAGS $boost_cv_pthread_flag" +LIBS=$boost_threads_save_LIBS +LDFLAGS=$boost_threads_save_LDFLAGS +CPPFLAGS=$boost_threads_save_CPPFLAGS +])# BOOST_THREADS + + +# BOOST_TOKENIZER() +# ----------------- +# Look for Boost.Tokenizer +BOOST_DEFUN([Tokenizer], +[BOOST_FIND_HEADER([boost/tokenizer.hpp])]) + + +# BOOST_TRIBOOL() +# --------------- +# Look for Boost.Tribool +BOOST_DEFUN([Tribool], +[BOOST_FIND_HEADER([boost/logic/tribool_fwd.hpp]) +BOOST_FIND_HEADER([boost/logic/tribool.hpp]) +]) + + +# BOOST_TUPLE() +# ------------- +# Look for Boost.Tuple +BOOST_DEFUN([Tuple], +[BOOST_FIND_HEADER([boost/tuple/tuple.hpp])]) + + +# BOOST_TYPETRAITS() +# -------------------- +# Look for Boost.TypeTraits +BOOST_DEFUN([TypeTraits], +[BOOST_FIND_HEADER([boost/type_traits.hpp])]) + + +# BOOST_UTILITY() +# --------------- +# Look for Boost.Utility (noncopyable, result_of, base-from-member idiom, +# etc.) +BOOST_DEFUN([Utility], +[BOOST_FIND_HEADER([boost/utility.hpp])]) + + +# BOOST_VARIANT() +# --------------- +# Look for Boost.Variant. +BOOST_DEFUN([Variant], +[BOOST_FIND_HEADER([boost/variant/variant_fwd.hpp]) +BOOST_FIND_HEADER([boost/variant.hpp])]) + + +# BOOST_WAVE([PREFERRED-RT-OPT]) +# ------------------------------ +# NOTE: If you intend to use Wave/Spirit with thread support, make sure you +# call BOOST_THREADS first. +# Look for Boost.Wave. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Wave], +[AC_REQUIRE([BOOST_FILESYSTEM])dnl +AC_REQUIRE([BOOST_DATE_TIME])dnl +boost_wave_save_LIBS=$LIBS +boost_wave_save_LDFLAGS=$LDFLAGS +m4_pattern_allow([^BOOST_((FILE)?SYSTEM|DATE_TIME|THREAD)_(LIBS|LDFLAGS)$])dnl +LIBS="$LIBS $BOOST_SYSTEM_LIBS $BOOST_FILESYSTEM_LIBS $BOOST_DATE_TIME_LIBS \ +$BOOST_THREAD_LIBS" +LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS $BOOST_FILESYSTEM_LDFLAGS \ +$BOOST_DATE_TIME_LDFLAGS $BOOST_THREAD_LDFLAGS" +BOOST_FIND_LIB([wave], [$1], + [boost/wave.hpp], + [boost::wave::token_id id; get_token_name(id);]) +LIBS=$boost_wave_save_LIBS +LDFLAGS=$boost_wave_save_LDFLAGS +])# BOOST_WAVE + + +# BOOST_XPRESSIVE() +# ----------------- +# Look for Boost.Xpressive (new since 1.36.0). +BOOST_DEFUN([Xpressive], +[BOOST_FIND_HEADER([boost/xpressive/xpressive.hpp])]) + + +# ----------------- # +# Internal helpers. # +# ----------------- # + + +# _BOOST_PTHREAD_FLAG() +# --------------------- +# Internal helper for BOOST_THREADS. Based on ACX_PTHREAD: +# http://autoconf-archive.cryp.to/acx_pthread.html +AC_DEFUN([_BOOST_PTHREAD_FLAG], +[AC_REQUIRE([AC_PROG_CXX])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_LANG_PUSH([C++])dnl +AC_CACHE_CHECK([for the flags needed to use pthreads], [boost_cv_pthread_flag], +[ boost_cv_pthread_flag= + # The ordering *is* (sometimes) important. Some notes on the + # individual items follow: + # (none): in case threads are in libc; should be tried before -Kthread and + # other compiler flags to prevent continual compiler warnings + # -lpthreads: AIX (must check this before -lpthread) + # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + # -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads) + # -pthreads: Solaris/GCC + # -mthreads: MinGW32/GCC, Lynx/GCC + # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it + # doesn't hurt to check since this sometimes defines pthreads too; + # also defines -D_REENTRANT) + # ... -mt is also the pthreads flag for HP/aCC + # -lpthread: GNU Linux, etc. + # --thread-safe: KAI C++ + case $host_os in #( + *solaris*) + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + boost_pthread_flags="-pthreads -lpthread -mt -pthread";; #( + *) + boost_pthread_flags="-lpthreads -Kthread -kthread -llthread -pthread \ + -pthreads -mthreads -lpthread --thread-safe -mt";; + esac + # Generate the test file. + AC_LANG_CONFTEST([AC_LANG_PROGRAM([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0);])]) + for boost_pthread_flag in '' $boost_pthread_flags; do + boost_pthread_ok=false +dnl Re-use the test file already generated. + boost_pthreads__save_LIBS=$LIBS + LIBS="$LIBS $boost_pthread_flag" + AC_LINK_IFELSE([], + [if grep ".*$boost_pthread_flag" conftest.err; then + echo "This flag seems to have triggered warnings" >&AS_MESSAGE_LOG_FD + else + boost_pthread_ok=:; boost_cv_pthread_flag=$boost_pthread_flag + fi]) + LIBS=$boost_pthreads__save_LIBS + $boost_pthread_ok && break + done +]) +AC_LANG_POP([C++])dnl +])# _BOOST_PTHREAD_FLAG + + +# _BOOST_gcc_test(MAJOR, MINOR) +# ----------------------------- +# Internal helper for _BOOST_FIND_COMPILER_TAG. +m4_define([_BOOST_gcc_test], +["defined __GNUC__ && __GNUC__ == $1 && __GNUC_MINOR__ == $2 && !defined __ICC @ gcc$1$2"])dnl + + +# _BOOST_FIND_COMPILER_TAG() +# -------------------------- +# Internal. When Boost is installed without --layout=system, each library +# filename will hold a suffix that encodes the compiler used during the +# build. The Boost build system seems to call this a `tag'. +AC_DEFUN([_BOOST_FIND_COMPILER_TAG], +[AC_REQUIRE([AC_PROG_CXX])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_CACHE_CHECK([for the toolset name used by Boost for $CXX], [boost_cv_lib_tag], +[boost_cv_lib_tag=unknown +if test x$boost_cv_inc_path != xno; then + AC_LANG_PUSH([C++])dnl + # The following tests are mostly inspired by boost/config/auto_link.hpp + # The list is sorted to most recent/common to oldest compiler (in order + # to increase the likelihood of finding the right compiler with the + # least number of compilation attempt). + # Beware that some tests are sensible to the order (for instance, we must + # look for MinGW before looking for GCC3). + # I used one compilation test per compiler with a #error to recognize + # each compiler so that it works even when cross-compiling (let me know + # if you know a better approach). + # Known missing tags (known from Boost's tools/build/v2/tools/common.jam): + # como, edg, kcc, bck, mp, sw, tru, xlc + # I'm not sure about my test for `il' (be careful: Intel's ICC pre-defines + # the same defines as GCC's). + for i in \ + _BOOST_gcc_test(4, 8) \ + _BOOST_gcc_test(4, 7) \ + _BOOST_gcc_test(4, 6) \ + _BOOST_gcc_test(4, 5) \ + _BOOST_gcc_test(4, 4) \ + _BOOST_gcc_test(4, 3) \ + _BOOST_gcc_test(4, 2) \ + _BOOST_gcc_test(4, 1) \ + _BOOST_gcc_test(4, 0) \ + "defined __GNUC__ && __GNUC__ == 3 && !defined __ICC \ + && (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ + || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw" \ + _BOOST_gcc_test(3, 4) \ + _BOOST_gcc_test(3, 3) \ + "defined _MSC_VER && _MSC_VER >= 1500 @ vc90" \ + "defined _MSC_VER && _MSC_VER == 1400 @ vc80" \ + _BOOST_gcc_test(3, 2) \ + "defined _MSC_VER && _MSC_VER == 1310 @ vc71" \ + _BOOST_gcc_test(3, 1) \ + _BOOST_gcc_test(3, 0) \ + "defined __BORLANDC__ @ bcb" \ + "defined __ICC && (defined __unix || defined __unix__) @ il" \ + "defined __ICL @ iw" \ + "defined _MSC_VER && _MSC_VER == 1300 @ vc7" \ + _BOOST_gcc_test(2, 95) \ + "defined __MWERKS__ && __MWERKS__ <= 0x32FF @ cw9" \ + "defined _MSC_VER && _MSC_VER < 1300 && !defined UNDER_CE @ vc6" \ + "defined _MSC_VER && _MSC_VER < 1300 && defined UNDER_CE @ evc4" \ + "defined __MWERKS__ && __MWERKS__ <= 0x31FF @ cw8" + do + boost_tag_test=`expr "X$i" : 'X\([[^@]]*\) @ '` + boost_tag=`expr "X$i" : 'X[[^@]]* @ \(.*\)'` + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#if $boost_tag_test +/* OK */ +#else +# error $boost_tag_test +#endif +]])], [boost_cv_lib_tag=$boost_tag; break], []) + done +AC_LANG_POP([C++])dnl + case $boost_cv_lib_tag in #( + # Some newer (>= 1.35?) versions of Boost seem to only use "gcc" as opposed + # to "gcc41" for instance. + *-gcc | *'-gcc ') :;; #( Don't re-add -gcc: it's already in there. + gcc*) + boost_tag_x= + case $host_os in #( + darwin*) + if test $boost_major_version -ge 136; then + # The `x' added in r46793 of Boost. + boost_tag_x=x + fi;; + esac + # We can specify multiple tags in this variable because it's used by + # BOOST_FIND_LIB that does a `for tag in -$boost_cv_lib_tag' ... + boost_cv_lib_tag="$boost_tag_x$boost_cv_lib_tag -${boost_tag_x}gcc" + ;; #( + unknown) + AC_MSG_WARN([[could not figure out which toolset name to use for $CXX]]) + boost_cv_lib_tag= + ;; + esac +fi])dnl end of AC_CACHE_CHECK +])# _BOOST_FIND_COMPILER_TAG + + +# _BOOST_GUESS_WHETHER_TO_USE_MT() +# -------------------------------- +# Compile a small test to try to guess whether we should favor MT (Multi +# Thread) flavors of Boost. Sets boost_guess_use_mt accordingly. +AC_DEFUN([_BOOST_GUESS_WHETHER_TO_USE_MT], +[# Check whether we do better use `mt' even though we weren't ask to. +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#if defined _REENTRANT || defined _MT || defined __MT__ +/* use -mt */ +#else +# error MT not needed +#endif +]])], [boost_guess_use_mt=:], [boost_guess_use_mt=false]) +]) + +# _BOOST_AC_LINK_IFELSE(PROGRAM, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# ------------------------------------------------------------------- +# Fork of _AC_LINK_IFELSE that preserves conftest.o across calls. Fragile, +# will break when Autoconf changes its internals. Requires that you manually +# rm -f conftest.$ac_objext in between to really different tests, otherwise +# you will try to link a conftest.o left behind by a previous test. +# Used to aggressively optimize BOOST_FIND_LIB (see the big comment in this +# macro). +# +# Don't use "break" in the actions, as it would short-circuit some code +# this macro runs after the actions. +m4_define([_BOOST_AC_LINK_IFELSE], +[m4_ifvaln([$1], [AC_LANG_CONFTEST([$1])])dnl +rm -f conftest$ac_exeext +boost_save_ac_ext=$ac_ext +boost_use_source=: +# If we already have a .o, re-use it. We change $ac_ext so that $ac_link +# tries to link the existing object file instead of compiling from source. +test -f conftest.$ac_objext && ac_ext=$ac_objext && boost_use_source=false && + _AS_ECHO_LOG([re-using the existing conftest.$ac_objext]) +AS_IF([_AC_DO_STDERR($ac_link) && { + test -z "$ac_[]_AC_LANG_ABBREV[]_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_executable_p conftest$ac_exeext +dnl FIXME: use AS_TEST_X instead when 2.61 is widespread enough. + }], + [$2], + [if $boost_use_source; then + _AC_MSG_LOG_CONFTEST + fi + $3]) +ac_objext=$boost_save_ac_objext +ac_ext=$boost_save_ac_ext +dnl Delete also the IPA/IPO (Inter Procedural Analysis/Optimization) +dnl information created by the PGI compiler (conftest_ipa8_conftest.oo), +dnl as it would interfere with the next link command. +rm -f core conftest.err conftest_ipa8_conftest.oo \ + conftest$ac_exeext m4_ifval([$1], [conftest.$ac_ext])[]dnl +])# _BOOST_AC_LINK_IFELSE + +# Local Variables: +# mode: autoconf +# End: diff --git a/m4/geant4.bkp b/m4/geant4.bkp new file mode 100644 index 0000000..b911c74 --- /dev/null +++ b/m4/geant4.bkp @@ -0,0 +1,361 @@ +dnl +dnl m4 macros for setting up Geant4 +dnl + +# call all the Geant4 macros +AC_DEFUN( [GDML_SETUP_GEANT4], [ + +GDML_WITH_GEANT4 +AC_GEANT4_VERSION +GDML_WITH_G4SYSTEM +GDML_WITH_GEANT4_INCLUDE +GDML_WITH_GEANT4_LIBDIR +GDML_ENABLE_GEANT4_GRANULAR_LIBS +GDML_SUBST_GEANT4 + +GDML_CHECK_NIST +GDML_ENABLE_NIST + +AC_HAVE_G4TESSELLATED +AC_HAVE_G4TET +AC_HAVE_G4TWISTEDBOX +AC_HAVE_G4TWISTEDTRD +AC_HAVE_G4TWISTEDTRAP +AC_HAVE_G4TWISTEDTUBS +AC_HAVE_G4ELLIPSOID +AC_HAVE_G4EXTRUDEDSOLID + +]) + +# macro to set GEANT4 base dir (G4INSTALL) +AC_DEFUN( GDML_WITH_GEANT4, [ + +AC_MSG_CHECKING(for GEANT4 installation setting) + +AC_ARG_WITH(geant4, + AC_HELP_STRING([--with-geant4=],[Geant4 installation base [[G4INSTALL]] ]), + [GEANT4_PREFIX=$with_geant4], + [GEANT4_PREFIX=$G4INSTALL]) + +AC_MSG_RESULT([$GEANT4_PREFIX]) + +GDML_CHECK_PKG_DIR( [$GEANT4_PREFIX], [Geant4]) + +]) + +# macro to set G4SYSTEM +AC_DEFUN( GDML_WITH_G4SYSTEM, [ + +AC_MSG_CHECKING(for G4SYSTEM setting) + +AC_ARG_WITH(geant4-system, + AC_HELP_STRING([--with-geant4-system=],[Value of G4SYSTEM variable]), + [G4SYSTEM=$with_geant4_g4system]) + +if test -z "${G4SYSTEM}"; then + G4SYSTEM=`uname`-${CXX} +fi + +AC_MSG_RESULT([$G4SYSTEM]) + +AC_SUBST(G4SYSTEM) + +]) + +# macro to set GEANT4 include dir +AC_DEFUN( GDML_WITH_GEANT4_INCLUDE, [ + +AC_MSG_CHECKING([for Geant4 include dir setting]) + +AC_ARG_WITH([geant4-include], + AC_HELP_STRING([--with-geant4-include=],[Geant4 alternate headers dir]), + [GEANT4_INCLUDE=$with_geant4_include], + [GEANT4_INCLUDE=$GEANT4_PREFIX/include]) + +AC_MSG_RESULT([$GEANT4_INCLUDE]) + +GDML_CHECK_PKG_DIR( [$GEANT4_INCLUDE], + [GEANT4], + [G4RunManager.hh]) +]) + +AC_MSG_RESULT(yes) + +# macro to set GEANT4 lib dir +AC_DEFUN( GDML_WITH_GEANT4_LIBDIR, [ + +AC_MSG_CHECKING([for Geant4 lib dir]) + +AC_ARG_WITH([geant4-libdir], + AC_HELP_STRING([--with-geant4-libdir=], [Geant4 alternate library dir]), + [GEANT4_LIBDIR=$with_geant4_libdir], + [GEANT4_LIBDIR=$GEANT4_PREFIX/lib/$G4SYSTEM]) + +AC_MSG_RESULT([$GEANT4_LIBDIR]) + +GDML_CHECK_PKG_DIR( [$GEANT4_LIBDIR], + [GEANT4]) +]) + +# macro to substitute GEANT4 vars to output +AC_DEFUN( GDML_SUBST_GEANT4, [ + +AC_SUBST(GEANT4_PREFIX) +AC_SUBST(GEANT4_INCLUDE) +AC_SUBST(GEANT4_LIBDIR) + +]) + +# macro to select granular libs +AC_DEFUN( GDML_ENABLE_GEANT4_GRANULAR_LIBS, [ + +AC_MSG_CHECKING(whether to use Geant4 granular libs) + +AC_ARG_ENABLE([geant4-granular-libs], + AC_HELP_STRING( [--enable-geant4-granular-libs], [Enable linking against granular rather than global Geant4 libs] ), + [ac_g4_use_granular=$enable_geant4_granular_libs], + [ac_g4_use_granular=no]) + +# no option? +if test -z "${with_geant4_granular_libs}"; then + # set in env? + if test -n "${G4LIB_USE_GRANULAR}"; then + ac_g4_use_granular=yes + fi +fi + +AC_MSG_RESULT([$ac_g4_use_granular]) + +if test "${ac_g4_use_granular}" = "yes"; then + GEANT4_USE_GRANULAR=1 + AC_SUBST(GEANT4_USE_GRANULAR) +else + GEANT4_USE_GLOBAL=1 + AC_SUBST(GEANT4_USE_GLOBAL) +fi + +]) + +# macro to check whether NIST is supported by the current Geant4 version +AC_DEFUN(GDML_CHECK_NIST, [ + +HAVE_NIST=no + +AC_CHECK_FILE([$GEANT4_PREFIX/source/materials/include/G4NistManager.hh],HAVE_NIST=yes) + +if test "$HAVE_NIST" = "yes" +then + AC_DEFINE(HAVE_NIST) +fi + +]) + +# macro to enable/disable NIST support +AC_DEFUN(GDML_ENABLE_NIST, [ + +dnl Removed because this is somehow getting put in front of GEANT4_PREFIX setting, which breaks NIST config. +dnl AC_REQUIRE([GDML_CHECK_NIST]) + +AC_MSG_CHECKING(whether to enable Geant4 NIST support for material lookup) + +AC_ARG_ENABLE([nist], + AC_HELP_STRING([--enable-nist=]., [Turn NIST support on or off.])) + +# default to using NIST if not set from the enable-nist option +if test "X$enable_nist" = "X" +then + enable_nist=yes +fi + +if test "X$enable_nist" = "Xyes" +then + if test "X$HAVE_NIST" = "Xyes" + then + AC_MSG_RESULT(yes) + AC_DEFINE(GDML_USE_NIST) + else + AC_MSG_RESULT(no) + AC_MSG_WARN(NIST was selected but your version of Geant4 does not support it) + fi +else + AC_MSG_RESULT(no) +fi + +]) + +dnl Macro to extract the Geant4 version from G4Version.hh or G4RunManagerKernel.hh, if the former file does not exist. +AC_DEFUN(AC_GEANT4_VERSION, [ + +AC_MSG_CHECKING(for Geant4 full version) + +if test -n "$GEANT4_PREFIX" +then + + if ! test -d $GEANT4_PREFIX; then + AC_MSG_ERROR(G4INSTALL does not point to a directory) + fi + + if ! test -e $GEANT4_PREFIX/source/run/include/G4RunManager.hh; then + AC_MSG_ERROR(G4INSTALL does not appear to contain the Geant4 source code) + fi + + if test -e "$GEANT4_PREFIX/source/global/management/include/G4Version.hh" + then + GEANT4_FULL_VERSION=$(sed -n -e '/#define G4VERSION_NUMBER/s/#define G4VERSION_NUMBER //p' $GEANT4_PREFIX/source/global/management/include/G4Version.hh | \ + awk 'BEGIN { FS="" } ; { print [$]1"."[$]2"."[$]3 }') + elif test -e "$GEANT4_PREFIX/source/run/src/G4RunManagerKernel.cc" + then + GEANT4_FULL_VERSION=$(sed -n -e '/\/\/ GEANT4 tag /s/.*\(geant4-[[0-9]]*-[[0-9]]*[[0-9a-z-]]*\).*/\1/p' \ + $GEANT4_PREFIX/source/run/src/G4RunManagerKernel.cc | sed -e 's/geant4-//g' -e 's/patch-//g' -e 's/-/./g') + else + AC_MSG_ERROR(could not determine Geant4 version because G4Version.hh or G4RunManagerKernel.hh was not found in $GEANT4_PREFIX) + fi +else + AC_MSG_ERROR(G4INSTALL is not set in the environment) +fi + +GEANT4_MAJOR_VERSION=$(echo "$GEANT4_FULL_VERSION" | awk 'BEGIN{ FS="." } { print [$]1 }' | sed 's/0*//') +GEANT4_MINOR_VERSION=$(echo "$GEANT4_FULL_VERSION" | awk 'BEGIN{ FS="." } { print [$]2 }' | sed 's/0*//') +GEANT4_PATCH_VERSION=$(echo "$GEANT4_FULL_VERSION" | awk 'BEGIN{ FS="." } { print [$]3 }' | sed 's/0*//') + +if test -z "$GEANT4_MINOR_VERSION"; +then + GEANT4_MINOR_VERSION=0 +fi + +if test -z "$GEANT4_PATCH_VERSION"; +then + GEANT4_PATCH_VERSION=0 +fi + +GEANT4_FULL_VERSION=$GEANT4_MAJOR_VERSION"."$GEANT4_MINOR_VERSION"."$GEANT4_PATCH_VERSION + +AC_MSG_RESULT($GEANT4_FULL_VERSION) + +AC_MSG_CHECKING(for Geant4 major version level) +AC_MSG_RESULT($GEANT4_MAJOR_VERSION) + +AC_MSG_CHECKING(for Geant4 minor version level) +AC_MSG_RESULT($GEANT4_MINOR_VERSION) + +AC_MSG_CHECKING(for Geant4 patch level) +AC_MSG_RESULT($GEANT4_PATCH_VERSION) + +AC_SUBST(GEANT4_FULL_VERSION) +AC_SUBST(GEANT4_MAJOR_VERSION) +AC_SUBST(GEANT4_MINOR_VERSION) +AC_SUBST(GEANT4_PATCH_VERSION) + +]) + +# Macro to set HAVE_G4TESSELLATED if G4TessellatedSolid.hh exists. +AC_DEFUN(AC_HAVE_G4TESSELLATED, [ + +AC_MSG_CHECKING(whether to enable G4TessellatedSolid) + +if test -e $GEANT4_PREFIX/source/geometry/solids/specific/include/G4TessellatedSolid.hh; then + AC_DEFINE(HAVE_G4TESSELLATEDSOLID) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +]) + +# Macro to set HAVE_G4TET if G4Tet.hh exists. +AC_DEFUN(AC_HAVE_G4TET, [ + +AC_MSG_CHECKING(whether to enable G4Tet) + +if test -e $GEANT4_PREFIX/source/geometry/solids/specific/include/G4Tet.hh; then + AC_DEFINE(HAVE_G4TET) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +]) + +# Macro to set HAVE_G4TWISTEDBOX if G4TwistedBox.hh exists. +AC_DEFUN(AC_HAVE_G4TWISTEDBOX, [ + +AC_MSG_CHECKING(whether to enable G4TwistedBox) + +if test -e $GEANT4_PREFIX/source/geometry/solids/specific/include/G4TwistedBox.hh; then + AC_DEFINE(HAVE_G4TWISTEDBOX) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +]) + +# Macro to set HAVE_G4TWISTEDTRD if G4TwistedTrd.hh exists. +AC_DEFUN(AC_HAVE_G4TWISTEDTRD, [ + +AC_MSG_CHECKING(whether to enable G4TwistedTrd) + +if test -e $GEANT4_PREFIX/source/geometry/solids/specific/include/G4TwistedTrd.hh; then + AC_DEFINE(HAVE_G4TWISTEDTRD) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +]) + +# Macro to set HAVE_G4TWISTEDTRAP if G4TwistedTrap.hh exists. +AC_DEFUN(AC_HAVE_G4TWISTEDTRAP, [ + +AC_MSG_CHECKING(whether to enable G4TwistedTrap) + +if test -e $GEANT4_PREFIX/source/geometry/solids/specific/include/G4TwistedTrap.hh; then + AC_DEFINE(HAVE_G4TWISTEDTRAP) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +]) + +# Macro to set HAVE_G4TWISTEDTUBS if G4TwistedTubs.hh exists. +AC_DEFUN(AC_HAVE_G4TWISTEDTUBS, [ + +AC_MSG_CHECKING(whether to enable G4TwistedTubs) + +if test -e $GEANT4_PREFIX/source/geometry/solids/specific/include/G4TwistedTubs.hh; then + AC_DEFINE(HAVE_G4TWISTEDTUBS) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +]) + +# Macro to set HAVE_G4ELLIPSOID if G4Ellipsoid.hh exists. +AC_DEFUN(AC_HAVE_G4ELLIPSOID, [ + +AC_MSG_CHECKING(whether to enable G4Ellipsoid) + +if test -e $GEANT4_PREFIX/source/geometry/solids/specific/include/G4Ellipsoid.hh; then + AC_DEFINE(HAVE_G4ELLIPSOID) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +]) + +# Macro to set HAVE_G4EXTRUDEDSOLID if G4ExtrudedSolid.hh exists. +AC_DEFUN(AC_HAVE_G4EXTRUDEDSOLID, [ + +AC_MSG_CHECKING(whether to enable G4ExtrudedSolid) + +if test -e $GEANT4_PREFIX/source/geometry/solids/specific/include/G4ExtrudedSolid.hh; then + AC_DEFINE(HAVE_G4EXTRUDEDSOLID) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +]) diff --git a/m4/geant4.m4 b/m4/geant4.m4 new file mode 100644 index 0000000..7f73e39 --- /dev/null +++ b/m4/geant4.m4 @@ -0,0 +1,64 @@ +dnl +dnl m4 macros for setting up Geant4 +dnl + + +## +## Geant4 Config +## + +AC_DEFUN([GEANT4_PATH], +[ + AC_ARG_WITH(gean4sys, + [ --with-geant4sys top of the GEANT4 installation directory], + user_genat4sys=$withval, + user_geant4sys="none") + if test ! x"$user_geant4sys" = xnone; then + geant4bin="$user_geant4sys/bin" + elif test ! x"$GEANT4SYS" = x ; then + geant4bin="$GEANT4SYS/bin" + else + geant4bin=$PATH + fi + AC_PATH_PROG(GEANT4CONF, geant4-config , no, $geant4bin) + + if test ! x"$GEANT4CONF" = "xno"; then + + # define some variables + GEANT4CFLAGS=`$GEANT4CONF --cflags` + GEANT4LIBS=`$GEANT4CONF --libs` + GEANT4VERSION=`$GEANT4CONF --version` + + if test $1 ; then + AC_MSG_CHECKING(wether GEANT4 version >= [$1]) + vers=`$GEANT4CONF --version | tr './' ' ' | awk 'BEGIN { FS = " "; } { printf "%d", ($''1 * 1000 + $''2) * 1000 + $''3;}'` + requ=`echo $1 | tr './' ' ' | awk 'BEGIN { FS = " "; } { printf "%d", ($''1 * 1000 + $''2) * 1000 + $''3;}'` + if test $vers -lt $requ ; then + AC_MSG_RESULT(no) + no_geant4="yes" + else + AC_MSG_RESULT(yes) + no_genat4="no" + fi + fi + else + # otherwise, we say no_GEANT4 + no_geant4="yes" + fi + + AC_SUBST(GEANT4CFLAGS) + AC_SUBST(GEANT4LIBS) + AC_SUBST(GEANT4VERSION) + + if test "x$no_geant4" = "x" ; then + ifelse([$2], , :, [$2]) + else + ifelse([$3], , :, [$3]) + fi +]) + + + + + + diff --git a/m4/openmp.m4 b/m4/openmp.m4 new file mode 100644 index 0000000..78f2b75 --- /dev/null +++ b/m4/openmp.m4 @@ -0,0 +1,98 @@ +# openmp.m4 serial 7 +dnl Copyright (C) 2006-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This file can be removed once we assume autoconf >= 2.62. + +dnl Expand to nothing in autoconf >= 2.62. m4_copy has a different +dnl semantic in autoconf > 2.63. +m4_ifdef([AC_OPENMP], [], [ + +# _AC_LANG_OPENMP +# --------------- +# Expands to some language dependent source code for testing the presence of +# OpenMP. +AC_DEFUN([_AC_LANG_OPENMP], +[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)]) + +# _AC_LANG_OPENMP(C) +# ------------------ +m4_define([_AC_LANG_OPENMP(C)], +[ +#ifndef _OPENMP + choke me +#endif +#include +int main () { return omp_get_num_threads (); } +]) + +# _AC_LANG_OPENMP(C++) +# -------------------- +m4_copy([_AC_LANG_OPENMP(C)], [_AC_LANG_OPENMP(C++)]) + +# _AC_LANG_OPENMP(Fortran 77) +# --------------------------- +m4_define([_AC_LANG_OPENMP(Fortran 77)], +[AC_LANG_FUNC_LINK_TRY([omp_get_num_threads])]) + +# _AC_LANG_OPENMP(Fortran) +# --------------------------- +m4_copy([_AC_LANG_OPENMP(Fortran 77)], [_AC_LANG_OPENMP(Fortran)]) + +# AC_OPENMP +# --------- +# Check which options need to be passed to the C compiler to support OpenMP. +# Set the OPENMP_CFLAGS / OPENMP_CXXFLAGS / OPENMP_FFLAGS variable to these +# options. +# The options are necessary at compile time (so the #pragmas are understood) +# and at link time (so the appropriate library is linked with). +# This macro takes care to not produce redundant options if $CC $CFLAGS already +# supports OpenMP. It also is careful to not pass options to compilers that +# misinterpret them; for example, most compilers accept "-openmp" and create +# an output file called 'penmp' rather than activating OpenMP support. +AC_DEFUN([AC_OPENMP], +[ + OPENMP_[]_AC_LANG_PREFIX[]FLAGS= + AC_ARG_ENABLE([openmp], + [AS_HELP_STRING([--disable-openmp], [do not use OpenMP])]) + if test "$enable_openmp" != no; then + AC_CACHE_CHECK([for $CC option to support OpenMP], + [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp], + [AC_LINK_IFELSE([_AC_LANG_OPENMP], + [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp='none needed'], + [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp='unsupported' + dnl Try these flags: + dnl GCC >= 4.2 -fopenmp + dnl SunPRO C -xopenmp + dnl Intel C -openmp + dnl SGI C, PGI C -mp + dnl Tru64 Compaq C -omp + dnl IBM C (AIX, Linux) -qsmp=omp + dnl If in this loop a compiler is passed an option that it doesn't + dnl understand or that it misinterprets, the AC_LINK_IFELSE test + dnl will fail (since we know that it failed without the option), + dnl therefore the loop will continue searching for an option, and + dnl no output file called 'penmp' or 'mp' is created. + for ac_option in -fopenmp -xopenmp -openmp -mp -omp -qsmp=omp; do + ac_save_[]_AC_LANG_PREFIX[]FLAGS=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $ac_option" + AC_LINK_IFELSE([_AC_LANG_OPENMP], + [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp=$ac_option]) + _AC_LANG_PREFIX[]FLAGS=$ac_save_[]_AC_LANG_PREFIX[]FLAGS + if test "$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp" != unsupported; then + break + fi + done])]) + case $ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp in #( + "none needed" | unsupported) + ;; #( + *) + OPENMP_[]_AC_LANG_PREFIX[]FLAGS=$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp ;; + esac + fi + AC_SUBST([OPENMP_]_AC_LANG_PREFIX[FLAGS]) +]) + +]) diff --git a/m4/root.m4 b/m4/root.m4 new file mode 100644 index 0000000..a671713 --- /dev/null +++ b/m4/root.m4 @@ -0,0 +1,125 @@ +dnl -*- mode: autoconf -*- +dnl +dnl $Id: root.m4,v 1.3 2005/03/21 21:42:21 rdm Exp $ +dnl $Author: rdm $ +dnl $Date: 2005/03/21 21:42:21 $ +dnl +dnl Autoconf macro to check for existence or ROOT on the system +dnl Synopsis: +dnl +dnl ROOT_PATH([MINIMUM-VERSION, [ACTION-IF-FOUND, [ACTION-IF-NOT-FOUND]]]) +dnl +dnl Some examples: +dnl +dnl ROOT_PATH(3.03/05, , AC_MSG_ERROR(Your ROOT version is too old)) +dnl ROOT_PATH(, AC_DEFINE([HAVE_ROOT])) +dnl +dnl The macro defines the following substitution variables +dnl +dnl ROOTCONF full path to root-config +dnl ROOTEXEC full path to root +dnl ROOTCINT full path to rootcint +dnl ROOTLIBDIR Where the ROOT libraries are +dnl ROOTINCDIR Where the ROOT headers are +dnl ROOTCFLAGS Extra compiler flags +dnl ROOTLIBS ROOT basic libraries +dnl ROOTGLIBS ROOT basic + GUI libraries +dnl ROOTAUXLIBS Auxilary libraries and linker flags for ROOT +dnl ROOTAUXCFLAGS Auxilary compiler flags +dnl ROOTRPATH Same as ROOTLIBDIR +dnl +dnl The macro will fail if root-config and rootcint isn't found. +dnl +dnl Christian Holm Christensen +dnl +AC_DEFUN([ROOT_PATH], +[ + AC_ARG_WITH(rootsys, + [ --with-rootsys top of the ROOT installation directory], + user_rootsys=$withval, + user_rootsys="none") + if test ! x"$user_rootsys" = xnone; then + rootbin="$user_rootsys/bin" + elif test ! x"$ROOTSYS" = x ; then + rootbin="$ROOTSYS/bin" + else + rootbin=$PATH + fi + AC_PATH_PROG(ROOTCONF, root-config , no, $rootbin) + AC_PATH_PROG(ROOTEXEC, root , no, $rootbin) + AC_PATH_PROG(ROOTCINT, rootcint , no, $rootbin) + + if test ! x"$ROOTCONF" = "xno" && \ + test ! x"$ROOTCINT" = "xno" ; then + + # define some variables + ROOTLIBDIR=`$ROOTCONF --libdir` + ROOTINCDIR=`$ROOTCONF --incdir` + ROOTCFLAGS=`$ROOTCONF --noauxcflags --cflags` + ROOTLIBS=`$ROOTCONF --noauxlibs --noldflags --libs` + ROOTGLIBS=`$ROOTCONF --noauxlibs --noldflags --glibs` + ROOTAUXCFLAGS=`$ROOTCONF --auxcflags` + ROOTAUXLIBS=`$ROOTCONF --auxlibs` + ROOTRPATH=$ROOTLIBDIR + ROOTVERSION=`$ROOTCONF --version` + ROOTSOVERSION=`dirname $ROOTVERSION` + + if test $1 ; then + AC_MSG_CHECKING(wether ROOT version >= [$1]) + vers=`$ROOTCONF --version | tr './' ' ' | awk 'BEGIN { FS = " "; } { printf "%d", ($''1 * 1000 + $''2) * 1000 + $''3;}'` + requ=`echo $1 | tr './' ' ' | awk 'BEGIN { FS = " "; } { printf "%d", ($''1 * 1000 + $''2) * 1000 + $''3;}'` + if test $vers -lt $requ ; then + AC_MSG_RESULT(no) + no_root="yes" + else + AC_MSG_RESULT(yes) + no_root="no" + fi + fi + else + # otherwise, we say no_root + no_root="yes" + fi + + AC_SUBST(ROOTLIBDIR) + AC_SUBST(ROOTINCDIR) + AC_SUBST(ROOTCFLAGS) + AC_SUBST(ROOTLIBS) + AC_SUBST(ROOTGLIBS) + AC_SUBST(ROOTAUXLIBS) + AC_SUBST(ROOTAUXCFLAGS) + AC_SUBST(ROOTRPATH) + AC_SUBST(ROOTVERSION) + AC_SUBST(ROOTSOVERSION) + + if test "x$no_root" = "x" ; then + ifelse([$2], , :, [$2]) + else + ifelse([$3], , :, [$3]) + fi +]) + +# +# Macro to check if ROOT has a specific feature: +# +# ROOT_FEATURE(FEATURE,[ACTION_IF_HAVE,[ACTION_IF_NOT]]) +# +# For example +# +# ROOT_FEATURE([ldap],[AC_DEFINE([HAVE_ROOT_LDAP])]) +# +AC_DEFUN([ROOT_FEATURE], +[ + AC_REQUIRE([ROOT_PATH]) + feat=$1 + res=`$ROOTCONF --has-$feat` + if test "x$res" = "xyes" ; then + ifelse([$2], , :, [$2]) + else + ifelse([$3], , :, [$3]) + fi +]) + +# +# EOF +# diff --git a/m4/vtk.m4 b/m4/vtk.m4 new file mode 100644 index 0000000..b58e5c7 --- /dev/null +++ b/m4/vtk.m4 @@ -0,0 +1,166 @@ +dnl ====================================================================================== +dnl Author: Francesco Montorsi +dnl RCS-ID: $Id: vtk.m4,v 1.1 2005/11/20 14:47:40 frm Exp $ +dnl +dnl Implements the AM_OPTIONS_VTK, to add the --with-vtk=path option, and the +dnl AM_PATH_VTK macro used to detect VTK presence, location and version. +dnl ====================================================================================== + + + +dnl +dnl AM_OPTIONS_VTK +dnl ------------------------------------------------------------------------ +dnl Adds the --with-vtk=path option to the configure options +dnl +AC_DEFUN([AM_OPTIONS_VTK], +[ + AC_ARG_WITH([vtk-path], + [AC_HELP_STRING([--with-vtk-path], + [The prefix where VTK is installed (default is /usr/local)])], + [with_vtk=$withval], + [with_vtk="/usr/local"]) + + AC_ARG_WITH([vtk-version], + [AC_HELP_STRING([--with-vtk-version], + [VTK's include directory name is vtk-suffix, e.g. vtk-5.0/. What's the suffix? (Default -5.10)])], + [vtk_suffix=$withval], + [vtk_suffix="-5.10"]) + +])# AM_OPTIONS_VTK + + + +dnl +dnl AM_PATH_VTK([minimum-version], [action-if-found], [action-if-not-found]) +dnl ------------------------------------------------------------------------ +dnl +dnl NOTE: [minimum-version] must be in the form [X.Y.Z] +dnl +AC_DEFUN([AM_PATH_VTK], +[ + dnl do we want to check for VTK ? + if test "$with_vtk" = yes; then + dnl in case user wrote --with-vtk=yes + with_vtk="/usr/local" + fi + + if test "$with_vtk" != no; then + dnl + dnl A path was provided in $with_vtk...try hard to find the VTK library {{{ + VTK_PREFIX="$with_vtk" + + AC_CHECK_FILE([$VTK_PREFIX/include/vtk$vtk_suffix/vtkObject.h], [vtkFound="OK"]) + AC_MSG_CHECKING([if VTK is installed in $VTK_PREFIX]) + + if test -z "$vtkFound"; then + dnl + dnl VTK was not found! ...execute $3 unconditionally {{{ + AC_MSG_RESULT([no]) + $3 + dnl }}} + dnl + else + dnl + dnl VTK was found! ...execute $2 if version matches {{{ + AC_MSG_RESULT([yes]) + + dnl these are the VTK libraries of a default build + VTK_LIBS="" + + dnl set VTK c,cpp,ld flags + VTK_CFLAGS="-I$VTK_PREFIX/include/vtk$vtk_suffix" + VTK_CXXFLAGS="$VTK_CFLAGS" + VTK_LDFLAGS="-L$VTK_PREFIX/lib/vtk$vtk_suffix $VTK_LIBS" + + + AC_SUBST(VTK_LIBS) + AC_SUBST(VTK_CFLAGS) + AC_SUBST(VTK_CXXFLAGS) + AC_SUBST(VTK_LDFLAGS) + + dnl now, eventually check version {{{ + if test -n "$1"; then + dnl + dnl A version was specified... parse the version string in $1 {{{ + + dnl The version of VTK that we need: {{{ + maj=`echo $1 | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + min=`echo $1 | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + rel=`echo $1 | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + AC_MSG_CHECKING([if VTK version is at least $maj.$min.$rel]) + dnl }}} + + dnl Compare required version of VTK against installed version: {{{ + dnl + dnl Note that in order to be able to compile the following test program, + dnl we need to add to the current flags, the VTK settings... + OLD_CFLAGS=$CFLAGS + OLD_CXXFLAGS=$CXXFLAGS + OLD_LDFLAGS=$LDFLAGS + CFLAGS="$VTK_CFLAGS $CFLAGS" + CXXFLAGS="$VTK_CXXFLAGS $CXXFLAGS" + LDFLAGS="$VTK_LDFLAGS $LDFLAGS" + dnl + dnl check if the installed VTK is greater or not + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [ + #include + #include + ], + [ + printf("VTK version is: %d.%d.%d", VTK_MAJOR_VERSION, VTK_MINOR_VERSION, VTK_BUILD_VERSION); + if VTK_MAJOR_VERSION < $maj + error Installed VTK is too old ! + endif + if VTK_MINOR_VERSION < $min + error Installed VTK is too old ! + endif + if VTK_BUILD_VERSION < $rel + error Installed VTK is too old ! + endif + ]) + ], [vtkVersion="OK"]) + dnl + dnl restore all flags without VTK values + CFLAGS=$OLD_CFLAGS + CXXFLAGS=$OLD_CXXFLAGS + LDFLAGS=$OLD_LDFLAGS + dnl }}} + + dnl Execute $2 if version is ok, otherwise execute $3 {{{ + if test "$vtkVersion" = "OK"; then + AC_MSG_RESULT([yes]) + $2 + else + AC_MSG_RESULT([no]) + $3 + fi + dnl }}} + + dnl }}} + dnl + else + dnl + dnl A target version number was not provided... execute $2 unconditionally {{{ + + dnl if we don't have to check for minimum version (because the user did not set that option), + dnl then we can execute here the block action-if-found + CFLAGS="$VTK_CFLAGS $CFLAGS" + CXXFLAGS="$VTK_CXXFLAGS $CXXFLAGS" + LDFLAGS="$VTK_LDFLAGS $LDFLAGS" + $2 + dnl }}} + dnl + fi + dnl }}} + + dnl }}} + dnl + fi + dnl }}} + dnl + fi +])# AM_PATH_VTK +dnl +dnl vim: foldmethod=marker foldlevel=1 ts=2 sw=2 diff --git a/m4/zeromq.m4 b/m4/zeromq.m4 new file mode 100644 index 0000000..381abc1 --- /dev/null +++ b/m4/zeromq.m4 @@ -0,0 +1,90 @@ +# +# Configure paths and flags for the ZeroMQ library. +# Denis Arnaud , May 2011 +# +# Variables set by this macro: +# * AM_PATH_ZEROMQ +# * ZEROMQ_VERSION +# * ZEROMQ_CFLAGS +# * ZEROMQ_LIBS +# + +AC_DEFUN([AM_PATH_ZEROMQ], +[ +AC_LANG_SAVE +AC_LANG([C++]) + +## +AC_ARG_WITH(zeromq, + [[ --with-zeromq[=PFX] Prefix where ZeroMQ is installed (optional) ]], + zeromq_dir="$withval", + zeromq_dir="") + + ac_zeromq_path="" + if test "x${zeromq_dir}" = "xno" + then + without_zeromq=yes + elif test "x${zeromq_dir}" != "xyes" + then + with_arg="${zeromq_dir}/include:-L${zeromq_dir}/lib ${zeromq_dir}/include/zeromq:-L${zeromq_dir}/lib" + fi + + ## + AC_MSG_CHECKING(for zmq.hpp) + + if test "x$without_zeromq" != "xyes" + then + for i in $with_arg /usr/include: /usr/local/include:-L/usr/local/lib \ + /usr/pkg/include:-L/usr/pkg/lib + do + ac_zeromq_path=`echo "$i" | sed 's/:.*//'` + lib=`echo "$i" | sed 's/.*://'` + + if test -f ${ac_zeromq_path}/zmq.hpp + then + AC_MSG_RESULT(${ac_zeromq_path}/zmq.hpp) + ZEROMQ_LIBS="$lib -lzmq" + + AC_DEFINE(HAVE_ZEROMQ, 1, [define if you have ZeroMQ]) + have_zeromq=yes + break + fi + done + fi + + if test "x$have_zeromq" != "xyes"; then + AC_MSG_ERROR([The ZeroMQ library cannot be found. You may want to install zeromq-devel (RPM-based)/zeromq-dev (Debian-based) package.]) + fi + + ## ZeroMQ version + zeromq_lib_version_req=ifelse([$1], ,2.0,$1) + AC_MSG_CHECKING(for zeromq lib version >= $zeromq_lib_version_req) + succeeded=no + zeromq_lib_version_req_shorten=`expr $zeromq_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` + zeromq_lib_version_req_major=`expr $zeromq_lib_version_req : '\([[0-9]]*\)'` + zeromq_lib_version_req_minor=`expr $zeromq_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` + WANT_ZEROMQ_VERSION=`expr $zeromq_lib_version_req_major \* 100 \+ $zeromq_lib_version_req_minor` + + # The lines specifying the ZeroMQ version are like the following: + #define ZMQ_VERSION_MAJOR 2 + #define ZMQ_VERSION_MINOR 1 + #define ZMQ_VERSION_PATCH 4 + zeromq_version_major=`grep "define ZMQ_VERSION_MAJOR" ${ac_zeromq_path}/zmq.h | cut -d' ' -f3` + zeromq_version_minor=`grep "define ZMQ_VERSION_MINOR" ${ac_zeromq_path}/zmq.h | cut -d' ' -f3` + zeromq_version_computed=`expr $zeromq_version_major \* 100 \+ $zeromq_version_minor` + ZEROMQ_VERSION="${zeromq_version_major}.${zeromq_version_minor}" + + if test ${zeromq_version_computed} -ge ${WANT_ZEROMQ_VERSION} + then + AC_MSG_RESULT([yes (${ZEROMQ_VERSION}.)]) + else + AC_MSG_ERROR([The version (${ZEROMQ_VERSION}) of the ZeroMQ library is too old. You may want to upgrade your zeromq package.]) + fi + + ## + AC_SUBST([ZEROMQ_VERSION]) + AC_SUBST([ZEROMQ_CFLAGS]) + AC_SUBST([ZEROMQ_LIBS]) + +AC_LANG_RESTORE +]) diff --git a/src/Core/Archives.cpp b/src/Core/Archives.cpp new file mode 100644 index 0000000..017868d --- /dev/null +++ b/src/Core/Archives.cpp @@ -0,0 +1,92 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + + + +#include "Core/Archives.h" + +//#define BOOST_ARCHIVE_SOURCE +#include + +// explicitly instantiate for this type of xml stream +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + + +namespace boost { +namespace archive { + + + +template class detail::archive_serializer_map ; +template class basic_xml_oarchive ; +template class xml_oarchive_impl ; + +template class detail::archive_serializer_map ; +template class basic_xml_iarchive ; +template class xml_iarchive_impl ; + +template class detail::archive_serializer_map ; +template class basic_text_oarchive ; +template class text_oarchive_impl ; + +template class detail::archive_serializer_map ; +template class basic_text_iarchive ; +template class text_iarchive_impl ; + +template class detail::archive_serializer_map ; +template class basic_text_oarchive ; +template class text_oarchive_impl ; + +template class detail::archive_serializer_map ; +template class basic_text_iarchive ; +template class text_iarchive_impl ; + +template class detail::archive_serializer_map ; +template class basic_xml_oarchive ; +template class xml_oarchive_impl ; + + + + +} // namespace archive +} // namespace boost diff --git a/src/Core/Archives.h b/src/Core/Archives.h new file mode 100644 index 0000000..9e9e635 --- /dev/null +++ b/src/Core/Archives.h @@ -0,0 +1,784 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_ARCHIVES_H +#define U_CORE_ARCHIVES_H + + +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include "StringReader.h" + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// FWD DECLARATIONS OF ARCHIVES // + + + + +namespace uLib { +namespace Archive { + +class xml_iarchive; +class xml_oarchive; +class text_iarchive; +class text_oarchive; +class log_archive; + + +} +} + + +namespace boost { +namespace archive { +namespace detail { +template class polymorphic_oarchive_route; +template class polymorphic_iarchive_route; +} +} +} + +namespace boost { +namespace serialization { + template struct hrp; +} +} + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// ARCHIVES REGISTRATION // + + +namespace uLib { +namespace Archive { +namespace detail { +struct adl_tag {}; +} +} +} + +namespace boost { +namespace archive { +namespace detail { +// This function gets called, but its only purpose is to participate +// in overload resolution with the functions declared by +// BOOST_SERIALIZATION_REGISTER_ARCHIVE, below. +template +void instantiate_ptr_serialization(Serializable*, int, uLib::Archive::detail::adl_tag ) {} +} +} +} + +// The function declaration generated by this macro never actually +// gets called, but its return type gets instantiated, and that's +// enough to cause registration of serialization functions between +// Archive and any exported Serializable type. See also: +// boost/serialization/export.hpp +# define ULIB_SERIALIZATION_REGISTER_ARCHIVE(_Archive) \ +namespace boost { namespace archive { namespace detail { \ + \ +template \ +BOOST_DEDUCED_TYPENAME _ptr_serialization_support<_Archive, Serializable>::type \ +instantiate_ptr_serialization( Serializable*, _Archive*, uLib::Archive::detail::adl_tag ); }}} + + + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// ARCHIVES IO INTERFACES // + + +namespace boost { +namespace archive { +namespace detail { + +/** + * Custom implementation of boost interface_iarchive to add new operators + */ +template +class uLib_interface_iarchive +{ +protected: + uLib_interface_iarchive(){}; +public: + ///////////////////////////////////////////////////////// + // archive public interface + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + + template + const basic_pointer_iserializer * + register_type(T * = NULL){ + const basic_pointer_iserializer & bpis = + boost::serialization::singleton< + pointer_iserializer + >::get_const_instance(); + this->This()->register_basic_serializer(bpis.get_basic_serializer()); + return & bpis; + } + template + Archive & operator>>(T & t){ + this->This()->load_override(t, 0); + return * this->This(); + } + + // the & operator + template + Archive & operator&(T & t){ + return *(this->This()) >> t; + } + + // the == operator + template + Archive & operator == (T & t) { + return this->operator &(t); + } + + // the != operator for human readable access + template + Archive & operator != (T & t) { + std::cerr << std::flush << "cauch string: " << t << "\n"; // REMOVE THIS ! + return * this->This(); + } +}; + + +/** + * Custom implementation of boost interface_oarchive to add new operators + */ +template +class uLib_interface_oarchive { +protected: + uLib_interface_oarchive(){}; +public: + ///////////////////////////////////////////////////////// + // archive public interface + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + + template + const basic_pointer_oserializer * + register_type(const T * = NULL){ + const basic_pointer_oserializer & bpos = + boost::serialization::singleton< + pointer_oserializer + >::get_const_instance(); + this->This()->register_basic_serializer(bpos.get_basic_serializer()); + return & bpos; + } + + template + Archive & operator<<(T & t){ + // to get access you must redefine save_override by typing + // "using save_override" in archive impl + this->This()->save_override(t, 0); + return * this->This(); + } + + // the & operator + template + Archive & operator&(T & t){ + #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + return * this->This() << const_cast(t); + #else + return * this->This() << t; + #endif + } + + // the == operator + template + Archive & operator == (T & t) { + return this->operator &(t); + } + + // the != operator for human readable access + template + Archive & operator != (T & t) { + std::cerr << std::flush << "cauch string: " << t << "\n"; // REMOVE THIS ! + return * this->This(); + } +}; + + + +// DECLARE INTERFACE SPECIALIZATIONS /////////////////////////////////////////// +// With this declarations all uLib archive Implementation will use their own +// extended interface // + +template <> +class interface_iarchive : public + uLib_interface_iarchive {}; + +template <> +class interface_oarchive : public + uLib_interface_oarchive {}; + +template <> +class interface_iarchive : public + uLib_interface_iarchive {}; + +template <> +class interface_oarchive : public + uLib_interface_oarchive {}; + +template <> +class interface_oarchive : public + uLib_interface_oarchive {}; + + +//// Veritical repetition macro // FINIRE !!!!!!!!!!!!!!!!!!!!!!!!! +//#define _DECL_INTERFACE_ARCHIVE_V(vz,vn,vdata) \ +// template \ +// struct inherit_nofold : \ +// BOOST_PP_REPEAT(BOOST_PP_INC(vn),_INERIT_NOFOLD_H,~) \ +// {}; + +//// Multiple size declaration // +//BOOST_PP_REPEAT(ULIB_CFG_MPL_INERIT_NOFOLD_MAXSIZE,_INERIT_NOFOLD_V,~) + +//#undef _INERIT_NOFOLD_H +//#undef _INERIT_NOFOLD_V + + +} // detail +} // archive +} // boost + + + + + + + + + + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// ARCHIVES DEFINITIONS // + +namespace boost { +namespace archive { + +//template +//inline void load_const_override(Archive & ar, const char *t ){ +// typedef typename mpl::identity >::type typex; +// typex::invoke(ar, t); +//} + +//template +//inline void load(Archive & ar, T &t){ +// // if this assertion trips. It means we're trying to load a +// // const object with a compiler that doesn't have correct +// // funtion template ordering. On other compilers, this is +// // handled below. +// // detail::check_const_loading< T >(); +// typedef +// BOOST_DEDUCED_TYPENAME mpl::eval_if, +// mpl::identity > +// ,//else +// BOOST_DEDUCED_TYPENAME mpl::eval_if, +// mpl::identity > +// ,//else +// BOOST_DEDUCED_TYPENAME mpl::eval_if, +// mpl::identity > +// ,//else +// mpl::identity > +// > +// > +// >::type typex; +// typex::invoke(ar, t); +//} + + + +} +} + + + + +namespace uLib { + +namespace Archive { + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// POLYMORPHIC // + + +//class polymorphic_iarchive : +// public boost::archive::polymorphic_iarchive { + +//public: +// void load_override(const char *t, BOOST_PFTO int) +// { +// boost::archive::load_const_override(* this->This(), const_cast(t)); +// } + +//}; + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// XML // + +class xml_iarchive : + public boost::archive::xml_iarchive_impl, + public boost::archive::detail::shared_ptr_helper +{ + typedef xml_iarchive Archive; + typedef boost::archive::xml_iarchive_impl base; + + // give serialization implementation access to this class + friend class boost::archive::detail::interface_iarchive; + friend class boost::archive::basic_xml_iarchive; + friend class boost::archive::load_access; +public: + xml_iarchive(std::istream & is, unsigned int flags = 0) : + xml_iarchive_impl(is, flags) + {} + + using basic_xml_iarchive::load_override; + + // Anything not an attribute should be a name value pair as nvp or hrp + typedef boost::archive::detail::common_iarchive detail_common_iarchive; + template + void load_override( + #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + const + #endif + boost::serialization::hrp< T > & t, + int v + ){ + this->This()->load_start(t.name()); + this->detail_common_iarchive::load_override(t.value(), 0); +// t.stov(); + this->This()->load_end(t.name()); + } + + + // class_name_type can't be handled here as it depends upon the + // char type used by the stream. So require the derived implementation. + // derived in this case is xml_iarchive_impl or base .. + using base::load_override; + + void load_override(const char *str, int v) { + // StringReader sr(basic_text_iprimitive::is); + // sr >> str; + } + + ~xml_iarchive(){}; +}; + +//typedef boost::archive::detail::polymorphic_iarchive_route< +//boost::archive::xml_iarchive_impl +//> polymorphic_xml_iarchive; + +template +struct polymorphic_iarchive_route : + boost::archive::detail::polymorphic_iarchive_route +{ + virtual void load(const char * t){ + ArchiveImpl::load(t); + } +}; + + +class polymorphic_xml_iarchive : + public polymorphic_iarchive_route< boost::archive::xml_iarchive_impl > +{ + // give serialization implementation access to this class +// friend class boost::archive::detail::interface_iarchive; +// friend class boost::archive::basic_xml_iarchive; +// friend class boost::archive::load_access; +public: + virtual void load_override(const char *str, int v) { + ; + } +}; + + + +class xml_oarchive : + public boost::archive::xml_oarchive_impl +{ + typedef xml_oarchive Archive; + typedef boost::archive::xml_oarchive_impl base; + + // give serialization implementation access to this class + friend class boost::archive::detail::interface_oarchive; + friend class boost::archive::basic_xml_oarchive; + friend class boost::archive::save_access; +public: + xml_oarchive(std::ostream & os, unsigned int flags = 0) : + boost::archive::xml_oarchive_impl(os, flags) + {} + + // example of implementing save_override for const char* // + // void save_override(const char *t, int) { + // std::cout << "found char: " << t << "\n"; + // } + + using basic_xml_oarchive::save_override; + + // special treatment for name-value pairs. + typedef boost::archive::detail::common_oarchive detail_common_oarchive; + template + void save_override( + #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + const + #endif + ::boost::serialization::hrp< T > & t, + int v + ){ + this->This()->save_start(t.name()); +// t.vtos(); +// this->detail_common_oarchive::save_override(t.const_value(), 0); + this->This()->save_end(t.name()); + } + + void save_override(const char *str, int v) { + // Do not save any human decoration string // + // basic_text_oprimitive::save(str); + } + + ~xml_oarchive(){} +}; + +//typedef boost::archive::detail::polymorphic_oarchive_route< +//boost::archive::xml_oarchive_impl +//> polymorphic_xml_oarchive; + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// TEXT // + +class text_iarchive : + public boost::archive::text_iarchive_impl, + public boost::archive::detail::shared_ptr_helper +{ + typedef text_iarchive Archive; + typedef boost::archive::text_iarchive_impl base; + + // give serialization implementation access to this class + friend class boost::archive::detail::interface_iarchive; + friend class boost::archive::basic_text_iarchive; + friend class boost::archive::load_access; +public: + text_iarchive(std::istream & is, unsigned int flags = 0) : + text_iarchive_impl(is, flags) + {} + + using basic_text_iarchive::load_override; + + void load_override(boost::archive::object_id_type & t, int) {} + + // class_name_type can't be handled here as it depends upon the + // char type used by the stream. So require the derived implementation. + // derived in this case is xml_iarchive_impl or base .. + using base::load_override; + + void load_override(const char *str, int v) { + StringReader sr(basic_text_iprimitive::is); + sr >> str; + } + + ~text_iarchive() {}; +}; + +typedef text_iarchive naked_text_iarchive; + +//typedef boost::archive::detail::polymorphic_iarchive_route< +//naked_text_iarchive +//> polymorphic_text_iarchive; + + + +class text_oarchive : + public boost::archive::text_oarchive_impl +{ + typedef text_oarchive Archive; + typedef boost::archive::text_oarchive_impl base; + + // give serialization implementation access to this class + friend class boost::archive::detail::interface_oarchive; + friend class boost::archive::basic_text_oarchive; + friend class boost::archive::save_access; +public: + text_oarchive(std::ostream & os, unsigned int flags = 0) : + boost::archive::text_oarchive_impl(os, flags) + {} + + using basic_text_oarchive::save_override; + + void save_override(const char *str, int v) { + basic_text_oprimitive::save(str); + } + + ~text_oarchive(){} +}; + +//typedef boost::archive::detail::polymorphic_oarchive_route< +//boost::archive::text_oarchive_impl +//> polymorphic_text_oarchive; + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// SIMPLE HUMAN READABLE TEXT // + +class hrt_iarchive : + public boost::archive::text_iarchive_impl, + public boost::archive::detail::shared_ptr_helper +{ + typedef hrt_iarchive Archive; + typedef boost::archive::text_iarchive_impl base; + + // give serialization implementation access to this class + friend class boost::archive::detail::interface_iarchive; + friend class boost::archive::basic_text_iarchive; + friend class boost::archive::load_access; +public: + hrt_iarchive(std::istream & is, unsigned int flags = 0) : + base(is, flags | boost::archive::no_header ) + {} + + using basic_text_iarchive::load_override; + + // hide all archive props // + void load_override( boost::archive::object_id_type & t, int) {} + void load_override( boost::archive::object_reference_type & t, int) {} + void load_override( boost::archive::version_type & t, int) {} + void load_override( boost::archive::class_id_type & t, int) {} + void load_override( boost::archive::class_id_optional_type & t, int) {} + void load_override( boost::archive::class_id_reference_type & t, int){} + void load_override( boost::archive::class_name_type & t, int) {} + void load_override( boost::archive::tracking_type & t, int) {} + + // class_name_type can't be handled here as it depends upon the + // char type used by the stream. So require the derived implementation. + // derived in this case is xml_iarchive_impl or base .. + using base::load_override; + + void load_override(const char *str, int v) { + StringReader sr(basic_text_iprimitive::is); + sr >> str; + } + + ~hrt_iarchive() {}; +}; + + +class hrt_oarchive : + public boost::archive::text_oarchive_impl + { + typedef hrt_oarchive Archive; + typedef boost::archive::text_oarchive_impl base; + + // give serialization implementation access to this class + friend class boost::archive::detail::interface_oarchive; + friend class boost::archive::basic_text_oarchive; + friend class boost::archive::save_access; + public: + hrt_oarchive(std::ostream & os, unsigned int flags = 0) : + base(os, flags | boost::archive::no_header ) + {} + + using basic_text_oarchive::save_override; + + void save_override(const boost::archive::object_id_type & t, int) {} + void save_override(const boost::archive::object_reference_type & t, int) {} + void save_override(const boost::archive::version_type & t, int) {} + void save_override(const boost::archive::class_id_type & t, int) {} + void save_override(const boost::archive::class_id_optional_type & t, int) {} + void save_override(const boost::archive::class_id_reference_type & t, int){} + void save_override(const boost::archive::class_name_type & t, int) {} + void save_override(const boost::archive::tracking_type & t, int) {} + + + void save_override(const char *str, int v) { + basic_text_oprimitive::save(str); + } + + ~hrt_oarchive(){} + }; + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// XML FOR LOG OUTPUT PURPOUSE // + +///////////////////////////////////////////////////////////////////////// +// log data to an output stream. This illustrates a simpler implemenation +// of text output which is useful for getting a formatted display of +// any serializable class. Intended to be useful as a debugging aid. +class log_archive : + /* protected ? */ + public boost::archive::xml_oarchive_impl +{ + typedef boost::archive::xml_oarchive_impl base; + typedef log_archive Archive; + // give serialization implementation access to this clas + friend class boost::archive::detail::interface_oarchive; + friend class boost::archive::basic_xml_oarchive; + friend class boost::archive::save_access; + +public: + + void save_override(const char *str, int v) { + // Do not save any human decoration string // + // basic_text_oprimitive::save(str); + } + + template + void save_override(T & t, BOOST_PFTO int){ + base::save_override(boost::serialization::make_nvp(NULL, t), 0); + } + + // activate this if you want to trap non nvp objects // + // template + // void save_override(T & t, BOOST_PFTO int) + // { + // BOOST_MPL_ASSERT((boost::serialization::is_wrapper< T >)); + // // this->detail_common_oarchive::save_override(t, 0); + // } + + template + void save_override(const boost::serialization::nvp & t, int){ + base::save_override(t, 0); + } + + + // specific overrides for attributes - not name value pairs so we + // want to trap them before the above "fall through" + // since we don't want to see these in the output - make them no-ops. + void save_override(const boost::archive::object_id_type & t, int) {} + void save_override(const boost::archive::object_reference_type & t, int) {} + void save_override(const boost::archive::version_type & t, int) {} + void save_override(const boost::archive::class_id_type & t, int) {} + void save_override(const boost::archive::class_id_optional_type & t, int) {} + void save_override(const boost::archive::class_id_reference_type & t, int){} + void save_override(const boost::archive::class_name_type & t, int) {} + void save_override(const boost::archive::tracking_type & t, int) {} + + +public: + log_archive(std::ostream & os, unsigned int flags = 0) : + boost::archive::xml_oarchive_impl( + os, + flags | boost::archive::no_header + ) + {} +}; + +//typedef boost::archive::detail::polymorphic_oarchive_route< +//boost::archive::xml_oarchive_impl +//> polymorphic_log_archive; + + + + +} // Archive + + + +} // uLib + + +ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::xml_iarchive) +ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::xml_oarchive) +ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::text_iarchive) +ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::text_oarchive) +ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::hrt_iarchive) +ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::hrt_oarchive) +ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::log_archive) + +//ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::polymorphic_xml_iarchive) +//ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::polymorphic_xml_oarchive) +//ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::polymorphic_text_iarchive) +//ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::polymorphic_text_oarchive) +//ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::polymorphic_log_archive) + + + + +#endif // U_CORE_ARCHIVES_H diff --git a/src/Core/Array.h b/src/Core/Array.h new file mode 100644 index 0000000..0e42f07 --- /dev/null +++ b/src/Core/Array.h @@ -0,0 +1,72 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_ARRAY_H +#define U_CORE_ARRAY_H + +#include // std::array + +#include "Types.h" + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//// ERROR NOT WORKING CLASS, USE VECTOR INSTEAD ////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +namespace uLib { + +template< typename T, Size_t size > +class Array : public std::array { + +}; + + +template< typename T, Size_t size > +class SmartArray : public SmartPointer< Array > { + typedef SmartPointer< Array > ptr; +public: + SmartArray() : ptr(new Array()) { } + SmartArray( const SmartArray ©) : ptr(copy) { } + virtual ~SmartArray() {} + + T& operator[](unsigned int p) { + return ptr::get()->at(p); + } + + + +}; + + + +} + +#endif // ARRAY_H diff --git a/src/Core/CMakeLists.txt b/src/Core/CMakeLists.txt new file mode 100644 index 0000000..862ee5b --- /dev/null +++ b/src/Core/CMakeLists.txt @@ -0,0 +1,46 @@ + +set(HEADERS + Archives.h + Array.h + Collection.h + Debug.h + Export.h + Function.h + Macros.h + Mpl.h + Object.h + ObjectProps.h + Options.h + Serializable.h + Signal.h + Singleton.h + SmartPointer.h + StaticInterface.h + StringReader.h + Types.h + Uuid.h + Vector.h + CommaInitializer.h + ProgrammableAccessor.h +) + +SET(SOURCES + Archives.cpp + Object.cpp + Options.cpp + Serializable.cpp + Signal.cpp + Uuid.cpp +) + +set(LIBRARIES + ${Boost_SERIALIZATION_LIBRARY} + ${Boost_SIGNALS_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${ROOT_LIBRARIES} + ${PACKAGE_LIBPREFIX}Core + ${PACKAGE_LIBPREFIX}Math +) + +uLib_add_shared_library(${uLib-module}) +add_subdirectory(testing) diff --git a/src/Core/Collection.h b/src/Core/Collection.h new file mode 100644 index 0000000..b4be65f --- /dev/null +++ b/src/Core/Collection.h @@ -0,0 +1,101 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_COLLECTION_H +#define U_CORE_COLLECTION_H + +#include +#include + +#include "SmartPointer.h" +#include "Vector.h" + +//////////////////////////////////////////////////////////////////////////////// +/////// COLLECTION TEMPLATE ////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +// TODO: REWRITE THIS CLASS ... // + +namespace uLib { + +namespace Abstract { + +template +class Collection { +public: + virtual ~Collection() {} + + virtual void AddItem(T obj) =0; + virtual void RemoveItem(int i) =0; + virtual int GetNumberOfItems() =0; + virtual T& At(unsigned int i) =0; + + virtual void PrintSelf(std::ostream &o) =0; +}; + +} + + +template +class Collection : public Abstract::Collection { + +public: + Collection() : data() {} + Collection(int size) : data(size) {} + ~Collection() {} + + inline void AddItem(T obj) { data->push_back(obj); } + inline void RemoveItem(int i) { data.remove_element(i); } + inline int GetNumberOfItems() { return data->size(); } + + inline T& At(unsigned int i) { return data->at(i); } + inline T& operator[] (unsigned int i) { return data->at(i); } + + inline void PrintSelf(std::ostream &o); + +private: + SmartVector data; +}; + + +template +void Collection::PrintSelf(std::ostream &o) +{ + o << " *** uLib Collection *** \n"; + o << " n. of items = " << this->GetNumberOfItems() << "\n"; +} + + +} + + + + + + + +#endif // COLLECTION_H diff --git a/src/Core/CommaInitializer.h b/src/Core/CommaInitializer.h new file mode 100644 index 0000000..262b918 --- /dev/null +++ b/src/Core/CommaInitializer.h @@ -0,0 +1,89 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + +#ifndef U_CORE_COMMAINITIALIZER_H +#define U_CORE_COMMAINITIALIZER_H + +namespace uLib { + +// Comma Initializer template ... +// ContentT should provide operator[] and resize() methods. +// Waiting for Static interface check + +template < typename ContainerT, typename ContentT > +struct CommaInitializer +{ + inline explicit CommaInitializer(ContainerT *container, ContentT s) + : container(container) + { + this->index = 0; + container->resize(1); + this->container->operator[](0) = s; + } + inline CommaInitializer & operator, (ContentT s) { + this->index++; + container->resize(index + 1); + this->container->operator[](this->index) = s; + return *this; + } + + ContainerT *container; + unsigned int index; +}; + + +// Comma Initializer template for fixed array... +// ContentT should provide operator[] and size() methods. +// Waiting for Static interface check + +template < typename ContainerT, typename ContentT > +struct CommaInitializerFixed +{ + inline explicit CommaInitializerFixed(ContainerT *container, ContentT s) + : container(container) + { + this->index = 0; + this->container->operator[](0) = s; + } + inline CommaInitializerFixed & operator, (ContentT s) { + this->index++; + this->container->operator[](this->index) = s; + return *this; + } + + ContainerT *container; + unsigned int index; +}; + + + + + + +} // uLib + + + +#endif // COMMAINITIALIZER_H diff --git a/src/Core/Debug.cpp b/src/Core/Debug.cpp new file mode 100644 index 0000000..09603cb --- /dev/null +++ b/src/Core/Debug.cpp @@ -0,0 +1,31 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Debug.h" + + diff --git a/src/Core/Debug.h b/src/Core/Debug.h new file mode 100644 index 0000000..cd70930 --- /dev/null +++ b/src/Core/Debug.h @@ -0,0 +1,148 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_DEBUG_H +#define U_CORE_DEBUG_H + + + +#include "ltk/ltkdebug.h" +#include "Macros.h" +#include "Types.h" +#include "Mpl.h" +#include "Vector.h" + +#include +#include + +namespace uLib { + + +namespace detail { + +struct DebugAdapterInterface { + virtual ~DebugAdapterInterface() {} + + virtual void operator()(char val) {} + virtual void operator()(unsigned char val) {} + virtual void operator()(short val) {} + virtual void operator()(unsigned short val) {} + virtual void operator()(int val) {} + virtual void operator()(unsigned int val) {} + virtual void operator()(long val) {} + virtual void operator()(unsigned long val) {} + + virtual void operator()(float val) {} + virtual void operator()(double val) {} + + virtual void operator()(std::string val) {} +}; + + +struct DebugAdapter { + struct AnyCastAdapterBase { + virtual ~AnyCastAdapterBase(){} + virtual void operator()(SmartPointer &ad, boost::any &val) {} + }; + + template < typename T > + struct AnyCastAdapter : AnyCastAdapterBase { + void operator()(SmartPointer &ad, boost::any &val) { ad->operator()(boost::any_cast(val)); } + }; + + struct DItem { + DItem(){} + template DItem(std::string str, T &t) : + m_adapter(new AnyCastAdapter()), + m_name(str), + m_value(t) { } + + SmartPointer m_adapter; + std::string m_name; + boost::any m_value; + }; + +}; + + +} // detail + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// text ADAPTER + +class DebugAdapterText : public detail::DebugAdapterInterface { + std::ostream &m_out; +public: + DebugAdapterText(std::ostream &o) : m_out(o) {} + void operator()(int val) { m_out << "debug: " << val << "\n"; } + void operator()(std::string val) { m_out << "debug: " << val << "\n"; } +}; + + + + + +class Debug { + typedef detail::DebugAdapterInterface AdapterInterface; + typedef SmartPointer Adapter; + typedef detail::DebugAdapter::DItem DItem; +public: + + template void operator() (std::string str, T &t) { m_v.push_back(DItem(str,t)); } + + void AddAdapter(AdapterInterface &ad) { m_a.push_back(Adapter(ad)); } + + void Update() { + foreach(Adapter &ad, m_a) { + foreach(DItem &item, m_v) { + item.m_adapter->operator()(ad, item.m_value); + } + } + } + +private: + Vector m_v; + Vector m_a; +}; + + + + + + +} // uLib + + + + + + + +#endif // DEBUG_H diff --git a/src/Core/DebugArchives.cpp b/src/Core/DebugArchives.cpp new file mode 100644 index 0000000..3620d7a --- /dev/null +++ b/src/Core/DebugArchives.cpp @@ -0,0 +1,52 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + + +#include +#include "DebugArchives.h" + +namespace uLib { +namespace Archive { +namespace detail { + +basic_Root_Ttree_oprimitive::basic_Root_Ttree_oprimitive(const char *tree_name) +{ + m_tree = new TTree(tree_name,tree_name); +} + +basic_Root_Ttree_oprimitive::~basic_Root_Ttree_oprimitive() +{ + m_tree->Write(); + m_tree->ResetBranchAddresses(); + m_tree->Delete(); +} + +} // detail +} // Archive +} // uLib + diff --git a/src/Core/DebugArchives.h b/src/Core/DebugArchives.h new file mode 100644 index 0000000..1109635 --- /dev/null +++ b/src/Core/DebugArchives.h @@ -0,0 +1,289 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_DEBUGARCHIVES_H +#define U_CORE_DEBUGARCHIVES_H + +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include "Archives.h" +#include "StringReader.h" + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// FWD DECLARATIONS OF ARCHIVES // + + +namespace uLib { +namespace Archive { + +class Root_debug_archive; + +} +} + + +namespace boost { +namespace archive { +namespace detail { +template class polymorphic_oarchive_route; +template class polymorphic_iarchive_route; +} +} +} + +namespace boost { +namespace serialization { + template struct hrp; +} +} + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// ARCHIVES REGISTRATION // + +// in Archives.h + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// ARCHIVES IO INTERFACES // + + +namespace boost { +namespace archive { +namespace detail { + + +// DECLARE INTERFACE SPECIALIZATIONS /////////////////////////////////////////// +// With this declarations all uLib archive Implementation will use their own +// extended interface // + +template <> +class interface_iarchive : public + uLib_interface_iarchive {}; + + +} // detail +} // archive +} // boost + + + + + + + + + + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// ARCHIVES DEFINITIONS // + +namespace boost { +namespace archive { + +//template +//inline void load_const_override(Archive & ar, const char *t ){ +// typedef typename mpl::identity >::type typex; +// typex::invoke(ar, t); +//} + +//template +//inline void load(Archive & ar, T &t){ +// // if this assertion trips. It means we're trying to load a +// // const object with a compiler that doesn't have correct +// // funtion template ordering. On other compilers, this is +// // handled below. +// // detail::check_const_loading< T >(); +// typedef +// BOOST_DEDUCED_TYPENAME mpl::eval_if, +// mpl::identity > +// ,//else +// BOOST_DEDUCED_TYPENAME mpl::eval_if, +// mpl::identity > +// ,//else +// BOOST_DEDUCED_TYPENAME mpl::eval_if, +// mpl::identity > +// ,//else +// mpl::identity > +// > +// > +// >::type typex; +// typex::invoke(ar, t); +//} + + + +} +} + +// ROOT FWD +class TTree; +/////////// + + +namespace uLib { +namespace Archive { + +namespace detail { + +class basic_Root_Ttree_oprimitive +{ + TTree *m_tree; + + + +public: + basic_Root_Ttree_oprimitive(const char *tree_name); + ~basic_Root_Ttree_oprimitive(); + +}; + +} // detail + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// XML FOR LOG OUTPUT PURPOUSE // + +/////////////////////////////////////////////////////////////////////////// +//// log data to an output stream. This illustrates a simpler implemenation +//// of text output which is useful for getting a formatted display of +//// any serializable class. Intended to be useful as a debugging aid. +class Root_debug_archive : + /* protected ? */ + public boost::archive::detail::common_oarchive +{ + typedef boost::archive::detail::common_oarchive base; + typedef Root_debug_archive Archive; + + // give serialization implementation access to this clas + friend class boost::archive::detail::interface_oarchive; + friend class boost::archive::save_access; + +public: + +// void save_override(const char *str, int v) { +// // Do not save any human decoration string // +// // basic_text_oprimitive::save(str); +// } + +// template +// void save_override(T & t, BOOST_PFTO int){ +// base::save_override(boost::serialization::make_nvp(NULL, t), 0); +// } + +// // activate this if you want to trap non nvp objects // +// // template +// // void save_override(T & t, BOOST_PFTO int) +// // { +// // BOOST_MPL_ASSERT((boost::serialization::is_wrapper< T >)); +// // // this->detail_common_oarchive::save_override(t, 0); +// // } + +// template +// void save_override(const boost::serialization::nvp & t, int){ +// base::save_override(t, 0); +// } + + +// // specific overrides for attributes - not name value pairs so we +// // want to trap them before the above "fall through" +// // since we don't want to see these in the output - make them no-ops. +// void save_override(const boost::archive::object_id_type & t, int) {} +// void save_override(const boost::archive::object_reference_type & t, int) {} +// void save_override(const boost::archive::version_type & t, int) {} +// void save_override(const boost::archive::class_id_type & t, int) {} +// void save_override(const boost::archive::class_id_optional_type & t, int) {} +// void save_override(const boost::archive::class_id_reference_type & t, int){} +// void save_override(const boost::archive::class_name_type & t, int) {} +// void save_override(const boost::archive::tracking_type & t, int) {} + + +//public: +// Root_debug_archive(std::ostream & os, unsigned int flags = 0) : +// boost::archive::xml_oarchive_impl( +// os, +// flags | boost::archive::no_header +// ) +// {} +}; + + + + + +} // Archive +} // uLib + + + +ULIB_SERIALIZATION_REGISTER_ARCHIVE(uLib::Archive::Root_debug_archive) + + + + + + +#endif // U_CORE_DEBUGARCHIVES_H diff --git a/src/Core/Export.h b/src/Core/Export.h new file mode 100644 index 0000000..1b43cd0 --- /dev/null +++ b/src/Core/Export.h @@ -0,0 +1,117 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_EXPORT_H +#define U_CORE_EXPORT_H + +#include +#include // NULL +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include // for guid_defined only +#include +#include +#include +#include + +#include + + +#include "Core/Archives.h" + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + + +namespace uLib { +namespace Archive { +namespace detail { +namespace extra_detail { + +template +struct guid_initializer +{ + void export_guid(mpl::false_) const { + // generates the statically-initialized objects whose constructors + // register the information allowing serialization of T objects + // through pointers to their base classes. + boost::archive::detail:: + instantiate_ptr_serialization((T*)0, 0, + uLib::Archive::detail::adl_tag()); + } + void export_guid(mpl::true_) const { + } + guid_initializer const & export_guid() const { + BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); + // note: exporting an abstract base class will have no effect + // and cannot be used to instantitiate serialization code + // (one might be using this in a DLL to instantiate code) + //BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value); + export_guid(boost::serialization::is_abstract< T >()); + return *this; + } +}; + +template +struct init_guid; + +} // anonymous +} // namespace detail +} // namespace Archive +} // namespace uLib + + + +#define ULIB_CLASS_EXPORT_IMPLEMENT(T) \ + namespace uLib { \ + namespace Archive { \ + namespace detail { \ + namespace extra_detail { \ + template<> \ + struct init_guid< T > { \ + static guid_initializer< T > const & g; \ + }; \ + guid_initializer< T > const & init_guid< T >::g = \ + ::boost::serialization::singleton< \ + guid_initializer< T > \ + >::get_mutable_instance().export_guid(); \ + }}}} \ +/**/ + +#endif // EXPORT_H diff --git a/src/Core/Flags.h b/src/Core/Flags.h new file mode 100644 index 0000000..1ce1a2d --- /dev/null +++ b/src/Core/Flags.h @@ -0,0 +1,54 @@ +#ifndef FLAGS_H +#define FLAGS_H + +#include + +namespace uLib { + +template +class Flags +{ + int i; +public: + typedef Enum enum_type; + CONSTEXPR inline Flags(const Flags &f) : i(f.i) {} + CONSTEXPR inline Flags(Enum f) : i(f) {} + CONSTEXPR inline Flags() : i(0) {} + + inline Flags &operator=(const Flags &f) { i = f.i; return *this; } + inline Flags &operator&=(int mask) { i &= mask; return *this; } + inline Flags &operator&=(uint mask) { i &= mask; return *this; } + inline Flags &operator|=(Flags f) { i |= f.i; return *this; } + inline Flags &operator|=(Enum f) { i |= f; return *this; } + inline Flags &operator^=(Flags f) { i ^= f.i; return *this; } + inline Flags &operator^=(Enum f) { i ^= f; return *this; } + + CONSTEXPR inline operator int() const { return i; } + + CONSTEXPR inline Flags operator|(Flags f) const { return Flags(Enum(i | f.i)); } + CONSTEXPR inline Flags operator|(Enum f) const { return Flags(Enum(i | f)); } + CONSTEXPR inline Flags operator^(Flags f) const { return Flags(Enum(i ^ f.i)); } + CONSTEXPR inline Flags operator^(Enum f) const { return Flags(Enum(i ^ f)); } + CONSTEXPR inline Flags operator&(int mask) const { return Flags(Enum(i & mask)); } + CONSTEXPR inline Flags operator&(uint mask) const { return Flags(Enum(i & mask)); } + CONSTEXPR inline Flags operator&(Enum f) const { return Flags(Enum(i & f)); } + CONSTEXPR inline Flags operator~() const { return Flags(Enum(~i)); } + + CONSTEXPR inline bool operator!() const { return !i; } + + inline bool testFlag(Enum f) const { return (i & f) == f && (f != 0 || i == int(f) ); } +}; + +#define ULIB_OPERATORS_FOR_FLAGS(Flags) \ +CONSTEXPR inline QFlags operator|(Flags::enum_type f1, Flags::enum_type f2) \ +{ return QFlags(f1) | f2; } \ +CONSTEXPR inline QFlags operator|(Flags::enum_type f1, QFlags f2) \ +{ return f2 | f1; } + + +} // uLib + + + + +#endif // FLAGS_H diff --git a/src/Core/Function.h b/src/Core/Function.h new file mode 100644 index 0000000..632dbb4 --- /dev/null +++ b/src/Core/Function.h @@ -0,0 +1,160 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_FUNCTION_H +#define U_CORE_FUNCTION_H + +#include + +#include +#include +#include + +#include +#include +#include + + +//#include + + +namespace uLib { + + + + + + + +namespace detail { + +//////////////////////////////////////////////////////////////////////////////// +// type synthesize ( please read: boost implementation synthesize.hpp ) // +//////////////////////////////////////////////////////////////////////////////// +// TODO: change this to boost implementation // +// return a reference to function ... as the boost signal signature wants + +template +struct FunctionTypes {}; + +template +struct FunctionTypes< R(O::*)() > { + typedef R ref(); + typedef R (ptr)(); + typedef O obj; +}; + +template +struct FunctionTypes< R(O::*)(T0) > { + typedef R ref(T0); + typedef R (ptr)(T0); + typedef O obj; +}; + +template +struct FunctionTypes< R(O::*)(T0,T1) > { + typedef R ref(T0,T1); + typedef R (ptr)(T0,T1); + typedef O obj; +}; + +template +struct FunctionTypes< R(O::*)(T0,T1,T2) > { + typedef R ref(T0,T1,T2); + typedef R (ptr)(T0,T1,T2); + typedef O obj; +}; + +} // detail + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// Function Types // + +template +struct FunctionTypes { + typedef typename boost::function_types::function_type::type Signature; + typedef typename detail::FunctionTypes::ref SignalSignature; + enum { + arity = boost::function_types::function_arity::value, + ismfp = boost::is_member_function_pointer::value + }; + + typedef boost::mpl::bool_< ismfp > HasObjectType; + typedef typename detail::FunctionTypes::obj Object; + typedef boost::function_traits< Signature > Traits; + + virtual void PrintSelf( std::ostream &o ) { + o << "[fp: " << typeid(Signature).name() + << " arity: " << arity << "]\n"; } +}; + + + + + + + +//////// generic mfp container object ///////////////////////////////////////// + +class GenericMFPtr { + typedef void (GenericMFPtr::*VoidMFPtr)(); +public: + typedef VoidMFPtr type; + + GenericMFPtr() {} + + template + GenericMFPtr(T in) { + m_ptr = reinterpret_cast(in); + } + + template + inline bool operator == (T in) { + return m_ptr == reinterpret_cast(in); + } + + inline bool operator == (const GenericMFPtr &in) { + return m_ptr == in.m_ptr; + } + + VoidMFPtr operator()() { return m_ptr; } + + VoidMFPtr m_ptr; +private: +}; + +} // uLib + + + + +#endif // FUNCTION_H diff --git a/src/Core/Macros.h b/src/Core/Macros.h new file mode 100644 index 0000000..6218dba --- /dev/null +++ b/src/Core/Macros.h @@ -0,0 +1,173 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_MACROS_H +#define U_CORE_MACROS_H + +//#ifndef HAVE_CONFIG_H +#include "config.h" +//#endif + +#include + +#define uLibAssert(condition) assert(condition) + + +// Symbols visibility attribute, see: http://gcc.gnu.org/wiki/Visibility // +// http://stackoverflow.com/questions/5116333/dynamic-cast-failed-when-hidding-symbol // +#if defined _WIN32 || defined __CYGWIN__ + #ifdef BUILDING_DLL + #ifdef __GNUC__ + #define DLL_PUBLIC __attribute__ ((dllexport)) + #else + #define DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax. + #endif + #else + #ifdef __GNUC__ + #define DLL_PUBLIC __attribute__ ((dllimport)) + #else + #define DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax. + #endif + #endif + #define DLL_LOCAL +#else + #if __GNUC__ >= 4 + #define DLL_PUBLIC __attribute__ ((visibility ("default"))) + #define DLL_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define DLL_PUBLIC + #define DLL_LOCAL + #endif +#endif + + + +// foreach Qt style +#ifndef foreach +#include "boost/foreach.hpp" +#define foreach(ref, list) BOOST_FOREACH(ref,list) +#endif + + + + + + + + +// TODO: verificare necessita' di typecast //////////////////////////////// + +#define uLibVGetMacro(name,type) \ + virtual inline const type Get##name() const = 0; + +#define uLibVSetMacro(name,type) \ + virtual inline void Set##name(const type name) = 0; + +#define uLibVGetSetMacro(name,type) \ + uLibVGet(name,type); \ + uLibVSet(name,type); + +#define uLibVRefMacro(name,type) \ + virtual inline type & name() = 0; + +#define uLibPtrMacro(name,type) \ + inline type name() const { return this->m_##name; } + +#define uLibArrayMacro(name,type) \ + inline type name() { return this->m_##name; } + +#define uLibGetMacro(name,type) \ + inline type Get##name() const { return this->m_##name; } + +#define uLibSetMacro(name,type) \ + inline void Set##name(type name) { this->m_##name = name; } + +#define uLibGetSetMacro(name,type) \ + inline type Get##name() const { return this->m_##name; } \ + uLibSetMacro(name,type); + +#define uLibRefMacro(name,type) \ + inline type & name() { return this->m_##name; } + +#define uLibConstRefMacro(name,type) \ + inline const type & name() const { return this->m_##name; } + +#define uLibAccessMacro(name,type) \ + inline void name(type name) { this->m_##name = name; } \ + uLibConstRefMacro(name,type) + + +#define uLib_CRTP_ACCESS(_Derive,_name) \ + inline _Derive * _name() { return reinterpret_cast<_Derive *>(this); } \ + inline const _Derive * _name() const { return reinterpret_cast(this); } \ + // + +#define uLib_CRTP_ACCESS_CASTED(_Derive,_Target,_name) \ + inline _Target _name() { return (_Target)(static_cast<_Derive &>(*this)); } \ + inline const _Target _name() const { return (const _Target)(static_cast(*this)); } \ + // + + + + + + + + + + +/* Following macros override usual branch prediction of compiler + * These are to be used in conditional statement whose result might + * be Bayesian biased: + * + * // previous_line + * if (likely(a>1)) { // block_1 } + * else { block_2 } + * + * will write the block_1 code right after previous line, without using + * compiler branch prediction for results. Otherwise + * + * // previous_line + * if (unlikely(a>1)) { // block_1 } + * else { block_2 } + * + * will write block_2 after previous_line, leaving block_1 after + * (usually after the end of the whole function! Use with care!) + */ + +#define unlikely(expr) __builtin_expect(!!(expr), 0) + +#define likely(expr) __builtin_expect(!!(expr), 1) + +/* Fastsign + */ +// #define sign(x) (( x > 0 ) - ( x < 0 )) +template +inline T sign(const T x) { return x>0 - x<0; } + + +#endif // MACROS_H diff --git a/src/Core/Makefile.am b/src/Core/Makefile.am new file mode 100644 index 0000000..2bb1092 --- /dev/null +++ b/src/Core/Makefile.am @@ -0,0 +1,41 @@ +SUBDIRS = . + +include $(top_srcdir)/Common.am + +library_includedir = $(includedir)/libmutom-${PACKAGE_VERSION}/Core + +library_include_HEADERS = \ + Archives.h \ + Array.h \ + Collection.h \ + Debug.h \ + Export.h \ + Function.h \ + Macros.h \ + Mpl.h \ + Object.h \ + ObjectProps.h \ + Options.h \ + Serializable.h \ + Signal.h \ + Singleton.h \ + SmartPointer.h \ + StaticInterface.h \ + StringReader.h \ + Types.h \ + Uuid.h \ + Vector.h + + +_CORE_SOURCES = \ + Archives.cpp \ + Debug.cpp \ + Object.cpp \ + Options.cpp \ + Serializable.cpp \ + Signal.cpp \ + Uuid.cpp + + +noinst_LTLIBRARIES = libmutomcore.la +libmutomcore_la_SOURCES = ${_CORE_SOURCES} diff --git a/src/Core/Mpl.h b/src/Core/Mpl.h new file mode 100644 index 0000000..d7f0130 --- /dev/null +++ b/src/Core/Mpl.h @@ -0,0 +1,139 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_MPL_H +#define U_MPL_H + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +/** + * Max size of nofold inerited capability + */ +#ifndef ULIB_CFG_MPL_INERIT_NOFOLD_MAXSIZE +# define ULIB_CFG_MPL_INERIT_NOFOLD_MAXSIZE 10 +#endif + +namespace uLib { + +namespace mpl { + +using namespace boost::mpl; +using namespace boost::mpl::placeholders; + +//using boost::enable_if; + +namespace detail { + +/** + * Inerit nofold implementation, set ULIB_CFG_MPL_INERIT_NOFOLD_MAXSIZE to + * desired max derivation size keeping in mind that total size accounts all + * mutiple inherited classes. + */ +template +struct inherit_nofold {}; + +// Horizontal repetition macro // +#define _INERIT_NOFOLD_H(hz,hn,hdata) \ + BOOST_PP_COMMA_IF(hn) \ + mpl::at >::type + +// Veritical repetition macro // +#define _INERIT_NOFOLD_V(vz,vn,vdata) \ + template \ + struct inherit_nofold : \ + BOOST_PP_REPEAT(BOOST_PP_INC(vn),_INERIT_NOFOLD_H,~) \ + {}; + +// Multiple size declaration // +BOOST_PP_REPEAT(ULIB_CFG_MPL_INERIT_NOFOLD_MAXSIZE,_INERIT_NOFOLD_V,~) + +#undef _INERIT_NOFOLD_H +#undef _INERIT_NOFOLD_V + + +} // detail + +/** + * Build a derivation tuple from mpl type sequence. + * The same behavior can be obtained by inherit_linearly but folding derivation + * results in a hard to read debugging + */ +template +struct inherit_nofold { + typedef detail::inherit_nofold< TypeSeq, mpl::size::type::value > type; +}; + +/** INHERIT LINEARLY standard utility macro */ +#define ULIB_MPL_INHERIT_SEQ(_TypeList) \ + uLib::mpl::inherit_linearly< _TypeList, mpl::inherit< mpl::_1, mpl::_2 > >::type + +/** INHERIT NOFOLD utility macro (see struct inherit_nofold template) */ +#define ULIB_MPL_INHERIT_NOFOLD_SEQ(_TypeList) \ + uLib::mpl::inherit_nofold< _TypeList >::type + + + + +template< class T> +struct type { + +}; + +template +struct nvp { + nvp() : name(N) {} + const char *name; + typedef T type; +}; + + +} // mpl + +} // uLib + +#endif // MPL_H diff --git a/src/Core/Object.cpp b/src/Core/Object.cpp new file mode 100644 index 0000000..bbaef39 --- /dev/null +++ b/src/Core/Object.cpp @@ -0,0 +1,227 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + + +#include "config.h" + +#include "Object.h" +#include "Vector.h" + +#include "boost/archive/polymorphic_xml_oarchive.hpp" +#include "boost/archive/polymorphic_xml_iarchive.hpp" +#include "boost/archive/polymorphic_text_oarchive.hpp" +#include "boost/archive/polymorphic_text_iarchive.hpp" +#include "boost/archive/polymorphic_binary_oarchive.hpp" +#include "boost/archive/polymorphic_binary_iarchive.hpp" + + + +namespace uLib { + + +const char *Version::PackageName = PACKAGE_NAME; +const char *Version::VersionNumber = PACKAGE_VERSION; +const char *Version::Release = SVN_REVISION; + + +//////////////////////////////////////////////////////////////////////////////// +// Object Private // + +class ObjectPrivate { +public: + + struct Signal { + GenericMFPtr sigptr; + std::string sigstr; + SignalBase *signal; + }; + + struct Slot { + GenericMFPtr sloptr; + std::string slostr; + }; + + + Vector sigv; + Vector slov; +}; + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// OBJECT IMPLEMENTATION + + + +Object::Object() : + d(new ObjectPrivate) +{} + +Object::Object(const Object ©) : + ObjectPropable(copy), + d(new ObjectPrivate(*copy.d)) +{} + +Object::~Object() { + delete d; +} + +void Object::DeepCopy(const Object ©) +{ + // should lock to be tread safe // + memcpy(d,copy.d,sizeof(ObjectPrivate)); + // ERROR! does not copy parameters ... <<<< FIXXXXX +} + + + + + +void Object::SaveXml(std::ostream &os, Object &ob) +{ + Archive::xml_oarchive ar(os); + ar << boost::serialization::make_nvp("Object",ob); +} + +void Object::LoadXml(std::istream &is, Object &ob) +{ + Archive::xml_iarchive ar(is); + ar >> boost::serialization::make_nvp("Object",ob); +} + + +// FINIRE +void Object::SaveConfig(std::ostream &os, int version) +{ + Archive::xml_oarchive ar(os); + ObjectPropable::serialize(ar,0); +} + +void Object::LoadConfig(std::istream &is, int version) +{ + if(!props()) this->init_properties(); + Archive::xml_iarchive ar(is); + ObjectPropable::serialize(ar,0); +} + + + + + +void Object::PrintSelf(std::ostream &o) const +{ + o << "OBJECT signals: ------------------\n"; + Vector::Iterator itr; + for(itr = d->sigv.begin(); itrsigv.end(); itr++) + { + o << " signal:[ " << itr->sigstr << " ]\n"; + } + o << "--------------------------------------\n\n"; +} + + +bool Object::addSignalImpl(SignalBase *sig, GenericMFPtr fptr, const char *name) +{ + ObjectPrivate::Signal s = {fptr,std::string(name),sig}; + d->sigv.push_back(s); +} + +bool Object::addSlotImpl(GenericMFPtr fptr, const char *name) +{ + ObjectPrivate::Slot s = {fptr,std::string(name)}; + d->slov.push_back(s); +} + +SignalBase *Object::findSignalImpl(const GenericMFPtr &fptr) const +{ + for(int i=0; isigv.size(); ++i) + { + if(d->sigv[i].sigptr == fptr) + return d->sigv[i].signal; + } + return NULL; +} + +SignalBase *Object::findSignalImpl(const char *name) const +{ + std::string in(name); + for(int i=0; isigv.size(); ++i) + { + if(d->sigv[i].sigstr == in) + return d->sigv[i].signal; + } + return NULL; +} + +GenericMFPtr *Object::findSlotImpl(const char *name) const +{ + std::string in(name); + for(int i=0; islov.size(); ++i) + { + if(d->slov[i].slostr == in) + return &d->slov[i].sloptr; + } + return NULL; +} + + + + +std::ostream & +operator << (std::ostream &os, uLib::Object &ob) +{ + uLib::Object *op = &ob; + uLib::Archive::hrt_oarchive (os) << op; + return os; +} + +std::ostream & +operator << (std::ostream &os, uLib::Object *ob) +{ + uLib::Archive::hrt_oarchive(os) << ob; + return os; +} + +std::istream & +operator >> (std::istream &is, uLib::Object &ob) +{ +// uLib::Object *op = &ob; + uLib::Archive::hrt_iarchive(is) >> ob; + return is; +} + + + + +} // uLib + + + diff --git a/src/Core/Object.h b/src/Core/Object.h new file mode 100644 index 0000000..0f1f417 --- /dev/null +++ b/src/Core/Object.h @@ -0,0 +1,222 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_OBJECT_H +#define U_CORE_OBJECT_H + +#include + +// WARNING: COPILE ERROR if this goes after mpl/vector // +//#include "Core/Vector.h" + +#include "Core/Types.h" +#include "Core/Debug.h" + +#include "Core/Function.h" +#include "Core/Signal.h" + +#include "Core/Mpl.h" +#include "Core/Serializable.h" +#include "Core/ObjectProps.h" +#include "Core/Uuid.h" + +namespace boost { +namespace archive { +class polymorphic_iarchive; +class polymorphic_oarchive; +} // archive +} // boost + + +namespace uLib { + + +class Version { +public: + static const char *PackageName; + static const char *VersionNumber; + static const char *Release; +}; + + + + + + +//////////////////////////////////////////////////////////////////////////////// +//// OBJECT //////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + + +/** + * @brief Object class is the object base implementation for uLib Framework. + */ +class Object : public ObjectPropable +{ + + +public: + // std::string name; + // void PrintName() { std::cout << "Ob name: " << name << "\n"; } + + Object(); + Object(const Object ©); + ~Object(); + + //////////////////////////////////////////////////////////////////////////// + // PARAMETERS // + + // FIXX !!! + virtual void DeepCopy(const Object ©); + + + //////////////////////////////////////////////////////////////////////////// + // SERIALIZATION // + + template void serialize(ArchiveT &ar, const unsigned int version) { + ObjectPropable::serialize(ar,version); + } + template void save_override(ArchiveT &ar,const unsigned int version) {} + + void SaveConfig(std::ostream &os, int version = 0); + void LoadConfig(std::istream &is, int version = 0); + + static void SaveXml(std::ostream &os, Object &ob); + static void LoadXml(std::istream &is, Object &ob); + + + + //////////////////////////////////////////////////////////////////////////// + // SIGNALS // + + // Qt4 style connector // + static bool connect(const Object *ob1, const char *signal_name, const Object *receiver, const char *slot_name) { + // // NOT WORKING YET // + // 1) find slot pointer from name + // SignalBase *sig = ob1->findSignal(signal_name); + // GenericMFPtr *slo = receiver->findSlot(slot_name); + // if(sig && slo) + // return Object::connect(sig,slo->operator ()(),receiver); + // else return false; + } + + // Qt5 style connector // + template + static bool connect( typename FunctionTypes::Object *sender, Func1 sigf, + typename FunctionTypes::Object *receiver, Func2 slof) + { + SignalBase *sigb = sender->findOrAddSignal(sigf); + typedef boost::signals2::signal::SignalSignature> SigT; + ConnectSignal(sigb,slof,receiver); + } + + template + static inline bool connect(SignalBase *sigb, FuncT slof, Object *receiver) { + ConnectSignal(sigb,slof,receiver); + } + + + template< typename FuncT > + inline typename Signal::SignalSignature>::type * + addSignal(FuncT fun, const char *name) { + typedef typename Signal::SignalSignature>::type SigT; + SignalBase *sig = NewSignal(fun); + addSignalImpl(sig,fun,name); + return (SigT *)sig; + } + + template< typename FuncT> + inline bool addSlot(FuncT fun, const char *name) { + this->addSlotImpl(GenericMFPtr(fun),name); + } + + template < typename FuncT > + inline typename Signal::SignalSignature>::type * + findSignal(FuncT fptr) + { + typedef typename Signal::SignalSignature>::type SigT; + return (SigT *)findSignalImpl(GenericMFPtr(fptr)); + } + + template < typename FuncT > + inline typename Signal::SignalSignature>::type * + findOrAddSignal(FuncT fptr) + { + typedef typename Signal::SignalSignature>::type SigT; + SignalBase *sig = findSignalImpl(GenericMFPtr(fptr)); + if(!sig) { + sig = NewSignal(fptr); + addSignalImpl(sig,fptr,"signal_name_to_be_implemented"); + } + return (SigT *)sig; + } + + + inline SignalBase * + findSignal(const char *name) const + { + return findSignalImpl(name); + } + + inline GenericMFPtr * + findSlot(const char *name) const + { + return findSlotImpl(name); + } + + + void PrintSelf(std::ostream &o) const; + + inline const Object& operator = (const Object ©) + { this->DeepCopy(copy); return *this; } + + +private: + bool addSignalImpl(SignalBase *sig, GenericMFPtr fptr, const char *name); + bool addSlotImpl(GenericMFPtr fptr, const char *name); + SignalBase *findSignalImpl(const GenericMFPtr &fptr) const; + SignalBase *findSignalImpl(const char *name) const; + GenericMFPtr *findSlotImpl(const char *name) const; + + friend class boost::serialization::access; + friend class ObjectPrivate; + class ObjectPrivate *d; +}; + + + +} // uLib + +//////////////////////////////////////////////////////////////////////////////// + +std::ostream & operator << (std::ostream &os, uLib::Object &ob); +std::ostream & operator << (std::ostream &os, uLib::Object *ob); +std::istream & operator >> (std::istream &is, uLib::Object &ob); + + +#endif // U_OBJECT_H diff --git a/src/Core/ObjectProps.h b/src/Core/ObjectProps.h new file mode 100644 index 0000000..b789d84 --- /dev/null +++ b/src/Core/ObjectProps.h @@ -0,0 +1,278 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_OBJECTPROPS_H +#define U_OBJECTPROPS_H + + + +#include + +#include +#include + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// MACROS // + + +#define ULIB_props() \ + public: struct ObjectProps; \ + virtual void init_properties(); \ + inline struct ObjectProps &p() { /* static const unsigned int offset = props_offset(this); */ \ + /* NON FUNZIA! return * (struct ObjectProps *)(reinterpret_cast(props())+offset); */ \ + return *props()->ptr(); } \ + typedef uLib::mpl::bool_::type propable_trait; \ + public: struct DLL_PUBLIC ObjectProps + +#define properties() ULIB_props() + +#define default(vlaue) + +#define $$ p() + +#define $(_name) props_ref<_name>() + +#define $_init() \ + if(props(this)) return; \ + props_new(this); \ + uLib::detail::ObjectProps::initializer::init_object_baselist(this); + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +namespace boost { +namespace serialization { +class access; +} +} + + +namespace uLib { + +namespace detail { + +struct ObjectProps { + + /** Define a trait has_member to find if an Object is Propable*/ + BOOST_MPL_HAS_XXX_TRAIT_DEF(propable_trait) + + /** IsA ProbapleObject Implementation Template */ + template + struct IsA : has_propable_trait {}; + + /** Lambda to get Props member type */ + template + struct props_type { + typedef typename T::ObjectProps type; + }; + + template + struct get_props { + + /** CFList has result but this method check for has BaseList */ + typedef typename detail::TypeIntrospection::child_first::type CFTypeList; + + /** Filter List items that have not Propable feature */ + typedef typename mpl::filter_view< CFTypeList, IsA >::type FilteredCFTypeList; + + /** Get Props from each Parent in Seq */ + typedef typename mpl::transform_view< FilteredCFTypeList, props_type >::type type; + + + // qui sotto ho un problema che ho temporaneamente tamponato // + // ovvero ho usato child_first_impl per ottenere la lista delle basi // + // vorrei farlo facendo un pop_back ma non va forse perche il tipo // + // non e' corretto. // + + /** Get Parent list from CFTypeList */ + typedef typename detail::TypeIntrospection::child_first_impl::Childs CFBaseList; + + /** Filter Parents that have not Propable feature */ + typedef typename mpl::filter_view< CFBaseList, IsA >::type FilteredCFBaseList; + }; + + + + // TODO: convert to pp const value, + // (non so se sia possibile con il dinamic casting intanto funziona cosi' ) + template + static unsigned int measure_offset(T1 base, T2 derived) { + return reinterpret_cast(derived) - reinterpret_cast(base); + } + + struct initializer { + + template + struct lambda_init_object { + _ObjectT *o; + lambda_init_object(_ObjectT *o) : o(o) {} + template void operator()(T) { + o->T::init_properties(); + } + }; + + + /** + * This calls the internal init_properties() virtual function for each + * object parent defined in BaseList only if it is propable + */ + template + static void init_object_baselist(T *o) { + typedef typename uLib::detail::ObjectProps::get_props::FilteredCFBaseList CFBaseList; + mpl::for_each(lambda_init_object(o)); + } + + /** + * This calls the internal init_properties() virtual function only if + * object is propable ( implementation if not propable ) + */ + template + static + typename boost::enable_if >,void>::type + init_object(T *o) { + ; // do nothing // + } + + /** + * This calls the internal init_properties() virtual function only if + * object is propable ( implementation if propable ) + */ + template + static + typename boost::enable_if,void>::type + init_object(T *o) { + o->init_properties(); + } + + }; + + template + struct serialize_baselist { + ThisClass & m_object; + Archive & m_ar; + serialize_baselist(ThisClass &o, Archive &ar) : m_object(o), m_ar(ar) {} + template void operator()(T &o) { + // T is taken fron get_props::FilteredPList types to get + // type_info_name that is the type name defined by Type macro + typedef typename props_type::type PType; + std::string name(TypeIntrospection::access::type_info::name); + boost::algorithm::replace_all(name,"::","_"); + m_ar & boost::serialization::make_nvp( + name.c_str() , + boost::serialization::base_object(m_object)); + } + }; + +}; + +} // detail + + + + + +struct ObjectPropsBase { + virtual ~ObjectPropsBase() {} + virtual ObjectPropsBase *copy() = 0; + + template inline T *ptr() { return dynamic_cast(this); } + + template void serialize(ArchiveT &ar, const unsigned int version) {} +}; + + + +template +struct ObjectPropsImpl : + ObjectPropsBase, + ULIB_MPL_INHERIT_NOFOLD_SEQ(typename uLib::detail::ObjectProps::get_props::type) +{ + typedef ObjectPropsImpl ThisClass; + typedef typename uLib::detail::ObjectProps::get_props::type CFList; + typedef typename uLib::detail::ObjectProps::get_props::FilteredCFTypeList FilteredCFTypeList; + ObjectPropsBase *copy() { return new ThisClass(*this); } + + template void serialize(ArchiveT &ar, const unsigned int version) { + boost::serialization::void_cast_register(); + mpl::for_each(detail::ObjectProps::serialize_baselist(*this,ar)); + } +}; + + +class ObjectPropable { + + ObjectPropsBase *m_props; + friend class uLib::detail::ObjectProps; + friend class boost::serialization::access; +public: + ObjectPropable() : m_props(NULL) {} + ObjectPropable(const ObjectPropable &c) { if(c.m_props) m_props = c.m_props->copy(); else m_props = NULL; } + ~ObjectPropable() { if(m_props) delete m_props; } + + + template inline typename T::ObjectProps& props_ref() const { if(m_props) return *m_props->ptr(); else exit(1); } + template inline typename T::ObjectProps* props(T *ptr = NULL) const { if(m_props) return m_props->ptr(); else return NULL; } +protected: + ObjectPropsBase *props() const { return m_props; } + template inline void props_new(T* ptr = NULL) { if(!m_props) m_props = new ObjectPropsImpl; } + + /** NOT working dynamic cache casting */ + template inline unsigned int props_offset(T *ptr) const + { if(m_props) return detail::ObjectProps::measure_offset(m_props,m_props->ptr()); else return -1; } + + + template void serialize(ArchiveT &ar, const unsigned int version) { + if(m_props) ar & boost::serialization::make_nvp("properties",m_props); + } + +public: + /** + * ObjectPropable is not directly propable itself to prevent Basclass + * duplication in inherit_nofold. And for the same reason ANY VIRTUAL BASE + * SHOULD NOT BE PROPABLE + */ + virtual void init_properties() {} + +}; + +} // uLib + + + + + + + +#endif // U_OBJECTPROPS_H diff --git a/src/Core/Options.cpp b/src/Core/Options.cpp new file mode 100644 index 0000000..bcd8bff --- /dev/null +++ b/src/Core/Options.cpp @@ -0,0 +1,87 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include +#include +#include "Core/Options.h" + +#include + + +//class boost::program_options::error_with_option_name; +//template<> boost::program_options::typed_value boost::program_options::value(); +//template<> boost::program_options::typed_value boost::program_options::value(int *); + + +namespace uLib { + +Options::Options(const char *str) : + m_global(str), + m_configuration("Configuration") +{} + +void Options::parse_command_line(int argc, char *argv[]) { + boost::program_options::store(boost::program_options::parse_command_line(argc,argv,m_global),m_vm); + boost::program_options::notify(m_vm); + + if(m_vm.count("help")) { + std::cout << "\n" << m_global << "\n"; + if(m_configuration.options().size()) { + std::cout << "\n" << m_configuration << "\n\n"; + } + exit(1); + } +} + +void Options::parse_config_file(std::string &str) +{ + this->parse_config_file(str.c_str()); +} + +void Options::parse_config_file(const char *fname) +{ + std::ifstream is; + is.open(fname); + boost::program_options::options_description fileopt; + fileopt.add(m_global).add(m_configuration); + if(is.is_open()) { + boost::program_options::store(boost::program_options::parse_config_file(is,fileopt,true),m_vm); + boost::program_options::notify(m_vm); + } +} + +bool Options::count(const char *str) const +{ + return (m_vm.count(str)); +} + + +} // uLib + + + + diff --git a/src/Core/Options.h b/src/Core/Options.h new file mode 100644 index 0000000..edd1899 --- /dev/null +++ b/src/Core/Options.h @@ -0,0 +1,179 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_OPTIONS_H +#define U_CORE_OPTIONS_H + +#include + +namespace uLib { + +namespace detail { + +struct Options { + + /** + * Wrapper for boost program_options easy init syntax + */ + class options_description_easy_init { + typedef boost::program_options::options_description_easy_init InitClass; + InitClass m_init; + public: + options_description_easy_init(InitClass init) : + m_init(init) {} + + + options_description_easy_init& + operator()(const char* name, + const char* description) + { + m_init(name,description); + return *this; + } + + options_description_easy_init& + operator()(const char* name, + const boost::program_options::value_semantic* s) + { + m_init(name,s); + return *this; + } + + + options_description_easy_init& + operator()(const char* name, + const boost::program_options::value_semantic* s, + const char* description) + { + m_init(name,s,description); + return *this; + } + + + template + options_description_easy_init& + operator()(const char* name, + T * value, + const T default_value, + const char* description) + { + m_init(name, + boost::program_options::value(value)->default_value(default_value), + description); + return *this; + } + + template + options_description_easy_init& + operator()(const char* name, + T * value, + const char* description) + { + assert(value); + m_init(name, + boost::program_options::value(value)->default_value(*value), + description); + return *this; + } + + template + options_description_easy_init& + operator()(const char* name, + T * value, + const T default_value) + { + m_init(name, + boost::program_options::value(value)->default_value(default_value)); + return *this; + } + + template + options_description_easy_init& + operator()(const char* name, + T * value) + { + assert(value); + m_init(name, + boost::program_options::value(value)->default_value(*value)); + return *this; + } + + }; + +}; // Options + +} // detail + + + +class Options { + boost::program_options::options_description m_global; + boost::program_options::options_description m_configuration; + boost::program_options::positional_options_description m_posdesc; + boost::program_options::variables_map m_vm; + +public: + typedef detail::Options::options_description_easy_init initType; + + Options(const char *str = "Program options"); + + initType add_options() { + return initType(m_global.add_options()); + } + + initType add_config_options() { + return initType(m_configuration.add_options()); + } + + void add_positional_option(const char *name, int max_count) { + // TODO: + // m_posdesc(name,max_count); + } + + void parse_command_line(int argc, char *argv[]); + + void parse_config_file(std::string &str); + + void parse_config_file(const char *fname); + + template + static inline boost::program_options::typed_value* value(T *v, T dvalue) { + boost::program_options::typed_value *r = boost::program_options::value(v); + r->default_value(dvalue); + return r; + } + + bool count(const char *str) const; + +}; + + +} // uLib + + + +#endif // U_CORE_OPTIONS_H diff --git a/src/Core/ProgrammableAccessor.h b/src/Core/ProgrammableAccessor.h new file mode 100644 index 0000000..62f1713 --- /dev/null +++ b/src/Core/ProgrammableAccessor.h @@ -0,0 +1,140 @@ +#ifndef U_CORE_PROGRAMMABLEACCESSOR_H +#define U_CORE_PROGRAMMABLEACCESSOR_H + +#include +#include +#include + +namespace uLib { + + + +namespace detail { + +template +class ProgrammableAccessor_Base { +public: + virtual R Get(void *) const = 0; + virtual void Set(void *,const R) const = 0; + + template + T Get(void *ob) const { + return static_cast(this->Get(ob)); + } + + template + void Set(void *ob, const T data) const { + this->Set(ob,static_cast(data)); + } + + virtual ~ProgrammableAccessor_Base() {} +}; + + +template +class functor_by_ref : public ProgrammableAccessor_Base +{ +public: + explicit functor_by_ref(R&(T::*__pf)()) : MFRef(__pf) {} + R Get(void * ptr) const + { return static_cast((reinterpret_cast(ptr)->*MFRef)()); } + void Set(void * ptr, const R data) const + { ((reinterpret_cast(ptr)->*MFRef)()) = data; } +private: + R&(T::*MFRef)(); +}; + +template +class functor_by_mfptr_cc : public ProgrammableAccessor_Base +{ + typedef R(T::*GetterType)() const; + typedef void(T::*SetterType)(const R); +public: + explicit functor_by_mfptr_cc( GetterType _get, SetterType _set ) : + GetPtr(_get), SetPtr(_set) {} + R Get(void * ptr) const + { return static_cast((reinterpret_cast(ptr)->*GetPtr)()); } + void Set(void * ptr, const R data) const + { if (SetPtr) (reinterpret_cast(ptr)->*SetPtr)(data); } + +private: + GetterType GetPtr; + SetterType SetPtr; +}; + +template +class functor_by_mfptr_vv : public ProgrammableAccessor_Base +{ + typedef R(T::*GetterType)(); + typedef void(T::*SetterType)(R); +public: + explicit functor_by_mfptr_vv( GetterType _get, SetterType _set ) : + GetPtr(_get), SetPtr(_set) {} + R Get(void * ptr) const + { return static_cast((reinterpret_cast(ptr)->*GetPtr)()); } + void Set(void * ptr, const R data) const + { if (SetPtr) (reinterpret_cast(ptr)->*SetPtr)(data); } + +private: + GetterType GetPtr; + SetterType SetPtr; +}; + + +template +class functor_by_member : public ProgrammableAccessor_Base +{ +public: + explicit functor_by_member(R T::*__pf) : MDPtr(__pf) {} + R Get(void * ptr) const + { return static_cast(reinterpret_cast(ptr)->*MDPtr); } + void Set(void * ptr, const R data) const + { (reinterpret_cast(ptr)->*MDPtr) = data; } +private: + R T::*MDPtr; +}; + +} // detail + + + +//////////////////////////////////////////////////////////////////////////////// +// Programmable Accessor Factory ///////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +template +class ProgrammableAccessor { +public: + template + ProgrammableAccessor(R(T::*_pg)()const, void(T::*_ps)(const R) = NULL) : + m_base(new detail::functor_by_mfptr_cc(_pg,_ps)) {} + + template + ProgrammableAccessor(R(T::*_pg)(), void(T::*_ps)(R) = NULL) : + m_base(new detail::functor_by_mfptr_vv(_pg,_ps)) {} + + template + ProgrammableAccessor(R&(T::*_pf)()) : + m_base(new detail::functor_by_ref(_pf)) {} + + template + ProgrammableAccessor(R T::*_pf) : + m_base(new detail::functor_by_member(_pf)) {} + + template + inline OtherR Get(void *ob) const { return m_base->Get(ob); } + + template + inline void Set(void *ob, const OtherR data) const { return m_base->Set(ob,data); } + +private: + SmartPointer< detail::ProgrammableAccessor_Base > m_base; +}; + + +} // uLib + + + +#endif // PROGRAMMABLEACCESSOR_H diff --git a/src/Core/Serializable.cpp b/src/Core/Serializable.cpp new file mode 100644 index 0000000..5efc2ea --- /dev/null +++ b/src/Core/Serializable.cpp @@ -0,0 +1,95 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "boost/archive/polymorphic_xml_oarchive.hpp" +#include "boost/archive/polymorphic_xml_iarchive.hpp" +#include "boost/archive/polymorphic_text_oarchive.hpp" +#include "boost/archive/polymorphic_text_iarchive.hpp" +#include "boost/archive/polymorphic_binary_oarchive.hpp" +#include "boost/archive/polymorphic_binary_iarchive.hpp" + +#include "Serializable.h" + + +using namespace uLib; + + + +//void Serializable::SaveXml(std::ostream &os, const char *name) +//{ +// boost::archive::polymorphic_oarchive *xoa = new boost::archive::polymorphic_xml_oarchive(os); +// this->Save(*xoa); +// delete xoa; +//} + +//void Serializable::LoadXml(std::istream &is, const char *name) +//{ +// boost::archive::polymorphic_iarchive *xia = new boost::archive::polymorphic_xml_iarchive(is); +// this->Load(*xia,this); +// delete xia; +//} + +//void Serializable::SaveText(std::ostream &os, const char *name) +//{ +// boost::archive::polymorphic_oarchive *xoa = new boost::archive::polymorphic_text_oarchive(os); +// this->Save(*xoa); +// delete xoa; +//} + +//void Serializable::LoadText(std::istream &is, const char *name) +//{ +// boost::archive::polymorphic_iarchive *xia = new boost::archive::polymorphic_text_iarchive(is); +// this->Load(*xia,this); +// delete xia; +//} + +//void Serializable::SaveBin(std::ostream &os, const char *name) +//{ +// boost::archive::polymorphic_oarchive *xoa = new boost::archive::polymorphic_binary_oarchive(os); +// this->Save(*xoa); +// delete xoa; +//} + +//void Serializable::LoadBin(std::istream &is, const char *name) +//{ +// boost::archive::polymorphic_iarchive *xia = new boost::archive::polymorphic_binary_iarchive(is); +// Serializable::Load(*xia,this); +// delete xia; +//} + + +//void Serializable::Save(boost::archive::polymorphic_oarchive &ar, Serializable *ob) +//{ +// ar << boost::serialization::make_nvp("Object",ob); +//} + +//void Serializable::Load(boost::archive::polymorphic_iarchive &ar, Serializable *ob) +//{ +// ar >> boost::serialization::make_nvp("Object",ob); +//} + + diff --git a/src/Core/Serializable.h b/src/Core/Serializable.h new file mode 100644 index 0000000..85221ce --- /dev/null +++ b/src/Core/Serializable.h @@ -0,0 +1,412 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_SERIALIZABLE_H +#define U_SERIALIZABLE_H + +/* Serialization: + + + +TODO: +* Problema nella serializzazione delle properties in test_archive +* implementare human readable make_hrp ... non riesco.. + +*/ + + + + +#include +#include + +#include +#include +#include + +//#include +//#include +//#include +//#include +//#include "boost/archive/polymorphic_iarchive.hpp" +//#include "boost/archive/polymorphic_oarchive.hpp" + +#include +#include +#include +#include +#include + + +#include "Core/Mpl.h" +#include "Core/ObjectProps.h" +#include "Core/Archives.h" +#include "Core/Export.h" + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// BOOST SERIALIZATION ADD-ON + +namespace boost { +namespace serialization { + +// ACCESS 2 // +template struct access2 {}; + + +// NON FUNZIONA ... SISTEMARE !!!! // ------------------------------------------ +template +class hrp : + public wrapper_traits > +{ + const char *m_name; + T *m_value; + std::string *m_str; + +public: + explicit hrp(const char * name_, T &t) : + m_str(new std::string), + m_name(name_), m_value(&t) {} + + const char * name() const { + return this->m_name; + } + + + template + void save( Archivex & ar, const unsigned int /* file_version */) const { + //// ar.operator<<(const_value()); + // std::stringstream ss; + // uLib::Archive::hrt_oarchive har(ss); + // har << make_nvp(m_name,*m_value); + // // (*m_str) = ss.str(); + //// ar.operator << (make_nvp(m_name, ss.str()); + } + template + void load( Archivex & ar, const unsigned int /* file_version */) { +// ar.operator>>(value()); + } + BOOST_SERIALIZATION_SPLIT_MEMBER() +}; + + +template +inline +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +const +#endif +hrp< T > make_hrp(const char * name, T & t){ + return hrp< T >(name, t); +} + +#define HRP(name) \ + boost::serialization::make_hrp(BOOST_PP_STRINGIZE(name), name) + + +} // serialization +} // boost + + + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// ULIB SERIALIZATION + +namespace uLib { + + + +#define _AR_OP(r,data,elem) data&BOOST_SERIALIZATION_BASE_OBJECT_NVP(elem); + +#define NVP(data) BOOST_SERIALIZATION_NVP(data) + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// SERIALIZTION MACROS // + +// !!! WARNING !!! INTRUSIVE SERIALIZATION IS ACTUALLY NOT WORKING FEATURE +// SO LEAVE ULIB_CFG_INTRUSIVE_SERIALIZATION NOT DEFINED + +#ifdef ULIB_CFG_INTRUSIVE_SERIALIZATION_OBJECT +# define ULIB_SERIALIZABLE_OBJECT _ULIB_DETAIL_INTRUSIVE_SERIALIZABLE_OBJECT +# define ULIB_SERIALIZE_OBJECT(_Ob,...) _ULIB_DETAIL_INTRUSIVE_SERIALIZE_OBJECT(_Ob,__VA_ARGS__) +# define _AR_(_name) _ULIB_DETAIL_INTRUSIVE_AR_(_name) +#else +# define ULIB_SERIALIZABLE(_Ob) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZABLE(_Ob) \ + ULIB_CLASS_EXPORT_KEY(_Ob) +# define ULIB_SERIALIZE(_Ob,...) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE(_Ob) +# define ULIB_SERIALIZE_DERIVED(_Ob,...) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_DERIVED(_Ob,__VA_ARGS__) +# define ULIB_SERIALIZABLE_OBJECT(_Ob) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZABLE_OBJECT(_Ob) \ + ULIB_CLASS_EXPORT_OBJECT_KEY(_Ob) +# define ULIB_SERIALIZE_OBJECT(_Ob,...) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_OBJECT(_Ob,__VA_ARGS__) +# define ULIB_SERIALIZE_OBJECT_PROPS(_Ob) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_PROPS(_Ob) +# define AR(_name) _ULIB_DETAIL_UNINTRUSIVE_AR_(_name) +# define HR(_name) _ULIB_DETAIL_UNINTRUSIVE_AR_(_name) +#endif + + +#define ULIB_SERIALIZE_ACCESS \ + friend class boost::serialization::access; \ + template friend class boost::serialization::access2; + +#define ULIB_CLASS_EXPORT_KEY(_FullNamespaceClass) \ + BOOST_CLASS_EXPORT_KEY(_FullNamespaceClass) + +#define ULIB_CLASS_EXPORT_OBJECT_KEY(_FullNamespaceClass) \ + BOOST_CLASS_EXPORT_KEY(_FullNamespaceClass) \ + BOOST_CLASS_EXPORT_KEY(_FullNamespaceClass::ObjectProps) \ + BOOST_CLASS_EXPORT_KEY(uLib::ObjectPropsImpl<_FullNamespaceClass>) + + +#define _SERIALIZE_IMPL_SEQ \ + (uLib::Archive::text_iarchive) \ + (uLib::Archive::text_oarchive) \ + (uLib::Archive::hrt_iarchive) \ + (uLib::Archive::hrt_oarchive) \ + (uLib::Archive::xml_iarchive) \ + (uLib::Archive::xml_oarchive) \ + (uLib::Archive::log_archive) + + +/** Solving virtual class check problem */ +#define _ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE(_Base,_Derived) namespace boost{ template<> struct is_virtual_base_of<_Base,_Derived>: public boost::mpl::true_ {}; } +#define _ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE_OP(r,data,elem) _ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE(elem,data) + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// INTRUSIVE SERIALIZATION ( NOT WORKING YET !! ) // + +#define _ULIB_DETAIL_INTRUSIVE_AR_(name) ar & BOOST_SERIALIZATION_NVP(name); + +#define _ULIB_DETAIL_INTRUSIVE_SERIALIZE_FUNC(Class,Archive) \ + template void Class::serialize(Archive &ar,const unsigned int); + +#define _ULIB_DETAIL_INTRUSIVE_SERIALIZE_FUNC_OP(r,data,elem) _ULIB_DETAIL_INTRUSIVE_SERIALIZE_FUNC(data,elem); + +#define _ULIB_DETAIL_INTRUSIVE_SERIALIZABLE_OBJECT \ + typedef boost::mpl::bool_ serializable; \ + typedef boost::mpl::remove_if< TypeList, IsUnSerializable >::type SerilizableTypeList; \ + void PrintSerializableListId() { boost::mpl::for_each(PrintTypeId()); } \ + template void serialize(ArchiveT &ar,const unsigned int version); \ + template void serialize_parents(ArchiveT &ar,const unsigned int version); \ + template void save_override(ArchiveT &ar,const unsigned int version); + +#define _ULIB_DETAIL_INTRUSIVE_SERIALIZE_OBJECT(_Ob,...) \ + template void _Ob::serialize(ArchiveT &ar, const unsigned int version) { \ + boost::serialization::void_cast_register<_Ob,_Ob::BaseClass>(static_cast<_Ob *>(NULL),static_cast<_Ob::BaseClass *>(NULL)); \ + _Ob::serialize_parents(ar,version); \ + _Ob::save_override(ar,version); }\ + template void _Ob::serialize_parents(ArchiveT &ar, const unsigned int v) { \ + BOOST_PP_SEQ_FOR_EACH(_AR_OP,ar,BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))); } \ + BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_INTRUSIVE_SERIALIZE_FUNC_OP,_Ob,_SERIALIZE_IMPL_SEQ)\ + BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE_OP,_Ob,BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))) \ + ULIB_CLASS_EXPORT_IMPLEMENT(_Ob) \ + namespace boost { \ + namespace serialization { \ + template inline void load_construct_data(ArchiveT & ar, _Ob *o, const unsigned int file_version) \ + { ::new(o)_Ob(); o->init_parameters(); } }}\ + template void _Ob::save_override(ArchiveT &ar, const unsigned int version) + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// UNINTRUSIVE SERIALIZATION + +#define _UNAR_OP(r,data,elem) ar&boost::serialization::make_nvp(BOOST_PP_STRINGIZE(elem),boost::serialization::base_object(ob)); + +#define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC(Class,Archive) \ + template void boost::serialization::serialize(Archive &ar, Class &ob, const unsigned int i); + +#define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC_OP(r,data,elem) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC(data,elem) + + +// NOTE: becouse of BOOST_PP_VARIADIC_SIZE issue of some boost macro has two +// different implementation + +#define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZABLE(_Ob) \ + namespace boost { namespace serialization { \ + template void serialize (ArchiveT &ar, _Ob &ob, const unsigned int version); \ + template void serialize_parents (ArchiveT &ar, _Ob &ob, const unsigned int version); \ + template <> struct access2< _Ob > { template static void save_override (ArchiveT &ar, _Ob &ob, const unsigned int version); }; }} + +#define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE(_Ob) \ + namespace boost { namespace serialization { \ + template void serialize_parents(ArchiveT &ar, _Ob &ob, const unsigned int v) {} \ + template void serialize (ArchiveT &ar, _Ob &ob, const unsigned int version) { \ + serialize_parents(ar,ob,version); \ + access2< _Ob >::save_override(ar,ob,version); } }}\ + ULIB_CLASS_EXPORT_IMPLEMENT(_Ob) \ + BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC_OP,_Ob,_SERIALIZE_IMPL_SEQ)\ + template void boost::serialization::access2< _Ob >::save_override(ArchiveT &ar, _Ob &ob, const unsigned int version) + +#define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_DERIVED(_Ob,...) \ + namespace boost { namespace serialization { \ + template void serialize_parents(ArchiveT &ar, _Ob &ob, const unsigned int v) { \ + BOOST_PP_IF(BOOST_PP_VARIADIC_SIZE((__VA_ARGS__)),BOOST_PP_SEQ_FOR_EACH(_UNAR_OP,ob,BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__)));,) } \ + template void serialize (ArchiveT &ar, _Ob &ob, const unsigned int version) { \ + serialize_parents(ar,ob,version); \ + access2< _Ob >::save_override (ar,ob,version); } }}\ + ULIB_CLASS_EXPORT_IMPLEMENT(_Ob) \ + BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC_OP,_Ob,_SERIALIZE_IMPL_SEQ) \ + BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE_OP,_Ob,BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))) \ + template void boost::serialization::access2< _Ob >::save_override(ArchiveT &ar, _Ob &ob, const unsigned int version) + + +#define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZABLE_OBJECT(_Ob) \ + namespace boost { namespace serialization { \ + template void serialize (ArchiveT &ar, _Ob &ob, const unsigned int version); \ + template void serialize_parents (ArchiveT &ar, _Ob &ob, const unsigned int version); \ + template <> struct access2< _Ob > { template static void save_override (ArchiveT &ar, _Ob &ob, const unsigned int version); }; \ + template void serialize (ArchiveT &ar, class _Ob::ObjectProps &ob, const unsigned int version); \ + template void save_override (ArchiveT &ar, class _Ob::ObjectProps &ob, const unsigned int version); }} + +#define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_OBJECT(_Ob,...) \ + namespace boost { namespace serialization { \ + template void serialize_parents(ArchiveT &ar, _Ob &ob, const unsigned int v) { \ + /* PP serialize */ BOOST_PP_SEQ_FOR_EACH(_UNAR_OP,ob,BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))); \ + /* MPL serialize */ /*uLib::mpl::for_each<_Ob::BaseList>(uLib::detail::Serializable::serialize_baseobject<_Ob,ArchiveT>(ob,ar) );*/ } \ + template inline void load_construct_data(ArchiveT & ar, _Ob *ob, const unsigned int file_version) { \ + ::new(ob)_Ob(); uLib::detail::ObjectProps::initializer::init_object(ob); } \ + template void serialize (ArchiveT &ar, _Ob &ob, const unsigned int version) { \ + void_cast_register<_Ob,_Ob::BaseClass>(static_cast<_Ob *>(NULL),static_cast<_Ob::BaseClass *>(NULL)); /*fix*/ \ + serialize_parents(ar,ob,version); \ + access2< _Ob >::save_override (ar,ob,version); } }}\ + ULIB_CLASS_EXPORT_IMPLEMENT(_Ob) \ + BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE_OP,_Ob,BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))) \ + BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC_OP,_Ob,_SERIALIZE_IMPL_SEQ)\ + template void boost::serialization::access2< _Ob >::save_override(ArchiveT &ar, _Ob &ob, const unsigned int version) + +#define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_PROPS(_Ob) \ + namespace boost { namespace serialization { \ + template void serialize (ArchiveT &ar, _Ob::ObjectProps &ob, const unsigned int version) { \ + save_override (ar,ob,version); } }}\ + BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC_OP,_Ob::ObjectProps,_SERIALIZE_IMPL_SEQ)\ + ULIB_CLASS_EXPORT_IMPLEMENT(_Ob::ObjectProps) \ + ULIB_CLASS_EXPORT_IMPLEMENT(uLib::ObjectPropsImpl<_Ob>) \ + template void boost::serialization::save_override(ArchiveT &ar, _Ob::ObjectProps &ob, const unsigned int version) + + +#define _ULIB_DETAIL_UNINTRUSIVE_AR_(name) boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name),ob.name) + + + + + + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + + +namespace detail { + +struct Serializable { + + /** + * Serializable trait to check if an object type is serializable. + * This only works if UNINTRUSIVE SERIALIZATION is applyed; in intrusive + * cases a has_serialize trait should be implemented + */ + template + struct serializable_trait : mpl::bool_ {}; + + /** + * IsA Serializable Implementation Template + */ + template + struct IsA : serializable_trait {}; + + template + struct serialize_baseobject { + ThisClass & m_object; + Archive & m_ar; + serialize_baseobject(ThisClass &o, Archive &ar) : m_object(o), m_ar(ar) {} + template void operator()(T &o) { + m_ar & boost::serialization::make_nvp( + typeid(T).name() , + boost::serialization::base_object(m_object)); + } + }; + + +}; + + +} // detail + + + + + +struct Serializable { + friend class boost::serialization::access; + template friend class boost::serialization::access2; + virtual ~Serializable() {} +protected: +}; + + + + + +} // uLib + + + + + + +#endif // U_SERIALIZABLE_H diff --git a/src/Core/Signal.cpp b/src/Core/Signal.cpp new file mode 100644 index 0000000..f99873b --- /dev/null +++ b/src/Core/Signal.cpp @@ -0,0 +1,28 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + diff --git a/src/Core/Signal.h b/src/Core/Signal.h new file mode 100644 index 0000000..f27bc7a --- /dev/null +++ b/src/Core/Signal.h @@ -0,0 +1,168 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_SIGNAL_H +#define U_CORE_SIGNAL_H + +#include + +#include +#include +#include + +#include "Function.h" + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// Signals macro // + +#define default(vlaue) +#define slots +#define signals /*virtual void init_signals();*/ public +#define emit +#define SLOT(a) BOOST_STRINGIZE(a) +#define SIGNAL(a) BOOST_STRINGIZE(a) + +#define _ULIB_DETAIL_SIGNAL_EMIT(_name,...) \ + static BOOST_AUTO(sig,this->findOrAddSignal(&_name)); \ + sig->operator()(__VA_ARGS__); + +/** + * Utility macro to implement signal emission implementa una delle seguenti: + * + * // metodo standard con cast // + * SignalBase * sig = this->findSignal((void (Ob1::*)(void))&Ob1::V0); + * typedef Signal::type SigT; + * if(sig) reinterpret_cast(sig)->operator()(); + * + * // cast automatico // + * static BOOST_AUTO(sig,this->findOrAddSignal(&Ob1::V0)); + * sig->operator()(); +*/ +#define ULIB_SIGNAL_EMIT(_name,...) _ULIB_DETAIL_SIGNAL_EMIT(_name,__VA_ARGS__) + + +namespace uLib { + + +// A boost::signal wrapper structure /////////////////////////////////////////// + +// TODO ... + +typedef boost::signals2::signal_base SignalBase; + +template +struct Signal { + typedef boost::signals2::signal type; +}; + + + +//////////////////////////////////////////////////////////////////////////////// + + +namespace detail { + + +template +struct ConnectSignal {}; + +template +struct ConnectSignal< FuncT, 0 > { + static void connect(SignalBase *sigb, FuncT slof, typename FunctionTypes::Object *receiver) { + typedef typename Signal::SignalSignature>::type SigT; + reinterpret_cast(sigb)->connect(slof); + } +}; + +template +struct ConnectSignal< FuncT, 1 > { + static void connect(SignalBase *sigb, FuncT slof, typename FunctionTypes::Object *receiver) { + typedef typename Signal::SignalSignature>::type SigT; + reinterpret_cast(sigb)->connect(boost::bind(slof,receiver)); + } +}; + +template +struct ConnectSignal< FuncT, 2 > { + static void connect(SignalBase *sigb, FuncT slof, typename FunctionTypes::Object *receiver) { + typedef typename Signal::SignalSignature>::type SigT; + reinterpret_cast(sigb)->connect(boost::bind(slof,receiver,_1)); + } +}; + +template +struct ConnectSignal< FuncT, 3 > { + static void connect(SignalBase *sigb, FuncT slof, typename FunctionTypes::Object *receiver) { + typedef typename Signal::SignalSignature>::type SigT; + reinterpret_cast(sigb)->connect(boost::bind(slof,receiver,_1,_2)); + } +}; + +template +struct ConnectSignal< FuncT, 4 > { + static void connect(SignalBase *sigb, FuncT slof, typename FunctionTypes::Object *receiver) { + typedef typename Signal::SignalSignature>::type SigT; + reinterpret_cast(sigb)->connect(boost::bind(slof,receiver,_1,_2,_3)); + } +}; + +template +struct ConnectSignal< FuncT, 5 > { + static void connect(SignalBase *sigb, FuncT slof, typename FunctionTypes::Object *receiver) { + typedef typename Signal::SignalSignature>::type SigT; + reinterpret_cast(sigb)->connect(boost::bind(slof,receiver,_1,_2,_3,_4)); + } +}; + + +} // detail + + + +template +SignalBase *NewSignal(FuncT f) { + // seems to work wow ! + return new Signal::type; +} + +template +void ConnectSignal(SignalBase *sigb, FuncT slof, typename FunctionTypes::Object *receiver) +{ + detail::ConnectSignal< FuncT, FunctionTypes::arity >::connect(sigb,slof,receiver); +} + + + + +} // uLib + +#endif // SIGNAL_H diff --git a/src/Core/Singleton.h b/src/Core/Singleton.h new file mode 100644 index 0000000..be50548 --- /dev/null +++ b/src/Core/Singleton.h @@ -0,0 +1,46 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_SINGLETON_H +#define U_CORE_SINGLETON_H + +#include + + +namespace uLib { + +template +struct Singleton : boost::serialization::singleton { + +}; + + +} + + + +#endif // SINGLETON_H diff --git a/src/Core/SmartPointer.h b/src/Core/SmartPointer.h new file mode 100644 index 0000000..0627487 --- /dev/null +++ b/src/Core/SmartPointer.h @@ -0,0 +1,114 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_SMARTPOINTER_H +#define U_CORE_SMARTPOINTER_H + + +namespace uLib { + +class SmartPointerBase {}; + + +template +class SmartPointer : SmartPointerBase { + typedef T element_type; +public: + + explicit + SmartPointer(T* ptr = NULL) : m_counter(0) { + // if(!ptr) ptr = new T; + if (ptr) m_counter = new ReferenceCounter(ptr); // ??? + } + + // TakeReference // + SmartPointer(T &ref) : m_counter(new ReferenceCounter(&ref,0)) { } + + SmartPointer(const SmartPointer& copy) throw () { + acquire(copy.m_counter); + } + + SmartPointer(SmartPointer * copy) throw () { + acquire(copy->m_counter); + } + + virtual ~SmartPointer() { release(); } + + SmartPointer & operator=(const SmartPointer& copy) { + if (this != ©) + { + release(); + acquire(copy.m_counter); + } + return *this; + } + + T & operator*() const throw () { return *m_counter->ptr; } + T * operator->() const throw () { return m_counter->ptr; } + + T * get() const throw () { + return m_counter ? m_counter->ptr : 0; } + bool unique() const throw () { + return (m_counter ? m_counter->count == 1 : true); } + + + private: + + struct ReferenceCounter + { + ReferenceCounter(T* ptr = 0, unsigned c = 1) : ptr(ptr), count(c) { } + T* ptr; + unsigned count; + } * m_counter; + + // increment the count + void acquire(ReferenceCounter* c) throw () + { + m_counter = c; + if (c && c->count>0) ++c->count; + } + + // decrement the count, delete if it is 0 + void release() { + if (m_counter) { + if (--m_counter->count == 0) { + delete m_counter->ptr; + } + if (m_counter->count <= 0) { + delete m_counter; + m_counter = NULL; + } + } + } + +}; + + + +} + +#endif // SMARTPOINTER_H diff --git a/src/Core/StaticInterface.h b/src/Core/StaticInterface.h new file mode 100644 index 0000000..cb26039 --- /dev/null +++ b/src/Core/StaticInterface.h @@ -0,0 +1,77 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_STATICINTERFACE_H +#define U_CORE_STATICINTERFACE_H + +namespace uLib { + +#define MAKE_TRAITS ; // TODO + +#define uLibCheckFunction(class_name,name,out, ... ) \ +{ out (class_name::*x)(__VA_ARGS__) = &class_name::name; (void) x; } + +#define uLibCheckConstFunction(class_name,name,out,...) \ +{ out (class_name::*x)(__VA_ARGS__) const = &class_name::name; (void) x; } + +#define uLibCheckMember(class_name,name,type) \ +{ class_name x; type *y = &x.name; (void) y; } + + +namespace Interface { + +// EXAMPLE : +//template struct Voxel { +// MAKE_TRAITS; +// template void check_structural() { +// { float & (Self::*x)() = &Self::Density; (void) x; } +// { int & (Self::*x)() = &Self::TrackCount; (void) x; } +// } +//protected: +// ~Voxel() {} +//}; + +template +static inline void IsA() { + (void) ((void (SI::*)()) &SI::template check_structural); +} + +// not working +//template +//struct StaticIsA { +// void test() { +// static const void (SI::*x)() = SI::template check_structural; +// } +//}; + +} + + + +} + +#endif // STATICINTERFACE_H diff --git a/src/Core/String.h b/src/Core/String.h new file mode 100644 index 0000000..c65c007 --- /dev/null +++ b/src/Core/String.h @@ -0,0 +1,21 @@ +#ifndef U_CORE_STRING_H +#define U_CORE_STRING_H + +#include +#include + +namespace uLib { + +typedef std::string String; +typedef std::wstring Stringw; + +} + +template < typename C > +std::basic_string & operator << (std::basic_string &str, const C *c_str) { + std::basic_stringstream ss(c_str); + str += ss.str(); + return str; +} + +#endif // STRING_H diff --git a/src/Core/StringReader.h b/src/Core/StringReader.h new file mode 100644 index 0000000..3b7aa6c --- /dev/null +++ b/src/Core/StringReader.h @@ -0,0 +1,94 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_STRINGREADER_H +#define U_CORE_STRINGREADER_H + +#include +#include + +#include "Core/Vector.h" +#include +#include + + +// RIPENSARE COMPLETAMENTE !!! + +namespace uLib { + +struct StringReader { + + std::istream & m_is; + + StringReader(std::istream &is) : m_is(is) {} + + void ReadString(const char *str) { + // // clean compared string // + // char chars[] = " \t\n"; + // for (unsigned int i = 0; i < strlen(chars); ++i) + // { cmps.erase (std::remove(str.begin(), str.end(), chars[i]), str.end()); } + + // SISTEMARE !!! + + int pos = 0; + char c; + while( pos < strlen(str) ) { + while( IsEscape(str[pos])) pos++; + if ( pos >= strlen(str) ) break; + while( IsEscape(c = m_is.get()) ); + if (c == str[pos] ) pos++; + else pos = 0; + } + } + + static inline bool IsEscape(char c){ + const char *escapes = " \r\n\t"; + for ( int i = 0 ; i < 4 ; ++i) { + if(c == escapes[i]) return true; + } + return false; + } + +}; + +template +inline StringReader & operator >> (StringReader &isr, T &t) { + isr.m_is >> t; + return isr; +} + +inline StringReader & operator >> (StringReader &isr, const char *str) { + isr.ReadString(str); + return isr; +} + + + +} // uLib + + +#endif // STRINGREADER_H diff --git a/src/Core/Types.h b/src/Core/Types.h new file mode 100644 index 0000000..a3dfa1c --- /dev/null +++ b/src/Core/Types.h @@ -0,0 +1,278 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_TYPES_H +#define U_CORE_TYPES_H + +#include +#include + +#include + +#include + +#include "Core/Macros.h" +#include "Core/Mpl.h" + + + + + + + +namespace uLib { + + +//////////////////////////////////////////////////////////////////////////////// + +namespace detail { + +struct TypeIntrospection { + + // BOOST IMPL // + BOOST_MPL_HAS_XXX_TRAIT_DEF(type_info) + + // SFINAE IMPL // + /* + template + struct has_type_info { + typedef char yes[1]; + typedef char no[2]; + template static yes& test(typename U::type_info::BaseList*); + template static no& test(...); + // struct apply { + static const bool value = sizeof(test(0)) == sizeof(yes); + typedef boost::mpl::bool_ type; + // }; + }; + */ + + /** IsA Introspectable Object Implementation Template */ + template + struct IsIntrospectable : has_type_info {}; + + template struct access { + typedef typename T::type_info type_info; + }; + + template + struct child_first_impl { + + template + struct lambda_CFList_f { + typedef mpl::vector type; + }; + + template + struct lambda_CFList_f { + // typedef typename T1::type_info::CFList type; + typedef typename access::type_info::CFList type; + }; + + template + struct lambda_CFList : lambda_CFList_f::value> {}; + + /** Transforms all Base Type into proper CFList */ + typedef typename mpl::transform_view < typename access::type_info::BaseList + , lambda_CFList + >::type CFListSeq; + + /** Folds each CFList into a new sequence */ + typedef typename mpl::fold< CFListSeq + , mpl::vector<> + , mpl::copy< mpl::_1 + , mpl::back_inserter + > + >::type Childs; + + /** Add This Class to final CFList sequence */ + typedef typename mpl::copy< Childs + , mpl::back_inserter< mpl::vector > + >::type type; + }; + + + /** + * Tests if T has a member called type_info then compile type CFList + */ + template + struct child_first : mpl::if_< has_type_info + , child_first_impl + , mpl::vector<> + >::type {}; + + +}; + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// TYPE ADAPTERS // FINIRE !!! + +//#define _REPETITION_V(vz,vn,vdata) + + +//template < class TypeList > +//class TypeAdapterInputInterface { +// virtual ~TypeAdapterInputInterface() {} +//public: + + + +// virtual void operator()(int val) {} +// virtual void operator()(std::string val) {} +//}; + + + + + + + +} // detail //////////////////////////////////////////////////////////////////// + + +#define CONSTEXPR BOOST_CONSTEXPR + + +typedef ltk::Real_t Real_t; +typedef ltk::Id_t Id_t; +typedef ltk::Size_t Size_t; +typedef ltk::Pointer_t Pointer_t; +typedef bool Bool_t; //Boolean (0=false, 1=true) (bool) + +//--- bit manipulation --------------------------------------------------------- +#ifndef BIT +#define BIT(n) (1ULL << (n)) +#endif + +#ifndef SETBIT +#define SETBIT(n,i) ((n) |= BIT(i)) +#endif + +#ifndef CLRBIT +#define CLRBIT(n,i) ((n) &= ~BIT(i)) +#endif + +#ifndef TESTBIT +#define TESTBIT(n,i) ((Bool_t)(((n) & BIT(i)) != 0)) +#endif + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// TYPE INTROSPECTION FOR OBJECTS // + + + +#define uLibTypeMacro(thisClass,...) \ + \ + /* Friendship detail for accessing introspection */ \ + template friend class uLib::detail::TypeIntrospection::access; \ + \ + /* type info structure*/ public: \ + /* in GCC 4.8 must be public or dynamic_cast wont work */ \ + struct type_info { \ + /*WARNING: -std=c++0x required for this! */ \ + constexpr static const char *name = BOOST_PP_STRINGIZE(thisClass); \ + typedef BOOST_PP_VARIADIC_ELEM(0,__VA_ARGS__) BaseClass; \ + typedef thisClass ThisClass; \ + typedef uLib::mpl::vector<__VA_ARGS__,thisClass> TypeList; \ + typedef uLib::mpl::vector<__VA_ARGS__> BaseList; \ + typedef uLib::detail::TypeIntrospection::child_first::type CFList; \ + }; \ + \ + public: \ + typedef type_info::BaseClass BaseClass; \ + virtual const char *type_name() const { return type_info::name; } \ + /* Object Props fwd declaration*/ \ + struct ObjectProps; \ + /**/ + + +/** + * TypeList inheritance introspection + */ +struct TypeIntrospection { + template + struct child_first : detail::TypeIntrospection::child_first {}; +}; + + + + + + +// SISTEMARE // +struct PrintTypeId { + template + void operator()(T) const + { std::cout << typeid(T).name() << std::endl; } + + template + static void PrintMplSeq(SeqT *p = NULL) { boost::mpl::for_each(PrintTypeId()); } + + template + static void PrintType(Class *p = NULL) { std::cout << typeid(Class).name() << std::endl; } +}; + + + +// ACCESS // +struct Access {}; +template struct Access2 {}; + + + + +} // uLib + +#endif // U_CORE_TYPES_H + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Core/Uuid.cpp b/src/Core/Uuid.cpp new file mode 100644 index 0000000..0270de8 --- /dev/null +++ b/src/Core/Uuid.cpp @@ -0,0 +1,45 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "Uuid.h" +#include "Singleton.h" + +using namespace uLib; + +uLib::uuid_t uLib::uLib_dns_uuid; +TypeRegister* TypeRegister::s_Instance = new TypeRegister(); + +TypeRegister::TypeRegister() : + BaseClass(uLib_dns_uuid) +{} + +TypeRegister * TypeRegister::Controller() { + return TypeRegister::s_Instance; +} + + + diff --git a/src/Core/Uuid.h b/src/Core/Uuid.h new file mode 100644 index 0000000..4787655 --- /dev/null +++ b/src/Core/Uuid.h @@ -0,0 +1,163 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_UUID_H +#define U_CORE_UUID_H + +#include + +#include +#include +#include +#include + +#include "Core/Mpl.h" +#include "Core/Vector.h" +#include "Core/Object.h" + + +namespace uLib { + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// Object Registration // + + +typedef boost::uuids::uuid uuid_t; + +extern uuid_t uLib_dns_uuid; + +template < typename T > +class type_id : public boost::uuids::uuid { +public: + type_id() : + m_size(sizeof(T)), + uuid(boost::uuids::name_generator(uLib_dns_uuid)(typeid(T).name())) + { + std::cout << "Request for register new type\n" << + "name: " << typeid(T).name() << "\n" << + "uuid: " << to_string(*this) << "\n"; + } + + explicit type_id(boost::uuids::uuid const& u) + : boost::uuids::uuid(u) {} + + operator boost::uuids::uuid() { + return static_cast(*this); + } + + operator boost::uuids::uuid() const { + return static_cast(*this); + } + + unsigned int size() const { return m_size; } + +private: + unsigned int m_size; +}; + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// TYPE REGISTER // + +namespace detail { + +class TypeRegister { + typedef boost::uuids::name_generator IDGen_t; +public: + struct RegisterEntry { + uuid_t id; + int size; + }; + + TypeRegister(uuid_t const &dns) : + gen(dns) {} + + + template< typename T > + RegisterEntry * AddType(T *t = NULL) { + RegisterEntry en = { gen(typeid(T).name()), sizeof(T) }; + for(int i=0; i < m_registry.size(); ++i) + if(en.id == m_registry[i].id) return &(m_registry[i]); + m_registry.push_back(en); + return &m_registry.back(); + } + + void PrintSelf(std::ostream &o) { + std::cout << "RegisterController: \n"; + for (int i=0; i m_registry; + +}; + +} // detail + + + + +class TypeRegister : public detail::TypeRegister { +public: + typedef detail::TypeRegister BaseClass; + typedef detail::TypeRegister::RegisterEntry Entry; + + static TypeRegister* Controller(); + +private: + TypeRegister(); // Blocks constructor + static TypeRegister *s_Instance; // Singleton instance +}; + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// OBJECT REGISTER // + + + +} // uLib + +#endif // UUID_H diff --git a/src/Core/Vector.h b/src/Core/Vector.h new file mode 100644 index 0000000..ace265b --- /dev/null +++ b/src/Core/Vector.h @@ -0,0 +1,195 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_VECTOR_H +#define U_CORE_VECTOR_H + +#include +#include + +#include +#include +#include + + +namespace uLib { + +// Vector Implemetation ... wraps std::vector +template +class Vector : public std::vector > +{ + typedef std::vector< T,std::allocator > BaseClass; + typedef std::allocator Allocator; +public: + typedef T TypeData; + typedef __gnu_cxx::__normal_iterator Iterator; + typedef __gnu_cxx::__normal_iterator ConstIterator; + + typedef CommaInitializer< Vector , T > VectorCommaInit; + + Vector(unsigned int size) : BaseClass(size) {} + Vector(unsigned int size, T &value) : BaseClass(size,value) {} + Vector() : BaseClass(0) {} + + inline VectorCommaInit operator <<(T scalar) { + return VectorCommaInit(this, scalar); + } + + inline void PrintSelf(std::ostream &o); + + void remove_element(unsigned int index) { + std::swap(this->at(index),this->back()); + this->pop_back(); + } + + void remove_element(T &t) { + std::swap(t, this->back()); + this->pop_back(); + } + +}; + +template +void Vector::PrintSelf(std::ostream &o) +{ + o << " *** uLib Vector *** \n"; + o << " n. of items = " << this->size() << "\n"; + for(int i=0; i< this->size(); ++i) + o << (T)this->at(i) << " "; + o << "\n"; +} + +template +std::ostream &operator << (std::ostream &o, const Vector &v) { + for(int i=0; i< v.size(); ++i) + o << (T)v.at(i) << " "; + o << "\n"; + return o; +} + +template +std::ofstream &operator << (std::ofstream &o, const Vector &v) { + for(int i=0; i< v.size(); ++i) + o << (T)v.at(i) << " "; + return o; +} + + +// MATH OPERATIONS // + +#define ULIB_CONTAINER_MATHOP(container,op) \ +template < typename T1, typename T2 > \ +inline container & operator op##= (container &src, const T2 data) { \ + foreach (T1 &el, src) { \ + el op##= static_cast(data); \ + } \ +} \ +\ +template < typename T1, typename T2 > \ +inline container operator op (const container &src, const T2 data) { \ + container out(src); \ + out op##= data; \ + return out; \ +} \ +// +ULIB_CONTAINER_MATHOP(Vector,+) +ULIB_CONTAINER_MATHOP(Vector,-) +ULIB_CONTAINER_MATHOP(Vector,*) +ULIB_CONTAINER_MATHOP(Vector,/) + + + + + + + +// Smart pointer Vector Implementation // + + +template +class SmartVector : public SmartPointer< Vector > { + typedef SmartPointer< Vector > Base; +public: + + SmartVector() : Base(NULL) { } +// SmartVector() : Base(new Vector()) { } + SmartVector( const SmartVector ©) : Base(copy) { } + SmartVector(unsigned int size) : Base(new Vector((int)size)) { } + + virtual ~SmartVector() {} + + T& operator[](int p) { + return Base::get()->at(p); + } + + void swap_elements(unsigned int first, unsigned int second) { + std::swap(Base::get()->at(first),Base::get()->at(second)); + } + + void remove_element(unsigned int index) { + std::swap(Base::get()->at(index),Base::get()->back()); + Base::get()->pop_back(); + } + + void remove_element(T &t) { + std::swap(t, Base::get()->back()); + Base::get()->pop_back(); + } +}; + + + + +// ------ Utils ------------------------------------------------------------- // + + + +// RIFARE con iteratore ! +template +inline const unsigned long +VectorSplice(const _Tp &_it, const _Tp &_end, const float value, _CmpT _comp) +{ + _Tp it = _it; + _Tp end = _end-1; + for(it; it != end;) + { + if (_comp(*it,value)) ++it; + else if(_comp(*end,value)) std::swap(*it,*end--); + else --end; + } + return it - _it; +} + + + +} // uLib + + + + + +#endif // VECTOR_H diff --git a/src/Core/testing/BoostAccumulatorTest.cpp b/src/Core/testing/BoostAccumulatorTest.cpp new file mode 100644 index 0000000..fabf75a --- /dev/null +++ b/src/Core/testing/BoostAccumulatorTest.cpp @@ -0,0 +1,88 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include + +#include +#include +#include +#include +#include +#include + + +#include "testing-prototype.h" + +using namespace boost::accumulators; + +using namespace boost; +using namespace boost::accumulators; + +typedef accumulator_set > acc; +typedef iterator_range >::iterator > histogram_type; + +template +class data_filler +{ +public: + data_filler(){} + T operator()() { return rand()/(T)RAND_MAX; } +}; + + +int main(int argc, char** argv) +{ + + //create some random data + std::vector data(100); + std::generate(data.begin(), data.end(), data_filler()); + int c = data.size();//cache size for histogramm. + + //create an accumulator + acc myAccumulator( tag::density::num_bins = 20, tag::density::cache_size = 10); + + //fill accumulator + for (int j = 0; j < c; ++j) + { + myAccumulator(data[j]); + } + + histogram_type hist = density(myAccumulator); + + double total = 0.0; + + for( int i = 0; i < hist.size(); i++ ) + { + std::cout << "Bin lower bound: " << hist[i].first << ", Value: " << hist[i].second << std::endl; + total += hist[i].second; + } + + std::cout << "Total: " << total << std::endl; //should be 1 (and it is) + + return 0; +} diff --git a/src/Core/testing/BoostTest.cpp b/src/Core/testing/BoostTest.cpp new file mode 100644 index 0000000..d22aa12 --- /dev/null +++ b/src/Core/testing/BoostTest.cpp @@ -0,0 +1,64 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include + +#include "Core/Object.h" +#include "Core/Options.h" + +#include "Core/Singleton.h" + +#include "testing-prototype.h" + +using namespace uLib; + + +struct A : Object { + A() : a(0) {} + int a; +}; + + +int main(int argc, char **argv) +{ + BEGIN_TESTING(Boost Mock); + + A &a = Singleton::get_mutable_instance(); + a.a = 5552368; + + const A &aa = Singleton::get_const_instance(); + + std::cout << a.a << "\n"; + std::cout << aa.a << "\n"; + + TEST1( a.a == 5552368 ); + TEST1( aa.a == 5552368 ); + + END_TESTING; +} diff --git a/src/Core/testing/CMakeLists.txt b/src/Core/testing/CMakeLists.txt new file mode 100644 index 0000000..ca9d68c --- /dev/null +++ b/src/Core/testing/CMakeLists.txt @@ -0,0 +1,34 @@ + +# TESTS +set( TESTS + SmartVectorTest + VectorTest + ObjectFlagsTest + ObjectParametersTest + ObjectCopyTest + StaticInterfaceTest + CommaInitTest + DebugTTreeDumpTest + BoostTest + BoostAccumulatorTest + PropertiesTest + FunctionTest + SignalTest + SerializeTest + SerializeDreadDiamondTest + DreadDiamondParameters + ObjectPropableTest + UuidTest + TypeIntrospectionTraversal + OptionsTest +) + +set(LIBRARIES + ${PACKAGE_LIBPREFIX}Core + ${PACKAGE_LIBPREFIX}Math + ${Boost_SERIALIZATION_LIBRARY} + ${Boost_SIGNALS_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${ROOT_LIBRARIES} +) +uLib_add_tests(${uLib-module}) diff --git a/src/Core/testing/CommaInitTest.cpp b/src/Core/testing/CommaInitTest.cpp new file mode 100755 index 0000000..a23f265 --- /dev/null +++ b/src/Core/testing/CommaInitTest.cpp @@ -0,0 +1,57 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include + +#include "testing-prototype.h" +#include "Core/Vector.h" + +#include + +#define test_print(file,str,...) \ + printf(str,__VA_ARGS__) + +using namespace uLib; + +int main() +{ + BEGIN_TESTING( Comma Init ); + + Vector test; + + test << 1,2,3,4,5; + + test.PrintSelf(std::cout); + + + test_print(stdout,"ciao %d \n",5); + + printf("ciao\n"); + + END_TESTING; +} diff --git a/src/Core/testing/DebugTTreeDumpTest.cpp b/src/Core/testing/DebugTTreeDumpTest.cpp new file mode 100644 index 0000000..c40b75d --- /dev/null +++ b/src/Core/testing/DebugTTreeDumpTest.cpp @@ -0,0 +1,118 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include + +#include "testing-prototype.h" +#include "Core/Debug.h" + +#include +#include +#include + +#include +#include +#include + + +#include +#include +#include +#include +#include +#include + +using namespace uLib; + + + +class DebugAdapterTTree : public detail::DebugAdapterInterface { + TTree *m_tree; +public: + + DebugAdapterTTree(const char *name) : m_tree(new TTree(name,name)) {} + ~DebugAdapterTTree() { delete m_tree; } + + void operator()(int val) { + std::cout << "debugger 2 prints: " << val << "\n"; + } +}; + + + + +int main(int argc, char **argv) +{ + + { + Debug debug; + DebugAdapterText adapter(std::cout); + DebugAdapterTTree treead("test"); + + debug.AddAdapter(adapter); + debug.AddAdapter(treead); + + int a = 5552368; + debug("a",a); + + std::string str = "ciao"; + debug("str",str); + + debug.Update(); + } + + + // TestTObject *test = new TestTObject; + + + TFile *file = new TFile("test_file.root","RECREATE"); + file->cd(); + TTree *tree = new TTree; +// tree->Branch("test",&test); + +// for(int i=0;i<10;++i) { +// test->a = i; +// test->b = -i; +// tree->Fill(); +// } + tree->Write(); + + gApplication = new TApplication("My ROOT Application", &argc, argv); + TBrowser *tbr = new TBrowser("test"); + tbr->Show(); + + + gApplication->Run(); + + return 0; +} + + + + + diff --git a/src/Core/testing/DreadDiamondParameters.cpp b/src/Core/testing/DreadDiamondParameters.cpp new file mode 100644 index 0000000..fa1b3fe --- /dev/null +++ b/src/Core/testing/DreadDiamondParameters.cpp @@ -0,0 +1,80 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include +#include +#include + + + +#include "boost/archive/xml_oarchive.hpp" +#include "boost/archive/xml_iarchive.hpp" + +#include "testing-prototype.h" + +#include "Core/Object.h" +#include "Math/Dense.h" +#include "Core/Mpl.h" + + +using namespace uLib; + + +////////////////////////////////////////////////////////////////////////////// + + +int main() { + + + + +} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Core/testing/Flags.h b/src/Core/testing/Flags.h new file mode 100644 index 0000000..f6a8d1b --- /dev/null +++ b/src/Core/testing/Flags.h @@ -0,0 +1,76 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CORE_FLAGS_H +#define U_CORE_FLAGS_H + +namespace uLib { + +template class Flags +{ + T i; +public: + typedef T EnumT; + + inline Flags(const Flags &f) : i(f.i) {} + inline Flags() : i((T)0) {} + inline Flags(T f) : i(f) {} + + inline Flags &operator=(const Flags &f) { i = f.i; return *this; } + inline Flags &operator&=(T mask) { i &= mask; return *this; } + + inline Flags &operator|=(const Flags f) { i |= f.i; return *this; } + inline Flags &operator|=(const T f) { i |= f; return *this; } + inline Flags &operator^=(const Flags f) { i ^= f.i; return *this; } + inline Flags &operator^=(const T f) { i ^= f; return *this; } + + inline Flags operator|(const Flags f) const { return Flags(i | f.i); } + inline Flags operator|(const T f) const { return Flags(i | f); } + inline Flags operator^(const Flags f) const { return Flags(i ^ f.i); } + inline Flags operator^(const T f) const { return Flags(i ^ f); } + inline Flags operator&(const Flags f) const { return Flags(i & f.i); } + inline Flags operator&(const T f) const { return Flags(i & f); } + inline Flags operator~() const { return Flags(~i); } + + inline bool operator !() const { return !i; } + inline bool testFlag(const T f) const + { return (i & f) == f && (f != 0 || i == f ); } + // inline bool operator==(const T f) const { return i==f; } + + inline T operator()() { return i; } + inline operator T() const { return i; } +}; + + +typedef Flags Flags2B; +typedef Flags Flags4B; +typedef Flags Flags8B; + +} // uLib + + +#endif // FLAGS_H diff --git a/src/Core/testing/FunctionTest.cpp b/src/Core/testing/FunctionTest.cpp new file mode 100644 index 0000000..9a3b3ca --- /dev/null +++ b/src/Core/testing/FunctionTest.cpp @@ -0,0 +1,57 @@ + +#include +#include +#include + +#include "testing-prototype.h" +#include "Core/Types.h" + +#include +#include + +namespace uLib { + +class TestVoxel { +public: + float m_data; + float Get() { return m_data; } + float ConstGet() const { return m_data; } + float & GetRef() { return m_data; } + const float & ConstGetRef() const { return m_data; } +}; + + + +} // uLib + +using namespace uLib; + +int main() { + BEGIN_TESTING(Function Test); + + + Vector v; + v.push_back(TestVoxel()); + v.push_back(TestVoxel()); + v.push_back(TestVoxel()); + v.push_back(TestVoxel()); + v.push_back(TestVoxel()); + v.push_back(TestVoxel()); + v.push_back(TestVoxel()); + + + v[5].m_data = 5552368.0; + + ProgrammableAccessor f1(&TestVoxel::m_data); + ProgrammableAccessor f2(&TestVoxel::GetRef); + + int i=0; + foreach (TestVoxel &el,v) { + f1.Set(&el,i++); + std::cout << " -> " << f2.Get(&el) << "\n"; + } + + + END_TESTING; +} + diff --git a/src/Core/testing/Makefile.am b/src/Core/testing/Makefile.am new file mode 100644 index 0000000..882b9fd --- /dev/null +++ b/src/Core/testing/Makefile.am @@ -0,0 +1,38 @@ +include $(top_srcdir)/Common.am + +#AM_DEFAULT_SOURCE_EXT = .cpp + +# if HAVE_CHECK +TESTS = SmartPointerTest \ + SmartVectorTest \ + VectorTest \ + ObjectFlagsTest \ + ObjectParametersTest \ + ObjectCopyTest \ + StaticInterfaceTest \ + CommaInitTest \ + DebugTTreeDumpTest \ + BoostTest \ + BoostAccumulatorTest \ + PropertiesTest \ + SignalTest \ + SerializeTest \ + SerializeDreadDiamondTest \ + DreadDiamondParameters \ + ObjectPropableTest \ + TypeIntrospectionTraversal \ + OptionsTest + +# UuidTest + +# else +# TEST = +# endif + +LDADD = $(top_srcdir)/libmutom-${PACKAGE_VERSION}.la $(AM_LIBS_BOOST) $(AM_LIBS_ROOT) + +check_PROGRAMS = $(TESTS) + + +all: $(TESTS) + diff --git a/src/Core/testing/ObjectCopyTest.cpp b/src/Core/testing/ObjectCopyTest.cpp new file mode 100644 index 0000000..5e1ddc9 --- /dev/null +++ b/src/Core/testing/ObjectCopyTest.cpp @@ -0,0 +1,50 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include + +#include "testing-prototype.h" +#include "Core/Types.h" +#include "Core/Object.h" + + +using namespace uLib; + + + + +int main() +{ + BEGIN_TESTING(ObjectParameters); + + + + + END_TESTING; +} diff --git a/src/Core/testing/ObjectFlagsTest.cpp b/src/Core/testing/ObjectFlagsTest.cpp new file mode 100644 index 0000000..58c1b3c --- /dev/null +++ b/src/Core/testing/ObjectFlagsTest.cpp @@ -0,0 +1,69 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "testing-prototype.h" +#include "Core/Object.h" + + +using namespace uLib; + + +//class Derived : public uLib::Object { +//public: +// Derived(int flags) : uLib::Object(flags) {} +// enum Flags { +// a = 1<<0, // 1 +// b = 1<<1, // 2 +// c = 1<<2 // 4 +// }; +//}; + + + + + +int main() { + BEGIN_TESTING(ObjectFlags); + +// Object o(2); +// o.flags() = 4; +// o.flags() |= 1; +// TEST1( o.flags() == 5); +// o.flags() &= 1; +// TEST1( o.flags() == 1); +// TEST1( o.flags().testFlag(1) ); + +// Derived d( Derived::a | Derived::b); +// d.flags() = Derived::c; +// d.flags() |= Derived::a; +// TEST1( d.flags() == Derived::a | Derived::c); +// d.flags() &= 1; +// TEST1( d.flags() == Derived::a); +// TEST1( d.flags().testFlag(Derived::a) ); + + END_TESTING +} diff --git a/src/Core/testing/ObjectMock/Makefile.am b/src/Core/testing/ObjectMock/Makefile.am new file mode 100644 index 0000000..d191897 --- /dev/null +++ b/src/Core/testing/ObjectMock/Makefile.am @@ -0,0 +1,11 @@ + +include $(top_srcdir)/Common.am + +#AM_DEFAULT_SOURCE_EXT = .cpp + + +LDADD = $(top_srcdir)/libmutom-0.1.la $(AM_LIBS_BOOST) + +bin_PROGRAMS = ObjectMock +ObjectMock_SOURCES = main.cpp Ob.cpp Ob1.cpp Ob2.cpp + diff --git a/src/Core/testing/ObjectMock/Ob.cpp b/src/Core/testing/ObjectMock/Ob.cpp new file mode 100644 index 0000000..ccf9bc8 --- /dev/null +++ b/src/Core/testing/ObjectMock/Ob.cpp @@ -0,0 +1,59 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Ob.h" + + + +BOOST_CLASS_EXPORT_IMPLEMENT(uLib::Ob) // use this in cpp file + +namespace uLib { + +class ObPrivate { +public: + + + +}; + + + +Ob::Ob() : + m_p(NULL), + m_s(NULL), + m_type_id(0), + d(new ObPrivate) +{ + +} + + + + +} + diff --git a/src/Core/testing/ObjectMock/Ob.h b/src/Core/testing/ObjectMock/Ob.h new file mode 100644 index 0000000..5ef3917 --- /dev/null +++ b/src/Core/testing/ObjectMock/Ob.h @@ -0,0 +1,181 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + + +#ifndef OB_H +#define OB_H + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "testing-prototype.h" + + + + + + +#include "Core/Vector.h" +#include "Core/Uuid.h" + +#include "boost/typeof/typeof.hpp" +#include + +#include +#include +#include +#include + + +#include +#include +#include + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// Mock of serializable object system // + +#define default(vlaue) +#define slots +#define signals public +#define emit +# define SLOT(a) a +# define SIGNAL(a) a + + + + + +namespace uLib { + + + + + + + + + +//////////////////////////////////////////////////////////////////////////////// +//// OB /////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +class Ob { + +public: + + Ob(); + ~Ob() { + if(m_p) delete m_p; + } + + //// init ////////////////////////////////////////////////////////////////// + template + void init(){ + if(!m_type_id) { + m_p = (Parameters *) new typename T::Parameters; + m_type_id = TypeRegister::Controller()->AddType< T >(); + } + } + + virtual void PrintSelf(std::ostream &o) const { o << "Base Object PrintSelf\n"; } + +protected: + // parameters ////////////////////////////////////////////////////////////// + struct Parameters { friend class boost::serialization::access; }; + inline Parameters &p() { assert(m_p); return *m_p; } + inline const Parameters &p() const { assert(m_p); return *m_p; } + virtual void init() {} + + + // serialization access //////////////////////////////////////////////////// + friend class boost::serialization::access; + template + void serialize(Archive &ar, const unsigned int version) { + // ar & boost::serialization::make_nvp("instance_size", m_type_id->size); + // ar & boost::serialization::make_nvp("instance_data",boost::serialization::make_binary_object(this,m_type_id->size)); + } + + template + static void serialize(Archive &ar, Ob &ob, const unsigned int version) {} + + template + static void serialize(Archive &ar, Ob::Parameters &p, const unsigned int version) {} + + +public: + + TypeRegister::Entry * type_id() const { return m_type_id; } + +private: + + // members ///////////////////////////////////////////////////////////////// + struct Parameters *m_p; + struct Signals *m_s; + + friend class ObPrivate; + class ObPrivate *d; + + TypeRegister::Entry * m_type_id; +}; + + + + + + + + + +} + +//////////////////////////////////////////////////////////////////////////////// + + + + + +BOOST_CLASS_EXPORT_KEY(uLib::Ob) + + + + + + + +#endif diff --git a/src/Core/testing/ObjectMock/Ob1.cpp b/src/Core/testing/ObjectMock/Ob1.cpp new file mode 100644 index 0000000..e7a36ba --- /dev/null +++ b/src/Core/testing/ObjectMock/Ob1.cpp @@ -0,0 +1,80 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Ob1.h" + +namespace uLib { + + + + + +// created by moc // -------------------------------------------------------- // + + +void Ob1::init() +{ + Ob::init(); + boost::serialization::void_cast_register(); + BaseClass::init(); + // default parameters value // + p().a = 1; + p().b = 2; +} + + + + +//// serialization accessor that can be made by moc // + +//template +//void Ob1::serialize(Archive &ar, Ob1::Parameters &p, const unsigned int version) +//{ +// Ob1::BaseClass::serialize( ar,p,version ); +// ar & boost::serialization::make_nvp("a",p.a); +// ar & boost::serialization::make_nvp("b",p.b); +//} + +//template +//void Ob1::serialize(Archive &ar, Ob1 &ob, const unsigned int version ) +//{ +// Ob1::BaseClass::serialize(ar,ob,version); +// // other members to be serialized // +//} + + + +// -------------------------------------------------------------------------- // + + + +} + + +BOOST_CLASS_EXPORT_IMPLEMENT(uLib::Ob1) // use this in cpp file + diff --git a/src/Core/testing/ObjectMock/Ob1.h b/src/Core/testing/ObjectMock/Ob1.h new file mode 100644 index 0000000..5796c4f --- /dev/null +++ b/src/Core/testing/ObjectMock/Ob1.h @@ -0,0 +1,122 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef OB1_H +#define OB1_H + +#include +#include "Ob.h" + + +//////////////////////////////////////////////////////////////////////////////// +// OB1 /////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace uLib { + +class Ob1 : public Ob { +public: + + typedef Ob BaseClass; + struct Parameters : public BaseClass::Parameters { + int a default(1); + int b default(2); + }; + virtual ~Ob1() {} + + // created by macro //////////////////////////////////////////////////////// + void init(); + inline Parameters &p() { return (Parameters &)Ob::p(); } + inline const Parameters &p() const { return (Parameters &)Ob::p(); } + static Ob1 *New() { Ob1 *o = new Ob1; o->init(); return o; } + + + friend class boost::serialization::access; + + template + void serialize(Archive &ar, const unsigned int version); + + template + static void serialize(Archive & ar, + Ob1::Parameters & p, + const unsigned int version ); + + template + static void serialize(Archive &ar, + Ob1 &ob, + const unsigned int version ); + //////////////////////////////////////////////////////////////////////////// + + virtual void PrintSelf(std::ostream &o) const { o << "Object Ob1 PrintSelf\n"; } + + +}; + +// serialize accessors in macro // ------------------------------------------ // +template +void serialize(Archive &ar, Ob1::Parameters &p, const unsigned int version ) +{ + Ob1::serialize(ar,p,version); +} + + +template +void Ob1::serialize(Archive & ar, const unsigned int version) +{ + ar & boost::serialization::make_nvp("parameters",p()); + this->serialize(ar,*this,version); + Ob::serialize(ar,version); +} +// -------------------------------------------------------------------------- // + + +// serialization accessor that can be made by moc // + +template +void Ob1::serialize(Archive &ar, Ob1::Parameters &p, const unsigned int version) +{ + Ob1::BaseClass::serialize( ar,p,version ); + ar & boost::serialization::make_nvp("a",p.a); + ar & boost::serialization::make_nvp("b",p.b); +} + +template +void Ob1::serialize(Archive &ar, Ob1 &ob, const unsigned int version ) +{ + Ob1::BaseClass::serialize(ar,ob,version); + // other members to be serialized // +} + + + + +} // namespace + +BOOST_CLASS_EXPORT_KEY(uLib::Ob1) // use this in header + + +#endif diff --git a/src/Core/testing/ObjectMock/Ob2.cpp b/src/Core/testing/ObjectMock/Ob2.cpp new file mode 100644 index 0000000..c526faf --- /dev/null +++ b/src/Core/testing/ObjectMock/Ob2.cpp @@ -0,0 +1,73 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + + +#include "Ob2.h" + +namespace uLib { + + +// created by moc // -------------------------------------------------------- // + + + + +void Ob2::init() +{ + Ob::init(); + boost::serialization::void_cast_register(); + BaseClass::init(); + p().c = 3; + p().d = 4; +} + +//template +//void Ob2::serialize(Archive &ar, Parameters &p, const unsigned int version) +//{ +// Ob2::BaseClass::serialize( ar,p,version ); +// ar & boost::serialization::make_nvp("c",p.c); +// ar & boost::serialization::make_nvp("d",p.d); +//} + +//template +//void Ob2::serialize(Archive &ar, Ob2 &o, const unsigned int version ) +//{ +// Ob2::BaseClass::serialize(ar,o,version); +// ar & boost::serialization::make_nvp("serializzable_member",o.serializzable_member); +// // other members // +//} + + + +// -------------------------------------------------------------------------- // + +} + + + +BOOST_CLASS_EXPORT_IMPLEMENT(uLib::Ob2) // use this in cpp file diff --git a/src/Core/testing/ObjectMock/Ob2.h b/src/Core/testing/ObjectMock/Ob2.h new file mode 100644 index 0000000..8735ecb --- /dev/null +++ b/src/Core/testing/ObjectMock/Ob2.h @@ -0,0 +1,135 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#ifndef OB2_H +#define OB2_H + + +#include "Ob.h" +#include "Ob1.h" + +//////////////////////////////////////////////////////////////////////////////// +// OB2 /////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace uLib { + +class Ob2 : public Ob1 { +public: + typedef Ob1 BaseClass; + + struct Parameters : public BaseClass::Parameters { + int c default(3),d default(4); + }; + + Ob2() { + serializzable_member = 0; + memset(non_serializable_member,0,sizeof(char[250])); + } + + virtual ~Ob2() {} + + // created by macro //////////////////////////////////////////// + void init(); + inline Parameters &p() { return (Parameters &)Ob::p(); } + inline const Parameters &p() const { return (Parameters &)Ob::p(); } + static Ob2 *New() { Ob2 *o = new Ob2; o->init(); return o; } + + friend class boost::serialization::access; + template + void serialize(Archive &ar, const unsigned int version); + template + static void serialize(Archive & ar, Parameters & p, const unsigned int version ); + template + static void serialize(Archive &ar, Ob2 &o, const unsigned int version ); + + //////////////////////////////////////////////////////////////// + + virtual void PrintSelf(std::ostream &o) const { o << "Object Ob2 PrintSelf\n"; } + + int serializzable_member; + char non_serializable_member[250]; +private: + +}; + + + +template +void serialize(Archive &ar, Ob2::Parameters &p, const unsigned int version ) +{ + Ob2::serialize(ar,p,version); +} + + + +template +void Ob2::serialize(Archive & ar, const unsigned int version) +{ +// boost::serialization::split_member(ar, *this, version); + ar & boost::serialization::make_nvp("parameters",p()); + this->serialize(ar,*this,version); + Ob::serialize(ar,version); +} + + + + + + +template +void Ob2::serialize(Archive &ar, Parameters &p, const unsigned int version) +{ + Ob2::BaseClass::serialize( ar,p,version ); + ar & boost::serialization::make_nvp("c",p.c); + ar & boost::serialization::make_nvp("d",p.d); +} + +template +void Ob2::serialize(Archive &ar, Ob2 &o, const unsigned int version ) +{ + Ob2::BaseClass::serialize(ar,o,version); + ar & boost::serialization::make_nvp("serializzable_member",o.serializzable_member); + // other members // +} + + + + + +} + + +BOOST_CLASS_EXPORT_KEY(uLib::Ob2) // use this in header +//BOOST_SERIALIZATION_FACTORY_0(uLib::Ob2) // use this for plugin construction + + + + + +#endif diff --git a/src/Core/testing/ObjectMock/main.cpp b/src/Core/testing/ObjectMock/main.cpp new file mode 100644 index 0000000..97c0a8b --- /dev/null +++ b/src/Core/testing/ObjectMock/main.cpp @@ -0,0 +1,174 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include + +#include +#include +#include +#include + +#include + + + +#include "Ob.h" +#include "Ob1.h" +#include "Ob2.h" + + +using namespace uLib; + + +////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// +//// test boost ETI system // + +// used in external plugin construction mechanism // +int test_boost_eti () { + + boost::serialization::extended_type_info_typeid i_eti; + + std::cout << "int eti guid key: " << i_eti.get_key() << "\n"; + + Ob2 *test = (Ob2*)i_eti.construct(0); + test->init(); + + std::cout << "int eti typeid name: " << i_eti.get_typeid().name() << "\n"; + +} + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// main // + + + + + + +int main() +{ + +// //////////////////////////////////////////////////// +// // serialization tests +{ + Ob1 ob1; + ob1.init(); + std::cout << "ob1 param: " << + ob1.p().a << " " << + ob1.p().b << "\n"; + + + + Ob2 *ob2 = Ob2::New(); + std::cout << "ob2 param: " << + ob2->p().a << " " << + ob2->p().b << " " << + ob2->p().c << " " << + ob2->p().d << "\n"; + std::cout << "ob2 uuid: " << + to_string(ob2->type_id()->id) << "\n"; + + +// // serialize ob2 to file // +// { +// std::ofstream ofs("_BoostTest.xml"); +// boost::archive::xml_oarchive oa(ofs); +// oa << BOOST_SERIALIZATION_NVP(ob2); +// } + + // serialize ob2 to file via objact base cast // + { + Ob *ob = Ob2::New(); + sprintf(static_cast(ob)->non_serializable_member, + "deserializzati dati interni attraverso dump binario"); + std::ofstream ofs("_BoostTest.xml"); + boost::archive::xml_oarchive oa(ofs); + oa << BOOST_SERIALIZATION_NVP(ob); + } + + +// delete ob2; + + // deserialize ob2 from file // + { + Ob2 *newob2 = Ob2::New(); + newob2->p().c = 0; + std::ifstream ifs("_BoostTest.xml"); + boost::archive::xml_iarchive ia(ifs); + ia >> BOOST_SERIALIZATION_NVP(*newob2); + printf("%s\n",newob2->non_serializable_member); + std::cout << "deserialized ob2: > " << + newob2->p().a << " " << + newob2->p().b << " " << + newob2->p().c << " " << + newob2->p().d << "\n"; + std::cout << "deserialized ob2 member: " << + "serializable_member = " << newob2->serializzable_member << "\n"; + std::cout << "deserialized ob2 uuid: " << + to_string(newob2->type_id()->id) << "\n"; + } + +} + + + + + + + +} + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Core/testing/ObjectMock/testing-prototype.h b/src/Core/testing/ObjectMock/testing-prototype.h new file mode 100644 index 0000000..39f4e6c --- /dev/null +++ b/src/Core/testing/ObjectMock/testing-prototype.h @@ -0,0 +1,37 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include + +#define BEGIN_TESTING(name) \ +static int _fail = 0; \ +printf("..:: Testing " #name " ::..\n"); + +#define TEST1(val) _fail += (val)==0 +#define TEST0(val) _fail += (val)!=0 +#define END_TESTING return _fail; + diff --git a/src/Core/testing/ObjectParametersTest.cpp b/src/Core/testing/ObjectParametersTest.cpp new file mode 100644 index 0000000..5a5cc4d --- /dev/null +++ b/src/Core/testing/ObjectParametersTest.cpp @@ -0,0 +1,61 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include +#include +#include + +#include "boost/archive/xml_oarchive.hpp" +#include "boost/archive/xml_iarchive.hpp" + +#include "Core/Object.h" +#include "Math/Dense.h" + +#include "testing-prototype.h" + + + + +using namespace uLib; + + + + +int main() { + +} + + + + + + + + + diff --git a/src/Core/testing/ObjectPropableTest.cpp b/src/Core/testing/ObjectPropableTest.cpp new file mode 100644 index 0000000..9e319db --- /dev/null +++ b/src/Core/testing/ObjectPropableTest.cpp @@ -0,0 +1,237 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include +#include +#include +#include + + +#include "Core/Types.h" +#include "Core/Object.h" +#include "Core/ObjectProps.h" +#include "Core/StringReader.h" +#include "Math/Dense.h" + +#include "boost/archive/text_oarchive.hpp" +#include "boost/archive/text_iarchive.hpp" + + +#include "testing-prototype.h" + + + + +using namespace uLib; + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// STRUCTURES // + + +struct A : virtual Object { + + uLibTypeMacro(A, Object) + + properties() { + int p_a; + Vector3f p_3f; + }; + + int m_a; +}; + +void A::init_properties() { + $_init(); + $$.p_a = 0; + $$.p_3f << 1,2,3; +} + +ULIB_SERIALIZABLE_OBJECT(A) +ULIB_SERIALIZE_OBJECT(A, Object) { ar & AR(m_a); } +ULIB_SERIALIZE_OBJECT_PROPS(A) { ar & AR(p_a) & AR(p_3f); } + + + + +struct B : A { + uLibTypeMacro(B,A) + + properties() { + std::string p; + }; + + B() : m_b(324) {} + + int m_b; +}; + + +void B::init_properties() { + $_init(); + $$.p = "ciao"; +} + +ULIB_SERIALIZABLE_OBJECT(B) +ULIB_SERIALIZE_OBJECT(B,A) { ar & AR(m_b); } +ULIB_SERIALIZE_OBJECT_PROPS(B) { ar & AR(p); } + + + +struct C { + int m_c; + std::string m_str; +}; + +ULIB_SERIALIZABLE(C) +ULIB_SERIALIZE(C) { ar & AR(m_c) & AR(m_str); } + + + +struct D : virtual Object, B { + uLibTypeMacro(D,Object,B) + + properties() { + C p_c; + }; +}; + +void D::init_properties() { + $_init(); + $$.p_c.m_c = 1234; +} + +ULIB_SERIALIZABLE_OBJECT(D) +ULIB_SERIALIZE_OBJECT(D,Object) {} +ULIB_SERIALIZE_OBJECT_PROPS(D) { + ar & AR(p_c); +} + + + +class E : public C, public D { + uLibTypeMacro(E,D,C) +public: + E() : m_Ea(5552368) {} + int m_Ea; +}; + +ULIB_SERIALIZABLE_OBJECT(E) +ULIB_SERIALIZE_OBJECT(E,C,D) { + ar & AR(m_Ea); +} + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// TESTS // + + +int test_xml_direct() { + // TEST ARCHIVE SAVE AND LOAD direct // + E o; o.init_properties(); + o.$$.p_c.m_str = "works"; + { + std::ofstream file("test.xml"); + Archive::xml_oarchive ar(file); + ar << NVP(o); + } + o.$$.p_c.m_str = "hola"; + { + std::ifstream file("test.xml"); + Archive::xml_iarchive ar(file); + ar >> NVP(o); + } + std::cout << o.$$.p_c.m_str << "\n"; + return ( o.$$.p_c.m_str == "works" ); +} + + +int test_xml_pointer() { + // TEST ARCHIVE SAVE AND LOAD from pointer // + E *o = new E; o->init_properties(); + o->$$.p_c.m_str = "works"; + { + std::ofstream file("test.xml"); + Archive::xml_oarchive ar(file); + ar << NVP(o); + } + o->$$.p_c.m_str = "hola"; + { + std::ifstream file("test.xml"); + Archive::xml_iarchive ar(file); + ar >> NVP(o); + } + std::cout << o->$$.p_c.m_str << "\n"; + return ( o->$$.p_c.m_str == "works" ); +} + + +int test_xml_objsave() { + // TEST SELF SAVE + E o; o.init_properties(); + o.$(B).p = "works"; + { + std::ofstream file("test.xml"); + Object::SaveXml(file,o); + } + o.$(B).p = "hola"; + { + std::ifstream file("test.xml"); + Object::LoadXml(file,o); + } + + std::cout << o.$(B).p << "\n"; + return ( o.$(B).p == "works" ); +} + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// MAIN // + +int main() +{ + BEGIN_TESTING(PropableTest); + + TEST1( test_xml_direct() ); + TEST1( test_xml_pointer() ); + TEST1( test_xml_objsave() ); + + END_TESTING; +} + + diff --git a/src/Core/testing/OptionsTest.cpp b/src/Core/testing/OptionsTest.cpp new file mode 100644 index 0000000..5463ae7 --- /dev/null +++ b/src/Core/testing/OptionsTest.cpp @@ -0,0 +1,72 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include + + + +#include "Core/Object.h" +#include "Core/Options.h" +#include "testing-prototype.h" + + +using namespace uLib; + + + + +int main(int argc, char **argv) +{ + BEGIN_TESTING(Boost ProgramOptions); + + + std::string optfile("configuration.ini"); + int a = 0; + int b = 0; + Options opt; + + opt.add_options() + ("help", "printout help") + ("value",&a,"value") + ("config",&optfile,"config_file"); + + opt.add_config_options() + ("B.value",&b,"b vlaue"); + + opt.parse_command_line(argc,argv); + opt.parse_config_file(optfile.c_str()); + + std::cout << "a = " << a << "\n"; + std::cout << "b = " << b << "\n"; + + + END_TESTING; +} + + diff --git a/src/Core/testing/PropertiesTest.cpp b/src/Core/testing/PropertiesTest.cpp new file mode 100644 index 0000000..23e4c4e --- /dev/null +++ b/src/Core/testing/PropertiesTest.cpp @@ -0,0 +1,96 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include + +#include + + +#include "Core/Object.h" +#include "testing-prototype.h" + +#define emit + + + + +template +class property +{ + typedef boost::signals2::signal& )> signal_t; + +public: + property() : m_changed(new signal_t) {} + property(const T in) : value(in) , m_changed(new signal_t) {} + + inline operator T const & () const { return value; } + inline operator T & () { return value; } + inline T & operator = (const T &i) { value = i; return value; } + template T2 & operator = (const T2 &i) { T2 &guard = value; } // Assign exact identical types only. + inline signal_t & valueChanged() { return *m_changed; } + +private: + T value; + boost::shared_ptr m_changed; +}; + + +//template +//class property { +// typedef boost::signals2::signal signal_t; + +//public: +// property() : m_changed() {} +// property(const T in) : value(in) , m_changed() {} + +// inline operator T const & () const { return value; } +// inline operator T & () { valueChanged()(value); return value; } +// inline T & operator = (const T &i) { value = i; valueChanged()(value); return value; } +// template T2 & operator = (const T2 &i) { T2 &guard = value; } // Assign exact identical types only. +// inline signal_t &valueChanged() { return m_changed; } + +//private: +// property(const property &); +// property &operator = (const property&); + +// T value; +// signal_t m_changed; +//}; + +// test generic void function slot // +void PrintSlot(const property &i) { std::cout << "slot called, new value = " << i << "!\n"; } + + + + + +int main() +{ + + +} diff --git a/src/Core/testing/SerializeDreadDiamondTest.cpp b/src/Core/testing/SerializeDreadDiamondTest.cpp new file mode 100644 index 0000000..5bd3a57 --- /dev/null +++ b/src/Core/testing/SerializeDreadDiamondTest.cpp @@ -0,0 +1,114 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include +#include +#include + +#include "Core/Object.h" + +#include "testing-prototype.h" + +using namespace uLib; + + + + + + + +struct A : Object { + uLibTypeMacro(A,Object) + A() : numa(5552368) {} + int numa; +}; + + +ULIB_SERIALIZABLE_OBJECT(A) +ULIB_SERIALIZE_OBJECT(A,Object) { + ar & AR(numa); +} + +struct B : virtual Object { + uLibTypeMacro(B,Object) + B() : numb(5552369) {} + int numb; +}; + +ULIB_SERIALIZABLE_OBJECT(B) +ULIB_SERIALIZE_OBJECT(B,Object) { ar & AR(numb); } + + +struct C : B { + uLibTypeMacro(C,B) + C() : numc(5552370) {} + int numc; +}; + +ULIB_SERIALIZABLE_OBJECT(C) +ULIB_SERIALIZE_OBJECT(C,B) { ar & AR(numc); } + +struct D : A,B { + uLibTypeMacro(D,A,B) + + D() : numd(5552371) {} + int numd; +}; + +ULIB_SERIALIZABLE_OBJECT(D) +ULIB_SERIALIZE_OBJECT(D,A,B) { ar & AR(numd); } + + + +main() { + A o; o.init_properties(); + + Archive::xml_oarchive(std::cout) << NVP(o); + +} + + + + + + + + + + + + + + + + + + + + diff --git a/src/Core/testing/SerializeMock/Makefile.am b/src/Core/testing/SerializeMock/Makefile.am new file mode 100644 index 0000000..2151e88 --- /dev/null +++ b/src/Core/testing/SerializeMock/Makefile.am @@ -0,0 +1,13 @@ + +include $(top_srcdir)/Common.am +#AM_DEFAULT_SOURCE_EXT = .cpp + + +LDADD = $(top_srcdir)/libmutom-0.1.la $(AM_LIBS_BOOST) + + + +bin_PROGRAMS = SerializeMock +SerializeMock_SOURCES = main.cpp Ob.cpp Ob1.cpp +#log_archive.cpp + diff --git a/src/Core/testing/SerializeMock/Ob.cpp b/src/Core/testing/SerializeMock/Ob.cpp new file mode 100644 index 0000000..5cf243d --- /dev/null +++ b/src/Core/testing/SerializeMock/Ob.cpp @@ -0,0 +1,103 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + + + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_base.cpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +//#include +//#include +//#include +//#include + +#include "Ob.h" + + +//// A ///////////////////////////////////////////////////////////////////////// + +template +void A::serialize(Archive &ar, unsigned int v) { + ar & BOOST_SERIALIZATION_NVP(i); +} + +//_SERIALIZE_IMPL(A,boost::archive::polymorphic_oarchive) +SERILIZE_IMPL(A) + +void A::Save(boost::archive::polymorphic_oarchive &ar) +{ ar << boost::serialization::make_nvp(boost::serialization::guid(),this); } + +// note: only the most derived classes need be exported +// BOOST_CLASS_EXPORT(A) + + + + +//// B ///////////////////////////////////////////////////////////////////////// + +template +void B::serialize(Ar &ar, unsigned int v) { + ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A); +} + +SERILIZE_IMPL(B) + +void B::Save(boost::archive::polymorphic_oarchive &ar) +{ ar << boost::serialization::make_nvp(boost::serialization::guid(),this); } + +_SPECIALIZE_IS_VIRTUAL_BASE(A,B) +BOOST_CLASS_EXPORT_IMPLEMENT(B) + + + + +//// C ///////////////////////////////////////////////////////////////////////// + +template +void C::serialize(Ar &ar, unsigned int v) { + ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A); +} + +SERILIZE_IMPL(C) + +void C::Save(boost::archive::polymorphic_oarchive &ar) +{ ar << boost::serialization::make_nvp(boost::serialization::guid(),this); } + +_SPECIALIZE_IS_VIRTUAL_BASE(A,C) +BOOST_CLASS_EXPORT_IMPLEMENT(C) + + + + diff --git a/src/Core/testing/SerializeMock/Ob.h b/src/Core/testing/SerializeMock/Ob.h new file mode 100644 index 0000000..8710400 --- /dev/null +++ b/src/Core/testing/SerializeMock/Ob.h @@ -0,0 +1,112 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + + +#ifndef OB_H +#define OB_H + + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// test_polymorphic2.hpp + +// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include + +#include + +#include +#include +#include +#include + + + +#define _SERIALIZE_IMPL_SEQ \ + (boost::archive::polymorphic_iarchive) \ + (boost::archive::polymorphic_oarchive) \ + (boost::archive::xml_iarchive) \ + (boost::archive::xml_oarchive) + +#define _SERIALIZE_IMPL(Class,Archive) \ + template void Class::serialize(Archive &ar,const unsigned int); + +#define _SERIALIZE_IMPL_OP(r,data,elem) _SERIALIZE_IMPL(data,elem) + +#define SERILIZE_IMPL(Class) BOOST_PP_SEQ_FOR_EACH(_SERIALIZE_IMPL_OP,Class,_SERIALIZE_IMPL_SEQ) + +#define _SPECIALIZE_IS_VIRTUAL_BASE(Base,Derived) namespace boost{ template<> struct is_virtual_base_of: public boost::mpl::true_ {}; } +#define _SPECIALIZE_IS_VIRTUAL_BASE_OP(r,data,elem) _SPECIALIZE_IS_VIRTUAL_BASE(data,elem) + + + + +// should pass compilation and execution +namespace boost { +namespace archive { + class polymorphic_oarchive; + class polymorphic_iarchive; +} +} + + +struct A { + virtual ~A() {} + + template void serialize(Archive &ar, unsigned int v); + virtual void Save(boost::archive::polymorphic_oarchive &ar); + + int i; +}; + + +struct B : virtual A { + + template void serialize(Ar &ar, unsigned int v); + virtual void Save(boost::archive::polymorphic_oarchive &ar); + +}; + +BOOST_CLASS_EXPORT_KEY(B) + +struct C : virtual A { + + template void serialize(Ar &ar, unsigned int v); + virtual void Save(boost::archive::polymorphic_oarchive &ar); +}; + +BOOST_CLASS_EXPORT_KEY(C) + + + +#endif diff --git a/src/Core/testing/SerializeMock/Ob1.cpp b/src/Core/testing/SerializeMock/Ob1.cpp new file mode 100644 index 0000000..4e2f411 --- /dev/null +++ b/src/Core/testing/SerializeMock/Ob1.cpp @@ -0,0 +1,52 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include +#include +#include +#include + +#include "Ob.h" +#include "Ob1.h" + + +template +void D::serialize(Ar &ar, unsigned int v) { + ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(B); + ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(C); +} + +SERILIZE_IMPL(D) + +void D::Save(boost::archive::polymorphic_oarchive &ar) +{ ar << boost::serialization::make_nvp(boost::serialization::guid(),this); } + +_SPECIALIZE_IS_VIRTUAL_BASE(B,D) +_SPECIALIZE_IS_VIRTUAL_BASE(C,D) +BOOST_CLASS_EXPORT_IMPLEMENT(D) diff --git a/src/Core/testing/SerializeMock/Ob1.h b/src/Core/testing/SerializeMock/Ob1.h new file mode 100644 index 0000000..c062906 --- /dev/null +++ b/src/Core/testing/SerializeMock/Ob1.h @@ -0,0 +1,45 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef OB1_H +#define OB1_H + + +#include "Ob.h" + + +struct D : B,C { + + template void serialize(Ar &ar, unsigned int v); + virtual void Save(boost::archive::polymorphic_oarchive &ar); + +}; + +BOOST_CLASS_EXPORT_KEY(D) + + +#endif // OB1_H diff --git a/src/Core/testing/SerializeMock/main.cpp b/src/Core/testing/SerializeMock/main.cpp new file mode 100644 index 0000000..fc8f0e1 --- /dev/null +++ b/src/Core/testing/SerializeMock/main.cpp @@ -0,0 +1,111 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include + +#include "boost/archive/xml_oarchive.hpp" +#include "boost/archive/polymorphic_xml_oarchive.hpp" +#include "boost/archive/polymorphic_xml_iarchive.hpp" +#include "boost/archive/polymorphic_text_oarchive.hpp" +#include "boost/archive/polymorphic_text_iarchive.hpp" + +#include "boost/serialization/export.hpp" + +#include "Ob.h" +#include "Ob1.h" + +#include "boost/archive/detail/basic_pointer_oserializer.hpp" + + + + + +//template class boost::archive::detail::archive_serializer_map; + +int main(int /*argc*/, char* /*argv*/[]) +{ + D d; + A *a = &d; + a->i = 5552368; + + A *la = NULL; + + D *dla = NULL; + + { + std::ofstream file; + file.open("test.xml"); + boost::archive::polymorphic_xml_oarchive oa_implementation(file,0); + boost::archive::polymorphic_oarchive & opa = oa_implementation; + opa << BOOST_SERIALIZATION_NVP(a); + a->Save(opa); + file.close(); + } + + { + std::ifstream file; + file.open("test.xml"); + boost::archive::polymorphic_xml_iarchive ia_implementation(file,0); + boost::archive::polymorphic_iarchive & ipa = ia_implementation; + ipa >> BOOST_SERIALIZATION_NVP(la); + ipa >> BOOST_SERIALIZATION_NVP(dla); + file.close(); + } + + boost::archive::polymorphic_xml_oarchive xoa(std::cout); + dla->Save(xoa); + + + +} + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Core/testing/SerializeTest.cpp b/src/Core/testing/SerializeTest.cpp new file mode 100644 index 0000000..f15660a --- /dev/null +++ b/src/Core/testing/SerializeTest.cpp @@ -0,0 +1,249 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include + +#include "Core/Object.h" +#include "Core/Archives.h" +#include "ParticlePhysics/MuonTomography/MuonScatter.h" + +#include "testing-prototype.h" + +using namespace uLib; + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// MANUAL SERIALIZATION // + +struct V3f { + + float x,y,z; + V3f() + { x = y = z =0; } + + V3f(float x, float y, float z) : + x(x), y(y), z(z) {} + + template + void serialize (Archive &ar,unsigned int v) { + ar + & "<" & NVP(x) & NVP(y) & NVP(z) & ">"; + } +}; + +ULIB_CLASS_EXPORT_KEY(V3f); +ULIB_CLASS_EXPORT_IMPLEMENT(V3f); + + +inline std::ostream & +operator <<(std::ostream &o, const V3f &v) { + Archive::hrt_oarchive(o) << v; + return o; +} + +inline std::istream & +operator >>(std::istream &is, V3f &v) { + Archive::hrt_iarchive(is) >> v; + return is; +} + + + + +int test_V3f() { + // testing human readble archive with simple serializable structure // + + V3f v1(1,2,3),v2,v3,v4; + std::cout << "v --> " << v1 << "\n"; + + std::stringstream ss; ss << v1; + std::cout << "ss.v --> " << ss.str() << "\n"; + + Archive::hrt_iarchive ar(ss); ar >> v2; + std::cout << "v2 --> " << v2 << "\n"; + + std::stringstream("<2 3 4>") >> v3; + std::cout << "v3 --> " << v3 << "\n"; + + // std::cout << "insert V3f string to parse: "; std::cin >> v4; + // std::cout << "v4 --> " << v4 << "\n"; + return (1); +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// OBJECT SERIALIZATION // + +class A : public virtual Object { + uLibTypeMacro(A,Object) + ULIB_SERIALIZE_ACCESS +public: + A() : m_a(5552368) {} + + properties() { + std::string p_a; + }; + + uLibRefMacro (a,int); +private: + int m_a; +}; + +void A::init_properties() { + $_init(); + $$.p_a = "A property string"; +} + +ULIB_SERIALIZABLE_OBJECT(A) +ULIB_SERIALIZE_OBJECT(A,Object) { + ar + & "Object A : " + & "--> m_a = " & AR(m_a) + & "\n"; +} + +ULIB_SERIALIZE_OBJECT_PROPS(A) { + ar + & "Object A properties: " + & "---> p_a = " & AR(p_a) & "\n"; +} + + + +int testing_xml_class() { + + A a; a.init_properties(); + + { + std::ofstream file("test.xml"); + Archive::xml_oarchive(file) << NVP(a); + } + a.a() = 0; + a.$$.p_a = "zero string"; + { + std::ifstream file("test.xml"); + Archive::xml_iarchive(file) >> NVP(a); + } + + Archive::xml_oarchive(std::cout) << NVP(a); + return ( a.a() == 5552368 && a.$$.p_a == "A property string" ); +} + +int testing_hrt_class() { + + A a; a.init_properties(); + + { + std::ofstream file("test.xml"); + Archive::hrt_oarchive(file) << NVP(a); + } + a.a() = 0; + a.$$.p_a = "zero string"; + { + // ERRORE FIX ! + // std::ifstream file("test.xml"); + // Archive::hrt_iarchive(file) >> NVP(a); + } + + Archive::hrt_oarchive(std::cout) << NVP(a); + return ( a.a() == 5552368 && a.$$.p_a == "A property string" ); +} + + + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// MUON SCATTER EXAMPLE // + +int testing_mu() +{ + std::stringstream ss; + + MuonScatter mu; + mu.SetMomentumIn(555); + mu.SetMomentumOut(2368); + { + std::ofstream file("test.txt"); + file << mu; + } + + mu.SetMomentumIn(0); + mu.SetMomentumOut(0); + { + std::ifstream file("test.txt"); + file >> mu; + } + + std::cout << mu << "\n"; + + +} + + + + + + +int main() { + BEGIN_TESTING(Serialize Test); + + TEST1( test_V3f() ); + TEST1( testing_xml_class() ); + // testing_hrt_class(); ///// << ERRORE in HRT with properties + TEST1( testing_mu() ); + + END_TESTING; +} + + + + + + + + + + + + + diff --git a/src/Core/testing/SignalMock/Makefile.am b/src/Core/testing/SignalMock/Makefile.am new file mode 100644 index 0000000..dfb0c93 --- /dev/null +++ b/src/Core/testing/SignalMock/Makefile.am @@ -0,0 +1,11 @@ + +include $(top_srcdir)/Common.am + +#AM_DEFAULT_SOURCE_EXT = .cpp + + +LDADD = $(top_srcdir)/libmutom-0.1.la $(AM_LIBS_BOOST) + +bin_PROGRAMS = SignalMock +SignalMock_SOURCES = main.cpp Ob.cpp Ob1.cpp Ob2.cpp + diff --git a/src/Core/testing/SignalMock/Ob.cpp b/src/Core/testing/SignalMock/Ob.cpp new file mode 100644 index 0000000..6a19a13 --- /dev/null +++ b/src/Core/testing/SignalMock/Ob.cpp @@ -0,0 +1,104 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Ob.h" + + + + + +namespace uLib { + + + + + + + +namespace SignalMock { + +class ObPrivate { +public: + + struct Signal { + GenericMFPtr sigptr; + std::string sigstr; + SignalBase *signal; + }; + + Vector sigv; + + +}; + + + + + + +Ob::Ob() : + d(new ObPrivate) +{} + + +void Ob::PrintSelf(std::ostream &o) const +{ + o << "OBJECT signal Mock: ------------------\n"; + Vector::Iterator itr; + for(itr = d->sigv.begin(); itrsigv.end(); itr++) + { + o << " signal:[ " << itr->sigstr << " ]\n"; + } + o << "--------------------------------------\n\n"; +} + + + +bool Ob::addSignalImpl(SignalBase *sig, GenericMFPtr fptr, const char *name) +{ + ObPrivate::Signal s = {fptr,std::string(name),sig}; + d->sigv.push_back(s); +} + +SignalBase *Ob::findSignalImpl(const GenericMFPtr &fptr) +{ + for(int i=0; isigv.size(); ++i) + { + if(d->sigv[i].sigptr == fptr) + return d->sigv[i].signal; + } + return NULL; +} + + + + +} + +} + diff --git a/src/Core/testing/SignalMock/Ob.h b/src/Core/testing/SignalMock/Ob.h new file mode 100644 index 0000000..a9fb376 --- /dev/null +++ b/src/Core/testing/SignalMock/Ob.h @@ -0,0 +1,348 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + + +#ifndef OB_H +#define OB_H + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + + +#include + +#include "testing-prototype.h" + + + + + + +#include "Core/Vector.h" + +#include "boost/typeof/typeof.hpp" +#include + +#include +#include +#include +#include + + +#include +#include +#include + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// Mock of serializable object system // + +#define default(vlaue) +#define slots +#define signals public +#define emit +# define SLOT(a) a +# define SIGNAL(a) a + + + + + +namespace uLib { + +namespace SignalMock { + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// Function pointers // + + + +//////////////////////////////////////////////////////////////////////////////// +// type synthesize ( please read: boost implementation synthesize.hpp ) // +//////////////////////////////////////////////////////////////////////////////// +// TODO: change this to boost implementation // +// return a reference to function ... as the boost signal signature wants + +template +struct FunctionTypes {}; + +template +struct FunctionTypes< R(O::*)() > { + typedef R ref(); + typedef R (ptr)(); + typedef O obj; +}; + +template +struct FunctionTypes< R(O::*)(T0) > { + typedef R ref(T0); + typedef R (ptr)(T0); + typedef O obj; +}; + +template +struct FunctionTypes< R(O::*)(T0,T1) > { + typedef R ref(T0,T1); + typedef R (ptr)(T0,T1); + typedef O obj; +}; + +template +struct FunctionTypes< R(O::*)(T0,T1,T2) > { + typedef R ref(T0,T1,T2); + typedef R (ptr)(T0,T1,T2); + typedef O obj; +}; + + + + + + + +template +struct FunctionPointer { + typedef typename boost::function_types::function_type::type Signature; + typedef typename FunctionTypes::ref SignalSignature; + enum { + arity = boost::function_types::function_arity::value, + ismfp = boost::is_member_function_pointer::value + }; + + typedef boost::mpl::bool_< ismfp > HasObjectType; + typedef typename FunctionTypes::obj Object; + typedef boost::function_traits< Signature > Traits; + + virtual void PrintSelf( std::ostream &o ) { + o << "[fp: " << typeid(Signature).name() + << " arity: " << arity << "]\n"; } +}; + + + + +//////// generic function holder /////////////////////////////////////////////// + +class GenericMFPtr { + typedef void (GenericMFPtr::*_MFPtrStub_t)(); +public: + + typedef _MFPtrStub_t Type; + + GenericMFPtr() {} + + template + GenericMFPtr(T in) { + m_ptr = reinterpret_cast<_MFPtrStub_t>(in); + } + + template + inline bool operator == (T in) { + return m_ptr == reinterpret_cast<_MFPtrStub_t>(in); + } + + inline bool operator == (const GenericMFPtr &in) { + return m_ptr == in.m_ptr; + } + + Type operator()() { return m_ptr; } + + _MFPtrStub_t m_ptr; +private: +}; + + + + + + + +// A boost::signal wrapper structure /////////////////////////////////////////// + +// TODO ... + +typedef boost::signals2::signal_base SignalBase; + +template +struct Signal { + typedef boost::signals2::signal type; +}; + +template +SignalBase *NewSignal(FuncT f) { + // seems to work ! + return new Signal::type; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +template +struct ConnectSignal {}; + +template +struct ConnectSignal< FuncT, 0 > { + static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer::Object *receiver) { + typedef typename Signal::SignalSignature>::type SigT; + reinterpret_cast(sigb)->connect(slof); + } +}; + +template +struct ConnectSignal< FuncT, 1 > { + static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer::Object *receiver) { + typedef typename Signal::SignalSignature>::type SigT; + reinterpret_cast(sigb)->connect(boost::bind(slof,receiver)); + } +}; + +template +struct ConnectSignal< FuncT, 2 > { + static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer::Object *receiver) { + typedef typename Signal::SignalSignature>::type SigT; + reinterpret_cast(sigb)->connect(boost::bind(slof,receiver,_1)); + } +}; + +template +struct ConnectSignal< FuncT, 3 > { + static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer::Object *receiver) { + typedef typename Signal::SignalSignature>::type SigT; + reinterpret_cast(sigb)->connect(boost::bind(slof,receiver,_1,_2)); + } +}; + + + + + +//////////////////////////////////////////////////////////////////////////////// +//// OB /////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +class Ob { + +public: + + Ob(); + + // Qt4 style connector // + static bool connect(const Ob *ob1, const char *signal, const Ob *receiver, const char *slot) { + // 1) find slot pointer from name + // 2) find a way to do connection with no type + // TODO: finire + } + + // Qt5 style connector // + template + static bool connect( typename FunctionPointer::Object *sender, Func1 sigf, + typename FunctionPointer::Object *receiver, Func2 slof) + { + SignalBase *sigb = sender->findSignal(sigf); + typedef boost::signals2::signal::SignalSignature> SigT; + ConnectSignal::arity>::connect(sigb,slof,receiver); + } + + template + static inline bool connect(SignalBase *sigb, FuncT slof, Ob *receiver) { + ConnectSignal::arity>::connect(sigb,slof,receiver); + } + + + template< typename FuncT > + inline bool addSignal(FuncT fun, const char *name) { + SignalBase *sig = NewSignal(fun); + addSignalImpl(sig,fun,name); + } + + + template < typename FuncT > + inline SignalBase *findSignal(FuncT fptr) + { + return findSignalImpl(GenericMFPtr(fptr)); + } + + template < typename FuncT > + inline boost::signals2::signal< typename FunctionPointer::SignalSignature> *findSignal2(FuncT fptr) + { + return (boost::signals2::signal::SignalSignature> *)findSignalImpl(GenericMFPtr(fptr)); + } + + void PrintSelf(std::ostream &o) const; + +private: + + bool addSignalImpl(SignalBase *sig, GenericMFPtr fptr, const char *name); + + SignalBase *findSignalImpl(const GenericMFPtr &fptr); + + + friend class ObPrivate; + class ObPrivate *d; +}; + + + + + + + +} // SignalMock + +} + +//////////////////////////////////////////////////////////////////////////////// + + + + + + +#endif diff --git a/src/Core/testing/SignalMock/Ob1.cpp b/src/Core/testing/SignalMock/Ob1.cpp new file mode 100644 index 0000000..7a89c5f --- /dev/null +++ b/src/Core/testing/SignalMock/Ob1.cpp @@ -0,0 +1,55 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Ob1.h" + +namespace uLib { + +void SignalMock::Ob1::PrintHelloOb1() { + std::cout << "Hello Ob1!\n"; +} + + + + + + +// created by moc // -------------------------------------------------------- // + + + + + + +// -------------------------------------------------------------------------- // + + + +} + + diff --git a/src/Core/testing/SignalMock/Ob1.h b/src/Core/testing/SignalMock/Ob1.h new file mode 100644 index 0000000..5f50bad --- /dev/null +++ b/src/Core/testing/SignalMock/Ob1.h @@ -0,0 +1,68 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef SOB1_H +#define SOB1_H + +#include +#include "Ob.h" + + +//////////////////////////////////////////////////////////////////////////////// +// OB1 /////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace uLib { + +namespace SignalMock { + +class Ob1 : public Ob { +public: + + +signals: + void TestSignal(); + +public slots: + void PrintHelloOb1(); + + +}; + +// serialize accessors in macro // ------------------------------------------ // + + +// -------------------------------------------------------------------------- // + + +} + +} // namespace + + + +#endif diff --git a/src/Core/testing/SignalMock/Ob2.cpp b/src/Core/testing/SignalMock/Ob2.cpp new file mode 100644 index 0000000..b48bbb9 --- /dev/null +++ b/src/Core/testing/SignalMock/Ob2.cpp @@ -0,0 +1,44 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + + +#include "Ob2.h" + +namespace uLib { + + +// created by moc // -------------------------------------------------------- // + + + +// -------------------------------------------------------------------------- // + +} + + + diff --git a/src/Core/testing/SignalMock/Ob2.h b/src/Core/testing/SignalMock/Ob2.h new file mode 100644 index 0000000..7cc7b30 --- /dev/null +++ b/src/Core/testing/SignalMock/Ob2.h @@ -0,0 +1,57 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#ifndef SOB2_H +#define SOB2_H + + +#include "Ob.h" +#include "Ob1.h" + +//////////////////////////////////////////////////////////////////////////////// +// OB2 /////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace uLib { + +namespace SignalMock { + +class Ob2 : public Ob1 { +public: + typedef Ob1 BaseClass; + + +private: + +}; + +} + +} + +#endif diff --git a/src/Core/testing/SignalMock/main.cpp b/src/Core/testing/SignalMock/main.cpp new file mode 100644 index 0000000..c8133c2 --- /dev/null +++ b/src/Core/testing/SignalMock/main.cpp @@ -0,0 +1,180 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include + +#include + + +#include +#include +#include +#include + + +#include +#include +#include +#include + + +#include "Ob.h" +#include "Ob1.h" +#include "Ob2.h" + + + + +using namespace uLib; + +using namespace SignalMock;; + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// main // + + + + +class OBT1 : public Ob { +public: + +signals: + void Sig_v(); + + void Sig_v(int i); + + void Sig_v(int i, int j); + + int Sig_i(int i, int j); + + int SignalTest(int i,int j); + +public slots: + void Slot() { + std::cout << "slot v0 called\n"; + } + + void Slot(int i) { + std::cout << "slot v1i called with i=" << i << "\n"; + } + + void Slot(int i,int j) { + std::cout << "slot v2i called with i=" << i << " j=" << j << "\n"; + } + + int SlotAdd(int i,int j) { + std::cout << "slot i2i called with i=" << i << " j=" << j << "\n"; + return i+j; + } +}; + + + + +// Wrote by moc // +void OBT1::Sig_v() { + // SignalBase * sig = this->findSignal((void(OBT1::*)())&OBT1::Sig_v); + // typedef SignalMock::Signal::type SigT; + // if(sig) reinterpret_cast(sig)->operator()(); + BOOST_AUTO(sig, this->findSignal2((void(OBT1::*)())&OBT1::Sig_v)); + sig->operator()(); +} + +void OBT1::Sig_v(int i) { + SignalBase * sig = this->findSignal((void(OBT1::*)(int))&OBT1::Sig_v); + typedef SignalMock::Signal::type SigT; + if(sig) reinterpret_cast(sig)->operator()(i); +} + +void OBT1::Sig_v(int i, int j) { + SignalBase * sig = this->findSignal((void(OBT1::*)(int,int))&OBT1::Sig_v); + typedef SignalMock::Signal::type SigT; + if(sig) reinterpret_cast(sig)->operator()(i,j); +} + +int OBT1::Sig_i(int i, int j) +{ + SignalBase * sig = this->findSignal(&OBT1::Sig_i); + typedef SignalMock::Signal::type SigT; + if(sig) return *reinterpret_cast(sig)->operator()(i,j); + else return 0; +} + +int OBT1::SignalTest(int i, int j) +{ + SignalBase * sig = this->findSignal(&OBT1::SignalTest); + typedef SignalMock::Signal::type SigT; + if(sig) return *reinterpret_cast(sig)->operator()(i,j); + else return 0; +} + + + + + + + + + + + +int main() +{ + OBT1 o1,o2; + + o1.addSignal(&OBT1::SignalTest, "OBT1::SignalTest"); + o1.addSignal((void(OBT1::*)())&OBT1::Sig_v, "OBT1::Sig_v0"); + o1.addSignal((void(OBT1::*)(int))&OBT1::Sig_v, "OBT1::Sig_v1i"); + + Ob::connect(&o1,(void(OBT1::*)())&OBT1::Sig_v, + &o2,(void(OBT1::*)())&OBT1::Slot); + Ob::connect(&o1,(void(OBT1::*)(int))&OBT1::Sig_v, + &o2,(void(OBT1::*)(int))&OBT1::Slot); + Ob::connect(&o1,&OBT1::SignalTest,&o2,&OBT1::SlotAdd); + + + + o1.PrintSelf(std::cout); + + + // Qt style emit // + emit o1.Sig_v(); + emit o1.Sig_v(1); + emit o1.Sig_v(1,2); + std::cout << "return val2 = " << o1.SignalTest(3,4) << "\n"; + + + + return 0; +} + + + diff --git a/src/Core/testing/SignalMock/main2.cpp b/src/Core/testing/SignalMock/main2.cpp new file mode 100644 index 0000000..f75d0ab --- /dev/null +++ b/src/Core/testing/SignalMock/main2.cpp @@ -0,0 +1,169 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + + +#include "Ob.h" +#include "Ob1.h" +#include "Ob2.h" + + +using namespace uLib; + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// main // + + + + +class Test : public Ob{ +public: + +signals: + void PrintSng() { } + void PrintSng2(int i); + void PrintSng3(int i, char c); +}; + +// written by moc // +void Test::PrintSng2(int i) +{ + std::cout << "[Emit signal: PrintSgn2(" << i <<")]\n"; + typedef void(Test::* FPtr)(int); + FPtr fptr = &Test::PrintSng2; + typedef Signal::arity, typename FunctionTypes::Signature > SType; + SignalBase *s = this->findSignal(fptr); + static_cast(s)->m_signal(*this,i); +} + +// written by moc // +void Test::PrintSng3(int i,char c) +{ +} + + + + +class TestSlot: public Ob { +public: + TestSlot(const char *name) : m_name(name) {} + +public slots: + void PrintInt(int i) { + std::cout << "SLOT [" << m_name << "]>> TestSlot::PrintInt(" << i << ")\n"; + } + +private: + std::string m_name; +}; + + +void freeFunction0() {} + +void freeFunction1(int i) {} + +template +void printSignature(FuncT f){ + + typedef typename boost::function_types::function_type::type Signature; + typedef boost::mpl::if_< boost::mpl::bool_::value > , typename boost::function_traits< Signature >::arg1_type, void > Object; + + std::cout << "***Function Signature ***\n" + << " type_name : " << typeid(typename boost::function_types::function_type::type).name() << "\n" + // << " object type : " << typeid(typename boost::function_traits< typename boost::function_types::function_type::type >::arg1_type).name() << "\n" + << " object type : " << typeid(Object).name() << "\n" + << " is memfn : " << (boost::is_member_function_pointer::value == true) << "\n" + << " n aguments : " << boost::function_types::function_arity::value << "\n\n"; +} + + + + + + +int main() +{ + + Test t1; + TestSlot t2("slotOb1"),t3("slotOb2"); + + // in moc we add signals + t1.addSignal(&Test::PrintSng2,"Test::PrintSng2(int)"); + t1.addSignal(&Test::PrintSng3,"Test::PrintSng3(int,char)"); + + + SignalBase * signal = t1.findSignal(&Test::PrintSng2); + if(signal) + std::cout << "signal found" << "\n"; + + + + Ob::connect(&t1, &Test::PrintSng2, + &t2, &TestSlot::PrintInt); + Ob::connect(&t1, &Test::PrintSng2, + &t3, &TestSlot::PrintInt); + + emit t1.PrintSng2(5552368); + + // SignalBase *s = NewSignal(&Test::PrintSng2); + + +// printSignature(&freeFunction0); + printSignature(&freeFunction1); + printSignature(&Test::PrintSng2); + + + + + + + + + return 0; + +} + + + diff --git a/src/Core/testing/SignalMock/test1.cpp b/src/Core/testing/SignalMock/test1.cpp new file mode 100644 index 0000000..b49f560 --- /dev/null +++ b/src/Core/testing/SignalMock/test1.cpp @@ -0,0 +1,216 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include + +#include +#include +#include +#include + +#include + + + +#include "Ob.h" +#include "Ob1.h" +#include "Ob2.h" + + +using namespace uLib; + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// main // + +class SignalBase { +public: + virtual void call() = 0; +}; + +template +struct Signal : public boost::noncopyable, SignalBase +{ + typedef T PtrSignature; + virtual void call() {} +}; + +template +struct Signal : public boost::noncopyable, SignalBase +{ + typedef boost::function_traits< Ret() > SignatureTraits; + + typedef boost::signals2::signal SignalType; + typedef typename SignalType::slot_function_type SlotFunctionType; + typedef typename SignalType::result_type ResultType; + typedef boost::signals2::connection ConnectionType; + + Signal() : m_signal() {}; + virtual ~Signal() {}; + + void call() { m_signal(); } + + SignalType & signal() { return m_signal; } + +protected: + SignalType m_signal; +}; + + +template +struct Signal : public boost::noncopyable, SignalBase +{ + typedef boost::function_traits< Ret(Arg) > SignatureTraits; + + typedef boost::signals2::signal SignalType; + typedef typename SignalType::slot_function_type SlotFunctionType; + typedef typename SignalType::result_type ResultType; + typedef boost::signals2::connection ConnectionType; + + Signal() : m_signal() {}; + virtual ~Signal() {}; + + void call() { m_signal(0); } + + SignalType & signal() { return m_signal; } + +protected: + SignalType m_signal; +}; + + + +template < typename T > +static SignalBase * BuildSig(typename FunctionTypes::Object *obj, T f) { + Signal *s = new Signal; + typename FunctionTypes::Object::TS ts = { + static_cast(s), + reinterpret_cast(f) + }; + obj->v.push_back(ts); + return static_cast(s); +} + +template < typename T > +static SignalBase * FindSignal(typename FunctionTypes::Object *obj, T f) { + void *ptr = reinterpret_cast(f); + for (int i=0; iv.size(); ++i) + if(obj->v[i].ptr == ptr) return obj->v[i].sig; + return NULL; +} + +template < typename T1, typename T2 > +static bool Connect(typename FunctionTypes::Object *sender, T1 signal, + typename FunctionTypes::Object *receiver, T2 slot) +{ + SignalBase *s = FindSignal(sender,signal); + if(!s) return false; + static_cast< Signal * >(s)->signal().connect(boost::bind(slot,receiver)); + return true; +} + + + + +class Test : public Ob { +public: + + struct TS{ + SignalBase *sig; + void *ptr; + }; + + Vector v; + + + Test() { + BuildSig(this, &Test::TestSignal); + BuildSig(this, &Test::TestSignal1); +// BuildSig(this, &Test::TestSignal2); + } + +signals: + + void TestSignal(); + void TestSignal1(int); + void TestSignal2(int,int); + +public slots: + + void PrintHello() { std::cout << "Hello!\n"; } + +}; + + + +// moc it // +void Test::TestSignal(){ +// static SignalBase *signal = BuildSig(this, &Test::TestSignal); + static SignalBase *signal = FindSignal(this,&Test::TestSignal); + signal->call(); + // signal->call(); +} + +void Test::TestSignal1(int) +{ + static SignalBase *signal = FindSignal(this,&Test::TestSignal1); + signal->call(); +} + +void Test::TestSignal2(int,int) +{ +// static SignalBase *signal = FindSignal(this,&Test::TestSignal2); +// signal->call(); +} + + +int main() +{ + + //////////////////////////////////////////////////// + // signalling tests + + + Test test; + +// test.addSignal(&Test::TestSignal,"TestSignal()"); + +// Test::connect(&test,&Test::TestSignal,&test,&Test::PrintHello); + + + Connect(&test,&Test::TestSignal,&test,&Test::PrintHello); + + emit test.TestSignal(); + + return 0; +} + + diff --git a/src/Core/testing/SignalMock/testing-prototype.h b/src/Core/testing/SignalMock/testing-prototype.h new file mode 100644 index 0000000..39f4e6c --- /dev/null +++ b/src/Core/testing/SignalMock/testing-prototype.h @@ -0,0 +1,37 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include + +#define BEGIN_TESTING(name) \ +static int _fail = 0; \ +printf("..:: Testing " #name " ::..\n"); + +#define TEST1(val) _fail += (val)==0 +#define TEST0(val) _fail += (val)!=0 +#define END_TESTING return _fail; + diff --git a/src/Core/testing/SignalTest.cpp b/src/Core/testing/SignalTest.cpp new file mode 100644 index 0000000..491af54 --- /dev/null +++ b/src/Core/testing/SignalTest.cpp @@ -0,0 +1,115 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include +#include + + +#include "testing-prototype.h" +#include "Core/Types.h" +#include "Core/Object.h" +#include "Core/Signal.h" + + +using namespace uLib; + + + + +class Ob1 : public Object { +public: + + +signals: + void V0(); + + int V1(int a); + +}; + + + + +// should be done by moc // +void Ob1::V0() { + ULIB_SIGNAL_EMIT(Ob1::V0); +} + +int Ob1::V1(int a) { + ULIB_SIGNAL_EMIT(Ob1::V1,a); +} + + + + + +class Ob2 : public Object { + +public slots: + void PrintV0() { + std::cout << "Ob2 prints V0\n" << std::flush; + } +}; + +class Ob3 : public Object { + +public slots: + void PrintV0() { + std::cout << "Ob3 prints V0\n" << std::flush; + } + + void PrintNumber(int n) { + std::cout << "Ob3 is printing number: " << n << "\n"; + } +}; + + + + +int main() { + BEGIN_TESTING(Signals); + + Ob1 ob1; + Ob2 ob2; + Ob3 ob3; + + Object::connect(&ob1,&Ob1::V0,&ob2,&Ob2::PrintV0); + Object::connect(&ob1,&Ob1::V0,&ob3,&Ob3::PrintV0); + Object::connect(&ob1,&Ob1::V1,&ob3,&Ob3::PrintNumber); + + // not working yet + // Object::connect(&ob1,SIGNAL(V0(),&ob2,SLOT(PrintV0()) + + ob1.PrintSelf(std::cout); + + emit ob1.V0(); + emit ob1.V1(5552368); + + END_TESTING; +} + + diff --git a/src/Core/testing/SmartPointerTest.cpp b/src/Core/testing/SmartPointerTest.cpp new file mode 100644 index 0000000..5a2e129 --- /dev/null +++ b/src/Core/testing/SmartPointerTest.cpp @@ -0,0 +1,94 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include "Core/SmartPointer.h" +#include "testing-prototype.h" + +using namespace uLib; + +namespace Test { + +struct ObjectMockInterface { + virtual void PrintValue()=0; + virtual int& Value()=0; +}; + +class ObjectMock : ObjectMockInterface { + int value; +public: + int& Value() { return value; } + void PrintValue() { std::cout << "Value: " << value << "\n"; } + +}; +} // Test + + +bool test_smpt(SmartPointer &p) { + + SmartPointer spt = p; + spt->Value() = 5552368; + { + SmartPointer copy = spt; + copy->Value() = 123; + } + return (spt->Value() == 123); +} + + + + + +int main () { + BEGIN_TESTING(SmartPointer); + + // HOLD REFERENCE // + { + SmartPointer spt(new Test::ObjectMock); + TEST1(test_smpt(spt)); + } + { + SmartPointer spt; + TEST1(test_smpt(spt)); + } + { + SmartPointer spt = new SmartPointer; + TEST1(test_smpt(spt)); + } + + // TAKE REFERENCE // + { + Test::ObjectMock obj; + SmartPointer spt(obj); + TEST1(test_smpt(spt)); + } + + + + END_TESTING; +} diff --git a/src/Core/testing/SmartVectorTest.cpp b/src/Core/testing/SmartVectorTest.cpp new file mode 100644 index 0000000..13b6232 --- /dev/null +++ b/src/Core/testing/SmartVectorTest.cpp @@ -0,0 +1,120 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include + +#include "testing-prototype.h" +#include "Core/Vector.h" +#include "Core/Object.h" + +using namespace uLib; + +static int instanziated_objects_number; + +class ObjectTest : public Object { +public: + ObjectTest() { + data[0] = 0; + data[1] = 1; + data[2] = 2; + instanziated_objects_number++; + } + ObjectTest(const ObjectTest ©) { + data[0] = copy.data[0]; + data[1] = copy.data[1]; + data[2] = copy.data[2]; + instanziated_objects_number++; + } + + ~ObjectTest() + { + instanziated_objects_number--; + } + float data[3]; +}; + +int main() { + BEGIN_TESTING(SmartVector); + + instanziated_objects_number =0; + + + ///////////////////////// SMART POINTER FUNCIONALITY /////////////////////// + + // int smart vector // + SmartVector sv(10); + for (int i=0;i<10;++i) + sv[i] = i; + // new shallow copy inside a code block // + { + SmartVector newsv = sv; + newsv[5] = 5552368; + TEST1(sv[5] == newsv[5]); + } + // verify that newsv destruction does not delete instance // + TEST1( sv[5] == 5552368 ); + + SmartVector svo(10); + for (int i=0;i<10;++i) + svo[i] = ObjectTest(); + + TEST1(instanziated_objects_number == 10); + { + SmartVector newsvo = svo; + newsvo[5].data[1] = 5552368.0; + TEST1(svo[5].data[1] == newsvo[5].data[1]); + TEST1(instanziated_objects_number == 10); + } + TEST1(instanziated_objects_number == 10); + + + + /////////////////////////// ITERATOR FUNCIONALITY ////////////////////////// + + + Vector v(10); + Vector::Iterator it; + + int i=1; + for(it=v.begin() ; it==v.end(); it++, i++) + *it = i; + + for(i = 0; i::ConstIterator cit; + i=1; + for(cit=v.begin(); cit==v.end(); cit++, i++) + TEST1( *cit == i+1 ); + + + END_TESTING +} + + + + diff --git a/src/Core/testing/StaticInterfaceTest.cpp b/src/Core/testing/StaticInterfaceTest.cpp new file mode 100644 index 0000000..a618c44 --- /dev/null +++ b/src/Core/testing/StaticInterfaceTest.cpp @@ -0,0 +1,112 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include + +#include "testing-prototype.h" +#include + + + +namespace uLib { + +//// INTERFACE TO COMPLEX CLASS ///// + +namespace Interface { +struct Test { + MAKE_TRAITS + template void check_structural() { + uLibCheckFunction(Self,test,bool,int,float); + uLibCheckMember(Self,testmemb,int); + } +}; +} + +struct Test { + bool test(int i, float f){} + int testmemb; +}; + + + +//// INTERFAC TO SIMPLE CLASS /////////// + +namespace Interface { +struct Simple { + MAKE_TRAITS + template void check_structural() { + uLibCheckMember(Self,memb1,int); + uLibCheckMember(Self,memb2,float); + } +}; +} + +struct Simple { + int memb1; + float memb2; +}; + + +///////////////////////// + +template +class UseTest { +public: + UseTest() { + Interface::IsA(); + T t; + int i; float f; + t.test(i,f); + } +}; + +template +class UseSimple { +public: + UseSimple() { + Interface::IsA(); + } +}; + + + +} + +int main() +{ + BEGIN_TESTING(Static Interface); + + + + uLib::UseTest u; + + uLib::UseSimple s; + + END_TESTING; +} + diff --git a/src/Core/testing/TypeIntrospectionTraversal.cpp b/src/Core/testing/TypeIntrospectionTraversal.cpp new file mode 100644 index 0000000..c163939 --- /dev/null +++ b/src/Core/testing/TypeIntrospectionTraversal.cpp @@ -0,0 +1,52 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include +#include +#include +#include + + +#include "Core/Types.h" +#include "Core/Object.h" + + +#include "testing-prototype.h" + +using namespace uLib; + + + + + + + +int main() { + + + +} diff --git a/src/Core/testing/UuidTest.cpp b/src/Core/testing/UuidTest.cpp new file mode 100644 index 0000000..1445df3 --- /dev/null +++ b/src/Core/testing/UuidTest.cpp @@ -0,0 +1,45 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include + +#include "Core/Object.h" +#include "Core/Uuid.h" + +#include "testing-prototype.h" + + +using namespace uLib; + +int main() +{ + BEGIN_TESTING(uuid); + + + + END_TESTING; +} diff --git a/src/Core/testing/VectorTest.cpp b/src/Core/testing/VectorTest.cpp new file mode 100644 index 0000000..6fee192 --- /dev/null +++ b/src/Core/testing/VectorTest.cpp @@ -0,0 +1,84 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include +#include "testing-prototype.h" + +#include + +template < typename T > +struct __Cmp { + bool operator()(const T &data, const float value) { + return data <= value; + } +}; + + + + +template +inline const unsigned long +VectorSplice(const _Tp &_it, const _Tp &_end, const float value, _CmpT _comp) + { + + _Tp it = _it; + _Tp end = _end-1; + for(it; it != end; ) + { + if ( _comp(*it, value) ) it++; + else if( _comp(*end, value) ) + { + std::swap(*it,*end--); + } + else --end; + } + return it - _it; +} + + +int main() +{ + BEGIN_TESTING(Vector); + + uLib::Vector v; + v << 5,4,3,2,6,1,2,3,65,7,32,23,4,3,45,4,34,3,4,4,3,3,4,2,2,3; + + + + int id = VectorSplice(v.begin(),v.end(),3,__Cmp()); + + std::cout << "id: " << id << "\n"; + std::cout << "vector: "; + for(uLib::Vector::Iterator it = v.begin(); it!=v.end(); it++) + std::cout << *it <<" "; + std::cout << std::endl; +// std::sort(v.begin(),v.end(),LT()); + + + END_TESTING; +} + diff --git a/src/Core/testing/testing-prototype.h b/src/Core/testing/testing-prototype.h new file mode 100644 index 0000000..39f4e6c --- /dev/null +++ b/src/Core/testing/testing-prototype.h @@ -0,0 +1,37 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include + +#define BEGIN_TESTING(name) \ +static int _fail = 0; \ +printf("..:: Testing " #name " ::..\n"); + +#define TEST1(val) _fail += (val)==0 +#define TEST0(val) _fail += (val)!=0 +#define END_TESTING return _fail; + diff --git a/src/Detectors/CMakeLists.txt b/src/Detectors/CMakeLists.txt new file mode 100644 index 0000000..3820ba9 --- /dev/null +++ b/src/Detectors/CMakeLists.txt @@ -0,0 +1,38 @@ +# HEADERS +set(HEADERS + DetectorChamber.h + ExperimentFitEvent.h + GeantEvent.h + HitMC.h + MuonScatter.h + MuonEvent.h + MuonError.h + ChamberHitEvent.h + Hit.h + LinearFit.h + Solid.h + Matter.h + Scene.h +) + + +# SOURCES +set(SOURCES + Solid.cpp + Scene.cpp +) + +set(LIBRARIES + ${Boost_SERIALIZATION_LIBRARY} + ${Boost_SIGNALS_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Eigen_LIBRARY} + ${Geant4_LIBRARIES} + ${ROOT_LIBRARIES} + ${PACKAGE_LIBPREFIX}Core + ${PACKAGE_LIBPREFIX}Math + ${PACKAGE_LIBPREFIX}Detectors +) + +uLib_add_shared_library(${uLib-module}) +add_subdirectory(testing) diff --git a/src/Detectors/ChamberHitEvent.h b/src/Detectors/ChamberHitEvent.h new file mode 100644 index 0000000..7fbe98e --- /dev/null +++ b/src/Detectors/ChamberHitEvent.h @@ -0,0 +1,56 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CHAMBERHITEVENT_H +#define U_CHAMBERHITEVENT_H + +#include "Core/Vector.h" +#include "Hit.h" +#include "ChamberDetector.h" + +namespace uLib { + +class ChamberHitEventData +{ +public: + uLibConstRefMacro (Hits, Vector ) + uLibGetMacro (Idv, ChamberDetector::ID) +private: + friend class ChamberHitEvent; + Vector m_Hits; + DetectorChamber::ID m_Idv; // -> chamber/view +}; + +class ChamberHitEvent : public ChamberHitEventData { +public: + uLibRefMacro (Hits, Vector ) + uLibSetMacro (Idv, ChamberDetector::ID) +}; + +} + +#endif // CHAMBERHITEVENT_H diff --git a/src/Detectors/DetectorChamber.h b/src/Detectors/DetectorChamber.h new file mode 100644 index 0000000..a5ed09f --- /dev/null +++ b/src/Detectors/DetectorChamber.h @@ -0,0 +1,48 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CHAMBERDETECTOR_H +#define U_CHAMBERDETECTOR_H + +#include "Core/Types.h" +#include "Math/ContainerBox.h" + +namespace uLib { + + +class DetectorChamber : public ContainerBox { + +public: + +private: +}; + + +} + + +#endif // CHAMBERDETECTOR_H diff --git a/src/Detectors/ExperimentFitEvent.h b/src/Detectors/ExperimentFitEvent.h new file mode 100644 index 0000000..8a08427 --- /dev/null +++ b/src/Detectors/ExperimentFitEvent.h @@ -0,0 +1,48 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_EXPERIMENTFITEVENT_H +#define U_EXPERIMENTFITEVENT_H + +namespace uLib { + + +class ExperimentFitEventData { +public: + +private: + +}; + + + + + +} + + +#endif // EXPERIMENTFITEVENT_H diff --git a/src/Detectors/GeantEvent.h b/src/Detectors/GeantEvent.h new file mode 100644 index 0000000..33d26aa --- /dev/null +++ b/src/Detectors/GeantEvent.h @@ -0,0 +1,69 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_GEANTEVENT_H +#define U_GEANTEVENT_H + +#include "Core/Types.h" +#include "Core/Vector.h" +#include "Math/Dense.h" + +#include "ChamberHitEvent.h" + +namespace uLib { + +class GeantEventData { +public: + uLibGetMacro (EventID, Id_t ) + uLibGetMacro (Momentum,Scalarf ) + uLibConstRefMacro (GenPos, Vector3f) + uLibConstRefMacro (GenDir, Vector3f) + uLibConstRefMacro (ChEvents,Vector) + +private: + friend class GeantEvent; + Id_t m_EventID; + Scalarf m_Momentum; + Vector3f m_GenPos; + Vector3f m_GenDir; + Vector m_ChEvents; +}; + +class GeantEvent { +public: + uLibSetMacro (EventID, Id_t ) + uLibSetMacro (Momentum,Scalarf ) + uLibRefMacro (GenPos, Vector3f) + uLibRefMacro (GenDir, Vector3f) + uLibRefMacro (ChEvents,Vector) +}; + + +} + + +#endif // GEANTEVENT_H diff --git a/src/Detectors/HierarchicalEncoding.h b/src/Detectors/HierarchicalEncoding.h new file mode 100644 index 0000000..16abffb --- /dev/null +++ b/src/Detectors/HierarchicalEncoding.h @@ -0,0 +1,41 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + +#ifndef U_DETECTORS_HIERARCHICALENCODING_H +#define U_DETECTORS_HIERARCHICALENCODING_H + +#include + +namespace uLib { + + + +} // uLib + + + + + +#endif // HIERARCHICALENCODING_H diff --git a/src/Detectors/Hit.h b/src/Detectors/Hit.h new file mode 100644 index 0000000..1261417 --- /dev/null +++ b/src/Detectors/Hit.h @@ -0,0 +1,70 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef HIT_H +#define HIT_H + +#include "Math/BitCode.h" + +namespace uLib { + + + + + +class HitRawCode_CMSDrift : + public BitCode4 +{ + typedef unsigned short T; +public: + HitRawCode_CMSDrift() : BitCode4(0) {} + HitRawCode_CMSDrift(const Vector4i &v) : BitCode4(v) {} + HitRawCode_CMSDrift(T Chamber, T ROB, T TDC, T Channel ) { + (*this) << Chamber, ROB, TDC, Channel; + } + + inline T Chamber() const { return m_data.bitf.field1; } + inline void SetChamber(const T data) { m_data.bitf.field1 = data; } + inline T ROB() const { return m_data.bitf.field2; } + inline void SetROB(const T data) { m_data.bitf.field2 = data; } + inline T TDC() const { return m_data.bitf.field3; } + inline void SetTDC(const T data) { m_data.bitf.field3 = data; } + inline T Channel() const { return m_data.bitf.field4; } + inline void SetChannel(const T data) { m_data.bitf.field4 = data; } + +}; + + + + + + + + + +} +#endif // HIT_H diff --git a/src/Detectors/HitMC.h b/src/Detectors/HitMC.h new file mode 100644 index 0000000..95404b2 --- /dev/null +++ b/src/Detectors/HitMC.h @@ -0,0 +1,67 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_HITMC_H +#define U_HITMC_H + +#include "Core/Macros.h" +#include "Math/Dense.h" +#include "Hit.h" + +namespace uLib { + + +class HitMCData : public HitData{ +public: + enum Type { + PrimaryMu, + SecondaryMu, + DeltaRay + }; + + uLibConstRefMacro(Position,HPoint3f) + uLibGetMacro(Type, enum Type) + +private: + HPoint3f m_Position; + enum Type m_Type; +}; + + +class HitMC : public HitMCData { +public: + uLibRefMacro(Position,HPoint3f) + uLibSetMacro(Type, enum Type) +}; + + + +} + + + +#endif // HITMC_H diff --git a/src/Detectors/LinearFit.h b/src/Detectors/LinearFit.h new file mode 100644 index 0000000..9419e69 --- /dev/null +++ b/src/Detectors/LinearFit.h @@ -0,0 +1,73 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_LINEARFIT_H +#define U_LINEARFIT_H + +#include "Core/Macros.h" +#include "Math/Dense.h" +#include "ChamberDetector.h" + + +namespace uLib { + +class LinearFitData { +public: + uLibConstRefMacro(Position,Vector2f) + uLibConstRefMacro(Slope,Vector2f) + uLibConstRefMacro(PositionError,Vector2f) + uLibConstRefMacro(SlopeError,Vector2f) + uLibGetMacro(HitsNumber,int) + uLibGetMacro(Idv,ChamberDetector::ID) + +private: + friend class LinearFit; + Vector2f m_Position; + Vector2f m_Slope; + Vector2f m_PositionError; + Vector2f m_SlopeError; + int m_HitsNumber; + DetectorChamber::ID m_Idv; +}; + + +class LinearFit : public LinearFitData { +public: + uLibRefMacro(Position,Vector2f) + uLibRefMacro(Slope,Vector2f) + uLibRefMacro(PositionError,Vector2f) + uLibRefMacro(SlopeError,Vector2f) + uLibSetMacro(HitsNumber,int) + uLibSetMacro(Idv,ChamberDetector::ID) +}; + + + +} + + +#endif // LINEARFIT_H diff --git a/src/Detectors/Makefile.am b/src/Detectors/Makefile.am new file mode 100644 index 0000000..b420a03 --- /dev/null +++ b/src/Detectors/Makefile.am @@ -0,0 +1,25 @@ +include $(top_srcdir)/Common.am + +library_includedir = $(includedir)/libmutom-${PACKAGE_VERSION}/Detectors +library_include_HEADERS = DetectorChamber.h \ + ExperimentFitEvent.h \ + GeantEvent.h \ + HitMC.h \ + MuonScatter.h \ + MuonEvent.h \ + MuonError.h \ + ChamberHitEvent.h \ + Hit.h \ + LinearFit.h \ + Solid.h \ + Matter.h \ + Scene.h + +_DETECTORS_SOURCES = \ + Solid.cpp \ + Scene.cpp + +noinst_LTLIBRARIES = libmutomdetectors.la +libmutomdetectors_la_SOURCES = ${_DETECTORS_SOURCES} + + diff --git a/src/Detectors/Matter.h b/src/Detectors/Matter.h new file mode 100644 index 0000000..04815c0 --- /dev/null +++ b/src/Detectors/Matter.h @@ -0,0 +1,71 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef MATTER_H +#define MATTER_H + +#include "Core/Object.h" + +class G4Element; +class G4Material; + +namespace uLib { + + +//////////////////////////////////////////////////////////////////////////////// +//// ELEMENT /////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +class Element { +public: + + uLibRefMacro(G4Data,G4Element *) +private: + G4Element *m_G4Data; +}; + + + +//////////////////////////////////////////////////////////////////////////////// +//// MATERIAL ////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +class Material : public Object { +public: + + uLibRefMacro(G4Data,G4Material *) +private: + G4Material *m_G4Data; +}; + + + +} + + +#endif // MATTER_H diff --git a/src/Detectors/MuonError.h b/src/Detectors/MuonError.h new file mode 100644 index 0000000..47aa570 --- /dev/null +++ b/src/Detectors/MuonError.h @@ -0,0 +1,58 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_MUONERROR_H +#define U_MUONERROR_H + +#include "Core/Macros.h" +#include "Math/Dense.h" + +namespace uLib { + + +class MuonErrorData { + friend class MuonError; +public: + uLibConstRefMacro(Theta,Scalarf) + uLibConstRefMacro(Phi,Scalarf) +private: + Scalarf m_Theta; + Scalarf m_Phi; +}; + + +class MuonError : public MuonErrorData { +public: + uLibRefMacro(Theta,Scalarf) + uLibRefMacro(Phi,Scalarf) +}; + + +} // end ulib space + + +#endif // U_MUONERROR_H diff --git a/src/Detectors/MuonEvent.h b/src/Detectors/MuonEvent.h new file mode 100644 index 0000000..72e5c9b --- /dev/null +++ b/src/Detectors/MuonEvent.h @@ -0,0 +1,75 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_MUONEVENT_H +#define U_MUONEVENT_H + +#include "Core/Macros.h" +#include "Math/Dense.h" + +namespace uLib { + + +class MuonEventData { + friend class MuonEvent; +public: + uLibConstRefMacro(LineIn,HLine3f) + uLibConstRefMacro(LineOut,HLine3f) + uLibGetMacro(Momentum,Scalarf) + +private: + HLine3f m_LineIn; + HLine3f m_LineOut; + Scalarf m_Momentum; +}; + + +class MuonEvent : public MuonEventData { +public: + uLibRefMacro(LineIn,HLine3f) + uLibRefMacro(LineOut,HLine3f) + uLibRefMacro(Momentum,Scalarf) + +}; + +inline std::ostream& +operator<< (std::ostream& stream, const MuonEventData &mu) { + stream << " MuonEventData: --------------- \n" + << " P: " << mu.GetMomentum() << "\n" + << " IN: " << mu.LineIn() << "\n" + << " OUT: " << mu.LineOut() << "\n" + << " ------------------------------ \n"; + return stream; +} + + + +} // end ulib space + + + +#endif // U_MUONEVENT_H diff --git a/src/Detectors/MuonScatter.h b/src/Detectors/MuonScatter.h new file mode 100644 index 0000000..a370f17 --- /dev/null +++ b/src/Detectors/MuonScatter.h @@ -0,0 +1,81 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#ifndef U_MUONSCATTER_H +#define U_MUONSCATTER_H + +#include "Core/Macros.h" +#include "Math/Dense.h" +#include "Math/Line.h" + +namespace uLib { + + +class MuonScatter { +public: + uLibConstRefMacro(LineIn,Line4f) + uLibConstRefMacro(ErrorIn,Line4f) + uLibConstRefMacro(LineOut,Line4f) + uLibConstRefMacro(ErrorOut,Line4f) + + uLibRefMacro(LineIn,Line4f) + uLibRefMacro(ErrorIn,Line4f) + uLibRefMacro(LineOut,Line4f) + uLibRefMacro(ErrorOut,Line4f) + uLibSetMacro(Momentum,Scalarf) + uLibSetMacro(MomentumPrime,Scalarf) + + uLibGetMacro(Momentum,Scalarf) + uLibGetMacro(MomentumPrime,Scalarf) + +protected: + Line4f m_LineIn; + Line4f m_LineOut; + Line4f m_ErrorIn; + Line4f m_ErrorOut; + Scalarf m_Momentum; + Scalarf m_MomentumPrime; +}; + +typedef MuonScatter MuonScatterData; + +inline std::ostream& +operator<< (std::ostream& stream, const MuonScatterData &mu) { + stream << " MuonScatterData: ------------- \n" +// << " P: " << mu.GetMomentum() << " Pprim: " << mu.GetMomentumPrime() << "\n" +// << " IN: " << mu.LineIn() << "\n" +// << " " << mu.ErrorIn() << "\n" +// << " OUT: " << mu.LineOut() << "\n" +// << " " << mu.ErrorOut() <<"\n" + << " ------------------------------ \n"; + return stream; +} + +} + +#endif // U_MUONSCATTER_H diff --git a/src/Detectors/Scene.cpp b/src/Detectors/Scene.cpp new file mode 100644 index 0000000..2439b50 --- /dev/null +++ b/src/Detectors/Scene.cpp @@ -0,0 +1,75 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + + +#include +#include +#include +#include + +#include "Core/Vector.h" +#include "Matter.h" +#include "Solid.h" + +#include "Scene.h" + + +namespace uLib { + + +class DetectorsScenePimpl { + +public: + + + // members // + //Vector m_Solids; +}; + + + + +DetectorsScene::DetectorsScene() : + d(new DetectorsScenePimpl()) +{} + +DetectorsScene::~DetectorsScene() +{ + delete d; +} + +void DetectorsScene::AddSolid(const Solid &solid) +{ +// d->m_Solids.push_back(solid); +} + + + + + +} diff --git a/src/Detectors/Scene.h b/src/Detectors/Scene.h new file mode 100644 index 0000000..e7c7edb --- /dev/null +++ b/src/Detectors/Scene.h @@ -0,0 +1,52 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef SCENE_H +#define SCENE_H + +#include "Core/Object.h" +#include "Core/Vector.h" +#include "Solid.h" + +namespace uLib { + + +class DetectorsScene : public Object { +public: + DetectorsScene(); + ~DetectorsScene(); + + + void AddSolid(const Solid &solid); + +private: + class DetectorsScenePimpl *d; +}; + + +} +#endif // SCENE_H diff --git a/src/Detectors/Solid.cpp b/src/Detectors/Solid.cpp new file mode 100644 index 0000000..46597b2 --- /dev/null +++ b/src/Detectors/Solid.cpp @@ -0,0 +1,114 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +// G4 Solid // +#include +#include +#include + +// Tessellated solid // +#include +#include +#include + + +#include "Math/Dense.h" + +#include "Solid.h" + +namespace uLib { + +class DetectorsSolidPimpl { +public: + static G4ThreeVector getG4Vector3f(const Vector3f &vector) { + return G4ThreeVector( vector(0), vector(1), vector(2) ); + } +}; + + + +Solid::Solid() : + m_Logical (new G4LogicalVolume(NULL,NULL,"unnamed_solid")), + m_Material(NULL) +{} + +Solid::Solid(const char *name) : + m_Logical(new G4LogicalVolume(NULL,NULL,name)), + m_Material(NULL) +{} + + + +void Solid::SetNistMaterial(const char *name) +{ + G4NistManager *nist = G4NistManager::Instance(); + if (m_Material) delete m_Material; + m_Material = nist->FindOrBuildMaterial(name); + m_Logical->SetMaterial(m_Material); +} + +void Solid::SetMaterial(G4Material *material) +{ + if(material) + { + m_Material = material; + m_Logical->SetMaterial(material); + } +} + + + + + + + + + + +TessellatedSolid::TessellatedSolid(const char *name) : + BaseClass(name), + m_Solid(new G4TessellatedSolid(name)) +{} + + +void TessellatedSolid::SetMesh(TriangleMesh &mesh) +{ + G4TessellatedSolid *ts = this->m_Solid; + for (int i=0; iAddFacet((G4VFacet *)facet); + } + this->m_Logical->SetSolid(ts); +} + + +} diff --git a/src/Detectors/Solid.h b/src/Detectors/Solid.h new file mode 100644 index 0000000..7babd27 --- /dev/null +++ b/src/Detectors/Solid.h @@ -0,0 +1,86 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef SOLID_H +#define SOLID_H + +#include "Core/Object.h" +#include "Math/Dense.h" +#include "Math/TriangleMesh.h" +#include "Detectors/Matter.h" + +class G4Material; +class G4LogicalVolume; +class G4TessellatedSolid; + + +namespace uLib { + +class Solid : public Object { +public: + + Solid(); + Solid(const char *name); + + void SetNistMaterial(const char *name); + + void SetMaterial(G4Material *material); + + uLibGetMacro(Material,G4Material *) + uLibGetMacro(Logical,G4LogicalVolume *) + +protected: + G4Material *m_Material; + G4LogicalVolume *m_Logical; +}; + + + + + +class TessellatedSolid : public Solid { + typedef Solid BaseClass; + +public: + TessellatedSolid(const char *name); + + void SetMesh(TriangleMesh &mesh); + + uLibGetMacro(Solid,G4TessellatedSolid *) +private: + G4TessellatedSolid *m_Solid; +}; + + + + +} + + + + +#endif // SOLID_H diff --git a/src/Detectors/testing/CMakeLists.txt b/src/Detectors/testing/CMakeLists.txt new file mode 100644 index 0000000..d3bff8f --- /dev/null +++ b/src/Detectors/testing/CMakeLists.txt @@ -0,0 +1,18 @@ +# TESTS +set( TESTS + GDMLSolidTest + HierarchicalEncodingTest +) + +#set(LIBRARIES +# ${PACKAGE_LIBPREFIX}Core +# ${PACKAGE_LIBPREFIX}Math +# ${PACKAGE_LIBPREFIX}Detectors +# ${Boost_SERIALIZATION_LIBRARY} +# ${Boost_SIGNALS_LIBRARY} +# ${Boost_PROGRAM_OPTIONS_LIBRARY} +# ${Eigen_LIBRARY} +# ${Geant4_LIBRARIES} +# ${ROOT_LIBRARIES} +#) +uLib_add_tests(${uLib-module}) diff --git a/src/Detectors/testing/GDMLSolidTest.cpp b/src/Detectors/testing/GDMLSolidTest.cpp new file mode 100644 index 0000000..3c8843f --- /dev/null +++ b/src/Detectors/testing/GDMLSolidTest.cpp @@ -0,0 +1,72 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include + +#include +#include + +#include +#include +#include +#include + +#include +//#include +//#include + + +#include "Detectors/Solid.h" +#include "testing-prototype.h" + + + + +int main() +{ + +// G4RunManager* runManager = new G4RunManager; + + G4NistManager *nist = G4NistManager::Instance(); + G4Material *air = nist->FindOrBuildMaterial("G4_AIR"); + + + + G4Box *box = new G4Box("box",5,5,5); + + G4LogicalVolume box_lv(NULL,NULL,"box test"); + box_lv.SetSolid(box); + box_lv.SetMaterial(air); + G4PVPlacement box_pl(0,G4ThreeVector(),&box_lv,"box test",0,0,0); + + G4GDMLParser parser; + + parser.Write("test_out.gdml",&box_lv); + + +} diff --git a/src/Detectors/testing/HierarchicalEncodingTest.cpp b/src/Detectors/testing/HierarchicalEncodingTest.cpp new file mode 100644 index 0000000..b02d6da --- /dev/null +++ b/src/Detectors/testing/HierarchicalEncodingTest.cpp @@ -0,0 +1,50 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + +#include +#include + +#include "testing-prototype.h" + +using namespace uLib; + +int main() { + BEGIN_TESTING(Hierarchical Encoding); + + + HitRawCode_CMSDrift code; + code = Vector4i(5,6,2,8); + + + + Vector4i v = code; + + + std::cout << code << "\n"; + std::cout << v << "\n"; + + END_TESTING; +} + diff --git a/src/Detectors/testing/Makefile.am b/src/Detectors/testing/Makefile.am new file mode 100644 index 0000000..cd956fc --- /dev/null +++ b/src/Detectors/testing/Makefile.am @@ -0,0 +1,16 @@ + +include $(top_srcdir)/Common.am + +#AM_DEFAULT_SOURCE_EXT = .cpp + +# if HAVE_CHECK +TESTS = GDMLSolidTest + +# else +# TEST = +# endif + +LDADD = $(top_srcdir)/libmutom-${PACKAGE_VERSION}.la + +check_PROGRAMS = $(TESTS) + diff --git a/src/Detectors/testing/testing-prototype.h b/src/Detectors/testing/testing-prototype.h new file mode 100644 index 0000000..39f4e6c --- /dev/null +++ b/src/Detectors/testing/testing-prototype.h @@ -0,0 +1,37 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include + +#define BEGIN_TESTING(name) \ +static int _fail = 0; \ +printf("..:: Testing " #name " ::..\n"); + +#define TEST1(val) _fail += (val)==0 +#define TEST0(val) _fail += (val)!=0 +#define END_TESTING return _fail; + diff --git a/src/Gui/Qt/QVTKViewport2/Makefile.am b/src/Gui/Qt/QVTKViewport2/Makefile.am new file mode 100644 index 0000000..c6e1b8c --- /dev/null +++ b/src/Gui/Qt/QVTKViewport2/Makefile.am @@ -0,0 +1,35 @@ +# SUBDIRS = . + +include $(top_srcdir)/Common.am + +DISTSOURCES = vtkviewport.cpp main.cpp +DISTHEADERS_MOC = +DISTHEADERS_NO_MOC = +FORMS = vtkviewport.ui + +FORMHEADERS = $(FORMS:.ui=.h) +MOC_CC = $(FORMS:.ui=.moc.cpp) $(DISTHEADERS_MOC:.h=.moc.cpp) + +bin_PROGRAMS = QTVtkViewport + +BUILT_SOURCES = $(FORMHEADERS) $(MOC_CC) +CLEANFILES = $(BUILT_SOURCES) + +EXTRA_DIST = $(FORMS) +QTVtkViewport_SOURCES = $(DISTSOURCES) $(DISTHEADERS_MOC) $(DISTHEADERS_NO_MOC) +nodist_QTVtkViewport_SOURCES = $(MOC_CC) + +QTVtkViewport_LDADD = $(top_srcdir)/libmutom.la + + +.ui.h: $(FORMS) + $(UIC) -o ui_$@ $< + +.ui.hpp: $(FORMS_HPP) + $(UIC) -o $@ $< + +.h.moc.cpp: + $(MOC) -o $@ $< + + +SUFFIXES = .h .ui .moc.cpp diff --git a/src/Gui/Qt/QVTKViewport2/QVTKViewport2.pro b/src/Gui/Qt/QVTKViewport2/QVTKViewport2.pro new file mode 100644 index 0000000..6a3a510 --- /dev/null +++ b/src/Gui/Qt/QVTKViewport2/QVTKViewport2.pro @@ -0,0 +1,18 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2012-08-30T18:59:53 +# +#------------------------------------------------- + +QT += core gui + +TARGET = QVTKViewport2 +TEMPLATE = app + + +SOURCES += main.cpp\ + vtkviewport.cpp + +HEADERS += vtkviewport.h + +FORMS += vtkviewport.ui diff --git a/src/Gui/Qt/QVTKViewport2/QVTKViewport2.pro.user b/src/Gui/Qt/QVTKViewport2/QVTKViewport2.pro.user new file mode 100644 index 0000000..419ba5a --- /dev/null +++ b/src/Gui/Qt/QVTKViewport2/QVTKViewport2.pro.user @@ -0,0 +1,453 @@ + + + + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + System + false + 4 + true + 1 + true + 0 + true + 1 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Qt4ProjectManager.Target.DesktopTarget + 0 + 0 + 0 + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Desktop Qt 4.7.4 for GCC (Qt SDK) Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /home/andrea/devel/MuonTomography/mutom/uLib/trunk/src/Gui/Qt/QVTKViewport2 + 3 + false + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Desktop Qt 4.7.4 for GCC (Qt SDK) Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /home/andrea/devel/MuonTomography/mutom/uLib/trunk/src/Gui/Qt/QVTKViewport2 + 3 + false + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Qt 4.7.0 in PATH (System) Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /home/andrea/devel/MuonTomography/mutom/uLib/trunk/src/Gui/Qt/QVTKViewport2 + 4 + false + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Qt 4.7.0 in PATH (System) Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /home/andrea/devel/MuonTomography/mutom/uLib/trunk/src/Gui/Qt/QVTKViewport2 + 4 + false + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Qt 4.7.0 (System) Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /home/andrea/devel/MuonTomography/mutom/uLib/trunk/src/Gui/Qt/QVTKViewport2 + 5 + false + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Qt 4.7.0 (System) Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /home/andrea/devel/MuonTomography/mutom/uLib/trunk/src/Gui/Qt/QVTKViewport2 + 5 + false + + 6 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + No deployment + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + false + false + 25 + 25 + + + true + true + valgrind + valgrind + + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + + + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + + QVTKViewport2 + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + QVTKViewport2.pro + false + false + + + 3768 + true + false + false + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.EnvironmentId + {f8bb0047-7f6e-45df-9cc8-e746abebf883} + + + ProjectExplorer.Project.Updater.FileVersion + 10 + + diff --git a/src/Gui/Qt/QVTKViewport2/main.cpp b/src/Gui/Qt/QVTKViewport2/main.cpp new file mode 100644 index 0000000..aabcdd9 --- /dev/null +++ b/src/Gui/Qt/QVTKViewport2/main.cpp @@ -0,0 +1,38 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include +#include "vtkviewport.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + VtkViewport w; + w.show(); + + return a.exec(); +} diff --git a/src/Gui/Qt/QVTKViewport2/vtkviewport.cpp b/src/Gui/Qt/QVTKViewport2/vtkviewport.cpp new file mode 100644 index 0000000..77629da --- /dev/null +++ b/src/Gui/Qt/QVTKViewport2/vtkviewport.cpp @@ -0,0 +1,41 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "vtkviewport.h" +#include "ui_vtkviewport.h" + +VtkViewport::VtkViewport(QWidget *parent) : + QWidget(parent), + ui(new Ui::VtkViewport) +{ + ui->setupUi(this); +} + +VtkViewport::~VtkViewport() +{ + delete ui; +} diff --git a/src/Gui/Qt/QVTKViewport2/vtkviewport.h b/src/Gui/Qt/QVTKViewport2/vtkviewport.h new file mode 100644 index 0000000..09c2d7d --- /dev/null +++ b/src/Gui/Qt/QVTKViewport2/vtkviewport.h @@ -0,0 +1,49 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VTKVIEWPORT_H +#define VTKVIEWPORT_H + +#include + +namespace Ui { +class VtkViewport; +} + +class VtkViewport : public QWidget +{ + Q_OBJECT + +public: + explicit VtkViewport(QWidget *parent = 0); + ~VtkViewport(); + +private: + Ui::VtkViewport *ui; +}; + +#endif // VTKVIEWPORT_H diff --git a/src/Gui/Qt/QVTKViewport2/vtkviewport.ui b/src/Gui/Qt/QVTKViewport2/vtkviewport.ui new file mode 100644 index 0000000..095019b --- /dev/null +++ b/src/Gui/Qt/QVTKViewport2/vtkviewport.ui @@ -0,0 +1,32 @@ + + + VtkViewport + + + + 0 + 0 + 580 + 536 + + + + Form + + + + + 140 + 170 + 161 + 41 + + + + Hello World ! + + + + + + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..4709f04 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = ltk Core Math Detectors Root + + diff --git a/src/Math/Accumulator.h b/src/Math/Accumulator.h new file mode 100644 index 0000000..ca711ba --- /dev/null +++ b/src/Math/Accumulator.h @@ -0,0 +1,334 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_DATABINNING_H +#define U_DATABINNING_H + +#include "Core/Vector.h" +#include "Dense.h" + + +namespace uLib { + + + +// TODO: USE BOOST ACCUMULATORS // + + +template +class Accumulator_Mean { + typedef std::pair Tmean; +public: + Accumulator_Mean() { + m_Means.push_back( Tmean(0,0) ); + } + + void operator()(const T data) { + T tmp = 0; + // for(typename std::vector::iterator it = m_Means.begin(); it < m_Means.back(); ++it) + // tmp += it->first/it->second; + for(int i=0; i::iterator it = m_Means.begin(); it < m_Means.end(); ++it) { + // mean += it->first/it->second; } + for(int i=0; i m_Means; +}; + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// accumulator Trim // + +template < typename T, int subsample_size=200 > +class Accumulator_ABTrim { + +public: + Accumulator_ABTrim() : + m_Avg(0), + m_InternalCount(0), + m_SizeA(0), + m_SizeB(0), + m_IdA(0), + m_IdB(0) + {} + + Accumulator_ABTrim(const Accumulator_ABTrim &c) { +# pragma omp critical + { + m_Avg = c.m_Avg; + m_InternalCount = c.m_InternalCount; + m_SizeA = c.m_SizeA; + m_SizeB = c.m_SizeB; + m_IdA = c.m_IdA; + m_IdB = c.m_IdB; + memcpy (m_Av, c.m_Av, sizeof (m_Av)); + } + } + + void operator += (T value) { + if(m_InternalCount > subsample_size) { + // array complete and counter over subsample // + if( m_SizeA > 0 && value < m_ValA ) { + ;// m_Avg += m_ValA; + } + else if (m_SizeB > 0 && value > m_ValB) + { + ;// m_Avg += m_ValB; + } + else + { + m_Avg += value; + m_InternalCount++; + } + } + else if(m_InternalCount >=0) { + // array complete + if(m_SizeA > 0 && value < m_ValA) + { + m_Avg += m_ValA; + m_Av[m_IdA] = value; + for (unsigned int i=0; i < m_SizeA; i++) + if(m_Av[i] > m_Av[m_IdA]) + { m_IdA = i; m_ValA = m_Av[i]; } + } + else if(m_SizeB > 0 && value > m_ValB) + { + m_Avg += m_ValB; + m_Av[m_IdB] = value; + for (unsigned int i=m_SizeA; i < m_SizeA+m_SizeB; i++) + if(m_Av[i] < m_Av[m_IdB]) + { m_IdB = i; m_ValB = m_Av[i]; } + } + else { + m_Avg += value; + } + m_InternalCount++; + } + else { // m_InternalCount < 0 + // array is not fullfilled + m_Av[m_SizeA+m_SizeB+m_InternalCount] = value; + m_InternalCount++; + if(m_InternalCount == 0) { + std::sort(m_Av,m_Av+m_SizeA+m_SizeB); + if(m_SizeA > 0) { + m_IdA = m_SizeA-1; + m_ValA = m_Av[m_IdA]; + } + if(m_SizeB > 0) { + m_IdB = m_SizeA; + m_ValB = m_Av[m_SizeA]; + } + } + } + } + + T operator()() { + if(m_InternalCount <= 0) { + std::sort(m_Av, m_Av+m_SizeA+m_SizeB+m_InternalCount); + return m_Av[ (m_SizeA+m_SizeB+m_InternalCount) / 2]; // median value // + } + else { +// return (m_Avg + m_ValA * m_SizeA + m_ValB * m_SizeB) / +// (m_InternalCount + m_SizeA + m_SizeB); + return (m_Avg) / m_InternalCount; + } + } + + void SetABTrim(int a, int b) { + if(a+b > subsample_size/2) { + m_SizeA = a/(a+b) * subsample_size/2; + m_SizeB = b/(a+b) * subsample_size/2; + } + else { + m_SizeA = a; + m_SizeB = b; + } + m_Avg = 0; + m_InternalCount = -m_SizeA-m_SizeB; + } + + +private: + T m_Av[subsample_size/2]; + T m_Avg, m_ValA, m_ValB; + int m_IdA, m_IdB, m_InternalCount; + int m_SizeA, m_SizeB; +}; + + + + + + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// Clip Accumulator // + +template < typename T, int subsample_size=200 > +class Accumulator_ABClip { + +public: + Accumulator_ABClip() : + m_Avg(0), + m_InternalCount(0), + m_SizeA(0), + m_SizeB(0), + m_IdA(0), + m_IdB(0) + {} + + Accumulator_ABClip(const Accumulator_ABClip &c) { +# pragma omp critical + { + m_Avg = c.m_Avg; + m_InternalCount = c.m_InternalCount; + m_SizeA = c.m_SizeA; + m_SizeB = c.m_SizeB; + m_IdA = c.m_IdA; + m_IdB = c.m_IdB; + memcpy (m_Av, c.m_Av, sizeof (m_Av)); + } + } + + void operator += (T value) { + if(m_InternalCount > subsample_size) { + // array complete and counter over subsample // + if( m_SizeA > 0 && value < m_ValA ) { + m_Avg += m_ValA; + } + else if (m_SizeB > 0 && value > m_ValB) { + m_Avg += m_ValB; + } + else { + m_Avg += value; + } + m_InternalCount++; + } + else if(m_InternalCount >=0) { + // array complete + if(m_SizeA > 0 && value < m_ValA) + { + m_Avg += m_ValA; + m_Av[m_IdA] = value; + for (unsigned int i=0; i < m_SizeA; i++) + if(m_Av[i] > m_Av[m_IdA]) + { m_IdA = i; m_ValA = m_Av[i]; } + } + else if(m_SizeB > 0 && value > m_ValB) + { + m_Avg += m_ValB; + m_Av[m_IdB] = value; + for (unsigned int i=m_SizeA; i < m_SizeA+m_SizeB; i++) + if(m_Av[i] < m_Av[m_IdB]) + { m_IdB = i; m_ValB = m_Av[i]; } + } + else { + m_Avg += value; + } + m_InternalCount++; + } + else { // m_InternalCount < 0 + // array is not fullfilled + m_Av[m_SizeA+m_SizeB+m_InternalCount] = value; + m_InternalCount++; + if(m_InternalCount == 0) { + std::sort(m_Av,m_Av+m_SizeA+m_SizeB); + if(m_SizeA > 0) { + m_IdA = m_SizeA-1; + m_ValA = m_Av[m_IdA]; + } + if(m_SizeB > 0) { + m_IdB = m_SizeA; + m_ValB = m_Av[m_SizeA]; + } + } + } + } + + T operator()() { + if(m_InternalCount <= 0) { + std::sort(m_Av, m_Av+m_SizeA+m_SizeB+m_InternalCount); + return m_Av[ (m_SizeA+m_SizeB+m_InternalCount) / 2]; // median value // + } + else { + return (m_Avg + m_ValA * m_SizeA + m_ValB * m_SizeB) / + (m_InternalCount + m_SizeA + m_SizeB); + } + } + + void SetABTrim(int a, int b) { + if(a+b > subsample_size/2) { + m_SizeA = a/(a+b) * subsample_size/2; + m_SizeB = b/(a+b) * subsample_size/2; + } + else { + m_SizeA = a; + m_SizeB = b; + } + m_Avg = 0; + m_InternalCount = -m_SizeA-m_SizeB; + } + + +private: + T m_Av[subsample_size/2]; + T m_Avg, m_ValA, m_ValB; + int m_IdA, m_IdB, m_InternalCount; + int m_SizeA, m_SizeB; +}; + + + + + +} // uLib + + + + +#endif // U_DATABINNING_H diff --git a/src/Math/BitCode.h b/src/Math/BitCode.h new file mode 100644 index 0000000..40e6714 --- /dev/null +++ b/src/Math/BitCode.h @@ -0,0 +1,259 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + +#ifndef U_MATH_BITCODE_H +#define U_MATH_BITCODE_H + +#include +#include +//#include +#include + +#include +#include +#include +#include + +namespace uLib { + + +template < typename ContainerT, typename ContentT > +struct CommaInitializerBitCode +{ + inline explicit CommaInitializerBitCode(ContainerT *container, ContentT s) + : container(container) + { + this->index = 0; + this->container->operator()().field1 = s; + } + inline CommaInitializerBitCode & operator, (ContentT s) { + this->index++; + if(index < container->size()) { + if(index == 1) container->operator()().field2 = s; + if(index == 2) container->operator()().field3 = s; + if(index == 3) container->operator()().field4 = s; + } + return *this; + } + + ContainerT *container; + unsigned int index; +}; + + + + +template +class BitCode2 +{ +protected: + typedef T Type; + typedef BitCode2 ThisClass; + typedef CommaInitializerBitCode< ThisClass, T > CommaInit; + BOOST_STATIC_ASSERT_MSG( boost::is_unsigned::value == 1, "CODE TYPE MUST BE UNSIGNED" ); + BOOST_STATIC_ASSERT( L1+L2 == sizeof(T)*8 ); + +public: + struct BitField { + T field1 : L1; + T field2 : L2; + }; + union CodeSet { + BitField bitf; + T value; + } m_data; + + BitCode2() {} + BitCode2(const T& data) { m_data.value = data; } + BitCode2(const Vector2i & data) { + (*this) << data(0),data(1); + } + inline CommaInit operator <<(T scalar) { return CommaInit(this, scalar); } + static const int size() { return 2; } + + BitField & operator()() { return m_data.bitf; } + const BitField & operator()() const { return m_data.bitf; } + operator Vector2i () { return Vector2i(m_data.bitf.field1, + m_data.bitf.field2); } + + void set(const T data) { m_data.value = data; } + T get() const { return m_data.value; } +}; + +template +std::ostream & +operator << (std::ostream &o, const BitCode2 &code) { + o << code().field1 << "," << code().field2; + return o; +} + + + + + + + +template +class BitCode3 +{ +protected: + typedef T Type; + typedef BitCode3 ThisClass; + typedef CommaInitializerBitCode< ThisClass, T > CommaInit; + BOOST_STATIC_ASSERT_MSG( boost::is_unsigned::value == 1, "CODE TYPE MUST BE UNSIGNED" ); + BOOST_STATIC_ASSERT( L1+L2+L3 == sizeof(T)*8 ); + +public: + struct BitField { + T field1 : L1; + T field2 : L2; + T field3 : L3; + }; + union CodeSet { + BitField bitf; + T value; + } m_data; + + + BitCode3() {} + BitCode3(const T& data) { m_data.value = data; } + BitCode3(const Vector3i & data) { + (*this) << data(0),data(1),data(2); + } + inline CommaInit operator <<(T scalar) { return CommaInit(this, scalar); } + static const int size() { return 3; } + + BitField & operator()() { return m_data.bitf; } + const BitField & operator()() const { return m_data.bitf; } + operator Vector3i () { return Vector3i(m_data.bitf.field1, + m_data.bitf.field2, + m_data.bitf.field3); } + + void set(const T data) { m_data.value = data; } + T get() const { return m_data.value; } +}; + +template +std::ostream & +operator << (std::ostream &o, const BitCode3 &code) { + o << code().field1 << "," << code().field2 << "," << code().field3; + return o; +} + + + + + + + +template +class BitCode4 +{ +protected: + typedef T Type; + typedef BitCode4 ThisClass; + typedef CommaInitializerBitCode< ThisClass, T > CommaInit; + BOOST_STATIC_ASSERT_MSG( boost::is_unsigned::value == 1, "CODE TYPE MUST BE UNSIGNED" ); + BOOST_STATIC_ASSERT( L1+L2+L3+L4 == sizeof(T)*8 ); +public: + struct BitField { + T field1 : L1; + T field2 : L2; + T field3 : L3; + T field4 : L4; + }; + union CodeSet { + BitField bitf; + T value; + } m_data; + + BitCode4() {} + BitCode4(const T& data) { m_data.value = data; } + BitCode4(const Vector4i & data) { + (*this) << data(0),data(1),data(2),data(3); + } + inline CommaInit operator << (T scalar) { return CommaInit(this, scalar); } + static const int size() { return 4; } + + BitField & operator()() { return m_data.bitf; } + const BitField & operator()() const { return m_data.bitf; } + operator Vector4i () { return Vector4i(m_data.bitf.field1, + m_data.bitf.field2, + m_data.bitf.field3, + m_data.bitf.field4); } + + void set(const T data) { m_data.value = data; } + T get() const { return m_data.value; } + + + +}; + +template +std::ostream & +operator << (std::ostream &o, const BitCode4 &code) { + o << code().field1 << "," << code().field2 << "," << code().field3 << "," << code().field4; + return o; +} + + + +template +class BitCode { + typedef boost::mpl::vector_c BitSet; + typedef boost::mpl::vector_c BitSft; + +// static constexpr uint bset[3] = {L1,L2,L3}; +// static constexpr uint bsft[3] = {0,L1,L1+L2}; + + BOOST_STATIC_ASSERT_MSG( boost::is_unsigned::value == 1, "CODE TYPE MUST BE UNSIGNED" ); + //BOOST_STATIC_ASSERT( L1+L2+L3 == sizeof(T)*8 ); + T m_data; +public: + void PrintSelf( ) { +// for(int i=0; i< boost::mpl::size() ;++i) +// std::cout << "BitSet " << i << " [" << bset[i] << "] -> " << Get(i) << "\n"; + } + + T Get(unsigned short field) const { + // return (m_data >> bsft[field]) & (1< + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CONTAINERBOX_H +#define U_CONTAINERBOX_H + +#include "Geometry.h" + + +namespace uLib { + + + +class ContainerBox : public AffineTransform { +public: + ContainerBox() : m_LocalT(this) {} + + ContainerBox(const ContainerBox ©) : + m_LocalT(this), + AffineTransform(copy) + { + // FIX for performance // + this->SetOrigin(copy.GetOrigin()); + this->SetSize(copy.GetSize()); + } + + inline void SetOrigin(const Vector3f &v) { m_LocalT.SetPosition(v); } + + inline Vector3f GetOrigin() const { return m_LocalT.GetPosition(); } + + void SetSize(const Vector3f &v) { + Vector3f pos = this->GetOrigin(); + m_LocalT = AffineTransform(this); + m_LocalT.Scale(v); + m_LocalT.SetPosition(pos); + } + + inline Vector3f GetSize() const { return m_LocalT.GetScale(); } + + // WARNING: FIX... // + inline void FlipLocalAxes(int first, int second) + { m_LocalT.FlipAxes(first,second); } + + Matrix4f GetWorldMatrix() const { return m_LocalT.GetWorldMatrix(); } + + inline Vector4f GetWorldPoint(const Vector4f &v) const { + return m_LocalT.GetWorldMatrix() * v; + } + + inline Vector4f GetWorldPoint(const float x, const float y, const float z) { + return this->GetWorldPoint(Vector4f(x,y,z,1)); + } + + inline Vector4f GetLocalPoint(const Vector4f &v) const { + return m_LocalT.GetWorldMatrix().inverse() * v; + } + + inline Vector4f GetLocalPoint(const float x, const float y, const float z) { + return this->GetLocalPoint(Vector4f(x,y,z,1)); + } + +private: + AffineTransform m_LocalT; +}; + + +} + + + +#endif // CONTAINERBOX_H diff --git a/src/Math/DataSet.h b/src/Math/DataSet.h new file mode 100644 index 0000000..5c7202e --- /dev/null +++ b/src/Math/DataSet.h @@ -0,0 +1,77 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + +#ifndef U_MATH_DATASET_H +#define U_MATH_DATASET_H + +#include +#include + +#include + +#include "Math/Dense.h" +#include "Math/StructuredData.h" +#include + +namespace uLib { + +class DataSet_Base { +public: + DataSet_Base() {} + + virtual ~DataSet_Base() {} + virtual const void * GetPtr(Id_t id) const = 0; + virtual void * GetPtr(Id_t id) = 0; + virtual size_t Size() const = 0; + +private: + + +}; + +template +class VectorData : public DataSet_Base, public Vector { +public: + + +protected: + const void *GetPtr(Id_t id) const { return &this->at(id); } + void * GetPtr(Id_t id) { return &this->at(id); } +}; + + + + + + + + + + +} // uLib + + + +#endif // DATASET_H diff --git a/src/Math/Dense.cpp b/src/Math/Dense.cpp new file mode 100644 index 0000000..eb3e473 --- /dev/null +++ b/src/Math/Dense.cpp @@ -0,0 +1,64 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Dense.h" +#include "Core/Archives.h" + +//ULIB_SERIALIZE(uLib::HPoint3f) { +// ar & boost::serialization::make_nvp(NULL,boost::serialization::base_object(ob)); +//} + + +//ULIB_SERIALIZE(uLib::Vector4f) { +// ar & boost::serialization::make_nvp(NULL,boost::serialization::base_object(ob)); +//} + + +//ULIB_SERIALIZE(uLib::HLine3f) { +// ar +// & "HLine -> ( origin: " & AR(origin) & "; direction: " & AR(direction) & ") "; +//} + +//ULIB_SERIALIZE(uLib::HError3f) { +// ar +// & "HLine -> ( poserr: " & AR(position_error) & "; direrr: " & AR(direction_error) & ") "; +//} + + +// NEW // +ULIB_SERIALIZE(uLib::Vector2i) { ar & boost::serialization::make_nvp(NULL,ob); } +ULIB_SERIALIZE(uLib::Vector3i) { ar & boost::serialization::make_nvp(NULL,ob); } +ULIB_SERIALIZE(uLib::Vector4i) { ar & boost::serialization::make_nvp(NULL,ob); } +ULIB_SERIALIZE(uLib::Vector2f) { ar & boost::serialization::make_nvp(NULL,ob); } +ULIB_SERIALIZE(uLib::Vector3f) { ar & boost::serialization::make_nvp(NULL,ob); } +ULIB_SERIALIZE(uLib::Vector4f) { ar & boost::serialization::make_nvp(NULL,ob); } +ULIB_SERIALIZE(uLib::Vector2d) { ar & boost::serialization::make_nvp(NULL,ob); } +ULIB_SERIALIZE(uLib::Vector3d) { ar & boost::serialization::make_nvp(NULL,ob); } +ULIB_SERIALIZE(uLib::Vector4d) { ar & boost::serialization::make_nvp(NULL,ob); } + + diff --git a/src/Math/Dense.h b/src/Math/Dense.h new file mode 100644 index 0000000..add140a --- /dev/null +++ b/src/Math/Dense.h @@ -0,0 +1,364 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +/* + * + * Copyright (C) 2012 Andrea Rigoni Garola + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + + +#ifndef ULIB_DENSEMATRIX_H +#define ULIB_DENSEMATRIX_H + +#include + +#include +#include "Core/Types.h" +#include "Core/Serializable.h" + + + + +/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// NEW PART // + + + +namespace uLib { + +//////////////////////////////////////////////////////////////////////////////// +// DENSE MATRIX DEFINITION ///////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +using Eigen::Matrix; + + +//////////////////////////////////////////////////////////////////////////////// +// DENSE TYPES DEFINITIONS ///////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ + typedef Eigen::Matrix Matrix##SizeSuffix##TypeSuffix; \ + typedef Eigen::Matrix Vector##SizeSuffix##TypeSuffix; \ + typedef Eigen::Matrix RowVector##SizeSuffix##TypeSuffix; \ +// /* IMPORT INTERFACES */ \ +// typedef Interface::DenseMatrix, mpl::int_ > IMatrix##SizeSuffix##TypeSuffix; \ +// typedef Interface::DenseArray > IVector##SizeSuffix##TypeSuffix; \ +// typedef Interface::DenseArray > IRowVector##SizeSuffix##TypeSuffix; + + +#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ + EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \ + EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \ + EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 4, 4) + +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int, i) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float, f) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(double, d) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex, cf) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex, cd) + +#undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES +#undef EIGEN_MAKE_TYPEDEFS + +} // uLib + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// OLD PART // + +//// BOOST SERIALIZATION /////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include + + +namespace boost { +namespace serialization { + +template +void serialize(Archive & ar, ::Eigen::Matrix & m, const unsigned int /*version*/) { + ar & boost::serialization::make_array(m.data(), RowsAtCompileTime * ColsAtCompileTime); +} + +} // serialization +} // boost + +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// EIGEN VECTOR STREAM INTERACTIONS //////////////////////////////////////////// +// this is needed by boost::lexical_cast to cope with Eigens Vectors /////////// +namespace Eigen { + +template +std::istream & operator >> (std::basic_istream &is, Eigen::Matrix &vec) { + std::basic_string str; + for( unsigned int i=0; i> std::skipws >> str; + if(is.fail()) vec(i) = 0; + else vec(i) = boost::lexical_cast(str); + } + return is; +} + +template +Eigen::Matrix & operator >> (const std::basic_string &str, Eigen::Matrix &vec) { + std::stringstream ss(str); + ss >> vec; + return vec; +} + +template +std::basic_ostream & operator << (std::basic_ostream &os, const Eigen::Matrix &vec) { + // os << "[" << vec.transpose() << "]T"; // TODO: read and write Transposition with a proper symbol + os << vec.transpose(); + return os; +} + +template +std::basic_string & operator << (std::basic_string &str, const Eigen::Matrix &vec) { + std::basic_stringstream ss; + ss << vec; + str += ss.str(); + return str; +} + + +} // Eigen +//////////////////////////////////////////////////////////////////////////////// + + + +namespace uLib { + + +typedef int Scalari; +typedef unsigned int Scalarui; +typedef long Scalarl; +typedef unsigned long Scalarul; +typedef float Scalarf; +typedef double Scalard; + +} // uLib + +//typedef Eigen::Matrix Matrix1i; +//typedef Eigen::Matrix2i Matrix2i; +//typedef Eigen::Matrix3i Matrix3i; +//typedef Eigen::Matrix4i Matrix4i; + +//typedef Eigen::Matrix Matrix1f; +//typedef Eigen::Matrix2f Matrix2f; +//typedef Eigen::Matrix3f Matrix3f; +//typedef Eigen::Matrix4f Matrix4f; + +//typedef Eigen::Matrix Vector1i; +//typedef Eigen::Vector2i Vector2i; +//typedef Eigen::Vector3i Vector3i; +//typedef Eigen::Vector4i Vector4i; + +//typedef Eigen::Matrix Vector1f; +//typedef Eigen::Vector2f Vector2f; +//typedef Eigen::Vector3f Vector3f; +//typedef Eigen::Vector4f Vector4f; + + + + +//////////////////////////////////////////////////////////////////////////////// +// Vector String interaction /////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +///*! Given a string consisting of a series of doubles with some +//* delimiter, return an Eigen::Vector populated with those +//* values, in the same order as they are given in the string. +//* +//* \param vec A double vector to be populated with the results +//* \param str A string to be parsed as a series of doubles. +//* \param delim Delimiters of the text (a typical default is " ," for comma and space-delimited text +//* +//*/ +//template +//void VectorxT_StringTo(Eigen::Matrix &vec, std::string str, const char *delim = " ,;\t\n") { +// std::vector strvec; + +// boost::algorithm::trim_if( str, boost::algorithm::is_any_of(delim)); +// boost::algorithm::split(strvec,str,boost::algorithm::is_any_of(delim), boost::algorithm::token_compress_on); + +// for( unsigned int i=0; i(strvec[i]); +// } +//} + +//template +//std::string VectorxT_ToString(const Eigen::Matrix &vec) { +// std::stringstream sst; +// sst << vec.transpose(); +// return sst.str(); +//} + + +////template +////Eigen::Matrix & operator >> (std::istream &is, Eigen::Matrix &vec) { +////} + +//template +//void operator>> (std::string& str, Eigen::Matrix &vec){ +// VectorxT_StringTo(vec,str); +//} + + +//////////////////////////////////////////////////////////////////////////////// +////// HOMOGENEOUS VECTORS ////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +//template +//class _HPoint3f : public Eigen::Matrix< Scalarf,4,1 > { +//public: +// typedef Eigen::Matrix< Scalarf,4,1 > BaseClass; + +// _HPoint3f

() : BaseClass(0,0,0,p) {} +// _HPoint3f

(float x,float y,float z) : BaseClass(x,y,z,p) {} +// _HPoint3f

(Vector3f &in) : BaseClass(in.homogeneous()) { this->w = p; } + +// // This constructor allows to construct MyVectorType from Eigen expressions +// template +// inline _HPoint3f

(const Eigen::MatrixBase& other) +// : BaseClass(other) +// { } + +// // This method allows to assign Eigen expressions to Vector3H +// template +// inline _HPoint3f

& operator= (const Eigen::MatrixBase & other) +// { +// this->BaseClass::operator=(other); +// return *this; +// } + +//}; +//typedef _HPoint3f Vector4f; +//typedef _HPoint3f HPoint3f; + + + + +//////////////////////////////////////////////////////////////////////////////// +////// HOMOGENEOUS LINE ////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +//struct _HLine3f +//{ +// HPoint3f origin; +// Vector4f direction; +//}; +//typedef struct _HLine3f HLine3f; + +//inline std::ostream& +//operator<< (std::ostream& stream, const HLine3f &line) { +// stream << "HLine3f(" << "pt[" << line.origin.transpose() <<"] , dr[" << line.direction.transpose() << "]) "; +// return stream; +//} + + + + +//struct _HError3f +//{ +// Vector4f position_error; +// Vector4f direction_error; +//}; +//typedef struct _HError3f HError3f; + +//inline std::ostream& +//operator<< (std::ostream& stream, const HError3f &err) { +// stream << "HError3f(" << "ept[" << err.position_error.transpose() <<"] , edr[" << err.direction_error.transpose() << "]) "; +// return stream; +//} + + +//} + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// SERIALIZTION // + +// NEW // +ULIB_SERIALIZABLE(uLib::Vector2i) +ULIB_SERIALIZABLE(uLib::Vector3i) +ULIB_SERIALIZABLE(uLib::Vector4i) +ULIB_SERIALIZABLE(uLib::Vector2f) +ULIB_SERIALIZABLE(uLib::Vector3f) +ULIB_SERIALIZABLE(uLib::Vector4f) +ULIB_SERIALIZABLE(uLib::Vector2d) +ULIB_SERIALIZABLE(uLib::Vector3d) +ULIB_SERIALIZABLE(uLib::Vector4d) + + + +//ULIB_SERIALIZABLE(uLib::HPoint3f) +//ULIB_SERIALIZABLE(uLib::Vector4f) +//ULIB_SERIALIZABLE(uLib::HLine3f) +//ULIB_SERIALIZABLE(uLib::HError3f) + + + + + +#endif // U_DENSEMATRIX_H diff --git a/src/Math/Geometry.h b/src/Math/Geometry.h new file mode 100644 index 0000000..c2c9912 --- /dev/null +++ b/src/Math/Geometry.h @@ -0,0 +1,60 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_GEOMETRY_H +#define U_GEOMETRY_H + +#include "Core/Object.h" +#include "Math/Dense.h" +#include "Math/Transform.h" + +namespace uLib { + +class Geometry : public AffineTransform { +public: + + inline Vector4f GetWorldPoint(const Vector4f &v) const { + return this->GetWorldMatrix() * v; + } + + inline Vector4f GetWorldPoint(const float x, const float y, const float z) { + return this->GetWorldPoint(Vector4f(x,y,z,1)); + } + + inline Vector4f GetLocalPoint(const Vector4f &v) const { + return this->GetWorldMatrix().inverse() * v; + } + + inline Vector4f GetLocalPoint(const float x, const float y, const float z) { + return this->GetLocalPoint(Vector4f(x,y,z,1)); + } +}; + + +} + +#endif // GEOMETRY_H diff --git a/src/Math/ImageData.cpp b/src/Math/ImageData.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/Math/ImageData.h b/src/Math/ImageData.h new file mode 100644 index 0000000..69feac6 --- /dev/null +++ b/src/Math/ImageData.h @@ -0,0 +1,54 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + +#ifndef U_MATH_IMAGEDATA_H +#define U_MATH_IMAGEDATA_H + + +#include +#include + +#include +#include + +namespace uLib { + +class ImageData : public ImageSpace, public ImageMap { + + ImageData() {} + + +public: + + +}; + + + + + +} // uLib + +#endif // IMAGEDATA_H diff --git a/src/Math/ImageMap.cpp b/src/Math/ImageMap.cpp new file mode 100644 index 0000000..29045d6 --- /dev/null +++ b/src/Math/ImageMap.cpp @@ -0,0 +1,80 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + +#include "ImageMap.h" + +using namespace uLib; + +ImageMap::ImageMap(const Vector3i &size) : + m_Dims(size) +{ + SetDataOrder(); +} + +void ImageMap::SetDims(const Vector3i &size) +{ + this->m_Dims = size; + SetDataOrder(); +} + +void ImageMap::SetDataOrder(ImageMap::Order order) +{ + int i = order & 0x3; + int j = (order >> 2) & 0x3; + int k = (order >> 4) & 0x3; + this->m_Increments[i] = 1; + this->m_Increments[j] = m_Dims[i]; + this->m_Increments[k] = m_Dims[i] * m_Dims[j]; + this->m_DataOrder = order; +} + +bool ImageMap::IsInsideGrid(const Vector3i &v) const +{ + int vok = 1; + vok *= (v(0) >= 0 && v(0) < m_Dims[0]); + vok *= (v(1) >= 0 && v(1) < m_Dims[1]); + vok *= (v(2) >= 0 && v(2) < m_Dims[2]); + return vok; +} + + + +Vector3i ImageMap::UnMap(int index) const +{ + Vector3i v( 0,0,0 ); + Vector3i iv = m_Increments; + int id = 0; + for(int k=0; k<3; ++k) { + int inc = iv.maxCoeff(&id); + v(id) = index / inc; + index -= v(id) * inc; + iv(id) = 0; + } + return v; +} + + + + diff --git a/src/Math/ImageMap.h b/src/Math/ImageMap.h new file mode 100644 index 0000000..e27cd8d --- /dev/null +++ b/src/Math/ImageMap.h @@ -0,0 +1,95 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + +#ifndef U_MATH_IMAGEMAP_H +#define U_MATH_IMAGEMAP_H + +#include "Core/Macros.h" +#include "Core/Object.h" +#include "Math/Dense.h" +#include "Math/DataSet.h" + +namespace uLib { + +class ImageMap { +public: + typedef enum { + CustomOrder = 0, + XYZ = 0 | 1 << 2 | 2 << 4, + XZY = 0 | 2 << 2 | 1 << 4, + YXZ = 1 | 0 << 2 | 2 << 4, + YZX = 2 | 0 << 2 | 1 << 4, + ZXY = 1 | 2 << 2 | 0 << 4, + ZYX = 2 | 1 << 2 | 0 << 4 + } Order; + + ImageMap(const Vector3i &size); + + ImageMap(const ImageMap ©) : + m_DataOrder(copy.m_DataOrder), + m_Dims(copy.m_Dims), + m_Increments(copy.m_Increments) + {} + + uLibGetMacro(Dims,Vector3i) + + void SetDims(const Vector3i &size); + + uLibGetSetMacro(Increments,Vector3i) + + void SetDataOrder(Order order = YXZ); + + uLibGetMacro(DataOrder,Order) + + bool IsInsideGrid(const Vector3i &v) const; + + inline int Map(Vector3i index) const; + + Vector3i UnMap(int index) const; + +private: + Order m_DataOrder; + Vector3i m_Dims; + Vector3i m_Increments; //TODO: make this line matrix // +}; + + +// --- INLINES -------------------------------------------------------------- // + + +inline int ImageMap::Map(Vector3i index) const +{ + return (m_Increments.transpose() * index); +} + + + + + +} // uLib + + + +#endif // IMAGEMAP_H diff --git a/src/Math/ImageSpace.cpp b/src/Math/ImageSpace.cpp new file mode 100644 index 0000000..0cb5112 --- /dev/null +++ b/src/Math/ImageSpace.cpp @@ -0,0 +1,87 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + +#include "ImageSpace.h" + +namespace uLib { + +ImageSpace::ImageSpace(const Vector3i size) : + StructuredData(size) +{} + +//void ImageSpace::SetSize(const Vector3f v) +//{ +// ContainerBox::SetSize( v.array() / this->GetDims().array().cast() ); +//} + +//Vector3f ImageSpace::GetSize() const +//{ +// return ContainerBox::GetSize().array() * this->GetDims().array().cast(); +//} + +void ImageSpace::SetSpacing(const Vector3f spacing) +{ + ContainerBox::SetSize(spacing); +} + +Vector3f ImageSpace::GetSpacing() const +{ + return ContainerBox::GetSize(); +} + + +//bool ImageSpace::IsInsideBounds(const Vector4f pt) const +//{ +// Vector4f ptl = this->GetLocalPoint(pt); +// int result = 0; +// for ( int i=0; i<3 ;++i) { +// result += ptl(i) > (float)this->GetDims()(i); +// result += ptl(i) < 0; +// } +// return result == 0; +//} + +Vector3i ImageSpace::Find(const Vector4f pt) const +{ + Vector3i out; + Vector4f p = GetLocalPoint(pt); + out << (int)floor(p(0)), + (int)floor(p(1)), + (int)floor(p(2)); + return out; +} + +void ImageSpace::PrintSelf(std::ostream &o) +{ + o << "uLib Structured Grid: \n" +// << "dim = " << this->GetDims().transpose() << "\n" + << "spacing = " << this->GetSpacing().transpose() << "\n"; +} + + +} // uLib + + diff --git a/src/Math/ImageSpace.h b/src/Math/ImageSpace.h new file mode 100644 index 0000000..2991318 --- /dev/null +++ b/src/Math/ImageSpace.h @@ -0,0 +1,67 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + +#ifndef U_MATH_IMAGESPACE_H +#define U_MATH_IMAGESPACE_H + +#include "Core/Object.h" +#include "Math/ContainerBox.h" + + +namespace uLib { + +class ImageSpace : public ContainerBox { + typedef ContainerBox BaseClass; +public: + ImageSpace(const Vector3i size); + + using ContainerBox::SetOrigin; + +// void SetSize(const Vector3f v); + +// Vector3f GetSize() const; + + void SetSpacing(const Vector3f spacing); + + Vector3f GetSpacing() const; + +// bool IsInsideBounds(const Vector4f pt) const; + + Vector3i Find(const Vector4f pt) const; + + void PrintSelf(std::ostream &o); + +private: + using ContainerBox::GetSize; + using ContainerBox::SetSize; +}; + + +} // uLib + + + + +#endif // IMAGESPACE_H diff --git a/src/Math/Line.h b/src/Math/Line.h new file mode 100644 index 0000000..a192efd --- /dev/null +++ b/src/Math/Line.h @@ -0,0 +1,69 @@ +#ifndef U_GEO_LINE_H +#define U_GEO_LINE_H + +#include "Core/Macros.h" +#include "Core/Mpl.h" +#include "Core/Serializable.h" + + +#include "Math/Dense.h" + + + +namespace uLib { + +//////////////////////////////////////////////////////////////////////////////// +// VECTOR PAIR ///////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +template +class VectorPair { +public: + typedef Matrix<_Scalar,_Dim,1> Vector; + VectorPair() {} + VectorPair(const Vector &first, + const Vector &second) { + this->m_data[0] = first; + this->m_data[1] = second; + } + uLibArrayMacro(Data,Vector *) +protected: + EIGEN_ALIGN16 Vector m_Data[2]; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// LINE //////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +template +class Line : public VectorPair<_Scalar, _Dim> { +public: + ULIB_SERIALIZE_ACCESS + typedef VectorPair<_Scalar, _Dim> BaseClass; + typedef typename BaseClass::Vector Vector; + + Line() {} + Line(const Vector &origin, const Vector &direction) : BaseClass(origin,direction) {} + + Vector & origin() { return this->m_Data[0]; } + Vector & direction() { return this->m_Data[1]; } + const Vector & origin() const { return this->m_Data[0]; } + const Vector & direction() const { return this->m_Data[1]; } +}; + +typedef Line Line2f; +typedef Line Line3f; +typedef Line Line4f; +typedef Line4f HLine3f; + +} // uLib + + + +//ULIB_SERIALIZABLE(uLib::Line2f) +//ULIB_SERIALIZABLE(uLib::Line3f) +//ULIB_SERIALIZABLE(uLib::Line4f) + + +#endif // LINE_H diff --git a/src/Math/Makefile.am b/src/Math/Makefile.am new file mode 100644 index 0000000..e8add8c --- /dev/null +++ b/src/Math/Makefile.am @@ -0,0 +1,42 @@ +SUBDIRS = . + +include $(top_srcdir)/Common.am + +library_includedir = $(includedir)/libmutom-${PACKAGE_VERSION}/Math +library_include_HEADERS = ContainerBox.h \ + Dense.h \ + Geometry.h \ + Transform.h \ + StructuredData.h\ + StructuredGrid.h\ + VoxImage.h \ + VoxRaytracer.h \ + Utils.h \ + VoxImageFilter.h\ + VoxImageFilter.hpp \ + VoxImageFilterLinear.hpp \ + VoxImageFilterMedian.hpp \ + VoxImageFilterABTrim.hpp \ + VoxImageFilterBilateral.hpp \ + VoxImageFilterThreshold.hpp \ + VoxImageFilter2ndStat.hpp \ + VoxImageFilterCustom.hpp \ + Accumulator.h \ + TriangleMesh.h + + +_MATH_SOURCES = \ + VoxRaytracer.cpp \ + StructuredData.cpp \ + StructuredGrid.cpp \ + VoxImage.cpp \ + TriangleMesh.cpp \ + Dense.cpp + + + + +noinst_LTLIBRARIES = libmutommath.la +libmutommath_la_SOURCES = ${_MATH_SOURCES} + + diff --git a/src/Math/Polydata.h b/src/Math/Polydata.h new file mode 100644 index 0000000..4cd462f --- /dev/null +++ b/src/Math/Polydata.h @@ -0,0 +1,48 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef POLYDATA_H +#define POLYDATA_H + +#include "Core/Object.h" + +namespace uLib { + +class Polydata : public Object { + +public: + + + +}; + + +} + + + +#endif // POLYDATA_H diff --git a/src/Math/Quote.h b/src/Math/Quote.h new file mode 100644 index 0000000..f10f042 --- /dev/null +++ b/src/Math/Quote.h @@ -0,0 +1,49 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_MATH_QUOTE_H +#define U_MATH_QUOTE_H + +#include "Math/Dense.h" + +namespace uLib { + +class Quote : public Vector2f { +public: + + + uLibRefMacro(Offset,Scalarf); + +private: + Scalarf m_Offset; +}; + + +} // uLib + + +#endif // QUOTE_H diff --git a/src/Math/StructuredData.cpp b/src/Math/StructuredData.cpp new file mode 100644 index 0000000..456747a --- /dev/null +++ b/src/Math/StructuredData.cpp @@ -0,0 +1,80 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "StructuredData.h" + +using namespace uLib; + +StructuredData::StructuredData(const Vector3i &size) : + m_Dims(size) +{ + SetDataOrder(); +} + +void StructuredData::SetDims(const Vector3i &size) +{ + this->m_Dims = size; + SetDataOrder(); +} + +void StructuredData::SetDataOrder(StructuredData::Order order) +{ + int i = order & 0x3; + int j = (order >> 2) & 0x3; + int k = (order >> 4) & 0x3; + this->m_Increments[i] = 1; + this->m_Increments[j] = m_Dims[i]; + this->m_Increments[k] = m_Dims[i] * m_Dims[j]; + this->m_DataOrder = order; +} + +bool StructuredData::IsInsideGrid(const Vector3i &v) const +{ + int vok = 1; + vok *= (v(0) >= 0 && v(0) < m_Dims[0]); + vok *= (v(1) >= 0 && v(1) < m_Dims[1]); + vok *= (v(2) >= 0 && v(2) < m_Dims[2]); + return vok; +} + + + +Vector3i StructuredData::UnMap(int index) const +{ + Vector3i v( 0,0,0 ); + Vector3i iv = m_Increments; + int id = 0; + for(int k=0; k<3; ++k) { + int inc = iv.maxCoeff(&id); + v(id) = index / inc; + index -= v(id) * inc; + iv(id) = 0; + } + return v; +} + + diff --git a/src/Math/StructuredData.h b/src/Math/StructuredData.h new file mode 100644 index 0000000..9ccb868 --- /dev/null +++ b/src/Math/StructuredData.h @@ -0,0 +1,101 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef STRUCTUREDDATA_H +#define STRUCTUREDDATA_H + +#include "Core/Macros.h" +#include "Core/Object.h" +#include "Math/Dense.h" +#include "Math/DataSet.h" + + +namespace uLib { + +class StructuredData { +public: + enum _Order + { + CustomOrder = 0, + XYZ = 0 | 1 << 2 | 2 << 4, + XZY = 0 | 2 << 2 | 1 << 4, + YXZ = 1 | 0 << 2 | 2 << 4, + YZX = 2 | 0 << 2 | 1 << 4, + ZXY = 1 | 2 << 2 | 0 << 4, + ZYX = 2 | 1 << 2 | 0 << 4 + }; + + typedef enum _Order Order; + + StructuredData(const Vector3i &size); + + StructuredData(const StructuredData ©) : + m_DataOrder(copy.m_DataOrder), + m_Dims(copy.m_Dims), + m_Increments(copy.m_Increments) + {} + + + uLibGetMacro(Dims,Vector3i) + + void SetDims(const Vector3i &size); + + uLibGetSetMacro(Increments,Vector3i) + + void SetDataOrder(Order order = YXZ); + + uLibGetMacro(DataOrder,Order) + + bool IsInsideGrid(const Vector3i &v) const; + + inline int Map(Vector3i index) const; + + Vector3i UnMap(int index) const; + +private: + Order m_DataOrder; + Vector3i m_Dims; + Vector3i m_Increments; //TODO: make this line matrix // +}; + + + +// --- INLINES -------------------------------------------------------------- // + + +inline int StructuredData::Map(Vector3i index) const +{ + return (m_Increments.transpose() * index); +} + + + + + +} + +#endif // STRUCTUREDDATA_H diff --git a/src/Math/StructuredGrid.cpp b/src/Math/StructuredGrid.cpp new file mode 100644 index 0000000..fe81d2e --- /dev/null +++ b/src/Math/StructuredGrid.cpp @@ -0,0 +1,87 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "StructuredGrid.h" + +//namespace uLib { + +//ImageData::ImageData(const Vector3i size) : +// StructuredData(size) +//{} + +//void ImageData::SetSize(const Vector3f v) +//{ +// ContainerBox::SetSize( v.array() / this->GetDims().array().cast() ); +//} + +//Vector3f ImageData::GetSize() const +//{ +// return ContainerBox::GetSize().array() * this->GetDims().array().cast(); +//} + +//void ImageData::SetSpacing(const Vector3f spacing) +//{ +// ContainerBox::SetSize(spacing); +//} + +//Vector3f ImageData::GetSpacing() const +//{ +// return ContainerBox::GetSize(); +//} + + +//bool ImageData::IsInsideBounds(const Vector4f pt) const +//{ +// Vector4f ptl = this->GetLocalPoint(pt); +// int result = 0; +// for ( int i=0; i<3 ;++i) { +// result += ptl(i) > (float)this->GetDims()(i); +// result += ptl(i) < 0; +// } +// return result == 0; +//} + +//Vector3i ImageData::Find(const Vector4f pt) const +//{ +// Vector3i out; +// Vector4f p = GetLocalPoint(pt); +// out << (int)floor(p(0)), +// (int)floor(p(1)), +// (int)floor(p(2)); +// return out; +//} + +//void ImageData::PrintSelf(std::ostream &o) +//{ +// o << "uLib Structured Grid: \n" +// << "dim = " << this->GetDims().transpose() << "\n" +// << "spacing = " << this->GetSpacing().transpose() << "\n"; +//} + + +//} diff --git a/src/Math/StructuredGrid.h b/src/Math/StructuredGrid.h new file mode 100644 index 0000000..4e17a74 --- /dev/null +++ b/src/Math/StructuredGrid.h @@ -0,0 +1,65 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_MATH_STRUCTUREDGRID_H +#define U_MATH_STRUCTUREDGRID_H + +//#include "Core/Object.h" +//#include "Math/ContainerBox.h" +//#include "Math/StructuredData.h" + +//namespace uLib { + + +//class ImageData : public ContainerBox, public StructuredData { +// typedef ContainerBox BaseClass; +//public: +// ImageData(const Vector3i size); + +// using ContainerBox::SetOrigin; + +// void SetSize(const Vector3f v); + +// Vector3f GetSize() const; + +// void SetSpacing(const Vector3f spacing); + +// Vector3f GetSpacing() const; + +// bool IsInsideBounds(const Vector4f pt) const; + +// Vector3i Find(const Vector4f pt) const; + +// void PrintSelf(std::ostream &o); +//}; + + + + +//} + +#endif // STRUCTUREDGRID_H diff --git a/src/Math/Transform.h b/src/Math/Transform.h new file mode 100644 index 0000000..634f3a2 --- /dev/null +++ b/src/Math/Transform.h @@ -0,0 +1,141 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +/* + * Copyright (C) 2012 Andrea Rigoni Garola + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + + +#ifndef U_TRANSFORM_H +#define U_TRANSFORM_H + +#include +#include + + +namespace uLib { + +//////////////////////////////////////////////////////////////////////////////// +///////// AFFINE TRANSFORM WRAPPER ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +class AffineTransform { +protected: + Eigen::Affine3f m_T; + AffineTransform *m_Parent; +public: + AffineTransform() : + m_T(Matrix4f::Identity()), + m_Parent(NULL) + {} + + AffineTransform(AffineTransform *parent) : + m_T(Matrix4f::Identity()), + m_Parent(parent) + {} + + AffineTransform(const AffineTransform ©) : + m_T(copy.m_T), + m_Parent(copy.m_Parent) + {} + + Eigen::Affine3f& GetTransform() { return m_T; } + uLibGetSetMacro(Parent,AffineTransform *) + + inline void SetMatrix (Matrix4f &mat) { m_T.matrix() = mat; } + inline Matrix4f& GetMatrix () { return m_T.matrix(); } + + Matrix4f GetWorldMatrix() const + { + if(!m_Parent) return m_T.matrix(); + else return m_Parent->GetWorldMatrix() * m_T.matrix(); // T = B * A // + } + + inline void SetPosition(const Vector3f &v) { this->m_T.translation() = v; } + + inline Vector3f GetPosition() const { return this->m_T.translation(); } + + inline void SetRotation(const Matrix3f &m) { this->m_T.linear() = m; } + + inline Matrix3f GetRotation() const { return this->m_T.rotation(); } + + inline Vector3f GetOrientation(uint i0 = 0, uint i1 = 1, uint i2 = 2) const { return this->m_T.linear().eulerAngles(i0,i1,i2); } + + inline void Translate(const Vector3f &v) { this->m_T.translate(v); } + + inline void Scale(const Vector3f &v) { this->m_T.scale(v); } + + inline Vector3f GetScale() const { return this->m_T.linear() * Vector3f(1,1,1); } // FIXXXXXXX + + + inline void Rotate(const Matrix3f &m) { this->m_T.rotate(m); } + + + inline void PreRotate(const Matrix3f &m) { this->m_T.prerotate(m); } + + inline void QuaternionRotate(const Vector4f &q) + { this->m_T.rotate(Eigen::Quaternion(q)); } + + inline void EulerYZYRotate(const Vector3f &e) { + Matrix3f mat; + mat = Eigen::AngleAxisf(e.x(), Vector3f::UnitY()) + * Eigen::AngleAxisf(e.y(), Vector3f::UnitZ()) + * Eigen::AngleAxisf(e.z(), Vector3f::UnitY()); + m_T.rotate(mat); + } + + inline void FlipAxes(int first, int second) + { + Matrix3f mat = Matrix3f::Identity(); + mat.col(first).swap(mat.col(second)); + m_T.rotate(mat); + } +}; + + + +} + + + +#endif//U_TRANSFORM_H diff --git a/src/Math/TriangleMesh.cpp b/src/Math/TriangleMesh.cpp new file mode 100644 index 0000000..d8828ef --- /dev/null +++ b/src/Math/TriangleMesh.cpp @@ -0,0 +1,69 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "TriangleMesh.h" + + +namespace uLib { + +void TriangleMesh::PrintSelf(std::ostream &o) +{ + o << " // ------- TRIANGLE MESH ------- // \n" ; + o << " #Points : " << m_Points.size() << "\n"; + o << " #Triang : " << m_Triangles.size() << "\n"; + for(int i=0; i < m_Triangles.size(); ++i ) { + o << " - triangle[" << i << "]" << + " " << m_Triangles[i](0) << + "->(" << m_Points[m_Triangles[i](0)].transpose() << ") " << + " " << m_Triangles[i](1) << + "->(" << m_Points[m_Triangles[i](1)].transpose() << ") " << + " " << m_Triangles[i](2) << + "->(" << m_Points[m_Triangles[i](2)].transpose() << ") " << + " \n"; + } + o << " // ----------------------------- // \n"; +} + +void TriangleMesh::AddPoint(const Vector3f &pt) +{ + this->m_Points.push_back(pt); +} + +void TriangleMesh::AddTriangle(const Id_t *id) +{ + Vector3i triangle(id[0],id[1],id[2]); + this->m_Triangles.push_back(triangle); +} + +void TriangleMesh::AddTriangle(const Vector3i &id) +{ + this->m_Triangles.push_back(id); +} + + +} diff --git a/src/Math/TriangleMesh.h b/src/Math/TriangleMesh.h new file mode 100644 index 0000000..0fdebac --- /dev/null +++ b/src/Math/TriangleMesh.h @@ -0,0 +1,59 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef TRIANGLEMESH_H +#define TRIANGLEMESH_H + +#include "Core/Object.h" +#include "Core/Vector.h" +#include "Math/Dense.h" + +namespace uLib { + +class TriangleMesh : public Object { + +public: + void PrintSelf(std::ostream &o); + + void AddPoint(const Vector3f &pt); + + void AddTriangle(const Id_t *id); + void AddTriangle(const Vector3i &id); + + uLibRefMacro(Points,Vector) + uLibRefMacro(Triangles,Vector) + +private: + Vector m_Points; + Vector m_Triangles; + +}; + +} + + +#endif // TRIANGLEMESH_H diff --git a/src/Math/Utils.h b/src/Math/Utils.h new file mode 100644 index 0000000..99334b2 --- /dev/null +++ b/src/Math/Utils.h @@ -0,0 +1,50 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_UTILS_H +#define U_UTILS_H + +#include +#include +#include + +#define fastSign(x) ((x>0)-(x<0)) + +namespace uLib { + +inline bool isFinite(float x) { + return (x<=FLT_MAX && x>= -FLT_MAX); +} + +inline bool isFinite(double x) { + return (x<=DBL_MAX && x>= -DBL_MAX); +} + + +} + +#endif // UTILS_H diff --git a/src/Math/VectorSpace.h b/src/Math/VectorSpace.h new file mode 100644 index 0000000..f45146f --- /dev/null +++ b/src/Math/VectorSpace.h @@ -0,0 +1,70 @@ +#ifndef U_GEO_VECTORSPACE_H +#define U_GEO_VECTORSPACE_H + +#include "Core/Macros.h" +#include "Core/Mpl.h" + +#include "Math/Dense.h" +#include "Math/Line.h" + + + +//#include "boost/geometry.hpp" +//#include "boost/geometry/geometries/adapted/c_array.hpp" +//#include "boost/geometry/geometries/adapted/boost_array.hpp" +//#include "boost/geometry/geometries/adapted/std_pair_as_segment.hpp" + +//#include "boost/geometry/geometries/register/point.hpp" +//#include "boost/geometry/geometries/register/linestring.hpp" + + +namespace uLib { + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// VECTOR SPACE //////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////////// +// VECTOR UTILS //////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +inline Vector4f HVector3f(float x, float y, float z) { return Vector4f(x,y,z,0); } +inline Vector4f HVector3f(const Vector4f &v) { return Vector4f(v(0),v(1),v(2),0); } + +inline Vector4f HPoint3f(float x, float y, float z) { return Vector4f(x,y,z,1); } +inline Vector4f HPoint3f(const Vector4f &v) { return Vector4f(v(0),v(1),v(2),1); } + + +// this is an example of function imported from eigen // +//using boost::geometry::distance; + +} // uLib + + + +// BOOST GEOMETRY REGISTRATION // + +//BOOST_GEOMETRY_REGISTER_POINT_2D(uLib::Vector2i, int, boost::geometry::cs::cartesian, operator()(0), operator()(1)) +//BOOST_GEOMETRY_REGISTER_POINT_3D(uLib::Vector3i, int, boost::geometry::cs::cartesian, operator()(0), operator()(1), operator()(2)) +//BOOST_GEOMETRY_REGISTER_POINT_3D(uLib::Vector4i, int, boost::geometry::cs::cartesian, operator()(0), operator()(1), operator()(2)) + +//BOOST_GEOMETRY_REGISTER_POINT_2D(uLib::Vector2f, float, boost::geometry::cs::cartesian, operator()(0), operator()(1)) +//BOOST_GEOMETRY_REGISTER_POINT_3D(uLib::Vector3f, float, boost::geometry::cs::cartesian, operator()(0), operator()(1), operator()(2)) +//BOOST_GEOMETRY_REGISTER_POINT_3D(uLib::Vector4f, float, boost::geometry::cs::cartesian, operator()(0), operator()(1), operator()(2)) + +//BOOST_GEOMETRY_REGISTER_POINT_2D(uLib::Vector2d, double, boost::geometry::cs::cartesian, operator()(0), operator()(1)) +//BOOST_GEOMETRY_REGISTER_POINT_3D(uLib::Vector3d, double, boost::geometry::cs::cartesian, operator()(0), operator()(1), operator()(2)) +//BOOST_GEOMETRY_REGISTER_POINT_3D(uLib::Vector4d, double, boost::geometry::cs::cartesian, operator()(0), operator()(1), operator()(2)) + + + + + +#endif // VECTORSPACE_H diff --git a/src/Math/VoxImage.cpp b/src/Math/VoxImage.cpp new file mode 100644 index 0000000..a73f94e --- /dev/null +++ b/src/Math/VoxImage.cpp @@ -0,0 +1,192 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include +#include + +#include "VoxImage.h" + + +namespace uLib { + +void Abstract::VoxImage::ExportToVtk (const char *file, bool density_type) +{ + FILE * vtk_file = fopen(file,"wb"); + assert(vtk_file); + Abstract::VoxImage *voxels = this; + float norm; + if (density_type) { + norm = 40000; + } else norm = 1.E6; + int nx = voxels->GetDims()(0); + int ny = voxels->GetDims()(1); + int nz = voxels->GetDims()(2); + + fprintf(vtk_file, + "# vtk DataFile Version 2.0\n" + "Image Builder vtk output\n" + "ASCII\n" + "DATASET STRUCTURED_POINTS\n" + "DIMENSIONS %d %d %d\n" + "SPACING %f %f %f\n" + "ORIGIN %f %f %f\n" + "POINT_DATA %d\n" + "SCALARS volume_scalars float 1\n" + "LOOKUP_TABLE default\n", + nx , ny , nz , + voxels->GetSpacing()(0), + voxels->GetSpacing()(1), + voxels->GetSpacing()(2), + voxels->GetPosition()(0), // FIX FOR ORIGIN // + voxels->GetPosition()(1), + voxels->GetPosition()(2), + nx * ny * nz + ); + + Vector3i index(0,0,0); + for (int zv = 0; zv < nz; ++zv) { + for (int yv = 0; yv < ny; ++yv) { + for (int xv = 0; xv < nx; ++xv) { + index << xv,yv,zv; + // write voxel density in mrad^2/cm // + float density = fabs(voxels->GetValue(index)) * norm; + fprintf(vtk_file, "%f ", density); + } + } + } + + fclose(vtk_file); + printf("%s vtk file saved\n",file); +} + +int Abstract::VoxImage::ImportFromVtk(const char *file) +{ + FILE * vtk_file = fopen(file, "r"); + if (!vtk_file) return false; + + char word[20]; + int dx, dy, dz, n_tot; + float sx, sy, sz, ox, oy, oz; + do { + fscanf(vtk_file, "%s", word); + } while (strcmp(word, "DIMENSIONS")); + fscanf(vtk_file, "%d %d %d", &dx, &dy, &dz); + do { + fscanf(vtk_file, "%s", word); + } while (strcmp(word, "SPACING")); + fscanf(vtk_file, "%f %f %f", &sx, &sy, &sz); + do { + fscanf(vtk_file, "%s", word); + } while (strcmp(word, "ORIGIN")); + fscanf(vtk_file, "%f %f %f", &ox, &oy, &oz); + do { + fscanf(vtk_file, "%s", word); + } while (strcmp(word, "POINT_DATA")); + fscanf(vtk_file, "%d", &n_tot); + do { + fscanf(vtk_file, "%s", word); + } while (strcmp(word, "default")); + + this->SetDims(Vector3i(dx,dy,dz)); + this->SetSpacing(Vector3f(sx,sy,sz)); + this->SetPosition(Vector3f(ox,oy,oz)); + + for (int k = 0; k < dz; ++k) { + for (int j = 0; j < dy; ++j) { + for (int i = 0; i < dx; ++i) { + Vector3i idx(i, j, k); + float tmp_val; + fscanf(vtk_file, "%f", &tmp_val); + this->SetValue(idx,fabs(tmp_val)*1E-6); + } + } + } + fclose(vtk_file); + return true; +} + +void Abstract::VoxImage::ExportToVtkXml(const char *file, bool density_type) +{ + // Not implemented yet // + FILE * vtk_file = fopen(file,"wb"); + assert(vtk_file); + Abstract::VoxImage *voxels = this; + float norm; + if (density_type) { + norm = 40000; + } else norm = 1.E6; + int nx = voxels->GetDims()(0); + int ny = voxels->GetDims()(1); + int nz = voxels->GetDims()(2); + + fprintf(vtk_file, + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + "\n", + nx, ny, nz, + voxels->GetPosition()(0), // FIX FOR ORIGIN // + voxels->GetPosition()(1), + voxels->GetPosition()(2), + voxels->GetSpacing()(0), + voxels->GetSpacing()(1), + voxels->GetSpacing()(2), + nx, ny, nz + ); + Vector3i index(0,0,0); + for (int zv = 0; zv < nz; ++zv) { + for (int yv = 0; yv < ny; ++yv) { + for (int xv = 0; xv < nx; ++xv) { + index << xv,yv,zv; + // write voxel density in mrad^2/cm // + float density = fabs(voxels->GetValue(index)) * norm; + fprintf(vtk_file, "%f ", density); + } + } + } + fprintf(vtk_file, + "\n \n \n"); + + fprintf(vtk_file, + "\n \n \n"); + fclose(vtk_file); + printf("%s vtk file saved\n",file); +} + + + + +} + diff --git a/src/Math/VoxImage.h b/src/Math/VoxImage.h new file mode 100644 index 0000000..d845949 --- /dev/null +++ b/src/Math/VoxImage.h @@ -0,0 +1,286 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_MATH_VOXIMAGE_H +#define U_MATH_VOXIMAGE_H + +#include "Core/Vector.h" +#include "Core/StaticInterface.h" +#include "Math/Dense.h" +#include "Math/ImageData.h" + +#include +#include + +namespace uLib { + + + + +//////////////////////////////////////////////////////////////////////////////// +// ABSTRACT VOX IMAGE ////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace Abstract { +class VoxImage : public uLib::ImageData { +public: + typedef uLib::ImageData BaseClass; + + virtual float GetValue(const Vector3i id) const = 0; + virtual float GetValue(const int id) const = 0; + virtual void SetValue(const Vector3i id, float value) = 0; + virtual void SetValue(const int id, float value) = 0; + + virtual void SetDims(const Vector3i &size) = 0; + + void ExportToVtk(const char *file, bool density_type = 0); + void ExportToVtkXml(const char *file, bool density_type = 0); + int ImportFromVtk(const char *file); + +protected: + + virtual ~VoxImage() {} + VoxImage(const Vector3i &size) : BaseClass(size) {} +}; +} + +//////////////////////////////////////////////////////////////////////////////// +// VOXEL //////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +struct Voxel { + Scalarf Value; + float & operator()() { return Value; } + const float & operator()() const { return Value; } +}; + +template +std::basic_ostream & operator << (std::basic_ostream &o, const Voxel &v) { + o << v.Value; + return o; +} + + +//////////////////////////////////////////////////////////////////////////////// +// VOX IMAGE ///////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +template< typename T > +class VoxImage : public Abstract::VoxImage { +public: + typedef Abstract::VoxImage BaseClass; + + VoxImage(); + + VoxImage(const Vector3i &size); + + VoxImage(const VoxImage ©) : + BaseClass(copy) + { + this->m_Data = copy.m_Data; + } + + uLibRefMacro(Data,Vector) + inline const Vector& ConstData() const { return m_Data; } + + inline const T& At(int i) const { return m_Data.at(i); } + inline const T& At(const Vector3i &id) const { return m_Data.at(Map(id)); } + inline T& At(int i) { return m_Data.at(i); } + inline T& At(const Vector3i &id) { return m_Data.at(Map(id)); } + + inline const T& operator[](unsigned int i) const { return m_Data[i]; } + inline const T& operator[](const Vector3i &id) const { return m_Data[Map(id)]; } + inline T& operator[](unsigned int i) { return m_Data[i]; } + inline T& operator[](const Vector3i &id) { return m_Data[Map(id)]; } + + // this implements Abstract interface // + inline Scalarf GetValue(const Vector3i id) const { return this->At(id)(); } + inline Scalarf GetValue(const int id) const { return this->At(id)(); } + inline void SetValue(const Vector3i id, Scalarf value) { this->operator [](id)() = value; } + inline void SetValue(const int id, float value) { this->operator [](id)() = value; } + + inline void SetDims(const Vector3i &size) { + this->m_Data.resize(size.prod()); + StructuredData::SetDims(size); + } + + inline VoxImage clipImage(const Vector3i begin, const Vector3i end) const; + + inline VoxImage clipImage(const Vector4f begin, const Vector4f end) const; + + inline VoxImage clipImage(const float density) const; + + inline void SelectScalarfComponent(T &element, Scalarf *scalar); + + inline void InitVoxels(T t); + + + // MATH OPERATORS // + inline void operator *=(Scalarf scalar) { + for(unsigned int i = 0; i < m_Data.size(); ++i) + m_Data[i].Value *= scalar; + } + inline void operator +=(Scalarf scalar) { + for(unsigned int i = 0; i < m_Data.size(); ++i) + m_Data[i].Value += scalar; + } + inline void operator /=(Scalarf scalar) { + for(unsigned int i = 0; i < m_Data.size(); ++i) + m_Data[i].Value /= scalar; + } + inline void operator -=(Scalarf scalar) { + for(unsigned int i = 0; i < m_Data.size(); ++i) + m_Data[i].Value -= scalar; + } + + // MATH VoxImage Operators // + template + void operator +=(VoxImage &sibling) { + if (this->GetDims() != sibling.GetDims()) { + //printf("Warning when adding VoxImages: I'm NOT doing it!\n"); + return; + }// WARNING! You must Warn the user! + for(unsigned int i = 0; i < m_Data.size(); ++i) { + m_Data[i].Value += sibling.At(i).Value; + } + } + + template + void operator -=(VoxImage &sibling) { + if (this->GetDims() != sibling.GetDims()) { + //printf("Warning when subtracting VoxImages: I'm NOT doing it!\n"); + return; + }// WARNING! You must Warn the user! + for(unsigned int i = 0; i < m_Data.size(); ++i) { + m_Data[i].Value -= sibling.At(i).Value; + } + } + + template + void operator *=(VoxImage &sibling) { + if (this->GetDims() != sibling.GetDims()) { + //printf("Warning when multiplying VoxImages: I'm NOT doing it!\n"); + return; + }// WARNING! You must Warn the user! + for(unsigned int i = 0; i < m_Data.size(); ++i) { + m_Data[i].Value *= sibling.At(i).Value; + } + } + + template + void operator /=(VoxImage &sibling) { + if (this->GetDims() != sibling.GetDims()) { + //printf("Warning when dividing VoxImages: I'm NOT doing it!\n"); + return; + }// WARNING! You must Warn the user! + for(unsigned int i = 0; i < m_Data.size(); ++i) { + m_Data[i].Value /= sibling.At(i).Value; + } + } + +private: + Vector m_Data; +}; + + +template +VoxImage::VoxImage() : + m_Data(0), + BaseClass(Vector3i(0,0,0)) {} +//{ Interface::IsA (); /* structural check for T */ } + +template +VoxImage::VoxImage(const Vector3i &size) : + m_Data(size.prod()), + BaseClass(size) {} +//{ Interface::IsA (); /* structural check for T */ } + + +template +VoxImage VoxImage::clipImage(const Vector3i begin, const Vector3i end) const +{ + Vector3i dim = (end-begin)+Vector3i(1,1,1); + VoxImage out(*this); + out.SetDims(dim); + // WARNING Origin or Position??? + out.SetPosition(this->GetPosition() + this->GetSpacing().cwiseProduct(begin.cast()) ); + + for(uint x = 0; xAt(begin + id); + } + return out; +} + +template +VoxImage VoxImage::clipImage(const Vector4f begin, const Vector4f end) const +{ + Vector3i v1 = this->Find(begin); + Vector3i v2 = this->Find(end); + return this->clipImage(v1,v2); +} + +template +VoxImage VoxImage::clipImage(const float density) const +{ + Vector3i v1 = this->GetDims(); + Vector3i v2 = Vector3i(0,0,0); + for(uint i=0; i< this->m_Data.size(); ++i) { + if( this->GetValue(i) >= density ) { + Vector3i id = this->UnMap(i); + v1 = v1.array().min(id.array()); + v2 = v2.array().max(id.array()); + } + } + return this->clipImage(v1,v2); +} + + +template +void VoxImage::InitVoxels(T t) +{ + std::fill( m_Data.begin(), m_Data.end(), t ); // warning... stl function // +} + + + + + +} // uLib + + + + + + + +#endif // VOXIMAGE_H diff --git a/src/Math/VoxImageFilter.h b/src/Math/VoxImageFilter.h new file mode 100644 index 0000000..c9fcf9d --- /dev/null +++ b/src/Math/VoxImageFilter.h @@ -0,0 +1,129 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VOXIMAGEFILTER_H +#define VOXIMAGEFILTER_H + +#include "Core/StaticInterface.h" +#include "Core/Object.h" +#include "Math/Dense.h" + +#include "Math/VoxImage.h" + + +namespace uLib { + + +namespace Interface { +struct VoxImageFilterShape { + template void check_structural() { + uLibCheckFunction(Self,operator(),float,float); + uLibCheckFunction(Self,operator(),float,const Vector3f&); + } +}; +} + +template < typename VoxelT > class Kernel; + + +namespace Abstract { +class VoxImageFilter { +public: + virtual void Run() = 0; + + virtual void SetImage(Abstract::VoxImage *image) = 0; + +protected: + virtual ~VoxImageFilter() {} +}; +} + + +template < typename VoxelT, typename AlgorithmT > +class VoxImageFilter : public Abstract::VoxImageFilter, public Object +{ + +public: + VoxImageFilter(const Vector3i &size); + + void Run(); + + void SetKernelNumericXZY(const Vector &numeric); + + void SetKernelSpherical(float (*shape)(float)); + + template < class ShapeT > + void SetKernelSpherical( ShapeT shape ); + + void SetKernelWeightFunction(float (*shape)(const Vector3f &)); + + template < class ShapeT > + void SetKernelWeightFunction( ShapeT shape ); + + uLibGetMacro(KernelData,Kernel) + + uLibGetMacro(Image,VoxImage *) + + void SetImage(Abstract::VoxImage *image); + +protected: + + float Convolve(const VoxImage &buffer, int index); // remove // + + void SetKernelOffset(); + + float Distance2(const Vector3i &v); + + // protected members for algorithm access // + Kernel m_KernelData; + VoxImage *m_Image; + +private: + AlgorithmT *t_Algoritm; + +}; + + + + + + +} + + +#endif // VOXIMAGEFILTER_H + +#include "VoxImageFilter.hpp" + +#include "VoxImageFilterLinear.hpp" +#include "VoxImageFilterThreshold.hpp" +#include "VoxImageFilterMedian.hpp" +#include "VoxImageFilterABTrim.hpp" +#include "VoxImageFilterBilateral.hpp" +#include "VoxImageFilter2ndStat.hpp" +#include "VoxImageFilterCustom.hpp" + diff --git a/src/Math/VoxImageFilter.hpp b/src/Math/VoxImageFilter.hpp new file mode 100644 index 0000000..621c208 --- /dev/null +++ b/src/Math/VoxImageFilter.hpp @@ -0,0 +1,302 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VOXIMAGEFILTER_HPP +#define VOXIMAGEFILTER_HPP + +#include +#include "Math/StructuredData.h" +#include "Math/VoxImage.h" +#include "VoxImageFilter.h" + +namespace uLib { + + +// KERNEL ////////////////////////////////////////////////////////////////////// + +template < typename T > +class Kernel : public StructuredData { + typedef StructuredData BaseClass; +public: + Kernel(const Vector3i &size); + + inline T& operator[](const Vector3i &id) { return m_Data[Map(id)]; } + inline T& operator[](const int &id) { return m_Data[id]; } + inline int GetCenterData() const; + + uLibRefMacro(Data,Vector) + + inline const Vector& ConstData() const { return this->m_Data; } + + void PrintSelf(std::ostream &o) const; + +private: + Vector m_Data; +}; + +template < typename T > +Kernel::Kernel(const Vector3i &size) : + BaseClass(size), + m_Data(size.prod()) +{ + Interface::IsA(); +} + +template < typename T > +inline int Kernel::GetCenterData() const +{ + static int center = Map(this->GetDims() / 2); + return center; +} + +template < typename T > +void Kernel::PrintSelf(std::ostream &o) const +{ + o << " Filter Kernel Dump [XZ_Y]: \n"; + Vector3i index; + o << "\n Value: \n\n" + << "------------------------------------------------- \n"; + for (int y = 0 ; y < this->GetDims()(1); ++y ) { + o << "[y=" << y << "]\n"; + for (int z = 0 ; z < this->GetDims()(2); ++z ) { + for (int x = 0 ; x < this->GetDims()(0); ++x ) { + index << x,y,z; + o << m_Data[Map(index)].Value << " "; + } o << "\n"; + } o << " --------------------------------------------------- \n"; + } + o << "\n Offset: \n" + << "------------------------------------------------- \n"; + for (int y = 0 ; y < this->GetDims()(1); ++y ) { + o << "[y=" << y << "]\n"; + for (int z = 0 ; z < this->GetDims()(2); ++z ) { + for (int x = 0 ; x < this->GetDims()(0); ++x ) { + index << x,y,z; + o << m_Data[Map(index)].Count << " "; + } o << "\n"; + } o << " --------------------------------------------------- \n"; + } +} + +//////////////////////////////////////////////////////////////////////////////// + + + + + + + + +#define _TPL_ template < typename VoxelT , typename AlgorithmT > +#define _TPLT_ VoxelT,AlgorithmT + + + +_TPL_ +VoxImageFilter<_TPLT_>::VoxImageFilter(const Vector3i &size) : + m_KernelData(size), + t_Algoritm(static_cast(this)) +{ + +} + +_TPL_ +void VoxImageFilter<_TPLT_>::Run() +{ + VoxImage buffer = *m_Image; + #pragma omp parallel for + for(int i=0 ; i < m_Image->Data().size() ; ++i) + m_Image->operator [](i).Value = this->t_Algoritm->Evaluate(buffer,i); + #pragma omp barrier +} + +_TPL_ +void VoxImageFilter<_TPLT_>::SetKernelOffset() +{ + Vector3i id(0,0,0); + for( int z=0 ; z < m_KernelData.GetDims()(2); ++z ) { + for( int x=0 ; x < m_KernelData.GetDims()(0); ++x ) { + for( int y=0 ; y < m_KernelData.GetDims()(1); ++y ) { + id << x,y,z; + m_KernelData[id].Count = id.transpose() * m_Image->GetIncrements(); + } + } + } +} + +_TPL_ +float VoxImageFilter<_TPLT_>::Distance2(const Vector3i &v) +{ + Vector3i tmp = v; + const Vector3i &dim = this->m_KernelData.GetDims(); + Vector3i center = dim / 2; + tmp = tmp - center; + center = center.cwiseProduct(center); + tmp = tmp.cwiseProduct(tmp); + return (float)(tmp.sum()) / (float)( center.sum() + 0.25 * + (3 - (dim(0) % 2) - (dim(1) % 2) - (dim(2) % 2))); +} + + +_TPL_ +void VoxImageFilter<_TPLT_>::SetKernelNumericXZY(const Vector &numeric) +{ + // set data order // + StructuredData::Order order = m_KernelData.GetDataOrder(); + //m_KernelData.SetDataOrder(StructuredData::XZY); + Vector3i id; + int index = 0; + for( int y=0 ; y < m_KernelData.GetDims()(1); ++y ) { + for( int z=0 ; z < m_KernelData.GetDims()(2); ++z ) { + for( int x=0 ; x < m_KernelData.GetDims()(0); ++x ) { + id << x,y,z; + m_KernelData[id].Value = numeric[index++]; + } + } + } + //m_KernelData.SetDataOrder(order); +} + +_TPL_ +void VoxImageFilter<_TPLT_>::SetKernelSpherical(float(* shape)(float)) +{ + Vector3i id; + for( int y=0 ; y < m_KernelData.GetDims()(1); ++y ) { + for( int z=0 ; z < m_KernelData.GetDims()(2); ++z ) { + for( int x=0 ; x < m_KernelData.GetDims()(0); ++x ) { + id << x,y,z; + m_KernelData[id].Value = shape(this->Distance2(id)); + } + } + } +} + + +_TPL_ template +void VoxImageFilter<_TPLT_>::SetKernelSpherical(ShapeT shape) +{ + Interface::IsA(); + Vector3i id; + for( int y=0 ; y < m_KernelData.GetDims()(1); ++y ) { + for( int z=0 ; z < m_KernelData.GetDims()(2); ++z ) { + for( int x=0 ; x < m_KernelData.GetDims()(0); ++x ) { + id << x,y,z; + m_KernelData[id].Value = shape(this->Distance2(id)); + } + } + } +} + +_TPL_ +void VoxImageFilter<_TPLT_>::SetKernelWeightFunction(float (*shape)(const Vector3f &)) +{ + const Vector3i &dim = m_KernelData.GetDims(); + Vector3i id; + Vector3f pt; + for( int y=0 ; y < dim(1); ++y ) { + for( int z=0 ; z < dim(2); ++z ) { + for( int x=0 ; x < dim(0); ++x ) { + // get voxels centroid coords from kernel center // + id << x,y,z; + pt << id(0) - dim(0)/2 + 0.5 * !(dim(0) % 2), + id(1) - dim(1)/2 + 0.5 * !(dim(1) % 2), + id(2) - dim(2)/2 + 0.5 * !(dim(2) % 2); + // compute function using given shape // + m_KernelData[id].Value = shape(pt); + } + } + } +} + +_TPL_ template < class ShapeT > +void VoxImageFilter<_TPLT_>::SetKernelWeightFunction(ShapeT shape) +{ + Interface::IsA(); + const Vector3i &dim = m_KernelData.GetDims(); + Vector3i id; + Vector3f pt; + for( int y=0 ; y < dim(1); ++y ) { + for( int z=0 ; z < dim(2); ++z ) { + for( int x=0 ; x < dim(0); ++x ) { + // get voxels centroid coords from kernel center // + id << x,y,z; + pt << id(0) - dim(0)/2 + 0.5 * !(dim(0) % 2), + id(1) - dim(1)/2 + 0.5 * !(dim(1) % 2), + id(2) - dim(2)/2 + 0.5 * !(dim(2) % 2); + // compute function using given shape // + m_KernelData[id].Value = shape(pt); + } + } + } +} + + + + +_TPL_ +void VoxImageFilter<_TPLT_>::SetImage(Abstract::VoxImage *image) +{ + this->m_Image = reinterpret_cast *> (image); + this->SetKernelOffset(); +} + + +_TPL_ +float VoxImageFilter<_TPLT_>::Convolve(const VoxImage &buffer, int index) +{ + const Vector &vbuf = buffer.ConstData(); + const Vector &vker = m_KernelData.ConstData(); + int vox_size = vbuf.size(); + int ker_size = vker.size(); + int pos; + float conv = 0, ksum = 0; + for (int ik = 0; ik < ker_size; ++ik) { + pos = index + vker[ik].Count - vker[m_KernelData.GetCenterData()].Count; + pos = (pos + vox_size) % vox_size; + conv += vbuf[pos].Value * vker[ik].Value; + ksum += vker[ik].Value; + } + return conv / ksum; +} + + + +#undef _TPLT_ +#undef _TPL_ + + + + + + + +} + + + + +#endif // VOXIMAGEFILTER_HPP diff --git a/src/Math/VoxImageFilter2ndStat.hpp b/src/Math/VoxImageFilter2ndStat.hpp new file mode 100644 index 0000000..d85acc7 --- /dev/null +++ b/src/Math/VoxImageFilter2ndStat.hpp @@ -0,0 +1,83 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VOXIMAGEFILTER2NDSTAT_HPP +#define VOXIMAGEFILTER2NDSTAT_HPP + +#include +#include "Math/VoxImage.h" +#include "VoxImageFilter.h" + +//////////////////////////////////////////////////////////////////////////////// +///// VOXIMAGE FILTER ABTRIM ///////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace uLib { + +template +class VoxFilterAlgorithm2ndStat : + public VoxImageFilter > { + +public: + typedef VoxImageFilter > BaseClass; + VoxFilterAlgorithm2ndStat(const Vector3i &size) : + BaseClass(size) + { } + + float Evaluate(const VoxImage &buffer, int index) + { + const Vector &vbuf = buffer.ConstData(); + const Vector &vker = this->m_KernelData.ConstData(); + int vox_size = vbuf.size(); + int ker_size = vker.size(); + int pos; + + // mean // + float conv = 0, ksum = 0; + for (int ik = 0; ik < ker_size; ++ik) { + pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; + pos = (pos + vox_size) % vox_size; + conv += vbuf[pos].Value * vker[ik].Value; + ksum += vker[ik].Value; + } + float mean = conv / ksum; + + // rms // + conv = 0; + for (int ik = 0; ik < ker_size; ++ik) { + pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; + pos = (pos + vox_size) % vox_size; + conv += pow((vbuf[pos].Value * vker[ik].Value) - mean , 2); + } + return conv / (vker.size() - 1) ; + } + + +}; + +} +#endif // VOXIMAGEFILTER2NDSTAT_HPP diff --git a/src/Math/VoxImageFilterABTrim.hpp b/src/Math/VoxImageFilterABTrim.hpp new file mode 100644 index 0000000..0b1799c --- /dev/null +++ b/src/Math/VoxImageFilterABTrim.hpp @@ -0,0 +1,179 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VOXIMAGEFILTERABTRIM_HPP +#define VOXIMAGEFILTERABTRIM_HPP + +#include +#include "Math/VoxImage.h" +#include "VoxImageFilter.h" + +//////////////////////////////////////////////////////////////////////////////// +///// VOXIMAGE FILTER ABTRIM ///////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace uLib { + +template +class VoxFilterAlgorithmAbtrim : + public VoxImageFilter > { + + struct KernelSortAscending + { + bool operator()(const VoxelT& e1, const VoxelT& e2) + { return e1.Value < e2.Value; } + }; + +public: + typedef VoxImageFilter > BaseClass; + VoxFilterAlgorithmAbtrim(const Vector3i &size) : + BaseClass(size) + { + mAtrim = 0; + mBtrim = 0; + } + + float Evaluate(const VoxImage &buffer, int index) + { + const Vector &vbuf = buffer.ConstData(); + const Vector &vker = this->m_KernelData.ConstData(); + int vox_size = vbuf.size(); + int ker_size = vker.size(); + int pos; + + Vector mfh(ker_size); + for (int i = 0; i < ker_size; ++i) + mfh[i].Count = i; //index key for ordering function + for (int ik = 0; ik < ker_size; ik++) { + pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; + pos = (pos + vox_size) % vox_size; + mfh[ik].Value = vbuf[pos].Value; + } + + std::sort(mfh.begin(), mfh.end(), KernelSortAscending()); + float ker_sum = 0; + float fconv = 0; + for (int ik = 0; ik < mAtrim; ik++) + ker_sum += vker[ mfh[ik].Count ].Value; + for (int ik = mAtrim; ik < ker_size - mBtrim; ik++) { + fconv += mfh[ik].Value * vker[ mfh[ik].Count ].Value; // convloution // + ker_sum += vker[ mfh[ik].Count ].Value; + } + for (int ik = ker_size - mBtrim; ik < ker_size; ik++) + ker_sum += vker[ mfh[ik].Count ].Value; + + return fconv / ker_sum; + } + + inline void SetABTrim(int a, int b) { mAtrim = a; mBtrim = b; } + +private: + int mAtrim; + int mBtrim; +}; + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// Roberspierre Filter // + + + +template +class VoxFilterAlgorithmSPR : + public VoxImageFilter > { + + struct KernelSortAscending + { + bool operator()(const VoxelT& e1, const VoxelT& e2) + { return e1.Value < e2.Value; } + }; + +public: + typedef VoxImageFilter > BaseClass; + VoxFilterAlgorithmSPR(const Vector3i &size) : + BaseClass(size) + { + mAtrim = 0; + mBtrim = 0; + } + + float Evaluate(const VoxImage &buffer, int index) + { + const Vector &vbuf = buffer.ConstData(); + const Vector &vker = this->m_KernelData.ConstData(); + int vox_size = vbuf.size(); + int ker_size = vker.size(); + int pos; + + Vector mfh(ker_size); + for (int i = 0; i < ker_size; ++i) + mfh[i].Count = i; //index key for ordering function + for (int ik = 0; ik < ker_size; ik++) { + pos = index + vker[ik].Count - + vker[this->m_KernelData.GetCenterData()].Count; + pos = (pos + vox_size) % vox_size; + mfh[ik].Value = vbuf[pos].Value; + } + + std::sort(mfh.begin(), mfh.end(), KernelSortAscending()); + float spr = vbuf[index].Value; + if( (mAtrim > 0 && spr <= mfh[mAtrim-1].Value) || + (mBtrim > 0 && spr >= mfh[ker_size - mBtrim].Value) ) + { + float ker_sum = 0; + float fconv = 0; + for (int ik = 0; ik < mAtrim; ik++) + ker_sum += vker[ mfh[ik].Count ].Value; + for (int ik = mAtrim; ik < ker_size - mBtrim; ik++) { + fconv += mfh[ik].Value * vker[ mfh[ik].Count ].Value; + ker_sum += vker[ mfh[ik].Count ].Value; + } + for (int ik = ker_size - mBtrim; ik < ker_size; ik++) + ker_sum += vker[ mfh[ik].Count ].Value; + + return fconv / ker_sum; + } + else + return spr; + } + + inline void SetABTrim(int a, int b) { mAtrim = a; mBtrim = b; } + +private: + int mAtrim; + int mBtrim; +}; + + + + +} + +#endif // VOXIMAGEFILTERABTRIM_HPP diff --git a/src/Math/VoxImageFilterBilateral.hpp b/src/Math/VoxImageFilterBilateral.hpp new file mode 100644 index 0000000..ade0f6e --- /dev/null +++ b/src/Math/VoxImageFilterBilateral.hpp @@ -0,0 +1,152 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VOXIMAGEFILTERBILATERAL_HPP +#define VOXIMAGEFILTERBILATERAL_HPP + +#include +#include "Math/VoxImage.h" +#include "VoxImageFilter.h" + +//////////////////////////////////////////////////////////////////////////////// +///// VOXIMAGE FILTER LINEAR ///////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace uLib { + + +template +class VoxFilterAlgorithmBilateral : + public VoxImageFilter > { +public: + typedef VoxImageFilter > BaseClass; + VoxFilterAlgorithmBilateral(const Vector3i &size) : BaseClass(size) { + m_sigma = 1; + } + + float Evaluate(const VoxImage &buffer, int index) + { + const Vector &vbuf = buffer.ConstData(); + const Vector &vker = this->m_KernelData.ConstData(); + int vox_size = vbuf.size(); + int ker_size = vker.size(); + int pos; + float conv = 0, ksum = 0; + float gamma_smooth; + for (int ik = 0; ik < ker_size; ++ik) { + // if (ik==this->m_KernelData.GetCenterData()) continue; + pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; + pos = (pos + vox_size) % vox_size; + gamma_smooth = compute_gauss( fabs(vbuf[index].Value - vbuf[pos].Value) * 1.E6 ); + conv += vbuf[pos].Value * vker[ik].Value * gamma_smooth; + ksum += vker[ik].Value * gamma_smooth; + } + return conv / ksum; + } + + inline void SetIntensitySigma(const float s) { m_sigma = s; } + +private: + inline float compute_gauss(const float x) { + return 1/(sqrt(2*M_PI)* m_sigma) * exp(-0.5*(x*x)/(m_sigma*m_sigma)); + } + + Scalarf m_sigma; +}; + + +template +class VoxFilterAlgorithmBilateralTrim : + public VoxImageFilter > { + + typedef std::pair FPair; + + struct KernelSortAscending + { + bool operator()(const FPair& e1, const FPair& e2) + { return e1.second < e2.second; } + }; + +public: + typedef VoxImageFilter > BaseClass; + VoxFilterAlgorithmBilateralTrim(const Vector3i &size) : BaseClass(size) { + m_sigma = 1; + mAtrim = 0; + mBtrim = 0; + } + + float Evaluate(const VoxImage &buffer, int index) + { + const Vector &vbuf = buffer.ConstData(); + const Vector &vker = this->m_KernelData.ConstData(); + int img_size = vbuf.size(); + int ker_size = vker.size(); + int pos; + + + + Vector mfh(ker_size); + for (int i = 0; i < ker_size; ++i) + mfh[i].first = vker[i].Value; // kernel value in first + for (int ik = 0; ik < ker_size; ik++) { + pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; + pos = (pos + img_size) % img_size; + mfh[ik].second = vbuf[pos].Value; // image value in second + } + std::sort(mfh.begin(), mfh.end(), KernelSortAscending()); + + float conv = 0, ksum = 0; + float gamma_smooth; + // for (int ik = 0; ik < mAtrim; ik++) + // ksum += mfh[ik].first; + for (int ik = mAtrim; ik < ker_size - mBtrim; ik++) { + gamma_smooth = compute_gauss( fabs(vbuf[index].Value - mfh[ik].second) * 1.E6 ); + conv += mfh[ik].first * mfh[ik].second * gamma_smooth; + ksum += mfh[ik].first * gamma_smooth; + } + // for (int ik = ker_size - mBtrim; ik < ker_size; ik++) + // ksum += mfh[ik].first; + + return conv / ksum; + } + + inline void SetIntensitySigma(const float s) { m_sigma = s; } + inline void SetABTrim(int a, int b) { mAtrim = a; mBtrim = b; } + +private: + inline float compute_gauss(const float x) { + return 1/(sqrt(2*M_PI)* m_sigma) * exp(-0.5*(x*x)/(m_sigma*m_sigma)); + } + + Scalarf m_sigma; + int mAtrim; + int mBtrim; +}; + +} + +#endif // VOXIMAGEFILTERBILATERAL_HPP diff --git a/src/Math/VoxImageFilterCustom.hpp b/src/Math/VoxImageFilterCustom.hpp new file mode 100644 index 0000000..831dbec --- /dev/null +++ b/src/Math/VoxImageFilterCustom.hpp @@ -0,0 +1,88 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VOXIMAGEFILTERCUSTOM_HPP +#define VOXIMAGEFILTERCUSTOM_HPP + +#include +#include "Math/VoxImage.h" +#include "VoxImageFilter.h" + +//////////////////////////////////////////////////////////////////////////////// +///// VOXIMAGE FILTER CUSTOM ///////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace uLib { + +template +class VoxFilterAlgorithmCustom : + public VoxImageFilter > { + + + typedef float (* FunctionPt)(const Vector &); +public: + typedef VoxImageFilter > BaseClass; + VoxFilterAlgorithmCustom(const Vector3i &size) : + BaseClass(size), m_CustomEvaluate(NULL) + {} + + float Evaluate(const VoxImage &buffer, int index) + { + if(likely(m_CustomEvaluate)) { + const Vector &vbuf = buffer.ConstData(); + const Vector &vker = this->m_KernelData.ConstData(); + int vox_size = vbuf.size(); + int ker_size = vker.size(); + int pos; + + float ker_sum = 0; + Vector mfh(ker_size); + for (int ik = 0; ik < ker_size; ik++) { + pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; + pos = (pos + vox_size) % vox_size; + mfh[ik] = vbuf[pos].Value * vker[ik].Value; + ker_sum += vker[ik].Value; + } + + return this->m_CustomEvaluate(mfh); + } + else + std::cerr << "Custom evaluate function is NULL \n" << + "No operation performed by filter.\n"; + + } + + uLibSetMacro(CustomEvaluate,FunctionPt) + +private: + FunctionPt m_CustomEvaluate; +}; + +} + + +#endif // VOXIMAGEFILTERCUSTOM_HPP diff --git a/src/Math/VoxImageFilterLinear.hpp b/src/Math/VoxImageFilterLinear.hpp new file mode 100644 index 0000000..14b9112 --- /dev/null +++ b/src/Math/VoxImageFilterLinear.hpp @@ -0,0 +1,69 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VOXIMAGEFILTERLINEAR_HPP +#define VOXIMAGEFILTERLINEAR_HPP + +#include +#include "Math/VoxImage.h" +#include "VoxImageFilter.h" + +//////////////////////////////////////////////////////////////////////////////// +///// VOXIMAGE FILTER LINEAR ///////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace uLib { + + +template +class VoxFilterAlgorithmLinear : + public VoxImageFilter > { +public: + typedef VoxImageFilter > BaseClass; + VoxFilterAlgorithmLinear(const Vector3i &size) : BaseClass(size) {} + + float Evaluate(const VoxImage &buffer, int index) + { + const Vector &vbuf = buffer.ConstData(); + const Vector &vker = this->m_KernelData.ConstData(); + int vox_size = vbuf.size(); + int ker_size = vker.size(); + int pos; + float conv = 0, ksum = 0; + for (int ik = 0; ik < ker_size; ++ik) { + pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; + pos = (pos + vox_size) % vox_size; + conv += vbuf[pos].Value * vker[ik].Value; + ksum += vker[ik].Value; + } + return conv / ksum; + } +}; + +} + +#endif // VOXIMAGEFILTERLINEAR_HPP diff --git a/src/Math/VoxImageFilterMedian.hpp b/src/Math/VoxImageFilterMedian.hpp new file mode 100644 index 0000000..e4f88c4 --- /dev/null +++ b/src/Math/VoxImageFilterMedian.hpp @@ -0,0 +1,75 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VOXIMAGEFILTERMEDIAN_HPP +#define VOXIMAGEFILTERMEDIAN_HPP + +#include +#include "Math/VoxImage.h" +#include "VoxImageFilter.h" + +//////////////////////////////////////////////////////////////////////////////// +///// VOXIMAGE FILTER MEDIAN ///////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace uLib { + +template +class VoxFilterAlgorithmMedian : + public VoxImageFilter > { +public: + typedef VoxImageFilter > BaseClass; + VoxFilterAlgorithmMedian(const Vector3i &size) : BaseClass(size) {} + + float Evaluate(const VoxImage &buffer, int index) + { + const Vector &vbuf = buffer.ConstData(); + const Vector &vker = this->m_KernelData.ConstData(); + int vox_size = vbuf.size(); + int ker_size = vker.size(); + int pos; + + Vector mfh(ker_size); + for (int ik = 0; ik < ker_size; ik++) { + pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; + pos = (pos + vox_size) % vox_size; + mfh[ik] = vbuf[pos].Value * vker[ik].Value; + } + std::sort(mfh.begin(), mfh.end()); + pos = 0; + // count zeroes in filter kernel to move it out of median // + for (int i = 0; i < ker_size; ++i) + if (vker[i].Value == 0.0) pos++; + // median // + pos += (ker_size - pos) / 2; + return mfh[pos]; + } +}; + +} + +#endif // VOXIMAGEFILTERMEDIAN_HPP diff --git a/src/Math/VoxImageFilterThreshold.hpp b/src/Math/VoxImageFilterThreshold.hpp new file mode 100644 index 0000000..e125763 --- /dev/null +++ b/src/Math/VoxImageFilterThreshold.hpp @@ -0,0 +1,78 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VOXIMAGEFILTERTHRESHOLD_HPP +#define VOXIMAGEFILTERTHRESHOLD_HPP + +#include +#include "Math/VoxImage.h" +#include "VoxImageFilter.h" + +//////////////////////////////////////////////////////////////////////////////// +///// VOXIMAGE FILTER THRESHOLD ////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace uLib { + +template +class VoxFilterAlgorithmThreshold : + public VoxImageFilter > { + + typedef VoxImageFilter > BaseClass; + // ULIB_OBJECT_PARAMETERS(BaseClass) { + // float threshold; + // }; + + float m_threshold; + +public: + VoxFilterAlgorithmThreshold(const Vector3i &size) : BaseClass(size) + { + // init_parameters(); + m_threshold = 0; + } + + inline void SetThreshold(float th) { m_threshold = th; } + + float Evaluate(const VoxImage &buffer, int index) + { + return static_cast(buffer.ConstData().at(index).Value >= + // parameters().threshold); + m_threshold ); + } + +}; + +//template +//inline void VoxFilterAlgorithmThreshold::init_parameters() +//{ +// parameters().threshold = 0; +//} + +} + +#endif // VOXIMAGEFILTERTHRESHOLD_HPP diff --git a/src/Math/VoxImageFilterUser.cpp b/src/Math/VoxImageFilterUser.cpp new file mode 100644 index 0000000..d82fe21 --- /dev/null +++ b/src/Math/VoxImageFilterUser.cpp @@ -0,0 +1,35 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Core/Vector.h" +#include "Dense.h" +#include "VoxImage.h" +#include "VoxImageFilterUser.h" + +using namespace uLib; + diff --git a/src/Math/VoxRaytracer.cpp b/src/Math/VoxRaytracer.cpp new file mode 100644 index 0000000..01094b3 --- /dev/null +++ b/src/Math/VoxRaytracer.cpp @@ -0,0 +1,202 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "VoxRaytracer.h" +#include "Utils.h" + +inline float fast_sign(float f) { return 1 - 2 * (f < 0); } + +namespace uLib { + +//////////////////////////////////////////////////////////////////////////////// +///// RAY DATA ///////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +void VoxRaytracer::RayData::AddElement(Id_t id, float L) +{ + Element el = {id, L}; + m_Data.push_back(el); + m_TotalLength += L; +} + + +void VoxRaytracer::RayData::AppendRay(const VoxRaytracer::RayData &in) +{ + if (unlikely(!in.m_Data.size())) { + std::cout << "Warinig: PoCA on exit border!\n"; + return; + } + else if (unlikely(!m_Data.size())) { + m_Data = in.m_Data; + std::cout << "Warinig: PoCA on entrance border!\n"; + return; + } + else { + // Opzione 1) un voxel in piu' // + m_Data.reserve(m_Data.size() + in.m_Data.size()); + m_Data.insert(m_Data.end(), in.m_Data.begin(), in.m_Data.end()); + // Opzione 2) merge dei voxel nel poca. + // RayData::Element &e1 = m_Data.back(); + // const RayData::Element &e2 = in.m_Data.front(); + // if(e1.vox_id == e2.vox_id) + // { + // m_Data.reserve(m_Data.size() + in.m_Data.size() - 1); + // e1.L += e2.L; //fix// + // m_Data.insert(m_Data.end(), in.m_Data.begin()+1, in.m_Data.end()); + // } + // else { + // m_Data.reserve(m_Data.size() + in.m_Data.size()); + // m_Data.insert(m_Data.end(), in.m_Data.begin(), in.m_Data.end()); + // } + m_TotalLength += in.m_TotalLength; + } +} + +void VoxRaytracer::RayData::PrintSelf(std::ostream &o) +{ + o << "Ray: \n"; + Vector::Iterator it; + for(it = m_Data.begin(); it < m_Data.end(); ++it) + o << "[ " << (*it).vox_id << ", " << (*it).L << "] \n"; +} + + +//////////////////////////////////////////////////////////////////////////////// +//// RAY TRACER //////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +bool VoxRaytracer::GetEntryPoint(const HLine3f line, Vector4f &pt) +{ + Vector4f s = m_Image->GetLocalPoint(line.direction()); + pt = m_Image->GetLocalPoint(line.origin()); + + // Considers Structured grid dimensions // + Vector4f dims = m_Image->GetDims().homogeneous().cast(); + pt = pt.cwiseQuotient(dims); + s = s.cwiseQuotient(dims); + + float l = s.head(3).norm(); + Vector3f L(l/s(0), l/s(1), l/s(2)); + + Vector3f offset; + for(int i=0;i<3;++i) + offset(i) = (s(i)>0) - (pt(i)-floor(pt(i))) ; + offset = offset.cwiseProduct(L).cwiseAbs(); + + int id; float d; + for(int loop=0; loop<8; loop++) + { + int check_border = 0; + for ( int i=0; i<3 ;++i) { + check_border += pt(i) > 1; + check_border += pt(i) < 0; + } + if(check_border == 0) { + for(int i=0;i<3;++i) + pt(i) *= (float)dims(i); + pt = m_Image->GetWorldPoint(pt); + return true; + } + + d = offset.minCoeff(&id); + for(int i=0; i<3; ++i) + pt(i) += d / L(i); + + pt(id) = rintf(pt(id)); + + + offset.array() -= d; + offset(id) = fabs(L(id)); + } + for(int i=0;i<3;++i) + pt(i) *= (float)dims(i); + pt = m_Image->GetWorldPoint(pt); + return false; +} + +bool VoxRaytracer::GetExitPoint(const HLine3f line, Vector4f &pt) +{ + HLine3f out = line; + out.direction() *= -1; + return GetEntryPoint(out,pt); +} + + +VoxRaytracer::RayData VoxRaytracer::TraceBetweenPoints(const Vector4f &in, + const Vector4f &out) +const +{ + RayData ray; + Vector4f pt1 = m_Image->GetLocalPoint(in); + Vector4f pt2 = m_Image->GetLocalPoint(out); + Vector4f s = pt2 - pt1; + + + + Vector3f scale; // FIXXX + scale << (m_Image->GetWorldMatrix() * Vector4f(1,0,0,0)).norm(), + (m_Image->GetWorldMatrix() * Vector4f(0,1,0,0)).norm(), + (m_Image->GetWorldMatrix() * Vector4f(0,0,1,0)).norm(); + + float l = s.head(3).norm(); + Vector3f L(l/s(0), l/s(1), l/s(2)); + + Vector3f offset; + for(int i=0;i<3;++i) + offset(i) = (s(i)>=0) - (pt1(i)-floor(pt1(i))) ; + + offset = offset.cwiseProduct(L).cwiseAbs(); + L = L.cwiseAbs(); + + int id; float d; + Vector3i vid = m_Image->Find(in); + while(l>0) + { + d = offset.minCoeff(&id); + + if(m_Image->IsInsideGrid(vid)) + ray.AddElement(m_Image->Map(vid), d * scale(id) ); + + // nan check // + // if(unlikely(!isFinite(d * scale(id)))) { + // std:: cout << "NAN in raytracer\n"; + // exit(1); + // } + + vid(id) += (int)fast_sign(s(id)); + + l -= d; + offset.array() -= d; + offset(id) = fmin(L(id),l); + } + return ray; +} + + +} diff --git a/src/Math/VoxRaytracer.h b/src/Math/VoxRaytracer.h new file mode 100644 index 0000000..02b69a1 --- /dev/null +++ b/src/Math/VoxRaytracer.h @@ -0,0 +1,86 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VOXRAYTRACER_H +#define VOXRAYTRACER_H + +#include + +#include "Core/Vector.h" +#include "Math/ImageData.h" +#include "Math/Line.h" +#include "Math/VectorSpace.h" + +namespace uLib { + +class VoxRaytracer { + +public: + class RayData { + public: + RayData() : m_TotalLength(0) {} + + typedef struct { + Id_t vox_id; + Scalarf L; + } Element; + + inline void AddElement(Id_t id, float L); + + void AppendRay ( const RayData &in); + + uLibConstRefMacro(Data,Vector) + uLibConstRefMacro(TotalLength,Scalarf) + + void PrintSelf(std::ostream &o); + + private: + Vector m_Data; + Scalarf m_TotalLength; + }; + + +public: + VoxRaytracer(ImageData &image) : m_Image(&image) {} + + bool GetEntryPoint(const HLine3f line, Vector4f &pt); + + bool GetExitPoint(const HLine3f line, Vector4f &pt); + + RayData TraceBetweenPoints(const Vector4f &in, const Vector4f &out) const; + + uLibGetMacro(Image,ImageData *) + +private: + ImageData *m_Image; +}; + +} + + + +#endif // VOXRAYTRACER_H diff --git a/src/Math/testing/AccumulatorTest.cpp b/src/Math/testing/AccumulatorTest.cpp new file mode 100644 index 0000000..211f334 --- /dev/null +++ b/src/Math/testing/AccumulatorTest.cpp @@ -0,0 +1,108 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Math/Accumulator.h" +#include "testing-prototype.h" + +#include + + +//#include +//#include +//#include + +using namespace uLib; + +int test_ABTrim() { + + Accumulator_ABTrim acc; + + acc.SetABTrim(1,1); + + Vector v; + v << 1,5,5,5,300; + + for(Vector::Iterator itr=v.begin(); itr mean; + TRandom rnd; + const int c = 10000000; + Vector v; + v.reserve(c); + for(int i=0;i +#include + +using namespace uLib; + +int main() { + BEGIN_TESTING(BitCode Test); + + BitCode bc; + + bc.PrintSelf(); + + END_TESTING; +} diff --git a/src/Math/testing/CMakeLists.txt b/src/Math/testing/CMakeLists.txt new file mode 100644 index 0000000..278c133 --- /dev/null +++ b/src/Math/testing/CMakeLists.txt @@ -0,0 +1,19 @@ + +set(TESTS + MathVectorTest + GeometryTest + ContainerBoxTest + VoxImageTest + VoxRaytracerTest + StructuredDataTest + StructuredGridTest + VoxImageFilterTest + PolicyTest + AccumulatorTest + VoxImageCopyTest + TriangleMeshTest + BitCodeTest +) + + +uLib_add_tests(${uLib-module}) diff --git a/src/Math/testing/ContainerBoxTest.cpp b/src/Math/testing/ContainerBoxTest.cpp new file mode 100644 index 0000000..c85be26 --- /dev/null +++ b/src/Math/testing/ContainerBoxTest.cpp @@ -0,0 +1,95 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "testing-prototype.h" + +#include "Math/Dense.h" +#include "Math/VectorSpace.h" +#include "Math/ContainerBox.h" + +#include +#include + + +using namespace uLib; + +int Vector4f0(Vector4f c) +{ + c(3) = 0; + if ( fabs(c(0)) < 0.001 && fabs(c(1)) < 0.001 && fabs(c(2)) < 0.001 ) + return 0; + else + return 1; +} + + +int main() +{ + + BEGIN_TESTING(Math ContainerBox); + + ContainerBox Cnt; + +// // Local transform: + Cnt.SetOrigin(Vector3f(-1,-1,-1)); + Cnt.SetSize(Vector3f(2,2,2)); // scaling // + std::cout << "Container scale is: " << Cnt.GetSize().transpose() << "\n"; + std::cout << "Container scale is: " << Cnt.GetSize().transpose() << "\n"; + TEST0( Vector4f0(Cnt.GetSize().homogeneous() - HVector3f(2,2,2)) ); + + + ContainerBox Box; + + Box.SetPosition(Vector3f(1,1,1)); + Box.SetSize(Vector3f(2,2,2)); + Box.EulerYZYRotate(Vector3f(0,0,0)); + Vector4f pt = Box.GetLocalPoint(HPoint3f(2,3,2)); + Vector4f wp = Box.GetWorldPoint(pt); + TEST0( Vector4f0(wp - HPoint3f(2,3,2)) ); + + +//// // Global +// Cnt.SetPosition(Vector3f(1,1,1)); +// Cnt.EulerYZYRotate(Vector3f(M_PI_2,M_PI_2,0)); +// HPoint3f p = Cnt.GetWorldPoint(1,1,1); +// //std::cout << p.transpose() << "\n"; +// TEST0( Vector4f0(p - HVector3f(2,1,2)) ); +// p = Cnt.GetWorldPoint(1,2,3); +// //std::cout << p.transpose() << "\n"; +// TEST0( Vector4f0(p - HVector3f(4,1,3)) ); + + +// // scaling // + + + + _fail > 0 ? std::cout << "FAIL\n" : std::cout << "OK!\n"; + END_TESTING; +} + + diff --git a/src/Math/testing/GeometryTest.cpp b/src/Math/testing/GeometryTest.cpp new file mode 100644 index 0000000..3930f08 --- /dev/null +++ b/src/Math/testing/GeometryTest.cpp @@ -0,0 +1,99 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "testing-prototype.h" +#include "Math/Dense.h" +#include "Math/VectorSpace.h" +#include "Math/Geometry.h" +#include "Math/ContainerBox.h" + +#include +#include + +using namespace uLib; + +int Vector4f0(Vector4f c) +{ + c(3) = 0; + if ( fabs(c(0)) < 0.001 && fabs(c(1)) < 0.001 && fabs(c(2)) < 0.001 ) + return 0; + else + return 1; +} + + +int main() +{ + BEGIN_TESTING(Math Geometry); + + ////////////////////////////////////////////////////////////////////////////// + ///////////////// GEOMETRY TESTING /////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + Geometry Geo; + + Geo.SetPosition(Vector3f(1,1,1)); + Geo.EulerYZYRotate(Vector3f(0,0,0)); + Vector4f pt = Geo.GetLocalPoint(HPoint3f(2,3,2)); + Vector4f wp = Geo.GetWorldPoint(pt); + TEST0( Vector4f0(wp - HPoint3f(2,3,2)) ); + + Geo.Scale(Vector3f(2,2,2)); + wp = Geo.GetWorldPoint(HPoint3f(1,1,1)); + TEST0( Vector4f0(wp - HPoint3f(3,3,3)) ); + Geo.Scale(Vector3f( .5 , .5 , .5 )); + + + Geo.EulerYZYRotate(Vector3f(M_PI_2,0,0)); + wp = Geo.GetWorldPoint(HPoint3f(1,1,1)); + TEST0( Vector4f0(wp - HPoint3f(2,2,0)) ); + + Geo.EulerYZYRotate(Vector3f(0,M_PI_2,0)); + wp = Geo.GetWorldPoint(HPoint3f(1,1,1)); + TEST0( Vector4f0(wp - HPoint3f(2,2,2)) ); + + Geo.EulerYZYRotate(Vector3f(0,0,M_PI_2)); + wp = Geo.GetWorldPoint(HPoint3f(1,1,1)); + // std::cout << "Geometry matrix\n" << Geo.GetTransform() << "\n"; + // std::cout << "World 1,1,1 coords\n" << wp << "\n"; + TEST0( Vector4f0(wp - HPoint3f(0,2,2)) ); + + // TESTING FLIP AXES // + + Geo.SetPosition(Vector3f(0,0,0)); + Geo.EulerYZYRotate(Vector3f(-M_PI_2,-M_PI_2,-M_PI_2)); // reset previous + Geo.EulerYZYRotate(Vector3f(M_PI_2,0,0)); // PI_2 along X + Geo.FlipAxes(0,2); // flip X-Z + Vector4f p = Geo.GetWorldPoint(Vector3f(1,0,0).homogeneous()); + TEST0( Vector4f0(p - HVector3f(1,0,0)) ); // after flip and rotation X->X + + + _fail > 0 ? std::cout << "FAIL\n" : std::cout << "OK!\n"; + END_TESTING; +} + + diff --git a/src/Math/testing/Makefile.am b/src/Math/testing/Makefile.am new file mode 100644 index 0000000..22ea4f1 --- /dev/null +++ b/src/Math/testing/Makefile.am @@ -0,0 +1,28 @@ + +include $(top_srcdir)/Common.am + +#AM_DEFAULT_SOURCE_EXT = .cpp + +# if HAVE_CHECK +TESTS = MathVectorTest \ + GeometryTest \ + ContainerBoxTest \ + VoxImageTest \ + VoxRaytracerTest \ + StructuredDataTest \ + VoxImageFilterTest \ + PolicyTest \ + AccumulatorTest \ + VoxImageCopyTest \ + TriangleMeshTest + +# else +# TEST = +# endif + +LDADD = $(top_srcdir)/libmutom-${PACKAGE_VERSION}.la $(AM_LIBS_ALL) + +all: ${TESTS} + +check_PROGRAMS = $(TESTS) + diff --git a/src/Math/testing/MathVectorTest.cpp b/src/Math/testing/MathVectorTest.cpp new file mode 100644 index 0000000..be74913 --- /dev/null +++ b/src/Math/testing/MathVectorTest.cpp @@ -0,0 +1,120 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "testing-prototype.h" +#include "Math/Dense.h" +#include "Math/VectorSpace.h" + +#include "Core/Archives.h" +#include "Core/String.h" + +#include +#include + + + +using namespace uLib; + +int Vector4f0(Vector4f c) +{ + c(3) = 0; + if ( fabs(c(0)) < 0.001 && fabs(c(1)) < 0.001 && fabs(c(2)) < 0.001 ) + return 0; + else + return 1; +} + + + + +int main() +{ + BEGIN_TESTING(uLib Math); + + ////////////////////////////////////////////////////////////////////////////// + ///////////////// VECTOR TESTING ///////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + std::cout << "Testing Vectors\n"; + + { // ROW COLUMN ACCESSOR ORDER TEST // + Matrix2i test; + test << 1,2,3,4; + std::cout << "print row column test "; + std::cout << test(0,0) << " " << + test(0,1) << " " << + test(1,0) << " " << + test(1,1) << " " << "\n"; + + TEST1( test(0,1) == 2 && test(1,0) == 3 ); + } + + + { + Vector3i test(0,0,0); + ++test(1); + std::cout << "increment of single dim inside vector: " << test.transpose() << "\n"; + TEST1( test == Vector3i(0,1,0) ); + } + + { + Matrix4f mat; + mat << 1,0,0,0, + 0,1,0,0, + 0,0,1,0, + 0,0,0,1; + + std::cout << "determinant" << mat.determinant() << "\n"; + } + + + { + // Vector3f v(1,2,3); + // std::string str("2 3 5"); + // std::istringstream istr(str); + // uLib::Archive::hrt_iarchive hi(istr); + // hi >> v; + // uLib::Archive::hrt_oarchive ho(std::cout); + // ho << v; + } + + { + // VECTOR STRING INTERACTION // + Vector3f v; + std::string str("2 3 5"); + str >> v; + std::string sstr; + sstr << v << "\n"; + std::cout << sstr; + } + + + END_TESTING; +} + + diff --git a/src/Math/testing/PolicyTest.cpp b/src/Math/testing/PolicyTest.cpp new file mode 100644 index 0000000..dbe2685 --- /dev/null +++ b/src/Math/testing/PolicyTest.cpp @@ -0,0 +1,78 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include +#include "testing-prototype.h" + + + +// Curiously Recurring Template Pattern // + + +template < typename V, typename T > +class Base { +public: + Base(int a) : value(a) { + Algorithm = static_cast(this); + } + + void Print() + { + std::cout << Algorithm->Value() << "\n"; + } + + int value; + V voxel; + T* Algorithm; +}; + + +template < typename V > +class Derived : public Base< V ,Derived > { + typedef Base< V ,Derived > BaseClass; +public: + Derived(int a) : BaseClass(a) {} + int Value() { return this->value+1; } +}; + + + + + +int main() +{ + BEGIN_TESTING(Policy); + + + Derived my(5); + my.Print(); + + Base > my2(5); + my2.Print(); + + END_TESTING; +} diff --git a/src/Math/testing/StructuredDataTest.cpp b/src/Math/testing/StructuredDataTest.cpp new file mode 100644 index 0000000..f186405 --- /dev/null +++ b/src/Math/testing/StructuredDataTest.cpp @@ -0,0 +1,129 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + +#include + +#include "testing-prototype.h" + +#include "Math/Dense.h" +#include "Math/ContainerBox.h" +#include "Math/StructuredData.h" +#include "Math/DataSet.h" + +#include + +using namespace uLib; + + +struct Data { + Data() : d1(123), d2(234), i3(345) {} + float d1,d2; + int i3; + float D2() { return d2; } + float operator()() { return d2; } +}; + + + +int main() { + BEGIN_TESTING(Structured Data); + + Data data; + + VectorData vd; + vd.push_back(data); + vd.push_back(Data()); + vd.push_back(Data()); + + vd.SetScalar(sizeof(float)); + std::cout << vd.Value(2) << "\n"; + + vd.SetScalar(offsetof(Data,i3)); + std::cout << vd.Value(2) << "\n"; + +// vd.SetBindScalar(&data,&Data::D2); +// std::cout << vd.BindValue(2) << "\n"; + + + END_TESTING; +} + + + +int main2() { + BEGIN_TESTING(Structured Data); + + { // testing unmap function //////////////////////////////////////////////// + StructuredData sdata(Vector3i(2,3,4)); + for(int i=0; i < sdata.GetDims().prod() ; ++i) { + Vector3i d = sdata.UnMap(i); + std::cout << "TEST1( sdata.UnMap(" << i << ") == Vector3i(" + << d(0) << "," << d(1) << "," << d(2) << ")); \n"; + } + TEST1( sdata.UnMap(0) == Vector3i(0,0,0)); + TEST1( sdata.UnMap(1) == Vector3i(0,1,0)); + TEST1( sdata.UnMap(2) == Vector3i(0,2,0)); + TEST1( sdata.UnMap(3) == Vector3i(1,0,0)); + TEST1( sdata.UnMap(4) == Vector3i(1,1,0)); + TEST1( sdata.UnMap(5) == Vector3i(1,2,0)); + TEST1( sdata.UnMap(6) == Vector3i(0,0,1)); + TEST1( sdata.UnMap(7) == Vector3i(0,1,1)); + TEST1( sdata.UnMap(8) == Vector3i(0,2,1)); + TEST1( sdata.UnMap(9) == Vector3i(1,0,1)); + TEST1( sdata.UnMap(10) == Vector3i(1,1,1)); + TEST1( sdata.UnMap(11) == Vector3i(1,2,1)); + TEST1( sdata.UnMap(12) == Vector3i(0,0,2)); + TEST1( sdata.UnMap(13) == Vector3i(0,1,2)); + TEST1( sdata.UnMap(14) == Vector3i(0,2,2)); + TEST1( sdata.UnMap(15) == Vector3i(1,0,2)); + TEST1( sdata.UnMap(16) == Vector3i(1,1,2)); + TEST1( sdata.UnMap(17) == Vector3i(1,2,2)); + TEST1( sdata.UnMap(18) == Vector3i(0,0,3)); + TEST1( sdata.UnMap(19) == Vector3i(0,1,3)); + TEST1( sdata.UnMap(20) == Vector3i(0,2,3)); + TEST1( sdata.UnMap(21) == Vector3i(1,0,3)); + TEST1( sdata.UnMap(22) == Vector3i(1,1,3)); + TEST1( sdata.UnMap(23) == Vector3i(1,2,3)); + + + // testing map ///////////////////////////////////////////////////////// + int i=0; + // PREDEFINED ORDER IS YXZ // + for(int z=0; z + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include "testing-prototype.h" + +using namespace uLib; + +int main() +{ + BEGIN_TESTING(Math Structured Grid); + + VoxImage f_grid(Vector3i(100,100,100)); + + f_grid[Vector3i(1,2,3)]() = 5552368; + TEST1( f_grid.At(30102)() == 5552368 ); + + + // TESTING MAP // + VoxImage test_order(Vector3i(2,2,2)); + int index =0; + for(int z=0;z<2;++z) + for(int y=0;y<2;++y) + for(int x=0;x<2;x++) + { + test_order[Vector3i(x,y,z)]() = index; + std::cout << x << " " << y << " " << z << " -> " << + test_order.At(Vector3i(x,y,z))() << "\n"; + index++; + } + test_order.Data().PrintSelf(std::cout); + + int result[8] = {0,2,1,3,4,6,5,7}; + for(int i=0;i<8;++i) + TEST1( test_order.At(i)() == result[i] ); + + // TESTING UNMAP // + std::cout << "unmap = " << test_order.UnMap(7).transpose() << "\n"; + TEST1( test_order.UnMap(7) == Vector3i(1,1,1) ); + TEST1( test_order.UnMap(6) == Vector3i(1,0,1) ); + TEST1( test_order.UnMap(5) == Vector3i(0,1,1) ); + // ... + + + _fail > 0 ? std::cout << "FaIL\n" : std::cout << "OK!\n"; + END_TESTING +} diff --git a/src/Math/testing/TriangleMeshTest.cpp b/src/Math/testing/TriangleMeshTest.cpp new file mode 100644 index 0000000..bd89a03 --- /dev/null +++ b/src/Math/testing/TriangleMeshTest.cpp @@ -0,0 +1,52 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "testing-prototype.h" + +#include "Math/TriangleMesh.h" + + +using namespace uLib; + +int main() +{ + BEGIN_TESTING(Triangle Mesh); + + TriangleMesh mesh; + + mesh.AddPoint(Vector3f(0,0,0)); + mesh.AddPoint(Vector3f(0,1,0)); + mesh.AddPoint(Vector3f(1,0,0)); + + mesh.AddTriangle(Vector3i(0,1,2)); + + + mesh.PrintSelf(std::cout); + + END_TESTING; +} diff --git a/src/Math/testing/VoxImageCopyTest.cpp b/src/Math/testing/VoxImageCopyTest.cpp new file mode 100644 index 0000000..b4de751 --- /dev/null +++ b/src/Math/testing/VoxImageCopyTest.cpp @@ -0,0 +1,77 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "testing-prototype.h" + +#include "Math/VoxImage.h" + +using namespace uLib; + + +struct TestVoxel { + Scalarf Value; + unsigned int Count; +}; + +int main() { + BEGIN_TESTING(Math VoxImage Copy); + + { + VoxImage img(Vector3i(10,10,10)); + TestVoxel zero = {0,0}; + img.InitVoxels(zero); + TestVoxel nonzero = {5.552368, 0}; + img[Vector3i(5,1,7)] = nonzero; + img[img.Find(HPoint3f(3,3,3))].Value = 5.552369; + TEST1( img.GetValue(Vector3i(5,1,7)) == 5.552368f ); + + + img.SetOrigin(Vector3f(4,5,6)); + + std::cout << "\n"; + + img.PrintSelf(std::cout); + + VoxImage img2 = img; + img2.PrintSelf(std::cout); + + TEST1( img.GetOrigin() == img2.GetOrigin() ); + TEST1( img.GetSpacing() == img2.GetSpacing() ); + + img2 = img; + + } + + + + + + + + std::cout << "returns " << _fail << "\n"; + END_TESTING; +} diff --git a/src/Math/testing/VoxImageFilterTest.cpp b/src/Math/testing/VoxImageFilterTest.cpp new file mode 100644 index 0000000..2e4f312 --- /dev/null +++ b/src/Math/testing/VoxImageFilterTest.cpp @@ -0,0 +1,150 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "testing-prototype.h" +#include "Math/ImageData.h" + +#include "Math/VoxImage.h" +#include "Math/VoxImageFilter.h" + + + +using namespace uLib; + +struct TestVoxel { + Scalarf Value; + unsigned int Count; +}; + +float GaussianShape(float d) +{ + // normalized manually .. fix // + return 4.5 * exp(-d * 4.5); +} + + +class GaussianShapeClass : public Interface::VoxImageFilterShape { +public: + GaussianShapeClass(float sigma) : + m_sigma(sigma) + {} + + float operator ()(float d) { + return (1/m_sigma) * exp(-d/m_sigma); + } + +private: + float m_sigma; +}; + + +static float MaxInVector(const Vector &v) +{ + float max = 0; + for(int i=0; i max) max = v.at(i); + return max; +} + + +int main() +{ + BEGIN_TESTING(VoxImageFilters); + + VoxImage image(Vector3i(20,30,40)); + image[Vector3i(10,10,10)].Value = 1; + //image[Vector3i(10,10,8)].Value = 1; + image.ExportToVtk("test_filter_original.vtk",0); + + + + //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // RPS // + + { + VoxFilterAlgorithmSPR filter(Vector3i(2,3,4)); + + VoxImage filtered = image; + + Vector values; + for(int i=0; i < filter.GetKernelData().GetDims().prod(); ++i) { + values.push_back(1.); + std::cout << values[i] << " "; + } + std::cout << "\n"; + + filter.SetImage(&filtered); + + filter.SetKernelNumericXZY(values); + + filter.SetABTrim(0,2); + + filter.GetKernelData().PrintSelf(std::cout); + + filter.Run(); + + filtered.ExportToVtk("filter_RPS_out.vtk",0); + } + + + + + + { + + VoxImage image(Vector3i(20,30,40)); + image[Vector3i(10,10,10)].Value = 1; + image[Vector3i(9,10,8)].Value = 2; + image.ExportToVtk("test_filter_max_original.vtk",0); + + + + VoxFilterAlgorithmCustom filter(Vector3i(3,3,4)); + + Vector values; + for(int i=0; i < filter.GetKernelData().GetDims().prod(); ++i) { + values.push_back(static_cast(1)); + } + + filter.SetImage(&image); + + filter.SetKernelNumericXZY(values); + + filter.SetCustomEvaluate(MaxInVector); + + filter.Run(); + + image.ExportToVtk("test_filter_max.vtk",0); + } + + + + END_TESTING; +} diff --git a/src/Math/testing/VoxImageTest.cpp b/src/Math/testing/VoxImageTest.cpp new file mode 100644 index 0000000..368fc9b --- /dev/null +++ b/src/Math/testing/VoxImageTest.cpp @@ -0,0 +1,107 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "testing-prototype.h" +#include "Math/ImageData.h" +#include "Math/VoxImage.h" + +using namespace uLib; + + +struct TestVoxel { + Scalarf Value; + unsigned int Count; +}; + +int main() { + BEGIN_TESTING(Math ImageData); + + { // SIMPLE TESTS // + ImageData img(Vector3i(10,10,10)); + img.SetSpacing(Vector3f(3,3,3)); + TEST1( img.GetWorldPoint(2,0,0) == HPoint3f(6,0,0) ); + TEST1( img.GetWorldPoint(1,1,1) == HPoint3f(3,3,3) ); + + img.SetPosition(Vector3f(1,1,1)); + TEST1( img.GetWorldPoint(1,1,1) == HPoint3f(4,4,4) ); + TEST1( img.GetLocalPoint(4,4,4) == HPoint3f(1,1,1) ); + + TEST0( img.IsInsideBounds(HPoint3f(5,33,-5))); + TEST0( img.IsInsideBounds(HPoint3f(0,0,0))); + TEST1( img.IsInsideBounds(HPoint3f(1,1,1))); + } + + { // TEST WITH ORIGIN // + ImageData img(Vector3i(10,10,10)); + img.SetSpacing(Vector3f(3,3,3)); + img.SetOrigin(Vector3f(-1,1,-1)); + img.SetPosition(Vector3f(1,1,1)); + TEST1( img.GetWorldPoint(1,1,1) == HPoint3f(3,5,3) ); + } + + + { + VoxImage img(Vector3i(10,10,10)); + TestVoxel zero = {0,0}; + img.InitVoxels(zero); + TestVoxel nonzero = {5.552368, 0}; + img[Vector3i(5,1,7)] = nonzero; + img[img.Find(HPoint3f(3,3,3))].Value = 5.552369; + img.ExportToVtk("./test_vox_image.vtk",0); + img.ExportToVtkXml("./test_vox_image.vti",0); + TEST1( img.GetValue(Vector3i(5,1,7)) == 5.552368f ); + } + + { + VoxImage img(Vector3i(4,4,4)); + TestVoxel zero = {0,0}; + img.InitVoxels(zero); + img.SetSpacing(Vector3f(2,2,2)); + img.SetPosition(Vector3f(-4,-4,-4)); + TEST1( img.GetWorldPoint(img.GetLocalPoint(HPoint3f(5,5,5))) == HPoint3f(5,5,5)); + } + + { + VoxImage imgR(Vector3i(0,0,0)); + imgR.ImportFromVtk("./test_vox_image.vtk"); + imgR.ExportToVtk("./read_and_saved.vtk"); + } + + + { + VoxImage img1(Vector3i(5,5,5)); + VoxImage img2; + img2 = img1; + TEST1( img1.GetDims() == img2.GetDims() ); + } + + + + + END_TESTING +} diff --git a/src/Math/testing/VoxRaytracerTest.cpp b/src/Math/testing/VoxRaytracerTest.cpp new file mode 100644 index 0000000..73f045d --- /dev/null +++ b/src/Math/testing/VoxRaytracerTest.cpp @@ -0,0 +1,151 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Math/ImageData.h" +#include "Math/VoxRaytracer.h" +#include "testing-prototype.h" + +using namespace uLib; + + +int Vector4f0(Vector4f c) +{ + c(3) = 0; + if ( fabs(c(0)) < 0.001 && fabs(c(1)) < 0.001 && fabs(c(2)) < 0.001 ) + return 0; + else + return 1; +} + +//bool Comapare(const &t1, const T2 &t2) +//{ +// int out = 0; +// out += t1.vox_id != t2.vox_id; +// out += (fabs(t1.L) - fabs(t2.L)) > 0.001; +// return out == 0; +//} + + +typedef VoxRaytracer Raytracer; + +int main() +{ + BEGIN_TESTING(Math VoxRaytracer); + + ImageData img(Vector3i(2,2,2)); + img.SetSpacing(Vector3f(2,2,2)); + img.SetPosition(Vector3f(-2,0,-2)); + + { + HLine3f line; + line.origin << 0.1, 4.1, 0.1, 1; + line.direction << 0.1, -0.1, 0.1,0; + Raytracer rt(img); + HPoint3f pt; + TEST1( rt.GetEntryPoint(line,pt) ); + TEST0( Vector4f0( pt - HPoint3f(0.2,4,0.2) ) ); + } + + { + HLine3f line; + line.origin << 4,0,4, 1; + line.direction << -0.1, 0.1, -0.1, 0; + Raytracer rt(img); + HPoint3f pt; + TEST1( rt.GetEntryPoint(line,pt) ); + TEST0( Vector4f0( pt - HPoint3f(2,2,2) ) ); + } + + { // Test a point inside image // + ImageData img(Vector3i(4,4,4)); + img.SetSpacing(Vector3f(2,2,2)); + img.SetPosition(Vector3f(-4,-4,-4)); + Raytracer ray(img); + HPoint3f pt; + HLine3f line; + line.origin = HPoint3f(-3,-3,-3); + // line.direction = HVector3f(1,1,1); // + TEST1( ray.GetEntryPoint(line,pt) ); + TEST1( pt == HPoint3f(-3,-3,-3) ); + + Raytracer::RayData rdata = ray.TraceBetweenPoints(HPoint3f(-3,-3,-3), HPoint3f(3,3,3)); + foreach (const Raytracer::RayData::Element &el, rdata.Data()) + { + std::cout << " " << el.vox_id << " , " << el.L << "\n"; + } + } + + + { + Vector4f pt1(1,-0.5,1); + Vector4f pt2(1,4.5,1); + Raytracer rt(img); + + Raytracer::RayData ray = rt.TraceBetweenPoints(pt1,pt2); + TEST1( ray.Data().size() == 2 ); + TEST1( ray.Data().at(0).vox_id == 6 ); + TEST1( ray.Data().at(1).vox_id == 7 ); + ray.PrintSelf(std::cout); + } + + { + Vector4f pt1(5,1,1); + Vector4f pt2(-3,1,1); + Raytracer rt(img); + + Raytracer::RayData ray = rt.TraceBetweenPoints(pt1,pt2); + TEST1( ray.Data().size() == 2 ); + TEST1( ray.Data().at(0).vox_id == 6 ); + TEST1( ray.Data().at(1).vox_id == 4 ); + ray.PrintSelf(std::cout); + } + + { + Vector4f pt1(1,1,1); + Vector4f pt2(-1,3,-1); + Raytracer rt(img); + + Raytracer::RayData ray = rt.TraceBetweenPoints(pt1,pt2); + TEST1( ray.Data().size() == 4 ); + TEST1( ray.Data().at(0).vox_id == 6 ); + TEST1( ray.Data().at(1).vox_id == 4 ); + TEST1( ray.Data().at(2).vox_id == 5 ); + TEST1( ray.Data().at(3).vox_id == 1 ); + ray.PrintSelf(std::cout); + } + + END_TESTING +} + + + + + + + + diff --git a/src/Math/testing/testing-prototype.h b/src/Math/testing/testing-prototype.h new file mode 100644 index 0000000..39f4e6c --- /dev/null +++ b/src/Math/testing/testing-prototype.h @@ -0,0 +1,37 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include + +#define BEGIN_TESTING(name) \ +static int _fail = 0; \ +printf("..:: Testing " #name " ::..\n"); + +#define TEST1(val) _fail += (val)==0 +#define TEST0(val) _fail += (val)!=0 +#define END_TESTING return _fail; + diff --git a/src/ParticlePhysics/Geant/Makefile.am b/src/ParticlePhysics/Geant/Makefile.am new file mode 100644 index 0000000..70c690d --- /dev/null +++ b/src/ParticlePhysics/Geant/Makefile.am @@ -0,0 +1,14 @@ +include $(top_srcdir)/Common.am + +library_includedir = $(includedir)/libmutom-${PACKAGE_VERSION}/ParticlePhysics/Geant + +library_include_HEADERS = + +_PPGEANT_SOURCES = + + + +noinst_LTLIBRARIES = libmutomppgeant.la +libmutomppgeant_la_SOURCES = ${_PPGEANT_SOURCES} + + diff --git a/src/ParticlePhysics/MuonTomography/DetectorChamber.h b/src/ParticlePhysics/MuonTomography/DetectorChamber.h new file mode 100644 index 0000000..22aa495 --- /dev/null +++ b/src/ParticlePhysics/MuonTomography/DetectorChamber.h @@ -0,0 +1,47 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + +#ifndef U_PP_MUTOM_DETECTORCHAMBER_H +#define U_PP_MUTOM_DETECTORCHAMBER_H + +#include + +namespace uLib { + +class ContainerBox; + +class DetectorChamber : public Object { +public: + + virtual ContainerBox & Geometry() {} +protected: + virtual ~DetectorChamber() {} +}; + +} // uLib + + + +#endif // DETECTORCHAMBER_H diff --git a/src/ParticlePhysics/MuonTomography/DriftDetector.h b/src/ParticlePhysics/MuonTomography/DriftDetector.h new file mode 100644 index 0000000..e655929 --- /dev/null +++ b/src/ParticlePhysics/MuonTomography/DriftDetector.h @@ -0,0 +1,53 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_PPHY_DRIFTDETECTOR_H +#define U_PPHY_DRIFTDETECTOR_H + + +#include +#include + +#include "ParticlePhysics/MuonTomography/DetectorChamber.h" + +namespace uLib { + +class DriftDetectorChamber : public DetectorChamber { + + uLibRefMacro(Geometry,ContainerBox) +private: + ContainerBox m_Geometry; +}; + + + + +} // uLib + + + +#endif // U_PPHY_DRIFTDETECTOR_H diff --git a/src/ParticlePhysics/MuonTomography/Hit.h b/src/ParticlePhysics/MuonTomography/Hit.h new file mode 100644 index 0000000..a5b071a --- /dev/null +++ b/src/ParticlePhysics/MuonTomography/Hit.h @@ -0,0 +1,65 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + +#ifndef U_PPMUTOM_HIT_H +#define U_PPMUTOM_HIT_H + +#include +#include + + +namespace uLib { + +template +class Hit { + Code m_Code; + Type m_DriftTime; +}; + + + + + + + +class HitMC { +public: + virtual Id_t GetChamber() = 0; + virtual Vector3f GetPosition() = 0; + virtual Scalarf GetDritfTime() = 0; +protected: + virtual ~HitMC() {} +}; + + + +} // uLib + + + + + +#endif // HIT_H diff --git a/src/ParticlePhysics/MuonTomography/Makefile.am b/src/ParticlePhysics/MuonTomography/Makefile.am new file mode 100644 index 0000000..d169be8 --- /dev/null +++ b/src/ParticlePhysics/MuonTomography/Makefile.am @@ -0,0 +1,11 @@ +include $(top_srcdir)/Common.am + +library_includedir = $(includedir)/libmutom-${PACKAGE_VERSION}/ParticlePhysics/MuonTomography +library_include_HEADERS = + +_PPMUTOM_SOURCES = + +noinst_LTLIBRARIES = libmutomppmutom.la +libmutomppmutom_la_SOURCES = ${_PPMUTOM_SOURCES} + + diff --git a/src/ParticlePhysics/MuonTomography/MuonScatter.h b/src/ParticlePhysics/MuonTomography/MuonScatter.h new file mode 100644 index 0000000..67b195f --- /dev/null +++ b/src/ParticlePhysics/MuonTomography/MuonScatter.h @@ -0,0 +1,89 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_PPMUTOM_MUONSCATTER_H +#define U_PPMUTOM_MUONSCATTER_H + +#include "Core/Macros.h" +#include "Core/Serializable.h" + +#include "Math/Dense.h" + +namespace uLib { + + + +class MuonTrack { + ULIB_SERIALIZE_ACCESS +public: + HLine3f track; + Scalarf momentum; +}; + +class MuonScatter { + ULIB_SERIALIZE_ACCESS +public: + MuonTrack in, out; + MuonTrack error_in, error_out; +}; + + +} // uLib + +ULIB_SERIALIZABLE(uLib::MuonTrack) +ULIB_SERIALIZE(uLib::MuonTrack) { + ar & AR(line); +} + + + +ULIB_SERIALIZABLE(uLib::MuonScatter) +ULIB_SERIALIZE(uLib::MuonScatter) { + ar + & " MuonScatter: ----------------- \n" + & "IN : " & AR(in) & "\n" + & "OUT: " & AR(out) & "\n" + & " ------------------------------ \n"; +} + + +std::ostream & +operator << (std::ostream &o, const uLib::MuonScatter &d) { + uLib::Archive::hrt_oarchive(o) << d; + return o; +} + +inline std::istream & +operator >> (std::istream &is, uLib::MuonScatter &d) +{ + uLib::Archive::hrt_iarchive(is) >> d; + return is; +} + + + +#endif // MUONSCATTER_H diff --git a/src/Root/CMakeLists.txt b/src/Root/CMakeLists.txt new file mode 100644 index 0000000..06086b3 --- /dev/null +++ b/src/Root/CMakeLists.txt @@ -0,0 +1,39 @@ +set(HEADERS + TestTObject.h + RootMathDense.h + RootMuonScatter.h + RootHitRaw.h +) + +set(DICTIONARY_HEADERS + TestTObject.h + RootMathDense.h + RootMuonScatter.h + RootHitRaw.h +) + +SET(SOURCES + TestTObject.cpp + RootMuonScatter.cpp +) + + + +set(LIBRARIES +# ${Boost_SERIALIZATION_LIBRARY} +# ${Boost_SIGNALS_LIBRARY} +# ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${ROOT_LIBRARIES} + ${PACKAGE_LIBPREFIX}Core + ${PACKAGE_LIBPREFIX}Math +) + +include(FindROOTv6) +root_generate_dictionary(uLibRootDict ${DICTIONARY_HEADERS} LINKDEF Linkdef.h) +set_source_files_properties(uLibRootDict.cxx PROPERTIES GENERATED TRUE) +set_source_files_properties(uLibRootDict.h PROPERTIES GENERATED TRUE) +list(APPEND SOURCES uLibRootDict.cxx) + + +uLib_add_shared_library(${uLib-module}) +add_subdirectory(testing) diff --git a/src/Root/Linkdef.h b/src/Root/Linkdef.h new file mode 100644 index 0000000..8a7b5e7 --- /dev/null +++ b/src/Root/Linkdef.h @@ -0,0 +1,79 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_ROOT_LINKDEF_H +#define U_ROOT_LINKDEF_H + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; +#pragma link C++ nestedclasses; + +#pragma link C++ class TestTObject+; + +using namespace ROOT::Mutom; + +#pragma link C++ class ROOT::Math::Cartesian2D+; +#pragma link C++ class ROOT::Math::Cartesian2D+; +#pragma link C++ class ROOT::Math::Cartesian2D+; + +#pragma link C++ class ROOT::Math::Cartesian3D+; +#pragma link C++ class ROOT::Math::Cartesian3D+; +#pragma link C++ class ROOT::Math::Cartesian3D+; + +#pragma link C++ class Vector2i+; +#pragma link C++ class Vector2f+; +#pragma link C++ class Vector2d+; + +#pragma link C++ class Vector3i+; +#pragma link C++ class Vector3f+; +#pragma link C++ class Vector3d+; + +#pragma link C++ typedef Matrix3i; +#pragma link C++ typedef Matrix3f; +#pragma link C++ typedef Matrix3d; + +#pragma link C++ class Line3f+; +#pragma link C++ class Line3d+; + +#pragma link C++ class MuonScatter+; +#pragma link C++ function MuonScatter::p_mean() const; + +// #pragma link C++ class DetectorChamber+; + +#pragma link C++ class HitRaw+; +#pragma link C++ function HitRaw::Chm() const; +#pragma link C++ function HitRaw::Rob() const; +#pragma link C++ function HitRaw::Tdc() const; +#pragma link C++ function HitRaw::Ch() const; + + +#endif // __CINT__ + +#endif // LINKDEF_H diff --git a/src/Root/Makefile.am b/src/Root/Makefile.am new file mode 100644 index 0000000..868c022 --- /dev/null +++ b/src/Root/Makefile.am @@ -0,0 +1,20 @@ +SUBDIRS = . + +ROOTCINT = `which rootcint` + +include $(top_srcdir)/Common.am + +library_includedir = $(includedir)/libmutom-${PACKAGE_VERSION}/Root + +library_include_HEADERS = TestTObject.h + + +_CORE_SOURCES = TestTObject.cpp + + +MutomDict.cxx: $(library_include_HEADERS) Linkdef.h + $(ROOTCINT) -f $@ -c $(AM_CXXFLAGS) -p $^ + + +noinst_LTLIBRARIES = libmutomroot.la +libmutomroot_la_SOURCES = MutomDict.cxx ${_CORE_SOURCES} diff --git a/src/Root/RootHitMC.h b/src/Root/RootHitMC.h new file mode 100644 index 0000000..eef8541 --- /dev/null +++ b/src/Root/RootHitMC.h @@ -0,0 +1,50 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + +#ifndef ROOTHITMC_H +#define ROOTHITMC_H + +#include +#include + +namespace ROOT { +namespace Mutom { + +class HitMC { +public: + int chm; // chamber id + Vector3f pos; // hit position in local coords + float_t drift; // drift time + enum TMCParticleType ptype; +}; + + + +} // Mutom +} // ROOT + + +#endif // ROOTHITMC_H diff --git a/src/Root/RootHitRaw.h b/src/Root/RootHitRaw.h new file mode 100644 index 0000000..756c959 --- /dev/null +++ b/src/Root/RootHitRaw.h @@ -0,0 +1,71 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + +#ifndef ROOTHITRAW_H +#define ROOTHITRAW_H + +#include + +namespace ROOT { +namespace Mutom { + + + +class Hit32 { +public: + Int_t code; + Float_t drift; +}; + +class Hit64 { +public: + Long_t code; + Double_t drift; +}; + + + +class HitRaw +{ +public: + virtual Int_t Flags() {} + virtual Int_t Chm() const {} + virtual Int_t Rob() const {} + virtual Int_t Tdc() const {} + virtual Int_t Ch() const {} + virtual void SetFlags (Int_t flags) = 0; + virtual void SetChamber(Int_t cmb) = 0; + virtual void SetChannel(Int_t Rob, Int_t Tdc, Int_t Ch) = 0; + virtual float operator() ( ) {} +protected: + virtual ~HitRaw() {} +}; + + + +} // Mutom +} // ROOT + +#endif // ROOTHITRAW_H diff --git a/src/Root/RootMathDense.h b/src/Root/RootMathDense.h new file mode 100644 index 0000000..1435d77 --- /dev/null +++ b/src/Root/RootMathDense.h @@ -0,0 +1,68 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef ROOTMATHDENSE_H +#define ROOTMATHDENSE_H + + +#include +#include + +#include + +namespace ROOT { +namespace Mutom { + +typedef ROOT::Math::Cartesian2D Vector2i; +typedef ROOT::Math::Cartesian2D Vector2f; +typedef ROOT::Math::Cartesian2D Vector2d; + +typedef ROOT::Math::Cartesian3D Vector3i; +typedef ROOT::Math::Cartesian3D Vector3f; +typedef ROOT::Math::Cartesian3D Vector3d; + +typedef ROOT::Math::MatRepStd Matrix3i; +typedef ROOT::Math::MatRepStd Matrix3f; +typedef ROOT::Math::MatRepStd Matrix3d; + + +template +struct Line3D +{ + ROOT::Math::Cartesian3D origin,direction; +}; + + +typedef Line3D Line3f; +typedef Line3D Line3d; + + + +} // Mutom +} // ROOT + +#endif // ROOTMATHDENSE_H diff --git a/src/Root/RootMuonScatter.cpp b/src/Root/RootMuonScatter.cpp new file mode 100644 index 0000000..ce0e854 --- /dev/null +++ b/src/Root/RootMuonScatter.cpp @@ -0,0 +1,75 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "RootMuonScatter.h" +#include "Detectors/MuonScatter.h" + + +namespace ROOT { +namespace Mutom { + +MuonScatter &operator <<(MuonScatter &rmu, const uLib::MuonScatter &mu) +{ + + rmu.in.origin.SetX(mu.LineIn().origin()(0)); + rmu.in.origin.SetY(mu.LineIn().origin()(1)); + rmu.in.origin.SetZ(mu.LineIn().origin()(2)); + rmu.in.direction.SetX(mu.LineIn().direction()(0)); + rmu.in.direction.SetY(mu.LineIn().direction()(1)); + rmu.in.direction.SetZ(mu.LineIn().direction()(2)); + + rmu.out.origin.SetX(mu.LineOut().origin()(0)); + rmu.out.origin.SetY(mu.LineOut().origin()(1)); + rmu.out.origin.SetZ(mu.LineOut().origin()(2)); + rmu.out.direction.SetX(mu.LineOut().direction()(0)); + rmu.out.direction.SetY(mu.LineOut().direction()(1)); + rmu.out.direction.SetZ(mu.LineOut().direction()(2)); + + rmu.in.p = mu.GetMomentum(); + rmu.out.p = mu.GetMomentumPrime(); + + return rmu; +} + +uLib::MuonScatter &operator >>(const MuonScatter &rmu, uLib::MuonScatter &mu) { + + mu.LineIn().origin() << rmu.in.origin.x(), rmu.in.origin.z(), rmu.in.origin.z(); + mu.LineIn().direction() << rmu.in.direction.x(), rmu.in.direction.z(), rmu.in.direction.z(); + mu.LineOut().origin() << rmu.out.origin.x(), rmu.out.origin.z(), rmu.out.origin.z(); + mu.LineOut().direction() << rmu.out.direction.x(), rmu.out.direction.z(), rmu.out.direction.z(); + + mu.SetMomentum(rmu.in.p); + mu.SetMomentumPrime(rmu.out.p); + + return mu; +} + + + +} +} + diff --git a/src/Root/RootMuonScatter.h b/src/Root/RootMuonScatter.h new file mode 100644 index 0000000..2d82284 --- /dev/null +++ b/src/Root/RootMuonScatter.h @@ -0,0 +1,66 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef ROOTMUONSCATTER_H +#define ROOTMUONSCATTER_H + +#include + +namespace uLib { +class MuonScatter; +} + + +namespace ROOT { +namespace Mutom { + +struct MuonTrack { + Vector3f origin; + Vector3f direction; + float p; +}; + +struct MuonScatter { +public: + MuonTrack in,out; + MuonTrack in_err, out_err; + inline Vector2f p_mean() const; +}; + +// this is only for testing function link in dictionary ... // +Vector2f MuonScatter::p_mean() const { + return Vector2f( (in.p + out.p)/2, (in_err.p + out_err.p)/2 ); +} + +MuonScatter &operator <<(MuonScatter &rmu, const uLib::MuonScatter &mu); +uLib::MuonScatter &operator >>(const MuonScatter &rmu, uLib::MuonScatter &mu); + + +} // Mutom +} // ROOT + +#endif // ROOTMUONSCATTER_H diff --git a/src/Root/TestTObject.cpp b/src/Root/TestTObject.cpp new file mode 100644 index 0000000..213c9ea --- /dev/null +++ b/src/Root/TestTObject.cpp @@ -0,0 +1,31 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "TestTObject.h" + + +ClassImp(TestTObject) diff --git a/src/Root/TestTObject.h b/src/Root/TestTObject.h new file mode 100644 index 0000000..d7041e7 --- /dev/null +++ b/src/Root/TestTObject.h @@ -0,0 +1,47 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_ROOT_TESTTOBJECT_H +#define U_ROOT_TESTTOBJECT_H + +#include +#include +#include +#include + +class TestTObject : public TObject { +public: + int a,b,c; + TestTObject() : a(1),b(2),c(3) {} + virtual ~TestTObject() {} + ClassDef(TestTObject,1) +}; + + + + +#endif // TESTTOBJECT_H diff --git a/src/Root/testing/CMakeLists.txt b/src/Root/testing/CMakeLists.txt new file mode 100644 index 0000000..28f190a --- /dev/null +++ b/src/Root/testing/CMakeLists.txt @@ -0,0 +1,15 @@ +# TESTS +set( TESTS + RootDebugTest +) + +set(LIBRARIES + ${PACKAGE_LIBPREFIX}Core + ${PACKAGE_LIBPREFIX}Math + ${PACKAGE_LIBPREFIX}Root + ${Boost_SERIALIZATION_LIBRARY} + ${Boost_SIGNALS_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${ROOT_LIBRARIES} +) +uLib_add_tests(${uLib-module}) diff --git a/src/Root/testing/Makefile.am b/src/Root/testing/Makefile.am new file mode 100644 index 0000000..730b659 --- /dev/null +++ b/src/Root/testing/Makefile.am @@ -0,0 +1,20 @@ +include $(top_srcdir)/Common.am + +#AM_DEFAULT_SOURCE_EXT = .cpp + +# if HAVE_CHECK +TESTS = RootDebugTest + +# UuidTest + +# else +# TEST = +# endif + +LDADD = $(top_srcdir)/libmutom-${PACKAGE_VERSION}.la $(AM_LIBS_BOOST) $(AM_LIBS_ROOT) + +check_PROGRAMS = $(TESTS) + + +all: $(TESTS) + diff --git a/src/Root/testing/RootDebugTest.cpp b/src/Root/testing/RootDebugTest.cpp new file mode 100644 index 0000000..7a44b53 --- /dev/null +++ b/src/Root/testing/RootDebugTest.cpp @@ -0,0 +1,122 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include +#include +#include +#include +#include +#include + +#include "Root/TestTObject.h" +#include "Root/RootMuonScatter.h" + +#include "Detectors/MuonScatter.h" + +TTree * getTree(TFile *m_File, const char *path, const char *name) { + std::string p = std::string("/") + std::string(path); + TDirectory *dir = m_File->GetDirectory(p.c_str()); + if(!dir) { + m_File->mkdir(path); + } + m_File->cd(path); + std::string n = p + std::string("/") + std::string(name); + TObject *obj = m_File->Get(n.c_str()); + if(!obj) { + TTree *tree = new TTree(); + tree->SetName(name); + return tree; + } + else { + return (TTree *)obj; + } +} + + +int main(int argc,char **argv) { + + uLib::MuonScatter u_mu; + ROOT::Mutom::MuonScatter mu; + ROOT::Mutom::Vector3f v3f(0,1,0); + + TFile *file = new TFile("test_file.root","RECREATE"); + TTree *tree = getTree(file,"testing/dump","testing_tree"); + TTree *tree2 = getTree(file,"new_dump","testing_tree"); + + tree->Branch("mu",&mu); + tree->AddFriend(tree2); + + + mu.in.origin = ROOT::Mutom::Vector3f(1,2,3); + mu.in.direction = ROOT::Mutom::Vector3f(4,5,6); + mu.p_in = 555; + mu.p_out = 2368; + + tree->Fill(); + + u_mu.LineIn().origin << 3,3,3; + u_mu.LineIn().direction << 5,5,5; + u_mu.LineOut().origin << 1,2,3; + u_mu.LineOut().direction << 4,5,6; + u_mu.SetMomentum(555); + u_mu.SetMomentumPrime(2368); + + mu << u_mu; + + tree->Fill(); + + tree2->Branch("vec",&v3f); + tree2->Branch("p_in",&mu.p_in); + tree2->Branch("p_out",&mu.p_out); + mu.p_in = 1; + mu.p_out = 2; + tree2->Fill(); + + file->cd("/testing/dump"); + tree->Write(); + file->cd("/new_dump"); + tree2->Write(); + + TText text(0,0,"this file contain a muon scatter event"); + file->cd("/"); + text.Write("content"); + + + + gApplication = new TApplication("Application", &argc, argv); + TBrowser *tbr = new TBrowser("test"); + tbr->Show(); + + + gApplication->Run(); + + + + return 0; +} diff --git a/src/Vtk/CMakeLists.txt b/src/Vtk/CMakeLists.txt new file mode 100644 index 0000000..c26cf09 --- /dev/null +++ b/src/Vtk/CMakeLists.txt @@ -0,0 +1,39 @@ +set(HEADERS + uLibVtkInterface.h + uLibVtkViewer.h + vtkContainerBox.h + vtkMuonScatter.h + vtkStructuredGrid.h + vtkVoxRaytracerRepresentation.h + vtkVoxImage.h +# vtkHLineRepresentation.h +# vtkTriangleMesh.h +) + +SET(SOURCES + uLibVtkInterface.cxx + uLibVtkViewer.cpp + vtkContainerBox.cpp + vtkMuonScatter.cxx + vtkStructuredGrid.cpp + vtkVoxRaytracerRepresentation.cpp + vtkVoxImage.cpp +) + +set(LIBRARIES + ${Boost_SERIALIZATION_LIBRARY} + ${Boost_SIGNALS_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Eigen_LIBRARY} + ${ROOT_LIBRARIES} + ${Geant4_LIBRARIES} + ${VTK_LIBRARIES} + ${PACKAGE_LIBPREFIX}Core + ${PACKAGE_LIBPREFIX}Math + ${PACKAGE_LIBPREFIX}Detectors + ${PACKAGE_LIBPREFIX}Vtk +) + +uLib_add_shared_library(${uLib-module}) + +add_subdirectory(testing) diff --git a/src/Vtk/Makefile.am b/src/Vtk/Makefile.am new file mode 100644 index 0000000..9d175a5 --- /dev/null +++ b/src/Vtk/Makefile.am @@ -0,0 +1,34 @@ +SUBDIRS = . + +include $(top_srcdir)/Common.am +include Vtk.am + + +library_includedir = $(includedir)/libmutom-${PACKAGE_VERSION}/Vtk +library_include_HEADERS = uLibVtkInterface.h \ + uLibVtkViewer.h \ + vtkContainerBox.h \ + vtkMuonScatter.h \ + vtkStructuredGrid.h \ + vtkVoxRaytracerRepresentation.h \ + vtkVoxImage.h +# vtkHLineRepresentation.h \ +# vtkTriangleMesh.h + + +_VTK_SOURCES = uLibVtkInterface.cxx \ + uLibVtkViewer.cpp \ + vtkContainerBox.cpp \ + vtkMuonScatter.cxx \ + vtkStructuredGrid.cpp \ + vtkVoxRaytracerRepresentation.cpp \ + vtkVoxImage.cpp +#vtkTriangleMesh.cpp + + + +noinst_LTLIBRARIES = libconvtk.la +libconvtk_la_SOURCES = ${_VTK_SOURCES} +libconvtk_la_LIBADD = $(AM_LIBS_ALL) + + diff --git a/src/Vtk/Vtk.am b/src/Vtk/Vtk.am new file mode 100644 index 0000000..27e030a --- /dev/null +++ b/src/Vtk/Vtk.am @@ -0,0 +1,93 @@ + + +#if VTK_5_x +_VTK_LIBS = -lQVTK \ + -lLSDyna \ + -lMapReduceMPI \ + -lmpistubs \ + -lvtkalglib \ + -lvtkCharts \ + -lvtkCommon \ + -lvtkDICOMParser \ + -lvtkexoIIc \ + -lvtkFiltering \ + -lvtkftgl \ + -lvtkGenericFiltering \ + -lvtkGraphics \ + -lvtkHybrid \ + -lvtkImaging \ + -lvtkInfovis \ + -lvtkmetaio \ + -lvtkNetCDF_cxx \ + -lvtkNetCDF \ + -lvtkproj4 \ + -lvtkRendering \ + -lvtksqlite \ + -lvtksys \ + -lvtkverdict \ + -lvtkViews \ + -lvtkVolumeRendering \ + -lvtkWidgets + +AM_CFLAGS += $(VTK_CFLAGS) +AM_CXXFLAGS += $(VTK_CXXFLAGS) +AM_LDFLAGS += $(VTK_LDFLAGS) $(_VTK_LIBS) + +#else +#_VTK_LIBS = \ +# -lvtkRenderingOpenGL-6.0 \ +# -lvtkImagingHybrid-6.0 \ +# -lvtkIOImage-6.0 \ +# -lvtkCommonDataModel-6.0 \ +# -lvtkCommonMath-6.0 \ +# -lvtkCommonCore-6.0 \ +# -lvtksys-6.0 \ +# -lvtkCommonMisc-6.0 \ +# -lvtkCommonSystem-6.0 \ +# -lvtkCommonTransforms-6.0 \ +# -lvtkCommonExecutionModel-6.0 \ +# -lvtkDICOMParser-6.0 \ +# -lvtkIOCore-6.0 \ +# -lvtkzlib-6.0 \ +# -lvtkmetaio-6.0 \ +# -lvtkjpeg-6.0 \ +# -lvtkpng-6.0 \ +# -lvtktiff-6.0 \ +# -lvtkImagingCore-6.0 \ +# -lvtkRenderingCore-6.0 \ +# -lvtkFiltersExtraction-6.0 \ +# -lvtkFiltersCore-6.0 \ +# -lvtkFiltersGeneral-6.0 \ +# -lvtkCommonComputationalGeometry-6.0 \ +# -lvtkFiltersStatistics-6.0 \ +# -lvtkImagingFourier-6.0 \ +# -lvtkalglib-6.0 \ +# -lvtkFiltersGeometry-6.0 \ +# -lvtkFiltersSources-6.0 \ +# -lvtkIOXMLParser-6.0 \ +# -lvtkexpat-6.0 \ +# -lvtkRenderingAnnotation-6.0 \ +# -lvtkImagingColor-6.0 \ +# -lvtkRenderingFreeType-6.0 \ +# -lvtkfreetype-6.0 \ +# -lvtkftgl-6.0 \ +# -lvtkInteractionStyle-6.0 \ +# -lvtkRenderingVolumeOpenGL-6.0 \ +# -lvtkRenderingVolume-6.0 \ +# -lvtkIOXML-6.0 \ +# -lvtkIOGeometry-6.0 \ +# -lvtkjsoncpp-6.0 \ +# -lvtkInteractionWidgets-6.0 \ +# -lvtkFiltersHybrid-6.0 \ +# -lvtkImagingSources-6.0 \ +# -lvtkFiltersModeling-6.0 \ +# -lvtkImagingGeneral-6.0 \ +# -lvtkIOLegacy-6.0 \ +# -lvtkRenderingFreeTypeOpenGL-6.0 + + + +#AM_CFLAGS += $(VTK_CFLAGS) +#AM_CXXFLAGS += $(VTK_CXXFLAGS) -rdynamic +#AM_LDFLAGS += $(VTK_LDFLAGS) $(_VTK_LIBS) -lGLU -lSM -lICE -lX11 -lXext -lSM -lICE -lX11 -lXext -lXt -lm -ldl -lGL +#endif diff --git a/src/Vtk/testing/CMakeLists.txt b/src/Vtk/testing/CMakeLists.txt new file mode 100644 index 0000000..33a3847 --- /dev/null +++ b/src/Vtk/testing/CMakeLists.txt @@ -0,0 +1,13 @@ +# TESTS +set( TESTS + vtkViewerTest + vtkContainerBoxTest + vtkMuonScatter + vtkStructuredGridTest + vtkVoxRaytracerTest + vtkVoxImageTest +# vtkTriangleMeshTest +) + +include(${VTK_USE_FILE}) +uLib_add_tests(${uLib-module}) diff --git a/src/Vtk/testing/Makefile.am b/src/Vtk/testing/Makefile.am new file mode 100644 index 0000000..4cc3180 --- /dev/null +++ b/src/Vtk/testing/Makefile.am @@ -0,0 +1,21 @@ + +include $(top_srcdir)/Common.am +include ../Vtk.am + +#AM_DEFAULT_SOURCE_EXT = .cpp + +# if HAVE_CHECK +TESTS = \ + vtkViewerTest \ + vtkContainerBoxTest \ + vtkMuonScatter \ + vtkStructuredGridTest \ + vtkVoxRaytracerTest \ + vtkVoxImageTest +# vtkTriangleMeshTest + +all: $(TESTS) + +LDADD = $(top_srcdir)/libmutom-${PACKAGE_VERSION}.la $(AM_LIBS_ALL) +check_PROGRAMS = $(TESTS) + diff --git a/src/Vtk/testing/testVtkWriter.cpp b/src/Vtk/testing/testVtkWriter.cpp new file mode 100644 index 0000000..5f8dc2d --- /dev/null +++ b/src/Vtk/testing/testVtkWriter.cpp @@ -0,0 +1,95 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include +#include +#include +#include +#include + +#include + + +#include +#include + +int main(int, char *[]) +{ + // Create an image data + vtkSmartPointer imageData = + vtkSmartPointer::New(); + + // Specify the size of the image data + imageData->SetDimensions(10,20,15); +#if VTK_MAJOR_VERSION <= 5 + imageData->SetNumberOfScalarComponents(1); + imageData->SetScalarTypeToDouble(); +#else + imageData->AllocateScalars(VTK_DOUBLE,1); +#endif + + int* dims = imageData->GetDimensions(); + // int dims[3]; // can't do this + + std::cout << "Dims: " << " x: " << dims[0] << " y: " << dims[1] << " z: " << dims[2] << std::endl; + + std::cout << "Number of points: " << imageData->GetNumberOfPoints() << std::endl; + std::cout << "Number of cells: " << imageData->GetNumberOfCells() << std::endl; + + // Fill every entry of the image data with "2.0" + for (int z = 0; z < dims[2]; z++) + { + for (int y = 0; y < dims[1]; y++) + { + for (int x = 0; x < dims[0]; x++) + { + double* pixel = static_cast(imageData->GetScalarPointer(x,y,z)); + pixel[0] = (double)x+y+z; + } + } + } + + // imageData->GetCellData()->SetScalars(imageData->GetPointData()->GetScalars()); + + vtkSmartPointer ptoc = + vtkSmartPointer::New(); + + ptoc->SetInputConnection(imageData->GetProducerPort()); + + ptoc->Update(); + + vtkSmartPointer writer = + vtkSmartPointer::New(); + + + writer->SetInput(ptoc->GetImageDataOutput()); + writer->SetFileTypeToASCII(); + writer->SetFileName("output.vtk"); + writer->Update(); + + return EXIT_SUCCESS; +} diff --git a/src/Vtk/testing/testing-prototype.h b/src/Vtk/testing/testing-prototype.h new file mode 100644 index 0000000..c801261 --- /dev/null +++ b/src/Vtk/testing/testing-prototype.h @@ -0,0 +1,41 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include + +#include "Vtk/uLibVtkInterface.h" + + +#define BEGIN_TESTING(name) \ +static int _fail = 0; \ +printf("..:: Testing " #name " ::..\n"); + +#define TEST1(val) _fail += (val)==0 +#define TEST0(val) _fail += (val)!=0 +#define END_TESTING return _fail; + + diff --git a/src/Vtk/testing/vtkContainerBoxTest.cpp b/src/Vtk/testing/vtkContainerBoxTest.cpp new file mode 100644 index 0000000..7c477ef --- /dev/null +++ b/src/Vtk/testing/vtkContainerBoxTest.cpp @@ -0,0 +1,53 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "Vtk/uLibVtkViewer.h" + +#include "Math/ContainerBox.h" +#include "Vtk/vtkContainerBox.h" + +#include "testing-prototype.h" + +using namespace uLib; + +int main() { + BEGIN_TESTING(vtk ContainerBox Test); + + Vtk::Viewer v_viewer; + + ContainerBox box; + box.SetSize(Vector3f(2,3,4)); + box.SetPosition(Vector3f(1,2,3)); + + Vtk::vtkContainerBox v_box(box); + + v_viewer.AddPuppet(v_box); + v_viewer.Start(); + + + END_TESTING; +} diff --git a/src/Vtk/testing/vtkMuonScatter.cpp b/src/Vtk/testing/vtkMuonScatter.cpp new file mode 100644 index 0000000..2c9e7ca --- /dev/null +++ b/src/Vtk/testing/vtkMuonScatter.cpp @@ -0,0 +1,62 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "Detectors/MuonScatter.h" +#include "Vtk/vtkMuonScatter.h" + +#include "Vtk/uLibVtkViewer.h" + +#include "testing-prototype.h" + +using namespace uLib; + +int main() +{ + MuonScatter event; + event.LineIn().direction << 0, -1, 1, 0; + event.LineIn().origin << 0, 1, -1, 1; + + event.LineOut().direction << 0, -1, 0, 0; + event.LineOut().origin << 0, -1, 0, 1; + + Vtk::vtkMuonScatter v_event(event); + v_event.AddPocaPoint(HPoint3f(0,0,0)); + + v_event.SaveToXMLFile("vtk_testing_muonevent.vtp"); + + Vtk::Viewer viewer; + +// Vtk::Tie tms; +// tms.DoAction(); +// Vtk::Tie vms; +// vms.DoAction(); + + viewer.AddPuppet(v_event); + viewer.Start(); + + return 0; +} diff --git a/src/Vtk/testing/vtkStructuredGridTest.cpp b/src/Vtk/testing/vtkStructuredGridTest.cpp new file mode 100644 index 0000000..a2c2d51 --- /dev/null +++ b/src/Vtk/testing/vtkStructuredGridTest.cpp @@ -0,0 +1,51 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Math/ImageData.h" + +#include "Vtk/vtkStructuredGrid.h" +#include "Vtk/uLibVtkViewer.h" + +#include "testing-prototype.h" + +using namespace uLib; + +int main() +{ + + ImageData grid(Vector3i(10,10,100)); + grid.SetSpacing(Vector3f(3,1,1)); + + Vtk::vtkStructuredGrid grid_viewer(grid); + + Vtk::Viewer viewer; + viewer.AddPuppet(grid_viewer); + viewer.Start(); + + return 0; +} diff --git a/src/Vtk/testing/vtkTriangleMeshTest.cpp b/src/Vtk/testing/vtkTriangleMeshTest.cpp new file mode 100644 index 0000000..5d12e6d --- /dev/null +++ b/src/Vtk/testing/vtkTriangleMeshTest.cpp @@ -0,0 +1,75 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Math/TriangleMesh.h" +#include "Vtk/vtkTriangleMesh.h" +#include "testing-prototype.h" + +using namespace uLib; + + +int main() +{ + BEGIN_TESTING(Vtk Triangle Mesh); + +// { // SIMPLE TESTS // + + +// TriangleMesh mesh; + +// mesh.AddPoint(Vector3f(0,0,0)); +// mesh.AddPoint(Vector3f(0,1,0)); +// mesh.AddPoint(Vector3f(1,0,0)); + +// mesh.AddTriangle(Vector3i(0,1,2)); + +// mesh.PrintSelf(std::cout); + + +// vtkTriangleMesh v_mesh(mesh); +// v_mesh.Update(); + +// TestingRenderWidow(&v_mesh); +// } + + { // SIMPLE TESTS // + + TriangleMesh mesh; + + vtkTriangleMesh v_mesh(mesh); + + v_mesh.ReadFromStlFile("prova.stl"); + + mesh.PrintSelf(std::cout); + + TestingRenderWidow(&v_mesh); + } + + + END_TESTING; +} diff --git a/src/Vtk/testing/vtkViewerTest.cpp b/src/Vtk/testing/vtkViewerTest.cpp new file mode 100644 index 0000000..22a42f8 --- /dev/null +++ b/src/Vtk/testing/vtkViewerTest.cpp @@ -0,0 +1,71 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include +#include +#include +#include + +#include "testing-prototype.h" + +using namespace uLib; + +int main() +{ + BEGIN_TESTING(vtk Viewer Test); + + Vtk::Viewer v_viewer; + + + vtkSmartPointer cube = vtkSmartPointer::New(); + cube->SetXLength(10); + cube->SetYLength(10); + cube->SetZLength(10); + cube->Update(); + + vtkSmartPointer mapper = + vtkSmartPointer::New(); + mapper->SetInputConnection(cube->GetOutputPort()); + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + v_viewer.addProp(actor); + v_viewer.GetRenderer()->Render(); + v_viewer.Start(); + + END_TESTING; +} + diff --git a/src/Vtk/testing/vtkVoxImageTest.cpp b/src/Vtk/testing/vtkVoxImageTest.cpp new file mode 100644 index 0000000..579bf62 --- /dev/null +++ b/src/Vtk/testing/vtkVoxImageTest.cpp @@ -0,0 +1,102 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Math/VoxImage.h" +#include "Vtk/vtkVoxImage.h" +#include "Vtk/uLibVtkViewer.h" + +#include "testing-prototype.h" + +using namespace uLib; + +struct TestVoxel { + Scalarf Value; + unsigned int Count; +}; + +int main() +{ + BEGIN_TESTING(Vtk Vox Image); + + TestVoxel zero = {0,0}; + TestVoxel nonzero = {5.5*1E-6,100}; + +// { // SIMPLE TESTS // +// VoxImage img(Vector3i(10,10,10)); +// img.SetSpacing(Vector3f(3,3,3)); + +// img.InitVoxels(zero); +// img[Vector3i(3,3,3)] = nonzero; + +// Vtk::vtkVoxImage vtk_img(img); + +// vtk_img.SaveToXMLFile("test.vti"); +// vtk_img.setShadingPreset(0); + +// // vtk_img.ReadFromVKTFile("error.vtk"); + +// // VoxImage img2 = img; + +// // Vtk::vtkVoxImage vtk_img2(img2); + +// // img2.ExportToVtk("error_saved.vtk",0); + +// // vtk_img2.SaveToXMLFile("error_saved.vti"); + +// Vtk::Viewer viewer; +// viewer.AddPuppet(vtk_img); +// viewer.Start(); +// } + + { // SIMPLE TESTS // + VoxImage img(Vector3i(10,10,1)); + img.SetSpacing(Vector3f(3,3,3)); + + img.InitVoxels(zero); + img[Vector3i(3,3,0)] = nonzero; + + Vtk::vtkVoxImage vtk_img(img); + + vtk_img.ReadFromVKTFile("test.vtk"); + vtk_img.Update(); + + // vtk_img.SaveToXMLFile("test.vti"); + // vtk_img.setShadingPreset(0); + + // Vtk::vtkVoxImage vtk_img2(img2); + // img2.ExportToVtk("error_saved.vtk",0); + // vtk_img2.SaveToXMLFile("error_saved.vti"); + + Vtk::Viewer viewer; + viewer.AddPuppet(vtk_img); + viewer.Start(); + } + + + END_TESTING; +} diff --git a/src/Vtk/testing/vtkVoxRaytracerTest.cpp b/src/Vtk/testing/vtkVoxRaytracerTest.cpp new file mode 100644 index 0000000..7bd8816 --- /dev/null +++ b/src/Vtk/testing/vtkVoxRaytracerTest.cpp @@ -0,0 +1,156 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include +#include +#include + + +#include +#include + +#include "Vtk/vtkMuonScatter.h" +#include "Vtk/vtkStructuredGrid.h" +#include "Vtk/vtkVoxRaytracerRepresentation.h" +#include "Vtk/uLibVtkViewer.h" + +// remove +#include + +#include "testing-prototype.h" + +using namespace uLib; + + + +class vtkWidgetCallback : public vtkCommand +{ +public: + static vtkWidgetCallback *New() { return new vtkWidgetCallback; } + + void SetTracer(Vtk::vtkVoxRaytracerRepresentation *parent) + { + this->vtk_raytr = parent; + } + + void SetMuon (uLib::MuonScatter *muon) { this->muon = muon; } + + void SetAnnotation ( vtkCornerAnnotation *annotation) { + this->annotation = annotation; + } + + virtual void Execute(vtkObject *caller, unsigned long, void*) + { + char str[40]; + vtk_raytr->SetMuon(*muon); + if(annotation) + { + sprintf(str,"total length = %f",vtk_raytr->GetRay().TotalLength()); + annotation->SetText(1,str); + for(int i=0; iGetRay().Data().size(); ++i) + { + std::cout << "L[" << i << "] = " + << vtk_raytr->GetRay().Data().at(i).L << "\n"; + } + std::cout << "\n"; + } + } + +private: + vtkWidgetCallback() : + vtk_raytr(NULL), + muon(NULL), + annotation(NULL) {} + + uLib::VoxRaytracer *raytracer; + Vtk::vtkVoxRaytracerRepresentation *vtk_raytr; + uLib::MuonScatter *muon; + vtkCornerAnnotation *annotation; +}; + + + + +int main() +{ + BEGIN_TESTING(vtk VoxRaytracer); + + + // muon scatter // + MuonScatter muon; + muon.LineIn().origin << -6, 12, -6, 1; + muon.LineIn().direction << 1 , -1 , 1 , 0; + muon.LineOut().origin << 6 , -4 , 6 , 1; + muon.LineOut().direction << 1 , -1 , 1 , 0; + + Vtk::vtkMuonScatter v_muon(muon); + + + // structured grid // + ImageData grid(Vector3i(12,10,12)); + grid.SetSpacing(Vector3f(1,1,1)); + grid.SetPosition(Vector3f(0,0,0)); + + + Vtk::vtkStructuredGrid v_grid(grid); + + + // voxraytracer // + VoxRaytracer rt(grid); + HPoint3f pt; + rt.GetEntryPoint(muon.LineIn(),pt); + std::cout << pt.transpose() << "\n"; + + Vtk::vtkVoxRaytracerRepresentation v_rt(rt); + v_rt.SetMuon(muon); + v_rt.SetRayColor(Vector4f(1,0,0,1)); + + // // renderer // + Vtk::Viewer viewer; + + // widget // + vtkBoxWidget *widget = v_grid.GetWidget(); + + + vtkWidgetCallback *cbk = vtkWidgetCallback::New(); + cbk->SetTracer(&v_rt); + cbk->SetMuon(&muon); + cbk->SetAnnotation(viewer.GetAnnotation()); + widget->AddObserver(vtkCommand::InteractionEvent, cbk); + widget->SetInteractor(viewer.GetInteractor()); + widget->PlaceWidget(); + widget->On(); + + viewer.AddPuppet(v_grid); + viewer.AddPuppet(v_rt); + viewer.AddPuppet(v_muon); + viewer.Start(); + + + END_TESTING; +} diff --git a/src/Vtk/uLibVtkInterface.cxx b/src/Vtk/uLibVtkInterface.cxx new file mode 100644 index 0000000..15a06a6 --- /dev/null +++ b/src/Vtk/uLibVtkInterface.cxx @@ -0,0 +1,238 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#if VTK_MAJOR_VERSION <= 5 +# +#else +# include +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "uLibVtkInterface.h" + + + + + + + +namespace uLib { +namespace Vtk { + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// POLYDATA // + + +void Polydata::SaveToFile(const char *vtk_file) +{ + vtkSmartPointer writer = + vtkSmartPointer::New(); + writer->SetFileName(vtk_file); + vtkPolyData * data = GetPolyData(); + if(data) { +# if VTK_MAJOR_VERSION <= 5 + writer->SetInputConnection(data->GetProducerPort()); +# else + writer->SetInputData(data); +# endif + writer->Update(); + } +} + +void Polydata::SaveToXMLFile(const char *vtp_file) +{ + vtkSmartPointer writer = + vtkSmartPointer::New(); + writer->SetFileName(vtp_file); + vtkPolyData * data = GetPolyData(); + if(data) { +# if VTK_MAJOR_VERSION <= 5 + writer->SetInputConnection(data->GetProducerPort()); +# else + writer->SetInputData(data); +# endif + writer->Update(); + } +} + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// PUPPET // + +// PIMPL -------------------------------------------------------------------- // + +class PuppetData { +public: + PuppetData() : + m_Renderers(vtkRendererCollection::New()), + m_Assembly(vtkPropAssembly::New()) + {} + + ~PuppetData() { + m_Renderers->RemoveAllItems(); + m_Assembly->GetParts()->RemoveAllItems(); + m_Renderers->Delete(); + m_Assembly->Delete(); + } + + // members // + vtkRendererCollection *m_Renderers; + vtkPropAssembly *m_Assembly; +}; + +// -------------------------------------------------------------------------- // + + + + +Puppet::Puppet() : d(new PuppetData) { } + +Puppet::~Puppet() +{ + delete d; +} + +vtkProp *Puppet::GetProp() +{ + if (d->m_Assembly->GetParts()->GetNumberOfItems() == 1) + { + // d->m_Assembly->GetParts()->InitTraversal(); + // return d->m_Assembly->GetParts()->GetNextProp(); + return d->m_Assembly->GetParts()->GetLastProp(); + } + else return d->m_Assembly; +} + +void Puppet::SetProp(vtkProp *prop) +{ + if(prop) d->m_Assembly->AddPart(prop); +} + +void Puppet::RemoveProp(vtkProp *prop) +{ + // TODO +} + + +vtkPropCollection *Puppet::GetProps() +{ + return d->m_Assembly->GetParts(); +} + +void Puppet::ConnectRenderer(vtkRenderer *renderer) +{ + if(renderer) { + this->GetRenderers()->AddItem(renderer); + if(d->m_Assembly->GetParts()->GetNumberOfItems() == 1) + renderer->AddActor(this->GetProp()); + else if(d->m_Assembly->GetParts()->GetNumberOfItems() >0) + { + vtkPropCollection *props = d->m_Assembly->GetParts(); + props->InitTraversal(); + for (int i=0; iGetNumberOfItems(); ++i) + renderer->AddActor(props->GetNextProp()); + } + } +} + +void Puppet::DisconnectRenderer(vtkRenderer *renderer) +{ + if(renderer) { + if(this->GetProp()) + renderer->RemoveViewProp(this->GetProp()); + else if(d->m_Assembly->GetParts()->GetNumberOfItems() >0) + { + vtkPropCollection *props = d->m_Assembly->GetParts(); + props->InitTraversal(); + for (int i=0; iGetNumberOfItems(); ++i) + renderer->RemoveViewProp(props->GetNextProp()); + } + this->GetRenderers()->RemoveItem(renderer); + } +} + +void Puppet::ConnectViewer(Viewer *viewer) +{ + // TODO +} + +void Puppet::DisonnectViewer(Viewer *viewer) +{ + // TODO +} + +vtkRendererCollection *Puppet::GetRenderers() const +{ + return d->m_Renderers; +} + +void Puppet::PrintSelf(std::ostream &o) const +{ + o << "Props Assembly: \n"; + d->m_Assembly->PrintSelf(o,vtkIndent(1)); + + o << "Connected Renderers: \n"; + d->m_Renderers->PrintSelf(o,vtkIndent(1)); +} + + + + + + + + + + +} // Vtk +} // uLib diff --git a/src/Vtk/uLibVtkInterface.h b/src/Vtk/uLibVtkInterface.h new file mode 100644 index 0000000..1e2687a --- /dev/null +++ b/src/Vtk/uLibVtkInterface.h @@ -0,0 +1,124 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef ULIBVTKINTERFACE_H +#define ULIBVTKINTERFACE_H + + + +#include +#include + +#include +#include + + + +// vtk classes forward declaration // +class vtkProp; +class vtkPolyData; +class vtkPropCollection; +class vtkRenderer; +class vtkRendererCollection; + + +namespace uLib { +namespace Vtk { + + + +//template +//class Tie { + +//public: +// typedef T Content; + + +//}; + + + +class Puppet : public Object +{ + uLibTypeMacro(Puppet, Object) +public: + Puppet(); + ~Puppet(); + + virtual vtkProp * GetProp(); + + virtual vtkPropCollection * GetProps(); + + void ConnectRenderer(vtkRenderer *renderer); + + void DisconnectRenderer(vtkRenderer *renderer); + + void ConnectViewer(class Viewer *viewer); + + void DisonnectViewer(class Viewer *viewer); + + vtkRendererCollection * GetRenderers() const; + + + virtual void PrintSelf(std::ostream &o) const; + + virtual void ConnectInteractor(class vtkRenderWindowInteractor *interactor) { (void)interactor; } + +protected: + + void SetProp(vtkProp *prop); + + void RemoveProp(vtkProp *prop); + +private: + friend class PuppetData; + class PuppetData *d; +}; + + + + +class Polydata { +public: + + virtual vtkPolyData * GetPolyData() const { return NULL; } + + virtual void SaveToFile(const char *vtk_file); + + virtual void SaveToXMLFile(const char *vtp_file); + +protected: + virtual ~Polydata() {} +}; + + +} // vtk +} // uLib + + + +#endif // ULIBVTKINTERFACE_H diff --git a/src/Vtk/uLibVtkViewer.cpp b/src/Vtk/uLibVtkViewer.cpp new file mode 100644 index 0000000..0f50e5d --- /dev/null +++ b/src/Vtk/uLibVtkViewer.cpp @@ -0,0 +1,190 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "uLibVtkViewer.h" + +namespace uLib { +namespace Vtk { + +template <> +class Tie { +public: + void DoAction() { + std::cout << " VIEWER TIE !!! \n"; + } +}; + + +//// PIMPL ///////////////////////////////////////////////////////////////////// + +class ViewerPimpl { +public: + ViewerPimpl() : + m_RenderWindow(vtkRenderWindow::New()), + m_Renderer(vtkRenderer::New()), + m_Annotation(vtkCornerAnnotation::New()), + m_Marker(vtkOrientationMarkerWidget::New()) + { + this->InstallPipe(); + } + + ~ViewerPimpl() { + this->UninstallPipe(); + + m_Annotation->Delete(); + m_Marker->Delete(); + m_Renderer->Delete(); + m_RenderWindow->Delete(); + } + + // members // + vtkRenderer *m_Renderer; + vtkRenderWindow *m_RenderWindow; + vtkCornerAnnotation *m_Annotation; + vtkOrientationMarkerWidget *m_Marker; + +private: + void InstallPipe() + { + m_RenderWindow->AddRenderer(m_Renderer); + vtkSmartPointer renderWindowInteractor = + vtkSmartPointer::New(); + renderWindowInteractor->SetRenderWindow(m_RenderWindow); + + // annotation // + m_Annotation->GetTextProperty()->SetColor(1,1,1); + m_Annotation->GetTextProperty()->SetFontFamilyToArial(); + m_Annotation->GetTextProperty()->SetOpacity(0.5); + m_Annotation->SetMaximumFontSize(10); + m_Annotation->SetText(0,"uLib VTK Viewer - OpenCMT all right reserved."); + m_Renderer->AddViewProp(m_Annotation); + + // orientation marker // + vtkSmartPointer axes = + vtkSmartPointer::New(); + m_Marker->SetInteractor(renderWindowInteractor); + m_Marker->SetOrientationMarker(axes); + m_Marker->SetViewport(0.0,0.0,0.2,0.2); + m_Marker->SetEnabled(true); + m_Marker->InteractiveOff(); + + // Must be rendered here in Vtk-6.0 or seg-fault // + m_RenderWindow->Render(); + } + + void UninstallPipe() { + m_Renderer->RemoveAllViewProps(); + m_Renderer->Clear(); + } + +}; + + + + +//////////////////////////////////////////////////////////////////////////////// +///// VTK VIEWER ////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +Viewer::Viewer() : d(new ViewerPimpl) {} + +Viewer::~Viewer() { delete d; } + + +void Viewer::addProp(vtkProp *prop) +{ + d->m_Renderer->AddActor(prop); + d->m_Renderer->Render(); +} + +void Viewer::RemoveProp(vtkProp *prop) +{ + d->m_Renderer->RemoveViewProp(prop); + d->m_Renderer->Render(); +} + +void Viewer::AddPuppet(Puppet &prop) +{ + prop.ConnectRenderer(d->m_Renderer); + d->m_Renderer->Render(); +} + +void Viewer::RemovePuppet(Puppet &prop) +{ + prop.DisconnectRenderer(d->m_Renderer); + d->m_Renderer->Render(); +} + +void Viewer::Start() +{ + d->m_RenderWindow->GetInteractor()->Start(); +} + +vtkCornerAnnotation *Viewer::GetAnnotation() +{ + return d->m_Annotation; +} + +vtkRenderer *Viewer::GetRenderer() +{ + return d->m_Renderer; +} + +vtkRenderWindowInteractor *Viewer::GetInteractor() +{ + return d->m_RenderWindow->GetInteractor(); +} + +void Viewer::Reset() +{ + d->m_Renderer->ResetCameraClippingRange(); + d->m_Renderer->ResetCamera(); + d->m_Renderer->Render(); +} + + +} // vtk +} // uLib + diff --git a/src/Vtk/uLibVtkViewer.h b/src/Vtk/uLibVtkViewer.h new file mode 100644 index 0000000..cc9e8a9 --- /dev/null +++ b/src/Vtk/uLibVtkViewer.h @@ -0,0 +1,90 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef ULIBVTKVIEWER_H +#define ULIBVTKVIEWER_H + +#include "uLibVtkInterface.h" + + +class vtkProp; +class vtk3DWidget; +class vtkCornerAnnotation; +class vtkRenderWindowInteractor; +class vtkRenderer; + +namespace uLib { +namespace Vtk { + + +template +class Tie { +public: + void DoAction() { + std::cout << "Tie::DoAction -> generic Tie does nothing\n"; + } +}; + + +class Viewer { + +public: + Viewer(); + ~Viewer(); + + + void AddPuppet(Puppet &prop); + + void RemovePuppet(Puppet &prop); + + void AddWidget(vtk3DWidget *widget); + + void Reset(); + + void Start(); + + vtkCornerAnnotation *GetAnnotation(); + + vtkRenderer * GetRenderer(); + + vtkRenderWindowInteractor * GetInteractor(); + + void addProp(vtkProp *prop); + + void RemoveProp(vtkProp *prop); + +private: + class ViewerPimpl *d; +}; + +template <> class Tie; + + +} // vtk +} // uLib + +#endif // ULIBVTKVIEWER_H diff --git a/src/Vtk/vtkContainerBox.cpp b/src/Vtk/vtkContainerBox.cpp new file mode 100644 index 0000000..0245946 --- /dev/null +++ b/src/Vtk/vtkContainerBox.cpp @@ -0,0 +1,158 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vtkContainerBox.h" + +#include "Math/Dense.h" +#include "Math/VectorSpace.h" +#include "Math/ContainerBox.h" + +namespace uLib { +namespace Vtk { + + +// PIMPL -------------------------------------------------------------------- // + +class vtkContainerBoxPimpl { +public: + vtkContainerBoxPimpl() : + m_Cube(vtkActor::New()), + m_Axes(vtkActor::New()), + m_Pivot(vtkActor::New()), + m_Content(NULL) + {} + + ~vtkContainerBoxPimpl() + { + m_Cube->Delete(); + m_Axes->Delete(); + m_Pivot->Delete(); + } + + // MEMBERS // + vtkActor *m_Cube; + vtkActor *m_Axes; + vtkActor *m_Pivot; + vtkContainerBox::Content *m_Content; +}; + +// -------------------------------------------------------------------------- // + + + + +vtkContainerBox::vtkContainerBox(vtkContainerBox::Content &content) : + d( new vtkContainerBoxPimpl) +{ + d->m_Content = &content; + this->InstallPipe(); +} + +vtkContainerBox::~vtkContainerBox() +{ + delete d; +} + +vtkPolyData *vtkContainerBox::GetPolyData() const +{ + // TODO +} + +void vtkContainerBox::InstallPipe() +{ + if(!d->m_Content) return; + Content *c = d->m_Content; + + // CUBE + vtkSmartPointer cube = vtkSmartPointer::New(); + Vector3f p = c->GetPosition(); + cube->SetCenter(p(0),p(1),p(2)); + Vector4f p1 = c->GetWorldPoint(HPoint3f(0,0,0)); + Vector4f p2 = c->GetWorldPoint(HPoint3f(1,1,1)); + vtkSmartPointer line = vtkSmartPointer::New(); + line->SetPoint1(p1(0),p1(1),p1(2)); + line->SetPoint2(p2(0),p2(1),p2(2)); + line->Update(); + cube->SetBounds(line->GetOutput()->GetBounds()); + vtkSmartPointer mapper = + vtkSmartPointer::New(); + mapper->SetInputConnection(cube->GetOutputPort()); + mapper->Update(); + d->m_Cube->SetMapper(mapper); + d->m_Cube->GetProperty()->SetRepresentationToWireframe(); + d->m_Cube->GetProperty()->SetAmbient(0.7); + + // AXES // + vtkSmartPointer axes = vtkSmartPointer::New(); + axes->SetOrigin(p1(0),p1(1),p1(2)); + mapper = vtkSmartPointer::New(); + mapper->SetInputConnection(axes->GetOutputPort()); + mapper->Update(); + d->m_Axes->SetMapper(mapper); + Vector3f s = c->GetSize(); + // d->m_Axes->SetScale(s(0),s(1),s(2)); + d->m_Axes->GetProperty()->SetLineWidth(3); + d->m_Axes->GetProperty()->SetAmbient(0.4); + d->m_Axes->GetProperty()->SetSpecular(0); + + // PIVOT // + axes = vtkSmartPointer::New(); + axes->SetOrigin(p(0),p(1),p(2)); + mapper = vtkSmartPointer::New(); + mapper->SetInputConnection(axes->GetOutputPort()); + mapper->Update(); + d->m_Pivot->SetMapper(mapper); + s = c->GetScale(); + // d->m_Pivot->SetScale(s(0),s(1),s(2)); + d->m_Pivot->GetProperty()->SetLineWidth(3); + d->m_Pivot->GetProperty()->SetAmbient(0.4); + d->m_Pivot->GetProperty()->SetSpecular(0); + + this->SetProp(d->m_Cube); + this->SetProp(d->m_Axes); + this->SetProp(d->m_Pivot); +} + + + +} // vtk +} // uLib diff --git a/src/Vtk/vtkContainerBox.h b/src/Vtk/vtkContainerBox.h new file mode 100644 index 0000000..1cebf48 --- /dev/null +++ b/src/Vtk/vtkContainerBox.h @@ -0,0 +1,57 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_VTKCONTAINERBOX_H +#define U_VTKCONTAINERBOX_H + + +#include "uLibVtkInterface.h" +#include "Math/ContainerBox.h" + + +namespace uLib { +namespace Vtk { + +class vtkContainerBox : public Puppet, public Polydata { + typedef ContainerBox Content; +public: + vtkContainerBox(Content &content); + ~vtkContainerBox(); + + virtual class vtkPolyData *GetPolyData() const; + +private: + void InstallPipe(); + + friend class vtkContainerBoxPimpl; + class vtkContainerBoxPimpl *d; +}; + +} // vtk +} // uLib + +#endif // VTKCONTAINERBOX_H diff --git a/src/Vtk/vtkHLineRepresentation.h b/src/Vtk/vtkHLineRepresentation.h new file mode 100644 index 0000000..c69ea14 --- /dev/null +++ b/src/Vtk/vtkHLineRepresentation.h @@ -0,0 +1,52 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VTKHLINEREPRESENTATION_H +#define VTKHLINEREPRESENTATION_H + + + +class vtkProp; +class vtkPolyData; + + +namespace uLib { + +class vtkHLineRepresentationDefault { + +public: + vtkHLineRepresentationDefault(); + + +}; + + +} + + + +#endif // VTKHLINEREPRESENTATION_H diff --git a/src/Vtk/vtkMuonContainerScattering.cpp b/src/Vtk/vtkMuonContainerScattering.cpp new file mode 100644 index 0000000..b49a65e --- /dev/null +++ b/src/Vtk/vtkMuonContainerScattering.cpp @@ -0,0 +1,35 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + + +// TO BE CONTINUED // diff --git a/src/Vtk/vtkMuonContainerScattering.h b/src/Vtk/vtkMuonContainerScattering.h new file mode 100644 index 0000000..b1ef9be --- /dev/null +++ b/src/Vtk/vtkMuonContainerScattering.h @@ -0,0 +1,77 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VTKMUONCONTAINERSCATTERING_H +#define VTKMUONCONTAINERSCATTERING_H + + + +#include "Core/Macros.h" +#include "Math/Dense.h" + +#include "uLibVtkInterface.h" +#include "Detectors/MuonScatter.h" + +class vtkRenderWindowInteractor; + +namespace uLib { + +class vtkMuonContainerScattering : public Abstract::uLibVtkPolydata { + typedef MuonScatter Content; +public: + vtkMuonContainerScattering(const MuonScatter &content); + ~vtkMuonScatter(); + + Content& GetContent(); + + void PrintSelf(std::ostream &o) const; + + virtual vtkProp *GetProp(); + + virtual vtkPolyData* GetPolyData() const; + + void AddPocaPoint(HPoint3f poca); + + HPoint3f GetPocaPoint(); + + void vtkStartInteractive(); + +protected: + void ConnectInteractor(vtkRenderWindowInteractor *interactor); + +private: + void InstallPipe(); + + friend class vtkMuonContainerScatteringPimpl; + class vtkMuonContainerScatteringPimpl *d; +}; + + +} + + +#endif // VTKMUONCONTAINERSCATTERING_H diff --git a/src/Vtk/vtkMuonEvent.cxx b/src/Vtk/vtkMuonEvent.cxx new file mode 100644 index 0000000..db34b24 --- /dev/null +++ b/src/Vtk/vtkMuonEvent.cxx @@ -0,0 +1,214 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include "vtkMuonEvent.h" +#include "Math/Dense.h" + +namespace uLib { + +///// CALLBACK ///////////////////////////////////////////////////////////////// + +class vtkWidgetCallback : public vtkCommand +{ +public: + static vtkWidgetCallback *New() + { return new vtkWidgetCallback; } + void SetParent(uLib::vtkMuonEvent *parent) { this->parent = parent; } + virtual void Execute(vtkObject *caller, unsigned long, void*) + { + vtkSmartPointer t = + vtkSmartPointer::New(); + vtkBoxWidget *widget = reinterpret_cast(caller); + widget->GetTransform(t); + //parent->SetTransform(t); + //std::cout << "event\n"; + } +private: + uLib::vtkMuonEvent *parent; +}; + + +//// PIMPL ///////////////////////////////////////////////////////////////////// + +class vtkMuonEventPimpl { + typedef vtkWidgetCallback Callback; +public: + vtkMuonEventPimpl() : + m_Prop(vtkActor::New()), + m_PolyData(NULL), + m_Appender(vtkAppendPolyData::New()), + content(NULL) + {} + + ~vtkMuonEventPimpl() + { + m_Prop->Delete(); + } + + // members // + vtkMuonEvent::Content *content; + vtkPolyData *m_PolyData; + vtkActor *m_Prop; + + vtkAppendPolyData *m_Appender; + vtkBoxWidget *m_WidgetIN, *m_WidgetOUT; + HPoint3f m_Poca; +}; + + + + + + +//////////////////////////////////////////////////////////////////////////////// +///// VTK MUON EVENT ///////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +vtkMuonEvent::vtkMuonEvent(MuonEventData &content) : + d(new vtkMuonEventPimpl) +{ + d->content = &content; + InstallPipe(); +} + +vtkMuonEvent::vtkMuonEvent(const MuonEventData &content) : + d(new vtkMuonEventPimpl) +{ + d->content = const_cast(&content); + InstallPipe(); +} + + +vtkMuonEvent::~vtkMuonEvent() +{ + if (d->m_Prop) d->m_Prop->Delete(); +} + +vtkMuonEvent::Content &vtkMuonEvent::GetContent() +{ + return *d->content; +} + +void vtkMuonEvent::PrintSelf(std::ostream &o) const +{ + o << "..:: MuonEvent ::..\n" \ + "\t[in] Origin > " << d->content->LineIn().origin.transpose() << "\n" << + "\t[in] Direction > " << d->content->LineIn().direction.transpose() << "\n" << + "\t[out] Origin > " << d->content->LineOut().origin.transpose() << "\n" << + "\t[out] Direction > " << d->content->LineOut().direction.transpose()<< "\n" << + "\tMomentum > " << d->content->GetMomentum() << "\n" << + "...................\n"; +} + +vtkProp *vtkMuonEvent::GetProp() +{ + return d->m_Prop; +} + +void vtkMuonEvent::InstallPipe() +{ + + + vtkAppendPolyData *appender = d->m_Appender; + vtkSmartPointer mapper = vtkSmartPointer::New(); + + if(d->content) { + vtkSmartPointer line_in = vtkSmartPointer::New(); + vtkSmartPointer line_out = vtkSmartPointer::New(); + + float distance = (d->content->LineIn().origin - d->content->LineOut().origin).norm() / 10; + + HPoint3f pt; + pt = d->content->LineIn().origin; + line_in->SetPoint1(pt(0),pt(1),pt(2)); + pt= d->content->LineIn().origin + d->content->LineIn().direction * distance; + line_in->SetPoint2(pt(0),pt(1),pt(2)); + pt = d->content->LineOut().origin; + line_out->SetPoint1(pt(0),pt(1),pt(2)); + pt = d->content->LineOut().origin + d->content->LineOut().direction * distance; + line_out->SetPoint2(pt(0),pt(1),pt(2)); + + appender->AddInputConnection(line_in->GetOutputPort()); + appender->AddInputConnection(line_out->GetOutputPort()); + } + + appender->Update(); + mapper->SetInputConnection(appender->GetOutputPort()); + mapper->Update(); + d->m_Prop->SetMapper(mapper); +} + +vtkPolyData *vtkMuonEvent::GetPolyData() const +{ + return d->m_Appender->GetOutput(); +} + +void vtkMuonEvent::AddPocaPoint(HPoint3f poca) +{ + d->m_Poca = poca; + vtkSmartPointer sphere = + vtkSmartPointer::New(); + float size = (d->content->LineIn().origin - d->content->LineOut().origin).head(3).norm(); + size /= 100; + sphere->SetRadius(size); + sphere->SetCenter(poca(0),poca(1),poca(2)); + sphere->Update(); + d->m_Appender->AddInputConnection(sphere->GetOutputPort()); + d->m_Appender->Update(); +} + +HPoint3f vtkMuonEvent::GetPocaPoint() +{ + return d->m_Poca; +} + + + + + +} diff --git a/src/Vtk/vtkMuonEvent.h b/src/Vtk/vtkMuonEvent.h new file mode 100644 index 0000000..310fc08 --- /dev/null +++ b/src/Vtk/vtkMuonEvent.h @@ -0,0 +1,74 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VTKMUONEVENT_H +#define VTKMUONEVENT_H + +#include "Core/Macros.h" +#include "Math/Dense.h" + +#include "uLibVtkInterface.h" +#include "Detectors/MuonEvent.h" + + + + +namespace uLib { + +class vtkMuonEvent : public Abstract::uLibVtkPolydata { + typedef MuonEventData Content; +public: + vtkMuonEvent(const MuonEventData &content); + vtkMuonEvent(MuonEventData &content); + ~vtkMuonEvent(); + + Content& GetContent(); + + void PrintSelf(std::ostream &o) const; + + virtual vtkProp *GetProp(); + + virtual vtkPolyData* GetPolyData() const; + + void AddPocaPoint(HPoint3f poca); + + HPoint3f GetPocaPoint(); + + void vtkStartInteractive(); + + +private: + void InstallPipe(); + + friend class vtkMuonEventPimpl; + class vtkMuonEventPimpl *d; +}; + + +} + +#endif // VTKMUONSCATTER_H diff --git a/src/Vtk/vtkMuonScatter.cxx b/src/Vtk/vtkMuonScatter.cxx new file mode 100644 index 0000000..c4ea984 --- /dev/null +++ b/src/Vtk/vtkMuonScatter.cxx @@ -0,0 +1,238 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include "vtkMuonScatter.h" +#include "Math/Dense.h" +#include "Math/VectorSpace.h" + + +namespace uLib { +namespace Vtk { + +///// CALLBACK ///////////////////////////////////////////////////////////////// + +//namespace { + +//class vtkWidgetCallback : public vtkCommand +//{ +//public: +// static vtkWidgetCallback *New() +// { return new vtkWidgetCallback; } +// void SetParent(uLib::vtkMuonScatter *parent) { this->parent = parent; } +// virtual void Execute(vtkObject *caller, unsigned long, void*) +// { +// vtkSmartPointer t = +// vtkSmartPointer::New(); +// vtkBoxWidget *widget = reinterpret_cast(caller); +// widget->GetTransform(t); +// //parent->SetTransform(t); +// //std::cout << "Scatter\n"; +// } +//private: +// uLib::vtkMuonScatter *parent; +//}; + +//} + +//// PIMPL ///////////////////////////////////////////////////////////////////// + +class vtkMuonScatterPimpl { +public: + vtkMuonScatterPimpl() : + m_Content(NULL), + m_LineIn(vtkLineSource::New()), + m_LineOut(vtkLineSource::New()), + m_PolyData(vtkPolyData::New()), + m_SpherePoca(NULL) + {} + + ~vtkMuonScatterPimpl() + { + m_LineIn->Delete(); + m_LineOut->Delete(); + if(m_SpherePoca) m_SpherePoca->Delete(); + } + + // members // + vtkMuonScatter::Content *m_Content; + vtkLineSource *m_LineIn, *m_LineOut; + vtkSphereSource *m_SpherePoca; + vtkPolyData *m_PolyData; +}; + + + + + + +//////////////////////////////////////////////////////////////////////////////// +///// VTK MUON Scatter ///////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +vtkMuonScatter::vtkMuonScatter(MuonScatter &content) : + d(new vtkMuonScatterPimpl) +{ + d->m_Content = &content; + InstallPipe(); +} + +vtkMuonScatter::vtkMuonScatter(const MuonScatter &content) : + d(new vtkMuonScatterPimpl) +{ + d->m_Content = const_cast(&content); + InstallPipe(); +} + + +vtkMuonScatter::~vtkMuonScatter() +{ + delete d; +} + +vtkMuonScatter::Content &vtkMuonScatter::GetContent() +{ + return *d->m_Content; +} + +void vtkMuonScatter::PrintSelf(std::ostream &o) const +{ + // o << d->content; +} + + +void vtkMuonScatter::InstallPipe() +{ + if(d->m_Content) { + vtkLineSource *line_in = d->m_LineIn; + vtkLineSource *line_out = d->m_LineOut; + + float distance = (d->m_Content->LineIn().origin() - d->m_Content->LineOut().origin()).norm() / 10; + + Vector4f pt; + pt = d->m_Content->LineIn().origin(); + line_in->SetPoint1(pt(0),pt(1),pt(2)); + pt= d->m_Content->LineIn().origin() + d->m_Content->LineIn().direction() * distance; + line_in->SetPoint2(pt(0),pt(1),pt(2)); + pt = d->m_Content->LineOut().origin(); + line_out->SetPoint1(pt(0),pt(1),pt(2)); + pt = d->m_Content->LineOut().origin() + d->m_Content->LineOut().direction() * distance; + line_out->SetPoint2(pt(0),pt(1),pt(2)); + } + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInputConnection(d->m_LineIn->GetOutputPort()); + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + this->SetProp(actor); + + mapper = vtkSmartPointer::New(); + mapper->SetInputConnection(d->m_LineOut->GetOutputPort()); + actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + this->SetProp(actor); +} + +vtkPolyData *vtkMuonScatter::GetPolyData() const +{ + vtkSmartPointer append = vtkSmartPointer::New(); +//# if VTK_MAJOR_VERSION <= 5 + append->AddInputConnection(d->m_LineIn->GetOutputPort()); + append->AddInputConnection(d->m_LineOut->GetOutputPort()); + if(d->m_SpherePoca) append->AddInputConnection(d->m_SpherePoca->GetOutputPort()); +//# else +// append->AddInputData(d->m_LineIn->GetOutput()); +// append->AddInputData(d->m_LineOut->GetOutput()); +// if(d->m_SpherePoca) append->AddInputData(d->m_SpherePoca->GetOutput()); +//# endif + append->Update(); + d->m_PolyData->DeepCopy(append->GetOutput()); + return d->m_PolyData; +} + +void vtkMuonScatter::AddPocaPoint(Vector4f poca) +{ + vtkSphereSource *sphere = vtkSphereSource::New(); + float size = (d->m_Content->LineIn().origin() - d->m_Content->LineOut().origin()).head(3).norm(); + size /= 100; + sphere->SetRadius(size); + sphere->SetCenter(poca(0),poca(1),poca(2)); + sphere->Update(); + d->m_SpherePoca = sphere; + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInputConnection(d->m_SpherePoca->GetOutputPort()); + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + this->SetProp(actor); +} + +Vector4f vtkMuonScatter::GetPocaPoint() +{ + double center[3]; + if(d->m_SpherePoca) { + d->m_SpherePoca->GetCenter(center); + return HPoint3f(center[0],center[1],center[2]); + } + else { + return HPoint3f(0,0,0); + } +} + + +void vtkMuonScatter::ConnectInteractor(vtkRenderWindowInteractor *interactor) +{ + // TODO +} + + + + +} // vtk +} // uLib diff --git a/src/Vtk/vtkMuonScatter.h b/src/Vtk/vtkMuonScatter.h new file mode 100644 index 0000000..4b2de71 --- /dev/null +++ b/src/Vtk/vtkMuonScatter.h @@ -0,0 +1,76 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VTKMUONSCATTER_H +#define VTKMUONSCATTER_H + +#include "Core/Macros.h" +#include "Math/Dense.h" + +#include "uLibVtkInterface.h" +#include "Detectors/MuonScatter.h" + +class vtkRenderWindowInteractor; + +namespace uLib { +namespace Vtk { + +class vtkMuonScatter : public Puppet, public Polydata { + typedef MuonScatter Content; +public: + + vtkMuonScatter(const MuonScatter &content); + vtkMuonScatter(MuonScatter &content); + + ~vtkMuonScatter(); + + Content &GetContent(); + + void PrintSelf(std::ostream &o) const; + + virtual vtkPolyData* GetPolyData() const; + + void AddPocaPoint(Vector4f poca); + + Vector4f GetPocaPoint(); + + void vtkStartInteractive(); + +protected: + void ConnectInteractor(vtkRenderWindowInteractor *interactor); + +private: + void InstallPipe(); + + friend class vtkMuonScatterPimpl; + class vtkMuonScatterPimpl *d; +}; + +} // vtk +} // uLib + +#endif // VTKMUONSCATTER_H diff --git a/src/Vtk/vtkPolydata.h b/src/Vtk/vtkPolydata.h new file mode 100644 index 0000000..5aa5b27 --- /dev/null +++ b/src/Vtk/vtkPolydata.h @@ -0,0 +1,49 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VTKPOLYDATA_H +#define VTKPOLYDATA_H + +#include "uLibVtkInterface.h" + + +namespace uLib { + +class vtkPolyData : public Abstract::uLibVtkPolydata { + typedef ::vtkPolyData Content; +public: + + + +}; + + + +} + + +#endif // VTKPOLYDATA_H diff --git a/src/Vtk/vtkStructuredGrid.cpp b/src/Vtk/vtkStructuredGrid.cpp new file mode 100644 index 0000000..05f0214 --- /dev/null +++ b/src/Vtk/vtkStructuredGrid.cpp @@ -0,0 +1,195 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "Math/ImageData.h" +#include "Vtk/vtkStructuredGrid.h" + +namespace uLib { +namespace Vtk { + +//////////////////////////////////////////////////////////////////////////////// +////// PIMPL ////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +class vtkStructuredGridPimpl { + + // ---- WIDGET CBK ------------------------------------------------------ // + class vtkWidgetCallback : public vtkCommand + { + public: + static vtkWidgetCallback *New() { return new vtkWidgetCallback; } + void SetParent(uLib::Vtk::vtkStructuredGrid *parent) { this->parent = parent; } + virtual void Execute(vtkObject *caller, unsigned long, void*) + { + vtkSmartPointer t = + vtkSmartPointer::New(); + vtkBoxWidget *widget = reinterpret_cast(caller); + widget->GetTransform(t); + parent->SetTransform(t); + //std::cout << "event\n"; + } + private: + uLib::Vtk::vtkStructuredGrid *parent; + }; + // ---------------------------------------------------------------------- // + +public: + vtkStructuredGridPimpl(vtkStructuredGrid *parent, ImageData &content) : + p(parent), + m_Content(&content), + m_Actor(vtkActor::New()), + m_Widget(vtkBoxWidget::New()), + m_Transform(vtkTransform::New()) + { + vtkSmartPointer callback = + vtkSmartPointer::New(); + callback->SetParent(p); + m_Widget->AddObserver(vtkCommand::InteractionEvent, callback); + } + + ~vtkStructuredGridPimpl() + { + m_Actor->Delete(); + m_Widget->Delete(); + m_Transform->Delete(); + } + + // members // + vtkActor *m_Actor; + vtkBoxWidget *m_Widget; + ImageData *m_Content; + vtkTransform *m_Transform; +private: + vtkStructuredGrid *p; +}; + + +//////////////////////////////////////////////////////////////////////////////// +////// VTK STRUCTURED GRID ///////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + + +vtkStructuredGrid::vtkStructuredGrid(Content &content) : + d(new vtkStructuredGridPimpl(this,content)) +{ + this->InstallPipe(); +} + +vtkStructuredGrid::~vtkStructuredGrid() +{ + delete d; +} + + +void vtkStructuredGrid::SetTransform(vtkTransform *t) +{ + vtkMatrix4x4 *vmat = t->GetMatrix(); + Matrix4f mat; + for(int i=0; i<4; ++i) + for(int j=0; j<4; ++j) + mat(i,j) = vmat->GetElement(i,j); + d->m_Content->SetMatrix(mat); + + vtkSmartPointer vmat2 = vtkSmartPointer::New(); + mat = d->m_Content->GetWorldMatrix(); + for(int i=0; i<4; ++i) + for(int j=0; j<4; ++j) + vmat2->SetElement(i,j,mat(i,j)); + d->m_Transform->SetMatrix(vmat2); + d->m_Transform->Update(); + this->Update(); +} + +vtkBoxWidget *vtkStructuredGrid::GetWidget() +{ + return d->m_Widget; +} + +void vtkStructuredGrid::Update() +{ + d->m_Actor->GetMapper()->Update(); +} + +void vtkStructuredGrid::InstallPipe() +{ + vtkSmartPointer cube = + vtkSmartPointer::New(); + vtkSmartPointer filter = + vtkSmartPointer::New(); + + vtkSmartPointer vmat = vtkSmartPointer::New(); + Matrix4f mat = d->m_Content->GetWorldMatrix(); + for(int i=0; i<4; ++i) + for(int j=0; j<4; ++j) + vmat->SetElement(i,j,mat(i,j)); + d->m_Transform->SetMatrix(vmat); + filter->SetTransform(d->m_Transform); + filter->SetInputConnection(cube->GetOutputPort()); + + Vector3i dims = d->m_Content->GetDims(); + cube->SetBounds(0,dims(0),0,dims(1),0,dims(2)); + cube->Update(); + filter->Update(); + + vtkSmartPointer mapper = + vtkSmartPointer::New(); + mapper->SetInputConnection(filter->GetOutputPort()); + + d->m_Actor->SetMapper(mapper); + d->m_Actor->GetProperty()->SetRepresentationToSurface(); + d->m_Actor->GetProperty()->SetEdgeVisibility(true); + d->m_Actor->GetProperty()->SetOpacity(0.4); + d->m_Actor->GetProperty()->SetAmbient(0.7); + // set content transform to actor // + this->Update(); + d->m_Widget->SetProp3D(d->m_Actor); + + this->SetProp(d->m_Actor); +} + + +} // vtk +} // uLib diff --git a/src/Vtk/vtkStructuredGrid.h b/src/Vtk/vtkStructuredGrid.h new file mode 100644 index 0000000..f77c88c --- /dev/null +++ b/src/Vtk/vtkStructuredGrid.h @@ -0,0 +1,67 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_VTKSTRUCTUREDGRID_H +#define U_VTKSTRUCTUREDGRID_H + +#include "Core/Macros.h" +#include "Math/Dense.h" + +#include "uLibVtkInterface.h" +#include "Math/ImageData.h" + + +namespace uLib { +namespace Vtk { + +class vtkStructuredGrid : public Puppet { + typedef ImageData Content; +public: + + vtkStructuredGrid(Content &content); + ~vtkStructuredGrid(); + + void SetTransform(class vtkTransform *t); + + class vtkBoxWidget * GetWidget(); + + void Update(); + + +private: + void InstallPipe(); + + friend class vtkStructuredGridPimpl; + class vtkStructuredGridPimpl *d; +}; + + +} // vtk +} // uLib + + +#endif // VTKSTRUCTUREDGRID_H diff --git a/src/Vtk/vtkTriangleMesh.cpp b/src/Vtk/vtkTriangleMesh.cpp new file mode 100644 index 0000000..4144270 --- /dev/null +++ b/src/Vtk/vtkTriangleMesh.cpp @@ -0,0 +1,227 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "Vtk/vtkTriangleMesh.h" + + +namespace uLib { + + +class vtkTriangleMeshPimpl { +public: + vtkTriangleMeshPimpl(vtkTriangleMesh::Content &content) : + m_content(content), + m_Poly(vtkPolyData::New()), + m_Actor(vtkActor::New()) + { + vtkSmartPointer mapper = + vtkSmartPointer::New(); + mapper->SetInputConnection(m_Poly->GetProducerPort()); + m_Actor->SetMapper(mapper); + } + + ~vtkTriangleMeshPimpl() { + m_Poly->Delete(); + m_Actor->Delete(); + } + + + void vtk2uLib_update(); + void uLib2vtk_update(); + + // members // + TriangleMesh &m_content; + vtkPolyData *m_Poly; + vtkActor *m_Actor; +}; + + +void vtkTriangleMeshPimpl::vtk2uLib_update() +{ + // Assumes that Polys are Triangles !!! // + vtkIdType number_of_points = m_Poly->GetNumberOfPoints(); + vtkIdType number_of_triangles = m_Poly->GetNumberOfPolys(); + + std::cout << "//////\n" << + "number of points = " << number_of_points << "\n" << + "muiber of polys = " << number_of_triangles << "\n" << + "//////\n"; + + + + + + m_content.Points().resize(number_of_points); + for (int i=0; iGetPoint(i); + m_content.Points()[i](0) = point[0]; + m_content.Points()[i](1) = point[1]; + m_content.Points()[i](2) = point[2]; +// std::cout << "pt" << i << " = " << m_content.Points()[i].transpose() << "\n"; + } + + m_content.Triangles().resize(number_of_triangles); + m_Poly->GetPolys()->InitTraversal(); + vtkSmartPointer idList = vtkSmartPointer::New(); + for (int i=0; iGetPolys()->GetNextCell(idList); + m_content.Triangles()[i](0) = idList->GetId(0); + m_content.Triangles()[i](1) = idList->GetId(1); + m_content.Triangles()[i](2) = idList->GetId(2); + } + m_Poly->Update(); + m_Actor->GetMapper()->Update(); +} + +void vtkTriangleMeshPimpl::uLib2vtk_update() +{ + vtkIdType number_of_points = m_content.Points().size(); + vtkIdType number_of_triangles = m_content.Triangles().size(); + + vtkSmartPointer points + = vtkSmartPointer::New(); + points->SetNumberOfPoints(number_of_points); + for (vtkIdType i = 0; i < number_of_points; i++) + { + double x, y, z; + x = m_content.Points().at(i)(0); + y = m_content.Points().at(i)(1); + z = m_content.Points().at(i)(2); + points->SetPoint(i, x, y, z); + } + + vtkSmartPointer polys + = vtkSmartPointer::New(); + for (vtkIdType i = 0; i < number_of_triangles; i++) + { + vtkIdType a, b, c; + a = m_content.Triangles().at(i)(0); + b = m_content.Triangles().at(i)(1); + c = m_content.Triangles().at(i)(2); + polys->InsertNextCell(3); + polys->InsertCellPoint(a); + polys->InsertCellPoint(b); + polys->InsertCellPoint(c); + } + + m_Poly->SetPoints(points); + m_Poly->SetPolys(polys); + m_Poly->Update(); + m_Actor->GetMapper()->Update(); +} + + +// -------------------------------------------------------------------------- // + + + + + +vtkTriangleMesh::vtkTriangleMesh(vtkTriangleMesh::Content &content) : + d(new vtkTriangleMeshPimpl(content)) +{} + +vtkTriangleMesh::~vtkTriangleMesh() +{ + delete d; +} + +void vtkTriangleMesh::ReadFromFile(const char *filename) +{ + vtkSmartPointer reader = + vtkSmartPointer::New(); + reader->SetFileName(filename); + reader->Update(); + d->m_Poly->DeepCopy(reader->GetOutput()); + d->vtk2uLib_update(); +} + +void vtkTriangleMesh::ReadFromXMLFile(const char *filename) +{ + vtkSmartPointer reader = + vtkSmartPointer::New(); + reader->SetFileName(filename); + reader->Update(); + d->m_Poly->DeepCopy(reader->GetOutput()); + d->vtk2uLib_update(); +} + +void vtkTriangleMesh::ReadFromObjFile(const char *filename) +{ + vtkSmartPointer reader = + vtkSmartPointer::New(); + reader->SetFileName(filename); + reader->Update(); + d->m_Poly->DeepCopy(reader->GetOutput()); + d->vtk2uLib_update(); +} + +void vtkTriangleMesh::ReadFromStlFile(const char *filename) +{ + vtkSmartPointer reader = + vtkSmartPointer::New(); + reader->SetFileName(filename); + reader->Update(); + d->m_Poly->DeepCopy(reader->GetOutput()); + d->vtk2uLib_update(); +} + +vtkProp *vtkTriangleMesh::GetProp() +{ + return d->m_Actor; +} + +vtkPolyData *vtkTriangleMesh::GetPolyData() const +{ + return d->m_Poly; +} + +void vtkTriangleMesh::Update() +{ + d->uLib2vtk_update(); +} + +} diff --git a/src/Vtk/vtkTriangleMesh.h b/src/Vtk/vtkTriangleMesh.h new file mode 100644 index 0000000..d0a1038 --- /dev/null +++ b/src/Vtk/vtkTriangleMesh.h @@ -0,0 +1,69 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef VTKTRIANGLEMESH_H +#define VTKTRIANGLEMESH_H + + +#include "uLibVtkInterface.h" +#include "Math/TriangleMesh.h" + +class vtkPolyData; + +namespace uLib { + + +class vtkTriangleMesh : public Abstract::uLibVtkPolydata { + typedef TriangleMesh Content; +public: + vtkTriangleMesh(Content &content); + ~vtkTriangleMesh(); + + void ReadFromFile(const char *filename); + + void ReadFromXMLFile(const char *filename); + + void ReadFromObjFile(const char *filename); + + void ReadFromStlFile(const char *filename); + + virtual class vtkProp *GetProp(); + + virtual class vtkPolyData *GetPolyData() const; + + void Update(); + +private: + friend class vtkTriangleMeshPimpl; + class vtkTriangleMeshPimpl *d; +}; + + + +} + +#endif // VTKTRIANGLEMESH_H diff --git a/src/Vtk/vtkVoxImage.cpp b/src/Vtk/vtkVoxImage.cpp new file mode 100644 index 0000000..2ef73d4 --- /dev/null +++ b/src/Vtk/vtkVoxImage.cpp @@ -0,0 +1,391 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + + +#include + +#include "vtkVoxImage.h" + + +namespace uLib { +namespace Vtk { + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// PIMPL + +class vtkVoxImagePimpl { +public: + vtkVoxImagePimpl(vtkVoxImage::Content &content) : + m_Content(content), + m_Actor(vtkVolume::New()), + m_Image(vtkImageData::New()), + m_Outline(vtkCubeSource::New()), + m_Reader(NULL), + m_Writer(NULL) + {} + + ~vtkVoxImagePimpl() + { + m_Image->Delete(); + m_Actor->Delete(); + m_Outline->Delete(); + } + + void GetContent(); + + void SetContent(); + + // members // + vtkVolume *m_Actor; + vtkImageData *m_Image; + vtkCubeSource *m_Outline; + + // io // + vtkXMLImageDataReader *m_Reader; + vtkXMLImageDataWriter *m_Writer; + + // content // + vtkVoxImage::Content &m_Content; + + // visual // + float m_Window; + float m_Level; +}; + + + +void vtkVoxImagePimpl::GetContent() +{ + // ULIB -> VTK // + // const int *dims = static_cast(m_Content.GetDims().data()); + Vector3i dims = m_Content.GetDims(); + m_Image->SetDimensions(dims(0),dims(1),dims(2)); + + Vector3f spacing = m_Content.GetSpacing(); + m_Image->SetSpacing(spacing(0),spacing(1),spacing(2)); + + // Warning .. TODO: Read complete Transform matrix // + float *pos = m_Content.GetPosition().data(); + m_Image->SetOrigin(pos[0],pos[1],pos[2]); + + + vtkFloatArray *array = vtkFloatArray::SafeDownCast(m_Image->GetPointData()->GetScalars()); + if(!array) { + array = vtkFloatArray::New(); + array->SetNumberOfComponents(1); + array->SetName("volume_scalars"); + int n_tup = dims.prod(); + array->SetNumberOfTuples(n_tup); //m_Content.GetDims().prod()); + } + + Vector3i index(0,0,0); + int i=0; + for (int zv = 0; zv < dims[2]; ++zv) { + for (int yv = 0; yv < dims[1]; ++yv) { + for (int xv = 0; xv < dims[0]; ++xv) { + index << xv,yv,zv; + array->SetValue(i++,m_Content.GetValue(index)); + } + } + } + m_Image->GetPointData()->SetScalars(array); +// m_Image->Update(); +} + +void vtkVoxImagePimpl::SetContent() +{ + // VTK -> ULIB // + int *ext = m_Image->GetExtent(); + int dims[3] = { ext[1]-ext[0] + 1, ext[3]-ext[2] + 1, ext[5]-ext[4] + 1 }; + m_Content.SetDims(Vector3i(dims[0],dims[1],dims[2])); + + double *spacing = m_Image->GetSpacing(); + m_Content.SetSpacing(Vector3f(spacing[0],spacing[1],spacing[2])); + + // Warning .. TODO: Read complete Transform matrix // + double *pos = m_Image->GetOrigin(); + m_Content.SetPosition(Vector3f(pos[0],pos[1],pos[2])); + + vtkFloatArray *array = vtkFloatArray::SafeDownCast + (m_Image->GetPointData()->GetScalars()); + if(array) { + Vector3i index(0,0,0); + int i=0; + for (int zv = 0; zv < dims[2]; ++zv) { + for (int yv = 0; yv < dims[1]; ++yv) { + for (int xv = 0; xv < dims[0]; ++xv) { + index << xv,yv,zv; + m_Content.SetValue(index,array->GetValue(i++)); + } + } + } + } + else { + std::cerr << "Error reading array Value Data\n"; + } +} + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// VTK VOXIMAGE + +vtkVoxImage::vtkVoxImage(Content &content) : + d(new vtkVoxImagePimpl(content)) +{ + init_properties(); + d->GetContent(); + InstallPipe(); +} + +vtkVoxImage::~vtkVoxImage() +{ + delete d; +} + +vtkImageData *vtkVoxImage::GetImageData() +{ + d->GetContent(); + return d->m_Image; +} + +void vtkVoxImage::SaveToXMLFile(const char *fname) +{ + vtkSmartPointer writer = + vtkSmartPointer::New(); + writer->SetFileName(fname); + d->GetContent(); + vtkSmartPointer vtkscale = + vtkSmartPointer::New(); + +# if VTK_MAJOR_VERSION <= 5 + vtkscale->SetInputConnection(d->m_Image->GetProducerPort()); +# else + vtkscale->SetInputData(d->m_Image); +# endif + vtkscale->SetScale(p().writer_factor); + vtkscale->Update(); + writer->SetInputConnection(vtkscale->GetOutputPort()); + writer->Update(); + writer->Write(); +} + +void vtkVoxImage::ReadFromVKTFile(const char *fname) +{ + vtkSmartPointer reader = + vtkSmartPointer::New(); + reader->SetFileName(fname); + reader->Update(); + if(reader->IsFileStructuredPoints()) + { + vtkSmartPointer vtkscale = + vtkSmartPointer::New(); + vtkscale->SetInputConnection(reader->GetOutputPort()); + vtkscale->SetScale(1/p().writer_factor); + vtkscale->Update(); + + d->m_Image->DeepCopy(vtkscale->GetOutput()); // FIX! (pipe connection) + d->SetContent(); + } + else { + std::cerr << "Error: file does not contain structured points\n"; + } + d->m_Actor->Update(); +} + +void vtkVoxImage::ReadFromXMLFile(const char *fname) +{ + vtkSmartPointer reader = + vtkSmartPointer::New(); + reader->SetFileName(fname); + reader->Update(); + vtkSmartPointer vtkscale = + vtkSmartPointer::New(); + vtkscale->SetInputConnection(reader->GetOutputPort()); + vtkscale->SetScale(1/p().writer_factor); + vtkscale->Update(); + + d->m_Image->DeepCopy(vtkscale->GetOutput()); + d->SetContent(); +} + + +void vtkVoxImage::setShadingPreset(int blendType) +{ + vtkSmartVolumeMapper *mapper = + (vtkSmartVolumeMapper *)d->m_Actor->GetMapper(); + vtkVolumeProperty *property = d->m_Actor->GetProperty(); + + static vtkColorTransferFunction *colorFun = vtkColorTransferFunction::New(); + static vtkPiecewiseFunction *opacityFun = vtkPiecewiseFunction::New(); + + float window = 40 / $$.writer_factor; + float level = 20 / $$.writer_factor; + + property->SetColor(colorFun); + property->SetScalarOpacity(opacityFun); + property->SetInterpolationTypeToLinear(); + + if(blendType != 6) { + colorFun->RemoveAllPoints(); + opacityFun->RemoveAllPoints(); + } + + switch (blendType) { + // MIP + // Create an opacity ramp from the window and level values. + // Color is white. Blending is MIP. + case 0: + colorFun->AddRGBSegment(0.0, 1.0, 1.0, 1.0, 255.0, 1.0, 1.0, 1.0); + opacityFun->AddSegment(level - 0.5 * window, 0.0, + level + 0.5 * window, 1.0); + mapper->SetBlendModeToMaximumIntensity(); + break; + + // CompositeRamp + // Create a ramp from the window and level values. Use compositing + // without shading. Color is a ramp from black to white. + case 1: + colorFun->AddRGBSegment(level - 0.5 * window, 0.0, 0.0, 0.0, + level + 0.5 * window, 1.0, 1.0, 1.0); + opacityFun->AddSegment(level - 0.5 * window, 0.0, + level + 0.5 * window, 1.0); + mapper->SetBlendModeToComposite(); + property->ShadeOff(); + break; + + // CompositeShadeRamp + // Create a ramp from the window and level values. Use compositing + // with shading. Color is white. + case 2: + colorFun->AddRGBSegment(0.0, 1.0, 1.0, 1.0, 255.0, 1.0, 1.0, 1.0); + opacityFun->AddSegment(level - 0.5 * window, 0.0, + level + 0.5 * window, 1.0); + mapper->SetBlendModeToComposite(); + property->ShadeOn(); + break; + + // CT_Skin + // Use compositing and functions set to highlight skin in CT data + // Not for use on RGB data + case 3: + colorFun->AddRGBPoint(-3024, 0, 0, 0, 0.5, 0.0); + colorFun->AddRGBPoint(-1000, .62, .36, .18, 0.5, 0.0); + colorFun->AddRGBPoint(-500, .88, .60, .29, 0.33, 0.45); + colorFun->AddRGBPoint(3071, .83, .66, 1, 0.5, 0.0); + + opacityFun->AddPoint(-3024, 0, 0.5, 0.0); + opacityFun->AddPoint(-1000, 0, 0.5, 0.0); + opacityFun->AddPoint(-500, 1.0, 0.33, 0.45); + opacityFun->AddPoint(3071, 1.0, 0.5, 0.0); + + mapper->SetBlendModeToComposite(); + property->ShadeOn(); + property->SetAmbient(0.1); + property->SetDiffuse(0.9); + property->SetSpecular(0.2); + property->SetSpecularPower(10.0); + property->SetScalarOpacityUnitDistance(0.8919); + break; + + + default: + vtkGenericWarningMacro("Unknown blend type."); + break; + } +} + +void vtkVoxImage::Update() { + d->m_Actor->Update(); + d->m_Outline->SetBounds(d->m_Image->GetBounds()); + d->m_Outline->Update(); +} + +void vtkVoxImage::InstallPipe() +{ + vtkSmartPointer mapper = + vtkSmartPointer::New(); +# if VTK_MAJOR_VERSION <= 5 + mapper->SetInputConnection(d->m_Image->GetProducerPort()); +# else + mapper->SetInputData(d->m_Image); +# endif + mapper->Update(); + + d->m_Actor->SetMapper(mapper); + this->setShadingPreset(0); + mapper->Update(); + + d->m_Outline->SetBounds(d->m_Image->GetBounds()); + vtkSmartPointer mmapper = vtkSmartPointer::New(); + mmapper->SetInputConnection(d->m_Outline->GetOutputPort()); + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mmapper); + actor->GetProperty()->SetRepresentationToWireframe(); + actor->GetProperty()->SetAmbient(0.7); + + // this->SetProp(actor); + this->SetProp(d->m_Actor); +} + + +} // vtk +} // uLib diff --git a/src/Vtk/vtkVoxImage.h b/src/Vtk/vtkVoxImage.h new file mode 100644 index 0000000..6497f0a --- /dev/null +++ b/src/Vtk/vtkVoxImage.h @@ -0,0 +1,88 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_VTKVOXIMAGE_H +#define U_VTKVOXIMAGE_H + +#include +#include + +#include "uLibVtkInterface.h" + + +class vtkImageData; + +namespace uLib { +namespace Vtk { + +class vtkVoxImage : public Puppet { + uLibTypeMacro(vtkVoxImage,Puppet) +public: + properties() + { + float writer_factor; + }; + +public: + typedef Abstract::VoxImage Content; + + vtkVoxImage(Content &content); + + ~vtkVoxImage(); + + vtkImageData * GetImageData(); + + void SaveToXMLFile(const char *fname); + + void ReadFromVKTFile(const char *fname); + + void ReadFromXMLFile(const char *fname); + + void setShadingPreset(int blendType = 2); + + void Update(); + +protected: + void InstallPipe(); + +private: + class vtkVoxImagePimpl *d; +}; + + +inline void vtkVoxImage::init_properties() +{ + $_init(); + $$.writer_factor = 1.E6; +} + + +} // vtk +} // uLib + + +#endif // VTKVOXIMAGE_H diff --git a/src/Vtk/vtkVoxRaytracerRepresentation.cpp b/src/Vtk/vtkVoxRaytracerRepresentation.cpp new file mode 100644 index 0000000..7d019a7 --- /dev/null +++ b/src/Vtk/vtkVoxRaytracerRepresentation.cpp @@ -0,0 +1,459 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include "vtkVoxRaytracerRepresentation.h" + +#include "Math/VoxRaytracer.h" + +//#include "vtkMuonEvent.h" +#include "vtkMuonScatter.h" + + +namespace uLib { +namespace Vtk { + +///// PIMPL //////////////////////////////////////////////////////////////////// + +class vtkVoxRaytracerRepresentationPimpl { + +public: + vtkVoxRaytracerRepresentationPimpl(VoxRaytracer &content) : + m_Content(&content), + m_Assembly(vtkAssembly::New()), + m_Sphere1(vtkSphereSource::New()), + m_Sphere2(vtkSphereSource::New()), + m_Line1(vtkLineSource::New()), + m_Line2(vtkLineSource::New()), + m_Line3(vtkLineSource::New()), + m_RayLine(vtkAppendPolyData::New()), + m_RayLineActor(vtkActor::New()), + m_RayRepresentation(vtkAppendPolyData::New()), + m_RayRepresentationActor(vtkActor::New()), + m_Transform(vtkTransform::New()) + { + default_radius = content.GetImage()->GetSpacing()(0)/4; + m_Sphere1->SetRadius(default_radius); + m_Sphere2->SetRadius(default_radius); + m_SelectedElement = m_RayLine; + } + ~vtkVoxRaytracerRepresentationPimpl() + { + m_Assembly->Delete(); + m_RayLine->Delete(); + m_RayLineActor->Delete(); + m_RayRepresentationActor->Delete(); + m_Transform->Delete(); + } + + // members // + VoxRaytracer *m_Content; + + Scalarf default_radius; + vtkAssembly *m_Assembly; + vtkAppendPolyData *m_RayLine; + vtkActor *m_RayLineActor; + vtkActor *m_RayRepresentationActor; + vtkSmartPointer m_Transform; + VoxRaytracer::RayData m_Ray; + vtkSmartPointer m_Sphere1,m_Sphere2; + vtkSmartPointer m_Line1, m_Line2, m_Line3; + vtkSmartPointer m_RayRepresentation; + + vtkAppendPolyData *m_SelectedElement; +}; + + + + +//////////////////////////////////////////////////////////////////////////////// +////// VOX RAYTRACER REPRESENTATION /////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + + +vtkVoxRaytracerRepresentation::vtkVoxRaytracerRepresentation(Content &content) : + d(new vtkVoxRaytracerRepresentationPimpl(content)) +{ + InstallPipe(); +} + +vtkVoxRaytracerRepresentation::~vtkVoxRaytracerRepresentation() +{ + delete d; +} + +VoxRaytracer *vtkVoxRaytracerRepresentation::GetRaytracerAlgorithm() +{ + return d->m_Content; +} + +vtkProp *vtkVoxRaytracerRepresentation::GetProp() +{ + return d->m_Assembly; +} + +vtkPolyData *vtkVoxRaytracerRepresentation::GetPolyData() const +{ + std::cout << "get Raytracer polydata\n"; + d->m_SelectedElement->Update(); + return d->m_SelectedElement->GetOutput(); +} + +void vtkVoxRaytracerRepresentation::SetRepresentationElements(vtkVoxRaytracerRepresentation::RepresentationElements el) +{ + switch(el) { + case Vtk::vtkVoxRaytracerRepresentation::RayElements: + d->m_SelectedElement = d->m_RayLine; + break; + case Vtk::vtkVoxRaytracerRepresentation::VoxelsElements: + d->m_SelectedElement = d->m_RayRepresentation; + break; + default: + d->m_SelectedElement = d->m_RayLine; + break; + } +} + + +void vtkVoxRaytracerRepresentation::SetMuon(MuonScatter &muon) +{ + Vector4f pt1,pt2,src; + src = muon.LineIn().origin(); + d->m_Content->GetEntryPoint(muon.LineIn(),pt1); + d->m_Sphere1->SetCenter(pt1(0),pt1(1),pt1(2)); + d->m_Line1->SetPoint1(src(0),src(1),src(2)); + d->m_Line1->SetPoint2(pt1(0),pt1(1),pt1(2)); + + HLine3f line_out = muon.LineOut(); + src = line_out.origin(); + float *direction = line_out.direction().data(); + for(int i=0;i<3;++i) direction[i] *= -1; + d->m_Content->GetEntryPoint(line_out,pt2); + d->m_Sphere2->SetCenter(pt2(0),pt2(1),pt2(2)); + d->m_Line2->SetPoint1(src(0),src(1),src(2)); + d->m_Line2->SetPoint2(pt2(0),pt2(1),pt2(2)); + + d->m_Line3->SetPoint1(pt1(0),pt1(1),pt1(2)); + d->m_Line3->SetPoint2(pt2(0),pt2(1),pt2(2)); + + // Create a vtkPoints object and store the points in it + vtkSmartPointer points = + vtkSmartPointer::New(); + points->InsertNextPoint(pt1(0),pt1(1),pt1(2)); + points->InsertNextPoint(pt2(0),pt2(1),pt2(2)); + + // Create a cell array to store the lines in and add the lines to it + vtkSmartPointer lines = + vtkSmartPointer::New(); + + vtkSmartPointer line = + vtkSmartPointer::New(); + line->GetPointIds()->SetId(0,0); + line->GetPointIds()->SetId(1,1); + lines->InsertNextCell(line); + + // Create a polydata to store everything in + vtkSmartPointer linesPolyData = + vtkSmartPointer::New(); + + // Add the points to the dataset + linesPolyData->SetPoints(points); + + // Add the lines to the dataset + linesPolyData->SetLines(lines); + + d->m_RayLine->RemoveAllInputs(); +# if VTK_MAJOR_VERSION <= 5 + d->m_RayLine->AddInputConnection(linesPolyData->GetProducerPort()); +# else + d->m_RayLine->AddInputData(linesPolyData); +# endif + d->m_RayLine->AddInputConnection(d->m_Line1->GetOutputPort()); + d->m_RayLine->AddInputConnection(d->m_Sphere1->GetOutputPort()); + d->m_RayLine->AddInputConnection(d->m_Line2->GetOutputPort()); + d->m_RayLine->AddInputConnection(d->m_Sphere2->GetOutputPort()); +// d->m_RayLine->AddInputConnection(d->m_Line3->GetOutputPort()); + + + vtkSmartPointer vmat = vtkSmartPointer::New(); + Matrix4f mat = d->m_Content->GetImage()->GetWorldMatrix(); + for(int i=0; i<4; ++i) + for(int j=0; j<4; ++j) + vmat->SetElement(i,j,mat(i,j)); + d->m_Transform->SetMatrix(vmat); + + this->SetRay(pt1,pt2); +} + +void vtkVoxRaytracerRepresentation::SetMuon(MuonScatter &muon, Vector4f poca) +{ + Vector4f pt1,pt2,src; + src = muon.LineIn().origin(); + d->m_Content->GetEntryPoint(muon.LineIn(),pt1); + d->m_Sphere1->SetCenter(pt1(0),pt1(1),pt1(2)); + d->m_Line1->SetPoint1(src(0),src(1),src(2)); + d->m_Line1->SetPoint2(pt1(0),pt1(1),pt1(2)); + + HLine3f line_out = muon.LineOut(); + src = line_out.origin(); + float *direction = line_out.direction().data(); + for(int i=0;i<3;++i) direction[i] *= -1; + d->m_Content->GetEntryPoint(line_out,pt2); + d->m_Sphere2->SetCenter(pt2(0),pt2(1),pt2(2)); + d->m_Line2->SetPoint1(src(0),src(1),src(2)); + d->m_Line2->SetPoint2(pt2(0),pt2(1),pt2(2)); + + d->m_Line3->SetPoint1(pt1(0),pt1(1),pt1(2)); + d->m_Line3->SetPoint2(pt2(0),pt2(1),pt2(2)); + + // Create a vtkPoints object and store the points in it + vtkSmartPointer points = + vtkSmartPointer::New(); + points->InsertNextPoint(pt1(0),pt1(1),pt1(2)); + points->InsertNextPoint(poca(0),poca(1),poca(2)); + points->InsertNextPoint(pt2(0),pt2(1),pt2(2)); + + // Create a cell array to store the lines in and add the lines to it + vtkSmartPointer lines = + vtkSmartPointer::New(); + + for(unsigned int i = 0; i < 2; i++) + { + vtkSmartPointer line = + vtkSmartPointer::New(); + line->GetPointIds()->SetId(0,i); + line->GetPointIds()->SetId(1,i+1); + lines->InsertNextCell(line); + } + + // Create a polydata to store everything in + vtkSmartPointer linesPolyData = + vtkSmartPointer::New(); + + // Add the points to the dataset + linesPolyData->SetPoints(points); + + // Add the lines to the dataset + linesPolyData->SetLines(lines); + + d->m_RayLine->RemoveAllInputs(); +# if VTK_MAJOR_VERSION <= 5 + d->m_RayLine->AddInputConnection(linesPolyData->GetProducerPort()); +# else + d->m_RayLine->AddInputData(linesPolyData); +# endif + d->m_RayLine->AddInputConnection(d->m_Line1->GetOutputPort()); + d->m_RayLine->AddInputConnection(d->m_Sphere1->GetOutputPort()); + d->m_RayLine->AddInputConnection(d->m_Line2->GetOutputPort()); + d->m_RayLine->AddInputConnection(d->m_Sphere2->GetOutputPort()); +// d->m_RayLine->AddInputConnection(d->m_Line3->GetOutputPort()); + + + vtkSmartPointer poca_sphere = + vtkSmartPointer::New(); + poca_sphere->SetRadius(d->default_radius); + poca_sphere->SetCenter(poca(0),poca(1),poca(2)); + d->m_RayLine->AddInputConnection(poca_sphere->GetOutputPort()); + + + vtkSmartPointer vmat = vtkSmartPointer::New(); + Matrix4f mat = d->m_Content->GetImage()->GetWorldMatrix(); + for(int i=0; i<4; ++i) + for(int j=0; j<4; ++j) + vmat->SetElement(i,j,mat(i,j)); + d->m_Transform->SetMatrix(vmat); + + if(d->m_Content->GetImage()->IsInsideBounds(poca)) + this->SetRay(pt1,poca,pt2); + else + this->SetRay(pt1,pt2); +} + + +void vtkVoxRaytracerRepresentation::SetMuon(vtkMuonScatter &muon) +{ + Vector4f poca = muon.GetPocaPoint(); + MuonScatter &mu = muon.GetContent(); + this->SetMuon(mu,poca); +} + + +VoxRaytracer::RayData vtkVoxRaytracerRepresentation::GetRay() +{ + return d->m_Ray; +} + +void vtkVoxRaytracerRepresentation::SetRay(Vector4f in, Vector4f out) +{ + d->m_Ray = d->m_Content->TraceBetweenPoints(in,out); + this->SetRay(&d->m_Ray); +} + +void vtkVoxRaytracerRepresentation::SetRay(Vector4f in, Vector4f mid, Vector4f out) +{ + d->m_Ray = d->m_Content->TraceBetweenPoints(in,mid); + d->m_Ray.AppendRay( d->m_Content->TraceBetweenPoints(mid,out) ); + this->SetRay(&d->m_Ray); +} + +void vtkVoxRaytracerRepresentation::SetRay(VoxRaytracer::RayData *ray) +{ + vtkAppendPolyData *appender = d->m_RayRepresentation; + appender->RemoveAllInputs(); + + for(int i=0; iData().size(); ++i) { + int id = ray->Data().at(i).vox_id; + Vector3i idv = d->m_Content->GetImage()->UnMap(id); + vtkSmartPointer cube = + vtkSmartPointer::New(); + cube->SetBounds(idv(0),idv(0)+1,idv(1),idv(1)+1,idv(2),idv(2)+1); + cube->Update(); +# if VTK_MAJOR_VERSION <= 5 + appender->AddInput(cube->GetOutput()); +# else + appender->AddInputData(cube->GetOutput()); +# endif + appender->Update(); + } + +} + +void vtkVoxRaytracerRepresentation::SetVoxelsColor(Vector4f rgba) +{ + this->SetColor(d->m_RayRepresentationActor,rgba); +} + +void vtkVoxRaytracerRepresentation::SetRayColor(Vector4f rgba) +{ + this->SetColor(d->m_RayLineActor,rgba); +} + +void vtkVoxRaytracerRepresentation::SetColor(vtkActor *actor, Vector4f rgba) +{ + if(!actor) return; + vtkProperty *pr = actor->GetProperty(); + pr->SetDiffuseColor( rgba(0), + rgba(1), + rgba(2) ); + pr->SetOpacity( rgba(3) ); + pr->SetDiffuse(1); +} + + + + +void vtkVoxRaytracerRepresentation::InstallPipe() +{ + + vtkSmartPointer append = + vtkSmartPointer::New(); + append->AddInputConnection(d->m_Sphere1->GetOutputPort()); + append->AddInputConnection(d->m_Sphere2->GetOutputPort()); + append->AddInputConnection(d->m_Line1->GetOutputPort()); + append->AddInputConnection(d->m_Line2->GetOutputPort()); + + append->Update(); + vtkSmartPointer mapper = + vtkSmartPointer::New(); + + mapper->SetInputConnection(append->GetOutputPort()); + mapper->Update(); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + actor->GetProperty()->SetColor(0.6,0.6,1); + this->SetProp(actor); + + mapper = vtkSmartPointer::New(); + mapper->SetInputConnection(d->m_RayLine->GetOutputPort()); + mapper->Update(); + + d->m_RayLineActor->SetMapper(mapper); + d->m_RayLineActor->GetProperty()->SetColor(1,0,0); + this->SetProp(d->m_RayLineActor); + +// mapper = vtkSmartPointer::New(); +// mapper->SetInputConnection(d->m_Line3->GetOutputPort()); +// mapper->Update(); + +// actor = vtkSmartPointer::New(); +// actor->SetMapper(mapper); +// actor->GetProperty()->SetColor(1,0,0); +// d->m_Assembly->AddPart(actor); + + + vtkSmartPointer polyfilter = + vtkSmartPointer::New(); + + polyfilter->SetInputConnection(d->m_RayRepresentation->GetOutputPort()); + polyfilter->SetTransform(d->m_Transform); + + mapper = vtkSmartPointer::New(); + mapper->SetInputConnection(polyfilter->GetOutputPort()); + mapper->Update(); + + vtkActor *vra = d->m_RayRepresentationActor; + vra->SetMapper(mapper); + vra->GetProperty()->SetOpacity(0.2); + vra->GetProperty()->SetEdgeVisibility(true); + vra->GetProperty()->SetColor(0.5,0.5,0.5); + + this->SetProp(vra); +} + + + + + + + +} // vtk +} // uLib diff --git a/src/Vtk/vtkVoxRaytracerRepresentation.h b/src/Vtk/vtkVoxRaytracerRepresentation.h new file mode 100644 index 0000000..4955e53 --- /dev/null +++ b/src/Vtk/vtkVoxRaytracerRepresentation.h @@ -0,0 +1,101 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_VTKVOXRAYTRACERREPRESENTATION_H +#define U_VTKVOXRAYTRACERREPRESENTATION_H + + +#include "Core/Macros.h" +#include "Math/Dense.h" + +#include "uLibVtkInterface.h" + +#include "Detectors/MuonScatter.h" + +#include "Math/ImageData.h" +#include "Math/VoxRaytracer.h" + + +class vtkActor; + +namespace uLib { +namespace Vtk { + +class vtkVoxRaytracerRepresentation : public Puppet { + typedef VoxRaytracer Content; +public: + vtkVoxRaytracerRepresentation(Content &content); + ~vtkVoxRaytracerRepresentation(); + + uLib::VoxRaytracer *GetRaytracerAlgorithm(); + + vtkProp *GetProp(); + + vtkPolyData *GetPolyData() const; + + enum RepresentationElements { + RayElements, + VoxelsElements + }; + void SetRepresentationElements(enum RepresentationElements el); + + void SetMuon(MuonScatter &muon); + + void SetMuon(MuonScatter &muon, Vector4f poca); + + void SetMuon(class vtkMuonEvent &muon); + + void SetMuon(class vtkMuonScatter &muon); + + VoxRaytracer::RayData GetRay(); + + void SetRay(Vector4f in, Vector4f out); + + void SetRay(Vector4f in, Vector4f mid, Vector4f out); + + void SetRay(VoxRaytracer::RayData *ray); + + void SetVoxelsColor(Vector4f rgba); + void SetRayColor(Vector4f rgba); + + + +private: + void InstallPipe(); + + void SetColor(vtkActor *actor, Vector4f rgba); + + friend class vtkVoxRaytracerRepresentationPimpl; + class vtkVoxRaytracerRepresentationPimpl *d; +}; + + +} // vtk +} // uLib + + +#endif // VTKVOXRAYTRACERREPRESENTATION_H diff --git a/src/Vtk/vtkuLibProp.h b/src/Vtk/vtkuLibProp.h new file mode 100644 index 0000000..fd6be35 --- /dev/null +++ b/src/Vtk/vtkuLibProp.h @@ -0,0 +1,51 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_VTKULIBPROP_H +#define U_VTKULIBPROP_H + +class vtkProp; + +namespace uLib { +namespace Abstract { + +class uLibVtkProp { +public: + virtual vtkProp *GetProp() = 0; + +protected: + ~uLibVtkProp() {} +}; + + + + +} + +} + +#endif // VTKULIBPROP_H diff --git a/src/cwchar.h b/src/cwchar.h new file mode 100644 index 0000000..c6f851e --- /dev/null +++ b/src/cwchar.h @@ -0,0 +1,37 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef U_CWCHAR_H +#define U_CWCHAR_H + +// cwchar.h does not exist, should be called "wchar.h" in C or in C++ +// this file serves as a patch to fix a error inclusion done by Root in cint. +// it must be placed in a included project directory + +#include + +#endif // CWCHAR_H diff --git a/src/ltk/CMakeLists.txt b/src/ltk/CMakeLists.txt new file mode 100644 index 0000000..8921da0 --- /dev/null +++ b/src/ltk/CMakeLists.txt @@ -0,0 +1,12 @@ + +set(HEADERS + ltktypes.h + ltkmacros.h + ltkdebug.h +) + +SET(SOURCES) + +set(LIBRARIES) + +uLib_add_shared_library(${uLib-module}) diff --git a/src/ltk/DenseMatrix.h b/src/ltk/DenseMatrix.h new file mode 100644 index 0000000..1214526 --- /dev/null +++ b/src/ltk/DenseMatrix.h @@ -0,0 +1,111 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#ifndef DENSEMATRIX_H +#define DENSEMATRIX_H + +#include "templates.h" +#include "Vector.h" + +BEGIN_NAMESPACE(ltk) + +/* ////////////////////////////////////////////////////////////////////////// */ +/* //////////////////////////// MATRIX ////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +C_BEGIN_DECLS + +#define LTK_MATRIX_DECLARE_FUNC(Type,ltkType,Class_name,csize,rsize) \ + inline Type ltkType##_##Class_name##_get(ltkType m, \ + unsigned int c, \ + unsigned int r) \ + { \ + assert(c + r * csize < csize * rsize); \ + return *((ltkType)m + c + r * csize); \ + } \ + inline void ltkType##_##Class_name##_set(ltkType m, \ + unsigned int c, \ + unsigned int r, \ + Type t) \ + { \ + assert (c + r * csize < csize * rsize); \ + *((ltkType)m + c + r * csize) = t; \ + } + + +#define LTK_MATRIX_DECLARE(Type,Type_name,csize,rsize) \ + typedef Type * Type_name; \ + LTK_SIMPLE_ALLOC_FUNC(Type, Type_name,ltk_matrix,csize * rsize) \ + LTK_MATRIX_DECLARE_FUNC(Type,Type_name,ltk_matrix,csize,rsize) + +C_END_DECLS + +#ifdef __cplusplus + +template class ltkDenseMatrix +: public ltkAbstractBuffer< T, csize * rsize > +{ +protected: + typedef ltkDenseMatrix ThisClass; + typedef ltkAbstractBuffer BaseClass; +public: + ltkDenseMatrix() {} + ~ltkDenseMatrix() { } + + inline T* getBuffer() { + return (T*)m_buffer; + } + inline const T* getBuffer() const { + return (const T*)m_buffer; + } + + ThisClass & operator =(const ThisClass &src) { + if (this != &src) { + CType_ltk_matrix_copy(m_buffer, (const CType) src.getBuffer()); + } + } + + typedef struct BaseClass::CommaInit CommaInit; + inline CommaInit operator = (T scalar) { + return this->operator <<(scalar); + } + + +private: + LTK_MATRIX_DECLARE(T,CType, csize, rsize); + T m_buffer [csize * rsize]; +}; + + + + +#endif // __cplusplus + +END_NAMESPACE + +#endif // DENSEMATRIX_H diff --git a/src/ltk/Makefile.am b/src/ltk/Makefile.am new file mode 100644 index 0000000..5f0e5d0 --- /dev/null +++ b/src/ltk/Makefile.am @@ -0,0 +1,6 @@ +include $(top_srcdir)/Common.am + +library_includedir = $(includedir)/libmutom-${PACKAGE_VERSION}/ltk +library_include_HEADERS = ltktypes.h \ + ltkmacros.h \ + ltkdebug.h diff --git a/src/ltk/Object.c b/src/ltk/Object.c new file mode 100644 index 0000000..6269c9a --- /dev/null +++ b/src/ltk/Object.c @@ -0,0 +1,18 @@ +#include "Object.h" + + +static const struct _ltkObjectClass { + size_t class_size; + void (* constructor)(struct _Object *); + void (* destructor) (struct _Object *); + int (* GetElement) (struct _Object *); +} _ObjectClassInstance; + +const struct _ltkObjectClass *ltkObjectClass = &_ObjectClassInstance; + +ltkPointer Object_new(struct _ObjectClass klass) +{ + struct _Object *ob = (struct _Object)malloc(klass->class_size); + klass->constructor(ob); + return ob; +} diff --git a/src/ltk/Object.h b/src/ltk/Object.h new file mode 100644 index 0000000..a39a87a --- /dev/null +++ b/src/ltk/Object.h @@ -0,0 +1,78 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef OBJECT_H +#define OBJECT_H + +#include // for std allocator // +#include // for memcpy // +#include + +#include "templates.h" + +BEGIN_NAMESPACE(ltk) + + +C_BEGIN_DECLS + +struct _ltkObject +{ + int element; +}; + +struct _ltkObjectClass { + size_t class_size; + void (* constructor)(struct _ltkObject *); + void (* destructor) (struct _ltkObject *); + int (* GetElement) (struct _ltkObject *); +}; + +struct _ltkObject *ltk_object_new() +{ + return NULL; +} + + +C_END_DECLS + +#ifdef __cplusplus + +class Object +{ + struct _ltkObject *d; + typedef struct _ltkObject ObjectType; + public: + Object() : d(new ObjectType()) { d->element = 5552368; } + int GetElement() { return d->element; } +}; + +#endif + + +END_NAMESPACE + +#endif //OBJECT_H diff --git a/src/ltk/Vector.h b/src/ltk/Vector.h new file mode 100644 index 0000000..229295b --- /dev/null +++ b/src/ltk/Vector.h @@ -0,0 +1,195 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +/* + * File: denseVector.h + * Author: andrea + * + * Created on July 6, 2012, 3:41 PM + */ + +#ifndef VECTOR_H +#define VECTOR_H + +#include // for std allocator // +#include // for memcpy // +#include + +#include "templates.h" + +BEGIN_NAMESPACE(ltk) + +/* ////////////////////////////////////////////////////////////////////////// */ +/* //////////////////////////// VECTOR ///////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +C_BEGIN_DECLS + +#define LTK_VECTOR_DECLARE(Type,Type_name,size) \ + typedef Type *Type_name; \ + LTK_SIMPLE_ALLOC_FUNC(Type,Type_name,ltk_vector,size) \ + inline unsigned int Type_name##_ltk_vector_size() { return size; } \ + inline Type Type_name##_ltk_vector_get(Type_name vector, unsigned int i) \ + { return *(vector+i); } \ + inline void Type_name##_ltk_vector_set(Type_name vector, unsigned int i, \ + Type data) { *(vector+i) = data; } + +C_END_DECLS + +#ifdef __cplusplus + +template class ltkVector +: public ltkAbstractBuffer< T, size > +{ + T m_vector [size]; +protected: + typedef ltkVector ThisClass; + typedef ltkAbstractBuffer BaseClass; +public: + ltkVector() {} + ltkVector(const ltkVector ©) { + CType_ltk_vector_copy(m_vector, (const CType) copy.getBuffer()); + } + + virtual ~ltkVector() { } + + inline unsigned int getSize() const { + return size; + } + inline T* getBuffer() { + return (T*)m_vector; + } + inline const T* getBuffer() const { + return (const T*)m_vector; + } + + + + ThisClass & operator =(const ThisClass &src) { + if (this != &src) { + CType_ltk_vector_copy(m_vector, (const CType) src.getBuffer()); + } + } + + typedef struct BaseClass::CommaInit CommaInit; + inline CommaInit operator = (T scalar) { + return this->operator <<(scalar); + } + + // MATH // + inline bool operator ==(const ThisClass &in) { + int test = 0; + for (int i = 0; i < size; ++i) test += this->at(i) != in(i); + return test == 0; + } + + inline bool operator !=(const ThisClass &in) { + return !this->operator ==(in); + } + + inline void operator +=(const ThisClass &in) { + for (int i = 0; i < size; ++i) this->at(i) += in(i); + } + inline void operator -=(const ThisClass &in) { + for (int i = 0; i < size; ++i) this->at(i) -= in(i); + } + inline void operator *=(const ThisClass &in) { + for (int i = 0; i < size; ++i) this->at(i) *= in(i); + } + inline void operator /=(const ThisClass &in) { + for (int i = 0; i < size; ++i) this->at(i) /= in(i); + } + + inline void operator +=(const T t) { + for (int i = 0; i < size; ++i) this->at(i) += t; + } + inline void operator -=(const T t) { + for (int i = 0; i < size; ++i) this->at(i) -= t; + } + inline void operator *=(const T t) { + for (int i = 0; i < size; ++i) this->at(i) *= t; + } + inline void operator /=(const T t) { + for (int i = 0; i < size; ++i) this->at(i) /= t; + } + + inline ThisClass & operator + (const ThisClass &in) { + ThisClass *out = new ThisClass(); + for (int i = 0; i < size; ++i) out->at(i) = this->at(i) + in(i); + return *out; + } + inline ThisClass & operator - (const ThisClass &in) { + ThisClass *out = new ThisClass(); + for (int i = 0; i < size; ++i) out->at(i) = this->at(i) - in(i); + return *out; + } + + // fix with constructor and product null element ------------- // + inline T operator * (const ThisClass &in) { + T out = 0; + for (int i = 0; i < size; ++i) out += this->at(i) * in(i); + return out; + } + inline T operator / (const ThisClass &in) { + T out = 0; + for (int i = 0; i < size; ++i) out += this->at(i) / in(i); + return out; + } + // ------------------------------------------------------------- // + + inline ThisClass & operator +(const T t) { + ThisClass *out = new ThisClass(); + for (int i = 0; i < size; ++i) out->at(i) = this->at(i) + t; + return *out; + } + inline ThisClass & operator -(const T t) { + ThisClass *out = new ThisClass(); + for (int i = 0; i < size; ++i) out->at(i) = this->at(i) - t; + return *out; + } + inline ThisClass & operator *(const T t) { + ThisClass *out = new ThisClass(); + for (int i = 0; i < size; ++i) out->at(i) = this->at(i) * t; + return *out; + } + inline ThisClass & operator /(const T t) { + ThisClass *out = new ThisClass(); + for (int i = 0; i < size; ++i) out->at(i) = this->at(i) / t; + return *out; + } +private: + LTK_VECTOR_DECLARE(T,CType, size) +}; + +#endif // __cplusplus + + + + +END_NAMESPACE // ltk +#endif /* DENSEVECTOR_H */ + diff --git a/src/ltk/container.h b/src/ltk/container.h new file mode 100644 index 0000000..58dbdc7 --- /dev/null +++ b/src/ltk/container.h @@ -0,0 +1,43 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +/* + * File: comma_init.h + * Author: andrea + * + * Created on May 24, 2012, 3:12 PM + */ + +#ifndef CONTAINER_H +#define CONTAINER_H + +#include + + + +#endif /* CONTAINER_H */ + diff --git a/src/ltk/ltk.h b/src/ltk/ltk.h new file mode 100644 index 0000000..38a16f2 --- /dev/null +++ b/src/ltk/ltk.h @@ -0,0 +1,32 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + + +#include "templates.h" +#include "Vector.h" +#include "DenseMatrix.h" diff --git a/src/ltk/ltk_bridge/ltkb.c b/src/ltk/ltk_bridge/ltkb.c new file mode 100644 index 0000000..f1b3d91 --- /dev/null +++ b/src/ltk/ltk_bridge/ltkb.c @@ -0,0 +1,339 @@ +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef MODVERSIONS +# include +#endif +#include +#include +#include + + + +/* methods of the character device */ +static int ltkb_open(struct inode *inode, struct file *filp); +static int ltkb_release(struct inode *inode, struct file *filp); +static int ltkb_mmap(struct file *filp, struct vm_area_struct *vma); +static ssize_t ltkb_read(struct file *filp, + char __user *buffer, + size_t count, + loff_t *offp); +static ssize_t ltkb_write(struct file *filp, + const char __user *buffer, + size_t count, + loff_t *offp); + + +// internal data +// length of the two memory areas +#define NPAGES 16 +// pointer to the vmalloc'd area - alway page aligned +static int *vmalloc_area; +// pointer to the kmalloc'd area, rounded up to a page boundary +static int *kmalloc_area; +// original pointer for kmalloc'd area as returned by kmalloc +static void *kmalloc_ptr; + + +#define BUF_LEN 80 +static int Device_Open = 0; + +static char Message[BUF_LEN]; +/* + * How far did the process reading the message get? + * Useful if the message is larger than the size of the + * buffer we get to fill in device_read. + */ +static char *Message_Ptr; + + +struct ltkb_dev { + struct cdev cdev; // device structure + struct semaphore semaphore; // lock semaphore for race control + char *message; // message passing from/to user + unsigned int size; // size of data stored + unsigned int acl_key; // user access control +}; + +struct ltkb_dev *_ltkb_devices; // devices array // + + + + + +/////// OPEN AND RELEASE /////////////////////////////////////////////////////// +static int ltkb_open(struct inode *inode, struct file *filp) +{ + // insert cdev data in dev structure and file->private_data // + struct ltkb_dev *dev; + dev = container_of (inode->i_cdev, struct ltkb_dev, cdev); + + // this shares dev for all methods // + filp->private_data = dev; + + pr_debug("ltk bridge opened"); + return 0; +} +/* character device last close method */ +static int ltkb_release(struct inode *inode, struct file *filp) +{ + pr_debug("ltk bridge released"); + return 0; +} +// -------------------------------------------------------------------------- // + + + +// kmalloc instancer // +int ltkb_kmem(struct file *filp, struct vm_area_struct *vma) +{ + int ret; + long length = vma->vm_end - vma->vm_start; + + /* check length - do not allow larger mappings than the number of + pages allocated */ + if (length > NPAGES * PAGE_SIZE) + return -EIO; + + /* map the whole physically contiguous area in one piece */ + if ((ret = remap_pfn_range(vma, + vma->vm_start, + virt_to_phys((void *)kmalloc_area) >> PAGE_SHIFT, + length, + vma->vm_page_prot)) < 0) { + return ret; + } + return 0; +} +// vmalloc instancer // +int ltkb_vmem(struct file *filp, struct vm_area_struct *vma) +{ + int ret; + long length = vma->vm_end - vma->vm_start; + unsigned long start = vma->vm_start; + char *vmalloc_area_ptr = (char *)vmalloc_area; + unsigned long pfn; + + /* check length - do not allow larger mappings than the number of + pages allocated */ + if (length > NPAGES * PAGE_SIZE) + return -EIO; + + /* loop over all pages, map it page individually */ + while (length > 0) { + pfn = vmalloc_to_pfn(vmalloc_area_ptr); + if ((ret = remap_pfn_range(vma, start, pfn, PAGE_SIZE, + PAGE_SHARED)) < 0) { + return ret; + } + start += PAGE_SIZE; + vmalloc_area_ptr += PAGE_SIZE; + length -= PAGE_SIZE; + } + return 0; +} + + + +// mmap function // +static int ltkb_mmap(struct file *filp, struct vm_area_struct *vma) +{ + /* at offset 0 we map the vmalloc'd area */ + if (vma->vm_pgoff == 0) { + return ltkb_vmem(filp, vma); + } + /* at offset NPAGES we map the kmalloc'd area */ + if (vma->vm_pgoff == NPAGES) { + return ltkb_kmem(filp, vma); + } + /* at any other offset we return an error */ + return -EIO; +} + + + + +////////////// CHAR DEVICE READ/WRITE ///////////////////////////////////////// +static ssize_t ltkb_read(struct file *filp, /* see include/linux/fs.h */ + char __user *buffer, /* buffer to fill with data */ + size_t length, /* length of the buffer */ + loff_t * offset) +{ + +#ifdef _DEBUG + printk(KERN_INFO "device_read(%p,%s,%d)", filp, buffer, (int)length); +#endif + + return 0; +} + +static ssize_t ltkb_write(struct file *filp, + const char __user *buffer, + size_t length, + loff_t * offset) +{ +#ifdef _DEBUG + printk(KERN_INFO "device_write(%p,%s,%d)", filp, buffer, (int)length); +#endif + return 0; +} +// ------------------------------------------------------------------------- // + + +#define LTKB_IOC_HEADER 'b' + +#define LTKB_IOC_RESET _IO(LTKB_IOC_HEADER, 0) +#define LTKB_IOC_PING _IOWR(LTKB_IOC_HEADER, 1, char) + +#define LTKB_IOC_MAXNR 1 + +////////////// IOCTL /////////////////////////////////////////////////////////// +int ltkb_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + char c = 0; + int retval = 0; + + /* + * extract the type and number bitfields, and don't decode + * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok() + */ + if (_IOC_TYPE(cmd) != LTKB_IOC_HEADER) return -ENOTTY; + if (_IOC_NR(cmd) > LTKB_IOC_MAXNR) return -ENOTTY; + + // TODO user access control // + + + switch(cmd) { + case LTKB_IOC_RESET: + if(!capable(CAP_SYS_ADMIN)) + return -EPERM; + // TODO free all memory mapping// + break; + case LTKB_IOC_PING: + retval = __get_user(c,(char __user *)arg); + c++; + retval = __put_user(c,(char __user *)arg); + break; + default: + return -ENOTTY; + } + return retval; + +} +// ------------------------------------------------------------------------- // + + + + + +#ifndef LTKB_MAJOR +#define LTKB_MAJOR 0 +#endif + +#ifndef LTKB_NR_DEVS +#define LTKB_NR_DEVS 4 +#endif + +#ifndef LTKB_DEVICE_NAME +#define LTKB_DEVICE_NAME "ltkb" +#endif + + + +/* the file operations, i.e. all character device methods */ +static struct file_operations ltkb_fops = { + .open = ltkb_open, + .release = ltkb_release, + .read = ltkb_read, + .write = ltkb_write, + .ioctl = ltkb_ioctl, + .mmap = ltkb_mmap, + .owner = THIS_MODULE, +}; + +static int _ltkb_major_number = LTKB_MAJOR; + +// Module init function //////////////////////////////////////////////////////// +static int __init ltkb_init(void) +{ + int i,ret = 0; + dev_t dev = 0; + + // REGISTER DEVICE // + if(_ltkb_major_number) + { + dev = MKDEV(_ltkb_major_number,0); + ret = register_chrdev_region(dev, LTKB_NR_DEVS, LTKB_DEVICE_NAME); + } + else { + ret = alloc_chrdev_region(&dev, 0, LTKB_NR_DEVS, LTKB_DEVICE_NAME ); + _ltkb_major_number = MAJOR(dev); + } + if (ret < 0) { + printk(KERN_WARNING "could not allocate major number %d for ltkb\n", + _ltkb_major_number); + return ret; + } + + // ALLOCATE DEVICES // + _ltkb_devices = kmalloc( LTKB_NR_DEVS * sizeof(struct ltkb_dev), GFP_KERNEL ); + if(!_ltkb_devices) { + printk(KERN_ERR "error allocating device structure in memory"); + return -ENOMEM; + } + memset(_ltkb_devices, 0, LTKB_NR_DEVS * sizeof(struct ltkb_dev)); + + // SETUP DEVICES // + for (i = 0 ; i < LTKB_NR_DEVS ; i++ ) + { + struct ltkb_dev *dev = &_ltkb_devices[i]; + int devno = MKDEV(_ltkb_major_number, i); + cdev_init (&dev->cdev, <kb_fops); + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = <kb_fops; + ret = cdev_add(&dev->cdev,devno,1); + if(ret) printk(KERN_NOTICE "Error %d adding ltkb%d device", ret, i); + init_MUTEX(&dev->semaphore); + } + printk( KERN_NOTICE "ltk bridge module loaded"); + return ret; +} + +// module release // +static void __exit ltkb_exit(void) +{ + // remove the character deivce // + int i; + dev_t devno = MKDEV(_ltkb_major_number,0); + if(_ltkb_devices) + { + for(i=0;i +#include +#include +#include +#include +#include +#include +#include + +#define LTKB_IOC_HEADER 'b' + +#define LTKB_IOC_RESET _IO(LTKB_IOC_HEADER, 0) +#define LTKB_IOC_PING _IOWR(LTKB_IOC_HEADER, 1, char) + +#define LTKB_IOC_MAXNR 1 + + +int main(void) +{ + int fd; + + if ((fd=open("ltkb0", O_RDWR|O_SYNC))<0) + { + perror("open"); + exit(-1); + } + + char buffer[200] = "hello"; + write(fd, (void *)&buffer, 6); + + char c = 'a'; + printf("%c ",c); + ioctl(fd, LTKB_IOC_PING, &c); + printf("%c ",c); + ioctl(fd, LTKB_IOC_PING, &c); + printf("%c\n",c); + close(fd); + return(0); +} + diff --git a/src/ltk/ltk_bridge/setup.sh b/src/ltk/ltk_bridge/setup.sh new file mode 100755 index 0000000..1886632 --- /dev/null +++ b/src/ltk/ltk_bridge/setup.sh @@ -0,0 +1,21 @@ +#!/bin/sh +module="ltkb" +device="ltkb" +mode="664" + +/sbin/insmod ./$module.ko $* || exit 1 + +rm -f ./${device}[0-3] + +major=$(awk "\$2==\"$module\" {print \$1}" /proc/devices) + +mknod ./${device}0 c $major 0 +mknod ./${device}1 c $major 1 +mknod ./${device}2 c $major 2 +mknod ./${device}3 c $major 3 + +group="mutom" +grep -q '^mutom:' /etc/group || group="adm" + +chgrp $group ./${device}[0-3] +chmod $mode ./${device}[0-3] \ No newline at end of file diff --git a/src/ltk/ltkdebug.c b/src/ltk/ltkdebug.c new file mode 100644 index 0000000..03b5024 --- /dev/null +++ b/src/ltk/ltkdebug.c @@ -0,0 +1,4 @@ + +#include "ltkdebug.h" + + diff --git a/src/ltk/ltkdebug.h b/src/ltk/ltkdebug.h new file mode 100755 index 0000000..fe55a04 --- /dev/null +++ b/src/ltk/ltkdebug.h @@ -0,0 +1,105 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef LTKDEBUG_H +#define LTKDEBUG_H + + +#include "ltkmacros.h" +#include "ltktypes.h" + +//! Provide a string for current function, non-concatenatable +#if defined (__GNUC__) || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 19901L) +# define __func_to_string__ ((const char*) (__func__)) +#else +# define __func_to_string__ ((const char*) ("???")) +#endif + +//! Provide a string for current function in pretty format, non-concatenatable +#if defined (__GNUC__) +# define __pfunc_to_string__ ((const char*) (__PRETTY_FUNCTION__)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 19901L +# define __pfunc_to_string__ ((const char*) (__func__)) +#else +# define __pfunc_to_string__ ((const char*) ("???")) +#endif + + + +//////////////////////////////////////////////////////////////////////////////// +//// Pragma Messages for debug allerts during compilation ///////////////////// +//////////////////////////////////////////////////////////////////////////////// + +#ifdef PRAGMA_MESSAGES +#define DEBUG_DO_PRAGMA(x) _Pragma (#x) +#else +#define DEBUG_DO_PRAGMA(x) ; +#endif + +#define TODO(x) DEBUG_DO_PRAGMA(message ("\n\n [TODO] >> " #x " <<\n")) +#define OPTIMIZE(x) DEBUG_DO_PRAGMA(message ("\n\n [OPTIMIZE] > " #x " <\n")) +#define DUMP(x) DEBUG_DO_PRAGMA(message ("\n\n [DUMP] > " #x " <\n")) + +// ------------------------------------------------------------------------ // + + + +C_BEGIN_DECLS + + +typedef enum +{ + LOG_FLAG_ACTIVE = 1 << 0, + LOG_FLAG_FATAL = 1 << 1, + LOG_LEVEL_ERROR = 1 << 2, + LOG_LEVEL_CRITICAL = 1 << 3, + LOG_LEVEL_WARNING = 1 << 4, + LOG_LEVEL_MESSAGE = 1 << 5, + LOG_LEVEL_INFO = 1 << 6, + LOG_LEVEL_DEBUG = 1 << 7, + LOG_LEVEL_ANNOING = 1 << 8, + LOG_LEVEL_PARANOID = 1 << 9 +} LogLevelFlags; + + + + +void debug_log( + void *handler, + LogLevelFlags flags, + const char *function_name, + const char *message, + ...); + + + +C_END_DECLS + + + + +#endif // LTKDEBUG_H diff --git a/src/ltk/ltkmacros.h b/src/ltk/ltkmacros.h new file mode 100644 index 0000000..c5e921d --- /dev/null +++ b/src/ltk/ltkmacros.h @@ -0,0 +1,61 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +/* + * File: macros.h + * Author: andrea + * + * Created on May 23, 2012, 9:01 AM + */ + +#ifndef LTK_MACROS_H +#define LTK_MACROS_H + +// C code in headers, while including them from C++ +#ifdef __cplusplus + +# define C_BEGIN_DECLS extern "C" { +# define C_END_DECLS } + +#define BEGIN_NAMESPACE(name) namespace name { +#define END_NAMESPACE } + +#else + +# define C_BEGIN_DECLS +# define C_END_DECLS + +#define BEGIN_NAMESPACE(name) +#define END_NAMESPACE + +#endif + + + + +#endif /* MACROS_H */ + diff --git a/src/ltk/ltktypes.h b/src/ltk/ltktypes.h new file mode 100644 index 0000000..c243841 --- /dev/null +++ b/src/ltk/ltktypes.h @@ -0,0 +1,127 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef LTK_TYPE_H +#define LTK_TYPE_H + +#include +#include + +//#include "templates.h" +#include "ltkmacros.h" + +#ifdef __cplusplus +# define LTK_TYPECAST(T, Type) static_cast< T >(Type) +#else +# define LTK_TYPECAST(T, Type) ((T)(Type)) +#endif + + +BEGIN_NAMESPACE(ltk) + +C_BEGIN_DECLS + +/* ////////////////////////////////////////////////////////////////////////// */ +/* //////////////////////////// TYPE DEFINITIONS ////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + + +typedef void * Pointer_t; +typedef id_t Id_t; +typedef size_t Size_t; + +#ifndef LTK_DOUBLE_PRECISION +typedef float Real_t; +#else +typedef double Real_t; +#endif + +#define LTK_SIGNED_CHAR_MIN LTK_TYPECAST(signed char, 0x80) +#define LTK_SIGNED_CHAR_MAX LTK_TYPECAST(signed char, 0x7f) + +#define LTK_UNSIGNED_CHAR_MIN LTK_TYPECAST(unsigned char, 0u) +#define LTK_UNSIGNED_CHAR_MAX LTK_TYPECAST(unsigned char, 0xffu) + +#define LTK_SHORT_MIN LTK_TYPECAST(short, 0x8000) +#define LTK_SHORT_MAX LTK_TYPECAST(short, 0x7fff) + +#define LTK_UNSIGNED_SHORT_MIN LTK_TYPECAST(unsigned short, 0u) +#define LTK_UNSIGNED_SHORT_MAX LTK_TYPECAST(unsigned short, 0xffffu) + +#define LTK_INT_MIN LTK_TYPECAST(int, ~(~0u >> 1)) +#define LTK_INT_MAX LTK_TYPECAST(int, ~0u >> 1) + +#define LTK_INT8_MIN LTK_TYPECAST(int8_t, 0x80) +#define LTK_INT8_MAX LTK_TYPECAST(int8_t, 0x7f) + +#define LTK_INT16_MIN LTK_TYPECAST(int16_t, 0x8000u) +#define LTK_INT16_MAX LTK_TYPECAST(int16_t, 0x7fffu) + +#define LTK_UNSIGNED_INT16_MIN LTK_TYPECAST(int16_t, 0u) +#define LTK_UNSIGNED_INT16_MAX LTK_TYPECAST(unsigned int16_t, 0xffffu) + +#define LTK_INT32_MIN LTK_TYPECAST(int32_t, 0x80000000u) +#define LTK_INT32_MAX LTK_TYPECAST(int32_t, 0x7fffffffu) + +#define LTK_UNSIGNED_INT32_MIN LTK_TYPECAST(unsigned int32_t, 0u) +#define LTK_UNSIGNED_INT32_MAX LTK_TYPECAST(unsigned int32_t, 0xffffffffu) + +#define LTK_INT64_MIN LTK_TYPECAST(int64_t, 0x8000000000000000u) +#define LTK_INT64_MAX LTK_TYPECAST(int64_t, 0x7fffffffffffffffu) + +#define LTK_UNSIGNED_INT8_MIN LTK_TYPECAST(int8_t, 0u) +#define LTK_UNSIGNED_INT8_MAX LTK_TYPECAST(int8_t, 0xffu) + +#define LTK_UNSIGNED_INT64_MIN LTK_TYPECAST(unsigned int64_t, 0u) +#define LTK_UNSIGNED_INT64_MAX LTK_TYPECAST(unsigned int64_t, \ + 0xffffffffffffffffu) + +#define LTK_UNSIGNED_INT_MIN LTK_TYPECAST(unsigned int, 0) +#define LTK_UNSIGNED_INT_MAX LTK_TYPECAST(unsigned int, ~0u) + +#define LTK_LONG_MIN LTK_TYPECAST(long, ~(~0ul >> 1)) +#define LTK_LONG_MAX LTK_TYPECAST(long, ~0ul >> 1) + +#define LTK_UNSIGNED_LONG_MIN LTK_TYPECAST(unsigned long, 0ul) +#define LTK_UNSIGNED_LONG_MAX LTK_TYPECAST(unsigned long, ~0ul) + +#define LTK_FLOAT_MIN LTK_TYPECAST(float, -1.0e+38f) +#define LTK_FLOAT_MAX LTK_TYPECAST(float, 1.0e+38f) + +#define LTK_DOUBLE_MIN LTK_TYPECAST(double, -1.0e+299) +#define LTK_DOUBLE_MAX LTK_TYPECAST(double, 1.0e+299) + + + + + +C_END_DECLS + +END_NAMESPACE + + +#endif //TYPE_H diff --git a/src/ltk/main.C b/src/ltk/main.C new file mode 100644 index 0000000..fb90774 --- /dev/null +++ b/src/ltk/main.C @@ -0,0 +1,35 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +#include "Object.h" + + +int main() +{ + return 0; +} diff --git a/src/ltk/main.c b/src/ltk/main.c new file mode 100644 index 0000000..12c29cd --- /dev/null +++ b/src/ltk/main.c @@ -0,0 +1,72 @@ + +#include "DenseMatrix.h" +#include "Vector.h" +#include "Object.h" + +#include "vectormath/simd/instrset.h" + +/* LTK_VECTOR_DECLARE(int,LtkInt4,4) */ + +/* LTK_MATRIX_DECLARE(int,LtkInt2x2,2,2) */ +/* LTK_MATRIX_DECLARE(int,LtkInt4x1,4,1) */ +/* LTK_MATRIX_DECLARE(int,LtkInt4x4,4,4) */ + +int test(int a) { return 0; } + + +int main(void) +{ + + // testing dense matrix // + /****************************************************/ + /* LtkInt2x2 a; */ + /* LtkInt4x1 b; */ + /* LtkInt4x4 c; */ + /* LtkInt4 v, w; */ + /* */ + /* v = LtkInt4_ltk_vector_new (); */ + /* w = LtkInt4_ltk_vector_new (); */ + /* */ + /* int i; */ + /* for (i = 0; i < LtkInt4_ltk_vector_size (); ++i) */ + /* { */ + /* LtkInt4_ltk_vector_set (v, i, 0); */ + /* LtkInt4_ltk_vector_set (w, i, 3); */ + /* } */ + /* */ + /* printf ("v = "); */ + /* for (i = 0; i < 4; ++i) */ + /* printf ("%d ", LtkInt4_ltk_vector_get (v, i)); */ + /* printf ("\n"); */ + /* */ + /* printf ("w = "); */ + /* for (i = 0; i < 4; ++i) */ + /* printf ("%d ", LtkInt4_ltk_vector_get (w, i)); */ + /* printf ("\n"); */ + /****************************************************/ + + // testing intrinsics // + printf("INSTRUCTION SET -> %d\n",INSTRSET); + __m128 aligned_float = _mm_setzero_ps(); + float *p = &aligned_float; + printf("%f,%f,%f,%f\n",p[0],p[1],p[2],p[3]); + + // adder // + __m128 a_1,a_2; + a_1 = _mm_set_ps(3,3,3,3); + a_2 = _mm_set_ps(1,2,3,4); + + + aligned_float = _mm_add_ps(a_1,a_2); + p = &aligned_float; printf("%f,%f,%f,%f\n",p[0],p[1],p[2],p[3]); + + + + // testing Objects // + //LTK_MATRIX_DECLARE(TypeName, type, r, c); + // Object *ob = New(ObjectClass); + // int el = ObjectClass->GetElement(ob); + + + return 0; +} diff --git a/src/ltk/templates.c b/src/ltk/templates.c new file mode 100644 index 0000000..a154d1a --- /dev/null +++ b/src/ltk/templates.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include "templates.h" + + +LtkList ltk_list_new() +{ + LtkList list = malloc(sizeof(struct _template_list)); + list->size = 0; + list->start = NULL; + list->end = NULL; + return list; +} + +void ltk_list_nodepush(LtkList list,LtkListNode node) +{ + if(list == NULL) return; + node->next = list->start; + list->start = node; + if(list->end == NULL) list->end = node; + list->size++; +} + +LtkListNode ltk_list_get_start(LtkList list) +{ + if (list==NULL || list->start==NULL) return NULL; + return list->start; +} + +LtkListNode ltk_list_get_end(LtkList list) +{ + if (list==NULL || list->end==NULL) return NULL; + return list->end; +} + +void ltk_list_remove(LtkList list,LtkListNode node) +{ + if (list == NULL || list->start==NULL) return; + struct _template_list_node *node_tofree,*prev; + node_tofree=list->start; + while (node_tofree != node) { + if(node_tofree->next == NULL) return; + prev = node_tofree; + node_tofree = node_tofree->next; + } + if(node_tofree == list->start) list->start = node_tofree->next; + else prev->next = node_tofree->next; + free(node_tofree); +} + +void ltk_list_pop_start(LtkList list) +{ + if (list==NULL || list->start==NULL) return; + struct _template_list_node *nodetofree; + nodetofree=list->start; + list->start = list->start->next; + free(nodetofree); +} + +void ltk_list_pop_end(LtkList list) +{ + if (list==NULL || list->end==NULL) return; + struct _template_list_node *iter; + iter=list->start; + if(iter==list->end) { + free(iter); + list->start = list->end = NULL; + } + else { + while(iter->next!=list->end) iter=iter->next; + free(iter->next); + iter->next = NULL; + list->end = iter; + } + list->size--; +} + +int ltk_list_get_size(LtkList list) +{ + if(list==NULL) return 0; + return list->size; +} + + +LtkListIterator ltk_list_iterator_new(LtkList list) +{ + if(list==NULL || list->start == NULL) return NULL; + return (LtkListIterator)list->start; +} + + diff --git a/src/ltk/templates.h b/src/ltk/templates.h new file mode 100644 index 0000000..00abd01 --- /dev/null +++ b/src/ltk/templates.h @@ -0,0 +1,303 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +/* + * + * Copyright (C) 2012 Andrea Rigoni Garola + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifndef TEMPLATES_H +#define TEMPLATES_H + +#include // for std allocator // +#include // for memcpy // +#include + +#include "ltkmacros.h" // default environment // +#include "container.h" // TODO !!! // + +#include + + + + + +/* ////////////////////////////////////////////////////////////////////////// */ +/* //////////////////////////// ALLOC FUNCTIONS ///////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +C_BEGIN_DECLS + +//inline ltkPointer ltk_malloc(unsigned int size) { return malloc(size); } +//inline void ltk_free (ltkPointer ptr) { free(ptr); } + +#define LTK_SIMPLE_ALLOC_FUNC(Type, ltkType, Class_name, size) \ + inline ltkType ltkType##_##Class_name##_new() \ + { \ + return LTK_TYPECAST(ltkType, malloc(sizeof(Type) * size)); \ + } \ + inline void ltkType##_##Class_name##_delete(ltkType t) \ + { free(t); } \ + inline void ltkType##_##Class_name##_copy(ltkType dst, const ltkType src) \ + { memcpy((ltkPointer)dst, (ltkPointer)src, sizeof(Type) * size ); } + +C_END_DECLS + + + + + +/* ////////////////////////////////////////////////////////////////////////// */ +/* //////////////////////////// ABSTRACT C BUFFER /////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +C_BEGIN_DECLS + +#define LTK_ABSTRACT_BUFFER_DECLARE_FUNC(Type,ltkType,Class_name,size) \ + inline int ltkType##_##Class_name##_size() { return size; } \ + inline Type ltkType##_##Class_name##_get(ltkType v, unsigned int c) \ + { assert(c < size); return *((ltkType)m + c); } \ + inline void ltkType##_##Class_name##_set(ltkType v, Type t, unsigned int c) \ + { assert(c < size); *((ltkType)m + c) = t; } + +// FINIRE !!! // + +C_END_DECLS + +#ifdef __cplusplus + +template class ltkAbstractBuffer +{ + typedef ltkAbstractBuffer ThisClass; +protected: + typedef T ContentType; + virtual T* getBuffer() = 0; + virtual const T* getBuffer() const = 0; + + struct CommaInit + { + inline explicit CommaInit(ltkAbstractBuffer *container,float s) + : container(container) { + this->index = 0; + this->container->getBuffer()[0] = s; + } + inline CommaInit & operator, (float s) { + this->index++; + assert(index < size); + this->container->getBuffer()[this->index] = s; + return *this; + } + ltkAbstractBuffer *container; + unsigned int index; + }; + +public: + inline CommaInit operator =(T scalar) { + return CommaInit(this, scalar); + } + inline CommaInit operator <<(T scalar) { + return CommaInit(this, scalar); + } + + inline T& at(const unsigned int i) { + return *(this->getBuffer() + i); + } + + inline T & operator[](unsigned int i) { + return *(this->getBuffer() + i); + } + inline const T & operator[](unsigned int i) const { + return *(this->getBuffer() + i); + } + inline T & operator()(unsigned int i) { + return *(this->getBuffer() + i); + } + inline const T & operator()(unsigned int i) const { + return *(this->getBuffer() + i); + } + + +}; + +#endif // __cplusplus + + +/* ////////////////////////////////////////////////////////////////////////// */ +/* //////////////////////////// ARRAY /////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +// COMING SOON // + + + + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/// DO NOT USE ANYTHING AFTER THIS LINE ... EXPERIMENTAL ////////////////// + + + + + + + + + +/* ////////////////////////////////////////////////////////////////////////// */ +/* //////////////////////////// CIRCULAR BUFFER ///////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* CIRCULAR BUFFER */ + +struct _ltk_template_buffer { + void *pos; + void *head; +}; + +#define LTK_BUFFER_DECLARE(Type, Type_name, size, overlap) \ +typedef struct _ltk_template_buffer *Type_name; \ +inline Type_name Type_name##_ltk_buffer_new() \ +{ Type_name out = (Type_name)ltk_malloc \ + (sizeof(Type) * (size + overlap) + 2); \ + out->head = (void *)out + 2 + overlap * sizeof(Type); \ + out->pos = out->head; \ +return out; } \ +inline void Type_name##_ltk_buffer_free(Type_name buffer) { ltk_free(buffer); }\ + + + +// TO BE CONTINUED.... // + + + + + + + + +///// LtkPTree //////// + +struct _LtkPTreeNode +{ + struct _LtkPTreeNode *parent; +}; +typedef struct _LtkPTreeNode *LtkPtree; + + + + + + + + + + + + +/* + one way list template usable as FIFO or LIFO by macros + Element must be a pointer to a real allocated object. +*/ +// this acts as dummy node, never really instanciated // +struct _template_list_node { + struct _template_list_node *next; +}; +typedef struct _template_list_node *LtkListNode; +#define LTK_LIST_HEADER LtkListNode ltk_list_node_next; + +struct _template_list { + int size; + struct _template_list_node *start; + struct _template_list_node *end; +}; + +typedef struct _template_list *LtkList; +typedef struct _template_list_node *LtkListIterator; + +LtkList ltk_list_new(); +void ltk_list_nodepush(LtkList list,LtkListNode node); +LtkListNode ltk_list_get_start(LtkList list); +LtkListNode ltk_list_get_end(LtkList list); +void ltk_list_remove(LtkList list,LtkListNode node); +void ltk_list_pop_start(LtkList list); +void ltk_list_pop_end(LtkList list); + + +#define LTK_LIST_DECLARE(Type,Type_name) \ + static LtkList (* Type_name##_list_new)(void) = ltk_list_new;\ + void (* Type_name##_list_nodepush)(LtkList list, Type *node) = (void (*)(LtkList, Type *))ltk_list_nodepush; \ + Type * (* Type_name##_list_get_start)(LtkList list) = (Type *(*)(LtkList))ltk_list_get_start; \ + Type * (* Type_name##_list_get_end)(LtkList list) = (Type *(*)(LtkList))ltk_list_get_end; \ + void (* Type_name##_list_remove)(LtkList list, Type *node) = (void (*)(LtkList, Type *))ltk_list_remove; \ + void (* Type_name##_list_pop_start)(LtkList list) = (void (*)(LtkList))ltk_list_pop_start; \ + void (* Type_name##_list_pop_end)(LtkList list) = (void (*)(LtkList))ltk_list_pop_end; + +#define LTK_LIST_DECLARE_KEYACCESS(Type,Type_name,KeyType,key_member_name,key_function) \ + Type * Type_name##_list_key_lookup(LtkList list, KeyType key) { \ + LtkListIterator iter = ltk_list_iterator_new(list); \ + while(iter) { \ + if (key_function( ((Type *)iter)->key_member_name, key )) \ + return (Type *)iter; \ + iter = iter->next; } \ + return NULL; } \ + \ + void Type_name##_list_key_remove(LtkList list, KeyType key) { \ + LtkListNode node = (LtkListNode)Type_name##_list_key_lookup(list,key); \ + if(node) ltk_list_remove(list,node); } \ + + +LtkListIterator ltk_list_iterator_new(LtkList list); + +#endif // TEMPLATES_H diff --git a/src/ltk/test_comma.h b/src/ltk/test_comma.h new file mode 100644 index 0000000..2d69036 --- /dev/null +++ b/src/ltk/test_comma.h @@ -0,0 +1,117 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +/* + * File: test_comma.h + * Author: andrea + * + * Created on May 24, 2012, 4:47 PM + */ + +#ifndef TEST_COMMA_H +#define TEST_COMMA_H + +#include + +struct Vector3 +{ + union + { + struct { float x, y, z; }; + float data[3]; + }; + + struct CommaAssign; + + CommaAssign operator=(float _x) + { + x = _x; + return CommaAssign(this,1); + } + + struct CommaAssign + { + Vector3 *vec3; + int index; + + explicit CommaAssign(Vector3 *vec3, int index) : vec3(vec3) { + this->index = index; + } + CommaAssign operator, (float f) { + vec3->data[index] = f; + return CommaAssign(vec3, index + 1); + } + + }; + +}; + + + +struct Container +{ + union + { + struct { float x, y, z; }; + float data[3]; + }; + + inline float *getBuffer() { + return this->data; + } + + template class CommaAssign + { + private: + T *container; + int index; + + public: + inline explicit CommaAssign(T *container, float s) : container(container) { + this->index = 0; + this->container->getBuffer()[0] = s; + } + + inline CommaAssign& operator, (float s) { + this->index++; + assert(index < size); + this->container->getBuffer()[this->index] = s; + return *this; + } + }; + + CommaAssign operator=(float s) { + return CommaAssign (this, s); + } + +}; + + + + +#endif /* TEST_COMMA_H */ + diff --git a/src/ltk/testing/Makefile.am b/src/ltk/testing/Makefile.am new file mode 100644 index 0000000..1964340 --- /dev/null +++ b/src/ltk/testing/Makefile.am @@ -0,0 +1,37 @@ + +include $(top_srcdir)/Common.am + +#AM_DEFAULT_SOURCE_EXT = .cpp + + + +TESTS = LtkDebugTest \ + LtkFunctionToStringTest + +LDADD = ../../../libmutom-0.1.la +check_PROGRAMS = $(TESTS) + + +#################################################### +# Hybrid c/c++ Ltk Specific tests # +#################################################### + +check_PROGRAMS += Vector-test +Vector_test_SOURCES = Vector.c +TESTS += Vector-test + +check_PROGRAMS += Vector-test-cc +Vector_test_cc_SOURCES = Vector-cc.cpp +TESTS += Vector-test-cc + +check_PROGRAMS += Object-test +Object_test_SOURCES = Object.c +TESTS += Object-test + +check_PROGRAMS += Object-test-cc +Object_test_cc_SOURCES = Object-cc.cpp +TESTS += Object-test-cc + +#################################################### + +AM_COLOR_TESTS = always diff --git a/src/ltk/testing/Object-cc.cpp b/src/ltk/testing/Object-cc.cpp new file mode 100644 index 0000000..011af7f --- /dev/null +++ b/src/ltk/testing/Object-cc.cpp @@ -0,0 +1,40 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "testing-prototype.h" +#include "../Object.h" + +using namespace ltk; + +int main() { + BEGIN_TESTING(Object - cc); + + Object ob; + TEST1( ob.GetElement() == 5552368 ); + + END_TESTING; +} diff --git a/src/ltk/testing/Object.c b/src/ltk/testing/Object.c new file mode 100644 index 0000000..9627bb9 --- /dev/null +++ b/src/ltk/testing/Object.c @@ -0,0 +1,11 @@ +#include "testing-prototype.h" +#include "../Object.h" + + +int main() { + BEGIN_TESTING(Object); + + struct _Object *ob = Object_new(ObjectClass); + + END_TESTING; +} diff --git a/src/ltk/testing/Vector-cc.cpp b/src/ltk/testing/Vector-cc.cpp new file mode 100644 index 0000000..d0d75fc --- /dev/null +++ b/src/ltk/testing/Vector-cc.cpp @@ -0,0 +1,79 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include "testing-prototype.h" +#include "../Vector.h" + +using namespace ltk; + +int main() { + BEGIN_TESTING(Vector - cc); + + typedef ltkVector ltkInt4; + + ltkInt4 v, w; + v = 1, 2, 3, 4; + w = v; + + printf("v -> %d,%d,%d,%d\n", v[0], *(v.getBuffer() + 1), v.at(2), v(3)); + + + // test assign operator + TEST1(v == w); + TEST0(v != w); + + // test accessors + TEST1(v[0] == 1); + TEST1(*(v.getBuffer() + 1) == 2); + TEST1(v.at(2) == 3); + TEST1(v(3) == 4); + + // setter + w << 1, 4, 9, 16; + TEST1(w[0] == 1); + TEST1(w[1] == 4); + TEST1(w[2] == 9); + TEST1(w[3] == 16); + + // math operators + v *= v; + w = 1, 4, 9, 16; + TEST1(v == w); + v /= v; + w = 1, 1, 1, 1; + TEST1(v == w); + v += v; + w = 2, 2, 2, 2; + TEST1(v == w); + + v << 1, 1, -1, 1; + w << -1, 1, 1, 1; + TEST0(v * w); + TEST0(v / w); + + END_TESTING; +} diff --git a/src/ltk/testing/Vector.c b/src/ltk/testing/Vector.c new file mode 100644 index 0000000..f7d1ab7 --- /dev/null +++ b/src/ltk/testing/Vector.c @@ -0,0 +1,14 @@ +#include +#include "testing-prototype.h" +#include "../Vector.h" + + +LTK_VECTOR_DECLARE (float, uFloat4, 4) + +int main() +{ + BEGIN_TESTING (Vector); + uFloat4 f = uFloat4_ltk_vector_new (); + + END_TESTING; +} diff --git a/src/ltk/testing/testing-prototype.h b/src/ltk/testing/testing-prototype.h new file mode 100644 index 0000000..39f4e6c --- /dev/null +++ b/src/ltk/testing/testing-prototype.h @@ -0,0 +1,37 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include + +#define BEGIN_TESTING(name) \ +static int _fail = 0; \ +printf("..:: Testing " #name " ::..\n"); + +#define TEST1(val) _fail += (val)==0 +#define TEST0(val) _fail += (val)!=0 +#define END_TESTING return _fail; + diff --git a/src/utils/copyrights/cr_update.py b/src/utils/copyrights/cr_update.py new file mode 100644 index 0000000..8fe6342 --- /dev/null +++ b/src/utils/copyrights/cr_update.py @@ -0,0 +1,45 @@ +# updates the copyright information for all .cs files +# usage: call recursive_traversal, with the following parameters +# parent directory, old copyright text content, new copyright text content + +import os + +excludedir = ["..\\Lib"] + +def update_source(filename, oldcopyright, copyright): + utfstr = chr(0xef)+chr(0xbb)+chr(0xbf) + fdata = file(filename,"r+").read() + isUTF = False + if (fdata.startswith(utfstr)): + isUTF = True + fdata = fdata[3:] + if (oldcopyright != None): + if (fdata.startswith(oldcopyright)): + fdata = fdata[len(oldcopyright):] + if not (fdata.startswith(copyright)): + print "updating "+filename + fdata = copyright + fdata + if (isUTF): + file(filename,"w").write(utfstr+fdata) + else: + file(filename,"w").write(fdata) + +def recursive_traversal(dir, oldcopyright, copyright): + global excludedir + fns = os.listdir(dir) + print "listing "+dir + for fn in fns: + fullfn = os.path.join(dir,fn) + if (fullfn in excludedir): + continue + if (os.path.isdir(fullfn)): + recursive_traversal(fullfn, oldcopyright, copyright) + else: + if ( fullfn.endswith(".cpp") or fullfn.endswith(".h") or fullfn.endswith(".hpp") or fullfn.endswith(".C") or fullfn.endswith(".cxx") ): + update_source(fullfn, oldcopyright, copyright) + + +oldcright = file("oldcr.txt","r+").read() +cright = file("newcr.txt","r+").read() +recursive_traversal("../../", oldcright, cright) +exit() diff --git a/src/utils/copyrights/newcr.txt b/src/utils/copyrights/newcr.txt new file mode 100644 index 0000000..3ed7526 --- /dev/null +++ b/src/utils/copyrights/newcr.txt @@ -0,0 +1,27 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + diff --git a/src/utils/copyrights/oldcr.txt b/src/utils/copyrights/oldcr.txt new file mode 100644 index 0000000..f781efb --- /dev/null +++ b/src/utils/copyrights/oldcr.txt @@ -0,0 +1,24 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ diff --git a/src/utils/make_recipe/CMakeLists.txt b/src/utils/make_recipe/CMakeLists.txt new file mode 100644 index 0000000..66cc8d9 --- /dev/null +++ b/src/utils/make_recipe/CMakeLists.txt @@ -0,0 +1,37 @@ +set(HEADERS +) + +SET(SOURCES +) + + +## Build target tar file ## +set(CMAKE_TAR_FILE "recipe.tar.gz") +add_custom_command(OUTPUT recipe_tar_data.o + COMMAND tar -zcvf ${CMAKE_TAR_FILE} -C "${CMAKE_CURRENT_SOURCE_DIR}/src" CMakeLists.txt main.cpp -C ${PROJECT_SOURCE_DIR} CMakeConfig.in.h + ## -C ${PROJECT_SOURCE_DIR} CMake + COMMAND objcopy --input binary --output elf64-x86-64 --binary-architecture i386 ${CMAKE_TAR_FILE} ${CMAKE_CURRENT_BINARY_DIR}/recipe_tar_data.o +) + +add_library(recipe_tar_data STATIC recipe_tar_data.o) +set_source_files_properties(recipe_tar_data.o PROPERTIES EXTERNAL_OBJECT true GENERATED true) +set_target_properties(recipe_tar_data PROPERTIES LINKER_LANGUAGE C) + + +set(CMAKE_TAR_FILE "cmake.tar.gz") +add_custom_command(OUTPUT cmake_tar_data.o + COMMAND tar -zcvf ${CMAKE_TAR_FILE} -C ${PROJECT_SOURCE_DIR} CMake "--exclude=CMake/.svn" + COMMAND objcopy --input binary --output elf64-x86-64 --binary-architecture i386 ${CMAKE_TAR_FILE} ${CMAKE_CURRENT_BINARY_DIR}/cmake_tar_data.o +) + +add_library(cmake_tar_data STATIC cmake_tar_data.o) +set_source_files_properties(cmake_tar_data.o PROPERTIES EXTERNAL_OBJECT true GENERATED true) +set_target_properties(cmake_tar_data PROPERTIES LINKER_LANGUAGE C) + + + +uLib_add_target(uLib_config main.cpp) +target_link_libraries(uLib_config cmake_tar_data) +target_link_libraries(uLib_config recipe_tar_data) +target_link_libraries(uLib_config ${PACKAGE_LIBPREFIX}Core) + diff --git a/src/utils/make_recipe/main.cpp b/src/utils/make_recipe/main.cpp new file mode 100644 index 0000000..d4734ff --- /dev/null +++ b/src/utils/make_recipe/main.cpp @@ -0,0 +1,137 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include +#include +#include +#include +#include + +#include "Core/Options.h" + + +using namespace uLib; + +extern "C" { +extern char _binary_recipe_tar_gz_start; +extern char _binary_recipe_tar_gz_end; +extern char _binary_cmake_tar_gz_start; +extern char _binary_cmake_tar_gz_end; +} + + +namespace { +static struct Parameters : Options +{ + std::string project; + Parameters(const char *hello = "Program options") : Options(hello) { + add_options() + ("help,h", "printout help") + // GENERAL // + ("project,p", &project, std::string(), "name of project") + ("cmake,k", "cmake recipe project") + ("cmake-modules,K", "only builds cmake modules directory") + ("libs", "get mutom linker flags") + ("cflags", "get compiler flags") + ; + } +} p; +} // namespace + + +static std::string system_pipe(std::string cmd) { + FILE *pipe = popen(cmd.c_str(),"r"); + if(pipe) { + std::stringstream ss; + int c = fgetc (pipe); + while (c != EOF) { + if(c != '\n') ss << (char)c; + c = fgetc (pipe); + } + return ss.str(); + } + else return std::string(""); +} + + + + + +int main(int argc, char *argv[]) +{ + p.parse_command_line(argc,argv); + + if(p.project != "") { + char dir[300]; + sprintf(dir,"mkdir %s",p.project.c_str()); + system(dir); + chdir(p.project.c_str()); + } + + if(p.count("cmake") || p.count("cmake-modules")) { + std::ofstream file; + file.open("_cmake.tar.gz", std::ios::out | std::ios::binary ); + char* ptr = &_binary_cmake_tar_gz_start; + while ( ptr != &_binary_cmake_tar_gz_end ) + file << *ptr++; + file.close(); + + std::cout << "Deploing CMake files .... \n"; + system("tar -zxvf _cmake.tar.gz"); + system("rm _cmake.tar.gz"); + std::cout << "done ... \n"; + } + + if(p.count("cmake")) { + std::ofstream file; + file.open("_recipe.tar.gz", std::ios::out | std::ios::binary ); + char* ptr = &_binary_recipe_tar_gz_start; + while ( ptr != &_binary_recipe_tar_gz_end ) + file << *ptr++; + file.close(); + + std::cout << "Deploing recipe files .... \n"; + system("tar -zxvf _recipe.tar.gz"); + system("rm _recipe.tar.gz"); + std::cout << "done ... \n"; + } + + if(p.count("cflags")) { + std::cout + << system_pipe("cmake --find-package -DCMAKE_PREFIX_PATH=/usr/local/lib/cmake/mutom-0.2 -DNAME=uLib -DLANGUAGE=C -DCOMPILER_ID=GNU -DMODE=COMPILE") + << system_pipe("cmake --find-package -DCMAKE_PREFIX_PATH=/usr/local/lib/cmake/mutom-0.2 -DNAME=IB -DLANGUAGE=C -DCOMPILER_ID=GNU -DMODE=COMPILE"); + } + + if(p.count("libs")) { + std::cout + << system_pipe("cmake --find-package -DCMAKE_PREFIX_PATH=/usr/local/lib/cmake/mutom-0.2 -DNAME=uLib -DLANGUAGE=C -DCOMPILER_ID=GNU -DMODE=LINK") + << system_pipe("cmake --find-package -DCMAKE_PREFIX_PATH=/usr/local/lib/cmake/mutom-0.2 -DNAME=IB -DLANGUAGE=C -DCOMPILER_ID=GNU -DMODE=LINK"); + } + + return 0; +} + diff --git a/src/utils/make_recipe/src/CMake b/src/utils/make_recipe/src/CMake new file mode 120000 index 0000000..5b0f7e9 --- /dev/null +++ b/src/utils/make_recipe/src/CMake @@ -0,0 +1 @@ +../../../../CMake \ No newline at end of file diff --git a/src/utils/make_recipe/src/CMakeLists.txt b/src/utils/make_recipe/src/CMakeLists.txt new file mode 100644 index 0000000..05e35c0 --- /dev/null +++ b/src/utils/make_recipe/src/CMakeLists.txt @@ -0,0 +1,104 @@ +################################################################################ +################################################################################ +################################################################################ + +cmake_minimum_required(VERSION 2.6) +project(hello_world) +set(SOURCES + # put your sources here + main.cpp +) + +set(DICTIONARY_HEADERS + # put dictionary headers here +) + +################################################################################ +################################################################################ +################################################################################ +################################################################################ +################################################################################ + + +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMake") +include(uLibDebugMacro) +include(uLibCommon) +include(uLibFindDependencies) +include(uLibConfigHeader) +include(uLibGenerateRMake) + + +## MUDULE FIND PACKAGE ------------------------------------------------------ ## +#find_package(uLib REQUIRED) # not working at the moment + +## CONFIG FIND PACKAGE ------------------------------------------------------ ## +#set(CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}/lib/cmake") +unset(ULIB_CONFIG) +find_package(ULIB 0.2 CONFIG + NAMES uLib + PATH_SUFFIXES mutom-0.2 +) +if(ULIB_CONFIG) + set(ULIB_FOUND true) +endif() + +unset(IB_CONFIG) +find_package(IB 0.2 CONFIG + PATH_SUFFIXES mutom-0.2 +) +if(IB_CONFIG) + set(IB_FOUND true) +endif() + + +## PROJECT EXECUTABLE ------------------------------------------------------- ## +add_executable(${PROJECT_NAME} ${SOURCES}) + +if(ULIB_FOUND) + include_directories(${ULIB_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} + ############################################################################ + ## ULIB MODULES ## + mutomCore + mutomMath + mutomDetectors + # mutomVtk + ############################################################################ + + ############################################################################ + # MANUAL INLCLUDE EXTERNAL DEPENDENCIES + # ${Boost_SERIALIZATION_LIBRARY} + # ${Boost_SIGNALS_LIBRARY} + # ${Boost_PROGRAM_OPTIONS_LIBRARY} + # ${Geant4_LIBRARIES} + # ${ROOT_LIBRARIES} + # ${VTK_LIBRARIES} # all VTK libs + ############################################################################ +) +endif(ULIB_FOUND) + +if(IB_FOUND) + include_directories(${IB_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} mutomIB ) +endif() + + +## ROOT DICTIONARY COMPILE -------------------------------------------------- ## +if(ROOT_FOUND AND DICTIONARY_HEADERS) +include(FindROOTv6) +message("----------- Building Root Dictionary ----------") +debug(DICTIONARY_HEADERS) +debug(ROOT_CINT_EXECUTABLE) +add_library(dictionary STATIC RootDict.cxx) +add_custom_command(OUTPUT RootDict.cxx RootDict.h + COMMAND ${ROOT_CINT_EXECUTABLE} -f RootDict.cxx -c -p ${DICTIONARY_HEADERS} Linkdef.h +) +#root_generate_dictionary(RootDict ${DICTIONARY_HEADERS} LINKDEF Linkdef.h) +set_source_files_properties(RootDict.cxx PROPERTIES GENERATED TRUE) +set_source_files_properties(RootDict.h PROPERTIES GENERATED TRUE) +target_link_libraries(${PROJECT_NAME} dictionary) +endif(ROOT_FOUND AND DICTIONARY_HEADERS) + + + + diff --git a/src/utils/make_recipe/src/main.cpp b/src/utils/make_recipe/src/main.cpp new file mode 100644 index 0000000..40c09ba --- /dev/null +++ b/src/utils/make_recipe/src/main.cpp @@ -0,0 +1,36 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#include +#include + + +int main(int argc, char **argv) +{ + std::cout << "hello uLib user\n"; + return 0; +} diff --git a/src/utils/moc/Makefile b/src/utils/moc/Makefile new file mode 100644 index 0000000..d42bd6d --- /dev/null +++ b/src/utils/moc/Makefile @@ -0,0 +1,24 @@ + + +# Makefile example -- scanner and parser. +# +CXX = g++ -D_DEBUG +LEX = flex +YACC = bison -y -t +YFLAGS = -d +objects = parse.o scan.o + +moc: $(objects) + $(CXX) -o $@ $(objects) -lfl + +parse.o: parse.y + +# parse.h: parse.c +# mv -f y.tab.h parse.h + +scan.o: scan.l + + +clean: + rm -f *.o parse.tab.c parse.tab.h + diff --git a/src/utils/moc/moc_actions.h b/src/utils/moc/moc_actions.h new file mode 100644 index 0000000..db6e97e --- /dev/null +++ b/src/utils/moc/moc_actions.h @@ -0,0 +1,92 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + +#ifndef MOC_ACTION_H +#define MOC_ACTION_H + +#include +#include +#include +#include + +#ifndef NDEBUG +#define DEBUG( ... ) { printf(" /*["); printf( __VA_ARGS__ ); printf("]*/ "); } +#else +#define DEBUG( ... ) ; +#endif + +#define CONCAT( dest , ... ) string_append(dest, __VA_ARGS__, NULL) + +char * string_append(char *first, ... ) { + va_list ap; + va_start (ap, first); /* Initialize the argument list. */ + + char *str_in = first; + char *str = malloc(sizeof(char) * strlen(str_in)); + strcat(str,str_in); + + str_in = va_arg (ap,char *); + while (str_in) { + char *tmp = malloc(sizeof(char) * (strlen(str)+strlen(str_in)) ); + memcpy(tmp,str,strlen(str)); + memcpy(tmp+strlen(str),str_in,strlen(str_in)); + free(str); + str = tmp; + str_in = va_arg (ap,char *); + } + return str; +} + + + + + + +// ACTIONS // + + + +#define SIMPLE_DECLARATION simple_declaration_action + +static int simple_declaration_action(const char *type, const char *ids); + + + + + + +// move to implementation .. // +static int simple_declaration_action(const char *type, const char *ids) { + DEBUG("simple_declaration -> type:\"%s\" decl:\"%s\" ",type,ids); + return 0; +} + + + + + +#endif // MOC_ACTION_H diff --git a/src/utils/moc/parse.y b/src/utils/moc/parse.y new file mode 100644 index 0000000..ba06996 --- /dev/null +++ b/src/utils/moc/parse.y @@ -0,0 +1,1257 @@ +%{ + +#include +#include +#include "moc_actions.h" + +#define EMPTY strdup(""); +#define YYDEBUG 1 +#define YYPRINT(file, type, value) yyprint (file, type, value) + +%} + +// Symbols. // +%union +{ + char *sval; +}; + +%token MOC_PROPERTY MOC_OBJECT_PARAMETERS +%type MOC_monk_seq_opt MOC_monk + + + +%token IDENTIFIER +%token INTEGER FLOATING CHARACTER STRING +%token TYPEDEF_NAME NAMESPACE_NAME CLASS_NAME ENUM_NAME TEMPLATE_NAME + +%token COLONCOLON +%token ELLIPSIS DOTSTAR ADDEQ SUBEQ MULEQ DIVEQ MODEQ +%token XOREQ ANDEQ OREQ SL SR SREQ SLEQ EQ NOTEQ LTEQ GTEQ ANDAND OROR +%token PLUSPLUS MINUSMINUS ARROWSTAR ARROW + + +%token ASM AUTO BOOL BREAK CASE CATCH CHAR CLASS CONST CONST_CAST CONTINUE +%token DEFAULT DELETE DO DOUBLE DYNAMIC_CAST ELSE ENUM EXPLICIT EXPORT EXTERN +%token FALSE FLOAT FOR FRIEND GOTO IF INLINE INT LONG MUTABLE NAMESPACE NEW +%token OPERATOR PRIVATE PROTECTED PUBLIC REGISTER REINTERPRET_CAST RETURN +%token SHORT SIGNED SIZEOF STATIC STATIC_CAST STRUCT SWITCH TEMPLATE THIS +%token THROW TRUE TRY TYPEDEF TYPEID TYPENAME UNION UNSIGNED USING VIRTUAL +%token VOID VOLATILE WCHAR_T WHILE + + + + +%type type_name class_name enum_name typedef_name + +%type simple_type_specifier +%type decl_specifier_seq decl_specifier +%type simple_declaration block_declaration + +%type init_declarator_list init_declarator +%type initializer initializer_clause +%type declarator direct_declarator ptr_operator declarator_id +%type type_specifier type_specifier_seq elaborated_type_specifier class_key nested_name_specifier template_argument_list +%type enum_specifier enumerator_list enumerator_definition enumerator +%type class_or_namespace_name +%type identifier +%type id_expression +%type constant_expression + + +%type declaration_seq_opt +%type TEMPLATE_opt +%type nested_name_specifier_opt +%type expression_list_opt +%type COLONCOLON_opt +%type new_placement_opt +%type new_initializer_opt +%type new_declarator_opt +%type expression_opt +%type statement_seq_opt +%type condition_opt +%type decl_specifier_seq_opt +%type init_declarator_list_opt +%type identifier_opt +%type enumerator_list_opt +%type TYPENAME_opt +%type initializer_opt +%type cv_qualifier_seq_opt +%type exception_specification_opt +%type constant_expression_opt +%type abstract_declarator_opt +%type type_specifier_seq_opt +%type direct_abstract_declarator_opt +%type parameter_declaration_list_opt +%type ELLIPSIS_opt +%type ctor_initializer_opt +%type COMMA_opt +%type member_specification_opt +%type base_clause_opt +%type member_declarator_list_opt +%type SEMICOLON_opt +%type pure_specifier_opt +%type constant_initializer_opt +%type access_specifier_opt +%type VIRTUAL_opt +%type conversion_declarator_opt +%type EXPORT_opt +%type handler_seq_opt +%type assignment_expression_opt +%type type_id_list_opt + + +%error-verbose +//%debug +%% + +MOC_block_seq_opt + : /* empty */ + | MOC_block_seq_opt MOC_uLib_Parameters + | MOC_block_seq_opt MOC_Property + ; + +MOC_Property: + MOC_PROPERTY '(' IDENTIFIER ')' '{' { DEBUG("found property: %s",$3); } + MOC_prop_content_opt + '}' { DEBUG("property ends"); } + ; + +MOC_uLib_Parameters: + MOC_OBJECT_PARAMETERS '(' IDENTIFIER ')' '{' { DEBUG("found parameters: %s",$3); } + MOC_prop_content_opt + '}' { DEBUG("parameters ends"); } + ; + +MOC_prop_content_opt + : + | translation_unit + ; + + +MOC_monk_seq_opt + : { $$ = EMPTY; } + | MOC_monk_seq_opt MOC_monk { $$ = CONCAT($1,$2); } + ; + +MOC_monk + : INT IDENTIFIER ';' { $$ = CONCAT("type:",$1," ","id:",$2," "); } + | CHAR IDENTIFIER ';' { $$ = CONCAT("type:",$1," ","id:",$2," "); } + | decl_specifier_seq_opt decl_specifier_seq_opt ';' { $$ = CONCAT("type:",$1," ","id:",$2," "); } + ; + +/*---------------------------------------------------------------------- + * Lexical elements. + *----------------------------------------------------------------------*/ + +identifier: + IDENTIFIER + ; + +literal: + integer_literal + | character_literal + | floating_literal + | string_literal + | boolean_literal + ; + +integer_literal: + INTEGER + ; + +character_literal: + CHARACTER + ; + +floating_literal: + FLOATING + ; + +string_literal: + STRING + ; + +boolean_literal: + TRUE + | FALSE + ; + +/*---------------------------------------------------------------------- + * Translation unit. + *----------------------------------------------------------------------*/ + +translation_unit: + declaration_seq_opt { DEBUG("t unit"); } + ; + +/*---------------------------------------------------------------------- + * Expressions. + *----------------------------------------------------------------------*/ + +primary_expression: + literal + | THIS + | COLONCOLON identifier + | COLONCOLON operator_function_id + | COLONCOLON qualified_id + | '(' expression ')' + | id_expression + ; + +id_expression: + unqualified_id + | qualified_id + ; + +unqualified_id: + identifier + | operator_function_id + | conversion_function_id + | '~' class_name + | template_id + ; + +qualified_id: + nested_name_specifier TEMPLATE_opt unqualified_id + ; + +nested_name_specifier: + class_or_namespace_name COLONCOLON nested_name_specifier_opt + ; + +class_or_namespace_name: + class_name + | namespace_name + ; + +postfix_expression: + primary_expression + | postfix_expression '[' expression ']' + | postfix_expression '(' expression_list_opt ')' + | simple_type_specifier '(' expression_list_opt ')' + | postfix_expression '.' TEMPLATE_opt COLONCOLON_opt id_expression + | postfix_expression ARROW TEMPLATE_opt COLONCOLON_opt id_expression + | postfix_expression '.' pseudo_destructor_name + | postfix_expression ARROW pseudo_destructor_name + | postfix_expression PLUSPLUS + | postfix_expression MINUSMINUS + | DYNAMIC_CAST '<' type_id '>' '(' expression ')' + | STATIC_CAST '<' type_id '>' '(' expression ')' + | REINTERPRET_CAST '<' type_id '>' '(' expression ')' + | CONST_CAST '<' type_id '>' '(' expression ')' + | TYPEID '(' expression ')' + | TYPEID '(' type_id ')' + ; + +expression_list: + assignment_expression + | expression_list ',' assignment_expression + ; + +pseudo_destructor_name: + COLONCOLON_opt nested_name_specifier_opt type_name COLONCOLON '~' type_name + | COLONCOLON_opt nested_name_specifier_opt '~' type_name + ; + +unary_expression: + postfix_expression + | PLUSPLUS cast_expression + | MINUSMINUS cast_expression + | unary_operator cast_expression + | SIZEOF unary_expression + | SIZEOF '(' type_id ')' + | new_expression + | delete_expression + ; + +unary_operator: + '*' + | '&' + | '+' + | '-' + | '!' + | '~' + ; + +new_expression: + COLONCOLON_opt NEW new_placement_opt new_type_id new_initializer_opt + | COLONCOLON_opt NEW new_placement_opt '(' type_id ')' new_initializer_opt + ; + +new_placement: + '(' expression_list ')' + ; + +new_type_id: + type_specifier_seq new_declarator_opt + ; + +new_declarator: + ptr_operator new_declarator_opt + | direct_new_declarator + ; + +direct_new_declarator: + '[' expression ']' + | direct_new_declarator '[' constant_expression ']' + ; + +new_initializer: + '(' expression_list_opt ')' + ; + +delete_expression: + COLONCOLON_opt DELETE cast_expression + | COLONCOLON_opt DELETE '[' ']' cast_expression + ; + +cast_expression: + unary_expression + | '(' type_id ')' cast_expression + ; + +pm_expression: + cast_expression + | pm_expression DOTSTAR cast_expression + | pm_expression ARROWSTAR cast_expression + ; + +multiplicative_expression: + pm_expression + | multiplicative_expression '*' pm_expression + | multiplicative_expression '/' pm_expression + | multiplicative_expression '%' pm_expression + ; + +additive_expression: + multiplicative_expression + | additive_expression '+' multiplicative_expression + | additive_expression '-' multiplicative_expression + ; + +shift_expression: + additive_expression + | shift_expression SL additive_expression + | shift_expression SR additive_expression + ; + +relational_expression: + shift_expression + | relational_expression '<' shift_expression + | relational_expression '>' shift_expression + | relational_expression LTEQ shift_expression + | relational_expression GTEQ shift_expression + ; + +equality_expression: + relational_expression + | equality_expression EQ relational_expression + | equality_expression NOTEQ relational_expression + ; + +and_expression: + equality_expression + | and_expression '&' equality_expression + ; + +exclusive_or_expression: + and_expression + | exclusive_or_expression '^' and_expression + ; + +inclusive_or_expression: + exclusive_or_expression + | inclusive_or_expression '|' exclusive_or_expression + ; + +logical_and_expression: + inclusive_or_expression + | logical_and_expression ANDAND inclusive_or_expression + ; + +logical_or_expression: + logical_and_expression + | logical_or_expression OROR logical_and_expression + ; + +conditional_expression: + logical_or_expression + | logical_or_expression '?' expression ':' assignment_expression + ; + +assignment_expression: + conditional_expression + | logical_or_expression assignment_operator assignment_expression + | throw_expression + ; + +assignment_operator: + '=' + | MULEQ + | DIVEQ + | MODEQ + | ADDEQ + | SUBEQ + | SREQ + | SLEQ + | ANDEQ + | XOREQ + | OREQ + ; + +expression: + assignment_expression + | expression ',' assignment_expression + ; + +constant_expression: + conditional_expression + ; + +/*---------------------------------------------------------------------- + * Statements. + *----------------------------------------------------------------------*/ + +statement: + labeled_statement + | expression_statement + | compound_statement + | selection_statement + | iteration_statement + | jump_statement + | declaration_statement + | try_block + ; + +labeled_statement: + identifier ':' statement + | CASE constant_expression ':' statement + | DEFAULT ':' statement + ; + +expression_statement: + expression_opt ';' + ; + +compound_statement: + '{' statement_seq_opt '}' + ; + +statement_seq: + statement + | statement_seq statement + ; + +selection_statement: + IF '(' condition ')' statement + | IF '(' condition ')' statement ELSE statement + | SWITCH '(' condition ')' statement + ; + +condition: + expression + | type_specifier_seq declarator '=' assignment_expression + ; + +iteration_statement: + WHILE '(' condition ')' statement + | DO statement WHILE '(' expression ')' ';' + | FOR '(' for_init_statement condition_opt ';' expression_opt ')' statement + ; + +for_init_statement: + expression_statement + | simple_declaration + ; + +jump_statement: + BREAK ';' + | CONTINUE ';' + | RETURN expression_opt ';' + | GOTO identifier ';' + ; + +declaration_statement: + block_declaration + ; + +/*---------------------------------------------------------------------- + * Declarations. + *----------------------------------------------------------------------*/ + +declaration_seq: + declaration + | declaration_seq declaration + ; + +declaration: + block_declaration + | function_definition + | template_declaration + | explicit_instantiation + | explicit_specialization + | linkage_specification + | namespace_definition + ; + +block_declaration: + simple_declaration + | asm_definition + | namespace_alias_definition + | using_declaration + | using_directive + ; + +simple_declaration: + decl_specifier_seq_opt init_declarator_list_opt ';' { SIMPLE_DECLARATION($1,$2); } + ; + +decl_specifier: + storage_class_specifier + | type_specifier + | function_specifier + | FRIEND + | TYPEDEF + ; + +decl_specifier_seq: + decl_specifier_seq_opt decl_specifier { $$ = CONCAT($1,$2); } + ; + +storage_class_specifier: + AUTO + | REGISTER + | STATIC + | EXTERN + | MUTABLE + ; + +function_specifier: + INLINE + | VIRTUAL + | EXPLICIT + ; + +typedef_name: + identifier + ; + +type_specifier: + simple_type_specifier + | class_specifier + | enum_specifier + | elaborated_type_specifier + | cv_qualifier + ; + +simple_type_specifier: + COLONCOLON_opt /*nested_name_specifier_opt*/ type_name { $$ = CONCAT($1,$2); } /*<<<<< FIX DISAMBIGUATION <<<<<<*/ + | CHAR + | WCHAR_T + | BOOL + | SHORT + | INT + | LONG + | SIGNED + | UNSIGNED + | FLOAT + | DOUBLE + | VOID + ; + +type_name: + class_name + | enum_name + | typedef_name + ; + +elaborated_type_specifier: + class_key COLONCOLON_opt nested_name_specifier_opt identifier { $$ = CONCAT($1,$2,$3,$4); } + | ENUM COLONCOLON_opt nested_name_specifier_opt identifier { $$ = CONCAT($1,$2,$3,$4); } + | TYPENAME COLONCOLON_opt nested_name_specifier identifier { $$ = CONCAT($1,$2,$3,$4); } + | TYPENAME COLONCOLON_opt nested_name_specifier identifier '<' template_argument_list '>' { $$ = CONCAT($1,$2,$3,$4,"<",$6,">"); } + ; + +enum_name: + identifier + ; + +enum_specifier: + ENUM identifier_opt '{' enumerator_list_opt '}' { $$ = CONCAT($1,$2,"{",$4,"}"); } + ; + +enumerator_list: + enumerator_definition + | enumerator_list ',' enumerator_definition { $$ = CONCAT($1,",",$3); } + ; + +enumerator_definition: + enumerator + | enumerator '=' constant_expression { $$ = CONCAT($1,"=",$3); } + ; + +enumerator: + identifier + ; + +namespace_name: + original_namespace_name + | namespace_alias + ; + +original_namespace_name: + identifier + ; + +namespace_definition: + named_namespace_definition + | unnamed_namespace_definition + ; + +named_namespace_definition: + original_namespace_definition + | extension_namespace_definition + ; + +original_namespace_definition: + NAMESPACE identifier '{' namespace_body '}' + ; + +extension_namespace_definition: + NAMESPACE original_namespace_name '{' namespace_body '}' + ; + +unnamed_namespace_definition: + NAMESPACE '{' namespace_body '}' + ; + +namespace_body: + declaration_seq_opt + ; + +namespace_alias: + identifier + ; + +namespace_alias_definition: + NAMESPACE identifier '=' qualified_namespace_specifier ';' + ; + +qualified_namespace_specifier: + COLONCOLON_opt nested_name_specifier_opt namespace_name + ; + +using_declaration: + USING TYPENAME_opt COLONCOLON_opt nested_name_specifier unqualified_id ';' + | USING COLONCOLON unqualified_id ';' + ; + +using_directive: + USING NAMESPACE COLONCOLON_opt nested_name_specifier_opt namespace_name ';' + ; + +asm_definition: + ASM '(' string_literal ')' ';' + ; + +linkage_specification: + EXTERN string_literal '{' declaration_seq_opt '}' + | EXTERN string_literal declaration + ; + +/*---------------------------------------------------------------------- + * Declarators. + *----------------------------------------------------------------------*/ + +init_declarator_list: + init_declarator + | init_declarator_list ',' init_declarator { $$ = CONCAT($1,",",$3); } + ; + +init_declarator: + declarator initializer_opt { $$ = CONCAT($1,$2); } + ; + +declarator: + direct_declarator + | ptr_operator declarator { $$ = CONCAT($1,$2); } + ; + +direct_declarator: + declarator_id + | direct_declarator '('parameter_declaration_clause ')' cv_qualifier_seq_opt exception_specification_opt + | direct_declarator '[' constant_expression_opt ']' { $$ = CONCAT($1,"[",$3,"]"); } + | '(' declarator ')' { $$ = CONCAT("(",$2,")"); } + ; + +ptr_operator: + '*' cv_qualifier_seq_opt { $$ = CONCAT("*",$2); } + | '&' { $$ = strdup("&"); } + | COLONCOLON_opt nested_name_specifier '*' cv_qualifier_seq_opt { $$ = CONCAT($1,$2,"*",$4); } + ; + +cv_qualifier_seq: + cv_qualifier cv_qualifier_seq_opt + ; + +cv_qualifier: + CONST + | VOLATILE + ; + +declarator_id: + COLONCOLON_opt id_expression { $$ = CONCAT($1,$2); } + | COLONCOLON_opt nested_name_specifier_opt type_name { $$ = CONCAT($1,$2,$3); } + ; + +type_id: + type_specifier_seq abstract_declarator_opt /*{ $$ = CONCAT($1,$2); }*/ + ; + +type_specifier_seq: + type_specifier type_specifier_seq_opt { $$ = CONCAT($1,$2); } + ; + +abstract_declarator: + ptr_operator abstract_declarator_opt /*{ $$ = CONCAT($1,$2); }*/ + | direct_abstract_declarator + ; + +direct_abstract_declarator: + direct_abstract_declarator_opt '(' parameter_declaration_clause ')' cv_qualifier_seq_opt exception_specification_opt + | direct_abstract_declarator_opt '[' constant_expression_opt ']' + | '(' abstract_declarator ')' + ; + +parameter_declaration_clause: + parameter_declaration_list_opt ELLIPSIS_opt + | parameter_declaration_list ',' ELLIPSIS + ; + +parameter_declaration_list: + parameter_declaration + | parameter_declaration_list ',' parameter_declaration + ; + +parameter_declaration: + decl_specifier_seq declarator + | decl_specifier_seq declarator '=' assignment_expression + | decl_specifier_seq abstract_declarator_opt + | decl_specifier_seq abstract_declarator_opt '=' assignment_expression + ; + +function_definition: + decl_specifier_seq_opt declarator ctor_initializer_opt function_body + | decl_specifier_seq_opt declarator function_try_block + ; + +function_body: + compound_statement + ; + +initializer: + '=' initializer_clause { $$ = strdup($2); } + | '(' expression_list ')' + ; + +initializer_clause: + assignment_expression + | '{' initializer_list COMMA_opt '}' + | '{' '}' + ; + +initializer_list: + initializer_clause + | initializer_list ',' initializer_clause + ; + +/*---------------------------------------------------------------------- + * Classes. + *----------------------------------------------------------------------*/ + +class_name: + identifier + | template_id + ; + +class_specifier: + class_head '{' member_specification_opt '}' + ; + +class_head: + class_key identifier_opt base_clause_opt + | class_key nested_name_specifier identifier base_clause_opt + ; + +class_key: + CLASS + | STRUCT + | UNION + ; + +member_specification: + member_declaration member_specification_opt + | access_specifier ':' member_specification_opt + ; + +member_declaration: + decl_specifier_seq_opt member_declarator_list_opt ';' + | function_definition SEMICOLON_opt + | qualified_id ';' + | using_declaration + | template_declaration + ; + +member_declarator_list: + member_declarator + | member_declarator_list ',' member_declarator + ; + +member_declarator: + declarator pure_specifier_opt + | declarator constant_initializer_opt + | identifier_opt ':' constant_expression + ; + +pure_specifier: + '=' '0' + ; + +constant_initializer: + '=' constant_expression + ; + +/*---------------------------------------------------------------------- + * Derived classes. + *----------------------------------------------------------------------*/ + +base_clause: + ':' base_specifier_list + ; + +base_specifier_list: + base_specifier + | base_specifier_list ',' base_specifier + ; + +base_specifier: + COLONCOLON_opt nested_name_specifier_opt class_name + | VIRTUAL access_specifier_opt COLONCOLON_opt nested_name_specifier_opt class_name + | access_specifier VIRTUAL_opt COLONCOLON_opt nested_name_specifier_opt class_name + ; + +access_specifier: + PRIVATE + | PROTECTED + | PUBLIC + ; + +/*---------------------------------------------------------------------- + * Special member functions. + *----------------------------------------------------------------------*/ + +conversion_function_id: + OPERATOR conversion_type_id + ; + +conversion_type_id: + type_specifier_seq conversion_declarator_opt + ; + +conversion_declarator: + ptr_operator conversion_declarator_opt + ; + +ctor_initializer: + ':' mem_initializer_list + ; + +mem_initializer_list: + mem_initializer + | mem_initializer ',' mem_initializer_list + ; + +mem_initializer: + mem_initializer_id '(' expression_list_opt ')' + ; + +mem_initializer_id: + COLONCOLON_opt nested_name_specifier_opt class_name + | identifier + ; + +/*---------------------------------------------------------------------- + * Overloading. + *----------------------------------------------------------------------*/ + +operator_function_id: + OPERATOR operator + ; + +operator: + NEW + | DELETE + | NEW '[' ']' + | DELETE '[' ']' + | '+' + | '_' + | '*' + | '/' + | '%' + | '^' + | '&' + | '|' + | '~' + | '!' + | '=' + | '<' + | '>' + | ADDEQ + | SUBEQ + | MULEQ + | DIVEQ + | MODEQ + | XOREQ + | ANDEQ + | OREQ + | SL + | SR + | SREQ + | SLEQ + | EQ + | NOTEQ + | LTEQ + | GTEQ + | ANDAND + | OROR + | PLUSPLUS + | MINUSMINUS + | ',' + | ARROWSTAR + | ARROW + | '(' ')' + | '[' ']' + ; + +/*---------------------------------------------------------------------- + * Templates. + *----------------------------------------------------------------------*/ + +template_declaration: + EXPORT_opt TEMPLATE '<' template_parameter_list '>' declaration + ; + +template_parameter_list: + template_parameter + | template_parameter_list ',' template_parameter + ; + +template_parameter: + type_parameter + | parameter_declaration + ; + +type_parameter: + CLASS identifier_opt + | CLASS identifier_opt '=' type_id + | TYPENAME identifier_opt + | TYPENAME identifier_opt '=' type_id + | TEMPLATE '<' template_parameter_list '>' CLASS identifier_opt + | TEMPLATE '<' template_parameter_list '>' CLASS identifier_opt '=' template_name + ; + +template_id: + template_name '<' template_argument_list '>' + ; + +template_name: + identifier + ; + +template_argument_list: + template_argument + | template_argument_list ',' template_argument + ; + +template_argument: + assignment_expression + | type_id + | template_name + ; + +explicit_instantiation: + TEMPLATE declaration + ; + +explicit_specialization: + TEMPLATE '<' '>' declaration + ; + +/*---------------------------------------------------------------------- + * Exception handling. + *----------------------------------------------------------------------*/ + +try_block: + TRY compound_statement handler_seq + ; + +function_try_block: + TRY ctor_initializer_opt function_body handler_seq + ; + +handler_seq: + handler handler_seq_opt + ; + +handler: + CATCH '(' exception_declaration ')' compound_statement + ; + +exception_declaration: + type_specifier_seq declarator + | type_specifier_seq abstract_declarator + | type_specifier_seq + | ELLIPSIS + ; + +throw_expression: + THROW assignment_expression_opt + ; + +exception_specification: + THROW '(' type_id_list_opt ')' + ; + +type_id_list: + type_id + | type_id_list ',' type_id + ; + +/*---------------------------------------------------------------------- + * Epsilon (optional) definitions. + *----------------------------------------------------------------------*/ + +declaration_seq_opt: + { $$ = EMPTY; } + | declaration_seq + ; + +TEMPLATE_opt: + { $$ = EMPTY; } + | TEMPLATE + ; + +nested_name_specifier_opt: + { $$ = EMPTY; } + | nested_name_specifier + ; + +expression_list_opt: + { $$ = EMPTY; } + | expression_list + ; + +COLONCOLON_opt: + { $$ = EMPTY; } + | COLONCOLON { $$ = strdup("::"); } + ; + +new_placement_opt: + { $$ = EMPTY; } + | new_placement + ; + +new_initializer_opt: + { $$ = EMPTY; } + | new_initializer + ; + +new_declarator_opt: + { $$ = EMPTY; } + | new_declarator + ; + +expression_opt: + { $$ = EMPTY; } + | expression + ; + +statement_seq_opt: + { $$ = EMPTY; } + | statement_seq + ; + +condition_opt: + { $$ = EMPTY; } + | condition + ; + +decl_specifier_seq_opt: + { $$ = EMPTY; } + | decl_specifier_seq + ; + +init_declarator_list_opt: + { $$ = EMPTY; } + | init_declarator_list + ; + +identifier_opt: + { $$ = EMPTY; } + | identifier + ; + +enumerator_list_opt: + { $$ = EMPTY; } + | enumerator_list + ; + +TYPENAME_opt: + { $$ = EMPTY; } + | TYPENAME + ; + +initializer_opt: + { $$ = EMPTY; } + | initializer + ; + +cv_qualifier_seq_opt: + { $$ = EMPTY; } + | cv_qualifier_seq + ; + +exception_specification_opt: + { $$ = EMPTY; } + | exception_specification + ; + +constant_expression_opt: + { $$ = EMPTY; } + | constant_expression + ; + +abstract_declarator_opt: + { $$ = EMPTY; } + | abstract_declarator + ; + +type_specifier_seq_opt: + { $$ = EMPTY; } + | type_specifier_seq + ; + +direct_abstract_declarator_opt: + { $$ = EMPTY; } + | direct_abstract_declarator + ; + +parameter_declaration_list_opt: + { $$ = EMPTY; } + | parameter_declaration_list + ; + +ELLIPSIS_opt: + { $$ = EMPTY; } + | ELLIPSIS + ; + +ctor_initializer_opt: + { $$ = EMPTY; } + | ctor_initializer + ; + +COMMA_opt: + { $$ = EMPTY; } + | ',' + ; + +member_specification_opt: + { $$ = EMPTY; } + | member_specification + ; + +base_clause_opt: + { $$ = EMPTY; } + | base_clause + ; + +member_declarator_list_opt: + { $$ = EMPTY; } + | member_declarator_list + ; + +SEMICOLON_opt: + { $$ = EMPTY; } + | ';' + ; + +pure_specifier_opt: + { $$ = EMPTY; } + | pure_specifier + ; + +constant_initializer_opt: + { $$ = EMPTY; } + | constant_initializer + ; + +access_specifier_opt: + { $$ = EMPTY; } + | access_specifier + ; + +VIRTUAL_opt: + { $$ = EMPTY; } + | VIRTUAL + ; + +conversion_declarator_opt: + { $$ = EMPTY; } + | conversion_declarator + ; + +EXPORT_opt: + { $$ = EMPTY; } + | EXPORT + ; + +handler_seq_opt: + { $$ = EMPTY; } + | handler_seq + ; + +assignment_expression_opt: + { $$ = EMPTY; } + | assignment_expression + ; + +type_id_list_opt: + { $$ = EMPTY; } + | type_id_list + ; + + +%% + +int yyerror(char *s) { + printf("error, %s\n", s); + return 1; +} + +void yyprint (FILE *file, + int type, + YYSTYPE value) +{ + if (type == IDENTIFIER) + fprintf (file, "%s", value.sval); + if (type == COLONCOLON) + fprintf (file, "%s", value.sval); + +} + +int main(void) { +/* yydebug = 1;*/ + yyparse(); +} diff --git a/src/utils/moc/sample.cpp b/src/utils/moc/sample.cpp new file mode 100644 index 0000000..8f8f2ff --- /dev/null +++ b/src/utils/moc/sample.cpp @@ -0,0 +1,51 @@ +/*////////////////////////////////////////////////////////////////////////////// +// CMT Cosmic Muon Tomography project ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova + All rights reserved + + Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > + + ------------------------------------------------------------------ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3.0 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + +//////////////////////////////////////////////////////////////////////////////*/ + + + + +typedef int TestInt; + +class DerivedObject { + + +public: + + ULIB_OBJECT_PARAMETERS(test) + { + Bubu *a; + }; + +}; + +int main() { + + ULIB_OBJECT_PARAMETERS(prova) { + int a,b; + char *c; + }; + + return 0; +} diff --git a/src/utils/moc/scan.l b/src/utils/moc/scan.l new file mode 100644 index 0000000..b5ff2d7 --- /dev/null +++ b/src/utils/moc/scan.l @@ -0,0 +1,252 @@ +%option stack +%{ +/* preamble */ +#include +#include +#include "y.tab.h" + +#define PRINT(str) { printf("%s",str); } +#define ENSTATE(st) { yy_push_state(YY_START); BEGIN(st); /*printf("ST[%i]",YY_START);*/ } +#define EXSTATE { BEGIN(yy_top_state()); yy_pop_state(); /*printf("ST[%i]",YY_START);*/ } + +#define SCANTEXT { fill_sval(); } +#define MATCH(name) { ECHO; SCANTEXT; return name; } + +int lineno; +int moc_level = 0; + +static int yywrap(void); +static void skip_until_eol(void); +static void skip_comment(void); +static int check_identifier(const char *); +static int fill_sval(); +%} + +blank [\t\f\v\r ]+ +anyunch <*>. + +intsuffix ([uU][lL]?)|([lL][uU]?) +fracconst ([0-9]*\.[0-9]+)|([0-9]+\.) +exppart [eE][-+]?[0-9]+ +floatsuffix [fFlL] +chartext ([^'])|(\\.) +stringtext ([^"])|(\\.) + +digit [0-9] +hex [0-9A-Fa-f] +letter [A-Z_a-z] +simple_escape_sequence (\\\'|\\\"|\\\?|\\\\|\\a|\\b|\\f|\\n|\\r|\\t|\\v) +octal_escape_sequence (\\[0-7]|\\[0-7][0-7]|\\[0-7][0-7][0-7]) +hexadecimal_escape_sequence (\\x{hex}+) +escape_sequence ({simple_escape_sequence}|{octal_escape_sequence}|{hexadecimal_escape_sequence}) +universal_character_name (\\u{hex}{hex}{hex}{hex}|\\U{hex}{hex}{hex}{hex}{hex}{hex}{hex}{hex}) +non_digit ({letter}|{universal_character_name}) +identifier ({non_digit}({non_digit}|{digit})*) + +begin_comment "/*" +end_comment "*/" +begin_inline_comment "//" +end_inline_comment "\n" + + +%s moc +%x cmt +%x inlcmt + +%% + +"\n" { ++lineno; ECHO; } +{blank} ECHO; + +{begin_comment} { ENSTATE(cmt); ECHO; } +{end_comment} { EXSTATE; ECHO; } + +{begin_inline_comment} { ENSTATE(inlcmt); ECHO; } +{end_inline_comment} { EXSTATE; ECHO; } + + +property { ECHO; ENSTATE(moc); return MOC_PROPERTY; } +ULIB_OBJECT_PARAMETERS { ECHO; ENSTATE(moc); return MOC_OBJECT_PARAMETERS; } +{ + "{" { moc_level++; MATCH('{'); } + "}" { if(!--moc_level)EXSTATE; MATCH('}'); } + + "<%" { MATCH('{'); } + "%>" { MATCH('}'); } + "[" { MATCH('['); } + "<:" { MATCH('['); } + "]" { MATCH(']'); } + ":>" { MATCH(']'); } + "(" { MATCH('('); } + ")" { MATCH(')'); } + ";" { MATCH(';'); } + "::" { MATCH(COLONCOLON); } + ":" { MATCH(':'); } + "..." { MATCH(ELLIPSIS); } + "?" { MATCH('?'); } + "." { MATCH('.'); } + ".*" { MATCH(DOTSTAR); } + "+" { MATCH('+'); } + "-" { MATCH('-'); } + "*" { MATCH('*'); } + "/" { MATCH('/'); } + "%" { MATCH('%'); } + "^" { MATCH('^'); } + "xor" { MATCH('^'); } + "&" { MATCH('&'); } + "bitand" { MATCH('&'); } + "|" { MATCH('|'); } + "bitor" { MATCH('|'); } + "~" { MATCH('~'); } + "compl" { MATCH('~'); } + "!" { MATCH('!'); } + "not" { MATCH('!'); } + "=" { MATCH('='); } + "<" { MATCH('<'); } + ">" { MATCH('>'); } + "+=" { MATCH(ADDEQ); } + "-=" { MATCH(SUBEQ); } + "*=" { MATCH(MULEQ); } + "/=" { MATCH(DIVEQ); } + "%=" { MATCH(MODEQ); } + "^=" { MATCH(XOREQ); } + "xor_eq" { MATCH(XOREQ); } + "&=" { MATCH(ANDEQ); } + "and_eq" { MATCH(ANDEQ); } + "|=" { MATCH(OREQ); } + "or_eq" { MATCH(OREQ); } + "<<" { MATCH(SL); } + ">>" { MATCH(SR); } + "<<=" { MATCH(SLEQ); } + ">>=" { MATCH(SREQ); } + "==" { MATCH(EQ); } + "!=" { MATCH(NOTEQ); } + "not_eq" { MATCH(NOTEQ); } + "<=" { MATCH(LTEQ); } + ">=" { MATCH(GTEQ); } + "&&" { MATCH(ANDAND); } + "and" { MATCH(ANDAND); } + "||" { MATCH(OROR); } + "or" { MATCH(OROR); } + "++" { MATCH(PLUSPLUS); } + "--" { MATCH(MINUSMINUS); } + "," { MATCH(','); } + "->*" { MATCH(ARROWSTAR); } + "->" { MATCH(ARROW); } + + "asm" { MATCH(ASM); } + "auto" { MATCH(AUTO); } + "bool" { MATCH(BOOL); } + "break" { MATCH(BREAK); } + "case" { MATCH(CASE); } + "catch" { MATCH(CATCH); } + "char" { MATCH(CHAR); } + "class" { MATCH(CLASS); } + "const" { MATCH(CONST); } + "const_cast" { MATCH(CONST_CAST); } + "continue" { MATCH(CONTINUE); } + "default" { MATCH(DEFAULT); } + "delete" { MATCH(DELETE); } + "do" { MATCH(DO); } + "double" { MATCH(DOUBLE); } + "dynamic_cast" { MATCH(DYNAMIC_CAST); } + "else" { MATCH(ELSE); } + "enum" { MATCH(ENUM); } + "explicit" { MATCH(EXPLICIT); } + "export" { MATCH(EXPORT); } + "extern" { MATCH(EXTERN); } + "false" { MATCH(FALSE); } + "float" { MATCH(FLOAT); } + "for" { MATCH(FOR); } + "friend" { MATCH(FRIEND); } + "goto" { MATCH(GOTO); } + "if" { MATCH(IF); } + "inline" { MATCH(INLINE); } + "int" { MATCH(INT); } + "long" { MATCH(LONG); } + "mutable" { MATCH(MUTABLE); } + "namespace" { MATCH(NAMESPACE); } + "new" { MATCH(NEW); } + "operator" { MATCH(OPERATOR); } + "private" { MATCH(PRIVATE); } + "protected" { MATCH(PROTECTED); } + "public" { MATCH(PUBLIC); } + "register" { MATCH(REGISTER); } + "reinterpret_cast" { MATCH(REINTERPRET_CAST); } + "return" { MATCH(RETURN); } + "short" { MATCH(SHORT); } + "signed" { MATCH(SIGNED); } + "sizeof" { MATCH(SIZEOF); } + "static" { MATCH(STATIC); } + "static_cast" { MATCH(STATIC_CAST); } + "struct" { MATCH(STRUCT); } + "switch" { MATCH(SWITCH); } + "template" { MATCH(TEMPLATE); } + "this" { MATCH(THIS); } + "throw" { MATCH(THROW); } + "true" { MATCH(TRUE); } + "try" { MATCH(TRY); } + "typedef" { MATCH(TYPEDEF); } + "typeid" { MATCH(TYPEID); } + "typename" { MATCH(TYPENAME); } + "union" { MATCH(UNION); } + "unsigned" { MATCH(UNSIGNED); } + "using" { MATCH(USING); } + "virtual" { MATCH(VIRTUAL); } + "void" { MATCH(VOID); } + "volatile" { MATCH(VOLATILE); } + "wchar_t" { MATCH(WCHAR_T); } + "while" { MATCH(WHILE); } + [a-zA-Z_][a-zA-Z_0-9]* { ECHO; return check_identifier(yytext); } + + "0"[xX][0-9a-fA-F]+{intsuffix}? { ECHO; return INTEGER; } + "0"[0-7]+{intsuffix}? { ECHO; return INTEGER; } + [0-9]+{intsuffix}? { ECHO; return INTEGER; } + + {fracconst}{exppart}?{floatsuffix}? { ECHO; return FLOATING; } + [0-9]+{exppart}{floatsuffix}? { ECHO; return FLOATING; } + + "'"{chartext}*"'" { ECHO; return CHARACTER; } + "L'"{chartext}*"'" { ECHO; return CHARACTER; } + "\""{stringtext}*"\"" { ECHO; return STRING; } + "L\""{stringtext}*"\"" { ECHO; return STRING; } + +} + +%% + +static int yywrap(void) +{ + return 1; +} + + +static int fill_sval() { + int len = strlen(yytext); + if(len) { + yylval.sval = malloc(len); + strncpy(yylval.sval, yytext, len); + } + else { + yylval.sval = strdup(""); + } + return len; +} + +static int check_identifier(const char *s) +{ +/* + switch (s[0]) { + case 'D': return TYPEDEF_NAME; + case 'N': return NAMESPACE_NAME; + case 'C': return CLASS_NAME; + case 'E': return ENUM_NAME; + case 'T': return TEMPLATE_NAME; + } +*/ + + yylval.sval = malloc(strlen(yytext)); + strncpy(yylval.sval, yytext, strlen(yytext)); + return IDENTIFIER; +} + diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..9969c96 --- /dev/null +++ b/test.cpp @@ -0,0 +1,10 @@ + +#include "Core/Object.h" + + + +int main() +{ + uLib::Object obj; + return 0; +} diff --git a/tmp/BuildTruck/BuildTruck.cpp b/tmp/BuildTruck/BuildTruck.cpp new file mode 100644 index 0000000..a952034 --- /dev/null +++ b/tmp/BuildTruck/BuildTruck.cpp @@ -0,0 +1,154 @@ + +#include + +#include +#include + +#include +#include +#include + +#include +//#include +//#include + + + +#include "Math/TriangleMesh.h" +#include "Vtk/vtkTriangleMesh.h" + +#include "Detectors/Solid.h" + +using namespace uLib; + + + +namespace Material { + +G4Material *StainlessSteel(float dens = 8.06) { // <- g/cm3 + G4NistManager* man = G4NistManager::Instance(); + man->SetVerbose(1); + + // Define elements from NIST + G4Element* C = man->FindOrBuildElement("C"); + G4Element* Si = man->FindOrBuildElement("Si"); + G4Element* Cr = man->FindOrBuildElement("Cr"); + G4Element* Mn = man->FindOrBuildElement("Mn"); + G4Element* Fe = man->FindOrBuildElement("Fe"); + G4Element* Ni = man->FindOrBuildElement("Ni"); + + + // Define materials not in NIST + G4double density = dens*g/cm3; + G4int ncomponents; + G4double fractionmass; + G4Material* StainlessSteel = new G4Material("StainlessSteel", density, ncomponents=6); + StainlessSteel->AddElement(C, fractionmass=0.001); + StainlessSteel->AddElement(Si, fractionmass=0.007); + StainlessSteel->AddElement(Cr, fractionmass=0.18); + StainlessSteel->AddElement(Mn, fractionmass=0.01); + StainlessSteel->AddElement(Fe, fractionmass=0.712); + StainlessSteel->AddElement(Ni, fractionmass=0.09); + return StainlessSteel; +} + +//G4Material *ASTM_A710(float dens = 7.85) { // <- g/cm3 +// G4NistManager* man = G4NistManager::Instance(); +// man->SetVerbose(1); + +// // Define elements from NIST +// G4Element* C = man->FindOrBuildElement("C"); +// G4Element* Cr = man->FindOrBuildElement("Cr"); +// G4Element* Cu = man->FindOrBuildElement("Cu"); +// G4Element* Fe = man->FindOrBuildElement("Fe"); +// G4Element* Mn = man->FindOrBuildElement("Mn"); +// G4Element* Mo = man->FindOrBuildElement("Mo"); +// G4Element* Ni = man->FindOrBuildElement("Ni"); +// G4Element* Nb = man->FindOrBuildElement("Nb"); +// G4Element* P = man->FindOrBuildElement("P"); +// G4Element* Si = man->FindOrBuildElement("Si"); +// G4Element* S = man->FindOrBuildElement("S"); + + +// // Define materials not in NIST +// G4double density = dens*g/cm3; +// G4int ncomponents; +// G4double fractionmass; +// G4Material* StainlessSteel = new G4Material("StainlessSteel", density, ncomponents=6); +// StainlessSteel->AddElement(C, fractionmass=0.0007); +// StainlessSteel->AddElement(Cr, fractionmass=0.18); +// StainlessSteel->AddElement(Cr, fractionmass=0.18); +// StainlessSteel->AddElement(Cr, fractionmass=0.18); +// StainlessSteel->AddElement(Si, fractionmass=0.007); +// StainlessSteel->AddElement(Mn, fractionmass=0.01); +// StainlessSteel->AddElement(Fe, fractionmass=0.712); +// StainlessSteel->AddElement(Ni, fractionmass=0.09); +// return StainlessSteel; +//} + + +G4Material *Tungsten(float dens = 19.25) { // <- g/cm3 + G4NistManager* man = G4NistManager::Instance(); + man->SetVerbose(1); + + G4Element* Wf = man->FindOrBuildElement("W"); + + G4double density = dens*g/cm3; + G4int ncomponents; + G4double fractionmass; + G4Material* Tungsten = new G4Material("Tungsten", density, ncomponents=1); + Tungsten->AddElement(Wf, fractionmass=1); + return Tungsten; +} + + +} + + + +#include + +int main() +{ + + G4GDMLParser parser; + G4Material *steel = Material::StainlessSteel(); + + // Acciaio1 // + { + TriangleMesh mesh; + vtkTriangleMesh v_mesh(mesh); + v_mesh.ReadFromObjFile("objects/ByMaterial/Acciaio1.obj"); + mesh.PrintSelf(std::cout); + TessellatedSolid solid("telaio1"); + solid.SetMaterial(steel); + solid.SetMesh(mesh); + parser.Write("telaio1.gdml",solid.GetLogical()); + } + + // Acciaio2 // + { + TriangleMesh mesh; + vtkTriangleMesh v_mesh(mesh); + v_mesh.ReadFromObjFile("objects/ByMaterial/Acciaio2.obj"); + mesh.PrintSelf(std::cout); + TessellatedSolid solid("telaio2"); + solid.SetMaterial(steel); + solid.SetMesh(mesh); + parser.Write("telaio2.gdml",solid.GetLogical()); + } + + // Assali // + { + TriangleMesh mesh; + vtkTriangleMesh v_mesh(mesh); + v_mesh.ReadFromObjFile("objects/ByMaterial/Assali.obj"); + mesh.PrintSelf(std::cout); + TessellatedSolid solid("assali"); + solid.SetMaterial(steel); + solid.SetMesh(mesh); + parser.Write("assali.gdml",solid.GetLogical()); + } + + +} diff --git a/tmp/BuildTruck/Makefile.am b/tmp/BuildTruck/Makefile.am new file mode 100644 index 0000000..459d8c0 --- /dev/null +++ b/tmp/BuildTruck/Makefile.am @@ -0,0 +1,11 @@ + +include $(top_srcdir)/Common.am +include $(top_srcdir)/src/Vtk/Vtk.am + +#AM_DEFAULT_SOURCE_EXT = .cpp + + +LDADD = $(top_srcdir)/libmutom-0.1.la $(AM_LIBS_ALL) + +bin_PROGRAMS = BuildTruck + diff --git a/tmp/BuildTruck/objects/acciaio1.stl b/tmp/BuildTruck/objects/acciaio1.stl new file mode 100644 index 0000000000000000000000000000000000000000..ee1624ce53efe18983a763556093598cb3ba9fa6 GIT binary patch literal 78284 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 X`EY~9g&L?Hfa?76#RZ)^Tvqn~iyy_X literal 0 HcmV?d00001 diff --git a/tmp/BuildTruck/objects/carrozzeria.stl b/tmp/BuildTruck/objects/carrozzeria.stl new file mode 100644 index 0000000000000000000000000000000000000000..adac38c1745156a6abb93009ba5082bafec10b11 GIT binary patch literal 143884 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%0D2`sk%y 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�&;+&{P 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Íu?m}!62{r@>S>eR*K^!Mj(9Pv)M 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 literal 0 HcmV?d00001 diff --git a/tmp/BuildTruck/objects/fusto.stl b/tmp/BuildTruck/objects/fusto.stl new file mode 100644 index 0000000000000000000000000000000000000000..5ae853c5b827ece5fd3092facbbc79b0cf2f59f8 GIT binary patch literal 22484 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 NOmK%|ACvaP{{w3553>LO literal 0 HcmV?d00001 diff --git a/tmp/BuildTruck/objects/telaio.stl b/tmp/BuildTruck/objects/telaio.stl new file mode 100644 index 0000000000000000000000000000000000000000..f7ff50f133a260d3fde6899fb88c963115b4da02 GIT binary patch literal 17684 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 Pf0OYVC;Xk*rOST+twJz` literal 0 HcmV?d00001 diff --git a/tmp/BuildTruck/objects/truck.blend b/tmp/BuildTruck/objects/truck.blend new file mode 100644 index 0000000000000000000000000000000000000000..c4957598ebcddb9ae28b8ff251754757f30d9d57 GIT binary patch literal 2693248 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