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
6a0b6b99
Unverified
Commit
6a0b6b99
authored
Oct 03, 2022
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
using index in category
parent
08dd9dd5
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
269 additions
and
175 deletions
+269
-175
CMakeLists.txt
+1
-2
include/cif++/category.hpp
+17
-1
include/cif++/file.hpp
+12
-0
include/cif++/model.hpp
+14
-105
include/cif++/row.hpp
+3
-7
src/category.cpp
+70
-1
src/model.cpp
+91
-23
src/row.cpp
+2
-1
test/1juh.cif.gz
+0
-0
test/model-test.cpp
+1
-0
test/rename-compound-test.cpp
+33
-9
test/sugar-test.cpp
+25
-26
No files found.
CMakeLists.txt
View file @
6a0b6b99
...
...
@@ -370,8 +370,7 @@ 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
)
...
...
include/cif++/category.hpp
View file @
6a0b6b99
...
...
@@ -159,6 +159,22 @@ class category
}
// --------------------------------------------------------------------
// A category can have a key, as defined by the validator/dictionary
/// @brief The key type
using
key_type
=
row_initializer
;
/// @brief Return a row_handle for the row specified by \a key
/// @param key The value for the key, fields specified in the dictionary should have a value
/// @return The row found in the index, or an undefined row_handle
row_handle
operator
[](
const
key_type
&
key
);
const
row_handle
operator
[](
const
key_type
&
key
)
const
{
return
const_cast
<
category
*>
(
this
)
->
operator
[](
key
);
}
// --------------------------------------------------------------------
template
<
typename
...
Ts
,
typename
...
Ns
>
iterator_proxy
<
const
category
,
Ts
...
>
rows
(
Ns
...
names
)
const
...
...
@@ -335,7 +351,7 @@ class category
iterator
emplace
(
row_initializer
&&
ri
)
{
return
this
->
emplace
(
ri
.
m_items
.
begin
(),
ri
.
m_items
.
end
());
return
this
->
emplace
(
ri
.
begin
(),
ri
.
end
());
}
template
<
typename
ItemIter
>
...
...
include/cif++/file.hpp
View file @
6a0b6b99
...
...
@@ -86,6 +86,18 @@ class file : public std::list<datablock>
bool
contains
(
std
::
string_view
name
)
const
;
datablock
&
front
()
{
assert
(
not
empty
());
return
std
::
list
<
datablock
>::
front
();
}
const
datablock
&
front
()
const
{
assert
(
not
empty
());
return
std
::
list
<
datablock
>::
front
();
}
datablock
&
operator
[](
std
::
string_view
name
);
const
datablock
&
operator
[](
std
::
string_view
name
)
const
;
...
...
include/cif++/model.hpp
View file @
6a0b6b99
...
...
@@ -34,19 +34,6 @@
#include <format>
#endif
/*
To modify a structure, you will have to use actions.
The currently supported actions are:
// - Move atom to new location
- Remove atom
// - Add new atom that was formerly missing
// - Add alternate residue
-
*/
namespace
cif
::
mm
{
...
...
@@ -63,10 +50,9 @@ class atom
private
:
struct
atom_impl
:
public
std
::
enable_shared_from_this
<
atom_impl
>
{
atom_impl
(
datablock
&
db
,
std
::
string_view
id
,
row_handle
row
)
atom_impl
(
datablock
&
db
,
std
::
string_view
id
)
:
m_db
(
db
)
,
m_id
(
id
)
,
m_row
(
row
)
{
prefetch
();
}
...
...
@@ -84,95 +70,18 @@ class atom
int
get_charge
()
const
;
void
moveTo
(
const
point
&
p
)
{
if
(
m_symop
!=
"1_555"
)
throw
std
::
runtime_error
(
"Moving symmetry copy"
);
#if __cpp_lib_format
m_row
.
assign
(
"Cartn_x"
,
std
::
format
(
"{:.3f}"
,
p
.
getX
()),
false
,
false
);
m_row
.
assign
(
"Cartn_y"
,
std
::
format
(
"{:.3f}"
,
p
.
getY
()),
false
,
false
);
m_row
.
assign
(
"Cartn_z"
,
std
::
format
(
"{:.3f}"
,
p
.
getZ
()),
false
,
false
);
#else
m_row
.
assign
(
"Cartn_x"
,
format
(
"%.3f"
,
p
.
m_x
).
str
(),
false
,
false
);
m_row
.
assign
(
"Cartn_y"
,
format
(
"%.3f"
,
p
.
m_y
).
str
(),
false
,
false
);
m_row
.
assign
(
"Cartn_z"
,
format
(
"%.3f"
,
p
.
m_z
).
str
(),
false
,
false
);
#endif
m_location
=
p
;
}
void
moveTo
(
const
point
&
p
);
// const compound *compound() const;
std
::
string
get_property
(
std
::
string_view
name
)
const
{
return
m_row
[
name
].
as
<
std
::
string
>
();
// for (auto &&[tag, ref] : mCachedRefs)
// {
// if (tag == name)
// return ref.as<std::string>();
// }
// mCachedRefs.emplace_back(name, const_cast<Row &>(mRow)[name]);
// return std::get<1>(mCachedRefs.back()).as<std::string>();
}
std
::
string
get_property
(
std
::
string_view
name
)
const
;
int
get_property_int
(
std
::
string_view
name
)
const
;
float
get_property_float
(
std
::
string_view
name
)
const
;
int
get_property_int
(
std
::
string_view
name
)
const
{
int
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
;
}
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
);
}
// const datablock &m_db;
// std::string mID;
// atom_type mType;
// std::string mAtomID;
// std::string mCompID;
// std::string m_asym_id;
// int m_seq_id;
// std::string mAltID;
// std::string m_auth_seq_id;
// point mLocation;
// row_handle mRow;
// // mutable std::vector<std::tuple<std::string, detail::ItemReference>> mCachedRefs;
// mutable const compound *mcompound = nullptr;
// bool mSymmetryCopy = false;
// bool mClone = false;
void
set_property
(
const
std
::
string_view
name
,
const
std
::
string
&
value
);
const
datablock
&
m_db
;
std
::
string
m_id
;
row_handle
m_row
;
point
m_location
;
std
::
string
m_symop
=
"1_555"
;
};
...
...
@@ -190,10 +99,10 @@ class atom
{
}
atom
(
datablock
&
db
,
row_handle
&
row
)
:
atom
(
std
::
make_shared
<
atom_impl
>
(
db
,
row
[
"id"
].
as
<
std
::
string
>
(),
row
))
{
}
//
atom(datablock &db, row_handle &row)
//
: atom(std::make_shared<atom_impl>(db, row["id"].as<std::string>(), row))
//
{
//
}
// a special constructor to create symmetry copies
atom
(
const
atom
&
rhs
,
const
point
&
symmmetry_location
,
const
std
::
string
&
symmetry_operation
)
...
...
@@ -897,10 +806,10 @@ class structure
/// \param entity_id The entity ID of the new nonpoly
/// \param atoms The array of sets of item data containing the data for the atoms.
/// \return The newly create asym ID
std
::
string
create_non_poly
(
const
std
::
string
&
entity_id
,
std
::
vector
<
std
::
vector
<
item
>>
&
atom_info
);
std
::
string
create_non_poly
(
const
std
::
string
&
entity_id
,
std
::
vector
<
row_initializer
>
atoms
);
/// \brief Create a new (sugar) branch with one first NAG containing atoms constructed from \a
nag_atom_info
branch
&
create_branch
(
std
::
vector
<
std
::
vector
<
item
>>
&
nag_atom_info
);
/// \brief Create a new (sugar) branch with one first NAG containing atoms constructed from \a
atoms
branch
&
create_branch
(
std
::
vector
<
row_initializer
>
atoms
);
/// \brief Extend an existing (sugar) branch identified by \a asymID with one sugar containing atoms constructed from \a atom_info
///
...
...
@@ -908,7 +817,7 @@ class structure
/// \param atom_info Array containing the info for the atoms to construct for the new sugar
/// \param link_sugar The sugar to link to, note: this is the sugar number (1 based)
/// \param link_atom The atom id of the atom linked in the sugar
branch
&
extend_branch
(
const
std
::
string
&
asym_id
,
std
::
vector
<
std
::
vector
<
item
>>
&
atom_info
,
branch
&
extend_branch
(
const
std
::
string
&
asym_id
,
std
::
vector
<
row_initializer
>
atom_info
,
int
link_sugar
,
const
std
::
string
&
link_atom
);
/// \brief Remove \a branch
...
...
include/cif++/row.hpp
View file @
6a0b6b99
...
...
@@ -277,7 +277,7 @@ class row_handle
// --------------------------------------------------------------------
class
row_initializer
class
row_initializer
:
public
std
::
vector
<
item
>
{
public
:
friend
class
category
;
...
...
@@ -289,20 +289,17 @@ class row_initializer
row_initializer
&
operator
=
(
row_initializer
&&
)
=
default
;
row_initializer
(
std
::
initializer_list
<
item
>
items
)
:
m_items
(
items
)
:
std
::
vector
<
item
>
(
items
)
{
}
template
<
typename
ItemIter
,
std
::
enable_if_t
<
std
::
is_same_v
<
typename
ItemIter
::
value_type
,
item
>
,
int
>
=
0
>
row_initializer
(
ItemIter
b
,
ItemIter
e
)
:
m_items
(
b
,
e
)
:
std
::
vector
<
item
>
(
b
,
e
)
{
}
row_initializer
(
row_handle
rh
);
private
:
std
::
vector
<
item
>
m_items
;
};
}
//
namespace
cif
\ No newline at end of file
src/category.cpp
View file @
6a0b6b99
...
...
@@ -96,6 +96,32 @@ class row_comparator
return
d
;
}
int
operator
()(
const
row_initializer
&
a
,
const
row
*
b
)
const
{
assert
(
b
);
row_handle
rhb
(
m_category
,
*
b
);
int
d
=
0
,
i
=
0
;
for
(
auto
&
c
:
m_comparator
)
{
size_t
k
;
compareFunc
f
;
std
::
tie
(
k
,
f
)
=
c
;
std
::
string_view
ka
=
a
[
i
++
].
value
();
std
::
string_view
kb
=
rhb
[
k
].
text
();
d
=
f
(
ka
,
kb
);
if
(
d
!=
0
)
break
;
}
return
d
;
}
private
:
typedef
std
::
function
<
int
(
std
::
string_view
,
std
::
string_view
)
>
compareFunc
;
typedef
std
::
tuple
<
size_t
,
compareFunc
>
key_comparator
;
...
...
@@ -126,6 +152,7 @@ class category_index
}
row
*
find
(
row
*
k
)
const
;
row
*
find_by_value
(
row_initializer
k
)
const
;
void
insert
(
row
*
r
);
void
erase
(
row
*
r
);
...
...
@@ -331,6 +358,37 @@ row *category_index::find(row *k) const
return
r
?
r
->
m_row
:
nullptr
;
}
row
*
category_index
::
find_by_value
(
row_initializer
k
)
const
{
// sort the values in k first
row_initializer
k2
;
for
(
auto
&
f
:
m_category
.
key_field_indices
())
{
std
::
string
fld
=
fld
=
m_category
.
get_column_name
(
f
);
auto
ki
=
find_if
(
k
.
begin
(),
k
.
end
(),
[
&
fld
](
item
&
i
)
{
return
i
.
name
()
==
fld
;
});
if
(
ki
==
k
.
end
())
k2
.
emplace_back
(
fld
,
""
);
else
k2
.
emplace_back
(
*
ki
);
}
const
entry
*
r
=
m_root
;
while
(
r
!=
nullptr
)
{
int
d
=
m_row_comparator
(
k2
,
r
->
m_row
);
if
(
d
<
0
)
r
=
r
->
m_left
;
else
if
(
d
>
0
)
r
=
r
->
m_right
;
else
break
;
}
return
r
?
r
->
m_row
:
nullptr
;
}
void
category_index
::
insert
(
row
*
k
)
{
m_root
=
insert
(
m_root
,
k
);
...
...
@@ -861,6 +919,17 @@ void category::validate_links() const
// --------------------------------------------------------------------
row_handle
category
::
operator
[](
const
key_type
&
key
)
{
if
(
m_index
==
nullptr
)
throw
std
::
logic_error
(
"Category "
+
m_name
+
" does not have an index"
);
auto
row
=
m_index
->
find_by_value
(
key
);
return
row
!=
nullptr
?
row_handle
{
*
this
,
*
row
}
:
row_handle
{};
}
// --------------------------------------------------------------------
condition
category
::
get_parents_condition
(
row_handle
rh
,
const
category
&
parentCat
)
const
{
if
(
m_validator
==
nullptr
or
m_cat_validator
==
nullptr
)
...
...
@@ -1714,7 +1783,7 @@ void category::swap_item(size_t column_ix, row_handle &a, row_handle &b)
v
->
m_next
=
vb
->
m_next
;
vb
->
m_next
=
nullptr
;
if
(
rb
->
m_tail
=
vb
)
if
(
rb
->
m_tail
=
=
vb
)
rb
->
m_tail
=
v
;
break
;
...
...
src/model.cpp
View file @
6a0b6b99
...
...
@@ -47,7 +47,7 @@ namespace cif::mm
atom
::
atom_impl
::
atom_impl
(
const
atom_impl
&
impl
,
const
point
&
loc
,
const
std
::
string
&
sym_op
)
:
m_db
(
impl
.
m_db
)
,
m_id
(
impl
.
m_id
)
,
m_row
(
impl
.
m_row
)
//
, m_row(impl.m_row)
,
m_location
(
loc
)
,
m_symop
(
sym_op
)
{
...
...
@@ -55,7 +55,65 @@ atom::atom_impl::atom_impl(const atom_impl &impl, const point &loc, const std::s
void
atom
::
atom_impl
::
prefetch
()
{
tie
(
m_location
.
m_x
,
m_location
.
m_y
,
m_location
.
m_z
)
=
m_row
.
get
(
"Cartn_x"
,
"Cartn_y"
,
"Cartn_z"
);
// tie(m_location.m_x, m_location.m_y, m_location.m_z) = m_row.get("Cartn_x", "Cartn_y", "Cartn_z");
}
void
atom
::
atom_impl
::
moveTo
(
const
point
&
p
)
{
// if (m_symop != "1_555")
// throw std::runtime_error("Moving symmetry copy");
// #if __cpp_lib_format
// m_row.assign("Cartn_x", std::format("{:.3f}", p.getX()), false, false);
// m_row.assign("Cartn_y", std::format("{:.3f}", p.getY()), false, false);
// m_row.assign("Cartn_z", std::format("{:.3f}", p.getZ()), false, false);
// #else
// m_row.assign("Cartn_x", format("%.3f", p.m_x).str(), false, false);
// m_row.assign("Cartn_y", format("%.3f", p.m_y).str(), false, false);
// m_row.assign("Cartn_z", format("%.3f", p.m_z).str(), false, false);
// #endif
// m_location = p;
}
// const compound *compound() const;
std
::
string
atom
::
atom_impl
::
get_property
(
std
::
string_view
name
)
const
{
// return m_row[name].as<std::string>();
}
int
atom
::
atom_impl
::
get_property_int
(
std
::
string_view
name
)
const
{
int
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
;
}
float
atom
::
atom_impl
::
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
atom
::
atom_impl
::
set_property
(
const
std
::
string_view
name
,
const
std
::
string
&
value
)
{
// m_row.assign(name, value, true, true);
}
// int atom::atom_impl::compare(const atom_impl &b) const
...
...
@@ -92,17 +150,17 @@ void atom::atom_impl::prefetch()
int
atom
::
atom_impl
::
get_charge
()
const
{
auto
formalCharge
=
m_row
[
"pdbx_formal_charge"
].
as
<
std
::
optional
<
int
>>
();
//
auto formalCharge = m_row["pdbx_formal_charge"].as<std::optional<int>>();
if
(
not
formalCharge
.
has_value
())
{
auto
c
=
cif
::
compound_factory
::
instance
().
create
(
get_property
(
"label_comp_id"
));
//
if (not formalCharge.has_value())
//
{
//
auto c = cif::compound_factory::instance().create(get_property("label_comp_id"));
if
(
c
!=
nullptr
and
c
->
atoms
().
size
()
==
1
)
formalCharge
=
c
->
atoms
().
front
().
charge
;
}
//
if (c != nullptr and c->atoms().size() == 1)
//
formalCharge = c->atoms().front().charge;
//
}
return
formalCharge
.
value_or
(
0
);
//
return formalCharge.value_or(0);
}
// const Compound *atom::atom_impl::compound() const
...
...
@@ -919,12 +977,14 @@ polymer::polymer(const structure &s, const std::string &entityID, const std::str
,
m_asym_id
(
asym_id
)
// , mPolySeq(s.m_db["pdbx_poly_seq_scheme"), key("asym_id") == m_asym_id and key("entity_id") == m_entity_i])
{
using
namespace
cif
::
literals
;
std
::
map
<
size_t
,
size_t
>
ix
;
auto
&
poly_seq_scheme
=
s
.
get_datablock
()[
"pdbx_poly_seq_scheme"
];
reserve
(
poly_seq_scheme
.
size
());
for
(
auto
r
:
poly_seq_scheme
)
for
(
auto
r
:
poly_seq_scheme
.
find
(
"asym_id"
_key
==
asym_id
)
)
{
int
seqID
;
std
::
string
compoundID
,
authSeqID
;
...
...
@@ -1251,7 +1311,7 @@ void structure::load_atoms_for_model(StructureOpenOptions options)
if
((
options
bitand
StructureOpenOptions
::
SkipHydrogen
)
and
type_symbol
==
"H"
)
continue
;
emplace_atom
(
std
::
make_shared
<
atom
::
atom_impl
>
(
m_db
,
id
,
a
));
emplace_atom
(
std
::
make_shared
<
atom
::
atom_impl
>
(
m_db
,
id
));
}
}
...
...
@@ -1689,6 +1749,14 @@ atom &structure::emplace_atom(atom &&atom)
m_atom_index
.
insert
(
m_atom_index
.
begin
()
+
R
+
1
,
m_atoms
.
size
());
// make sure the atom_type is known
auto
&
atom_type
=
m_db
[
"atom_type"
];
std
::
string
symbol
=
atom
.
get_property
(
"type_symbol"
);
using
namespace
cif
::
literals
;
if
(
not
atom_type
.
exists
(
"symbol"
_key
==
symbol
))
atom_type
.
emplace
({
{
"symbol"
,
symbol
}
});
return
m_atoms
.
emplace_back
(
std
::
move
(
atom
));
}
...
...
@@ -2088,7 +2156,7 @@ std::string structure::create_non_poly(const std::string &entity_id, const std::
{
"pdbx_PDB_model_num"
,
1
}
});
auto
&
newAtom
=
emplace_atom
(
std
::
make_shared
<
atom
::
atom_impl
>
(
m_db
,
atom_id
,
row
));
auto
&
newAtom
=
emplace_atom
(
std
::
make_shared
<
atom
::
atom_impl
>
(
m_db
,
atom_id
));
res
.
add_atom
(
newAtom
);
}
...
...
@@ -2110,7 +2178,7 @@ std::string structure::create_non_poly(const std::string &entity_id, const std::
return
asym_id
;
}
std
::
string
structure
::
create_non_poly
(
const
std
::
string
&
entity_id
,
std
::
vector
<
std
::
vector
<
item
>>
&
atom_info
)
std
::
string
structure
::
create_non_poly
(
const
std
::
string
&
entity_id
,
std
::
vector
<
row_initializer
>
atoms
)
{
using
namespace
literals
;
...
...
@@ -2131,14 +2199,14 @@ std::string structure::create_non_poly(const std::string &entity_id, std::vector
auto
&
res
=
m_non_polymers
.
emplace_back
(
*
this
,
comp_id
,
asym_id
,
0
,
"1"
);
auto
appendUnlessSet
=
[](
std
::
vector
<
item
>
&
ai
,
item
&&
i
)
auto
appendUnlessSet
=
[](
row_initializer
&
ai
,
item
&&
i
)
{
if
(
find_if
(
ai
.
begin
(),
ai
.
end
(),
[
name
=
i
.
name
()](
item
&
ci
)
{
return
ci
.
name
()
==
name
;
})
==
ai
.
end
())
ai
.
emplace_back
(
std
::
move
(
i
));
};
for
(
auto
&
atom
:
atom
_info
)
for
(
auto
&
atom
:
atom
s
)
{
auto
atom_id
=
atom_site
.
get_unique_id
(
""
);
...
...
@@ -2156,7 +2224,7 @@ std::string structure::create_non_poly(const std::string &entity_id, std::vector
auto
row
=
atom_site
.
emplace
(
atom
.
begin
(),
atom
.
end
());
auto
&
newAtom
=
emplace_atom
(
std
::
make_shared
<
atom
::
atom_impl
>
(
m_db
,
atom_id
,
row
));
auto
&
newAtom
=
emplace_atom
(
std
::
make_shared
<
atom
::
atom_impl
>
(
m_db
,
atom_id
));
res
.
add_atom
(
newAtom
);
}
...
...
@@ -2178,10 +2246,10 @@ std::string structure::create_non_poly(const std::string &entity_id, std::vector
return
asym_id
;
}
branch
&
structure
::
create_branch
(
std
::
vector
<
std
::
vector
<
item
>>
&
nag_
atoms
)
branch
&
structure
::
create_branch
(
std
::
vector
<
row_initializer
>
atoms
)
{
// sanity check
for
(
auto
&
nag_atom
:
nag_
atoms
)
for
(
auto
&
nag_atom
:
atoms
)
{
for
(
auto
info
:
nag_atom
)
{
...
...
@@ -2201,14 +2269,14 @@ branch &structure::create_branch(std::vector<std::vector<item>> &nag_atoms)
auto
&
atom_site
=
m_db
[
"atom_site"
];
auto
appendUnlessSet
=
[](
std
::
vector
<
item
>
&
ai
,
item
&&
i
)
auto
appendUnlessSet
=
[](
row_initializer
&
ai
,
item
&&
i
)
{
if
(
find_if
(
ai
.
begin
(),
ai
.
end
(),
[
name
=
i
.
name
()](
item
&
ci
)
{
return
ci
.
name
()
==
name
;
})
==
ai
.
end
())
ai
.
emplace_back
(
std
::
move
(
i
));
};
for
(
auto
&
atom
:
nag_
atoms
)
for
(
auto
&
atom
:
atoms
)
{
auto
atom_id
=
atom_site
.
get_unique_id
(
""
);
...
...
@@ -2226,7 +2294,7 @@ branch &structure::create_branch(std::vector<std::vector<item>> &nag_atoms)
auto
row
=
atom_site
.
emplace
(
atom
.
begin
(),
atom
.
end
());
auto
&
newAtom
=
emplace_atom
(
std
::
make_shared
<
atom
::
atom_impl
>
(
m_db
,
atom_id
,
row
));
auto
&
newAtom
=
emplace_atom
(
std
::
make_shared
<
atom
::
atom_impl
>
(
m_db
,
atom_id
));
sugar
.
add_atom
(
newAtom
);
}
...
...
@@ -2265,7 +2333,7 @@ branch &structure::create_branch(std::vector<std::vector<item>> &nag_atoms)
return
branch
;
}
branch
&
structure
::
extend_branch
(
const
std
::
string
&
asym_id
,
std
::
vector
<
std
::
vector
<
item
>>
&
atom_info
,
branch
&
structure
::
extend_branch
(
const
std
::
string
&
asym_id
,
std
::
vector
<
row_initializer
>
atom_info
,
int
link_sugar
,
const
std
::
string
&
link_atom
)
{
// sanity check
...
...
src/row.cpp
View file @
6a0b6b99
...
...
@@ -69,7 +69,7 @@ row_initializer::row_initializer(row_handle rh)
auto
&
cat
=
*
rh
.
m_category
;
for
(
auto
i
=
r
->
m_head
;
i
!=
nullptr
;
i
=
i
->
m_next
)
m_items
.
emplace_back
(
cat
.
get_column_name
(
i
->
m_column_ix
),
i
->
text
());
emplace_back
(
cat
.
get_column_name
(
i
->
m_column_ix
),
i
->
text
());
}
}
//
namespace
cif
\ No newline at end of file
test/1juh.cif.gz
0 → 100644
View file @
6a0b6b99
File added
test/model-test.cpp
View file @
6a0b6b99
...
...
@@ -177,6 +177,7 @@ _struct_asym.pdbx_blank_PDB_chainid_flag N
_struct_asym.pdbx_modified N
_struct_asym.details ?
#
_atom_type.symbol C
)"
_cf
;
expected
.
load_dictionary
(
"mmcif_pdbx.dic"
);
...
...
test/rename-compound-test.cpp
View file @
6a0b6b99
#include "../include/cif++/Cif++.hpp"
#include "../include/cif++/PDB2Cif.hpp"
#include "../include/cif++/Structure.hpp"
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cif++.hpp>
#include <iostream>
#include <fstream>
...
...
@@ -22,16 +46,16 @@ int main(int argc, char* argv[])
if
(
std
::
filesystem
::
exists
(
testdir
/
".."
/
"rsrc"
/
"mmcif_pdbx.dic"
))
cif
::
add_file_resource
(
"mmcif_pdbx.dic"
,
testdir
/
".."
/
"rsrc"
/
"mmcif_pdbx.dic"
);
mmcif
::
CompoundFactory
::
instance
().
pushD
ictionary
(
testdir
/
"REA.cif"
);
mmcif
::
CompoundFactory
::
instance
().
pushD
ictionary
(
testdir
/
"RXA.cif"
);
cif
::
compound_factory
::
instance
().
push_d
ictionary
(
testdir
/
"REA.cif"
);
cif
::
compound_factory
::
instance
().
push_d
ictionary
(
testdir
/
"RXA.cif"
);
mm
cif
::
file
f
(
testdir
/
".."
/
"examples"
/
"1cbs.cif.gz"
);
mmcif
::
S
tructure
structure
(
f
);
cif
::
file
f
(
testdir
/
".."
/
"examples"
/
"1cbs.cif.gz"
);
cif
::
mm
::
s
tructure
structure
(
f
);
auto
&
res
=
structure
.
get
R
esidue
(
"B"
);
auto
&
res
=
structure
.
get
_r
esidue
(
"B"
);
structure
.
change_residue
(
res
,
"RXA"
,
{});
structure
.
cleanup
EmptyC
ategories
();
structure
.
cleanup
_empty_c
ategories
();
f
.
save
(
std
::
cout
);
}
...
...
test/sugar-test.cpp
View file @
6a0b6b99
...
...
@@ -29,8 +29,7 @@
#include <stdexcept>
#include <cif++/cif.hpp>
#include <cif++/structure/Structure.hpp>
#include <cif++.hpp>
// --------------------------------------------------------------------
...
...
@@ -66,7 +65,7 @@ bool init_unit_test()
// initialize CCD location
cif
::
add_file_resource
(
"components.cif"
,
gTestDir
/
".."
/
"data"
/
"ccd-subset.cif"
);
mmcif
::
CompoundFactory
::
instance
().
pushD
ictionary
(
gTestDir
/
"HEM.cif"
);
cif
::
compound_factory
::
instance
().
push_d
ictionary
(
gTestDir
/
"HEM.cif"
);
return
true
;
}
...
...
@@ -78,10 +77,10 @@ BOOST_AUTO_TEST_CASE(sugar_name_1)
using
namespace
cif
::
literals
;
const
std
::
filesystem
::
path
example
(
gTestDir
/
"1juh.cif.gz"
);
mm
cif
::
file
file
(
example
.
string
());
mmcif
::
S
tructure
s
(
file
);
cif
::
file
file
(
example
.
string
());
cif
::
mm
::
s
tructure
s
(
file
);
auto
&
db
=
s
.
datablock
();
auto
&
db
=
s
.
get_
datablock
();
auto
&
entity
=
db
[
"entity"
];
auto
&
branches
=
s
.
branches
();
...
...
@@ -90,7 +89,7 @@ BOOST_AUTO_TEST_CASE(sugar_name_1)
for
(
auto
&
branch
:
branches
)
{
auto
entityID
=
branch
.
front
().
entityID
();
auto
entityID
=
branch
.
front
().
get_entity_id
();
auto
name
=
entity
.
find1
<
std
::
string
>
(
"id"
_key
==
entityID
,
"pdbx_description"
);
BOOST_CHECK_EQUAL
(
branch
.
name
(),
name
);
...
...
@@ -104,20 +103,20 @@ BOOST_AUTO_TEST_CASE(create_sugar_1)
using
namespace
cif
::
literals
;
const
std
::
filesystem
::
path
example
(
gTestDir
/
"1juh.cif.gz"
);
mm
cif
::
file
file
(
example
.
string
());
mmcif
::
S
tructure
s
(
file
);
cif
::
file
file
(
example
.
string
());
cif
::
mm
::
s
tructure
s
(
file
);
// collect atoms from asym L first
auto
&
NAG
=
s
.
get
R
esidue
(
"L"
);
auto
&
NAG
=
s
.
get
_r
esidue
(
"L"
);
auto
nagAtoms
=
NAG
.
atoms
();
std
::
vector
<
std
::
vector
<
cif
::
Item
>
>
ai
;
std
::
vector
<
cif
::
row_initializer
>
ai
;
auto
&
db
=
s
.
datablock
();
auto
&
db
=
s
.
get_
datablock
();
auto
&
as
=
db
[
"atom_site"
];
for
(
auto
r
:
as
.
find
(
"label_asym_id"
_key
==
"L"
))
ai
.
emplace_back
(
r
.
begin
(),
r
.
end
()
);
ai
.
emplace_back
(
r
);
s
.
remove_residue
(
NAG
);
...
...
@@ -136,36 +135,36 @@ BOOST_AUTO_TEST_CASE(create_sugar_2)
using
namespace
cif
::
literals
;
const
std
::
filesystem
::
path
example
(
gTestDir
/
"1juh.cif.gz"
);
mm
cif
::
file
file
(
example
.
string
());
mmcif
::
S
tructure
s
(
file
);
cif
::
file
file
(
example
.
string
());
cif
::
mm
::
s
tructure
s
(
file
);
// Get branch for H
auto
&
bH
=
s
.
get
BranchByAsymID
(
"H"
);
auto
&
bH
=
s
.
get
_branch_by_asym_id
(
"H"
);
BOOST_CHECK_EQUAL
(
bH
.
size
(),
2
);
std
::
vector
<
std
::
vector
<
cif
::
Item
>
>
ai
[
2
];
std
::
vector
<
cif
::
row_initializer
>
ai
[
2
];
auto
&
db
=
s
.
datablock
();
auto
&
db
=
s
.
get_
datablock
();
auto
&
as
=
db
[
"atom_site"
];
for
(
size_t
i
=
0
;
i
<
2
;
++
i
)
{
for
(
auto
r
:
as
.
find
(
"label_asym_id"
_key
==
"H"
and
"auth_seq_id"
_key
==
i
+
1
))
ai
[
i
].
emplace_back
(
r
.
begin
(),
r
.
end
()
);
ai
[
i
].
emplace_back
(
r
);
}
s
.
remove_branch
(
bH
);
auto
&
bN
=
s
.
create_branch
(
ai
[
0
]);
s
.
extend_branch
(
bN
.
asymID
(),
ai
[
1
],
1
,
"O4"
);
s
.
extend_branch
(
bN
.
get_asym_id
(),
ai
[
1
],
1
,
"O4"
);
BOOST_CHECK_EQUAL
(
bN
.
name
(),
"2-acetamido-2-deoxy-beta-D-glucopyranose-(1-4)-2-acetamido-2-deoxy-beta-D-glucopyranose"
);
BOOST_CHECK_EQUAL
(
bN
.
size
(),
2
);
file
.
save
(
gTestDir
/
"test-create_sugar_2.cif"
);
BOOST_CHECK_NO_THROW
(
mmcif
::
S
tructure
s2
(
file
));
BOOST_CHECK_NO_THROW
(
cif
::
mm
::
s
tructure
s2
(
file
));
}
// --------------------------------------------------------------------
...
...
@@ -175,11 +174,11 @@ BOOST_AUTO_TEST_CASE(delete_sugar_1)
using
namespace
cif
::
literals
;
const
std
::
filesystem
::
path
example
(
gTestDir
/
"1juh.cif.gz"
);
mm
cif
::
file
file
(
example
.
string
());
mmcif
::
S
tructure
s
(
file
);
cif
::
file
file
(
example
.
string
());
cif
::
mm
::
s
tructure
s
(
file
);
// Get branch for H
auto
&
bG
=
s
.
get
BranchByAsymID
(
"G"
);
auto
&
bG
=
s
.
get
_branch_by_asym_id
(
"G"
);
BOOST_CHECK_EQUAL
(
bG
.
size
(),
4
);
...
...
@@ -187,12 +186,12 @@ BOOST_AUTO_TEST_CASE(delete_sugar_1)
BOOST_CHECK_EQUAL
(
bG
.
size
(),
1
);
auto
&
bN
=
s
.
get
BranchByAsymID
(
"G"
);
auto
&
bN
=
s
.
get
_branch_by_asym_id
(
"G"
);
BOOST_CHECK_EQUAL
(
bN
.
name
(),
"2-acetamido-2-deoxy-beta-D-glucopyranose"
);
BOOST_CHECK_EQUAL
(
bN
.
size
(),
1
);
file
.
save
(
gTestDir
/
"test-create_sugar_3.cif"
);
BOOST_CHECK_NO_THROW
(
mmcif
::
S
tructure
s2
(
file
));
BOOST_CHECK_NO_THROW
(
cif
::
mm
::
s
tructure
s2
(
file
));
}
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