BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
SampleToPython Class Reference

Description

Generates Python code snippet from domain (C++) objects representing sample construction.

Definition at line 33 of file SampleToPython.h.

Collaboration diagram for SampleToPython:
[legend]

Public Member Functions

 SampleToPython ()
 
 ~SampleToPython ()
 
std::string sampleCode (const MultiLayer &sample)
 

Private Member Functions

std::string defineCoreShellParticles () const
 
std::string defineCrystals () const
 
std::string defineFormFactors () const
 
std::string defineGetSample () const
 
std::string defineInterferences () const
 
std::string defineLattices2D () const
 
std::string defineLattices3D () const
 
std::string defineLayers () const
 
std::string defineMaterials () const
 
std::string defineMesoCrystals () const
 
std::string defineMultiLayers () const
 
std::string defineParticleCompositions () const
 
std::string defineParticleLayouts () const
 
std::string defineParticles () const
 
std::string defineRoughnesses () const
 
void initLabels (const MultiLayer &sample)
 

Private Attributes

std::unique_ptr< MaterialKeyHandlerm_materials
 
std::unique_ptr< ComponentKeyHandlerm_objs
 

Constructor & Destructor Documentation

◆ SampleToPython()

SampleToPython::SampleToPython ( )
default

◆ ~SampleToPython()

SampleToPython::~SampleToPython ( )
default

Member Function Documentation

◆ defineCoreShellParticles()

std::string SampleToPython::defineCoreShellParticles ( ) const
private

Definition at line 388 of file SampleToPython.cpp.

389 {
390  std::vector<const ParticleCoreShell*> v = m_objs->objectsOfType<ParticleCoreShell>();
391  if (v.empty())
392  return "";
393  std::ostringstream result;
394  result << std::setprecision(12);
395  result << "\n" << indent() << "# Define core shell particles\n";
396  for (const auto* s : v) {
397  const std::string& key = m_objs->obj2key(s);
398  result << indent() << key << " = ba.ParticleCoreShell("
399  << m_objs->obj2key(s->shellParticle()) << ", " << m_objs->obj2key(s->coreParticle())
400  << ")\n";
401  setRotationInformation(s, key, result);
402  setPositionInformation(s, key, result);
403  }
404  return result.str();
405 }
A particle with a core/shell geometry.
std::unique_ptr< ComponentKeyHandler > m_objs
std::string indent(size_t width)
Returns a string of blanks with given width. By default the width equals standard offset in python fi...
Definition: PyFmt.cpp:203

References Py::Fmt::indent(), and m_objs.

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineCrystals()

std::string SampleToPython::defineCrystals ( ) const
private

Definition at line 492 of file SampleToPython.cpp.

493 {
494  std::vector<const Crystal*> v = m_objs->objectsOfType<Crystal>();
495  if (v.empty())
496  return "";
497  std::ostringstream result;
498  result << std::setprecision(12);
499  result << "\n" << indent() << "# Define crystals\n";
500  for (const auto* s : v) {
501  const std::string& key = m_objs->obj2key(s);
502  const auto* lattice = NodeUtils::OnlyChildOfType<Lattice3D>(*s);
503  const auto* basis = NodeUtils::OnlyChildOfType<IParticle>(*s);
504  if (!lattice || !basis)
505  continue;
506  result << indent() << key << " = ba.Crystal(";
507  result << m_objs->obj2key(basis) << ", ";
508  result << m_objs->obj2key(lattice) << ")\n";
509  }
510  return result.str();
511 }
A crystal structure, defined by a Bravais lattice, a basis, and a position variance.
Definition: Crystal.h:34

References Py::Fmt::indent(), and m_objs.

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineFormFactors()

std::string SampleToPython::defineFormFactors ( ) const
private

Definition at line 223 of file SampleToPython.cpp.

224 {
225  std::vector<const IFormFactor*> formfactors = m_objs->objectsOfType<IFormFactor>();
226  if (formfactors.empty())
227  return "";
228  std::ostringstream result;
229  result << "\n" << indent() << "# Define form factors\n";
230  result << std::setprecision(12);
231  for (const auto* s : formfactors) {
232  const std::string& key = m_objs->obj2key(s);
233  result << indent() << key << " = ba." << s->pythonConstructor() << "\n";
234  }
235 
236  return result.str();
237 }
Abstract base class for Born form factors.
Definition: IFormFactor.h:36

References Py::Fmt::indent(), and m_objs.

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineGetSample()

std::string SampleToPython::defineGetSample ( ) const
private

Definition at line 134 of file SampleToPython.cpp.

135 {
136  return "def get_sample():\n" + defineMaterials() + defineFormFactors() + defineParticles()
140  + "\n\n";
141 }
std::string defineLayers() const
std::string defineFormFactors() const
std::string defineMaterials() const
std::string defineLattices3D() const
std::string defineMesoCrystals() const
std::string defineCrystals() const
std::string defineParticles() const
std::string defineParticleCompositions() const
std::string defineLattices2D() const
std::string defineInterferences() const
std::string defineParticleLayouts() const
std::string defineCoreShellParticles() const
std::string defineMultiLayers() const
std::string defineRoughnesses() const

References defineCoreShellParticles(), defineCrystals(), defineFormFactors(), defineInterferences(), defineLattices2D(), defineLattices3D(), defineLayers(), defineMaterials(), defineMesoCrystals(), defineMultiLayers(), defineParticleCompositions(), defineParticleLayouts(), defineParticles(), and defineRoughnesses().

Referenced by sampleCode().

Here is the call graph for this function:

◆ defineInterferences()

std::string SampleToPython::defineInterferences ( ) const
private

Definition at line 239 of file SampleToPython.cpp.

