BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
SampleToPython Class Reference

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

Public Member Functions

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

Private Member Functions

std::string defineCoreShellParticles () const
 
std::string defineCrystals () const
 
std::string defineFormFactors () const
 
std::string defineGetSample () const
 
std::string defineInterferenceFunctions () 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 defineParticleDistributions () const
 
std::string defineParticleLayouts () const
 
std::string defineParticles () const
 
std::string defineRoughnesses () const
 
void initLabels (const MultiLayer &multilayer)
 

Private Attributes

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

Detailed Description

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

Definition at line 33 of file SampleToPython.h.

Constructor & Destructor Documentation

◆ SampleToPython()

SampleToPython::SampleToPython ( )
default

◆ ~SampleToPython()

SampleToPython::~SampleToPython ( )
default

Member Function Documentation

◆ defineCoreShellParticles()

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

Definition at line 413 of file SampleToPython.cpp.

414 {
415  std::vector<const ParticleCoreShell*> v = m_objs->objectsOfType<ParticleCoreShell>();
416  if (v.empty())
417  return "";
418  std::ostringstream result;
419  result << std::setprecision(12);
420  result << "\n" << indent() << "# Define core shell particles\n";
421  for (const auto* s : v) {
422  const std::string& key = m_objs->obj2key(s);
423  result << indent() << key << " = ba.ParticleCoreShell("
424  << m_objs->obj2key(s->shellParticle()) << ", " << m_objs->obj2key(s->coreParticle())
425  << ")\n";
426  setRotationInformation(s, key, result);
427  setPositionInformation(s, key, result);
428  }
429  return result.str();
430 }
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.
Definition: PyFmt.cpp:155

References pyfmt::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 561 of file SampleToPython.cpp.

562 {
563  std::vector<const Crystal*> v = m_objs->objectsOfType<Crystal>();
564  if (v.empty())
565  return "";
566  std::ostringstream result;
567  result << std::setprecision(12);
568  result << "\n" << indent() << "# Define crystals\n";
569  for (const auto* s : v) {
570  const std::string& key = m_objs->obj2key(s);
571  const auto* lattice = node_progeny::OnlyChildOfType<Lattice3D>(*s);
572  const auto* basis = node_progeny::OnlyChildOfType<IParticle>(*s);
573  if (!lattice || !basis)
574  continue;
575  result << indent() << key << " = ba.Crystal(";
576  result << m_objs->obj2key(basis) << ", ";
577  result << m_objs->obj2key(lattice) << ")\n";
578  }
579  return result.str();
580 }
A crystal structure, defined by a Bravais lattice, a basis, and a position variance.
Definition: Crystal.h:35

References pyfmt::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 232 of file SampleToPython.cpp.

233 {
234  std::vector<const IFormFactor*> v = m_objs->objectsOfType<IFormFactor>();
235  if (v.empty())
236  return "";
237  std::ostringstream result;
238  result << "\n" << indent() << "# Define form factors\n";
239  result << std::setprecision(12);
240  for (const auto* s : v) {
241  const std::string& key = m_objs->obj2key(s);
242  result << indent() << key << " = ba.FormFactor" << s->getName() << "("
243  << pyfmt2::argumentList(s) << ")\n";
244  }
245  return result.str();
246 }
Abstract base class for all form factors.
Definition: IFormFactor.h:36
std::string argumentList(const IParametricComponent *ip)
Returns comma-separated list of parameter values, including unit multiplicator (like "* nm").
Definition: PyFmt2.cpp:106

References pyfmt2::argumentList(), pyfmt::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 143 of file SampleToPython.cpp.

144 {
145  return "def get_sample():\n" + defineMaterials() + defineFormFactors() + defineParticles()
149  + defineRoughnesses() + defineLayers() + defineMultiLayers() + "\n\n";
150 }
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 defineParticleDistributions() const
std::string defineLattices2D() const
std::string defineParticleLayouts() const
std::string defineCoreShellParticles() const
std::string defineInterferenceFunctions() const
std::string defineMultiLayers() const
std::string defineRoughnesses() const

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

Referenced by sampleCode().

Here is the call graph for this function:

◆ defineInterferenceFunctions()

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

Definition at line 248 of file SampleToPython.cpp.

249 {
250  std::vector<const IInterferenceFunction*> v = m_objs->objectsOfType<IInterferenceFunction>();
251  if (v.empty())
252  return "";
253  std::ostringstream result;
254  result << std::setprecision(12);
255  result << "\n" << indent() << "# Define interference functions\n";
256  for (const auto* s : v) {
257  const std::string& key = m_objs->obj2key(s);
258 
259  if (dynamic_cast<const InterferenceFunctionNone*>(s))
260  result << indent() << key << " = ba.InterferenceFunctionNone()\n";
261 
262  else if (const auto* iff = dynamic_cast<const InterferenceFunction1DLattice*>(s)) {
263  result << indent() << key << " = ba.InterferenceFunction1DLattice("
264  << pyfmt::printNm(iff->getLength()) << ", " << pyfmt::printDegrees(iff->getXi())
265  << ")\n";
266 
267  const auto* pdf = node_progeny::OnlyChildOfType<IFTDecayFunction1D>(*iff);
268 
269  if (pdf->decayLength() != 0.0)
270  result << indent() << key << "_pdf = ba." << pdf->getName() << "("
271  << pyfmt2::argumentList(pdf) << ")\n"
272  << indent() << key << ".setDecayFunction(" << key << "_pdf)\n";
273 
274  } else if (const auto* iff =
275  dynamic_cast<const InterferenceFunctionRadialParaCrystal*>(s)) {
276  result << indent() << key << " = ba.InterferenceFunctionRadialParaCrystal("
277  << pyfmt::printNm(iff->peakDistance()) << ", "
278  << pyfmt::printNm(iff->dampingLength()) << ")\n";
279 
280  if (iff->kappa() != 0.0)
281  result << indent() << key << ".setKappa(" << pyfmt::printDouble(iff->kappa())
282  << ")\n";
283 
284  if (iff->domainSize() != 0.0)
285  result << indent() << key << ".setDomainSize("
286  << pyfmt::printDouble(iff->domainSize()) << ")\n";
287 
288  const auto* pdf = node_progeny::OnlyChildOfType<IFTDistribution1D>(*iff);
289 
290  if (pdf->omega() != 0.0)
291  result << indent() << key << "_pdf = ba." << pdf->getName() << "("
292  << pyfmt2::argumentList(pdf) << ")\n"
293  << indent() << key << ".setProbabilityDistribution(" << key << "_pdf)\n";
294 
295  } else if (const auto* iff = dynamic_cast<const InterferenceFunction2DLattice*>(s)) {
296  const auto* lattice = node_progeny::OnlyChildOfType<Lattice2D>(*iff);
297 
298  result << indent() << key << " = ba.InterferenceFunction2DLattice("
299  << m_objs->obj2key(lattice) << ")\n";
300 
301  const auto* pdf = node_progeny::OnlyChildOfType<IFTDecayFunction2D>(*iff);
302 
303  result << indent() << key << "_pdf = ba." << pdf->getName() << "("
304  << pyfmt2::argumentList(pdf) << ")\n"
305  << indent() << key << ".setDecayFunction(" << key << "_pdf)\n";
306 
307  if (iff->integrationOverXi() == true)
308  result << indent() << key << ".setIntegrationOverXi(True)\n";
309 
310  } else if (const auto* iff = dynamic_cast<const InterferenceFunctionFinite2DLattice*>(s)) {
311  const auto* lattice = node_progeny::OnlyChildOfType<Lattice2D>(*iff);
312 
313  result << indent() << key << " = ba.InterferenceFunctionFinite2DLattice("
314  << m_objs->obj2key(lattice) << ", " << iff->numberUnitCells1() << ", "
315  << iff->numberUnitCells2() << ")\n";
316 
317  if (iff->integrationOverXi() == true)
318  result << indent() << key << ".setIntegrationOverXi(True)\n";
319 
320  } else if (const auto* iff = dynamic_cast<const InterferenceFunction2DParaCrystal*>(s)) {
321  const auto* lattice = node_progeny::OnlyChildOfType<Lattice2D>(*iff);
322  std::vector<double> domainSize = iff->domainSizes();
323 
324  result << indent() << key << " = ba.InterferenceFunction2DParaCrystal("
325  << m_objs->obj2key(lattice) << ", " << pyfmt::printNm(iff->dampingLength())
326  << ", " << pyfmt::printNm(domainSize[0]) << ", " << pyfmt::printNm(domainSize[1])
327  << ")\n";
328 
329  if (iff->integrationOverXi() == true)
330  result << indent() << key << ".setIntegrationOverXi(True)\n";
331 
332  const auto pdf_vector = node_progeny::ChildNodesOfType<IFTDistribution2D>(*iff);
333  if (pdf_vector.size() != 2)
334  continue;
335  const IFTDistribution2D* pdf = pdf_vector[0];
336 
337  result << indent() << key << "_pdf_1 = ba." << pdf->getName() << "("
338  << pyfmt2::argumentList(pdf) << ")\n";
339 
340  pdf = pdf_vector[1];
341 
342  result << indent() << key << "_pdf_2 = ba." << pdf->getName() << "("
343  << pyfmt2::argumentList(pdf) << ")\n";
344  result << indent() << key << ".setProbabilityDistributions(" << key << "_pdf_1, " << key
345  << "_pdf_2)\n";
346 
347  } else if (const auto* lattice_hd = dynamic_cast<const InterferenceFunctionHardDisk*>(s)) {
348  result << indent() << key << " = ba.InterferenceFunctionHardDisk("
349  << pyfmt::printNm(lattice_hd->radius()) << ", "
350  << pyfmt::printDouble(lattice_hd->density()) << ")\n";
351 
352  } else
353  throw std::runtime_error(
354  "Bug: ExportToPython::defineInterferenceFunctions() called with unexpected "
355  "IInterferenceFunction "
356  + s->getName());
357 
358  if (s->positionVariance() > 0.0) {
359  result << indent() << key << ".setPositionVariance("
360  << pyfmt::printNm2(s->positionVariance()) << ")\n";
361  }
362  }
363  return result.str();
364 }
Interface for two-dimensional distributions in Fourier space.
Abstract base class of interference functions.
const std::string & getName() const
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.
std::string printNm(double input)
Definition: PyFmt.cpp:74
std::string printNm2(double input)
Definition: PyFmt.cpp:82
std::string printDegrees(double input)
Definition: PyFmt.cpp:111
std::string printDouble(double input)
Definition: PyFmt.cpp:41

References pyfmt2::argumentList(), IParametricComponent::getName(), pyfmt::indent(), m_objs, pyfmt::printDegrees(), pyfmt::printDouble(), pyfmt::printNm(), and pyfmt::printNm2().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineLattices2D()

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

Definition at line 519 of file SampleToPython.cpp.

520 {
521  std::vector<const Lattice2D*> v = m_objs->objectsOfType<Lattice2D>();
522  if (v.empty())
523  return "";
524  std::ostringstream result;
525  result << std::setprecision(12);
526  result << "\n" << indent() << "# Define 2D lattices\n";
527  for (const auto* s : v) {
528  const std::string& key = m_objs->obj2key(s);
529  result << indent() << key << " = ba.BasicLattice2D(\n";
530  result << indent() << indent() << pyfmt::printNm(s->length1()) << ", "
531  << pyfmt::printNm(s->length2()) << ", " << pyfmt::printDegrees(s->latticeAngle())
532  << ", " << pyfmt::printDegrees(s->rotationAngle()) << ")\n";
533  }
534  return result.str();
535 }
A two-dimensional Bravais lattice.
Definition: Lattice2D.h:23

References pyfmt::indent(), m_objs, pyfmt::printDegrees(), and pyfmt::printNm().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineLattices3D()

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

Definition at line 537 of file SampleToPython.cpp.

538 {
539  std::vector<const Lattice3D*> v = m_objs->objectsOfType<Lattice3D>();
540  if (v.empty())
541  return "";
542  std::ostringstream result;
543  result << std::setprecision(12);
544  result << "\n" << indent() << "# Define 3D lattices\n";
545  for (const auto* s : v) {
546  const std::string& key = m_objs->obj2key(s);
547  kvector_t bas_a = s->getBasisVectorA();
548  kvector_t bas_b = s->getBasisVectorB();
549  kvector_t bas_c = s->getBasisVectorC();
550  result << indent() << key << " = ba.Lattice3D(\n";
551  result << indent() << indent() << "ba.kvector_t(" << pyfmt::printNm(bas_a.x()) << ", "
552  << pyfmt::printNm(bas_a.y()) << ", " << pyfmt::printNm(bas_a.z()) << "),\n";
553  result << indent() << indent() << "ba.kvector_t(" << pyfmt::printNm(bas_b.x()) << ", "
554  << pyfmt::printNm(bas_b.y()) << ", " << pyfmt::printNm(bas_b.z()) << "),\n";
555  result << indent() << indent() << "ba.kvector_t(" << pyfmt::printNm(bas_c.x()) << ", "
556  << pyfmt::printNm(bas_c.y()) << ", " << pyfmt::printNm(bas_c.z()) << "))\n";
557  }
558  return result.str();
559 }
T z() const
Returns z-component in cartesian coordinate system.
Definition: BasicVector3D.h:67
T y() const
Returns y-component in cartesian coordinate system.
Definition: BasicVector3D.h:65
T x() const
Returns x-component in cartesian coordinate system.
Definition: BasicVector3D.h:63
A Bravais lattice, characterized by three basis vectors, and optionally an ISelectionRule.
Definition: Lattice3D.h:29

References pyfmt::indent(), m_objs, pyfmt::printNm(), BasicVector3D< T >::x(), BasicVector3D< T >::y(), and BasicVector3D< T >::z().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineLayers()

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

Definition at line 195 of file SampleToPython.cpp.

196 {
197  std::vector<const Layer*> v = m_objs->objectsOfType<Layer>();
198  if (v.empty())
199  return "";
200  std::ostringstream result;
201  result << "\n" << indent() << "# Define layers\n";
202  result << std::setprecision(12);
203  for (const auto* s : v) {
204  const std::string& key = m_objs->obj2key(s);
205  result << indent() << key << " = ba.Layer(" << m_materials->mat2key(s->material());
206  if (s->thickness() != 0)
207  result << ", " << pyfmt::printNm(s->thickness());
208  result << ")\n";
209  if (s->numberOfSlices() != 1)
210  result << indent() << key << ".setNumberOfSlices(" << s->numberOfSlices() << ")\n";
211  for (const auto* layout : s->layouts())
212  result << indent() << key << ".addLayout(" << m_objs->obj2key(layout) << ")\n";
213  }
214  return result.str();
215 }
A layer in a MultiLayer sample.
Definition: Layer.h:27
std::unique_ptr< MaterialKeyHandler > m_materials

References pyfmt::indent(), m_materials, m_objs, and pyfmt::printNm().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineMaterials()

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

Definition at line 156 of file SampleToPython.cpp.

157 {
158  const auto themap = m_materials->materialMap();
159  if (themap.empty())
160  return "";
161  std::ostringstream result;
162  result << std::setprecision(12);
163  result << indent() << "# Define materials\n";
164  std::set<std::string> visitedMaterials;
165  for (auto it : themap) {
166  const std::string& key = it.first;
167  if (visitedMaterials.find(key) != visitedMaterials.end())
168  continue;
169  visitedMaterials.insert(key);
170  const Material* p_material = it.second;
171  const auto factory_name = factory_names.find(p_material->typeID());
172  if (factory_name == factory_names.cend())
173  throw std::runtime_error(
174  "Error in ExportToPython::defineMaterials(): unknown material type");
175  const complex_t& material_data = p_material->materialData();
176  if (p_material->isScalarMaterial()) {
177  result << indent() << m_materials->mat2key(p_material) << " = ba."
178  << factory_name->second << "(\"" << p_material->getName() << "\", "
179  << pyfmt::printDouble(material_data.real()) << ", "
180  << pyfmt::printDouble(material_data.imag()) << ")\n";
181  } else {
182  kvector_t magnetic_field = p_material->magnetization();
183  result << indent() << "magnetic_field = kvector_t(" << magnetic_field.x() << ", "
184  << magnetic_field.y() << ", " << magnetic_field.z() << ")\n";
185  result << indent() << m_materials->mat2key(p_material) << " = ba."
186  << factory_name->second << "(\"" << p_material->getName();
187  result << "\", " << pyfmt::printDouble(material_data.real()) << ", "
188  << pyfmt::printDouble(material_data.imag()) << ", "
189  << "magnetic_field)\n";
190  }
191  }
192  return result.str();
193 }
std::complex< double > complex_t
Definition: Complex.h:20
const std::map< MATERIAL_TYPES, std::string > factory_names
A wrapper for underlying material implementation.
Definition: Material.h:29
kvector_t magnetization() const
Get the magnetization (in A/m)
Definition: Material.cpp:76
bool isScalarMaterial() const
Indicates whether the interaction with the material is scalar.
Definition: Material.cpp:56
std::string getName() const
Returns the name of material.
Definition: Material.cpp:66
MATERIAL_TYPES typeID() const
Returns the type of underlying material implementation.
Definition: Material.cpp:71
complex_t materialData() const
Returns underlying material data.
Definition: Material.cpp:81

References factory_names, Material::getName(), pyfmt::indent(), Material::isScalarMaterial(), m_materials, Material::magnetization(), Material::materialData(), pyfmt::printDouble(), Material::typeID(), BasicVector3D< T >::x(), BasicVector3D< T >::y(), and BasicVector3D< T >::z().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineMesoCrystals()

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

Definition at line 496 of file SampleToPython.cpp.

497 {
498  std::vector<const MesoCrystal*> v = m_objs->objectsOfType<MesoCrystal>();
499  if (v.empty())
500  return "";
501  std::ostringstream result;
502  result << std::setprecision(12);
503  result << "\n" << indent() << "# Define mesocrystals\n";
504  for (const auto* s : v) {
505  const std::string& key = m_objs->obj2key(s);
506  auto crystal = node_progeny::OnlyChildOfType<Crystal>(*s);
507  auto outer_shape = node_progeny::OnlyChildOfType<IFormFactor>(*s);
508  if (!crystal || !outer_shape)
509  continue;
510  result << indent() << key << " = ba.MesoCrystal(";
511  result << m_objs->obj2key(crystal) << ", ";
512  result << m_objs->obj2key(outer_shape) << ")\n";
513  setRotationInformation(s, key, result);
514  setPositionInformation(s, key, result);
515  }
516  return result.str();
517 }
A particle with an internal structure of smaller particles.
Definition: MesoCrystal.h:25

References pyfmt::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 582 of file SampleToPython.cpp.

583 {
584  std::vector<const MultiLayer*> v = m_objs->objectsOfType<MultiLayer>();
585  if (v.empty())
586  return "";
587  std::ostringstream result;
588  result << std::setprecision(12);
589  ASSERT(v.size() == 1); // as long as there is exactly one sample, we shall use the singular
590  result << "\n" << indent() << "# Define sample\n";
591  for (const auto* s : v) {
592  const std::string& key = m_objs->obj2key(s);
593  result << indent() << key << " = ba.MultiLayer()\n";
594  double ccl = s->crossCorrLength();
595  if (ccl > 0.0)
596  result << indent() << key << ".setCrossCorrLength(" << ccl << ")\n";
597  auto external_field = s->externalField();
598  if (external_field.mag() > 0.0) {
599  std::string field_name = key + "_external_field";
600  result << indent() << field_name << " = kvector_t("
601  << pyfmt::printScientificDouble(external_field.x()) << ", "
602  << pyfmt::printScientificDouble(external_field.y()) << ", "
603  << pyfmt::printScientificDouble(external_field.z()) << ")\n";
604  result << indent() << key << ".setExternalField(" << field_name << ")\n";
605  }
606  size_t numberOfLayers = s->numberOfLayers();
607  if (numberOfLayers) {
608  result << indent() << key << ".addLayer(" << m_objs->obj2key(s->layer(0)) << ")\n";
609 
610  size_t layerIndex = 1;
611  while (layerIndex != numberOfLayers) {
612  const LayerInterface* layerInterface = s->layerInterface(layerIndex - 1);
613  if (const LayerRoughness* rough = layerInterface->getRoughness())
614  result << indent() << key << ".addLayerWithTopRoughness("
615  << m_objs->obj2key(s->layer(layerIndex)) << ", "
616  << m_objs->obj2key(rough) << ")\n";
617  else
618  result << indent() << key << ".addLayer("
619  << m_objs->obj2key(s->layer(layerIndex)) << ")\n";
620  layerIndex++;
621  }
622  }
623  result << "\n" << indent() << "return " << key << "\n";
624  }
625  return result.str();
626 }
#define ASSERT(condition)
Definition: Assert.h:31
Interface between two layers, possibly with roughness.
const LayerRoughness * getRoughness() 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:41
std::string printScientificDouble(double input)
Definition: PyFmt.cpp:91

References ASSERT, LayerInterface::getRoughness(), pyfmt::indent(), m_objs, and pyfmt::printScientificDouble().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineParticleCompositions()

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

Definition at line 475 of file SampleToPython.cpp.

476 {
477  std::vector<const ParticleComposition*> v = m_objs->objectsOfType<ParticleComposition>();
478  if (v.empty())
479  return "";
480  std::ostringstream result;
481  result << std::setprecision(12);
482  result << "\n" << indent() << "# Define composition of particles at specific positions\n";
483  for (const auto* s : v) {
484  const std::string& key = m_objs->obj2key(s);
485  result << indent() << key << " = ba.ParticleComposition()\n";
486  const auto particle_list = node_progeny::ChildNodesOfType<IParticle>(*s);
487  for (const auto* particle : particle_list) {
488  result << indent() << key << ".addParticle(" << m_objs->obj2key(particle) << ")\n";
489  }
490  setRotationInformation(s, key, result);
491  setPositionInformation(s, key, result);
492  }
493  return result.str();
494 }
A composition of particles at fixed positions.

References pyfmt::indent(), and m_objs.

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineParticleDistributions()

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

Definition at line 432 of file SampleToPython.cpp.

433 {
434  std::vector<const ParticleDistribution*> v = m_objs->objectsOfType<ParticleDistribution>();
435  if (v.empty())
436  return "";
437  std::ostringstream result;
438  result << std::setprecision(12);
439  result << "\n" << indent() << "# Define particles with parameter following a distribution\n";
440  int index = 1;
441  for (const auto* s : v) {
442  const std::string& key = m_objs->obj2key(s);
443  const std::string units = s->mainUnits();
444  ParameterDistribution par_distr = s->parameterDistribution();
445  // building distribution functions
446  std::string s_distr = "distr_" + std::to_string(index);
447  result << indent() << s_distr << " = "
448  << pyfmt2::printDistribution(*par_distr.getDistribution(), units) << "\n";
449 
450  // building parameter distribution
451  std::string s_par_distr = "par_distr_" + std::to_string(index);
452 
453  result << indent() << s_par_distr << " = "
454  << pyfmt2::printParameterDistribution(par_distr, s_distr, units) << "\n";
455 
456  // linked parameters
457  std::vector<std::string> linked_pars = par_distr.getLinkedParameterNames();
458  if (!linked_pars.empty()) {
459  result << indent() << s_par_distr;
460  for (size_t i = 0; i < linked_pars.size(); ++i)
461  result << ".linkParameter(\"" << linked_pars[i] << "\")";
462  result << "\n";
463  }
464 
465  auto particle = node_progeny::OnlyChildOfType<IParticle>(*s);
466  if (!particle)
467  continue;
468  result << indent() << key << " = ba.ParticleDistribution(" << m_objs->obj2key(particle)
469  << ", " << s_par_distr << ")\n";
470  index++;
471  }
472  return result.str();
473 }
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 particle type that is a parametric distribution of IParticle's.
std::string printParameterDistribution(const ParameterDistribution &par_distr, const std::string &distVarName, const std::string &units)
Definition: PyFmt2.cpp:147
std::string printDistribution(const IDistribution1D &par_distr, const std::string &units)
Prints distribution with constructor parameters in given units.
Definition: PyFmt2.cpp:137

References ParameterDistribution::getDistribution(), ParameterDistribution::getLinkedParameterNames(), pyfmt::indent(), m_objs, pyfmt2::printDistribution(), and pyfmt2::printParameterDistribution().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineParticleLayouts()

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

Definition at line 366 of file SampleToPython.cpp.

367 {
368  std::vector<const ParticleLayout*> v = m_objs->objectsOfType<ParticleLayout>();
369  if (v.empty())
370  return "";
371  std::ostringstream result;
372  result << std::setprecision(12);
373  result << "\n" << indent() << "# Define particle layouts\n";
374  for (const auto* s : v) {
375  const std::string& key = m_objs->obj2key(s);
376  result << indent() << key << " = ba.ParticleLayout()\n";
377  const auto particles = node_progeny::ChildNodesOfType<IAbstractParticle>(*s);
378  for (const auto* particle : particles) {
379  double abundance = particle->abundance();
380  result << indent() << key << ".addParticle(" << m_objs->obj2key(particle) << ", "
381  << pyfmt::printDouble(abundance) << ")\n";
382  }
383  if (const auto* iff = node_progeny::OnlyChildOfType<IInterferenceFunction>(*s))
384  result << indent() << key << ".setInterferenceFunction(" << m_objs->obj2key(iff)
385  << ")\n";
386  result << indent() << key << ".setWeight(" << s->weight() << ")\n";
387  result << indent() << key << ".setTotalParticleSurfaceDensity("
388  << s->totalParticleSurfaceDensity() << ")\n";
389  }
390  return result.str();
391 }
Decorator class that adds particles to ISampleNode objects.

References IAbstractParticle::abundance(), pyfmt::indent(), m_objs, and pyfmt::printDouble().

Referenced by defineGetSample().

Here is the call graph for this function:

◆ defineParticles()

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

Definition at line 393 of file SampleToPython.cpp.

394 {
395  std::vector<const Particle*> v = m_objs->objectsOfType<Particle>();
396  if (v.empty())
397  return "";
398  std::ostringstream result;
399  result << std::setprecision(12);
400  result << "\n" << indent() << "# Define particles\n";
401  for (const auto* s : v) {
402  const std::string& key = m_objs->obj2key(s);
403  const auto* ff = node_progeny::OnlyChildOfType<IFormFactor>(*s);
404  ASSERT(ff);
405  result << indent() << key << " = ba.Particle(" << m_materials->mat2key(s->material())
406  << ", " << m_objs->obj2key(ff) << ")\n";
407  setRotationInformation(s, key, result);
408  setPositionInformation(s, key, result);
409  }
410  return result.str();
411 }
A particle with a form factor and refractive index.
Definition: Particle.h:24

References ASSERT, pyfmt::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 217 of file SampleToPython.cpp.

218 {
219  std::vector<const LayerRoughness*> v = m_objs->objectsOfType<LayerRoughness>();
220  if (v.empty())
221  return "";
222  std::ostringstream result;
223  result << std::setprecision(12);
224  result << "\n" << indent() << "# Define roughness\n";
225  for (const auto* s : v) {
226  const std::string& key = m_objs->obj2key(s);
227  result << indent() << key << " = ba.LayerRoughness(" << pyfmt2::argumentList(s) << ")\n";
228  }
229  return result.str();
230 }

References pyfmt2::argumentList(), pyfmt::indent(), and m_objs.

Referenced by defineGetSample().

Here is the call graph for this function:

◆ initLabels()

void SampleToPython::initLabels ( const MultiLayer multilayer)
private

Definition at line 102 of file SampleToPython.cpp.

103 {
104  m_objs.reset(new ComponentKeyHandler());
105  m_materials.reset(new MaterialKeyHandler());
106 
107  for (auto x : multilayer.containedMaterials())
108  m_materials->insertMaterial(x);
109 
110  m_objs->insertModel("sample", &multilayer);
111  for (const auto* x : node_progeny::AllDescendantsOfType<Layer>(multilayer))
112  m_objs->insertModel("layer", x);
113  for (const auto* x : node_progeny::AllDescendantsOfType<LayerRoughness>(multilayer))
114  m_objs->insertModel("roughness", x);
115  for (const auto* x : node_progeny::AllDescendantsOfType<ParticleLayout>(multilayer))
116  m_objs->insertModel("layout", x);
117  for (const auto* x : node_progeny::AllDescendantsOfType<IFormFactor>(multilayer))
118  m_objs->insertModel("ff", x);
119  for (const auto* x : node_progeny::AllDescendantsOfType<IInterferenceFunction>(multilayer))
120  m_objs->insertModel("iff", x);
121  for (const auto* x : node_progeny::AllDescendantsOfType<Particle>(multilayer))
122  m_objs->insertModel("particle", x);
123  for (const auto* x : node_progeny::AllDescendantsOfType<ParticleComposition>(multilayer))
124  m_objs->insertModel("particle", x);
125  for (const auto* x : node_progeny::AllDescendantsOfType<ParticleCoreShell>(multilayer))
126  m_objs->insertModel("particle", x);
127  for (const auto* x : node_progeny::AllDescendantsOfType<MesoCrystal>(multilayer))
128  m_objs->insertModel("particle", x);
129  for (const auto* x : node_progeny::AllDescendantsOfType<ParticleDistribution>(multilayer))
130  m_objs->insertModel("particle_distrib", x);
131  for (const auto* x : node_progeny::AllDescendantsOfType<Lattice2D>(multilayer))
132  m_objs->insertModel("lattice", x);
133  for (const auto* x : node_progeny::AllDescendantsOfType<Lattice3D>(multilayer))
134  m_objs->insertModel("lattice", x);
135  for (const auto* x : node_progeny::AllDescendantsOfType<Crystal>(multilayer))
136  m_objs->insertModel("crystal", x);
137 }
Stores IComponent instances, associates them with given tag, and provides unique keys.
std::vector< const Material * > containedMaterials() const
Returns set of unique materials contained in this ISampleNode.
Definition: ISampleNode.cpp:26
Stores Material instances, associates them with given tag, and provides unique keys.

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 multilayer)

Definition at line 96 of file SampleToPython.cpp.

97 {
98  initLabels(multilayer);
99  return defineGetSample();
100 }
std::string defineGetSample() const
void initLabels(const MultiLayer &multilayer)

References defineGetSample(), and initLabels().

Referenced by ExportToPython::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 61 of file SampleToPython.h.

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

◆ m_objs


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