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
c3434507
Unverified
Commit
c3434507
authored
Sep 14, 2021
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
new find1
parent
79ecf20b
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
71 additions
and
100 deletions
+71
-100
include/cif++/Cif++.hpp
+28
-8
include/cif++/Structure.hpp
+3
-5
src/Structure.cpp
+22
-35
test/structure-test.cpp
+17
-51
test/unit-test.cpp
+1
-1
No files found.
include/cif++/Cif++.hpp
View file @
c3434507
...
...
@@ -1903,19 +1903,39 @@ class Category
return
*
h
.
begin
();
}
template
<
typename
...
Ts
,
size_t
N
>
std
::
tuple
<
Ts
...
>
find1
(
Condition
&&
cond
,
char
const
*
const
(
&
columns
)[
N
]
)
template
<
typename
T
>
T
find1
(
Condition
&&
cond
,
const
char
*
column
)
{
static_assert
(
sizeof
...(
Ts
)
==
N
,
"The number of column titles should be equal to the number of types to return"
);
return
find1
<
Ts
...
>
(
cbegin
(),
std
::
forward
<
Condition
>
(
cond
),
std
::
forward
<
char
const
*
const
[
N
]
>
(
columns
));
return
find1
<
T
>
(
cbegin
(),
std
::
forward
<
Condition
>
(
cond
),
column
);
}
template
<
typename
...
Ts
,
size_t
N
>
std
::
tuple
<
Ts
...
>
find1
(
const_iterator
pos
,
Condition
&&
cond
,
char
const
*
const
(
&
columns
)[
N
]
)
template
<
typename
T
>
T
find1
(
const_iterator
pos
,
Condition
&&
cond
,
const
char
*
column
)
{
static_assert
(
sizeof
...(
Ts
)
==
N
,
"The number of column titles should be equal to the number of types to return"
);
auto
h
=
find
<
T
>
(
pos
,
std
::
forward
<
Condition
>
(
cond
),
{
column
});
if
(
h
.
empty
())
throw
std
::
runtime_error
(
"No hits found"
);
auto
h
=
find
<
Ts
...
>
(
pos
,
std
::
forward
<
Condition
>
(
cond
),
std
::
forward
<
char
const
*
const
[
N
]
>
(
columns
));
if
(
h
.
size
()
!=
1
)
throw
std
::
runtime_error
(
"Hit not unique"
);
return
std
::
get
<
0
>
(
*
h
.
begin
());
}
template
<
typename
...
Ts
,
typename
...
Cs
,
typename
U
=
std
::
enable_if_t
<
sizeof
...(
Ts
)
!=
1
>>
std
::
tuple
<
Ts
...
>
find1
(
Condition
&&
cond
,
Cs
...
columns
)
{
static_assert
(
sizeof
...(
Ts
)
==
sizeof
...(
Cs
),
"The number of column titles should be equal to the number of types to return"
);
// static_assert(std::is_same_v<Cs, const char*>..., "The column names should be const char");
return
find1
<
Ts
...
>
(
cbegin
(),
std
::
forward
<
Condition
>
(
cond
),
std
::
forward
<
Cs
>
(
columns
)...);
}
template
<
typename
...
Ts
,
typename
...
Cs
,
typename
U
=
std
::
enable_if_t
<
sizeof
...(
Ts
)
!=
1
>>
std
::
tuple
<
Ts
...
>
find1
(
const_iterator
pos
,
Condition
&&
cond
,
Cs
...
columns
)
{
static_assert
(
sizeof
...(
Ts
)
==
sizeof
...(
Cs
),
"The number of column titles should be equal to the number of types to return"
);
auto
h
=
find
<
Ts
...
>
(
pos
,
std
::
forward
<
Condition
>
(
cond
),
{
columns
...
});
if
(
h
.
empty
())
throw
std
::
runtime_error
(
"No hits found"
);
...
...
include/cif++/Structure.hpp
View file @
c3434507
...
...
@@ -485,11 +485,9 @@ class Structure
const
std
::
vector
<
std
::
tuple
<
std
::
string
,
std
::
string
>>
&
remappedAtoms
);
/// \brief Create a new non-polymer entity, returns new ID
/// \param data The data to use to fill the entity
/// \param mon_id The mon_id for the new nonpoly
/// \param name The name of the nonpoly
/// \param mon_id The mon_id for the new nonpoly, must be an existing and known compound from CCD
/// \return The ID of the created entity
std
::
string
createEntityNonPoly
(
std
::
vector
<
cif
::
Item
>
data
,
const
std
::
string
&
mon_id
);
std
::
string
createEntityNonPoly
(
const
std
::
string
&
mon_id
);
/// \brief Create a new NonPolymer struct_asym with atoms constructed from \a atom_data, returns asym_id
/// \param entity_id The entity ID of the new nonpoly
...
...
@@ -515,7 +513,7 @@ class Structure
cif
::
Category
&
category
(
const
char
*
name
)
const
;
cif
::
Datablock
&
datablock
()
const
;
void
insertCompound
(
const
std
::
string
&
compoundID
,
bool
isEntity
);
std
::
string
insertCompound
(
const
std
::
string
&
compoundID
,
bool
isEntity
);
void
loadData
();
void
updateAtomIndex
();
...
...
src/Structure.cpp
View file @
c3434507
...
...
@@ -2161,8 +2161,10 @@ cif::Datablock &Structure::datablock() const
return
*
mFile
.
impl
().
mDb
;
}
void
Structure
::
insertCompound
(
const
std
::
string
&
compoundID
,
bool
isEntity
)
std
::
string
Structure
::
insertCompound
(
const
std
::
string
&
compoundID
,
bool
isEntity
)
{
using
namespace
cif
::
literals
;
auto
compound
=
CompoundFactory
::
instance
().
create
(
compoundID
);
if
(
compound
==
nullptr
)
throw
std
::
runtime_error
(
"Trying to insert unknown compound "
+
compoundID
+
" (not found in CCD)"
);
...
...
@@ -2173,31 +2175,42 @@ void Structure::insertCompound(const std::string &compoundID, bool isEntity)
auto
r
=
chemComp
.
find
(
cif
::
Key
(
"id"
)
==
compoundID
);
if
(
r
.
empty
())
{
chemComp
.
emplace
({{
"id"
,
compoundID
},
chemComp
.
emplace
({
{
"id"
,
compoundID
},
{
"name"
,
compound
->
name
()},
{
"formula"
,
compound
->
formula
()},
{
"formula_weight"
,
compound
->
formulaWeight
()},
{
"type"
,
compound
->
type
()}});
}
std
::
string
entity_id
;
if
(
isEntity
)
{
auto
&
pdbxEntityNonpoly
=
db
[
"pdbx_entity_nonpoly"
];
if
(
not
pdbxEntityNonpoly
.
exists
(
cif
::
Key
(
"comp_id"
)
==
compoundID
))
try
{
entity_id
=
pdbxEntityNonpoly
.
find1
<
std
::
string
>
(
"comp_id"
_key
==
compoundID
,
"entity_id"
);
}
catch
(
const
std
::
exception
&
ex
)
{
auto
&
entity
=
db
[
"entity"
];
std
::
string
entityID
=
std
::
to_string
(
entity
.
size
()
+
1
);
entity_id
=
std
::
to_string
(
entity
.
size
()
+
1
);
entity
.
emplace
({{
"id"
,
entityID
},
entity
.
emplace
({
{
"id"
,
entity_id
},
{
"type"
,
"non-polymer"
},
{
"pdbx_description"
,
compound
->
name
()},
{
"formula_weight"
,
compound
->
formulaWeight
()}});
pdbxEntityNonpoly
.
emplace
({{
"entity_id"
,
entityID
},
pdbxEntityNonpoly
.
emplace
({
{
"entity_id"
,
entity_id
},
{
"name"
,
compound
->
name
()},
{
"comp_id"
,
compoundID
}});
}
}
return
entity_id
;
}
// // --------------------------------------------------------------------
...
...
@@ -2340,7 +2353,7 @@ void Structure::changeResidue(const Residue &res, const std::string &newCompound
try
{
std
::
tie
(
entityID
)
=
entity
.
find1
<
std
::
string
>
(
"type"
_key
==
"non-polymer"
and
"pdbx_description"
_key
==
compound
->
name
(),
{
"id"
}
);
entityID
=
entity
.
find1
<
std
::
string
>
(
"type"
_key
==
"non-polymer"
and
"pdbx_description"
_key
==
compound
->
name
(),
"id"
);
}
catch
(
const
std
::
exception
&
ex
)
{
...
...
@@ -2413,35 +2426,9 @@ void Structure::changeResidue(const Residue &res, const std::string &newCompound
}
}
std
::
string
Structure
::
createEntityNonPoly
(
std
::
vector
<
cif
::
Item
>
data
,
const
std
::
string
&
comp_id
)
std
::
string
Structure
::
createEntityNonPoly
(
const
std
::
string
&
comp_id
)
{
using
namespace
cif
::
literals
;
auto
&
db
=
mFile
.
data
();
auto
&
entity
=
db
[
"entity"
];
std
::
string
entity_id
=
entity
.
getUniqueID
(
""
);
// remove any ID fields
data
.
erase
(
std
::
remove_if
(
data
.
begin
(),
data
.
end
(),
[](
cif
::
Item
&
item
)
{
return
item
.
name
()
==
"id"
;
}),
data
.
end
());
// add our new ID
data
.
emplace_back
(
"id"
,
entity_id
);
data
.
emplace_back
(
"type"
,
"non-polymer"
);
entity
.
emplace
(
data
.
begin
(),
data
.
end
());
const
auto
&
[
name
]
=
entity
.
find1
<
std
::
string
>
(
"id"
_key
==
entity_id
,
{
"pdbx_description"
});
auto
&
pdbx_entity_nonpoly
=
db
[
"pdbx_entity_nonpoly"
];
pdbx_entity_nonpoly
.
emplace
({
{
"entity_id"
,
entity_id
},
{
"name"
,
name
},
{
"comp_id"
,
comp_id
}
});
return
entity_id
;
return
insertCompound
(
comp_id
,
true
);
}
std
::
string
Structure
::
createNonpoly
(
const
std
::
string
&
entity_id
,
const
std
::
vector
<
cif
::
Item
>
&
atoms
)
...
...
test/structure-test.cpp
View file @
c3434507
...
...
@@ -59,18 +59,22 @@ BOOST_AUTO_TEST_CASE(create_nonpoly_1)
auto
expected
=
R"(
data_TEST
loop_
_entity.id
_entity.type
_entity.src_method
_entity.pdbx_description
_entity.formula_weight
1 non-polymer syn 'PROTOPORPHYRIN IX CONTAINING FE' 616.487
loop_
_pdbx_entity_nonpoly.entity_id
_pdbx_entity_nonpoly.name
_pdbx_entity_nonpoly.comp_id
1 'PROTOPORPHYRIN IX CONTAINING FE' HEM
#
_chem_comp.id HEM
_chem_comp.type NON-POLYMER
_chem_comp.name 'PROTOPORPHYRIN IX CONTAINING FE'
_chem_comp.formula 'C34 H32 Fe N4 O4'
_chem_comp.formula_weight 616.487000
#
_pdbx_entity_nonpoly.entity_id 1
_pdbx_entity_nonpoly.name 'PROTOPORPHYRIN IX CONTAINING FE'
_pdbx_entity_nonpoly.comp_id HEM
#
_entity.id 1
_entity.type non-polymer
_entity.pdbx_description 'PROTOPORPHYRIN IX CONTAINING FE'
_entity.formula_weight 616.487000
#
)"
_cf
;
expected
.
loadDictionary
(
"mmcif_pdbx_v50.dic"
);
...
...
@@ -81,11 +85,7 @@ _pdbx_entity_nonpoly.comp_id
mmcif
::
Structure
structure
(
file
);
structure
.
createEntityNonPoly
({
{
"src_method"
,
"syn"
},
{
"pdbx_description"
,
"PROTOPORPHYRIN IX CONTAINING FE"
},
{
"formula_weight"
,
616.487
}
},
"HEM"
);
structure
.
createEntityNonPoly
(
"HEM"
);
if
(
not
(
expected
.
firstDatablock
()
==
structure
.
getFile
().
data
()))
{
...
...
@@ -94,38 +94,4 @@ _pdbx_entity_nonpoly.comp_id
<<
std
::
endl
<<
structure
.
getFile
().
data
()
<<
std
::
endl
;
}
// // using namespace mmcif;
// auto f = R"(data_TEST
// #
// loop_
// _test.id
// _test.name
// 1 aap
// 2 noot
// 3 mies
// )"_cf;
// auto& db = f.firstDatablock();
// BOOST_CHECK(db.getName() == "TEST");
// auto& test = db["test"];
// BOOST_CHECK(test.size() == 3);
// // wrong! the next lines will crash. And that's OK, don't do that
// // for (auto r: test)
// // test.erase(r);
// // BOOST_CHECK(test.empty());
// // test.purge();
// auto n = test.erase(cif::Key("id") == 1, [](const cif::Row& r) {
// BOOST_CHECK_EQUAL(r["id"].as<int>(), 1);
// BOOST_CHECK_EQUAL(r["name"].as<std::string>(), "aap");
// });
// BOOST_CHECK_EQUAL(n, 1);
}
test/unit-test.cpp
View file @
c3434507
...
...
@@ -1207,7 +1207,7 @@ _test.name
}
}
const
auto
&
[
id
,
name
]
=
db
[
"test"
].
find1
<
int
,
std
::
string
>
(
cif
::
Key
(
"id"
)
==
1
,
{
"id"
,
"name"
}
);
const
auto
&
[
id
,
name
]
=
db
[
"test"
].
find1
<
int
,
std
::
string
>
(
cif
::
Key
(
"id"
)
==
1
,
"id"
,
"name"
);
BOOST_CHECK
(
id
==
1
);
BOOST_CHECK
(
name
==
"aap"
);
...
...
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