240 {
241  std::vector<const IInterference*> v = m_objs->objectsOfType<IInterference>();
242  if (v.empty())
243  return "";
244  std::ostringstream result;
245  result << std::setprecision(12);
246  result << "\n" << indent() << "# Define interference functions\n";
247  for (const auto* s : v) {
248  const std::string& key = m_objs->obj2key(s);
249 
250  if (dynamic_cast<const InterferenceNone*>(s))
251  result << indent() << key << " = ba.InterferenceNone()\n";
252 
253  else if (const auto* iff = dynamic_cast<const Interference1DLattice*>(s)) {
254  result << indent() << key << " = ba.Interference1DLattice("
255  << Py::Fmt::printNm(iff->length()) << ", " << Py::Fmt::printDegrees(iff->xi())
256  << ")\n";
257 
258  const auto* pdf = NodeUtils::OnlyChildOfType<IProfile1D>(*iff);
259 
260  if (pdf->decayLength() != 0.0)
261  result << indent() << key << "_pdf = ba." << pdf->pythonConstructor() << "\n"
262  << indent() << key << ".setDecayFunction(" << key << "_pdf)\n";
263  } else if (const auto* iff = dynamic_cast<const InterferenceRadialParaCrystal*>(s)) {
264  result << indent() << key << " = ba.InterferenceRadialParaCrystal("
265  << Py::Fmt::printNm(iff->peakDistance()) << ", "
266  << Py::Fmt::printNm(iff->dampingLength()) << ")\n";
267 
268  if (iff->kappa() != 0.0)
269  result << indent() << key << ".setKappa(" << Py::Fmt::printDouble(iff->kappa())
270  << ")\n";
271 
272  if (iff->domainSize() != 0.0)
273  result << indent() << key << ".setDomainSize("
274  << Py::Fmt::printDouble(iff->domainSize()) << ")\n";
275 
276  const auto* pdf = NodeUtils::OnlyChildOfType<IProfile1D>(*iff);
277 
278  if (pdf->omega() != 0.0)
279  result << indent() << key << "_pdf = ba." << pdf->pythonConstructor() << "\n"
280  << indent() << key << ".setProbabilityDistribution(" << key << "_pdf)\n";
281  } else if (const auto* iff = dynamic_cast<const Interference2DLattice*>(s)) {
282  const auto* lattice = NodeUtils::OnlyChildOfType<Lattice2D>(*iff);
283 
284  result << indent() << key << " = ba.Interference2DLattice(" << m_objs->obj2key(lattice)
285  << ")\n";
286 
287  const auto* pdf = NodeUtils::OnlyChildOfType<IProfile2D>(*iff);
288 
289  result << indent() << key << "_pdf = ba." << pdf->pythonConstructor() << "\n"
290  << indent() << key << ".setDecayFunction(" << key << "_pdf)\n";
291 
292  if (iff->integrationOverXi())
293  result << indent() << key << ".setIntegrationOverXi(True)\n";
294  } else if (const auto* iff = dynamic_cast<const InterferenceFinite2DLattice*>(s)) {
295  const auto* lattice = NodeUtils::OnlyChildOfType<Lattice2D>(*iff);
296 
297  result << indent() << key << " = ba.InterferenceFinite2DLattice("
298  << m_objs->obj2key(lattice) << ", " << iff->numberUnitCells1() << ", "
299  << iff->numberUnitCells2() << ")\n";
300 
301  if (iff->integrationOverXi())
302  result << indent() << key << ".setIntegrationOverXi(True)\n";
303  } else if (const auto* iff = dynamic_cast<const Interference2DParaCrystal*>(s)) {
304  const auto* lattice = NodeUtils::OnlyChildOfType<Lattice2D>(*iff);
305  std::vector<double> domainSize = iff->domainSizes();
306 
307  result << indent() << key << " = ba.Interference2DParaCrystal("
308  << m_objs->obj2key(lattice) << ", " << Py::Fmt::printNm(iff->dampingLength())
309  << ", " << Py::Fmt::printNm(domainSize[0]) << ", "
310  << Py::Fmt::printNm(domainSize[1]) << ")\n";
311 
312  if (iff->integrationOverXi())
313  result << indent() << key << ".setIntegrationOverXi(True)\n";
314 
315  const auto pdf_vector = NodeUtils::ChildNodesOfType<IProfile2D>(*iff);
316  if (pdf_vector.size() != 2)
317  continue;
318  const IProfile2D* pdf = pdf_vector[0];
319 
320  result << indent() << key << "_pdf_1 = ba." << pdf->pythonConstructor() << "\n";
321 
322  pdf = pdf_vector[1];
323 
324  result << indent() << key << "_pdf_2 = ba." << pdf->pythonConstructor() << "\n";
325  result << indent() << key << ".setProbabilityDistributions(" << key << "_pdf_1, " << key
326  << "_pdf_2)\n";
327  } else if (const auto* lattice_hd = dynamic_cast<const InterferenceHardDisk*>(s)) {
328  result << indent() << key << " = ba.InterferenceHardDisk("
329  << Py::Fmt::printNm(lattice_hd->radius()) << ", "
330  << Py::Fmt::printDouble(lattice_hd->density()) << ")\n";
331  } else
332  ASSERT(0);
333 
334  if (s->positionVariance() > 0.0) {
335  result << indent() << key << ".setPositionVariance("
336  << Py::Fmt::printNm2(s->positionVariance()) << ")\n";
337  }
338  }
339  return result.str();
340 }
#define ASSERT(condition)
Definition: Assert.h:45
Abstract base class of interference functions.
Definition: IInterference.h:24
Interface for two-dimensional distributions in Fourier space.
Definition: Profiles2D.h:29
virtual std::string pythonConstructor() const
Creates the Python constructor of this class (or derived classes)
Definition: Profiles2D.cpp:34
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. absence of any interference).
Interference function of radial paracrystal.
std::string printDegrees(double input)
Definition: PyFmt.cpp:116
std::string printDouble(double input)
Definition: PyFmt.cpp:46
std::string printNm(double input)
Definition: PyFmt.cpp:79
std::string printNm2(double input)
Definition: PyFmt.cpp:87

References ASSERT, Py::Fmt::indent(), m_objs, Py::Fmt::printDegrees(), Py::Fmt::printDouble(), Py::Fmt::printNm(), Py::Fmt::printNm2(), and IProfile2D::pythonConstructor().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineLattices2D()

std::string SampleToPython::defineLattices2D ( ) const
private

Definition at line 450 of file SampleToPython.cpp.

451 {
452  std::vector<const Lattice2D*> v = m_objs->objectsOfType<Lattice2D>();
453  if (v.empty())
454  return "";
455  std::ostringstream result;
456  result << std::setprecision(12);
457  result << "\n" << indent() << "# Define 2D lattices\n";
458  for (const auto* s : v) {
459  const std::string& key = m_objs->obj2key(s);
460  result << indent() << key << " = ba.BasicLattice2D(\n";
461  result << indent() << indent() << Py::Fmt::printNm(s->length1()) << ", "
462  << Py::Fmt::printNm(s->length2()) << ", " << Py::Fmt::printDegrees(s->latticeAngle())
463  << ", " << Py::Fmt::printDegrees(s->rotationAngle()) << ")\n";
464  }
465  return result.str();
466 }
A two-dimensional Bravais lattice.
Definition: Lattice2D.h:23

References Py::Fmt::indent(), m_objs, Py::Fmt::printDegrees(), and Py::Fmt::printNm().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineLattices3D()

std::string SampleToPython::defineLattices3D ( ) const
private

Definition at line 468 of file SampleToPython.cpp.

469 {
470  std::vector<const Lattice3D*> v = m_objs->objectsOfType<Lattice3D>();
471  if (v.empty())
472  return "";
473  std::ostringstream result;
474  result << std::setprecision(12);
475  result << "\n" << indent() << "# Define 3D lattices\n";
476  for (const auto* s : v) {
477  const std::string& key = m_objs->obj2key(s);
478  R3 bas_a = s->basisVectorA();
479  R3 bas_b = s->basisVectorB();
480  R3 bas_c = s->basisVectorC();
481  result << indent() << key << " = ba.Lattice3D(\n";
482  result << indent() << indent() << "ba.R3(" << Py::Fmt::printNm(bas_a.x()) << ", "
483  << Py::Fmt::printNm(bas_a.y()) << ", " << Py::Fmt::printNm(bas_a.z()) << "),\n";
484  result << indent() << indent() << "ba.R3(" << Py::Fmt::printNm(bas_b.x()) << ", "
485  << Py::Fmt::printNm(bas_b.y()) << ", " << Py::Fmt::printNm(bas_b.z()) << "),\n";
486  result << indent() << indent() << "ba.R3(" << Py::Fmt::printNm(bas_c.x()) << ", "
487  << Py::Fmt::printNm(bas_c.y()) << ", " << Py::Fmt::printNm(bas_c.z()) << "))\n";
488  }
489  return result.str();
490 }
A Bravais lattice, characterized by three basis vectors, and optionally an ISelectionRule.
Definition: Lattice3D.h:30

References Py::Fmt::indent(), m_objs, and Py::Fmt::printNm().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineLayers()

std::string SampleToPython::defineLayers ( ) const
private

Definition at line 186 of file SampleToPython.cpp.

187 {
188  std::vector<const Layer*> v = m_objs->objectsOfType<Layer>();
189  if (v.empty())
190  return "";
191  std::ostringstream result;
192  result << "\n" << indent() << "# Define layers\n";
193  result << std::setprecision(12);
194  for (const auto* s : v) {
195  const std::string& key = m_objs->obj2key(s);
196  result << indent() << key << " = ba.Layer(" << m_materials->mat2key(s->material());
197  if (s->thickness() != 0)
198  result << ", " << Py::Fmt::printNm(s->thickness());
199  result << ")\n";
200  if (s->numberOfSlices() != 1)
201  result << indent() << key << ".setNumberOfSlices(" << s->numberOfSlices() << ")\n";
202  for (const auto* layout : s->layouts())
203  result << indent() << key << ".addLayout(" << m_objs->obj2key(layout) << ")\n";
204  }
205  return result.str();
206 }
A layer in a MultiLayer sample.
Definition: Layer.h:26
std::unique_ptr< MaterialKeyHandler > m_materials

References Py::Fmt::indent(), m_materials, m_objs, and Py::Fmt::printNm().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineMaterials()

std::string SampleToPython::defineMaterials ( ) const
private

Definition at line 147 of file SampleToPython.cpp.

148 {
149  const auto themap = m_materials->materialMap();
150  if (themap.empty())
151  return "";
152  std::ostringstream result;
153  result << std::setprecision(12);
154  result << indent() << "# Define materials\n";
155  std::set<std::string> visitedMaterials;
156  for (const auto& it : themap) {
157  const std::string& key = it.first;
158  if (visitedMaterials.find(key) != visitedMaterials.end())
159  continue;
160  visitedMaterials.insert(key);
161  const Material* p_material = it.second;
162  const auto factory_name = factory_names.find(p_material->typeID());
163  if (factory_name == factory_names.cend())
164  throw std::runtime_error(
165  "Error in Py::Export::defineMaterials(): unknown material type");
166  const complex_t& material_data = p_material->materialData();
167  if (p_material->isScalarMaterial()) {
168  result << indent() << m_materials->mat2key(p_material) << " = ba."
169  << factory_name->second << "(\"" << p_material->materialName() << "\", "
170  << Py::Fmt::printDouble(material_data.real()) << ", "
171  << Py::Fmt::printDouble(material_data.imag()) << ")\n";
172  } else {
173  R3 magnetic_field = p_material->magnetization();
174  result << indent() << "magnetic_field = R3(" << magnetic_field.x() << ", "
175  << magnetic_field.y() << ", " << magnetic_field.z() << ")\n";
176  result << indent() << m_materials->mat2key(p_material) << " = ba."
177  << factory_name->second << "(\"" << p_material->materialName();
178  result << "\", " << Py::Fmt::printDouble(material_data.real()) << ", "
179  << Py::Fmt::printDouble(material_data.imag()) << ", "
180  << "magnetic_field)\n";
181  }
182  }
183  return result.str();
184 }
const std::map< MATERIAL_TYPES, std::string > factory_names
A wrapper for underlying material implementation.
Definition: Material.h:35
R3 magnetization() const
Get the magnetization (in A/m)
Definition: Material.cpp:78
bool isScalarMaterial() const
Indicates whether the interaction with the material is scalar. This means that different polarization...
Definition: Material.cpp:58
std::string materialName() const
Returns the name of material.
Definition: Material.cpp:68
MATERIAL_TYPES typeID() const
Returns the type of underlying material implementation.
Definition: Material.cpp:73
complex_t materialData() const
Returns delta + i beta.
Definition: Material.cpp:83

References factory_names, Py::Fmt::indent(), Material::isScalarMaterial(), m_materials, Material::magnetization(), Material::materialData(), Material::materialName(), Py::Fmt::printDouble(), and Material::typeID().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineMesoCrystals()

std::string SampleToPython::defineMesoCrystals ( ) const
private

Definition at line 427 of file SampleToPython.cpp.

428 {
429  std::vector<const MesoCrystal*> v = m_objs->objectsOfType<MesoCrystal>();
430  if (v.empty())
431  return "";
432  std::ostringstream result;
433  result << std::setprecision(12);
434  result << "\n" << indent() << "# Define mesocrystals\n";
435  for (const auto* s : v) {
436  const std::string& key = m_objs->obj2key(s);
437  const auto* crystal = NodeUtils::OnlyChildOfType<Crystal>(*s);
438  const auto* outer_shape = NodeUtils::OnlyChildOfType<IFormFactor>(*s);
439  if (!crystal || !outer_shape)
440  continue;
441  result << indent() << key << " = ba.MesoCrystal(";
442  result << m_objs->obj2key(crystal) << ", ";
443  result << m_objs->obj2key(outer_shape) << ")\n";
444  setRotationInformation(s, key, result);
445  setPositionInformation(s, key, result);
446  }
447  return result.str();
448 }
A particle with a crystalline inner structure, made of smaller particles, and an outer shape describe...
Definition: MesoCrystal.h:27

References Py::Fmt::indent(), and m_objs.

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineMultiLayers()

std::string SampleToPython::defineMultiLayers ( ) const
private

Definition at line 513 of file SampleToPython.cpp.

514 {
515  std::vector<const MultiLayer*> v = m_objs->objectsOfType<MultiLayer>();
516  if (v.empty())
517  return "";
518  std::ostringstream result;
519  result << std::setprecision(12);
520  ASSERT(v.size() == 1); // as long as there is exactly one sample, we shall use the singular
521  result << "\n" << indent() << "# Define sample\n";
522  for (const auto* s : v) {
523  const std::string& key = m_objs->obj2key(s);
524  result << indent() << key << " = ba.MultiLayer()\n";
525  double ccl = s->crossCorrLength();
526  if (ccl > 0.0)
527  result << indent() << key << ".setCrossCorrLength(" << ccl << ")\n";
528  auto external_field = s->externalField();
529  if (external_field.mag() > 0.0) {
530  std::string field_name = key + "_external_field";
531  result << indent() << field_name << " = R3("
532  << Py::Fmt::printScientificDouble(external_field.x()) << ", "
533  << Py::Fmt::printScientificDouble(external_field.y()) << ", "
534  << Py::Fmt::printScientificDouble(external_field.z()) << ")\n";
535  result << indent() << key << ".setExternalField(" << field_name << ")\n";
536  }
537  size_t numberOfLayers = s->numberOfLayers();
538  if (numberOfLayers) {
539  result << indent() << key << ".addLayer(" << m_objs->obj2key(s->layer(0)) << ")\n";
540 
541  size_t i_layer = 1;
542  while (i_layer != numberOfLayers) {
543  const LayerInterface* layerInterface = s->layerInterface(i_layer - 1);
544  if (const LayerRoughness* rough = layerInterface->roughness())
545  result << indent() << key << ".addLayerWithTopRoughness("
546  << m_objs->obj2key(s->layer(i_layer)) << ", " << m_objs->obj2key(rough)
547  << ")\n";
548  else
549  result << indent() << key << ".addLayer(" << m_objs->obj2key(s->layer(i_layer))
550  << ")\n";
551  i_layer++;
552  }
553  }
554  result << "\n" << indent() << "return " << key << "\n";
555  }
556  return result.str();
557 }
Interface between two layers, possibly with roughness.
const LayerRoughness * roughness() const
Returns roughness of the interface.
A roughness of interface between two layers.
Our sample model: a stack of layers one below the other.
Definition: MultiLayer.h:43
std::string printScientificDouble(double input)
Definition: PyFmt.cpp:96

References ASSERT, Py::Fmt::indent(), m_objs, Py::Fmt::printScientificDouble(), and LayerInterface::roughness().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineParticleCompositions()

std::string SampleToPython::defineParticleCompositions ( ) const
private

Definition at line 407 of file SampleToPython.cpp.

408 {
409  std::vector<const ParticleComposition*> v = m_objs->objectsOfType<ParticleComposition>();
410  if (v.empty())
411  return "";
412  std::ostringstream result;
413  result << std::setprecision(12);
414  result << "\n" << indent() << "# Define composition of particles at specific positions\n";
415  for (const auto* s : v) {
416  const std::string& key = m_objs->obj2key(s);
417  result << indent() << key << " = ba.ParticleComposition()\n";
418  const auto particle_list = NodeUtils::ChildNodesOfType<IParticle>(*s);
419  for (const auto* particle : particle_list)
420  result << indent() << key << ".addParticle(" << m_objs->obj2key(particle) << ")\n";
421  setRotationInformation(s, key, result);
422  setPositionInformation(s, key, result);
423  }
424  return result.str();
425 }
A composition of particles at fixed positions.

References Py::Fmt::indent(), and m_objs.

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineParticleLayouts()

std::string SampleToPython::defineParticleLayouts ( ) const
private

Definition at line 342 of file SampleToPython.cpp.

343 {
344  std::vector<const ParticleLayout*> v = m_objs->objectsOfType<ParticleLayout>();
345  if (v.empty())
346  return "";
347  std::ostringstream result;
348  result << std::setprecision(12);
349  result << "\n" << indent() << "# Define particle layouts\n";
350  for (const auto* s : v) {
351  const std::string& key = m_objs->obj2key(s);
352  result << indent() << key << " = ba.ParticleLayout()\n";
353  const auto particles = NodeUtils::ChildNodesOfType<IParticle>(*s);
354  for (const auto* particle : particles) {
355  double abundance = particle->abundance();
356  result << indent() << key << ".addParticle(" << m_objs->obj2key(particle) << ", "
357  << Py::Fmt::printDouble(abundance) << ")\n";
358  }
359  if (const auto* iff = NodeUtils::OnlyChildOfType<IInterference>(*s))
360  result << indent() << key << ".setInterference(" << m_objs->obj2key(iff) << ")\n";
361  result << indent() << key << ".setWeight(" << s->weight() << ")\n";
362  result << indent() << key << ".setTotalParticleSurfaceDensity("
363  << s->totalParticleSurfaceDensity() << ")\n";
364  }
365  return result.str();
366 }
Decorator class that adds particles to ISampleNode objects.

References IParticle::abundance(), Py::Fmt::indent(), m_objs, and Py::Fmt::printDouble().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineParticles()

std::string SampleToPython::defineParticles ( ) const
private

Definition at line 368 of file SampleToPython.cpp.

369 {
370  std::vector<const Particle*> v = m_objs->objectsOfType<Particle>();
371  if (v.empty())
372  return "";
373  std::ostringstream result;
374  result << std::setprecision(12);
375  result << "\n" << indent() << "# Define particles\n";
376  for (const auto* s : v) {
377  const std::string& key = m_objs->obj2key(s);
378  const auto* ff = NodeUtils::OnlyChildOfType<IFormFactor>(*s);
379  ASSERT(ff);
380  result << indent() << key << " = ba.Particle(" << m_materials->mat2key(s->material())
381  << ", " << m_objs->obj2key(ff) << ")\n";
382  setRotationInformation(s, key, result);
383  setPositionInformation(s, key, result);
384  }
385  return result.str();
386 }
A particle with a form factor and refractive index.
Definition: Particle.h:25

References ASSERT, Py::Fmt::indent(), m_materials, and m_objs.

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineRoughnesses()

std::string SampleToPython::defineRoughnesses ( ) const
private

Definition at line 208 of file SampleToPython.cpp.

209 {
210  std::vector<const LayerRoughness*> v = m_objs->objectsOfType<LayerRoughness>();
211  if (v.empty())
212  return "";
213  std::ostringstream result;
214  result << std::setprecision(12);
215  result << "\n" << indent() << "# Define roughness\n";
216  for (const auto* s : v) {
217  const std::string& key = m_objs->obj2key(s);
218  result << indent() << key << " = ba." << s->pythonConstructor() << "\n";
219  }
220  return result.str();
221 }

References Py::Fmt::indent(), and m_objs.

Referenced by defineGetSample().

Here is the call graph for this function:

◆ initLabels()

void SampleToPython::initLabels ( const MultiLayer sample)
private

Definition at line 95 of file SampleToPython.cpp.

96 {
97  m_objs = std::make_unique<ComponentKeyHandler>();
98  m_materials = std::make_unique<MaterialKeyHandler>();
99 
100  for (const auto* x : sample.containedMaterials())
101  m_materials->insertMaterial(x);
102 
103  m_objs->insertModel("sample", &sample);
104  for (const auto* x : NodeUtils::AllDescendantsOfType<Layer>(sample))
105  m_objs->insertModel("layer", x);
106  for (const auto* x : NodeUtils::AllDescendantsOfType<LayerRoughness>(sample))
107  m_objs->insertModel("roughness", x);
108  for (const auto* x : NodeUtils::AllDescendantsOfType<ParticleLayout>(sample))
109  m_objs->insertModel("layout", x);
110  for (const auto* x : NodeUtils::AllDescendantsOfType<IFormFactor>(sample))
111  m_objs->insertModel("ff", x);
112  for (const auto* x : NodeUtils::AllDescendantsOfType<IInterference>(sample))
113  m_objs->insertModel("iff", x);
114  for (const auto* x : NodeUtils::AllDescendantsOfType<Particle>(sample))
115  m_objs->insertModel("particle", x);
116  for (const auto* x : NodeUtils::AllDescendantsOfType<ParticleComposition>(sample))
117  m_objs->insertModel("particle", x);
118  for (const auto* x : NodeUtils::AllDescendantsOfType<ParticleCoreShell>(sample))
119  m_objs->insertModel("particle", x);
120  for (const auto* x : NodeUtils::AllDescendantsOfType<MesoCrystal>(sample))
121  m_objs->insertModel("particle", x);
122  for (const auto* x : NodeUtils::AllDescendantsOfType<Lattice2D>(sample))
123  m_objs->insertModel("lattice", x);
124  for (const auto* x : NodeUtils::AllDescendantsOfType<Lattice3D>(sample))
125  m_objs->insertModel("lattice", x);
126  for (const auto* x : NodeUtils::AllDescendantsOfType<Crystal>(sample))
127  m_objs->insertModel("crystal", x);
128 }
std::vector< const Material * > containedMaterials() const
Returns set of unique materials contained in this ISampleNode.
Definition: ISampleNode.cpp:25

References ISampleNode::containedMaterials(), m_materials, and m_objs.

Referenced by sampleCode().

Here is the call graph for this function:

◆ sampleCode()

std::string SampleToPython::sampleCode ( const MultiLayer sample)

Definition at line 89 of file SampleToPython.cpp.

90 {
91  initLabels(sample);
92  return defineGetSample();
93 }
std::string defineGetSample() const
void initLabels(const MultiLayer &sample)

References defineGetSample(), and initLabels().

Referenced by Py::Export::sampleCode().

Here is the call graph for this function:

Member Data Documentation

◆ m_materials

std::unique_ptr<MaterialKeyHandler> SampleToPython::m_materials
private

Definition at line 60 of file SampleToPython.h.

Referenced by defineLayers(), defineMaterials(), defineParticles(), and initLabels().

◆ m_objs


The documentation for this class was generated from the following files: