From 38fca209ef9af38ca231710875e14e8d8ae54c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ne=C4=8Dada?= Date: Fri, 3 Jul 2020 23:04:53 +0300 Subject: [PATCH] Some features to enable ScatteringSystem reconstruction --- TODO.md | 5 +++-- misc/finiterectlat-modes.py | 7 ++++++- misc/lat2d_modes.py | 7 ++++++- qpms/argproc.py | 2 +- qpms/cymaterials.pyx | 17 ++++++++++++++++- 5 files changed, 32 insertions(+), 6 deletions(-) diff --git a/TODO.md b/TODO.md index a3dca51..d324c97 100644 --- a/TODO.md +++ b/TODO.md @@ -25,11 +25,12 @@ TODO list before 1.0 release * As a description of a T-matrix / particle metadata. - Nice CLI for all general enough utilities. - Remove legacy code. -- Split qpms_c.pyx. +- Split `qpms_c.pyx`. - Reduce compiler warnings. +- Serialisation (saving, loading) of `ScatteringSystem` and other structures. - Python exceptions instead of hard crashes in the C library where possible. - Scatsystem init sometimes fail due to rounding errors and hardcoded absolute tolerance - in the qpms_tmatrix_isclose() call. + in the `qpms_tmatrix_isclose()` call. - Prefix all identifiers. Maybe think about a different prefix than qpms? - Consistent indentation and style overall. - Rewrite the parallelized translation matrix, mode problem matrix generators diff --git a/misc/finiterectlat-modes.py b/misc/finiterectlat-modes.py index 87fd696..b12986e 100755 --- a/misc/finiterectlat-modes.py +++ b/misc/finiterectlat-modes.py @@ -95,7 +95,12 @@ results['inside_contour'] = inside_ellipse((results['eigval'].real, results['eig results['refractive_index_internal'] = [medium(om).n for om in results['eigval']] outfile = defaultprefix + (('_ir%s_%s.npz' % (str(iri), irname)) if iri is not None else '.npz') if a.output is None else a.output -np.savez(outfile, meta=vars(a), **results) +np.savez(outfile, meta=vars(a), + ss_positions=ss.positions, ss_fullvec_poffsets=ss.fullvec_poffsets, + ss_fullvec_psizes=ss.fullvec_psizes, + ss_bspecs_flat = np.concatenate(ss.bspecs), + ss_lattice_basis=ss.lattice_basis, ss_reciprocal_basis = ss.reciprocal_basis, + **results) logging.info("Saved to %s" % outfile) exit(0) diff --git a/misc/lat2d_modes.py b/misc/lat2d_modes.py index 6f6bcde..f7dad4b 100755 --- a/misc/lat2d_modes.py +++ b/misc/lat2d_modes.py @@ -112,7 +112,12 @@ res['inside_contour'] = inside_ellipse((res['eigval'].real, res['eigval'].imag), #del res['omega'] If contour points are not needed... #del res['ImTW'] # not if dbg=false anyway outfile = defaultprefix + ".npz" if a.output is None else a.output -np.savez(outfile, meta=vars(a), empty_freqs=np.array(empty_freqs), **res) +np.savez(outfile, meta=vars(a), empty_freqs=np.array(empty_freqs), + ss_positions=ss.positions, ss_fullvec_poffsets=ss.fullvec_poffsets, + ss_fullvec_psizes=ss.fullvec_psizes, + ss_bspecs_flat = np.concatenate(ss.bspecs), + ss_lattice_basis=ss.lattice_basis, ss_reciprocal_basis = ss.reciprocal_basis, + **res) logging.info("Saved to %s" % outfile) diff --git a/qpms/argproc.py b/qpms/argproc.py index d7cec6e..b06e9b7 100644 --- a/qpms/argproc.py +++ b/qpms/argproc.py @@ -189,7 +189,7 @@ def material_spec(string): except ValueError: try: lemat = complex(string) except ValueError as ve: - raise argpares.ArgumentTypeError("Material specification must be a supported material name %s, or a number" % (str(lorentz_drude.keys()),)) from ve + raise argparse.ArgumentTypeError("Material specification must be a supported material name %s, or a number" % (str(lorentz_drude.keys()),)) from ve return lemat class ArgParser: diff --git a/qpms/cymaterials.pyx b/qpms/cymaterials.pyx index 1730381..e2ec8eb 100644 --- a/qpms/cymaterials.pyx +++ b/qpms/cymaterials.pyx @@ -185,8 +185,23 @@ cdef qpms_epsmu_t python_epsmu_generator(cdouble omega, const void *params): em.eps, em.mu = fun(omega) return em + + cdef class EpsMuGenerator: def __init__(self, what): + if isinstance(what, str): + if what in lorentz_drude.keys(): + what = lorentz_drude[what] + else: + try: what = float(what) + except ValueError: + try: what = complex(what) + except ValueError as ve: + raise ValueError("Trying to create EpsMuGenerator from a string that can't be parsed as a number (constant refractive index) nor supported lorentz-drude key") from ve + if isinstance(what, int): + what = float(what) + if isinstance(what, (float, complex)): + what = EpsMu(what**2) if isinstance(what, EpsMu): self.holder = what self.g.function = qpms_epsmu_const_g @@ -212,7 +227,7 @@ cdef class EpsMuGenerator: self.g.function = python_epsmu_generator self.g.params = what else: - raise ValueError("Must be constructed from EpsMu, LorentzDrudeModel or MaterialInterpolator, or a python callable object that returns an (epsilon, mu) tuple.") + raise ValueError("Must be constructed from a number (refractive index), EpsMu, LorentzDrudeModel or MaterialInterpolator, or a python callable object that returns an (epsilon, mu) tuple.") property typ: def __get__(self):