Commit 28c531c5 authored by Elisa Rebolini's avatar Elisa Rebolini
Browse files

add function to update multiplicity and ADP when reading from a CIF string array

parent 7a395d9c
Pipeline #10417 passed with stages
in 13 minutes and 5 seconds
......@@ -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):
"""
total number of atoms in the list
Total 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")
......@@ -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)
do i=1,a_p%p%natoms
select case (A_p%p%atom(i)%thtype)
case ("isotr")
A_p%p%atom(i)%biso= A_p%p%atom(i)%ueq*78.95683521
case ("aniso")
select case (A_p%p%atom(i)%Utype)
case ("u_ij")
A_p%p%atom(i)%u(1:6) = Convert_U_Betas(A_p%p%atom(i)%u(1:6),Cell%p)
case ("b_ij")
A_p%p%atom(i)%u(1:6) = Convert_B_Betas(A_p%p%atom(i)%u(1:6),Cell%p)
end select
A_p%p%atom(i)%Utype="beta"
case default
A_p%p%atom(i)%biso = A_p%p%atom(i)%ueq*78.95683521
A_p%p%atom(i)%thtype = "isotr"
end select
enddo
ierror = dict_create(retval)
r = retval%get_c_ptr()
call args%destroy
end function atom_typedef_atomlist_set_all_adp_cif
function atom_typedef_set_item(self_ptr, args_ptr) result(r) bind(c)
type(c_ptr), value :: self_ptr
......@@ -1762,6 +1890,7 @@ contains
type(dict) :: retval
integer :: num_args
integer :: ierror
type(Atom_Type_p) :: atom_type_pointer
type(ndarray) :: Lm_xyz
......@@ -1787,4 +1916,7 @@ contains
call args%destroy
end function atom_typedef_get_Lm_xyz
end module API_Atom_TypeDef
......@@ -130,6 +130,8 @@ module API_init
use API_Atom_TypeDef, only: &
atom_typedef_del_atom_list, &
atom_typedef_atomlist_from_CIF_string_array, &
atom_typedef_atomlist_reset_occ_cif, &
atom_typedef_atomlist_set_all_adp_cif, &
atom_typedef_get_item, &
atom_typedef_get_natoms, &
atom_typedef_atom_from_string, &
......@@ -269,7 +271,7 @@ CONTAINS
!--------------------------
!Total number of method in the binding
!--------------------------
call method_table%init(206)
call method_table%init(208)
......@@ -884,7 +886,7 @@ CONTAINS
c_funloc(IO_Formats_set_bkg)) ! address of Fortran function to add
!--------------------------
! Atom Typedef (45)
! Atom Typedef (47)
!--------------------------
call method_table%add_method("atom_typedef_del_atom_list", & ! method name
"Delete an atom list", & !doc-string
......@@ -895,6 +897,16 @@ CONTAINS
"Create an atom list from an array of CIF lines", & !doc-string
METH_VARARGS, & ! this method takes arguments but no keyword arguments
c_funloc(atom_typedef_atomlist_from_CIF_string_array)) ! address of Fortran function to add
call method_table%add_method("atom_typedef_atomlist_reset_occ_cif", & ! method name
"Set mult and occ according to Sfac convention", & !doc-string
METH_VARARGS, & ! this method takes arguments but no keyword arguments
c_funloc(atom_typedef_atomlist_reset_occ_cif)) ! address of Fortran function to add
call method_table%add_method("atom_typedef_atomlist_set_all_adp_cif", & ! method name
"Set all Atom fields for Us, Bs and betas", & !doc-string
METH_VARARGS, & ! this method takes arguments but no keyword arguments
c_funloc(atom_typedef_atomlist_set_all_adp_cif)) ! address of Fortran function to add
call method_table%add_method("atom_typedef_set_item", & ! method name
"Set an item in the atom list", & !doc-string
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment