Define particle / T-matrix specifications as namedtuples.

Also get rid of separate T-matrix spec sequences.


Former-commit-id: 814df45116c56e638e13d370d5be11330adad722
This commit is contained in:
Marek Nečada 2017-07-18 16:07:31 +03:00
parent cff4a2cbf1
commit 681d3817ff
2 changed files with 85 additions and 41 deletions

View File

@ -2,6 +2,16 @@ import warnings
import argparse import argparse
#import sys # for debugging purpose, TODO remove in production #import sys # for debugging purpose, TODO remove in production
import os # because of path import os # because of path
from .types import TMatrixOp, TMatrixSpec, ParticleSpec, LatticeSpec
import collections
''' # REMOVE IN PRODUCTION
ParticleSpec = collections.namedtuple('ParticleSpec', ['label', 'position', 'tmatrix_spec'])
TMatrixOp = collections.namedtuple('TMatrixOp',
['optype', 'content'])
TMatrixSpec = collections.namedtuple('TMatrixSpec',
['lMax_override', 'tmatrix_path', 'ops'])
'''
__TODOs__ = ''' __TODOs__ = '''
- Checking validity of T-matrix ops (the arguments of --tr, --sym or similar) according to what is implemented - Checking validity of T-matrix ops (the arguments of --tr, --sym or similar) according to what is implemented
@ -64,32 +74,14 @@ def add_argparse_common_options(parser):
parser.add_argument('--verbose', '-v', action='count', help='Be verbose (about computation times, mostly)') parser.add_argument('--verbose', '-v', action='count', help='Be verbose (about computation times, mostly)')
parser.add_argument('--frequency_multiplier', action='store', type=float, default=1., help='Multiplies the frequencies in the TMatrix file by a given factor.') parser.add_argument('--frequency_multiplier', action='store', type=float, default=1., help='Multiplies the frequencies in the TMatrix file by a given factor.')
def arg_preprocess_particles(pargs, d=None, return_tuple=False): def arg_preprocess_particles(pargs, d=None, return_tuple=False):
''' '''
Nanoparticle position and T-matrix path parsing Nanoparticle position and T-matrix path parsing
returns a dictionary d with keys 'particle_specs' and 'TMatrix_specs'
parser: ArgumentParser on which add_argparse_unitcell_definitions() and whose parser: ArgumentParser on which add_argparse_unitcell_definitions() and whose
parse_args() has been called. parse_args() has been called.
d['TMatrix_specs'] is a list of specs where a spec is a tuple of returns a list of ParticleSpec objects
(lMax_override, TMatrix_path, ops).
lMax_override: int or None
TMatrix_path: string
ops: iterable with operations on the T-Matrix to be processed with perform_ops()
d['particle_specs'] is an iterable of tuples (label, (xpos, ypos), TMatrix_spec_index)
TMatrix_spec_index is an index of the corresponding element of d['TMatrix_specs']
If a dictionary d is provided, the result is written into it; if d is None (default),
a new dictionary is created.
If return_tuple is true, then a tuple (particle_specs, TMatrix_specs) is returned
instead of the dictionary d.
''' '''
TMatrix_paths = dict() TMatrix_paths = dict()
lMax_overrides = dict() lMax_overrides = dict()
@ -164,40 +156,29 @@ def arg_preprocess_particles(pargs, d=None, return_tuple=False):
# if, no label given, apply to all, otherwise on the specifield particles # if, no label given, apply to all, otherwise on the specifield particles
for label in (positions.keys() if len(arg_content) == 1 else arg_content[:-1]): for label in (positions.keys() if len(arg_content) == 1 else arg_content[:-1]):
try: try:
ops[label].append((optype, arg_content[-1])) ops[label].append(TMatrixOp(optype, arg_content[-1]))
except KeyError as e: except KeyError as e:
e.args += 'Specified operation on undefined particle labeled \'%s\'' % label e.args += 'Specified operation on undefined particle labeled \'%s\'' % label
raise raise
#### Collect all the info about the particles / their T-matrices into one list #### #### Collect all the info about the particles / their T-matrices into one list ####
# Enumerate and assign all the _different_ T-matrices (without any intelligent group-theory checking, though) # get rid of the non-unique T-matrix specs (so there is only one instance living
TMatrix_specs = dict((spec, number) # of each different TMatrixSpec, possibly with multiple references to it
for (number, spec) in enumerate(set( TMatrix_specs = dict((spec, spec)
(lMax_overrides[label] if label in lMax_overrides.keys() else None, for spec in (TMatrixSpec(
lMax_overrides[label] if label in lMax_overrides.keys() else None,
TMatrix_paths[label], TMatrix_paths[label],
tuple(ops[label])) tuple(ops[label]))
for label in positions.keys() for label in positions.keys())
))) )
# particles_specs contains (label, (xpos, ypos), tmspec_index per element) # particles_specs contains (label, (xpos, ypos), tmspec per element)
particles_specs = [(label, positions[label], particles_specs = [ParticleSpec(label, positions[label],
TMatrix_specs[(lMax_overrides[label] if label in lMax_overrides.keys() else None, TMatrix_specs[(lMax_overrides[label] if label in lMax_overrides.keys() else None,
TMatrix_paths[label], TMatrix_paths[label],
tuple(ops[label]))] tuple(ops[label]))]
) for label in positions.keys()] ) for label in positions.keys()]
# This converts the TMatrix_specs dict to a list of its ex-keys in the ex-value order return particles_specs
TMatrix_specs = dict((v,k) for (k,v) in TMatrix_specs.items()) # invert dict
TMatrix_specs = [TMatrix_specs[i] for i in range(len(TMatrix_specs))] # convert to list
if d is None:
d = dict()
# TODO what if I used classes instead?
d['particle_specs'] = particles_specs
d['TMatrix_specs'] = TMatrix_specs
if return_tuple:
return (particles_specs, TMatrix_specs)
else:
return d
''' '''
import argparse, re, random, string import argparse, re, random, string

63
qpms/types.py Normal file
View File

@ -0,0 +1,63 @@
"""
Here shall be defined some types that are needed across the individual
modules of the qpms package and they do not belong logically to a single
module.
"""
import collections
'''
The namedtuples below might become classes or other objects in later versions.
'''
TMatrixOp = collections.namedtuple('TMatrixOp',
['optype', 'content'])
TMatrixSpec = collections.namedtuple('TMatrixSpec',
['lMax_override', 'tmatrix_path', 'ops'])
TMatrixSpec.__doc__ = """\
Specification of a to-be-created TMatrix object.
lMax_override: int or None. If int and lower than the cutoff degree of the
T-Matrix file located at tmatrix_path, lMax_override shall be used instead.
tmatrix_path: str. Location of the .TMatrix file to be loaded.
ops: sequence of TMatrixOp instances. The operations to be performed on
top of the loaded .TMatrix files.
"""
ParticleSpec = collections.namedtuple('ParticleSpec', ['label', 'position', 'tmatrix_spec'])
ParticleSpec.__doc___ = """\
Specification of an individual scatterer, or a component scatterer
of a lattice unit cell.
label: immutable (usually a string or None). Unique label of a unit cell
component (and the corresponding sublattice).
position: tuple of floats (or similar, such as numpy array).
tmatrix_spec: TMatrixSpec or TMatrix instance.
"""
LatticeSpec = collections.namedtuple('LatticeSpec', ['basis', 'particle_specs', 'subset'])
LatticeSpec.__doc__ = """\
Specification of a lattice, finite or infinite.
basis: tuple of basic vectors (tuples of floats or similar) (or similar,
such as 2d numpy array), preferably of reduced basis.
particle_specs: sequence of ParticleSpecs
subset: For infinite lattices, None. For finite lattices, dictionary whose
keys are the sublattice labels from particle_specs and values are sequences
of (integer) coordinate tuples indicating which scatterers are to be included
to the finite sublattice.
"""
class TMatrix(object):
pass