From 11f9db18dd0d751c949a7cbc4cd4250583f6e130 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (home)" <j.wuttke@fz-juelich.de>
Date: Sat, 30 Mar 2013 11:06:58 +0100
Subject: [PATCH] bug found and resolved (ParticleDecoration::clone did not
 copy transform).

---
 Core/Geometry/inc/ITransform3D.h              |  6 ++
 Core/Geometry/inc/Rotate3D.h                  |  6 ++
 Core/Samples/inc/IDecoration.h                |  2 +
 Core/Samples/inc/Layer.h                      |  1 -
 Core/Samples/inc/LayerDecorator.h             | 15 ++++-
 Core/Samples/inc/ParticleDecoration.h         | 46 +++++++++-----
 Core/Samples/inc/ParticleInfo.h               | 14 ++++-
 Core/Samples/src/LayerDecorator.cpp           | 14 +----
 Core/Samples/src/ParticleDecoration.cpp       | 63 ++++++++++---------
 Core/Samples/src/ParticleInfo.cpp             | 20 +++---
 .../TestCore/IsGISAXS09/IsGISAXS09.cpp        |  2 +
 11 files changed, 117 insertions(+), 72 deletions(-)

diff --git a/Core/Geometry/inc/ITransform3D.h b/Core/Geometry/inc/ITransform3D.h
index 5ca6298b8fb..98f1072e3b0 100644
--- a/Core/Geometry/inc/ITransform3D.h
+++ b/Core/Geometry/inc/ITransform3D.h
@@ -43,6 +43,12 @@ class ITransform3D {
         transformed(const BasicVector3D<complex_t>& v) const
     { return v; }
 
+    friend std::ostream& operator<<(std::ostream& ostr, const ITransform3D& m)
+    { m.print(ostr); return ostr; }
+
+    virtual void print(std::ostream& ostr) const
+    { ostr << "Transform3D:Identity"; }
+
 };
  
 }  // namespace Geometry
diff --git a/Core/Geometry/inc/Rotate3D.h b/Core/Geometry/inc/Rotate3D.h
index ecc94172e4d..56dc32fdd13 100644
--- a/Core/Geometry/inc/Rotate3D.h
+++ b/Core/Geometry/inc/Rotate3D.h
@@ -54,6 +54,9 @@ class RotateY_3D : public ITransform3D {
                                         -m_sa*v.x() + m_ca*v.z() );
     }
 
+    virtual void print(std::ostream& ostr) const
+    { ostr << "Transform3D:Rotate_Y(" << m_ca << "," << m_sa << ")" ; }
+
  private:
     double m_ca, m_sa;
 
@@ -92,6 +95,9 @@ class RotateZ_3D : public ITransform3D {
                                          v.z()                    );
     }
 
+    virtual void print(std::ostream& ostr) const
+    { ostr << "Transform3D:Rotate_Z(" << m_ca << "," << m_sa << ")" ; }
+
  private:
     double m_ca, m_sa;
 
diff --git a/Core/Samples/inc/IDecoration.h b/Core/Samples/inc/IDecoration.h
index 56499d81db7..696ef73e449 100644
--- a/Core/Samples/inc/IDecoration.h
+++ b/Core/Samples/inc/IDecoration.h
@@ -26,6 +26,8 @@ class IInterferenceFunction;
 
 //! Interface to equip a sample component with various properties.
 
+//! Currently (March 2013) the only child class is ParticleDecoration.
+
 class IDecoration : public ICompositeSample
 {
  public:
diff --git a/Core/Samples/inc/Layer.h b/Core/Samples/inc/Layer.h
index f9ebb51e879..8f40bdfe00f 100644
--- a/Core/Samples/inc/Layer.h
+++ b/Core/Samples/inc/Layer.h
@@ -89,7 +89,6 @@ class Layer : public ICompositeSample
         getParameterPool()->registerParameter("thickness", &m_thickness);
     }
 
- private:
     void print(std::ostream& ostr) const;
 
     const IMaterial* mp_material;    //!< pointer to the material
