From 060d7ea5f618647d99ee04588c053d4230d31243 Mon Sep 17 00:00:00 2001
From: Mikhail Svechnikov <m.svechnikov@fz-juelich.de>
Date: Mon, 12 Aug 2024 10:31:48 +0200
Subject: [PATCH] export to script

---
 Sample/Interface/AutocorrelationModels.cpp  |  2 +-
 Sample/Interface/AutocorrelationModels.h    |  2 +-
 Sample/Interface/CrosscorrelationModels.cpp |  6 +++
 Sample/Interface/CrosscorrelationModels.h   | 10 +++++
 Sim/Export/SampleToPython.cpp               | 46 ++++++++++++++-------
 5 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/Sample/Interface/AutocorrelationModels.cpp b/Sample/Interface/AutocorrelationModels.cpp
index 6c2099bf7ca..a08e233b133 100644
--- a/Sample/Interface/AutocorrelationModels.cpp
+++ b/Sample/Interface/AutocorrelationModels.cpp
@@ -22,7 +22,7 @@ using std::numbers::pi;
 
 //! @param sigma: rms of the roughness in nanometers
 //! @param hurstParameter: hurst parameter which describes how jagged the interface,
-//! dimensionless [0.0, 1.0], where 0.0 gives more spikes, 1.0 more smoothness
+//! dimensionless (0.0, 1.0], where 0.0 gives more spikes, 1.0 more smoothness
 //! @param lateralCorrLength: lateral correlation length of the roughness in nanometers
 K_CorrelationModel::K_CorrelationModel(double sigma, double hurst, double lateralCorrLength)
     : m_sigma(sigma)
diff --git a/Sample/Interface/AutocorrelationModels.h b/Sample/Interface/AutocorrelationModels.h
index 5d87ae7f39d..a0ea5329bcc 100644
--- a/Sample/Interface/AutocorrelationModels.h
+++ b/Sample/Interface/AutocorrelationModels.h
@@ -28,7 +28,7 @@ public:
     virtual double corrFunction(const R3& k) const = 0;
 
 #ifndef SWIG
-    //! Creates the Python constructor of this class
+    //! Used to create the Python constructor of this class
     virtual std::string pythonArguments() const = 0;
 #endif
 };
diff --git a/Sample/Interface/CrosscorrelationModels.cpp b/Sample/Interface/CrosscorrelationModels.cpp
index 0cc65644fa6..0811c074ee6 100644
--- a/Sample/Interface/CrosscorrelationModels.cpp
+++ b/Sample/Interface/CrosscorrelationModels.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "Sample/Interface/CrosscorrelationModels.h"
+#include "Base/Py/PyFmt.h"
 #include <cmath>
 
 FixedDepthCrosscorrelation::FixedDepthCrosscorrelation(double cross_corr_depth)
@@ -36,6 +37,11 @@ std::string FixedDepthCrosscorrelation::validate() const
     return "";
 }
 
+std::string FixedDepthCrosscorrelation::pythonArguments() const
+{
+    return Py::Fmt::printArguments({{m_cross_corr_length, parDefs()[0].unit}});
+}
+
 double FixedDepthCrosscorrelation::replicationFactor(double thickness) const
 {
     if (m_cross_corr_length == 0)
diff --git a/Sample/Interface/CrosscorrelationModels.h b/Sample/Interface/CrosscorrelationModels.h
index ebc5df34dd6..95115adf912 100644
--- a/Sample/Interface/CrosscorrelationModels.h
+++ b/Sample/Interface/CrosscorrelationModels.h
@@ -25,6 +25,11 @@ public:
     CrosscorrelationModel* clone() const override = 0;
     virtual double crossCorrLength(const R3& k) const = 0;
     virtual double replicationFactor(double thickness) const = 0;
+
+#ifndef SWIG
+    //! Used to create the Python constructor of this class
+    virtual std::string pythonArguments() const = 0;
+#endif
 };
 
 //! The crosscorrelation factor depends on the distance between interfaces and does not depend
@@ -37,6 +42,11 @@ public:
     std::string validate() const override;
     double crossCorrLength(const R3&) const override { return m_cross_corr_length; }
     double replicationFactor(double thickness) const override;
+    std::vector<ParaMeta> parDefs() const final { return {{"CrossCorrLength", "nm"}}; }
+
+#ifndef SWIG
+    std::string pythonArguments() const override;
+#endif
 
 private:
     double m_cross_corr_length = 0;
diff --git a/Sim/Export/SampleToPython.cpp b/Sim/Export/SampleToPython.cpp
index a9ab49a0cc0..01f102021ae 100644
--- a/Sim/Export/SampleToPython.cpp
+++ b/Sim/Export/SampleToPython.cpp
@@ -42,7 +42,7 @@
 using Py::Fmt::indent;
 
 static const std::map<int, char> axisChar{{0, 'X'}, {1, 'Y'}, {2, 'Z'}};
-
+#include <iostream>
 namespace {
 
 void setRotationInformation(const IParticle* particle, std::string name, std::ostringstream& result)
@@ -149,12 +149,15 @@ std::string defineLayers(const ComponentKeyHandler& objHandler,
 std::string defineRoughnesses(const ComponentKeyHandler& objHandler)
 {
     std::vector<const LayerRoughness*> roughness = objHandler.objectsOfType<LayerRoughness>();
-    std::vector<const AutocorrelationModel*> autocorr =
+    std::vector<const AutocorrelationModel*> autocorrelation =
         objHandler.objectsOfType<AutocorrelationModel>();
     std::vector<const InterlayerModel*> interlayer = objHandler.objectsOfType<InterlayerModel>();
+    std::vector<const CrosscorrelationModel*> crosscorrelation =
+        objHandler.objectsOfType<CrosscorrelationModel>();
 
     ASSERT(roughness.size() == interlayer.size());
-    ASSERT(roughness.size() == autocorr.size());
+    ASSERT(roughness.size() == autocorrelation.size());
+    ASSERT(roughness.size() >= crosscorrelation.size());
     if (roughness.empty())
         return "";
 
@@ -175,9 +178,9 @@ std::string defineRoughnesses(const ComponentKeyHandler& objHandler)
     for (size_t i = 0; i < roughness.size(); i++) {
         if (!roughness[i]->showInScriptOrGui())
             continue;
-        const std::string& key = objHandler.obj2key(autocorr[i]);
-        result << indent() << key << " = ba." << autocorr[i]->className() << "("
-               << autocorr[i]->pythonArguments() << ")\n";
+        const std::string& key = objHandler.obj2key(autocorrelation[i]);
+        result << indent() << key << " = ba." << autocorrelation[i]->className() << "("
+               << autocorrelation[i]->pythonArguments() << ")\n";
     }
     result << "\n";
     // define interlayers
@@ -188,15 +191,29 @@ std::string defineRoughnesses(const ComponentKeyHandler& objHandler)
         result << indent() << key << " = ba." << interlayer[i]->className() << "()\n";
     }
     result << "\n";
+    // define crosscorrelations
+    if (crosscorrelation.size() > 0) {
+        for (const auto r : roughness) {
+            if (!r->showInScriptOrGui())
+                continue;
+            if (const auto cc = r->crosscorrelationModel())
+                result << indent() << objHandler.obj2key(cc) << " = ba." << cc->className() << "("
+                       << cc->pythonArguments() << ")\n";
+        }
+        result << "\n";
+    }
     // define roughnesses
-    for (size_t i = 0; i < roughness.size(); i++) {
-        if (!roughness[i]->showInScriptOrGui())
+    for (const auto r : roughness) {
+        if (!r->showInScriptOrGui())
             continue;
-        const std::string& roughness_key = objHandler.obj2key(roughness[i]);
-        const std::string& autocorr_key = objHandler.obj2key(autocorr[i]);
-        const std::string& interlayer_key = objHandler.obj2key(interlayer[i]);
-        result << indent() << roughness_key << " = ba." << roughness[i]->className() << "("
-               << autocorr_key << ", " << interlayer_key << ")\n";
+        const std::string& roughness_key = objHandler.obj2key(r);
+        const std::string& autocorr_key = objHandler.obj2key(r->autocorrelationModel());
+        const std::string& interlayer_key = objHandler.obj2key(r->interlayerModel());
+        result << indent() << roughness_key << " = ba." << r->className() << "(" << autocorr_key
+               << ", " << interlayer_key;
+        if (const auto crosscorrelation = r->crosscorrelationModel())
+            result << ", " << objHandler.obj2key(crosscorrelation);
+        result << ")\n";
     }
     return result.str();
 }
@@ -213,7 +230,6 @@ std::string defineFormfactors(const ComponentKeyHandler& objHandler)
         const std::string& key = objHandler.obj2key(s);
         result << indent() << key << " = ba." << s->pythonConstructor() << "\n";
     }
-
     return result.str();
 }
 
@@ -556,6 +572,8 @@ std::string SampleToPython::sampleCode(const MultiLayer& sample)
         objHandler.insertModel("layer", x);
     for (const auto* x : NodeUtil::AllDescendantsOfType<LayerRoughness>(sample))
         objHandler.insertModel("roughness", x);
+    for (const auto* x : NodeUtil::AllDescendantsOfType<CrosscorrelationModel>(sample))
+        objHandler.insertModel("crosscorrelation", x);
     for (const auto* x : NodeUtil::AllDescendantsOfType<InterlayerModel>(sample))
         objHandler.insertModel("interlayer", x);
     for (const auto* x : NodeUtil::AllDescendantsOfType<AutocorrelationModel>(sample))
-- 
GitLab