Initial qpms version metadata in library and output files
continuous-integration/drone/push Build is passing Details

Merge branch 'versioning'
This commit is contained in:
Marek Nečada 2022-06-21 08:53:18 +03:00
commit ac0d322246
19 changed files with 445 additions and 34 deletions

View File

@ -10,7 +10,7 @@ include(GNUInstallDirs)
project (QPMS) project (QPMS)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
macro(use_c99) macro(use_c99)
if (CMAKE_VERSION VERSION_LESS "3.1") if (CMAKE_VERSION VERSION_LESS "3.1")

View File

@ -0,0 +1,284 @@
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
# git_describe_working_tree(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the working tree (--dirty option),
# and adjusting the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
# git_local_changes(<var>)
#
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
# Uses the return code of "git diff-index --quiet HEAD --".
# Does not regard untracked files.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2020 Ryan Pavlik <ryan.pavlik@gmail.com> <abiryan@ryand.net>
# http://academic.cleardefinition.com
#
# Copyright 2009-2013, Iowa State University.
# Copyright 2013-2020, Ryan Pavlik
# Copyright 2013-2020, Contributors
# SPDX-License-Identifier: BSL-1.0
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
# Function _git_find_closest_git_dir finds the next closest .git directory
# that is part of any directory in the path defined by _start_dir.
# The result is returned in the parent scope variable whose name is passed
# as variable _git_dir_var. If no .git directory can be found, the
# function returns an empty string via _git_dir_var.
#
# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
# neither foo nor bar contain a file/directory .git. This wil return
# C:/bla/.git
#
function(_git_find_closest_git_dir _start_dir _git_dir_var)
set(cur_dir "${_start_dir}")
set(git_dir "${_start_dir}/.git")
while(NOT EXISTS "${git_dir}")
# .git dir not found, search parent directories
set(git_previous_parent "${cur_dir}")
get_filename_component(cur_dir "${cur_dir}" DIRECTORY)
if(cur_dir STREQUAL git_previous_parent)
# We have reached the root directory, we are not in git
set(${_git_dir_var}
""
PARENT_SCOPE)
return()
endif()
set(git_dir "${cur_dir}/.git")
endwhile()
set(${_git_dir_var}
"${git_dir}"
PARENT_SCOPE)
endfunction()
function(get_git_head_revision _refspecvar _hashvar)
_git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR")
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE)
else()
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE)
endif()
if(NOT "${GIT_DIR}" STREQUAL "")
file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
"${GIT_DIR}")
if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
# We've gone above the CMake root dir.
set(GIT_DIR "")
endif()
endif()
if("${GIT_DIR}" STREQUAL "")
set(${_refspecvar}
"GITDIR-NOTFOUND"
PARENT_SCOPE)
set(${_hashvar}
"GITDIR-NOTFOUND"
PARENT_SCOPE)
return()
endif()
# Check if the current source dir is a git submodule or a worktree.
# In both cases .git is a file instead of a directory.
#
if(NOT IS_DIRECTORY ${GIT_DIR})
# The following git command will return a non empty string that
# points to the super project working tree if the current
# source dir is inside a git submodule.
# Otherwise the command will return an empty string.
#
execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-parse
--show-superproject-working-tree
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT "${out}" STREQUAL "")
# If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE
${submodule})
string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE)
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE}
ABSOLUTE)
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
else()
# GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree
file(READ ${GIT_DIR} worktree_ref)
# The .git directory contains a path to the worktree information directory
# inside the parent git repo of the worktree.
#
string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
${worktree_ref})
string(STRIP ${git_worktree_dir} git_worktree_dir)
_git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR)
set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD")
endif()
else()
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${HEAD_SOURCE_FILE}")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake" @ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar}
"${HEAD_REF}"
PARENT_SCOPE)
set(${_hashvar}
"${HEAD_HASH}"
PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_describe_working_tree _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_local_changes _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(res EQUAL 0)
set(${_var}
"CLEAN"
PARENT_SCOPE)
else()
set(${_var}
"DIRTY"
PARENT_SCOPE)
endif()
endfunction()

View File

@ -0,0 +1,43 @@
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright 2009-2012, Iowa State University
# Copyright 2011-2015, Contributors
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# SPDX-License-Identifier: BSL-1.0
set(HEAD_HASH)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
else()
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
set(HEAD_HASH "${CMAKE_MATCH_1}")
endif()
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()
if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()

23
cmake/LICENSE_1_0.txt Normal file
View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import math import math
from qpms.argproc import ArgParser, make_dict_action, sslice from qpms.argproc import ArgParser, make_dict_action, sslice, annotate_pdf_metadata
figscale=3 figscale=3
ap = ArgParser(['rectlattice2d_finite', 'single_particle', 'single_lMax', 'single_omega']) ap = ArgParser(['rectlattice2d_finite', 'single_particle', 'single_lMax', 'single_omega'])
@ -44,7 +44,7 @@ import numpy as np
import qpms import qpms
from qpms.cybspec import BaseSpec from qpms.cybspec import BaseSpec
from qpms.cytmatrices import CTMatrix, TMatrixGenerator from qpms.cytmatrices import CTMatrix, TMatrixGenerator
from qpms.qpms_c import Particle from qpms.qpms_c import Particle, qpms_library_version
from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude from qpms.cymaterials import EpsMu, EpsMuGenerator, LorentzDrudeModel, lorentz_drude
from qpms.cycommon import DebugFlags, dbgmsg_enable from qpms.cycommon import DebugFlags, dbgmsg_enable
from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar from qpms import FinitePointGroup, ScatteringSystem, BesselType, eV, hbar
@ -225,7 +225,7 @@ for iri in range(ss.nirreps):
scattered_full[spi, y] += scattered_ir_unpacked[spi, y] scattered_full[spi, y] += scattered_ir_unpacked[spi, y]
if a.save_gradually: if a.save_gradually:
iriout = outfile_tmp + ".%d" % iri iriout = outfile_tmp + ".%d" % iri
np.savez(iriout, iri=iri, meta=vars(a), np.savez(iriout, iri=iri, meta={**vars(a), 'qpms_version' : qpms.__version__()},
omega=omega, wavenumber=wavenumber, nelem=nelem, wavevector=np.array(a.wavevector), phases=phases, omega=omega, wavenumber=wavenumber, nelem=nelem, wavevector=np.array(a.wavevector), phases=phases,
positions = ss.positions[:,:2], positions = ss.positions[:,:2],
scattered_ir_packed = scattered_ir[iri], scattered_ir_packed = scattered_ir[iri],
@ -251,7 +251,7 @@ if not math.isnan(a.ccd_distance):
logging.info("Far fields done") logging.info("Far fields done")
outfile = defaultprefix + ".npz" if a.output is None else a.output outfile = defaultprefix + ".npz" if a.output is None else a.output
np.savez(outfile, meta=vars(a), np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()},
omega=omega, wavenumber=wavenumber, nelem=nelem, wavevector=np.array(a.wavevector), phases=phases, omega=omega, wavenumber=wavenumber, nelem=nelem, wavevector=np.array(a.wavevector), phases=phases,
positions = ss.positions[:,:2], positions = ss.positions[:,:2],
scattered_ir_packed = scattered_ir, scattered_ir_packed = scattered_ir,
@ -355,6 +355,7 @@ if a.plot or (a.plot_out is not None):
axes[y,gg].yaxis.set_major_formatter(plt.NullFormatter()) axes[y,gg].yaxis.set_major_formatter(plt.NullFormatter())
fig.text(0, 0, str(slicepairs[spi]), horizontalalignment='left', verticalalignment='bottom') fig.text(0, 0, str(slicepairs[spi]), horizontalalignment='left', verticalalignment='bottom')
pp.savefig() pp.savefig()
annotate_pdf_metadata(pp, scriptname="finiterectlat-constant-driving.py")
pp.close() pp.close()
exit(0) exit(0)

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import math import math
from qpms.argproc import ArgParser from qpms.argproc import ArgParser, annotate_pdf_metadata
ap = ArgParser(['rectlattice2d_finite', 'background_analytical', 'single_particle', 'single_lMax', ]) ap = ArgParser(['rectlattice2d_finite', 'background_analytical', 'single_particle', 'single_lMax', ])
@ -100,7 +100,7 @@ results['inside_contour'] = inside_ellipse((results['eigval'].real, results['eig
results['refractive_index_internal'] = [medium(om).n for om in results['eigval']] 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 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), 'qpms_version' : qpms.__version__()}, **results)
logging.info("Saved to %s" % outfile) logging.info("Saved to %s" % outfile)
exit(0) exit(0)
@ -110,7 +110,7 @@ if a.plot or (a.plot_out is not None):
import matplotlib import matplotlib
matplotlib.use('pdf') matplotlib.use('pdf')
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
fig = plt.figure() fig = plt.figure()
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
ax.plot(sinalpha_list, σ_ext*1e12,label='$\sigma_\mathrm{ext}$') ax.plot(sinalpha_list, σ_ext*1e12,label='$\sigma_\mathrm{ext}$')
@ -121,7 +121,9 @@ if a.plot or (a.plot_out is not None):
ax.set_ylabel('$\sigma/\mathrm{\mu m^2}$') ax.set_ylabel('$\sigma/\mathrm{\mu m^2}$')
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
fig.savefig(plotfile) with PdfPages(plotfile) as pdf:
pdf.savefig(fig)
annotate_pdf_metadata(pdf, scriptname='finiterectlat-modes.py')
exit(0) exit(0)

View File

@ -111,7 +111,7 @@ for i, omega in enumerate(ap.allomegas):
σ_scat_arr_ir[i, j, iri] = np.vdot(fi,np.dot(translation_matrix, fi)).real/wavenumber**2 σ_scat_arr_ir[i, j, iri] = np.vdot(fi,np.dot(translation_matrix, fi)).real/wavenumber**2
if a.save_gradually: if a.save_gradually:
iriout = outfile_tmp + ".%d.%d" % (i, iri) iriout = outfile_tmp + ".%d.%d" % (i, iri)
np.savez(iriout, omegai=i, iri=iri, meta=vars(a), omega=omega, k_sph=k_sph_list, k_cart = k_cart_arr, E_cart=E_cart_list, E_sph=np.array(E_sph), np.savez(iriout, omegai=i, iri=iri, meta={**vars(a), 'qpms_version' : qpms.__version__()}, omega=omega, k_sph=k_sph_list, k_cart = k_cart_arr, E_cart=E_cart_list, E_sph=np.array(E_sph),
wavenumber=wavenumber, σ_ext_list_ir=σ_ext_arr_ir[i,:,iri], σ_scat_list_ir=σ_scat_list_ir[i,:,iri]) wavenumber=wavenumber, σ_ext_list_ir=σ_ext_arr_ir[i,:,iri], σ_scat_list_ir=σ_scat_list_ir[i,:,iri])
logging.info("partial results saved to %s"%iriout) logging.info("partial results saved to %s"%iriout)
@ -122,7 +122,8 @@ for i, omega in enumerate(ap.allomegas):
outfile = defaultprefix + ".npz" if a.output is None else a.output outfile = defaultprefix + ".npz" if a.output is None else a.output
np.savez(outfile, meta=vars(a), k_sph=k_sph_list, k_cart = k_cart_arr, E_cart=E_cart_list, E_sph=np.array(E_sph), np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()},
k_sph=k_sph_list, k_cart = k_cart_arr, E_cart=E_cart_list, E_sph=np.array(E_sph),
σ_ext=σ_ext_arr,σ_abs=σ_abs_arr,σ_scat=σ_scat_arr, σ_ext=σ_ext_arr,σ_abs=σ_abs_arr,σ_scat=σ_scat_arr,
σ_ext_ir=σ_ext_arr_ir,σ_abs_ir=σ_abs_arr_ir,σ_scat_ir=σ_scat_arr_ir, omega=ap.allomegas, wavenumbers=wavenumbers σ_ext_ir=σ_ext_arr_ir,σ_abs_ir=σ_abs_arr_ir,σ_scat_ir=σ_scat_arr_ir, omega=ap.allomegas, wavenumbers=wavenumbers
) )
@ -231,6 +232,7 @@ if a.plot or (a.plot_out is not None):
pdf.savefig(fig) pdf.savefig(fig)
plt.close(fig) plt.close(fig)
annotate_pdf_metadata(pdf, scriptname="finiterectlat-scatter.py")
exit(0) exit(0)

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import math import math
from qpms.argproc import ArgParser from qpms.argproc import ArgParser, annotate_pdf_metadata
ap = ArgParser(['rectlattice2d', 'single_particle', 'single_lMax', 'omega_seq']) ap = ArgParser(['rectlattice2d', 'single_particle', 'single_lMax', 'omega_seq'])
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)') ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
@ -93,7 +93,7 @@ for i, omega in enumerate(omegas):
SVs[iri][i] = np.linalg.svd(ImTW_packed, compute_uv = False) SVs[iri][i] = np.linalg.svd(ImTW_packed, compute_uv = False)
outfile = defaultprefix + ".npz" if a.output is None else a.output outfile = defaultprefix + ".npz" if a.output is None else a.output
np.savez(outfile, meta=vars(a), omegas=omegas, wavenumbers=wavenumbers, SVs=np.concatenate(SVs, axis=-1), irrep_names=ss1.irrep_names, irrep_sizes=ss1.saecv_sizes, unitcell_area=ss.unitcell_volume np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, omegas=omegas, wavenumbers=wavenumbers, SVs=np.concatenate(SVs, axis=-1), irrep_names=ss1.irrep_names, irrep_sizes=ss1.saecv_sizes, unitcell_area=ss.unitcell_volume
) )
logging.info("Saved to %s" % outfile) logging.info("Saved to %s" % outfile)
@ -102,6 +102,7 @@ if a.plot or (a.plot_out is not None):
import matplotlib import matplotlib
matplotlib.use('pdf') matplotlib.use('pdf')
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
fig = plt.figure() fig = plt.figure()
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
@ -119,7 +120,9 @@ if a.plot or (a.plot_out is not None):
ax.legend() ax.legend()
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
fig.savefig(plotfile) with PdfPages(plotfile) as pdf:
pdf.savefig(fig)
annotate_pdf_metadata(pdf, scriptname='infiniterectlat-k0realfreqsvd.py')
exit(0) exit(0)

View File

@ -2,7 +2,7 @@
import math import math
pi = math.pi pi = math.pi
from qpms.argproc import ArgParser from qpms.argproc import ArgParser, annotate_pdf_metadata
ap = ArgParser(['rectlattice2d', 'single_particle', 'single_lMax', 'omega_seq_real_ng', 'planewave']) ap = ArgParser(['rectlattice2d', 'single_particle', 'single_lMax', 'omega_seq_real_ng', 'planewave'])
ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)') ap.add_argument("-o", "--output", type=str, required=False, help='output path (if not provided, will be generated automatically)')
@ -106,7 +106,7 @@ with pgsl_ignore_error(15): # avoid gsl crashing on underflow
σ_abs_arr = σ_ext_arr - σ_scat_arr σ_abs_arr = σ_ext_arr - σ_scat_arr
outfile = defaultprefix + ".npz" if a.output is None else a.output outfile = defaultprefix + ".npz" if a.output is None else a.output
np.savez(outfile, meta=vars(a), dir_sph=dir_sph_list, k_cart = k_cart_arr, omega = ap.allomegas, E_cart = E_cart_list, wavenumbers= wavenumbers, σ_ext=σ_ext_arr,σ_abs=σ_abs_arr,σ_scat=σ_scat_arr, unitcell_area=ss.unitcell_volume np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, dir_sph=dir_sph_list, k_cart = k_cart_arr, omega = ap.allomegas, E_cart = E_cart_list, wavenumbers= wavenumbers, σ_ext=σ_ext_arr,σ_abs=σ_abs_arr,σ_scat=σ_scat_arr, unitcell_area=ss.unitcell_volume
) )
logging.info("Saved to %s" % outfile) logging.info("Saved to %s" % outfile)
@ -214,6 +214,6 @@ if a.plot or (a.plot_out is not None):
pdf.savefig(fig) pdf.savefig(fig)
plt.close(fig) plt.close(fig)
annotate_pdf_metadata(pdf)
exit(0) exit(0)

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import math import math
from qpms.argproc import ArgParser, sfloat from qpms.argproc import ArgParser, sfloat, annotate_pdf_metadata
ap = ArgParser(['const_real_background', 'lattice2d', 'multi_particle']) # TODO general analytical background ap = ArgParser(['const_real_background', 'lattice2d', 'multi_particle']) # TODO general analytical background
@ -112,7 +112,7 @@ res['inside_contour'] = inside_ellipse((res['eigval'].real, res['eigval'].imag),
#del res['omega'] If contour points are not needed... #del res['omega'] If contour points are not needed...
#del res['ImTW'] # not if dbg=false anyway #del res['ImTW'] # not if dbg=false anyway
outfile = defaultprefix + ".npz" if a.output is None else a.output outfile = defaultprefix + ".npz" if a.output is None else a.output
np.savez(outfile, meta=vars(a), empty_freqs=np.array(empty_freqs), np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, empty_freqs=np.array(empty_freqs),
ss_positions=ss.positions, ss_fullvec_poffsets=ss.fullvec_poffsets, ss_positions=ss.positions, ss_fullvec_poffsets=ss.fullvec_poffsets,
ss_fullvec_psizes=ss.fullvec_psizes, ss_fullvec_psizes=ss.fullvec_psizes,
ss_bspecs_flat = np.concatenate(ss.bspecs), ss_bspecs_flat = np.concatenate(ss.bspecs),
@ -132,6 +132,7 @@ if a.plot or (a.plot_out is not None):
import matplotlib import matplotlib
matplotlib.use('pdf') matplotlib.use('pdf')
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
fig = plt.figure() fig = plt.figure()
ax = fig.add_subplot(111,) ax = fig.add_subplot(111,)
@ -155,8 +156,11 @@ if a.plot or (a.plot_out is not None):
ax.set_ylim([ymin-.1*yspan, ymax+.1*yspan]) ax.set_ylim([ymin-.1*yspan, ymax+.1*yspan])
ax.set_xlabel('$\hbar \Re \omega / \mathrm{eV}$') ax.set_xlabel('$\hbar \Re \omega / \mathrm{eV}$')
ax.set_ylabel('$\hbar \Im \omega / \mathrm{meV}$') ax.set_ylabel('$\hbar \Im \omega / \mathrm{meV}$')
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
fig.savefig(plotfile) with PdfPages(plotfile) as pdf:
pdf.savefig(fig)
annotate_pdf_metadata(pdf, scriptname='lat2d_modes.py')
exit(0) exit(0)

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import math import math
from qpms.argproc import ArgParser, sfloat from qpms.argproc import ArgParser, sfloat, annotate_pdf_metadata
ap = ArgParser(['background', 'lattice2d', 'multi_particle', 'omega_seq']) ap = ArgParser(['background', 'lattice2d', 'multi_particle', 'omega_seq'])
@ -88,7 +88,7 @@ for i, omega in enumerate(omegas):
SVs[iri][i] = np.linalg.svd(ImTW_packed, compute_uv = False) SVs[iri][i] = np.linalg.svd(ImTW_packed, compute_uv = False)
outfile = defaultprefix + ".npz" if a.output is None else a.output outfile = defaultprefix + ".npz" if a.output is None else a.output
np.savez(outfile, meta=vars(a), omegas=omegas, wavenumbers=wavenumbers, SVs=np.concatenate(SVs, axis=-1), irrep_names=ss1.irrep_names, irrep_sizes=ss1.saecv_sizes, unitcell_area=ss.unitcell_volume np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, omegas=omegas, wavenumbers=wavenumbers, SVs=np.concatenate(SVs, axis=-1), irrep_names=ss1.irrep_names, irrep_sizes=ss1.saecv_sizes, unitcell_area=ss.unitcell_volume
) )
logging.info("Saved to %s" % outfile) logging.info("Saved to %s" % outfile)
@ -97,6 +97,7 @@ if a.plot or (a.plot_out is not None):
import matplotlib import matplotlib
matplotlib.use('pdf') matplotlib.use('pdf')
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
fig = plt.figure() fig = plt.figure()
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
@ -120,7 +121,9 @@ if a.plot or (a.plot_out is not None):
ax.legend() ax.legend()
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
fig.savefig(plotfile) with PdfPages(plotfile) as pdf:
pdf.savefig(fig)
annotate_pdf_metadata(pdf, scriptname='lat2d_realfreqsvd.py')
exit(0) exit(0)

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import math import math
from qpms.argproc import ArgParser from qpms.argproc import ArgParser, annotate_pdf_metadata
ap = ArgParser(['rectlattice2d', 'const_real_background', 'single_particle', 'single_lMax']) # const_real_background needed for calculation of the diffracted orders ap = ArgParser(['rectlattice2d', 'const_real_background', 'single_particle', 'single_lMax']) # const_real_background needed for calculation of the diffracted orders
ap.add_argument("-k", nargs=2, type=float, required=True, help='k vector', metavar=('K_X', 'K_Y')) ap.add_argument("-k", nargs=2, type=float, required=True, help='k vector', metavar=('K_X', 'K_Y'))
@ -116,7 +116,7 @@ res['refractive_index_internal'] = [emg(om).n for om in res['eigval']]
#del res['omega'] If contour points are not needed... #del res['omega'] If contour points are not needed...
#del res['ImTW'] # not if dbg=false anyway #del res['ImTW'] # not if dbg=false anyway
outfile = defaultprefix + ".npz" if a.output is None else a.output outfile = defaultprefix + ".npz" if a.output is None else a.output
np.savez(outfile, meta=vars(a), empty_freqs=np.array(empty_freqs), np.savez(outfile, meta={**vars(a), 'qpms_version' : qpms.__version__()}, empty_freqs=np.array(empty_freqs),
ss_positions=ss.positions, ss_fullvec_poffsets=ss.fullvec_poffsets, ss_positions=ss.positions, ss_fullvec_poffsets=ss.fullvec_poffsets,
ss_fullvec_psizes=ss.fullvec_psizes, ss_fullvec_psizes=ss.fullvec_psizes,
ss_bspecs_flat = np.concatenate(ss.bspecs), ss_bspecs_flat = np.concatenate(ss.bspecs),
@ -133,6 +133,7 @@ if a.plot or (a.plot_out is not None):
import matplotlib import matplotlib
matplotlib.use('pdf') matplotlib.use('pdf')
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
fig = plt.figure() fig = plt.figure()
ax = fig.add_subplot(111,) ax = fig.add_subplot(111,)
@ -156,8 +157,11 @@ if a.plot or (a.plot_out is not None):
ax.set_ylim([ymin-.1*yspan, ymax+.1*yspan]) ax.set_ylim([ymin-.1*yspan, ymax+.1*yspan])
ax.set_xlabel('$\hbar \Re \omega / \mathrm{eV}$') ax.set_xlabel('$\hbar \Re \omega / \mathrm{eV}$')
ax.set_ylabel('$\hbar \Im \omega / \mathrm{meV}$') ax.set_ylabel('$\hbar \Im \omega / \mathrm{meV}$')
plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out plotfile = defaultprefix + ".pdf" if a.plot_out is None else a.plot_out
fig.savefig(plotfile) with PdfPages(plotfile) as pdf:
pdf.savefig(fig)
annotate_pdf_metadata(pdf, scriptname="rectlat_simple_modes.py")
exit(0) exit(0)

View File

@ -7,15 +7,23 @@ find_package(LAPACK REQUIRED)
# and other not very relevant warnings # and other not very relevant warnings
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-int-in-bool-context -Wno-comment") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-int-in-bool-context -Wno-comment")
# version file
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/version.c.in" "${CMAKE_CURRENT_BINARY_DIR}/version.c" @ONLY)
list(APPEND SOURCES "${CMAKE_CURRENT_BINARY_DIR}/version.c" version.h)
#includes #includes
set (DIRS ${GSL_INCLUDE_DIRS} ${GSLCBLAS_INCLUDE_DIRS}) set (DIRS ${GSL_INCLUDE_DIRS} ${GSLCBLAS_INCLUDE_DIRS})
include_directories(${DIRS}) include_directories(${DIRS})
add_library (qpms SHARED translations.c tmatrices.c vecprint.c vswf.c wigner.c ewald.c add_library (qpms SHARED translations.c tmatrices.c vecprint.c vswf.c wigner.c ewald.c
ewaldsf.c pointgroups.c latticegens.c ewaldsf.c pointgroups.c latticegens.c
lattices2d.c gaunt.c error.c legendre.c symmetries.c vecprint.c lattices2d.c gaunt.c error.c legendre.c symmetries.c vecprint.c
bessel.c own_zgemm.c parsing.c scatsystem.c materials.c drudeparam_data.c bessel.c own_zgemm.c parsing.c scatsystem.c materials.c drudeparam_data.c
lll.c beyn.c trivialgroup.c lll.c beyn.c trivialgroup.c version.c
) )
use_c99() use_c99()

View File

@ -1,5 +1,3 @@
from pkg_resources import get_distribution
__version__ = get_distribution('qpms').version
import os as __os import os as __os
from sys import platform as __platform from sys import platform as __platform
@ -7,7 +5,7 @@ from sys import platform as __platform
import warnings as __warnings import warnings as __warnings
try: try:
from .qpms_c import PointGroup, FinitePointGroup, FinitePointGroupElement, Particle, scatsystem_set_nthreads, ScatteringSystem, ScatteringMatrix, pitau, set_gsl_pythonic_error_handling, pgsl_ignore_error, gamma_inc, lll_reduce from .qpms_c import PointGroup, FinitePointGroup, FinitePointGroupElement, Particle, scatsystem_set_nthreads, ScatteringSystem, ScatteringMatrix, pitau, set_gsl_pythonic_error_handling, pgsl_ignore_error, gamma_inc, lll_reduce, qpms_library_version
except ImportError as ex: except ImportError as ex:
if __platform == "linux" or __platform == "linux2": if __platform == "linux" or __platform == "linux2":
if 'LD_LIBRARY_PATH' not in __os.environ.keys(): if 'LD_LIBRARY_PATH' not in __os.environ.keys():
@ -24,6 +22,11 @@ from .cymaterials import MaterialInterpolator, EpsMu, LorentzDrudeModel, lorentz
from .cycommon import dbgmsg_enable, dbgmsg_disable, dbgmsg_active, BesselType, VSWFType from .cycommon import dbgmsg_enable, dbgmsg_disable, dbgmsg_active, BesselType, VSWFType
from .cywaves import vswf_single from .cywaves import vswf_single
def __version__():
from pkg_resources import get_distribution
librev = qpms_library_version()
return get_distribution('qpms').version + (("lr:"+librev) if librev else "")
#from .qpms_p import * # don't import automatically (adds around 0.5 s delay and depends on scipy) #from .qpms_p import * # don't import automatically (adds around 0.5 s delay and depends on scipy)
from .constants import * from .constants import *

View File

@ -540,3 +540,22 @@ class ArgParser:
plist.extend([Particle(pos, t, bspec=bspec) for pos in poss]) plist.extend([Particle(pos, t, bspec=bspec) for pos in poss])
return plist return plist
#TODO perhaps move into another module
def annotate_pdf_metadata(pdfPages, scriptname=None, keywords=None, author=None, title=None, subject=None, **kwargs):
"""Adds QPMS version-related metadata to a matplotlib PdfPages object
Use before closing the PDF file.
"""
from .qpms_c import qpms_library_version
d = pdfPages.infodict()
d['Creator'] = "QPMS%s (lib rev. %s), https://qpms.necada.org" % (
"" if scriptname is None else (" "+scriptname), qpms_library_version())
if author is not None:
d['Author'] = author
if title is not None:
d['Title'] = title
if subject is not None:
d['Subject'] = subject
if keywords is not None:
d['Keywords'] = ' '.join(keywords)
d.update(kwargs)

View File

@ -17,6 +17,9 @@ from .cymaterials cimport EpsMuGenerator, EpsMu
from libc.stdlib cimport malloc, free, calloc from libc.stdlib cimport malloc, free, calloc
import warnings import warnings
def qpms_library_version():
return "git_" + qpms_version_git_sha1.decode('utf-8')
from cython.parallel cimport prange, parallel from cython.parallel cimport prange, parallel
from cython cimport boundscheck, wraparound from cython cimport boundscheck, wraparound

View File

@ -4,6 +4,9 @@ ctypedef double complex cdouble
from libc.stdint cimport * from libc.stdint cimport *
cdef extern from "version.h":
const char *qpms_version_git_sha1
cdef extern from "gsl/gsl_errno.h": cdef extern from "gsl/gsl_errno.h":
ctypedef void gsl_error_handler_t (const char *reason, const char *file, ctypedef void gsl_error_handler_t (const char *reason, const char *file,
int line, int gsl_errno) int line, int gsl_errno)

2
qpms/version.c.in Normal file
View File

@ -0,0 +1,2 @@
#define QPMS_GIT_SHA1 "@GIT_SHA1@"
const char qpms_version_git_sha1[] = QPMS_GIT_SHA1;

4
qpms/version.h Normal file
View File

@ -0,0 +1,4 @@
#ifndef QPMS_VERSION_H
#define QPMS_VERSION_H
extern const char qpms_version_git_sha1[];
#endif //QPMS_VERSION_H