Source code for sknano.generators.layered_structure_generator

# -*- coding: utf-8 -*-
"""
===================================================================================
Layered structure generator (:mod:`sknano.generators.layered_structure_generator`)
===================================================================================

.. currentmodule:: sknano.generators.layered_structure_generator

"""
from __future__ import absolute_import, division, print_function, \
    unicode_literals
__docformat__ = 'restructuredtext en'

from collections import OrderedDict
import importlib
# import numpy as np

from sknano.core import BaseClass, call_signature
from sknano.core.atoms import StructureAtoms
from sknano.core.structures import StructureBase
from .base import GeneratorBase

import configparser

__all__ = ['LayeredStructureGenerator']


[docs]class LayeredStructureGenerator(GeneratorBase, StructureBase, BaseClass): """Class for generating structures. Parameters ---------- cfgfile : :class:`~python:str` """ # call_signature = Forward() # args = Group(Optional(delimitedList(expr_item) + COMMA)) # parameters = Group(args + ZeroOrMore(kwarg_expr)) call_signature = call_signature.copy() def __init__(self, cfgfile=None, **kwargs): super().__init__(autogen=False, **kwargs) self.cfgfile = cfgfile self.fmtstr = "{cfgfile!r}" self.parser = configparser.ConfigParser() self.config = OrderedDict() self.structures = [] self.fnames = [] if cfgfile is not None: self._parse_config() self.generate() def _parse_config(self): parser = self.parser parser.read(self.cfgfile) generator_module = 'sknano.generators' del self.structures[:] for section in parser.sections(): if section == 'settings': [self.config.update({option: value}) for option, value in zip(parser[section].keys(), parser[section].values())] if self.verbose: print(self.config) continue parameters = parser[section]['parameters'] fname = '{}({})'.format(section[:-len('Generator')], parameters) self.fnames.append(fname.replace(' ', '')) call_sig = \ self.call_signature.parseString(parameters, parseAll=True)[0] try: args, kwargs = call_sig except ValueError: args, kwargs = tuple(), call_sig[0] generator = getattr(importlib.import_module(generator_module), section)(*args, **kwargs) self.structures.append(generator)
[docs] def generate(self): structures = self.structures [structure.center_centroid() for structure in structures] for layer, structure in enumerate(structures[1:], start=1): # lattice_region = structure.lattice_region dy = -structure.bounding_box.ymin + \ structures[layer-1].bounding_box.ymax - \ float(self.config.get('overlap', 0.0)) structure.translate([0, dy, 0]) atoms = StructureAtoms() [atoms.extend(structure.atoms) for structure in structures] atoms.center_centroid() atoms.assign_unique_ids() atoms.assign_unique_types() selstr = self.config.get('selection', None) if selstr is not None: atoms = atoms.select(selstr) self.structure.extend(atoms)
# self.structure.extend( # atoms.select(self.config.get('selection', 'all')))
[docs] def generate_fname(self): fname = '_on_'.join([fname for fname in reversed(self.fnames)]) return fname
[docs] def save(self, fname=None, structure_format=None, **kwargs): if fname is None: kwargs['fname'] = self.config.get('fname', self.generate_fname()) if structure_format is None: kwargs['structure_format'] = \ self.config.get('structure_format', 'xyz') super().save(**kwargs)
[docs] def todict(self): return dict(cfgfile=self.cfgfile)