From 80c6b98eaa393c88fc07de532e36b23de6ba7b09 Mon Sep 17 00:00:00 2001
From: Walter Van Herck <w.van.herck@fz-juelich.de>
Date: Thu, 28 Nov 2013 16:04:06 +0100
Subject: [PATCH] Remove transformation from FormFactorCrystal; transform
 Lattice and LatticeBasis instead of q for form factor calculations; rotate
 mesoformfactor also

---
 Core/FormFactors/inc/FormFactorCrystal.h      |  4 --
 Core/FormFactors/src/FormFactorCrystal.cpp    | 38 +++++---------
 Core/Geometry/inc/ITransform3D.h              | 24 ---------
 Core/PythonAPI/src/Crystal.pypp.cpp           | 49 ++++++++++++++-----
 Core/PythonAPI/src/FormFactorCrystal.pypp.cpp | 10 ----
 .../src/IClusteredParticles.pypp.cpp          | 23 +++++++++
 Core/Samples/inc/Crystal.h                    | 14 ++++--
 Core/Samples/inc/IClusteredParticles.h        | 12 +++--
 Core/Samples/inc/Lattice.h                    |  5 ++
 Core/Samples/inc/LatticeBasis.h               |  3 ++
 Core/Samples/src/Crystal.cpp                  | 30 ++++++++----
 Core/Samples/src/Lattice.cpp                  | 10 +++-
 Core/Samples/src/LatticeBasis.cpp             | 22 +++++++++
 Core/Samples/src/MesoCrystal.cpp              |  2 +-
 14 files changed, 149 insertions(+), 97 deletions(-)

diff --git a/Core/FormFactors/inc/FormFactorCrystal.h b/Core/FormFactors/inc/FormFactorCrystal.h
index 874aeb587e3..b614ec314d3 100644
--- a/Core/FormFactors/inc/FormFactorCrystal.h
+++ b/Core/FormFactors/inc/FormFactorCrystal.h
@@ -48,8 +48,6 @@ public:
 
     virtual double getVolume() const;
 
-    void setTransformation(const Geometry::PTransform3D& P_transform);
-
 private:
     void calculateLargestReciprocalDistance();
 
@@ -60,8 +58,6 @@ private:
     IFormFactor *mp_meso_form_factor;
     const IMaterial *mp_ambient_material;
     double m_max_rec_length;
-    Geometry::PTransform3D mP_transform;
-    Geometry::PTransform3D mP_inverse_transform;
 };
 
 #endif /* FORMFACTORCRYSTAL_H_ */
diff --git a/Core/FormFactors/src/FormFactorCrystal.cpp b/Core/FormFactors/src/FormFactorCrystal.cpp
index 55d60da591e..97e8f9ddcb6 100644
--- a/Core/FormFactors/src/FormFactorCrystal.cpp
+++ b/Core/FormFactors/src/FormFactorCrystal.cpp
@@ -19,16 +19,22 @@ FormFactorCrystal::FormFactorCrystal(
         const Crystal& p_crystal,
         const IFormFactor& meso_crystal_form_factor,
         const IMaterial *p_material, complex_t wavevector_scattering_factor)
-: m_lattice(p_crystal.getLattice())
+: m_lattice(p_crystal.getTransformedLattice())
 , m_wavevector_scattering_factor(wavevector_scattering_factor)
 , mp_ambient_material(p_material)
 , m_max_rec_length(0.0)
 {
     setName("FormFactorCrystal");
-    mp_lattice_basis = p_crystal.createBasis();
+    mp_lattice_basis = p_crystal.createTransformedBasis();
     mp_basis_form_factor = mp_lattice_basis->createFormFactor(
             m_wavevector_scattering_factor);
-    mp_meso_form_factor = meso_crystal_form_factor.clone();
+    if (p_crystal.getTransform().get()) {
+        mp_meso_form_factor = new FormFactorDecoratorTransformation(
+                meso_crystal_form_factor.clone(),
+                p_crystal.getTransform() );
+    } else {
+        mp_meso_form_factor = meso_crystal_form_factor.clone();
+    }
     setAmbientMaterial(mp_ambient_material);
     calculateLargestReciprocalDistance();
 }
@@ -47,9 +53,6 @@ FormFactorCrystal* FormFactorCrystal::clone() const
             *mp_meso_form_factor, mp_ambient_material,
             m_wavevector_scattering_factor);
     result->setName(getName());
-    if (mP_transform.get()) {
-        result->setTransformation(mP_transform);
-    }
     return result;
 }
 
@@ -72,13 +75,7 @@ complex_t FormFactorCrystal::evaluate(const cvector_t& k_i,
     // construct a real reciprocal vector
     cvector_t q_bin_lower = k_i - k_f_bin.m_q_lower;
     cvector_t q_bin_upper = k_i - k_f_bin.m_q_upper;
-    Bin1DCVector q_bin;
-    if (mP_inverse_transform.get()) {
-        q_bin = Bin1DCVector(mP_inverse_transform->transformed(q_bin_lower),
-                mP_inverse_transform->transformed(q_bin_upper));
-    } else {
-        q_bin = Bin1DCVector(q_bin_lower, q_bin_upper);
-    }
+    Bin1DCVector q_bin = Bin1DCVector(q_bin_lower, q_bin_upper);
 
     cvector_t q = q_bin.getMidPoint();
     kvector_t q_real(q.x().real(), q.y().real(), q.z().real());
@@ -115,13 +112,7 @@ Eigen::Matrix2cd FormFactorCrystal::evaluatePol(const cvector_t& k_i,
     // construct a real reciprocal vector
     cvector_t q_bin_lower = k_i - k_f_bin.m_q_lower;
     cvector_t q_bin_upper = k_i - k_f_bin.m_q_upper;
-    Bin1DCVector q_bin;
-    if (mP_inverse_transform.get()) {
-        q_bin = Bin1DCVector(mP_inverse_transform->transformed(q_bin_lower),
-                mP_inverse_transform->transformed(q_bin_upper));
-    } else {
-        q_bin = Bin1DCVector(q_bin_lower, q_bin_upper);
-    }
+    Bin1DCVector q_bin =  Bin1DCVector(q_bin_lower, q_bin_upper);
 
     cvector_t q = q_bin.getMidPoint();
     kvector_t q_real(q.x().real(), q.y().real(), q.z().real());
@@ -157,13 +148,6 @@ double FormFactorCrystal::getVolume() const
     return mp_meso_form_factor->getVolume();
 }
 
-void FormFactorCrystal::setTransformation(
-        const Geometry::PTransform3D& P_transform)
-{
-    mP_transform = P_transform;
-    mP_inverse_transform = mP_transform->inverse();
-}
-
 void FormFactorCrystal::calculateLargestReciprocalDistance()
 {
     kvector_t a1 = m_lattice.getBasisVectorA();
diff --git a/Core/Geometry/inc/ITransform3D.h b/Core/Geometry/inc/ITransform3D.h
index 07a91420edf..733e93bbd3b 100644
--- a/Core/Geometry/inc/ITransform3D.h
+++ b/Core/Geometry/inc/ITransform3D.h
@@ -46,10 +46,6 @@ public:
         transformed(const BasicVector3D<complex_t>& v) const
     { return v; }
 
-#ifndef GCCXML_SKIP_THIS
-    Eigen::Matrix2cd transformed(const Eigen::Matrix2cd &m) const;
-#endif
-
     friend std::ostream& operator<<(std::ostream& ostr, const ITransform3D& m)
     { m.print(ostr); return ostr; }
 
@@ -59,26 +55,6 @@ public:
 
 }// namespace Geometry
 
-#ifndef GCCXML_SKIP_THIS
-inline Eigen::Matrix2cd Geometry::ITransform3D::transformed(
-        const Eigen::Matrix2cd& m) const
-{
-    Eigen::Matrix2cd result;
-    complex_t im(0.0, 1.0);
-    double a = std::real( (complex_t)(m(0,0) + m(1,1)) )/2.0;
-    double bx = std::real( (complex_t)m(1,0) );
-    double by = std::imag( (complex_t)m(1,0) );
-    double bz = std::real( (complex_t)(m(0,0) - m(1,1)) )/2.0;
-    BasicVector3D<double> b_v(bx, by, bz);
-    BasicVector3D<double> b_v_t = transformed(b_v);
-    result(0,0) = a + b_v_t.z();
-    result(0,1) = b_v_t.x() - im*b_v_t.y();
-    result(1,0) = b_v_t.x() + im*b_v_t.y();
-    result(1,1) = a - b_v_t.z();
-    return result;
-}
-#endif
-
 #endif /* GEOMETRY_ITRANSFORM3D_H */
 
 
diff --git a/Core/PythonAPI/src/Crystal.pypp.cpp b/Core/PythonAPI/src/Crystal.pypp.cpp
index 30711aebcec..0c46992beb8 100644
--- a/Core/PythonAPI/src/Crystal.pypp.cpp
+++ b/Core/PythonAPI/src/Crystal.pypp.cpp
@@ -49,6 +49,18 @@ struct Crystal_wrapper : Crystal, bp::wrapper< Crystal > {
         return Crystal::cloneInvertB( );
     }
 
+    virtual ::Geometry::PTransform3D getTransform(  ) const  {
+        if( bp::override func_getTransform = this->get_override( "getTransform" ) )
+            return func_getTransform(  );
+        else{
+            return this->Crystal::getTransform(  );
+        }
+    }
+    
+    ::Geometry::PTransform3D default_getTransform(  ) const  {
+        return Crystal::getTransform( );
+    }
+
     virtual void setTransform( ::Geometry::PTransform3D const & transform ) {
         if( bp::override func_setTransform = this->get_override( "setTransform" ) )
             func_setTransform( transform );
@@ -208,24 +220,15 @@ void register_Crystal_class(){
                 , bp::return_value_policy< bp::reference_existing_object >() );
         
         }
-        { //::Crystal::createBasis
+        { //::Crystal::createTransformedBasis
         
-            typedef ::LatticeBasis * ( ::Crystal::*createBasis_function_type )(  ) const;
+            typedef ::LatticeBasis * ( ::Crystal::*createTransformedBasis_function_type )(  ) const;
             
             Crystal_exposer.def( 
-                "createBasis"
-                , createBasis_function_type( &::Crystal::createBasis )
+                "createTransformedBasis"
+                , createTransformedBasis_function_type( &::Crystal::createTransformedBasis )
                 , bp::return_value_policy< bp::manage_new_object >() );
         
-        }
-        { //::Crystal::getLattice
-        
-            typedef ::Lattice ( ::Crystal::*getLattice_function_type )(  ) const;
-            
-            Crystal_exposer.def( 
-                "getLattice"
-                , getLattice_function_type( &::Crystal::getLattice ) );
-        
         }
         { //::Crystal::getLatticeBasis
         
@@ -236,6 +239,26 @@ void register_Crystal_class(){
                 , getLatticeBasis_function_type( &::Crystal::getLatticeBasis )
                 , bp::return_value_policy< bp::reference_existing_object >() );
         
+        }
+        { //::Crystal::getTransform
+        
+            typedef ::Geometry::PTransform3D ( ::Crystal::*getTransform_function_type )(  ) const;
+            typedef ::Geometry::PTransform3D ( Crystal_wrapper::*default_getTransform_function_type )(  ) const;
+            
+            Crystal_exposer.def( 
+                "getTransform"
+                , getTransform_function_type(&::Crystal::getTransform)
+                , default_getTransform_function_type(&Crystal_wrapper::default_getTransform) );
+        
+        }
+        { //::Crystal::getTransformedLattice
+        
+            typedef ::Lattice ( ::Crystal::*getTransformedLattice_function_type )(  ) const;
+            
+            Crystal_exposer.def( 
+                "getTransformedLattice"
+                , getTransformedLattice_function_type( &::Crystal::getTransformedLattice ) );
+        
         }
         { //::Crystal::setDWFactor
         
diff --git a/Core/PythonAPI/src/FormFactorCrystal.pypp.cpp b/Core/PythonAPI/src/FormFactorCrystal.pypp.cpp
index 71e92a0fae3..3faf86f8d95 100644
--- a/Core/PythonAPI/src/FormFactorCrystal.pypp.cpp
+++ b/Core/PythonAPI/src/FormFactorCrystal.pypp.cpp
@@ -319,16 +319,6 @@ void register_FormFactorCrystal_class(){
                 , getVolume_function_type(&::FormFactorCrystal::getVolume)
                 , default_getVolume_function_type(&FormFactorCrystal_wrapper::default_getVolume) );
         
-        }
-        { //::FormFactorCrystal::setTransformation
-        
-            typedef void ( ::FormFactorCrystal::*setTransformation_function_type )( ::Geometry::PTransform3D const & ) ;
-            
-            FormFactorCrystal_exposer.def( 
-                "setTransformation"
-                , setTransformation_function_type( &::FormFactorCrystal::setTransformation )
-                , ( bp::arg("P_transform") ) );
-        
         }
         { //::IParameterized::areParametersChanged
         
diff --git a/Core/PythonAPI/src/IClusteredParticles.pypp.cpp b/Core/PythonAPI/src/IClusteredParticles.pypp.cpp
index 290c5a3f77b..0d91d238c2d 100644
--- a/Core/PythonAPI/src/IClusteredParticles.pypp.cpp
+++ b/Core/PythonAPI/src/IClusteredParticles.pypp.cpp
@@ -49,6 +49,18 @@ struct IClusteredParticles_wrapper : IClusteredParticles, bp::wrapper< IClustere
         return IClusteredParticles::cloneInvertB( );
     }
 
+    virtual ::Geometry::PTransform3D getTransform(  ) const  {
+        if( bp::override func_getTransform = this->get_override( "getTransform" ) )
+            return func_getTransform(  );
+        else{
+            return this->IClusteredParticles::getTransform(  );
+        }
+    }
+    
+    ::Geometry::PTransform3D default_getTransform(  ) const  {
+        return IClusteredParticles::getTransform( );
+    }
+
     virtual void setAmbientMaterial( ::IMaterial const * p_ambient_material ){
         bp::override func_setAmbientMaterial = this->get_override( "setAmbientMaterial" );
         func_setAmbientMaterial( boost::python::ptr(p_ambient_material) );
@@ -212,6 +224,17 @@ void register_IClusteredParticles_class(){
                 , default_cloneInvertB_function_type(&IClusteredParticles_wrapper::default_cloneInvertB)
                 , bp::return_value_policy< bp::reference_existing_object >() );
         
+        }
+        { //::IClusteredParticles::getTransform
+        
+            typedef ::Geometry::PTransform3D ( ::IClusteredParticles::*getTransform_function_type )(  ) const;
+            typedef ::Geometry::PTransform3D ( IClusteredParticles_wrapper::*default_getTransform_function_type )(  ) const;
+            
+            IClusteredParticles_exposer.def( 
+                "getTransform"
+                , getTransform_function_type(&::IClusteredParticles::getTransform)
+                , default_getTransform_function_type(&IClusteredParticles_wrapper::default_getTransform) );
+        
         }
         { //::IClusteredParticles::setAmbientMaterial
         
diff --git a/Core/Samples/inc/Crystal.h b/Core/Samples/inc/Crystal.h
index f1cf70b8f50..65a9a33c63f 100644
--- a/Core/Samples/inc/Crystal.h
+++ b/Core/Samples/inc/Crystal.h
@@ -43,11 +43,10 @@ public:
     virtual IFormFactor *createTotalFormFactor(
         const IFormFactor& meso_crystal_form_factor,
         const IMaterial *p_ambient_material,
-        complex_t wavevector_scattering_factor,
-        const Geometry::PTransform3D& transform) const;
+        complex_t wavevector_scattering_factor) const;
 
-    Lattice getLattice() const { return m_lattice; }
-    LatticeBasis *createBasis() const { return mp_lattice_basis->clone(); }
+    Lattice getTransformedLattice() const;
+    LatticeBasis *createTransformedBasis() const;
 
     const LatticeBasis *getLatticeBasis() const { return mp_lattice_basis; }
 
@@ -59,10 +58,17 @@ public:
     //! Sets transformation.
     virtual void setTransform(const Geometry::PTransform3D& transform);
 
+    //! Gets transformation
+    virtual Geometry::PTransform3D getTransform() const {
+        return mP_transform;
+    }
+
+
 private:
     Crystal(LatticeBasis *p_lattice_basis, const Lattice& lattice);
 
     Lattice m_lattice;
+    Geometry::PTransform3D mP_transform;
     LatticeBasis *mp_lattice_basis;
     double m_dw_factor;
 };
diff --git a/Core/Samples/inc/IClusteredParticles.h b/Core/Samples/inc/IClusteredParticles.h
index b799a4a0455..4864b336726 100644
--- a/Core/Samples/inc/IClusteredParticles.h
+++ b/Core/Samples/inc/IClusteredParticles.h
@@ -59,13 +59,11 @@ public:
     virtual IFormFactor *createTotalFormFactor(
            const IFormFactor& meso_crystal_form_factor,
            const IMaterial *p_ambient_material,
-           complex_t wavevector_scattering_factor,
-           const Geometry::PTransform3D& transform) const
+           complex_t wavevector_scattering_factor) const
     {
         (void)meso_crystal_form_factor;
         (void)p_ambient_material;
         (void)wavevector_scattering_factor;
-        (void)transform;
         throw NotImplementedException(
                 "IClusteredParticles::createTotalFormFactor() "
                 "-> NotImplementedException");
@@ -80,7 +78,7 @@ public:
                 "-> NotImplementedException");
     }
 
-    //! Sets transformation.
+    //! Sets transformation
     virtual void setTransform(const Geometry::PTransform3D& transform)
     {
         (void)transform;
@@ -89,6 +87,12 @@ public:
                 "-> NotImplementedException");
     }
 
+    //! Gets transformation
+    virtual Geometry::PTransform3D getTransform() const
+    {
+        return Geometry::PTransform3D();
+    }
+
 };
 
 #endif /* ICLUSTEREDNANOPARTICLES_H_ */
diff --git a/Core/Samples/inc/Lattice.h b/Core/Samples/inc/Lattice.h
index f7504dcea3c..7165e6783c8 100644
--- a/Core/Samples/inc/Lattice.h
+++ b/Core/Samples/inc/Lattice.h
@@ -20,6 +20,7 @@
 #include "ISelectionRule.h"
 #include "TRange.h"
 #include "FastVector.h"
+#include "ITransform3D.h"
 
 #include <vector>
 
@@ -33,6 +34,10 @@ public:
     Lattice(const Lattice& lattice);
     ~Lattice();
 
+    //! Create transformed lattice
+    Lattice createTransformedLattice(
+            const Geometry::PTransform3D& transform) const;
+
     //! Initializes cached data
     void initialize() const;
 
diff --git a/Core/Samples/inc/LatticeBasis.h b/Core/Samples/inc/LatticeBasis.h
index 62a2c08a379..8c11d287947 100644
--- a/Core/Samples/inc/LatticeBasis.h
+++ b/Core/Samples/inc/LatticeBasis.h
@@ -32,6 +32,9 @@ public:
     //! Returns a clone with inverted magnetic fields
     virtual LatticeBasis *cloneInvertB() const;
 
+    //! Creates a transformed version of itself
+    LatticeBasis *createTransformed() const;
+
     //! Calls the ISampleVisitor's visit method
     virtual void accept(ISampleVisitor *p_visitor) const {
         p_visitor->visit(this);
diff --git a/Core/Samples/src/Crystal.cpp b/Core/Samples/src/Crystal.cpp
index 70f929ee722..8898dc7d686 100644
--- a/Core/Samples/src/Crystal.cpp
+++ b/Core/Samples/src/Crystal.cpp
@@ -52,21 +52,31 @@ Crystal* Crystal::cloneInvertB() const
 IFormFactor* Crystal::createTotalFormFactor(
         const IFormFactor& meso_crystal_form_factor,
         const IMaterial *p_ambient_material,
-        complex_t wavevector_scattering_factor,
-        const Geometry::PTransform3D& P_transform) const
+        complex_t wavevector_scattering_factor) const
 {
     FormFactorCrystal *p_ff_crystal =
         new FormFactorCrystal(*this, meso_crystal_form_factor,
                 p_ambient_material, wavevector_scattering_factor);
-    if (P_transform.get()) {
-        p_ff_crystal->setTransformation(P_transform);
-    }
     if (m_dw_factor>0.0) {
         return new FormFactorDecoratorDebyeWaller(p_ff_crystal, m_dw_factor);
     }
     return p_ff_crystal;
 }
 
+Lattice Crystal::getTransformedLattice() const
+{
+    if (mP_transform.get()) {
+        return m_lattice.createTransformedLattice(mP_transform);
+    } else {
+        return m_lattice;
+    }
+}
+
+LatticeBasis* Crystal::createTransformedBasis() const
+{
+    return mp_lattice_basis->createTransformed();
+}
+
 std::vector<DiffuseParticleInfo*>* Crystal::createDiffuseParticleInfo(
         const ParticleInfo& parent_info) const
 {
@@ -95,6 +105,12 @@ std::vector<DiffuseParticleInfo*>* Crystal::createDiffuseParticleInfo(
     return p_result;
 }
 
+void Crystal::setTransform(const Geometry::PTransform3D& transform)
+{
+    mp_lattice_basis->setTransform(transform);
+    mP_transform = transform;
+}
+
 Crystal::Crystal(LatticeBasis* p_lattice_basis, const Lattice& lattice)
 : m_lattice(lattice)
 , m_dw_factor(0.0)
@@ -104,7 +120,3 @@ Crystal::Crystal(LatticeBasis* p_lattice_basis, const Lattice& lattice)
     registerChild(mp_lattice_basis);
 }
 
-void Crystal::setTransform(const Geometry::PTransform3D& transform)
-{
-    mp_lattice_basis->setTransform(transform);
-}
diff --git a/Core/Samples/src/Lattice.cpp b/Core/Samples/src/Lattice.cpp
index 280f09146d2..434222116c5 100644
--- a/Core/Samples/src/Lattice.cpp
+++ b/Core/Samples/src/Lattice.cpp
@@ -55,6 +55,15 @@ Lattice::~Lattice()
     delete mp_selection_rule;
 }
 
+Lattice Lattice::createTransformedLattice(
+        const Geometry::PTransform3D& transform) const
+{
+    kvector_t a1 = transform->transformed(m_a1);
+    kvector_t a2 = transform->transformed(m_a2);
+    kvector_t a3 = transform->transformed(m_a3);
+    return Lattice(a1, a2, a3);
+}
+
 void Lattice::initialize() const
 {
     computeReciprocalVectors();
@@ -234,4 +243,3 @@ void Lattice::computeInverseVectors(const kvector_t& v1, const kvector_t& v2,
     gsl_matrix_free(p_inverseMatrix);
 }
 
-
diff --git a/Core/Samples/src/LatticeBasis.cpp b/Core/Samples/src/LatticeBasis.cpp
index 4f72fb60450..6cc4ea07cf8 100644
--- a/Core/Samples/src/LatticeBasis.cpp
+++ b/Core/Samples/src/LatticeBasis.cpp
@@ -73,6 +73,27 @@ LatticeBasis* LatticeBasis::cloneInvertB() const
     return p_new;
 }
 
+LatticeBasis* LatticeBasis::createTransformed() const
+{
+    if (!mP_transform.get()) {
+        return clone();
+    }
+    LatticeBasis *p_new = new LatticeBasis();
+    std::vector<kvector_t> new_positions;
+    for (size_t index=0; index<m_particles.size(); ++index) {
+        new_positions.clear();
+        for (std::vector<kvector_t>::const_iterator it =
+                m_positions_vector[index].begin();
+                it !=m_positions_vector[index].end(); ++it) {
+            new_positions.push_back(mP_transform->transformed(*it));
+        }
+        p_new->addParticle(*m_particles[index], new_positions);
+    }
+    p_new->setName(getName());
+    p_new->setAmbientMaterial(this->mp_ambient_material);
+    return p_new;
+}
+
 void LatticeBasis::addParticle(const Particle& particle,
         std::vector<kvector_t > positions)
 {
@@ -140,3 +161,4 @@ void LatticeBasis::addParticlePointer(Particle* p_particle,
     m_particles.push_back(p_particle);
     m_positions_vector.push_back(positions);
 }
+
diff --git a/Core/Samples/src/MesoCrystal.cpp b/Core/Samples/src/MesoCrystal.cpp
index 17384aa802a..4a178ffeaeb 100644
--- a/Core/Samples/src/MesoCrystal.cpp
+++ b/Core/Samples/src/MesoCrystal.cpp
@@ -72,7 +72,7 @@ IFormFactor* MesoCrystal::createFormFactor(
 {
     return mp_particle_structure->createTotalFormFactor(
             *mp_meso_form_factor, mp_ambient_material,
-            wavevector_scattering_factor, mP_transform);
+            wavevector_scattering_factor);
 }
 
 void MesoCrystal::setTransform(const Geometry::PTransform3D& transform)
-- 
GitLab