Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
libcifpp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
libcifpp
Commits
f77bbfed
Commit
f77bbfed
authored
Oct 03, 2022
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updates
parent
3aa3fe19
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
282 additions
and
86 deletions
+282
-86
CMakeLists.txt
+3
-1
include/cif++/category.hpp
+9
-6
include/cif++/model.hpp
+47
-17
src/category.cpp
+1
-4
src/model.cpp
+58
-58
test/unit-v2-test.cpp
+164
-0
No files found.
CMakeLists.txt
View file @
f77bbfed
...
...
@@ -370,7 +370,9 @@ if(ENABLE_TESTING)
find_package
(
Boost REQUIRED headers
)
list
(
APPEND CIFPP_tests unit-v2 unit-3d format model rename-compound sugar
)
list
(
APPEND CIFPP_tests unit-v2 unit-3d format model
# rename-compound sugar
)
foreach
(
CIFPP_TEST IN LISTS CIFPP_tests
)
set
(
CIFPP_TEST
"
${
CIFPP_TEST
}
-test"
)
...
...
include/cif++/category.hpp
View file @
f77bbfed
...
...
@@ -286,14 +286,17 @@ class category
{
bool
result
=
false
;
cond
.
prepare
(
*
this
);
for
(
auto
r
:
*
this
)
if
(
cond
)
{
if
(
cond
(
r
))
cond
.
prepare
(
*
this
);
for
(
auto
r
:
*
this
)
{
result
=
true
;
break
;
if
(
cond
(
r
))
{
result
=
true
;
break
;
}
}
}
...
...
include/cif++/model.hpp
View file @
f77bbfed
...
...
@@ -28,6 +28,8 @@
#include <numeric>
#include <cif++/atom_type.hpp>
#if __cpp_lib_format
#include <format>
#endif
...
...
@@ -80,7 +82,7 @@ class atom
// bool getAnisoU(float anisou[6]) const;
//
int charge() const;
int
charge
()
const
;
void
moveTo
(
const
point
&
p
)
{
...
...
@@ -128,6 +130,20 @@ class atom
return
result
;
}
float
get_property_float
(
std
::
string_view
name
)
const
{
float
result
=
0
;
if
(
not
m_row
[
name
].
empty
())
{
auto
s
=
get_property
(
name
);
std
::
from_chars_result
r
=
std
::
from_chars
(
s
.
data
(),
s
.
data
()
+
s
.
length
(),
result
);
if
(
r
.
ec
!=
std
::
errc
()
and
VERBOSE
>
0
)
std
::
cerr
<<
"Error converting "
<<
s
<<
" to number for property "
<<
name
<<
std
::
endl
;
}
return
result
;
}
void
set_property
(
const
std
::
string_view
name
,
const
std
::
string
&
value
)
{
m_row
.
assign
(
name
,
value
,
true
,
true
);
...
...
@@ -214,6 +230,13 @@ class atom
return
m_impl
->
get_property_int
(
name
);
}
float
get_property_float
(
std
::
string_view
name
)
const
{
if
(
not
m_impl
)
throw
std
::
logic_error
(
"Error trying to fetch a property from an uninitialized atom"
);
return
m_impl
->
get_property_float
(
name
);
}
void
set_property
(
const
std
::
string_view
name
,
const
std
::
string
&
value
)
{
if
(
not
m_impl
)
...
...
@@ -228,7 +251,8 @@ class atom
}
const
std
::
string
&
id
()
const
{
return
impl
().
m_id
;
}
// AtomType type() const { return impl().mType; }
cif
::
atom_type
get_type
()
const
{
return
atom_type_traits
(
get_property
(
"type_symbol"
)).
type
();
}
point
get_location
()
const
{
return
impl
().
m_location
;
}
void
set_location
(
point
p
)
...
...
@@ -280,7 +304,7 @@ class atom
// const compound &compound() const;
// bool isWater() const { return impl().mCompID == "HOH" or impl().mCompID == "H2O" or impl().mCompID == "WAT"; }
// int
charge() const;
int
get_
charge
()
const
;
// float uIso() const;
// bool getAnisoU(float anisou[6]) const { return impl().getAnisoU(anisou); }
...
...
@@ -297,6 +321,7 @@ class atom
std
::
string
get_auth_asym_id
()
const
{
return
get_property
(
"auth_asym_id"
);
}
std
::
string
get_auth_seq_id
()
const
{
return
get_property
(
"auth_seq_id"
);
}
std
::
string
get_auth_atom_id
()
const
{
return
get_property
(
"auth_atom_id"
);
}
std
::
string
get_pdb_ins_code
()
const
{
return
get_property
(
"pdbx_PDB_ins_code"
);
}
// const std::string &labelAtomID() const { return impl().mAtomID; }
...
...
@@ -457,6 +482,11 @@ class residue
}
const
std
::
string
get_auth_seq_id
()
const
{
return
m_auth_seq_id
;
}
std
::
string
get_pdb_ins_code
()
const
{
return
m_atoms
.
empty
()
?
""
:
m_atoms
.
front
().
get_pdb_ins_code
();
}
const
std
::
string
&
get_compound_id
()
const
{
return
m_compound_id
;
}
void
set_compound_id
(
const
std
::
string
&
id
)
{
m_compound_id
=
id
;
}
...
...
@@ -476,8 +506,8 @@ class residue
void
add_atom
(
atom
&
atom
);
//
//
/ \brief Unique atoms returns only the atoms without alternates and the first of each alternate atom id.
//
std::vector<atom> unique_atoms() const;
/// \brief Unique atoms returns only the atoms without alternates and the first of each alternate atom id.
std
::
vector
<
atom
>
unique_atoms
()
const
;
// /// \brief The alt ID used for the unique atoms
// std::string unique_alt_id() const;
...
...
@@ -773,12 +803,12 @@ class structure
const
std
::
list
<
polymer
>
&
polymers
()
const
{
return
m_polymers
;
}
std
::
list
<
polymer
>
&
polymers
()
{
return
m_polymers
;
}
// polymer &getPolymerByAsymID
(const std::string &asymID);
polymer
&
get_polymer_by_asym_id
(
const
std
::
string
&
asymID
);
// const polymer &getPolymerByAsymID
(const std::string &asymID) const
//
{
// return const_cast<structure *>(this)->getPolymerByAsymID
(asymID);
//
}
const
polymer
&
get_polymer_by_asym_id
(
const
std
::
string
&
asymID
)
const
{
return
const_cast
<
structure
*>
(
this
)
->
get_polymer_by_asym_id
(
asymID
);
}
const
std
::
list
<
branch
>
&
branches
()
const
{
return
m_branches
;
}
std
::
list
<
branch
>
&
branches
()
{
return
m_branches
;
}
...
...
@@ -797,8 +827,8 @@ class structure
// /// \brief Return the atom closest to point \a p
// atom getAtomByPosition(point p) const;
//
//
/ \brief Return the atom closest to point \a p with atom type \a type in a residue of type \a res_type
// atom getAtomByPositionAndT
ype(point p, std::string_view type, std::string_view res_type) const;
/// \brief Return the atom closest to point \a p with atom type \a type in a residue of type \a res_type
atom
get_atom_by_position_and_t
ype
(
point
p
,
std
::
string_view
type
,
std
::
string_view
res_type
)
const
;
/// \brief Get a non-poly residue for an asym with id \a asymID
residue
&
get_residue
(
const
std
::
string
&
asymID
)
...
...
@@ -917,11 +947,11 @@ class structure
void
cleanup_empty_categories
();
//
//
/ \brief Direct access to underlying data
// category &
category(std::string_view name) const
//
{
//
return m_db[name];
//
}
/// \brief Direct access to underlying data
category
&
get_
category
(
std
::
string_view
name
)
const
{
return
m_db
[
name
];
}
datablock
&
get_datablock
()
const
{
...
...
src/category.cpp
View file @
f77bbfed
...
...
@@ -885,10 +885,7 @@ condition category::get_parents_condition(row_handle rh, const category &parentC
cond
=
std
::
move
(
cond
)
and
key
(
link
->
m_parent_keys
[
ix
])
==
childValue
.
text
();
}
if
(
result
)
result
=
std
::
move
(
result
)
or
std
::
move
(
cond
);
else
result
=
std
::
move
(
cond
);
result
=
std
::
move
(
result
)
or
std
::
move
(
cond
);
}
return
result
;
...
...
src/model.cpp
View file @
f77bbfed
...
...
@@ -393,37 +393,37 @@ void residue::add_atom(atom &atom)
m_atoms
.
push_back
(
atom
);
}
//
std::vector<atom> residue::unique_atoms() const
//
{
//
if (m_structure == nullptr)
//
throw std::runtime_error("Invalid residue object");
std
::
vector
<
atom
>
residue
::
unique_atoms
()
const
{
//
if (m_structure == nullptr)
//
throw std::runtime_error("Invalid residue object");
//
std::vector<atom> result;
//
std::string firstAlt;
std
::
vector
<
atom
>
result
;
std
::
string
firstAlt
;
//
for (auto &atom : m_atoms)
//
{
//
auto alt = atom.get_label_alt_id();
//
if (alt.empty())
//
{
//
result.push_back(atom);
//
continue;
//
}
for
(
auto
&
atom
:
m_atoms
)
{
auto
alt
=
atom
.
get_label_alt_id
();
if
(
alt
.
empty
())
{
result
.
push_back
(
atom
);
continue
;
}
//
if (firstAlt.empty())
//
firstAlt = alt;
//
else if (alt != firstAlt)
//
{
//
if (VERBOSE > 0)
//
std::cerr << "skipping alternate atom " << atom << std::endl;
//
continue;
//
}
if
(
firstAlt
.
empty
())
firstAlt
=
alt
;
else
if
(
alt
!=
firstAlt
)
{
if
(
VERBOSE
>
0
)
std
::
cerr
<<
"skipping alternate atom "
<<
atom
<<
std
::
endl
;
continue
;
}
//
result.push_back(atom);
//
}
result
.
push_back
(
atom
);
}
//
return result;
//
}
return
result
;
}
// std::set<std::string> residue::getAlternateIDs() const
// {
...
...
@@ -1489,47 +1489,47 @@ atom structure::get_atom_by_id(const std::string &id) const
// return {};
// }
// atom structure::getAtomByPositionAndT
ype(point p, std::string_view type, std::string_view res_type) const
//
{
// double distance
= std::numeric_limits<double>::max();
//
size_t index = std::numeric_limits<size_t>::max();
atom
structure
::
get_atom_by_position_and_t
ype
(
point
p
,
std
::
string_view
type
,
std
::
string_view
res_type
)
const
{
double
dist
=
std
::
numeric_limits
<
double
>::
max
();
size_t
index
=
std
::
numeric_limits
<
size_t
>::
max
();
//
for (size_t i = 0; i < m_atoms.size(); ++i)
//
{
//
auto &a = m_atoms.at(i);
for
(
size_t
i
=
0
;
i
<
m_atoms
.
size
();
++
i
)
{
auto
&
a
=
m_atoms
.
at
(
i
);
// if (a.labelCompID
() != res_type)
//
continue;
if
(
a
.
get_label_comp_id
()
!=
res_type
)
continue
;
//
if (a.get_label_atom_id() != type)
//
continue;
if
(
a
.
get_label_atom_id
()
!=
type
)
continue
;
// auto d = Distance(a.
location(), p);
// if (d < distance
)
//
{
// distance
= d;
//
index = i;
//
}
//
}
auto
d
=
distance
(
a
.
get_
location
(),
p
);
if
(
dist
>
d
)
{
dist
=
d
;
index
=
i
;
}
}
//
if (index < m_atoms.size())
//
return m_atoms.at(index);
if
(
index
<
m_atoms
.
size
())
return
m_atoms
.
at
(
index
);
//
return {};
//
}
return
{};
}
// polymer &structure::getPolymerByA
sym_id(const std::string &asym_id)
//
{
//
for (auto &poly : m_polymers)
//
{
//
if (poly.get_asym_id() != asym_id)
//
continue;
polymer
&
structure
::
get_polymer_by_a
sym_id
(
const
std
::
string
&
asym_id
)
{
for
(
auto
&
poly
:
m_polymers
)
{
if
(
poly
.
get_asym_id
()
!=
asym_id
)
continue
;
//
return poly;
//
}
return
poly
;
}
//
throw std::runtime_error("polymer with asym id " + asym_id + " not found");
//
}
throw
std
::
runtime_error
(
"polymer with asym id "
+
asym_id
+
" not found"
);
}
residue
&
structure
::
get_residue
(
const
std
::
string
&
asym_id
,
int
seqID
,
const
std
::
string
&
authSeqID
)
{
...
...
test/unit-v2-test.cpp
View file @
f77bbfed
...
...
@@ -1514,6 +1514,170 @@ _cat_2.parent_id3
// --------------------------------------------------------------------
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE
(
d6
)
{
const
char
dict
[]
=
R"(
data_test_dict.dic
_datablock.id test_dict.dic
_datablock.description
;
A test dictionary
;
_dictionary.title test_dict.dic
_dictionary.datablock_id test_dict.dic
_dictionary.version 1.0
loop_
_item_type_list.code
_item_type_list.primitive_code
_item_type_list.construct
code char
'[][_,.;:"&<>()/\{}'`~!@#$%A-Za-z0-9*|+-]*'
text char
'[][ \n\t()_,.;:"&<>/\{}'`~!@#$%?+=*A-Za-z0-9|^-]*'
int numb
'[+-]?[0-9]+'
save_cat_1
_category.description 'A simple test category'
_category.id cat_1
_category.mandatory_code yes
_category_key.name '_cat_1.id'
save_
save__cat_1.id
_item.name '_cat_1.id'
_item.category_id cat_1
_item.mandatory_code yes
_item_type.code int
save_
save__cat_1.id_2
_item.name '_cat_1.id_2'
_item.category_id cat_1
_item.mandatory_code no
_item_type.code int
save_
save_cat_2
_category.description 'A second simple test category'
_category.id cat_2
_category.mandatory_code no
_category_key.name '_cat_2.id'
save_
save__cat_2.id
_item.name '_cat_2.id'
_item.category_id cat_2
_item.mandatory_code yes
_item_type.code int
save_
save__cat_2.parent_id
_item.name '_cat_2.parent_id'
_item.category_id cat_2
_item.mandatory_code yes
_item_type.code int
save_
save__cat_2.parent_id_2
_item.name '_cat_2.parent_id_2'
_item.category_id cat_2
_item.mandatory_code no
_item_type.code code
save_
loop_
_pdbx_item_linked_group_list.child_category_id
_pdbx_item_linked_group_list.link_group_id
_pdbx_item_linked_group_list.child_name
_pdbx_item_linked_group_list.parent_name
_pdbx_item_linked_group_list.parent_category_id
cat_2 1 '_cat_2.parent_id' '_cat_1.id' cat_1
cat_2 1 '_cat_2.parent_id_2' '_cat_1.id_2' cat_1
loop_
_pdbx_item_linked_group.category_id
_pdbx_item_linked_group.link_group_id
_pdbx_item_linked_group.label
cat_2 1 cat_2:cat_1:1
)"
;
struct
membuf
:
public
std
::
streambuf
{
membuf
(
char
*
text
,
size_t
length
)
{
this
->
setg
(
text
,
text
,
text
+
length
);
}
}
buffer
(
const_cast
<
char
*>
(
dict
),
sizeof
(
dict
)
-
1
);
std
::
istream
is_dict
(
&
buffer
);
auto
validator
=
cif
::
parse_dictionary
(
"test"
,
is_dict
);
cif
::
file
f
;
f
.
set_validator
(
&
validator
);
// --------------------------------------------------------------------
const
char
data
[]
=
R"(
data_test
loop_
_cat_1.id
_cat_1.id_2
1 1
2 2
3 ?
loop_
_cat_2.id
_cat_2.parent_id
_cat_2.parent_id_2
0 1 1
1 1 ?
2 ? 1
3 ? ?
4 2 2
5 3 1
6 3 ?
)"
;
// --------------------------------------------------------------------
struct
data_membuf
:
public
std
::
streambuf
{
data_membuf
(
char
*
text
,
size_t
length
)
{
this
->
setg
(
text
,
text
,
text
+
length
);
}
}
data_buffer
(
const_cast
<
char
*>
(
data
),
sizeof
(
data
)
-
1
);
std
::
istream
is_data
(
&
data_buffer
);
f
.
load
(
is_data
);
auto
&
cat1
=
f
.
front
()[
"cat_1"
];
auto
&
cat2
=
f
.
front
()[
"cat_2"
];
// f.front().validate_links();
// BOOST_CHECK(not );
using
namespace
cif
::
literals
;
BOOST_CHECK
(
cat2
.
has_parents
(
cat2
.
find1
(
"id"
_key
==
0
)));
BOOST_CHECK
(
cat2
.
has_parents
(
cat2
.
find1
(
"id"
_key
==
1
)));
BOOST_CHECK
(
cat2
.
has_parents
(
cat2
.
find1
(
"id"
_key
==
2
)));
BOOST_CHECK
(
not
cat2
.
has_parents
(
cat2
.
find1
(
"id"
_key
==
3
)));
BOOST_CHECK
(
cat2
.
has_parents
(
cat2
.
find1
(
"id"
_key
==
4
)));
BOOST_CHECK
(
cat2
.
has_parents
(
cat2
.
find1
(
"id"
_key
==
5
)));
BOOST_CHECK
(
cat2
.
has_parents
(
cat2
.
find1
(
"id"
_key
==
6
)));
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE
(
c1
)
{
cif
::
VERBOSE
=
1
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment