47 m_label->insertMultiLayer(&multilayer);
51 for (
auto x : INodeUtils::AllDescendantsOfType<Layer>(multilayer))
53 for (
auto x : INodeUtils::AllDescendantsOfType<LayerRoughness>(multilayer))
55 for (
auto x : INodeUtils::AllDescendantsOfType<IFormFactor>(multilayer))
57 for (
auto x : INodeUtils::AllDescendantsOfType<ILayout>(multilayer))
59 for (
auto x : INodeUtils::AllDescendantsOfType<IInterferenceFunction>(multilayer))
60 m_label->insertInterferenceFunction(x);
61 for (
auto x : INodeUtils::AllDescendantsOfType<Particle>(multilayer))
63 for (
auto x : INodeUtils::AllDescendantsOfType<ParticleCoreShell>(multilayer))
64 m_label->insertParticleCoreShell(x);
65 for (
auto x : INodeUtils::AllDescendantsOfType<ParticleComposition>(multilayer))
66 m_label->insertParticleComposition(x);
67 for (
auto x : INodeUtils::AllDescendantsOfType<ParticleDistribution>(multilayer))
68 m_label->insertParticleDistribution(x);
69 for (
auto x : INodeUtils::AllDescendantsOfType<Lattice>(multilayer))
71 for (
auto x : INodeUtils::AllDescendantsOfType<Crystal>(multilayer))
73 for (
auto x : INodeUtils::AllDescendantsOfType<MesoCrystal>(multilayer))
75 for (
auto x : INodeUtils::AllDescendantsOfType<IRotation>(multilayer))
101 return "# No Materials.\n\n";
102 std::ostringstream result;
103 result << std::setprecision(12);
104 result <<
indent() <<
"# Defining Materials\n";
105 std::set<std::string> visitedMaterials;
106 for (
auto it = themap->
begin(); it != themap->
end(); ++it) {
107 if (visitedMaterials.find(it->second) != visitedMaterials.end())
109 visitedMaterials.insert(it->second);
110 const Material* p_material = it->first;
113 throw std::runtime_error(
114 "Error in ExportToPython::defineMaterials(): unknown material type");
117 result <<
indent() <<
m_label->labelMaterial(p_material) <<
" = ba."
118 << factory_name->second <<
"(\"" << p_material->
getName() <<
"\", "
123 result <<
indent() <<
"magnetic_field = kvector_t(" << magnetic_field.
x() <<
", "
124 << magnetic_field.
y() <<
", " << magnetic_field.
z() <<
")\n";
125 result <<
indent() <<
m_label->labelMaterial(p_material) <<
" = ba."
126 << factory_name->second <<
"(\"" << p_material->
getName();
129 <<
"magnetic_field)\n";
137 const auto themap =
m_label->layerMap();
139 return "# No Layers.\n\n";
140 std::ostringstream result;
141 result << std::setprecision(12);
142 result <<
"\n" <<
indent() <<
"# Defining Layers\n";
143 for (
auto it = themap->begin(); it != themap->end(); ++it) {
144 const Layer* layer = it->first;
145 result <<
indent() << it->second <<
" = ba.Layer("
159 const auto themap =
m_label->formFactorMap();
162 std::ostringstream result;
163 result << std::setprecision(12);
164 result <<
"\n" <<
indent() <<
"# Defining Form Factors\n";
165 for (
auto it = themap->begin(); it != themap->end(); ++it) {
167 result <<
indent() << it->second <<
" = ba.FormFactor" << p_ff->
getName() <<
"("
175 const auto themap =
m_label->particleMap();
178 std::ostringstream result;
179 result << std::setprecision(12);
180 result <<
"\n" <<
indent() <<
"# Defining Particles\n";
181 for (
auto it = themap->begin(); it != themap->end(); ++it) {
182 const Particle* p_particle = it->first;
183 std::string particle_name = it->second;
184 auto p_ff = INodeUtils::OnlyChildOfType<IFormFactor>(*p_particle);
187 result <<
indent() << particle_name <<
" = ba.Particle("
189 <<
m_label->labelFormFactor(p_ff) <<
")\n";
198 const auto themap =
m_label->particleCoreShellMap();
201 std::ostringstream result;
202 result << std::setprecision(12);
203 result <<
"\n" <<
indent() <<
"# Defining Core Shell Particles\n";
204 for (
auto it = themap->begin(); it != themap->end(); ++it) {
207 <<
indent() << it->second <<
" = ba.ParticleCoreShell("
210 std::string core_shell_name = it->second;
219 const auto themap =
m_label->particleDistributionsMap();
223 std::ostringstream result;
224 result << std::setprecision(12);
225 result <<
"\n" <<
indent() <<
"# Defining particles with parameter following a distribution\n";
228 for (
auto it = themap->begin(); it != themap->end(); ++it) {
231 const std::string units = p_particle_distr->
mainUnits();
236 std::string s_distr =
"distr_" + std::to_string(index);
237 result <<
indent() << s_distr <<
" = "
241 std::string s_par_distr =
"par_distr_" + std::to_string(index);
243 result <<
indent() << s_par_distr <<
" = "
248 if (!linked_pars.empty()) {
249 result <<
indent() << s_par_distr;
250 for (
size_t i = 0; i < linked_pars.size(); ++i)
251 result <<
".linkParameter(\"" << linked_pars[i] <<
"\")";
255 auto p_particle = INodeUtils::OnlyChildOfType<IParticle>(*p_particle_distr);
258 result <<
indent() << it->second <<
" = ba.ParticleDistribution("
259 <<
m_label->labelParticle(p_particle) <<
", " << s_par_distr <<
")\n";
267 const auto themap =
m_label->particleCompositionMap();
270 std::ostringstream result;
271 result << std::setprecision(12);
272 result <<
"\n" <<
indent() <<
"# Defining composition of particles at specific positions\n";
273 for (
auto it = themap->begin(); it != themap->end(); ++it) {
275 std::string particle_composition_name = it->second;
276 result <<
indent() << particle_composition_name <<
" = ba.ParticleComposition()\n";
277 auto particle_list = INodeUtils::ChildNodesOfType<IParticle>(*p_particle_composition);
278 for (
auto p_particle : particle_list) {
279 result <<
indent() << particle_composition_name <<
".addParticle("
280 <<
m_label->labelParticle(p_particle) <<
")\n";
290 const auto themap =
m_label->latticeMap();
293 std::ostringstream result;
294 result << std::setprecision(12);
295 result <<
"\n" <<
indent() <<
"# Defining 3D lattices\n";
296 for (
auto it = themap->begin(); it != themap->end(); ++it) {
297 const Lattice* p_lattice = it->first;
298 std::string lattice_name = it->second;
302 result <<
indent() << lattice_name <<
" = ba.Lattice(\n";
315 const auto themap =
m_label->crystalMap();
318 std::ostringstream result;
319 result << std::setprecision(12);
320 result <<
"\n" <<
indent() <<
"# Defining crystals: basis particle + lattice\n";
321 for (
auto it = themap->begin(); it != themap->end(); ++it) {
322 const Crystal* p_crystal = it->first;
323 std::string crystal_name = it->second;
324 auto p_lattice = INodeUtils::OnlyChildOfType<Lattice>(*p_crystal);
325 auto p_basis = INodeUtils::OnlyChildOfType<IParticle>(*p_crystal);
326 if (!p_lattice || !p_basis)
328 result <<
indent() << crystal_name <<
" = ba.Crystal(";
329 result <<
m_label->labelParticle(p_basis) <<
", ";
330 result <<
m_label->labelLattice(p_lattice) <<
")\n";
337 const auto themap =
m_label->mesocrystalMap();
340 std::ostringstream result;
341 result << std::setprecision(12);
342 result <<
"\n" <<
indent() <<
"# Defining mesocrystals\n";
343 for (
auto it = themap->begin(); it != themap->end(); ++it) {
345 std::string mesocrystal_name = it->second;
346 auto p_crystal = INodeUtils::OnlyChildOfType<Crystal>(*p_mesocrystal);
347 auto p_outer_shape = INodeUtils::OnlyChildOfType<IFormFactor>(*p_mesocrystal);
348 if (!p_crystal || !p_outer_shape)
350 result <<
indent() << mesocrystal_name <<
" = ba.MesoCrystal(";
351 result <<
m_label->labelCrystal(p_crystal) <<
", ";
352 result <<
m_label->labelFormFactor(p_outer_shape) <<
")\n";
361 const auto themap =
m_label->interferenceFunctionMap();
364 std::ostringstream result;
365 result << std::setprecision(12);
366 result <<
"\n" <<
indent() <<
"# Defining Interference Functions\n";
367 for (
auto it = themap->begin(); it != themap->end(); ++it) {
371 result <<
indent() << it->second <<
" = ba.InterferenceFunctionNone()\n";
372 else if (
auto p_lattice_1d =
374 result <<
indent() << it->second <<
" = ba.InterferenceFunction1DLattice("
378 auto pdf = INodeUtils::OnlyChildOfType<IFTDecayFunction1D>(*p_lattice_1d);
380 if (pdf->decayLength() != 0.0)
381 result <<
indent() << it->second <<
"_pdf = ba." << pdf->getName() <<
"("
383 <<
indent() << it->second <<
".setDecayFunction(" << it->second <<
"_pdf)\n";
384 }
else if (
auto p_para_radial =
386 result <<
indent() << it->second <<
" = ba.InterferenceFunctionRadialParaCrystal("
390 if (p_para_radial->kappa() != 0.0)
391 result <<
indent() << it->second <<
".setKappa("
394 if (p_para_radial->domainSize() != 0.0)
395 result <<
indent() << it->second <<
".setDomainSize("
398 auto pdf = INodeUtils::OnlyChildOfType<IFTDistribution1D>(*p_para_radial);
400 if (pdf->omega() != 0.0)
401 result <<
indent() << it->second <<
"_pdf = ba." << pdf->getName() <<
"("
403 <<
indent() << it->second <<
".setProbabilityDistribution(" << it->second
405 }
else if (
auto p_lattice_2d =
407 const Lattice2D& lattice = p_lattice_2d->lattice();
408 result <<
indent() << it->second <<
" = ba.InterferenceFunction2DLattice("
413 auto pdf = INodeUtils::OnlyChildOfType<IFTDecayFunction2D>(*p_lattice_2d);
415 result <<
indent() << it->second <<
"_pdf = ba." << pdf->getName() <<
"("
417 <<
indent() << it->second <<
".setDecayFunction(" << it->second <<
"_pdf)\n";
419 if (p_lattice_2d->integrationOverXi() ==
true)
420 result <<
indent() << it->second <<
".setIntegrationOverXi(True)\n";
421 }
else if (
auto p_lattice_2d =
423 const Lattice2D& lattice = p_lattice_2d->lattice();
424 result <<
indent() << it->second <<
" = ba.InterferenceFunctionFinite2DLattice("
428 << p_lattice_2d->numberUnitCells1() <<
", " << p_lattice_2d->numberUnitCells2()
431 if (p_lattice_2d->integrationOverXi() ==
true)
432 result <<
indent() << it->second <<
".setIntegrationOverXi(True)\n";
433 }
else if (
auto p_para_2d =
435 std::vector<double> domainSize = p_para_2d->domainSizes();
436 const Lattice2D& lattice = p_para_2d->lattice();
437 result <<
indent() << it->second <<
" = ba.InterferenceFunction2DParaCrystal("
443 if (domainSize[0] != 0.0 || domainSize[1] != 0.0)
444 result <<
indent() << it->second <<
".setDomainSizes("
447 if (p_para_2d->integrationOverXi() ==
true)
448 result <<
indent() << it->second <<
".setIntegrationOverXi(True)\n";
450 auto pdf_vector = INodeUtils::ChildNodesOfType<IFTDistribution2D>(*p_para_2d);
451 if (pdf_vector.size() != 2)
455 result <<
indent() << it->second <<
"_pdf_1 = ba." << pdf->
getName() <<
"("
460 result <<
indent() << it->second <<
"_pdf_2 = ba." << pdf->
getName() <<
"("
462 result <<
indent() << it->second <<
".setProbabilityDistributions(" << it->second
463 <<
"_pdf_1, " << it->second <<
"_pdf_2)\n";
464 }
else if (
auto p_lattice_hd =
466 result <<
indent() << it->second <<
" = ba.InterferenceFunctionHardDisk("
471 "Bug: ExportToPython::defineInterferenceFunctions() called with unexpected "
472 "IInterferenceFunction "
475 result <<
indent() << it->second <<
".setPositionVariance("
484 const auto themap =
m_label->particleLayoutMap();
487 std::ostringstream result;
488 result << std::setprecision(12);
489 result <<
"\n" <<
indent() <<
"# Defining Particle Layouts and adding Particles\n";
490 for (
auto it = themap->begin(); it != themap->end(); ++it) {
491 const ILayout* iLayout = it->first;
493 result <<
indent() << it->second <<
" = ba.ParticleLayout()\n";
494 auto particles = INodeUtils::ChildNodesOfType<IAbstractParticle>(*particleLayout);
496 for (
auto p_particle : particles) {
497 double abundance = p_particle->abundance();
498 result <<
indent() << it->second <<
".addParticle("
499 <<
m_label->labelParticle(p_particle) <<
", "
502 if (
auto p_iff = INodeUtils::OnlyChildOfType<IInterferenceFunction>(*particleLayout))
503 result <<
indent() << it->second <<
".setInterferenceFunction("
504 <<
m_label->labelInterferenceFunction(p_iff) <<
")\n";
505 result <<
indent() << it->second <<
".setWeight(" << particleLayout->weight() <<
")\n";
506 result <<
indent() << it->second <<
".setTotalParticleSurfaceDensity("
507 << particleLayout->totalParticleSurfaceDensity() <<
")\n";
515 const auto themap =
m_label->layerRoughnessMap();
518 std::ostringstream result;
519 result << std::setprecision(12);
520 result <<
"\n" <<
indent() <<
"# Defining Roughness Parameters\n";
521 for (
auto it = themap->begin(); it != themap->end(); ++it)
522 result <<
indent() << it->second <<
" = ba.LayerRoughness("
529 if (
m_label->particleLayoutMap()->empty())
531 std::ostringstream result;
532 result << std::setprecision(12);
533 result <<
"\n" <<
indent() <<
"# Adding layouts to layers";
534 const auto layermap =
m_label->layerMap();
535 for (
auto it = layermap->begin(); it != layermap->end(); ++it) {
536 const Layer* layer = it->first;
537 for (
auto p_layout : layer->
layouts())
539 <<
indent() << it->second <<
".addLayout(" <<
m_label->labelLayout(p_layout)
547 const auto themap =
m_label->multiLayerMap();
549 return "# No MultiLayers.\n\n";
550 std::ostringstream result;
551 result << std::setprecision(12);
552 result <<
"\n" <<
indent() <<
"# Defining Multilayers\n";
553 for (
auto it = themap->begin(); it != themap->end(); ++it) {
554 result <<
indent() << it->second <<
" = ba.MultiLayer()\n";
555 double ccl = it->first->crossCorrLength();
557 result <<
indent() << it->second <<
".setCrossCorrLength(" << ccl <<
")\n";
558 auto external_field = it->first->externalField();
559 if (external_field.mag() > 0.0) {
560 std::string field_name = it->second +
"_external_field";
561 result <<
indent() << field_name <<
" = kvector_t("
565 result <<
indent() << it->second <<
".setExternalField(" << field_name <<
")\n";
567 size_t numberOfLayers = it->first->numberOfLayers();
568 if (numberOfLayers) {
569 result <<
indent() << it->second <<
".addLayer("
570 <<
m_label->labelLayer(it->first->layer(0)) <<
")\n";
572 size_t layerIndex = 1;
573 while (layerIndex != numberOfLayers) {
574 const LayerInterface* layerInterface = it->first->layerInterface(layerIndex - 1);
576 ==
m_label->layerRoughnessMap()->end())
577 result <<
indent() << it->second <<
".addLayer("
578 <<
m_label->labelLayer(it->first->layer(layerIndex)) <<
")\n";
580 result <<
indent() << it->second <<
".addLayerWithTopRoughness("
581 <<
m_label->labelLayer(it->first->layer(layerIndex)) <<
", "
586 result <<
indent() <<
"return " << it->second <<
"\n";
597 std::ostringstream& result)
const
602 double alpha, beta, gamma;
604 result <<
indent() << name <<
"_rotation = ba.RotationEuler("
628 result <<
indent() << name <<
".setRotation(" << name <<
"_rotation)\n";
633 std::ostringstream& result)
const
636 bool has_position_info = (pos !=
kvector_t());
638 if (has_position_info) {
642 result <<
indent() << name <<
".setPosition(" << name <<
"_position)\n";
std::complex< double > complex_t
Defines namespace INodeUtils.
Includes all interference function definitions.
Defines class LayerInterface.
Defines class LayerRoughness.
Defines class MesoCrystal.
Defines class MultiLayer.
Defines namespace ParameterUtils.
Defines class ParticleComposition.
Defines ParticleCoreShell.
Defines class ParticleDistribution.
Defines class ParticleLayout.
Defines namespace pyfmt2.
Defines functions in namespace pyfmt.
Defines classes LabelMap and SampleLabelHandler.
const std::map< MATERIAL_TYPES, std::string > factory_names
Defines class SampleToPython.
BasicVector3D< double > kvector_t
T z() const
Returns z-component in cartesian coordinate system.
T y() const
Returns y-component in cartesian coordinate system.
T x() const
Returns x-component in cartesian coordinate system.
A crystal structure with a ParticleComposition as a basis.
Interface for two-dimensional distributions in Fourier space.
Pure virtual base class of interference functions.
double positionVariance() const
Returns the position variance.
Pure virtual interface class to equip a sample layer with scattering properties.
const std::string & getName() const
Pure virtual base class for Particle, ParticleComposition, ParticleCoreShell, MesoCrystal.
kvector_t position() const
Returns particle position.
const IRotation * rotation() const
Returns rotation object.
virtual Transform3D getTransform3D() const =0
Returns transformation.
std::vector< const Material * > containedMaterials() const
Returns set of unique materials contained in this ISample.
Interference function of a 1D lattice.
Interference function of a 2D lattice.
Interference function of a 2D paracrystal.
Interference function of a finite 2D lattice.
Percus-Yevick hard disk interference function.
Default interference function (i.e.
Interference function of radial paracrystal.
double rotationAngle() const
virtual double latticeAngle() const =0
virtual double length2() const =0
virtual double length1() const =0
A lattice with three basis vectors.
kvector_t getBasisVectorB() const
Returns basis vector b.
kvector_t getBasisVectorC() const
Returns basis vector c.
kvector_t getBasisVectorA() const
Returns basis vector a.
Interface between two layers, possibly with roughness.
const LayerRoughness * getRoughness() const
Returns roughness of the interface.
A layer, with thickness (in nanometer) and material.
const Material * material() const override final
Returns nullptr, unless overwritten to return a specific material.
unsigned int numberOfSlices() const
std::vector< const ILayout * > layouts() const
A wrapper for underlying material implementation.
kvector_t magnetization() const
Get the magnetization (in A/m)
bool isScalarMaterial() const
Indicates whether the interaction with the material is scalar.
std::string getName() const
Returns the name of material.
MATERIAL_TYPES typeID() const
Returns the type of underlying material implementation.
complex_t materialData() const
Returns underlying material data.
A particle with an internal structure of smaller particles.
Our sample model: a stack of layers one below the other.
const_iterator end() const
const_iterator begin() const
A parametric distribution function, for use with any model parameter.
const IDistribution1D * getDistribution() const
std::vector< std::string > getLinkedParameterNames() const
get list of linked parameter names
A composition of particles at fixed positions.
A particle with a core/shell geometry.
const Particle * shellParticle() const
const Particle * coreParticle() const
A particle type that is a parametric distribution of IParticle's.
ParameterDistribution parameterDistribution() const
Returns the distributed parameter data.
std::string mainUnits() const
Decorator class that adds particles to ISample objects.
A particle with a form factor and refractive index.
const Material * material() const override final
Returns nullptr, unless overwritten to return a specific material.
The handler which construct labels for sample variables during python script generation.
std::string defineLayers() const
std::string defineGetSample() const
std::string defineFormFactors() const
std::string generateSampleCode(const MultiLayer &multilayer)
std::string defineMaterials() const
std::string defineMesoCrystals() const
void initLabels(const MultiLayer &multilayer)
std::string defineCrystals() const
std::unique_ptr< SampleLabelHandler > m_label
std::string defineParticles() const
std::string defineParticleCompositions() const
std::string indent() const
std::string defineParticleDistributions() const
std::string addLayoutsToLayers() const
std::string defineParticleLayouts() const
void setRotationInformation(const IParticle *particle, std::string particle_name, std::ostringstream &result) const
void setPositionInformation(const IParticle *particle, std::string particle_name, std::ostringstream &result) const
std::string defineLattices() const
std::string defineCoreShellParticles() const
std::string defineInterferenceFunctions() const
std::string defineMultiLayers() const
std::string defineRoughnesses() const
std::string printParameterDistribution(const ParameterDistribution &par_distr, const std::string &distVarName, const std::string &units)
std::string argumentList(const IParameterized *ip)
Returns comma-separated list of parameter values, including unit multiplicator (like "* nm").
std::string printDistribution(const IDistribution1D &par_distr, const std::string &units)
Prints distribution with constructor parameters in given units.
std::string printNm(double input)
std::string getSampleFunctionName()
std::string printNm2(double input)
std::string printDegrees(double input)
std::string printDouble(double input)
std::string printScientificDouble(double input)