Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Scientific Software
CrysFML
Commits
c47f28f4
Commit
c47f28f4
authored
Jul 22, 2021
by
Elisa Rebolini
Browse files
Merge branch 'feature-python_api-build_wheels' into 'master'
Feature - Python_api wheels See merge request
!17
parents
dc5abf95
1975c8cf
Pipeline
#10482
passed with stages
in 13 minutes and 19 seconds
Changes
20
Pipelines
1
Show whitespace changes
Inline
Side-by-side
.github/workflows/build_variants.yml
0 → 100644
View file @
c47f28f4
name
:
Python libs
on
:
push
:
branches
:
[
master
]
pull_request
:
branches
:
[
master
]
# schedule:
# # Every day at 1am
# - cron: '0 1 * * *'
jobs
:
get_Latest
:
runs-on
:
ubuntu-latest
if
:
"
!contains(github.event.head_commit.message,
'[ci
skip]')"
steps
:
-
name
:
Checkout ILL repo
run
:
|
git clone https://code.ill.fr/scientific-software/crysfml/ ./
git checkout feature-python_api-build_wheels
rm -rf ./.git ./Html
-
uses
:
actions/upload-artifact@v2
with
:
name
:
CrysFML_SRC
path
:
${{ github.workspace }}
retention-days
:
1
create-Linux
:
runs-on
:
ubuntu-latest
needs
:
get_Latest
steps
:
-
uses
:
actions/download-artifact@v2
with
:
name
:
CrysFML_SRC
-
name
:
Build manylinux wheels
run
:
|
chmod +x ./Scripts/buildscript.sh
docker run -e PLAT=manylinux2010_x86_64 -v ${{ github.workspace }}:/io quay.io/pypa/manylinux2010_x86_64 /io/Scripts/buildscript.sh
-
uses
:
actions/upload-artifact@v2
with
:
name
:
CrysFML - Linux
path
:
${{ github.workspace }}/dist/*.whl
create-OSX
:
strategy
:
max-parallel
:
4
matrix
:
python-version
:
[
'
3.8'
]
os
:
[
macos-10.15
]
gcc_v
:
[
10
]
# Version of GFortran we want to use.
runs-on
:
${{ matrix.os }}
needs
:
get_Latest
steps
:
-
uses
:
actions/download-artifact@v2
with
:
name
:
CrysFML_SRC
-
name
:
Setup python
uses
:
actions/setup-python@v1
with
:
python-version
:
${{matrix.python-version}}
-
name
:
Install cmake
run
:
pip3 install cmake delocate wheel
-
name
:
Build CFML (OSX)
env
:
FC
:
gfortran-${{ matrix.gcc_v }}
CC
:
gcc-${{ matrix.gcc_v }}
run
:
|
pip3 wheel ./ --no-deps -w ./old/
delocate-wheel -w dist -v ./old/*.whl
-
uses
:
actions/upload-artifact@v2
with
:
name
:
CrysFML - MacOS
path
:
./dist/*.whl
create-Windows
:
strategy
:
max-parallel
:
1
matrix
:
python-version
:
[
'
3.6'
,
'
3.7'
]
os
:
[
windows-latest
]
runs-on
:
${{ matrix.os }}
steps
:
-
uses
:
actions/checkout@v2
-
uses
:
conda-incubator/setup-miniconda@v2
with
:
auto-update-conda
:
true
python-version
:
${{ matrix.python-version }}
auto-activate-base
:
true
-
uses
:
msys2/setup-msys2@v2
with
:
msystem
:
MSYS
install
:
cmake mingw-w64-x86_64-toolchain
update
:
true
path-type
:
inherit
-
name
:
Build CFML
shell
:
msys2 {0}
id
:
build
run
:
python setup.py bdist_wheel
env
:
MINGW_ARCH
:
MINGW64
-
uses
:
actions/upload-artifact@v2
with
:
name
:
CrysFML - Windows
path
:
./dist/*.whl
Upload_Artifacts
:
runs-on
:
ubuntu-latest
needs
:
[
create-Linux
,
create-OSX
]
steps
:
-
uses
:
actions/download-artifact@v2
-
name
:
What is downloaded
run
:
|
ls -al
-
name
:
Upload Artifacts GitHub releases
uses
:
ncipollo/release-action@v1
with
:
draft
:
false
prerelease
:
true
allowUpdates
:
true
replacesArtifacts
:
true
token
:
${{ secrets.GITHUB_TOKEN }}
artifacts
:
"
./**/*.whl"
tag
:
"
CurrentBuild"
body
:
"
This
is
a
build
of
the
CFML
libraries."
.gitignore
View file @
c47f28f4
...
...
@@ -37,3 +37,12 @@
# Directories
Build
.idea/
build/
CFML.egg-info/
dist/
*.whl
CMakeLists.txt
View file @
c47f28f4
...
...
@@ -14,6 +14,7 @@ option(HEAP_ARRAYS "Put arrays in heap instead of stack (only for Windows ifort)
option
(
PROG_EX
"Build the Program Examples"
ON
)
option
(
PYTHON_API
"Build Python API"
OFF
)
option
(
QPARALLEL
"qparallel option for Ifort on Windows"
ON
)
option
(
PYSETUP
"Building from setup.py"
OFF
)
if
(
DEFINED CMAKE_Fortran_COMPILER
)
set
(
CMAKE_Fortran_COMPILER
${
CMAKE_Fortran_COMPILER
}
CACHE STRING
"The Fortran compiler. One of 'ifort', 'g95' or 'gfortran'."
)
...
...
@@ -52,16 +53,34 @@ message(STATUS "CrysFML installation path set to ${CRYSFML_PREFIX}")
# Include and library paths for Python.
# They must be set by the user.
if
(
DEFINED PYTHON_LIBRARY_PATH
)
set
(
PYTHON_LIBRARY_PATH
${
PYTHON_LIBRARY_PATH
}
CACHE PATH
"Python library path"
)
else
()
set
(
PYTHON_LIBRARY_PATH
""
CACHE PATH
"Python library path"
)
endif
()
if
(
DEFINED PYTHON_INTERPRETER_PATH
)
set
(
PYTHON_INTERPRETER_PATH
${
PYTHON_INTERPRETER_PATH
}
CACHE PATH
"Python interpreter path"
)
else
()
set
(
PYTHON_INTERPRETER_PATH
""
CACHE PATH
"Python interpreter path"
)
endif
()
# if(DEFINED PYTHON_LIBRARY_PATH)
# set(PYTHON_LIBRARY_PATH ${PYTHON_LIBRARY_PATH} CACHE PATH "Python library path")
# else()
# set(PYTHON_LIBRARY_PATH "" CACHE PATH "Python library path")
# endif()
# if(DEFINED PYTHON_INTERPRETER_PATH)
# set(PYTHON_INTERPRETER_PATH ${PYTHON_INTERPRETER_PATH} CACHE PATH "Python interpreter path")
# else()
# set(PYTHON_INTERPRETER_PATH "" CACHE PATH "Python interpreter path")
# endif()
# Use CMake v3.12+ FindPython3 to find the system-compatible interpreter *and* libraries at once
# This solves a potential issue on convoluted Windows build systems which have multiple
# python interpreters, some of which do not have build-system compatibility (I'm looking at you, msys2 python)
# In such a case FindPythonInterp might point to the wrong python interpreter and then further configuration
# steps will fail to find any (or any compatible) libraries which match the interpreter.
# find_package(Python3 COMPONENTS Interpreter Development)
# # Since FindPython3 and FindPythonInterp set different variables, fake the FindPythonInterp result
# # to prevent it running if called by, e.g., FindPybind11
# if(Python3_FOUND)
# set(PYTHONINTERP_FOUND ON)
# set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
# message(STATUS "USING PYTHON: " ${PYTHON_EXECUTABLE})
# # set(PYTHON_INTERPRETER_PATH ${Python3_EXECUTABLE})
# set(PYTHON_VERSION_STRING "${Python3_VERSION}")
# set(PYTHON_VERSION_MAJOR ${Python3_VERSION_MAJOR})
# set(PYTHON_VERSION_MINOR ${Python3_VERSION_MINOR})
# set(PYTHON_VERSION_PATCH ${Python3_VERSION_PATCH})
# endif()
# Include and library paths for HDF5.
# They must be set by the user.
...
...
Program_Examples/ReadNeXuS/CMakeLists.txt
View file @
c47f28f4
...
...
@@ -20,7 +20,7 @@ target_link_libraries(read_nexus crysfml)
link_directories
(
${
HDF5_LIBRARY_DIR
}
)
target_link_libraries
(
read_nexus
${
HDF5_LIBRARIES
}
)
if
(
WIN32
)
if
(
WIN32
OR MSYS
)
get_filename_component
(
COMPILER_NAME
${
CMAKE_Fortran_COMPILER
}
NAME_WE
)
if
(
COMPILER_NAME STREQUAL ifort
)
# Copy hdf5.dll hdf5_f90cstub.dll hdf5_fortran.dll
...
...
Python_API/Src/API_Atom_TypeDef.py
View file @
c47f28f4
...
...
@@ -42,7 +42,7 @@ class Atom(CFML_api.FortranBindedClass):
def
__str__
(
self
):
xyz
=
self
.
xyz
return
'ATOM %s %s %s %s %s %s %s'
%
(
self
.
label
,
self
.
chemical_symbol
,
str
(
xyz
[
0
]),
str
(
xyz
[
1
]),
str
(
xyz
[
2
]),
self
.
biso
,
s
elf
.
site_multiplicity
)
return
'ATOM %s %s %s %s %s %s
%s %s
%s'
%
(
self
.
label
,
self
.
chemical_symbol
,
str
(
xyz
[
0
]),
str
(
xyz
[
1
]),
str
(
xyz
[
2
]),
str
(
self
.
biso
)
,
s
tr
(
self
.
occ
),
str
(
self
.
moment
),
str
(
self
.
formal_charge
)
)
@
property
def
label
(
self
):
...
...
@@ -343,7 +343,12 @@ class AtomList(CFML_api.FortranBindedClass):
"""
def
__init__
(
self
,
string_array
=
None
):
CFML_api
.
FortranBindedClass
.
__init__
(
self
)
self
.
_mult
=
True
self
.
_adp
=
True
if
string_array
:
self
.
_mult
=
False
self
.
_adp
=
False
dict
=
CFML_api
.
crysfml_api
.
atom_typedef_atomlist_from_CIF_string_array
(
string_array
)
self
.
_set_fortran_address
(
dict
[
"AtomList"
])
...
...
@@ -366,7 +371,7 @@ class AtomList(CFML_api.FortranBindedClass):
@
property
def
natoms
(
self
):
"""
t
otal number of atoms in the list
T
otal number of atoms in the list
"""
return
CFML_api
.
crysfml_api
.
atom_typedef_get_natoms
(
self
.
get_fortran_address
())[
"natoms"
]
...
...
@@ -374,3 +379,29 @@ class AtomList(CFML_api.FortranBindedClass):
""" Print the list of atoms. """
CFML_api
.
crysfml_api
.
atom_typedef_write_atom_list
(
self
.
get_fortran_address
())
def
set_mult_occ_cif
(
self
,
spg
):
"""
Update the multiplicity and modify the occupancy when reading from a CIF array,
in order to be in agreement with the definitions of Sfac in CrysFML
This needs to be run when the AtomList is initialised from a CIF-like stringarray
rather than from the class CIFFile
"""
if
(
self
.
_mult
==
False
):
CFML_api
.
crysfml_api
.
atom_typedef_atomlist_reset_occ_cif
(
self
.
get_fortran_address
(),
spg
.
get_fortran_address
())
self
.
_mult
=
True
else
:
print
(
"Warning: multiplicity and occupancy have already been set"
)
def
set_all_anisotropic_displacement_parameters_cif
(
self
,
cell
):
"""
Update all Atom fields for Us, Bs and betas
This needs to be run when the AtomList is initialised from a CIF-like stringarray
rather than from the class CIFFile
"""
if
(
self
.
_adp
==
False
):
CFML_api
.
crysfml_api
.
atom_typedef_atomlist_set_all_adp_cif
(
self
.
get_fortran_address
(),
cell
.
get_fortran_address
())
self
.
_adp
=
True
else
:
print
(
"Warning: Anisotropic Displacement Parameters have already been set"
)
Python_API/Src/API_Crystal_Metrics.py
View file @
c47f28f4
...
...
@@ -170,3 +170,72 @@ class Cell(CFML_api.FortranBindedClass):
return
CFML_api
.
crysfml_api
.
crystal_metrics_get_CartType
(
self
.
get_fortran_address
())[
"CartType"
]
def
k_to_cart_vector
(
code
,
vector
,
cell
):
"""
Convert a vector in crystal space to cartesian components
The value of code has been extended to use also the Busing-Levy
Cartesian system as reference also for direct and reciprocal space.
Codes:
The Cartesian frame is that defined by the setting of the Cell object
D: The components are given with respect to basis (a,b,c)
R: The components are given with respect to basis (a*,b*,c*)
BL: The components are given with respect to basis (a*,b*,c*) but
the Cartesian frame is that defined by Busing and Levy
BLD: The components are given with respect to basis (a,b,c) but
the Cartesian frame is that defined by Busing and Levy
...
Parameters
----------
code : str
Cartesian frame
vector : np.array[dtype='float32', ndim=1]
kx,ky,kz coordinates
cell : CMFL_api.crysfml_api.Cell
Returns:
np.array[dtype='float32', ndim=1] : coordinates in the chosen cartesian frame
"""
return
CFML_api
.
crysfml_api
.
crystal_metrics_cart_vector
(
code
,
vector
,
cell
.
get_fortran_address
())[
"cart_vec"
]
def
k_to_cart_unitary_vector
(
code
,
vector
,
cell
):
"""
Convert a vector in crystal space to unitary cartesian components
The value of code has been extended to use also the Busing-Levy
Cartesian system as reference also for direct and reciprocal space.
Codes:
The Cartesian frame is that defined by the setting of the Cell object
D: The components are given with respect to basis (a,b,c)
R: The components are given with respect to basis (a*,b*,c*)
BL: The components are given with respect to basis (a*,b*,c*) but
the Cartesian frame is that defined by Busing and Levy
BLD: The components are given with respect to basis (a,b,c) but
the Cartesian frame is that defined by Busing and Levy
...
Parameters
----------
code : str
Cartesian frame
vector : np.array[dtype='float32', ndim=1]
kx,ky,kz coordinates
cell : CMFL_api.crysfml_api.Cell
Returns:
np.array[dtype='float32', ndim=1] : coordinates in the chosen cartesian frame
"""
return
CFML_api
.
crysfml_api
.
crystal_metrics_cart_u_vector
(
code
,
vector
,
cell
.
get_fortran_address
())[
"cart_vec"
]
def
betas_from_biso
(
biso
,
cell
):
"""
Get Betas from Biso
...
Parameters
----------
biso : float32
cell : CMFL_api.crysfml_api.Cell
Returns
np.array[dtype='float32', ndim=1] : betas[0:5] b11, b22, b33, b12, b13, b23
"""
return
CFML_api
.
crysfml_api
.
crystal_metrics_get_betas_from_biso
(
cell
.
get_fortran_address
(),
biso
)[
"betas"
]
Python_API/Src/CMakeLists.txt
View file @
c47f28f4
#################################
# Commad line arguments section
#################################
cmake_minimum_required
(
VERSION 3.1
.0
FATAL_ERROR
)
cmake_minimum_required
(
VERSION 3.1
3
FATAL_ERROR
)
#################################
# Project section
...
...
@@ -29,39 +29,38 @@ set_source_files_properties(forpy_mod.f90 PROPERTIES COMPILE_FLAG "-cpp")
# Dependencies section
#################################
# Add a dependency to crysfml_common to keep sure that the crysfml_common library will be built first.
# See https://gitlab.kitware.com/cmake/cmake/-/issues/19226 for linking
add_dependencies
(
${
LIBRARY_NAME
}
crysfml_common
)
set
(
COMPATIBLE_VERSIONS 3.8 3.7 3.6 3.5
)
if
(
NOT PYTHON_INTERPRETER_PATH
)
set
(
Python_ADDITIONAL_VERSIONS
${
COMPATIBLE_VERSIONS
}
)
find_package
(
PythonInterp REQUIRED
)
set
(
PYTHON_INTERPRETER_PATH
${
PYTHON_EXECUTABLE
}
)
message
(
STATUS
${
PYTHON_INTERPRETER_PATH
}
)
else
()
message
(
STATUS
"using Python interpreter provided with PYTHON_INTERPRETER_PATH variable: "
${
PYTHON_INTERPRETER_PATH
}
)
endif
()
if
(
NOT PYTHON_LIBRARY_PATH
)
set
(
Python_ADDITIONAL_VERSIONS
${
COMPATIBLE_VERSIONS
}
)
find_package
(
PythonLibs REQUIRED
)
set
(
PYTHON_LIBRARY_PATH
${
PYTHON_LIBRARY
}
)
message
(
STATUS
${
PYTHON_LIBRARY_PATH
}
)
if
(
NOT PYTHON_INTERPRETER_PATH OR NOT PYTHON_LIBRARY_PATH
)
set
(
Python3_USE_STATIC_LIBS, TRUE
)
find_package
(
Python3 COMPONENTS Interpreter Development
)
set
(
PYTHON_INTERPRETER_PATH
${
Python3_EXECUTABLE
}
)
set
(
PYTHON_LIBRARY_PATH Python3::Python
)
message
(
STATUS
"Using Python interpreter found with PYTHON_INTERPRETER_PATH variable: "
${
PYTHON_INTERPRETER_PATH
}
)
message
(
STATUS
"Linking Python extension with found PYTHON_LIBRARY_PATH variable: "
${
PYTHON_LIBRARY_PATH
}
)
else
()
message
(
STATUS
"Using Python interpreter provided with PYTHON_INTERPRETER_PATH variable: "
${
PYTHON_INTERPRETER_PATH
}
)
message
(
STATUS
"Linking Python extension with provided PYTHON_LIBRARY_PATH variable: "
${
PYTHON_LIBRARY_PATH
}
)
endif
()
if
(
UNIX
)
add_library
(
Python3_LIB SHARED IMPORTED
)
set_property
(
TARGET Python3_LIB PROPERTY IMPORTED_LOCATION
${
PYTHON_LIBRARY_PATH
}
)
else
if
(
WIN32
)
if
(
WIN32
OR MSYS
)
add_library
(
Python3_LIB STATIC IMPORTED
)
set_property
(
TARGET Python3_LIB PROPERTY IMPORTED_LOCATION
${
PYTHON_LIBRARY_PATH
}
)
target_link_libraries
(
${
LIBRARY_NAME
}
Python3_LIB
)
endif
()
# Set -Wl,-undefined,dynamic_lookup to OTHER_LDFLAGS
# Set include and linking
include_directories
(
${
CRYSFML_COMMON_MODULE_DIRECTORY
}
)
target_link_libraries
(
${
LIBRARY_NAME
}
crysfml_common
)
target_link_libraries
(
${
LIBRARY_NAME
}
Python3_LIB
)
# Fix a problem on Mac OS X when building shared libraries
if
(
APPLE
)
set
(
CMAKE_SHARED_LINKER_FLAGS
"
${
CMAKE_SHARED_LINKER_FLAGS
}
-undefined dynamic_lookup"
)
endif
()
# Set library extension
set_target_properties
(
${
LIBRARY_NAME
}
PROPERTIES PREFIX
""
OUTPUT_NAME
${
LIBRARY_NAME
}
)
...
...
@@ -69,7 +68,7 @@ set(LIBRARY_FILENAME "crysfml_api.so")
if
(
APPLE
)
set_target_properties
(
${
LIBRARY_NAME
}
PROPERTIES SUFFIX
".so"
)
set
(
LIBRARY_FILENAME
"crysfml_api.so"
)
elseif
(
WIN32
)
elseif
(
WIN32
OR MSYS
)
set_target_properties
(
${
LIBRARY_NAME
}
PROPERTIES SUFFIX
".pyd"
)
set
(
LIBRARY_FILENAME
"crysfml_api.pyd"
)
endif
()
...
...
@@ -112,7 +111,20 @@ endif (DOXYGEN_FOUND)
#################################
# Add tests
add_test
(
NAME
"Python_API_Tests"
COMMAND
${
PYTHON_INTERPRETER_PATH
}
-m unittest discover
${
CMAKE_CURRENT_BINARY_DIR
}
/../Tests
)
add_custom_target
(
Python_Files ALL
if
(
PYSETUP
)
add_custom_target
(
Python_Files ALL
COMMAND
${
CMAKE_COMMAND
}
-E copy_directory
${
CMAKE_CURRENT_SOURCE_DIR
}
/../Tests
${
CMAKE_CURRENT_BINARY_DIR
}
/../Tests
COMMAND
${
CMAKE_COMMAND
}
-E copy_directory
${
CMAKE_CURRENT_SOURCE_DIR
}
${
CMAKE_CURRENT_BINARY_DIR
}
/../Tests/CFML_api
)
else
()
add_custom_target
(
Python_Files ALL
COMMAND
${
CMAKE_COMMAND
}
-E copy_directory
${
CMAKE_CURRENT_SOURCE_DIR
}
/../Tests
...
...
@@ -126,28 +138,29 @@ add_custom_target(Python_Files ALL
COMMAND
${
CMAKE_COMMAND
}
-E copy
${
CMAKE_CURRENT_BINARY_DIR
}
/
${
LIBRARY_FILENAME
}
${
CMAKE_CURRENT_BINARY_DIR
}
/../Tests/CFML_api
${
CMAKE_CURRENT_BINARY_DIR
}
/../Tests/CFML_api
/
${
LIBRARY_FILENAME
}
)
add_dependencies
(
Python_Files
${
LIBRARY_NAME
}
)
endif
(
)
add_dependencies
(
Python_Files
${
LIBRARY_NAME
}
)
#################################
# Install section
#################################
# The rules for installing the library.
install
(
DIRECTORY
""
DESTINATION
${
PYTHON_API_PREFIX
}
/CFML_api FILES_MATCHING PATTERN
"*.py"
PATTERN
"Extensions"
EXCLUDE
)
if
(
WIN32
)
install
(
TARGETS
${
LIBRARY_NAME
}
RUNTIME DESTINATION
${
PYTHON_API_PREFIX
}
/CFML_api
)
if
(
WIN32
OR MSYS
)
install
(
TARGETS
${
LIBRARY_NAME
}
RUNTIME DESTINATION
${
PYTHON_API_PREFIX
}
/CFML_api
)
else
()
install
(
TARGETS
${
LIBRARY_NAME
}
LIBRARY DESTINATION
${
PYTHON_API_PREFIX
}
/CFML_api
)
install
(
TARGETS
${
LIBRARY_NAME
}
LIBRARY DESTINATION
${
PYTHON_API_PREFIX
}
/CFML_api
)
endif
()
# Installing example files
install
(
DIRECTORY
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/../Examples"
DESTINATION
${
PYTHON_API_PREFIX
}
FILES_MATCHING PATTERN
"*.py"
)
install
(
DIRECTORY
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/../Examples/Data"
DESTINATION
${
PYTHON_API_PREFIX
}
/Examples FILES_MATCHING PATTERN
"*.cfl"
PATTERN
"*.cif"
)
# Installing tests files
#
#
# Installing tests files
install
(
DIRECTORY
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/../Tests"
DESTINATION
${
PYTHON_API_PREFIX
}
FILES_MATCHING PATTERN
"*.py"
)
# Installing documentation files
#
#
# Installing documentation files
install
(
DIRECTORY
"
${
CMAKE_CURRENT_BINARY_DIR
}
/doxygen/html"
DESTINATION
${
PYTHON_API_PREFIX
}
/Doc OPTIONAL
)
\ No newline at end of file
Python_API/Src/Extensions/API_Atom_TypeDef.f90
View file @
c47f28f4
...
...
@@ -4,6 +4,8 @@ module API_Atom_TypeDef
use
,
intrinsic
::
iso_c_binding
use
,
intrinsic
::
iso_fortran_env
use
CFML_GlobalDeps
,
only
:
cp
,
eps
use
CFML_Atom_TypeDef
,
only
:
&
Atom_List_type
,
&
Atoms_Cell_type
,
&
...
...
@@ -13,9 +15,23 @@ module API_Atom_TypeDef
Write_Atom_list
,
&
Atom_type
Use
CFML_Crystallographic_Symmetry
,
only
:
&
Get_Multip_Pos
use
CFML_Crystal_Metrics
,
only
:
&
Convert_U_Betas
,
Convert_B_Betas
use
CFML_IO_Formats
,
only
:
&
Read_Atom
,
Read_Cif_Atom
use
API_Crystallographic_Symmetry
,
only
:
&
Space_Group_type_p
,
&
get_space_group_type_from_arg
use
API_Crystal_Metrics
,
only
:
&
Crystal_Cell_type_p
,
&
get_cell_from_arg
implicit
none
type
Atom_type_p
...
...
@@ -178,6 +194,118 @@ contains
end
function
atom_typedef_atomlist_from_CIF_string_array
!---- Modify occupation factors and set multiplicity of atoms
!---- in order to be in agreement with the definitions of Sfac in CrysFML
function
atom_typedef_atomlist_reset_occ_cif
(
self_ptr
,
args_ptr
)
result
(
r
)
bind
(
c
)
type
(
c_ptr
),
value
::
self_ptr
type
(
c_ptr
),
value
::
args_ptr
type
(
c_ptr
)
::
r
type
(
tuple
)
::
args
type
(
dict
)
::
retval
integer
::
num_args
integer
::
ierror
type
(
Atom_List_Type_p
)
::
a_p
type
(
Space_Group_type_p
)
::
spg
real
(
kind
=
cp
),
dimension
(
6
)::
pos
integer
::
i
r
=
C_NULL_PTR
! in case of an exception return C_NULL_PTR
! use unsafe_cast_from_c_ptr to cast from c_ptr to tuple
call
unsafe_cast_from_c_ptr
(
args
,
args_ptr
)
! Check if the arguments are OK
ierror
=
args
%
len
(
num_args
)
! we should also check ierror, but this example does not do complete error checking for simplicity
if
(
num_args
/
=
2
)
then
call
raise_exception
(
TypeError
,
"update_occ_cif expects exactly 1 argument"
)
call
args
%
destroy
return
endif
! Doing boring stuff
call
get_atom_list_type_from_arg
(
args
,
a_p
,
0
)
call
get_space_group_type_from_arg
(
args
,
spg
,
1
)
do
i
=
1
,
a_p
%
p
%
natoms
pos
(
1
:
3
)
=
a_p
%
p
%
atom
(
i
)
%
x
a_p
%
p
%
atom
(
i
)
%
Mult
=
Get_Multip_Pos
(
pos
(
1
:
3
),
SpG
%
p
)
! This step is needed for CIF file only as the convention is different!
a_p
%
p
%
atom
(
i
)
%
Occ
=
a_p
%
p
%
atom
(
i
)
%
Occ
*
real
(
a_p
%
p
%
atom
(
i
)
%
Mult
)/
max
(
1.0
,
real
(
SpG
%
p
%
Multip
))
if
(
a_p
%
p
%
atom
(
i
)
%
occ
<
eps
)
a_p
%
p
%
atom
(
i
)
%
occ
=
real
(
a_p
%
p
%
atom
(
i
)
%
Mult
)/
max
(
1.0
,
real
(
SpG
%
p
%
Multip
))
enddo
ierror
=
dict_create
(
retval
)
r
=
retval
%
get_c_ptr
()
call
args
%
destroy
end
function
atom_typedef_atomlist_reset_occ_cif
function
atom_typedef_atomlist_set_all_adp_cif
(
self_ptr
,
args_ptr
)
result
(
r
)
bind
(
c
)
type
(
c_ptr
),
value
::
self_ptr
type
(
c_ptr
),
value
::
args_ptr
type
(
c_ptr
)
::
r
type
(
tuple
)
::
args
type
(
dict
)
::
retval
integer
::
num_args
integer
::
ierror
type
(
Atom_List_Type_p
)
::
a_p
type
(
Crystal_Cell_type_p
)
::
cell
integer
::
i
r
=
C_NULL_PTR
! in case of an exception return C_NULL_PTR
! use unsafe_cast_from_c_ptr to cast from c_ptr to tuple
call
unsafe_cast_from_c_ptr
(
args
,
args_ptr
)
! Check if the arguments are OK
ierror
=
args
%
len
(
num_args
)
! we should also check ierror, but this example does not do complete error checking for simplicity
if
(
num_args
/
=
2
)
then
call
raise_exception
(
TypeError
,
"update_occ_cif expects exactly 1 argument"
)
call
args
%
destroy
return
endif
! Doing boring stuff
call
get_atom_list_type_from_arg
(
args
,
a_p
,
0
)
call
get_cell_from_arg
(
args
,
cell
,
1
)