diff --git a/Core/Samples/inc/LayerDecorator.h b/Core/Samples/inc/LayerDecorator.h
index 7afd84de74d..f9037a57c54 100644
--- a/Core/Samples/inc/LayerDecorator.h
+++ b/Core/Samples/inc/LayerDecorator.h
@@ -20,11 +20,12 @@
 #include "ParticleDecoration.h"
 #include "LayerDecoratorDWBASimulation.h"
 
-//! Equip a layer with thickness, material, refraction index, WHAT ELSE ?
+//! Combines a Layer with an IDecoration.
 
 class LayerDecorator : public Layer
 {
  public:
+    //! Constructs LayerDecorator object by cloning _layer_ and _decoration_.
     LayerDecorator(const Layer& layer, const IDecoration& decoration)
         : mp_decorated_layer(layer.clone()), mp_decoration(decoration.clone())
     {
@@ -89,7 +90,17 @@ class LayerDecorator : public Layer
     }
 
  protected:
-    LayerDecorator(const LayerDecorator& layer);
+    //! Constructs a new object by cloning _other_'s layer and decoration.
+    LayerDecorator(const LayerDecorator& other)
+        : Layer(other)
+    {
+        mp_decorated_layer = other.getDecoratedLayer()->clone();
+        mp_decoration = other.getDecoration()->clone();
+        setName("LayerDecorator");
+        registerChild(mp_decorated_layer);
+        registerChild(mp_decoration);
+        init_parameters();
+    }
 
     Layer *mp_decorated_layer;
     IDecoration *mp_decoration;
diff --git a/Core/Samples/inc/ParticleDecoration.h b/Core/Samples/inc/ParticleDecoration.h
index f61b8af9106..f9ce25404a1 100644
--- a/Core/Samples/inc/ParticleDecoration.h
+++ b/Core/Samples/inc/ParticleDecoration.h
@@ -26,13 +26,34 @@
 class ParticleDecoration : public IDecoration
 {
  public:
-    ParticleDecoration();
-    ParticleDecoration(
-        Particle *p_particle, double depth=0.0, double abundance=1.0);
+    ParticleDecoration()
+        : m_total_abundance(0.0)
+    {
+        setName("ParticleDecoration");
+    }
+
     ParticleDecoration(
-        const Particle& p_particle, double depth=0.0, double abundance=1.0);
-    virtual ~ParticleDecoration();
+        Particle* p_particle, double depth=0., double abundance=1.)
+        : m_total_abundance(0.0)
+    {
+        setName("ParticleDecoration");
+        addParticle(p_particle, depth, abundance);
+    }
 
+    ParticleDecoration(
+        const Particle& p_particle, double depth=0., double abundance=1.)
+        : m_total_abundance(0.0)
+    {
+        setName("ParticleDecoration");
+        addParticle(p_particle.clone(), depth, abundance);
+    }
+    
+    ~ParticleDecoration()
+    {
+        for (size_t i=0; i<m_particles.size(); ++i)
+            delete m_particles[i];
+    }
+    
     virtual ParticleDecoration *clone() const;
 
     //! Adds generic particle, *-version.
@@ -86,19 +107,12 @@ class ParticleDecoration : public IDecoration
 
  private:
     //! Adds particle information with simultaneous registration in parent class.
-    void addAndRegisterParticleInfo(ParticleInfo *child)
-    {
-        m_total_abundance += child->getAbundance();
-        m_particles.push_back(child);
-        registerChild(child);
-    }
+    void addAndRegisterParticleInfo(ParticleInfo *child);
 
     //! Adds interference function with simultaneous registration in parent class
-    void addAndRegisterInterferenceFunction(IInterferenceFunction *child)
-    {
-        m_interference_functions.push_back(child);
-        registerChild(child);
-    }
+    void addAndRegisterInterferenceFunction(IInterferenceFunction *child);
+
+    void print(std::ostream& ostr) const;
 
     //TODO: replace with SafePointerVector
     std::vector<ParticleInfo*> m_particles;
diff --git a/Core/Samples/inc/ParticleInfo.h b/Core/Samples/inc/ParticleInfo.h
index 44cb10b3a93..cd70ef4ea3f 100644
--- a/Core/Samples/inc/ParticleInfo.h
+++ b/Core/Samples/inc/ParticleInfo.h
@@ -22,6 +22,10 @@
 
 //! Holds additional information about particle (used in ParticleDecoration).
 
+//! Currently (March 2013), child classes are
+//! - DiffuseParticleInfo
+//! - PositionParticleInfo
+
 class ParticleInfo : public ICompositeSample
 {
  public:
@@ -36,9 +40,13 @@ class ParticleInfo : public ICompositeSample
     ParticleInfo(const Particle& p_particle,
                  double depth=0, double abundance=0);
 
-    virtual ~ParticleInfo();
+    virtual ~ParticleInfo() { delete mp_particle; }
 
-    virtual ParticleInfo *clone() const;
+    virtual ParticleInfo *clone() const 
+    {
+        return new ParticleInfo(
+            mp_particle->clone(), mP_transform, m_depth, m_abundance);
+    }
 
     //! Returns particle.
     const Particle *getParticle() const { return mp_particle; }
@@ -66,6 +74,8 @@ class ParticleInfo : public ICompositeSample
  protected:
     virtual void init_parameters();
 
+    virtual void print(std::ostream& ostr) const;
+
     Particle *mp_particle;
     Geometry::PTransform3D mP_transform;
     double m_depth;
diff --git a/Core/Samples/src/LayerDecorator.cpp b/Core/Samples/src/LayerDecorator.cpp
index cfed1d89d33..3112d80edce 100644
--- a/Core/Samples/src/LayerDecorator.cpp
+++ b/Core/Samples/src/LayerDecorator.cpp
@@ -44,20 +44,8 @@ DiffuseDWBASimulation* LayerDecorator::createDiffuseDWBASimulation() const
     return 0;
 }
 
-LayerDecorator::LayerDecorator(const LayerDecorator& other)
-: Layer(other)
-{
-    mp_decorated_layer = other.getDecoratedLayer()->clone();
-    mp_decoration = other.getDecoration()->clone();
-
-    setName("LayerDecorator");
-    registerChild(mp_decorated_layer);
-    registerChild(mp_decoration);
-    init_parameters();
-}
-
 void LayerDecorator::print(std::ostream& ostr) const
 {
-    ICompositeSample::print(ostr);
+    Layer::print(ostr);
     ostr << "-->LayerDecorator{" << *mp_decoration << "}";
 }
diff --git a/Core/Samples/src/ParticleDecoration.cpp b/Core/Samples/src/ParticleDecoration.cpp
index 2957c2b5481..1341c7f5a6e 100644
--- a/Core/Samples/src/ParticleDecoration.cpp
+++ b/Core/Samples/src/ParticleDecoration.cpp
@@ -19,38 +19,13 @@
 #include "LocalMonodisperseApproximationStrategy.h"
 #include "InterferenceFunction1DParaCrystal.h"
 #include "SizeSpacingCorrelationApproximationStrategy.h"
+#include "MessageService.h"
+#include <iomanip>
 
 
-ParticleDecoration::ParticleDecoration()
-  : m_total_abundance(0.0)
-{
-    setName("ParticleDecoration");
-}
-
-ParticleDecoration::ParticleDecoration(
-    Particle* p_particle, double depth, double abundance)
-  : m_total_abundance(0.0)
-{
-    setName("ParticleDecoration");
-    addParticle(p_particle, depth, abundance);
-}
-
-ParticleDecoration::ParticleDecoration(
-    const Particle& p_particle, double depth, double abundance)
-  : m_total_abundance(0.0)
-{
-    setName("ParticleDecoration");
-    addParticle(p_particle.clone(), depth, abundance);
-}
-
-ParticleDecoration::~ParticleDecoration()
-{
-    for (size_t i=0; i<m_particles.size(); ++i)
-        delete m_particles[i];
-}
-
 ParticleDecoration* ParticleDecoration::clone() const
 {
+    msglog(MSG::DEBUG) << "ParticleDecoration::clone()";
     ParticleDecoration *p_new = new ParticleDecoration();
     p_new->setName(getName());
 
@@ -105,7 +80,7 @@ void ParticleDecoration::addParticle(
     addParticle(p_particle.clone(), Geometry::PTransform3D(), depth, abundance);
 }
 
-//! Adds particle info
+//! Adds particle info.
 
 void ParticleDecoration::addParticleInfo(const ParticleInfo& info)
 {
@@ -151,3 +126,33 @@ const IInterferenceFunction* ParticleDecoration::getInterferenceFunction(
         "ParticleDecoration::getInterferenceFunction() ->"
         "Not so many interference functions in this decoration.");
 }
+
+//! Adds particle information with simultaneous registration in parent class.
+void ParticleDecoration::addAndRegisterParticleInfo(
+    ParticleInfo *child)
+{
+    msglog(MSG::DEBUG) << "ParticleDecoration::addAndRegisterParticleInfo {" <<
+        *child << "}";
+    m_total_abundance += child->getAbundance();
+    m_particles.push_back(child);
+    registerChild(child);
+}
+
+//! Adds interference function with simultaneous registration in parent class.
+
+void ParticleDecoration::addAndRegisterInterferenceFunction(
+    IInterferenceFunction *child)
+{
+    m_interference_functions.push_back(child);
+    registerChild(child);
+}
+
+void ParticleDecoration::print(std::ostream& ostr) const
+{
+    IDecoration::print(ostr);
+    ostr << "-->ParticleDecoration<" << this << ">{\n";
+    for( size_t i=0; i<m_particles.size(); ++i )
+        ostr << "      - particle " << std::left << std::setw(2) << i << " { "
+             << *(m_particles[i]) << "}\n";
+    ostr << "}";
+}
diff --git a/Core/Samples/src/ParticleInfo.cpp b/Core/Samples/src/ParticleInfo.cpp
index 6168c815612..ef8846b7b5d 100644
--- a/Core/Samples/src/ParticleInfo.cpp
+++ b/Core/Samples/src/ParticleInfo.cpp
@@ -71,20 +71,22 @@ ParticleInfo::ParticleInfo(
     init_parameters();
 }
 
-ParticleInfo::~ParticleInfo()
-{
-    delete mp_particle;
-}
-
-//! Registers some class members for later access via parameter pool
 void ParticleInfo::init_parameters()
 {
     getParameterPool()->clear();
     getParameterPool()->registerParameter("depth", &m_depth);
 }
 
-ParticleInfo *ParticleInfo::clone() const
+
+void ParticleInfo::print(std::ostream& ostr) const
 {
-    return new ParticleInfo(
-        mp_particle->clone(), m_depth, m_abundance);
+    ostr << "ParticleInfo:" << getName() << "<" << this << "> : {" <<
+        " depth=" << m_depth <<
+        ", abundance=" << m_abundance <<
+        ", transform=";
+    if ( mP_transform )
+        ostr << *mP_transform;
+    else
+        ostr << "NONE";
+    ostr << " }";
 }
diff --git a/Tests/FunctionalTests/TestCore/IsGISAXS09/IsGISAXS09.cpp b/Tests/FunctionalTests/TestCore/IsGISAXS09/IsGISAXS09.cpp
index 745e736f626..c8bc7c5436a 100644
--- a/Tests/FunctionalTests/TestCore/IsGISAXS09/IsGISAXS09.cpp
+++ b/Tests/FunctionalTests/TestCore/IsGISAXS09/IsGISAXS09.cpp
@@ -13,6 +13,7 @@
 #include "Rotate3D.h"
 #include "Utils.h"
 #include "InterferenceFunction1DParaCrystal.h"
+#include "MessageService.h"
 
 #include <iostream>
 #include <cmath>
@@ -99,6 +100,7 @@ void FunctionalTests::IsGISAXS09::runpyramidZ45()
 
     Geometry::PTransform3D transform(
         new Geometry::RotateZ_3D(45.*Units::degree) );
+    msglog(MSG::DEBUG) << "created rotZ45 {" << *transform << "}";
 
     ParticleDecoration particle_decoration;
     particle_decoration.addParticle(pyramid, transform);
-- 
GitLab