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
4732004b
Unverified
Commit
4732004b
authored
Jan 12, 2022
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into trunk
parents
d4bd3faa
faa9cd04
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
612 additions
and
1010 deletions
+612
-1010
include/cif++/Cif++.hpp
+3
-2
include/cif++/Structure.hpp
+139
-76
src/BondMap.cpp
+5
-2
src/Cif++.cpp
+76
-209
src/Cif2PDB.cpp
+6
-3
src/CifParser.cpp
+4
-3
src/CifUtils.cpp
+1
-1
src/CifValidator.cpp
+1
-1
src/Compound.cpp
+8
-6
src/PDB2Cif.cpp
+58
-49
src/PDB2CifRemark3.cpp
+9
-7
src/Secondary.cpp
+6
-6
src/Structure.cpp
+251
-622
src/TlsParser.cpp
+25
-23
test/structure-test.cpp
+20
-0
No files found.
include/cif++/Cif++.hpp
View file @
4732004b
...
...
@@ -792,7 +792,7 @@ class Row
}
void
assign
(
const
std
::
vector
<
Item
>
&
values
);
void
assign
(
std
::
string_view
name
,
const
std
::
string
&
value
,
bool
updateLinked
);
void
assign
(
std
::
string_view
name
,
const
std
::
string
&
value
,
bool
updateLinked
,
bool
validate
=
true
);
bool
operator
==
(
const
Row
&
rhs
)
const
{
...
...
@@ -814,7 +814,7 @@ class Row
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Row
&
row
);
private
:
void
assign
(
size_t
column
,
const
std
::
string
&
value
,
bool
updateLinked
);
void
assign
(
size_t
column
,
const
std
::
string
&
value
,
bool
updateLinked
,
bool
validate
=
true
);
void
assign
(
const
Item
&
i
,
bool
updateLinked
);
static
void
swap
(
size_t
column
,
ItemRow
*
a
,
ItemRow
*
b
);
...
...
@@ -2152,6 +2152,7 @@ class Category
std
::
vector
<
ItemColumn
>
mColumns
;
ItemRow
*
mHead
;
ItemRow
*
mTail
;
size_t
mLastUniqueNr
=
0
;
class
CatIndex
*
mIndex
;
std
::
vector
<
Linked
>
mParentLinks
,
mChildLinks
;
...
...
include/cif++/Structure.hpp
View file @
4732004b
...
...
@@ -60,30 +60,101 @@ class File;
class
Atom
{
private
:
struct
AtomImpl
:
public
std
::
enable_shared_from_this
<
AtomImpl
>
{
AtomImpl
(
cif
::
Datablock
&
db
,
const
std
::
string
&
id
,
cif
::
Row
row
);
// constructor for a symmetry copy of an atom
AtomImpl
(
const
AtomImpl
&
impl
,
const
Point
&
loc
,
const
std
::
string
&
sym_op
);
AtomImpl
(
const
AtomImpl
&
i
)
=
default
;
void
prefetch
();
int
compare
(
const
AtomImpl
&
b
)
const
;
bool
getAnisoU
(
float
anisou
[
6
])
const
;
void
moveTo
(
const
Point
&
p
);
const
Compound
&
comp
()
const
;
const
std
::
string
get_property
(
const
std
::
string_view
name
)
const
;
void
set_property
(
const
std
::
string_view
name
,
const
std
::
string
&
value
);
const
cif
::
Datablock
&
mDb
;
std
::
string
mID
;
AtomType
mType
;
std
::
string
mAtomID
;
std
::
string
mCompID
;
std
::
string
mAsymID
;
int
mSeqID
;
std
::
string
mAltID
;
std
::
string
mAuthSeqID
;
Point
mLocation
;
int
mRefcount
;
cif
::
Row
mRow
;
mutable
std
::
vector
<
std
::
tuple
<
std
::
string
,
cif
::
detail
::
ItemReference
>>
mCachedRefs
;
mutable
const
Compound
*
mCompound
=
nullptr
;
bool
mSymmetryCopy
=
false
;
bool
mClone
=
false
;
std
::
string
mSymmetryOperator
=
"1_555"
;
};
public
:
Atom
();
Atom
(
struct
AtomImpl
*
impl
);
Atom
(
const
Atom
&
rhs
);
Atom
()
{}
Atom
(
std
::
shared_ptr
<
AtomImpl
>
impl
)
:
mImpl
(
impl
)
{}
Atom
(
const
Atom
&
rhs
)
:
mImpl
(
rhs
.
mImpl
)
{}
Atom
(
cif
::
Datablock
&
db
,
cif
::
Row
&
row
);
// a special constructor to create symmetry copies
Atom
(
const
Atom
&
rhs
,
const
Point
&
symmmetry_location
,
const
std
::
string
&
symmetry_operation
);
~
Atom
();
explicit
operator
bool
()
const
{
return
mImpl_
!=
nullptr
;
}
explicit
operator
bool
()
const
{
return
(
bool
)
mImpl
;
}
// return a copy of this atom, with data copied instead of referenced
Atom
clone
()
const
;
Atom
clone
()
const
{
auto
copy
=
std
::
make_shared
<
AtomImpl
>
(
*
mImpl
);
copy
->
mClone
=
true
;
return
Atom
(
copy
);
}
Atom
&
operator
=
(
const
Atom
&
rhs
)
=
default
;
Atom
&
operator
=
(
const
Atom
&
rhs
);
template
<
typename
T
>
T
get_property
(
const
std
::
string_view
name
)
const
;
void
set_property
(
const
std
::
string_view
name
,
const
std
::
string
&
value
)
{
mImpl
->
set_property
(
name
,
value
);
}
template
<
typename
T
,
std
::
enable_if_t
<
std
::
is_arithmetic_v
<
T
>
,
int
>
=
0
>
void
property
(
const
std
::
string_view
name
,
const
T
&
value
)
{
set_property
(
name
,
std
::
to_string
(
value
));
}
const
std
::
string
&
id
()
const
;
AtomType
type
()
const
;
const
std
::
string
&
id
()
const
{
return
mImpl
->
mID
;
}
AtomType
type
()
const
{
return
mImpl
->
mType
;
}
Point
location
()
const
;
void
location
(
Point
p
)
;
Point
location
()
const
{
return
mImpl
->
mLocation
;
}
void
location
(
Point
p
)
{
mImpl
->
moveTo
(
p
);
}
/// \brief Translate the position of this atom by \a t
void
translate
(
Point
t
);
...
...
@@ -91,47 +162,40 @@ class Atom
/// \brief Rotate the position of this atom by \a q
void
rotate
(
Quaternion
q
);
/// \brief Translate and rotate the position of this atom by \a t and \a q
void
translateAndRotate
(
Point
t
,
Quaternion
q
);
/// \brief Translate, rotate and translate again the coordinates this atom by \a t1 , \a q and \a t2
void
translateRotateAndTranslate
(
Point
t1
,
Quaternion
q
,
Point
t2
);
// for direct access to underlying data, be careful!
const
cif
::
Row
getRow
()
const
;
const
cif
::
Row
getRow
()
const
{
return
mImpl
->
mRow
;
}
const
cif
::
Row
getRowAniso
()
const
;
// Atom symmetryCopy(const Point& d, const clipper::RTop_orth& rt);
bool
isSymmetryCopy
()
const
;
std
::
string
symmetry
()
const
;
// const clipper::RTop_orth& symop() const;
bool
isSymmetryCopy
()
const
{
return
mImpl
->
mSymmetryCopy
;
}
std
::
string
symmetry
()
const
{
return
mImpl
->
mSymmetryOperator
;
}
const
Compound
&
comp
()
const
;
bool
isWater
()
const
;
const
Compound
&
comp
()
const
{
return
mImpl
->
comp
();
}
bool
isWater
()
const
{
return
mImpl
->
mCompID
==
"HOH"
or
mImpl
->
mCompID
==
"H2O"
or
mImpl
->
mCompID
==
"WAT"
;
}
int
charge
()
const
;
float
uIso
()
const
;
bool
getAnisoU
(
float
anisou
[
6
])
const
;
bool
getAnisoU
(
float
anisou
[
6
])
const
{
return
mImpl
->
getAnisoU
(
anisou
);
}
float
occupancy
()
const
;
template
<
typename
T
>
T
property
(
const
std
::
string_view
name
)
const
;
void
property
(
const
std
::
string_view
name
,
const
std
::
string
&
value
);
template
<
typename
T
,
std
::
enable_if_t
<
std
::
is_arithmetic_v
<
T
>
,
int
>
=
0
>
void
property
(
const
std
::
string_view
name
,
const
T
&
value
)
{
property
(
name
,
std
::
to_string
(
value
));
}
// specifications
const
std
::
string
&
labelAtomID
()
const
{
return
mAtomID
;
}
const
std
::
string
&
labelCompID
()
const
{
return
mCompID
;
}
const
std
::
string
&
labelAsymID
()
const
{
return
mAsymID
;
}
const
std
::
string
&
labelAtomID
()
const
{
return
m
Impl
->
m
AtomID
;
}
const
std
::
string
&
labelCompID
()
const
{
return
m
Impl
->
m
CompID
;
}
const
std
::
string
&
labelAsymID
()
const
{
return
m
Impl
->
m
AsymID
;
}
std
::
string
labelEntityID
()
const
;
int
labelSeqID
()
const
{
return
mSeqID
;
}
const
std
::
string
&
labelAltID
()
const
{
return
mAltID
;
}
bool
isAlternate
()
const
{
return
not
mAltID
.
empty
();
}
int
labelSeqID
()
const
{
return
m
Impl
->
m
SeqID
;
}
const
std
::
string
&
labelAltID
()
const
{
return
m
Impl
->
m
AltID
;
}
bool
isAlternate
()
const
{
return
not
m
Impl
->
m
AltID
.
empty
();
}
std
::
string
authAtomID
()
const
;
std
::
string
authCompID
()
const
;
std
::
string
authAsymID
()
const
;
const
std
::
string
&
authSeqID
()
const
{
return
mAuthSeqID
;
}
const
std
::
string
&
authSeqID
()
const
{
return
m
Impl
->
m
AuthSeqID
;
}
std
::
string
pdbxAuthInsCode
()
const
;
std
::
string
pdbxAuthAltID
()
const
;
...
...
@@ -140,13 +204,6 @@ class Atom
bool
operator
==
(
const
Atom
&
rhs
)
const
;
// // get clipper format Atom
// clipper::Atom toClipper() const;
// Radius calculation based on integrating the density until perc of electrons is found
void
calculateRadius
(
float
resHigh
,
float
resLow
,
float
perc
);
float
radius
()
const
;
// access data in compound for this atom
// convenience routine
...
...
@@ -158,16 +215,10 @@ class Atom
void
swap
(
Atom
&
b
)
{
std
::
swap
(
mImpl_
,
b
.
mImpl_
);
std
::
swap
(
mAtomID
,
b
.
mAtomID
);
std
::
swap
(
mCompID
,
b
.
mCompID
);
std
::
swap
(
mAsymID
,
b
.
mAsymID
);
std
::
swap
(
mSeqID
,
b
.
mSeqID
);
std
::
swap
(
mAltID
,
b
.
mAltID
);
std
::
swap
(
mAuthSeqID
,
b
.
mAuthSeqID
);
std
::
swap
(
mImpl
,
b
.
mImpl
);
}
int
compare
(
const
Atom
&
b
)
const
;
int
compare
(
const
Atom
&
b
)
const
{
return
mImpl
->
compare
(
*
b
.
mImpl
);
}
bool
operator
<
(
const
Atom
&
rhs
)
const
{
...
...
@@ -178,21 +229,30 @@ class Atom
private
:
friend
class
Structure
;
void
setID
(
int
id
);
AtomImpl
*
impl
();
const
AtomImpl
*
impl
()
const
;
std
::
shared_ptr
<
AtomImpl
>
mImpl
;
};
template
<>
inline
std
::
string
Atom
::
get_property
<
std
::
string
>
(
const
std
::
string_view
name
)
const
{
return
mImpl
->
get_property
(
name
);
}
struct
AtomImpl
*
mImpl_
;
template
<>
inline
int
Atom
::
get_property
<
int
>
(
const
std
::
string_view
name
)
const
{
auto
v
=
mImpl
->
get_property
(
name
);
return
v
.
empty
()
?
0
:
stoi
(
v
);
}
// cached values
std
::
string
mAtomID
;
std
::
string
mCompID
;
std
::
string
mAsymID
;
int
mSeqID
;
std
::
string
mAltID
;
std
::
string
mAuthSeqID
;
};
template
<>
inline
float
Atom
::
get_property
<
float
>
(
const
std
::
string_view
name
)
const
{
return
stof
(
mImpl
->
get_property
(
name
));
}
inline
void
swap
(
mmcif
::
Atom
&
a
,
mmcif
::
Atom
&
b
)
{
...
...
@@ -216,19 +276,16 @@ typedef std::vector<Atom> AtomView;
class
Residue
{
public
:
// constructors should be private, but that's not possible for now (needed in emplace)
// constructor for waters
// constructor
Residue
(
const
Structure
&
structure
,
const
std
::
string
&
compoundID
,
const
std
::
string
&
asymID
,
const
std
::
string
&
authSeqID
);
// constructor for a residue without a sequence number
Residue
(
const
Structure
&
structure
,
const
std
::
string
&
compoundID
,
const
std
::
string
&
asymID
);
// constructor for a residue with a sequence number
Residue
(
const
Structure
&
structure
,
const
std
::
string
&
compoundID
,
const
std
::
string
&
asymID
,
int
seqID
,
const
std
::
string
&
authSeqID
);
const
std
::
string
&
asymID
,
int
seqID
=
0
,
const
std
::
string
&
authSeqID
=
{})
:
mStructure
(
&
structure
)
,
mCompoundID
(
compoundID
)
,
mAsymID
(
asymID
)
,
mSeqID
(
seqID
)
,
mAuthSeqID
(
authSeqID
)
{
}
Residue
(
const
Residue
&
rhs
)
=
delete
;
Residue
&
operator
=
(
const
Residue
&
rhs
)
=
delete
;
...
...
@@ -552,6 +609,12 @@ class Structure
/// \brief Rotate the coordinates of all atoms in the structure by \a q
void
rotate
(
Quaternion
t
);
/// \brief Translate and rotate the coordinates of all atoms in the structure by \a t and \a q
void
translateAndRotate
(
Point
t
,
Quaternion
q
);
/// \brief Translate, rotate and translate again the coordinates of all atoms in the structure by \a t1 , \a q and \a t2
void
translateRotateAndTranslate
(
Point
t1
,
Quaternion
q
,
Point
t2
);
const
std
::
vector
<
Residue
>
&
getNonPolymers
()
const
{
return
mNonPolymers
;
}
const
std
::
vector
<
Residue
>
&
getBranchResidues
()
const
{
return
mBranchResidues
;
}
...
...
src/BondMap.cpp
View file @
4732004b
...
...
@@ -180,7 +180,10 @@ bool CompoundBondMap::bonded(const std::string &compoundID, const std::string &a
auto
compound
=
mmcif
::
CompoundFactory
::
instance
().
create
(
compoundID
);
if
(
not
compound
)
std
::
cerr
<<
"Missing compound bond info for "
<<
compoundID
<<
std
::
endl
;
{
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Missing compound bond info for "
<<
compoundID
<<
std
::
endl
;
}
else
{
for
(
auto
&
atom
:
compound
->
bonds
())
...
...
@@ -308,7 +311,7 @@ BondMap::BondMap(const Structure &p)
{
if
(
c
==
"HOH"
or
c
==
"H2O"
or
c
==
"WAT"
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"skipping water in bond map calculation"
<<
std
::
endl
;
continue
;
}
...
...
src/Cif++.cpp
View file @
4732004b
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
*
* Copyright (c) 2020 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
...
...
@@ -30,10 +30,10 @@
#include <numeric>
#include <regex>
#include <set>
#include <shared_mutex>
#include <stack>
#include <tuple>
#include <unordered_map>
#include <shared_mutex>
#include <filesystem>
...
...
@@ -570,36 +570,6 @@ void Datablock::write(std::ostream &os, const std::vector<std::string> &order)
cat
.
write
(
os
);
}
// // mmcif support, sort of. First write the 'entry' Category
// // and if it exists, _AND_ we have a Validator, write out the
// // auditConform record.
//
// for (auto& cat: mCategories)
// {
// if (cat.name() == "entry")
// {
// cat.write(os);
//
// if (mValidator != nullptr)
// {
// Category auditConform(*this, "audit_conform", nullptr);
// auditConform.emplace({
// { "dict_name", mValidator->dictName() },
// { "dict_version", mValidator->dictVersion() }
// });
// auditConform.write(os);
// }
//
// break;
// }
// }
//
// for (auto& cat: mCategories)
// {
// if (cat.name() != "entry" and cat.name() != "audit_conform")
// cat.write(os);
// }
}
bool
operator
==
(
const
cif
::
Datablock
&
dbA
,
const
cif
::
Datablock
&
dbB
)
...
...
@@ -636,15 +606,15 @@ bool operator==(const cif::Datablock &dbA, const cif::Datablock &dbB)
{
std
::
string
nA
=
*
catA_i
;
ba
::
to_lower
(
nA
);
std
::
string
nB
=
*
catB_i
;
ba
::
to_lower
(
nB
);
int
d
=
nA
.
compare
(
nB
);
if
(
d
>
0
)
{
auto
cat
=
dbB
.
get
(
*
catB_i
);
if
(
cat
==
nullptr
)
missingA
.
push_back
(
*
catB_i
);
...
...
@@ -653,7 +623,7 @@ bool operator==(const cif::Datablock &dbA, const cif::Datablock &dbB)
else
if
(
d
<
0
)
{
auto
cat
=
dbA
.
get
(
*
catA_i
);
if
(
cat
==
nullptr
)
missingB
.
push_back
(
*
catA_i
);
...
...
@@ -662,25 +632,25 @@ bool operator==(const cif::Datablock &dbA, const cif::Datablock &dbB)
else
++
catA_i
,
++
catB_i
;
}
while
(
catA_i
!=
catA
.
end
())
missingB
.
push_back
(
*
catA_i
++
);
while
(
catB_i
!=
catB
.
end
())
missingA
.
push_back
(
*
catB_i
++
);
if
(
not
(
missingA
.
empty
()
and
missingB
.
empty
()))
if
(
not
(
missingA
.
empty
()
and
missingB
.
empty
()))
{
if
(
cif
::
VERBOSE
>
1
)
{
std
::
cerr
<<
"compare of datablocks failed"
<<
std
::
endl
;
if
(
not
missingA
.
empty
())
std
::
cerr
<<
"Categories missing in A: "
<<
ba
::
join
(
missingA
,
", "
)
<<
std
::
endl
<<
std
::
endl
;
<<
std
::
endl
;
if
(
not
missingB
.
empty
())
std
::
cerr
<<
"Categories missing in B: "
<<
ba
::
join
(
missingB
,
", "
)
<<
std
::
endl
<<
std
::
endl
;
<<
std
::
endl
;
result
=
false
;
}
...
...
@@ -706,7 +676,7 @@ bool operator==(const cif::Datablock &dbA, const cif::Datablock &dbB)
++
catA_i
;
else
{
if
(
not
(
*
dbA
.
get
(
*
catA_i
)
==
*
dbB
.
get
(
*
catB_i
)))
if
(
not
(
*
dbA
.
get
(
*
catA_i
)
==
*
dbB
.
get
(
*
catB_i
)))
{
if
(
cif
::
VERBOSE
>
1
)
{
...
...
@@ -724,10 +694,10 @@ bool operator==(const cif::Datablock &dbA, const cif::Datablock &dbB)
return
result
;
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Datablock
&
data
)
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Datablock
&
data
)
{
// whoohoo... this sucks!
const_cast
<
Datablock
&>
(
data
).
write
(
os
);
const_cast
<
Datablock
&>
(
data
).
write
(
os
);
return
os
;
}
...
...
@@ -1162,7 +1132,7 @@ void CatIndex::reconstruct()
insert
(
r
.
mData
);
// maybe reconstruction can be done quicker by using the following commented code.
// however, I've not had the time to think of a way to s
td::s
et the red/black flag correctly in that case.
// however, I've not had the time to think of a way to set the red/black flag correctly in that case.
// std::vector<ItemRow*> rows;
// transform(mCat.begin(), mCat.end(), backInserter(rows),
...
...
@@ -1254,82 +1224,15 @@ size_t CatIndex::size() const
return
result
;
}
//bool CatIndex::isValid() const
//{
// bool result = true;
//
// if (mRoot != nullptr)
// {
// uint32_t minBlack = numeric_limits<uint32_t>::max();
// uint32_t maxBlack = 0;
//
// assert(not mRoot->mRed);
//
// result = isValid(mRoot, false, 0, minBlack, maxBlack);
// assert(minBlack == maxBlack);
// }
//
// return result;
//}
//
//bool CatIndex::validate(entry* h, bool isParentRed, uint32_t blackDepth, uint32_t& minBlack, uint32_t& maxBlack) const
//{
// bool result = true;
//
// if (h->mRed)
// assert(not isParentRed);
// else
// ++blackDepth;
//
// if (isParentRed)
// assert(not h->mRed);
//
// if (h->mLeft != nullptr and h->mRight != nullptr)
// {
// if (isRed(h->mLeft))
// assert(not isRed(h->mRight));
// if (isRed(h->mRight))
// assert(not isRed(h->mLeft));
// }
//
// if (h->mLeft != nullptr)
// {
// assert(mComp(h->mLeft->mRow, h->mRow) < 0);
// validate(h->mLeft, h->mRed, blackDepth, minBlack, maxBlack);
// }
// else
// {
// if (minBlack > blackDepth)
// minBlack = blackDepth;
// if (maxBlack < blackDepth)
// maxBlack = blackDepth;
// }
//
// if (h->mRight != nullptr)
// {
// assert(mComp(h->mRight->mRow, h->mRow) > 0);
// validate(h->mRight, h->mRight, blackDepth, minBlack, maxBlack);
// }
// else
// {
// if (minBlack > blackDepth)
// minBlack = blackDepth;
// if (maxBlack < blackDepth)
// maxBlack = blackDepth;
// }
//}
// --------------------------------------------------------------------
RowSet
::
RowSet
(
Category
&
cat
)
:
mCat
(
&
cat
)
// , mCond(nullptr)
{
}
RowSet
::
RowSet
(
Category
&
cat
,
Condition
&&
cond
)
:
mCat
(
&
cat
)
// , mCond(new Condition(std::forward<Condition>(cond)))
{
cond
.
prepare
(
cat
);
...
...
@@ -1343,21 +1246,17 @@ RowSet::RowSet(Category &cat, Condition &&cond)
RowSet
::
RowSet
(
const
RowSet
&
rhs
)
:
mCat
(
rhs
.
mCat
)
,
mItems
(
rhs
.
mItems
)
// , mCond(nullptr)
{
}
RowSet
::
RowSet
(
RowSet
&&
rhs
)
:
mCat
(
rhs
.
mCat
)
,
mItems
(
std
::
move
(
rhs
.
mItems
))
// , mCond(rhs.mCond)
{
// rhs.mCond = nullptr;
}
RowSet
::~
RowSet
()
{
// delete mCond;
}
RowSet
&
RowSet
::
operator
=
(
const
RowSet
&
rhs
)
...
...
@@ -1469,7 +1368,7 @@ void Category::updateLinks()
auto
childCat
=
mDb
.
get
(
link
->
mChildCategory
);
if
(
childCat
==
nullptr
)
continue
;
mChildLinks
.
push_back
({
childCat
,
link
});
mChildLinks
.
push_back
({
childCat
,
link
});
}
for
(
auto
link
:
mValidator
->
getLinksForChild
(
mName
))
...
...
@@ -1477,7 +1376,7 @@ void Category::updateLinks()
auto
parentCat
=
mDb
.
get
(
link
->
mParentCategory
);
if
(
parentCat
==
nullptr
)
continue
;
mParentLinks
.
push_back
({
parentCat
,
link
});
mParentLinks
.
push_back
({
parentCat
,
link
});
}
}
}
...
...
@@ -1497,7 +1396,7 @@ size_t Category::getColumnIndex(std::string_view name) const
break
;
}
if
(
VERBOSE
and
result
==
mColumns
.
size
()
and
mCatValidator
!=
nullptr
)
// validate the name, if it is known at all (since it was not found)
if
(
VERBOSE
>
0
and
result
==
mColumns
.
size
()
and
mCatValidator
!=
nullptr
)
// validate the name, if it is known at all (since it was not found)
{
auto
iv
=
mCatValidator
->
getValidatorForItem
(
name
);
if
(
iv
==
nullptr
)
...
...
@@ -1543,21 +1442,6 @@ size_t Category::addColumn(std::string_view name)
return
result
;
}
// RowSet Category::find(Condition&& cond)
// {
// RowSet result(*this);
// cond.prepare(*this);
// for (auto r: *this)
// {
// if (cond(*this, r))
// result.push_back(r);
// }
// return result;
// }
void
Category
::
reorderByIndex
()
{
if
(
mIndex
!=
nullptr
)
...
...
@@ -1601,11 +1485,13 @@ std::string Category::getUniqueID(std::function<std::string(int)> generator)
if
(
mCatValidator
!=
nullptr
and
mCatValidator
->
mKeys
.
size
()
==
1
)
key
=
mCatValidator
->
mKeys
.
front
();
size_t
nr
=
size
();
// calling size() often is a waste of resources
if
(
mLastUniqueNr
==
0
)
mLastUniqueNr
=
size
();
for
(;;)
{
std
::
string
result
=
generator
(
int
(
n
r
++
));
std
::
string
result
=
generator
(
static_cast
<
int
>
(
mLastUniqueN
r
++
));
if
(
exists
(
Key
(
key
)
==
result
))
continue
;
...
...
@@ -1665,21 +1551,6 @@ Row Category::operator[](Condition &&cond)
return
result
;
}
// RowSet Category::find(Condition&& cond)
// {
// // return RowSet(*this, std::forward<Condition>(cond));
// RowSet result(*this);
// cond.prepare(*this);
// for (auto r: *this)
// {
// if (cond(*this, r))
// result.insert(result.end(), r);
// }
// return result;
// }
bool
Category
::
exists
(
Condition
&&
cond
)
const
{
bool
result
=
false
;
...
...
@@ -2340,7 +2211,7 @@ void Category::validateLinks() const
if
(
not
hasParent
(
r
,
*
parentCat
,
*
link
))
++
missing
;
if
(
missing
)
if
(
missing
and
VERBOSE
>=
0
)
{
std
::
cerr
<<
"Links for "
<<
link
->
mLinkGroupLabel
<<
" are incomplete"
<<
std
::
endl
<<
" There are "
<<
missing
<<
" items in "
<<
mName
<<
" that don't have matching parent items in "
<<
parentCat
->
mName
<<
std
::
endl
;
...
...
@@ -2408,26 +2279,26 @@ std::set<size_t> Category::keyFieldsByIndex() const
bool
operator
==
(
const
Category
&
a
,
const
Category
&
b
)
{
using
namespace
std
::
placeholders
;
using
namespace
std
::
placeholders
;
bool
result
=
true
;
// set<std::string> tagsA(a.fields()), tagsB(b.fields());
//
// if (tagsA != tagsB)
// std::cout << "Unequal number of fields" << std::endl;
// set<std::string> tagsA(a.fields()), tagsB(b.fields());
//
// if (tagsA != tagsB)
// std::cout << "Unequal number of fields" << std::endl;
auto
&
validator
=
a
.
getValidator
();
auto
&
validator
=
a
.
getValidator
();
auto
catValidator
=
validator
.
getValidatorForCategory
(
a
.
name
());
if
(
catValidator
==
nullptr
)
throw
std
::
runtime_error
(
"missing cat validator"
);
typedef
std
::
function
<
int
(
const
char
*
,
const
char
*
)
>
compType
;
std
::
vector
<
std
::
tuple
<
std
::
string
,
compType
>>
tags
;
typedef
std
::
function
<
int
(
const
char
*
,
const
char
*
)
>
compType
;
std
::
vector
<
std
::
tuple
<
std
::
string
,
compType
>>
tags
;
auto
keys
=
catValidator
->
mKeys
;
std
::
vector
<
size_t
>
keyIx
;
for
(
auto
&
tag
:
a
.
fields
())
for
(
auto
&
tag
:
a
.
fields
())
{
auto
iv
=
catValidator
->
getValidatorForItem
(
tag
);
if
(
iv
==
nullptr
)
...
...
@@ -2436,24 +2307,25 @@ bool operator==(const Category &a, const Category &b)
if
(
tv
==
nullptr
)
throw
std
::
runtime_error
(
"missing type validator"
);
tags
.
push_back
(
std
::
make_tuple
(
tag
,
std
::
bind
(
&
cif
::
ValidateType
::
compare
,
tv
,
std
::
placeholders
::
_1
,
std
::
placeholders
::
_2
)));
auto
pred
=
[
tag
](
const
std
::
string
&
s
)
->
bool
{
return
cif
::
iequals
(
tag
,
s
)
==
0
;
};
auto
pred
=
[
tag
](
const
std
::
string
&
s
)
->
bool
{
return
cif
::
iequals
(
tag
,
s
)
==
0
;
};
if
(
find_if
(
keys
.
begin
(),
keys
.
end
(),
pred
)
==
keys
.
end
())
keyIx
.
push_back
(
tags
.
size
()
-
1
);
}
// a.reorderByIndex();
// b.reorderByIndex();
auto
rowEqual
=
[
&
](
const
cif
::
Row
&
ra
,
const
cif
::
Row
&
rb
)
auto
rowEqual
=
[
&
](
const
cif
::
Row
&
ra
,
const
cif
::
Row
&
rb
)
{
int
d
=
0
;
for
(
auto
kix
:
keyIx
)
for
(
auto
kix
:
keyIx
)
{
std
::
string
tag
;
compType
compare
;
std
::
tie
(
tag
,
compare
)
=
tags
[
kix
];
d
=
compare
(
ra
[
tag
].
c_str
(),
rb
[
tag
].
c_str
());
...
...
@@ -2465,7 +2337,7 @@ bool operator==(const Category &a, const Category &b)
break
;
}
}
return
d
==
0
;
};
...
...
@@ -2483,9 +2355,9 @@ bool operator==(const Category &a, const Category &b)
else
return
false
;
}
cif
::
Row
ra
=
*
ai
,
rb
=
*
bi
;
if
(
not
rowEqual
(
ra
,
rb
))
{
if
(
cif
::
VERBOSE
>
1
)
...
...
@@ -2493,21 +2365,25 @@ bool operator==(const Category &a, const Category &b)
else
return
false
;
}
std
::
vector
<
std
::
string
>
missingA
,
missingB
,
different
;
for
(
auto
&
tt
:
tags
)
for
(
auto
&
tt
:
tags
)
{
std
::
string
tag
;
compType
compare
;
std
::
tie
(
tag
,
compare
)
=
tt
;
// make it an option to compare unapplicable to empty or something
const
char
*
ta
=
ra
[
tag
].
c_str
();
if
(
strcmp
(
ta
,
"."
)
==
0
or
strcmp
(
ta
,
"?"
)
==
0
)
ta
=
""
;
const
char
*
tb
=
rb
[
tag
].
c_str
();
if
(
strcmp
(
tb
,
"."
)
==
0
or
strcmp
(
tb
,
"?"
)
==
0
)
tb
=
""
;
const
char
*
ta
=
ra
[
tag
].
c_str
();
if
(
strcmp
(
ta
,
"."
)
==
0
or
strcmp
(
ta
,
"?"
)
==
0
)
ta
=
""
;
const
char
*
tb
=
rb
[
tag
].
c_str
();
if
(
strcmp
(
tb
,
"."
)
==
0
or
strcmp
(
tb
,
"?"
)
==
0
)
tb
=
""
;
if
(
compare
(
ta
,
tb
)
!=
0
)
{
if
(
cif
::
VERBOSE
>
1
)
...
...
@@ -2519,7 +2395,7 @@ bool operator==(const Category &a, const Category &b)
return
false
;
}
}
++
ai
;
++
bi
;
}
...
...
@@ -2527,18 +2403,6 @@ bool operator==(const Category &a, const Category &b)
return
result
;
}
// auto Category::iterator::operator++() -> iterator&
// {
// mCurrent = Row(mCurrent.data()->mNext);
// return *this;
// }
// auto Category::const_iterator::operator++() -> const_iterator&
// {
// mCurrent = Row(mCurrent.data()->mNext);
// return *this;
// }
namespace
detail
{
...
...
@@ -2900,7 +2764,7 @@ void Category::update_value(RowSet &&rows, const std::string &tag, const std::st
}
// cannot update this...
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Cannot update child "
<<
childCat
->
mName
<<
"."
<<
childTag
<<
" with value "
<<
value
<<
std
::
endl
;
}
...
...
@@ -3009,21 +2873,22 @@ void Row::assign(const Item &value, bool skipUpdateLinked)
assign
(
value
.
name
(),
value
.
value
(),
skipUpdateLinked
);
}
void
Row
::
assign
(
std
::
string_view
name
,
const
std
::
string
&
value
,
bool
skipUpdateLinked
)
void
Row
::
assign
(
std
::
string_view
name
,
const
std
::
string
&
value
,
bool
skipUpdateLinked
,
bool
validate
)
{
try
{
auto
cat
=
mData
->
mCategory
;
assign
(
cat
->
addColumn
(
name
),
value
,
skipUpdateLinked
);
assign
(
cat
->
addColumn
(
name
),
value
,
skipUpdateLinked
,
validate
);
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
"Could not assign value '"
<<
value
<<
"' to column _"
<<
mData
->
mCategory
->
name
()
<<
'.'
<<
name
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Could not assign value '"
<<
value
<<
"' to column _"
<<
mData
->
mCategory
->
name
()
<<
'.'
<<
name
<<
std
::
endl
;
throw
;
}
}
void
Row
::
assign
(
size_t
column
,
const
std
::
string
&
value
,
bool
skipUpdateLinked
)
void
Row
::
assign
(
size_t
column
,
const
std
::
string
&
value
,
bool
skipUpdateLinked
,
bool
validate
)
{
if
(
mData
==
nullptr
)
throw
std
::
logic_error
(
"invalid Row, no data assigning value '"
+
value
+
"' to column with index "
+
std
::
to_string
(
column
));
...
...
@@ -3049,7 +2914,7 @@ void Row::assign(size_t column, const std::string &value, bool skipUpdateLinked)
std
::
string
oldStrValue
=
oldValue
?
oldValue
:
""
;
// check the value
if
(
col
.
mValidator
)
if
(
col
.
mValidator
and
validate
)
(
*
col
.
mValidator
)(
value
);
// If the field is part of the Key for this Category, remove it from the index
...
...
@@ -3181,7 +3046,7 @@ void Row::assign(size_t column, const std::string &value, bool skipUpdateLinked)
auto
rows_n
=
childCat
->
find
(
std
::
move
(
cond_n
));
if
(
not
rows_n
.
empty
())
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Will not rename in child category since there are already rows that link to the parent"
<<
std
::
endl
;
continue
;
...
...
@@ -3387,7 +3252,7 @@ void Row::swap(size_t cix, ItemRow *a, ItemRow *b)
}
else
{
if
(
VERBOSE
)
if
(
VERBOSE
>
0
)
std
::
cerr
<<
"In "
<<
childCat
->
mName
<<
" changing "
<<
linkChildColName
<<
": "
<<
r
[
linkChildColName
].
as
<
std
::
string
>
()
<<
" => "
<<
(
i
?
i
->
mText
:
""
)
<<
std
::
endl
;
r
[
linkChildColName
]
=
i
?
i
->
mText
:
""
;
}
...
...
@@ -3496,7 +3361,8 @@ File::File(const std::filesystem::path &path, bool validate)
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
"Error while loading file "
<<
path
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Error while loading file "
<<
path
<<
std
::
endl
;
throw
;
}
}
...
...
@@ -3564,7 +3430,8 @@ void File::load(const std::filesystem::path &p)
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
"Error loading file "
<<
path
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Error loading file "
<<
path
<<
std
::
endl
;
throw
;
}
}
...
...
@@ -3660,7 +3527,7 @@ bool File::isValid()
{
if
(
mValidator
==
nullptr
)
{
if
(
VERBOSE
)
if
(
VERBOSE
>
0
)
std
::
cerr
<<
"No dictionary loaded explicitly, loading default"
<<
std
::
endl
;
loadDictionary
();
...
...
src/Cif2PDB.cpp
View file @
4732004b
...
...
@@ -753,7 +753,8 @@ class Ff : public FBase
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
"Failed to write '"
<<
s
<<
"' as a double, this indicates an error in the code for writing PDB files"
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Failed to write '"
<<
s
<<
"' as a double, this indicates an error in the code for writing PDB files"
<<
std
::
endl
;
os
<<
s
;
}
}
...
...
@@ -2329,7 +2330,8 @@ void WriteRemark200(std::ostream& pdbFile, Datablock& db)
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
ex
.
what
()
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
ex
.
what
()
<<
std
::
endl
;
}
}
...
...
@@ -2390,7 +2392,8 @@ void WriteRemark280(std::ostream& pdbFile, Datablock& db)
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
ex
.
what
()
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
ex
.
what
()
<<
std
::
endl
;
}
}
...
...
src/CifParser.cpp
View file @
4732004b
...
...
@@ -288,7 +288,7 @@ SacParser::CIFToken SacParser::getNextToken()
mState
=
eStateTextField
+
1
;
else
if
(
ch
==
kEOF
)
error
(
"unterminated textfield"
);
else
if
(
not
isAnyPrint
(
ch
))
else
if
(
not
isAnyPrint
(
ch
)
and
cif
::
VERBOSE
>=
0
)
// error("invalid character in text field '" + string({ static_cast<char>(ch) }) + "' (" + to_string((int)ch) + ")");
std
::
cerr
<<
"invalid character in text field '"
<<
std
::
string
({
static_cast
<
char
>
(
ch
)})
<<
"' ("
<<
ch
<<
") line: "
<<
mLineNr
<<
std
::
endl
;
break
;
...
...
@@ -1220,7 +1220,7 @@ void DictParser::linkItems()
{
for
(
auto
&
iv
:
cv
.
mItemValidators
)
{
if
(
iv
.
mType
==
nullptr
)
if
(
iv
.
mType
==
nullptr
and
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Missing item_type for "
<<
iv
.
mTag
<<
std
::
endl
;
}
}
...
...
@@ -1255,7 +1255,8 @@ void DictParser::loadDictionary()
}
catch
(
const
std
::
exception
&
)
{
std
::
cerr
<<
"Error parsing dictionary"
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Error parsing dictionary"
<<
std
::
endl
;
throw
;
}
...
...
src/CifUtils.cpp
View file @
4732004b
...
...
@@ -1237,7 +1237,7 @@ std::filesystem::path gDataDir;
void
addDataDirectory
(
std
::
filesystem
::
path
dataDir
)
{
if
(
VERBOSE
and
not
fs
::
exists
(
dataDir
))
if
(
VERBOSE
>
0
and
not
fs
::
exists
(
dataDir
))
std
::
cerr
<<
"The specified data directory "
<<
dataDir
<<
" does not exist"
<<
std
::
endl
;
gDataDir
=
dataDir
;
}
...
...
src/CifValidator.cpp
View file @
4732004b
...
...
@@ -354,7 +354,7 @@ void Validator::reportError(const std::string &msg, bool fatal) const
{
if
(
mStrict
or
fatal
)
throw
ValidationError
(
msg
);
else
if
(
VERBOSE
)
else
if
(
VERBOSE
>
0
)
std
::
cerr
<<
msg
<<
std
::
endl
;
}
...
...
src/Compound.cpp
View file @
4732004b
...
...
@@ -193,7 +193,7 @@ Compound::Compound(cif::Datablock &db, const std::string &id, const std::string
bond
.
type
=
BondType
::
delo
;
else
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Unimplemented chem_comp_bond.type "
<<
btype
<<
" in "
<<
id
<<
std
::
endl
;
bond
.
type
=
BondType
::
sing
;
}
...
...
@@ -520,7 +520,7 @@ Compound *CCDCompoundFactoryImpl::create(const std::string &id)
}
}
if
(
result
==
nullptr
and
cif
::
VERBOSE
)
if
(
result
==
nullptr
and
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Could not locate compound "
<<
id
<<
" in the CCD components file"
<<
std
::
endl
;
return
result
;
...
...
@@ -645,13 +645,13 @@ CompoundFactory::CompoundFactory()
auto
ccd
=
cif
::
loadResource
(
"components.cif"
);
if
(
ccd
)
mImpl
.
reset
(
new
CCDCompoundFactoryImpl
(
mImpl
));
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"CCD components.cif file was not found"
<<
std
::
endl
;
const
char
*
clibd_mon
=
getenv
(
"CLIBD_MON"
);
if
(
clibd_mon
!=
nullptr
and
fs
::
is_directory
(
clibd_mon
))
mImpl
.
reset
(
new
CCP4CompoundFactoryImpl
(
clibd_mon
));
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"CCP4 monomers library not found, CLIBD_MON is not defined"
<<
std
::
endl
;
}
...
...
@@ -695,7 +695,8 @@ void CompoundFactory::setDefaultDictionary(const std::filesystem::path &inDictFi
}
catch
(
const
std
::
exception
&
)
{
std
::
cerr
<<
"Error loading dictionary "
<<
inDictFile
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Error loading dictionary "
<<
inDictFile
<<
std
::
endl
;
throw
;
}
}
...
...
@@ -715,7 +716,8 @@ void CompoundFactory::pushDictionary(const std::filesystem::path &inDictFile)
}
catch
(
const
std
::
exception
&
)
{
std
::
cerr
<<
"Error loading dictionary "
<<
inDictFile
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Error loading dictionary "
<<
inDictFile
<<
std
::
endl
;
throw
;
}
}
...
...
src/PDB2Cif.cpp
View file @
4732004b
...
...
@@ -268,7 +268,8 @@ int PDBRecord::vI(int columnFirst, int columnLast)
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
"Trying to parse '"
<<
std
::
string
(
mValue
+
columnFirst
-
7
,
mValue
+
columnLast
-
7
)
<<
'\''
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Trying to parse '"
<<
std
::
string
(
mValue
+
columnFirst
-
7
,
mValue
+
columnLast
-
7
)
<<
'\''
<<
std
::
endl
;
throw
;
}
...
...
@@ -337,7 +338,7 @@ std::tuple<std::string, std::string> SpecificationListParser::GetNextSpecificati
}
else
if
(
not
isspace
(
ch
))
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"skipping invalid character in SOURCE ID: "
<<
ch
<<
std
::
endl
;
}
break
;
...
...
@@ -354,7 +355,7 @@ std::tuple<std::string, std::string> SpecificationListParser::GetNextSpecificati
case
eColon
:
if
(
ch
==
';'
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Empty value for SOURCE: "
<<
id
<<
std
::
endl
;
state
=
eStart
;
}
...
...
@@ -418,7 +419,7 @@ std::tuple<std::string, std::string> SpecificationListParser::GetNextSpecificati
case
eError
:
if
(
ch
==
';'
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Skipping invalid header line: '"
<<
std
::
string
(
start
,
mP
)
<<
std
::
endl
;
state
=
eStart
;
}
...
...
@@ -832,7 +833,7 @@ class PDBFileParser
if
(
not
mChainSeq2AsymSeq
.
count
(
key
))
{
ec
=
error
::
make_error_code
(
error
::
pdbErrors
::
residueNotFound
);
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Residue "
<<
chainID
<<
resSeq
<<
iCode
<<
" could not be mapped"
<<
std
::
endl
;
}
else
...
...
@@ -929,7 +930,7 @@ class PDBFileParser
}
catch
(
const
std
::
exception
&
ex
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
ex
.
what
()
<<
std
::
endl
;
ec
=
error
::
make_error_code
(
error
::
pdbErrors
::
invalidDate
);
}
...
...
@@ -1160,7 +1161,8 @@ void PDBFileParser::PreParseInput(std::istream &is)
if
(
is
.
eof
())
break
;
std
::
cerr
<<
"Line number "
<<
lineNr
<<
" is empty!"
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Line number "
<<
lineNr
<<
" is empty!"
<<
std
::
endl
;
getline
(
is
,
lookahead
);
++
lineNr
;
...
...
@@ -1278,7 +1280,8 @@ void PDBFileParser::PreParseInput(std::istream &is)
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
"Dropping FORMUL line ("
<<
(
lineNr
-
1
)
<<
") with invalid component number '"
<<
value
.
substr
(
1
,
3
)
<<
'\''
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Dropping FORMUL line ("
<<
(
lineNr
-
1
)
<<
") with invalid component number '"
<<
value
.
substr
(
1
,
3
)
<<
'\''
<<
std
::
endl
;
continue
;
// throw_with_nested(std::runtime_error("Invalid component number '" + value.substr(1, 3) + '\''));
}
...
...
@@ -1305,7 +1308,8 @@ void PDBFileParser::PreParseInput(std::istream &is)
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
"Error parsing FORMUL at line "
<<
lineNr
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Error parsing FORMUL at line "
<<
lineNr
<<
std
::
endl
;
throw
;
}
}
...
...
@@ -1412,7 +1416,8 @@ void PDBFileParser::PreParseInput(std::istream &is)
if
(
not
dropped
.
empty
())
{
std
::
cerr
<<
"Dropped unsupported records: "
<<
ba
::
join
(
dropped
,
", "
)
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Dropped unsupported records: "
<<
ba
::
join
(
dropped
,
", "
)
<<
std
::
endl
;
}
if
(
mData
==
nullptr
)
...
...
@@ -1440,7 +1445,7 @@ void PDBFileParser::Match(const std::string &expected, bool throwIfMissing)
{
if
(
throwIfMissing
)
throw
std
::
runtime_error
(
"Expected record "
+
expected
+
" but found "
+
mRec
->
mName
);
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Expected record "
+
expected
+
" but found "
+
mRec
->
mName
<<
std
::
endl
;
}
}
...
...
@@ -1575,7 +1580,8 @@ void PDBFileParser::ParseTitle()
if
(
not
iequals
(
key
,
"MOL_ID"
)
and
mCompounds
.
empty
())
{
std
::
cerr
<<
"Ignoring invalid COMPND record"
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Ignoring invalid COMPND record"
<<
std
::
endl
;
break
;
}
...
...
@@ -1625,7 +1631,7 @@ void PDBFileParser::ParseTitle()
// auto colon = s.find(": ");
// if (colon == std::string::npos)
// {
// if (cif::VERBOSE)
// if (cif::VERBOSE
> 0
)
// std::cerr << "invalid source field, missing colon (" << s << ')' << std::endl;
// continue;
// }
...
...
@@ -1713,7 +1719,7 @@ void PDBFileParser::ParseTitle()
// NUMMDL
if
(
mRec
->
is
(
"NUMMDL"
))
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"skipping unimplemented NUMMDL record"
<<
std
::
endl
;
GetNextRecord
();
}
...
...
@@ -1816,7 +1822,7 @@ void PDBFileParser::ParseTitle()
// SPRSDE
if
(
mRec
->
is
(
"SPRSDE"
))
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"skipping unimplemented SPRSDE record"
<<
std
::
endl
;
GetNextRecord
();
}
...
...
@@ -2265,7 +2271,7 @@ void PDBFileParser::ParseRemarks()
state
=
eMCP
;
else
if
(
subtopic
==
"CHIRAL CENTERS"
)
state
=
eChC
;
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
>
0
)
throw
std
::
runtime_error
(
"Unknown subtopic in REMARK 500: "
+
subtopic
);
headerSeen
=
false
;
...
...
@@ -2342,7 +2348,7 @@ void PDBFileParser::ParseRemarks()
}
catch
(
const
std
::
exception
&
ex
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Dropping REMARK 500 at line "
<<
mRec
->
mLineNr
<<
" due to invalid symmetry operation"
<<
std
::
endl
;
continue
;
}
...
...
@@ -2675,7 +2681,7 @@ void PDBFileParser::ParseRemarks()
case
sStart
:
if
(
s
==
"SITE"
)
state
=
sID
;
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
>
0
)
throw
std
::
runtime_error
(
"Invalid REMARK 800 record, expected SITE"
);
break
;
...
...
@@ -2685,7 +2691,7 @@ void PDBFileParser::ParseRemarks()
id
=
m
[
1
].
str
();
state
=
sEvidence
;
}
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
>
0
)
throw
std
::
runtime_error
(
"Invalid REMARK 800 record, expected SITE_IDENTIFIER"
);
break
;
...
...
@@ -2695,7 +2701,7 @@ void PDBFileParser::ParseRemarks()
evidence
=
m
[
1
].
str
();
state
=
sDesc
;
}
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
>
0
)
throw
std
::
runtime_error
(
"Invalid REMARK 800 record, expected SITE_IDENTIFIER"
);
break
;
...
...
@@ -2906,7 +2912,7 @@ void PDBFileParser::ParseRemark200()
collectionDate
=
pdb2cifDate
(
rm200
(
"DATE OF DATA COLLECTION"
,
diffrnNr
),
ec
);
if
(
ec
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
ec
.
message
()
<<
" for pdbx_collection_date"
<<
std
::
endl
;
// The date field can become truncated when multiple values are available
...
...
@@ -3025,7 +3031,7 @@ void PDBFileParser::ParseRemark200()
else
if
(
inRM200
({
"HIGHEST RESOLUTION SHELL, RANGE LOW (A)"
,
"COMPLETENESS FOR SHELL (%)"
,
"R MERGE FOR SHELL (I)"
,
"R SYM FOR SHELL (I)"
,
"<I/SIGMA(I)> FOR SHELL"
,
"DATA REDUNDANCY IN SHELL"
}))
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Not writing reflns_shell record since d_res_high is missing"
<<
std
::
endl
;
}
}
...
...
@@ -3595,7 +3601,7 @@ void PDBFileParser::ConstructEntities()
{
auto
&
r
=
chain
.
mResiduesSeen
[
lastResidueIndex
+
1
];
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
{
std
::
cerr
<<
"Detected residues that cannot be aligned to SEQRES"
<<
std
::
endl
<<
"First residue is "
<<
chain
.
mDbref
.
chainID
<<
':'
<<
r
.
mSeqNum
<<
r
.
mIcode
<<
std
::
endl
;
...
...
@@ -4005,7 +4011,7 @@ void PDBFileParser::ConstructEntities()
tie
(
asym
,
labelSeq
,
std
::
ignore
)
=
MapResidue
(
seqadv
.
chainID
,
seqadv
.
seqNum
,
seqadv
.
iCode
,
ec
);
if
(
ec
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"dropping unmatched SEQADV record"
<<
std
::
endl
;
continue
;
}
...
...
@@ -4319,7 +4325,7 @@ void PDBFileParser::ConstructEntities()
tie
(
asymID
,
seq
,
std
::
ignore
)
=
MapResidue
(
chainID
,
seqNum
,
iCode
,
ec
);
if
(
ec
)
// no need to write a modres if it could not be found
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"dropping unmapped MODRES record"
<<
std
::
endl
;
continue
;
}
...
...
@@ -4415,7 +4421,7 @@ void PDBFileParser::ConstructEntities()
tie
(
asymID
,
seqNr
,
isPolymer
)
=
MapResidue
(
unobs
.
chain
,
unobs
.
seq
,
unobs
.
iCode
,
ec
);
if
(
ec
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"error mapping unobserved residue"
<<
std
::
endl
;
continue
;
}
...
...
@@ -4676,7 +4682,7 @@ void PDBFileParser::ParseSecondaryStructure()
if
(
ec
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Could not map residue for HELIX "
<<
vI
(
8
,
10
)
<<
std
::
endl
;
}
else
...
...
@@ -4791,7 +4797,7 @@ void PDBFileParser::ParseSecondaryStructure()
if
(
ec
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Dropping SHEET record "
<<
vI
(
8
,
10
)
<<
std
::
endl
;
}
else
...
...
@@ -4827,7 +4833,7 @@ void PDBFileParser::ParseSecondaryStructure()
if
(
ec
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"skipping unmatched pdbx_struct_sheet_hbond record"
<<
std
::
endl
;
}
else
...
...
@@ -4927,7 +4933,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
if
(
ec
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Dropping SSBOND "
<<
vI
(
8
,
10
)
<<
std
::
endl
;
continue
;
}
...
...
@@ -4948,7 +4954,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
}
catch
(
const
std
::
exception
&
ex
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Dropping SSBOND "
<<
vI
(
8
,
10
)
<<
" due to invalid symmetry operation"
<<
std
::
endl
;
continue
;
}
...
...
@@ -4993,7 +4999,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
if
(
mRec
->
is
(
"LINK "
)
or
mRec
->
is
(
"LINKR "
))
{
if
(
cif
::
VERBOSE
and
mRec
->
is
(
"LINKR "
))
if
(
cif
::
VERBOSE
>
0
and
mRec
->
is
(
"LINKR "
))
std
::
cerr
<<
"Accepting non-standard LINKR record, but ignoring extra information"
<<
std
::
endl
;
// 1 - 6 Record name "LINK "
...
...
@@ -5046,7 +5052,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
if
(
ec
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Dropping LINK record at line "
<<
mRec
->
mLineNr
<<
std
::
endl
;
continue
;
}
...
...
@@ -5062,7 +5068,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
}
catch
(
const
std
::
invalid_argument
&
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Distance value '"
<<
distance
<<
"' is not a valid float in LINK record"
<<
std
::
endl
;
swap
(
ccp4LinkID
,
distance
);
// assume this is a ccp4_link_id... oh really?
}
...
...
@@ -5078,7 +5084,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
}
catch
(
const
std
::
exception
&
ex
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Dropping LINK record at line "
<<
mRec
->
mLineNr
<<
" due to invalid symmetry operation"
<<
std
::
endl
;
continue
;
}
...
...
@@ -5149,7 +5155,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
if
(
ec
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Dropping CISPEP record at line "
<<
mRec
->
mLineNr
<<
std
::
endl
;
continue
;
}
...
...
@@ -5215,7 +5221,7 @@ void PDBFileParser::ParseMiscellaneousFeatures()
if
(
ec
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"skipping struct_site_gen record"
<<
std
::
endl
;
}
else
...
...
@@ -5518,7 +5524,7 @@ void PDBFileParser::ParseCoordinate(int modelNr)
{
if
(
groupPDB
==
"HETATM"
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Changing atom from HETATM to ATOM at line "
<<
mRec
->
mLineNr
<<
std
::
endl
;
groupPDB
=
"ATOM"
;
}
...
...
@@ -5527,7 +5533,7 @@ void PDBFileParser::ParseCoordinate(int modelNr)
{
if
(
groupPDB
==
"ATOM"
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Changing atom from ATOM to HETATM at line "
<<
mRec
->
mLineNr
<<
std
::
endl
;
groupPDB
=
"HETATM"
;
}
...
...
@@ -5698,7 +5704,8 @@ void PDBFileParser::Parse(std::istream &is, cif::File &result)
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
"Error parsing REMARK 3"
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Error parsing REMARK 3"
<<
std
::
endl
;
throw
;
}
//
...
...
@@ -5750,12 +5757,12 @@ void PDBFileParser::Parse(std::istream &is, cif::File &result)
if
((
symm1
.
empty
()
or
symm1
==
"1_555"
)
and
(
symm2
.
empty
()
or
symm2
==
"1_555"
))
distance
=
static_cast
<
float
>
(
mmcif
::
Distance
(
mmcif
::
Point
{
x1
,
y1
,
z1
},
mmcif
::
Point
{
x2
,
y2
,
z2
}));
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Cannot calculate distance for link since one of the atoms is in another dimension"
<<
std
::
endl
;
}
catch
(
std
::
exception
&
ex
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Error finding atom for LINK distance calculation: "
<<
ex
.
what
()
<<
std
::
endl
;
}
...
...
@@ -5764,10 +5771,13 @@ void PDBFileParser::Parse(std::istream &is, cif::File &result)
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
"Error parsing PDB"
;
if
(
mRec
!=
nullptr
)
std
::
cerr
<<
" at line "
<<
mRec
->
mLineNr
;
std
::
cerr
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
{
std
::
cerr
<<
"Error parsing PDB"
;
if
(
mRec
!=
nullptr
)
std
::
cerr
<<
" at line "
<<
mRec
->
mLineNr
;
std
::
cerr
<<
std
::
endl
;
}
throw
;
}
}
...
...
@@ -5947,7 +5957,7 @@ int PDBFileParser::PDBChain::AlignResToSeqRes()
switch
(
tb
(
x
,
y
))
{
case
-
1
:
// if (cif::VERBOSE)
// if (cif::VERBOSE
> 0
)
// std::cerr << "A residue found in the ATOM records "
// << "(" << ry[y].mMonID << " @ " << mDbref.chainID << ":" << ry[y].mSeqNum
// << ((ry[y].mIcode == ' ' or ry[y].mIcode == 0) ? "" : std::string{ ry[y].mIcode }) << ")"
...
...
@@ -6034,7 +6044,6 @@ void ReadPDBFile(std::istream &pdbFile, cif::File &cifFile)
p
.
Parse
(
pdbFile
,
cifFile
);
if
(
not
cifFile
.
isValid
())
// throw std::runtime_error("Resulting mmCIF file is invalid");
if
(
not
cifFile
.
isValid
()
and
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Resulting mmCIF file is not valid!"
<<
std
::
endl
;
}
src/PDB2CifRemark3.cpp
View file @
4732004b
...
...
@@ -1320,7 +1320,7 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
if
(
line
!=
"REFINEMENT."
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Unexpected data in REMARK 3"
<<
std
::
endl
;
return
false
;
}
...
...
@@ -1332,7 +1332,7 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
if
(
not
std
::
regex_match
(
line
,
m
,
rxp
))
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Expected valid PROGRAM line in REMARK 3"
<<
std
::
endl
;
return
false
;
}
...
...
@@ -1367,8 +1367,9 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cerr
<<
"Error parsing REMARK 3 with "
<<
parser
->
program
()
<<
std
::
endl
<<
e
.
what
()
<<
'\n'
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Error parsing REMARK 3 with "
<<
parser
->
program
()
<<
std
::
endl
<<
e
.
what
()
<<
'\n'
;
score
=
0
;
}
...
...
@@ -1411,7 +1412,7 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
tryParser
(
new
TNT_Remark3Parser
(
program
,
expMethod
,
r
,
db
));
else
if
(
ba
::
starts_with
(
program
,
"X-PLOR"
))
tryParser
(
new
XPLOR_Remark3Parser
(
program
,
expMethod
,
r
,
db
));
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Skipping unknown program ("
<<
program
<<
") in REMARK 3"
<<
std
::
endl
;
}
...
...
@@ -1420,7 +1421,8 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
bool
guessProgram
=
scores
.
empty
()
or
scores
.
front
().
score
<
0.9
f
;;
if
(
guessProgram
)
{
std
::
cerr
<<
"Unknown or untrusted program in REMARK 3, trying all parsers to see if there is a match"
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Unknown or untrusted program in REMARK 3, trying all parsers to see if there is a match"
<<
std
::
endl
;
tryParser
(
new
BUSTER_TNT_Remark3Parser
(
"BUSTER-TNT"
,
expMethod
,
r
,
db
));
tryParser
(
new
CNS_Remark3Parser
(
"CNS"
,
expMethod
,
r
,
db
));
...
...
@@ -1444,7 +1446,7 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
auto
&
best
=
scores
.
front
();
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Choosing "
<<
best
.
parser
->
program
()
<<
" version '"
<<
best
.
parser
->
version
()
<<
"' as refinement program. Score = "
<<
best
.
score
<<
std
::
endl
;
auto
&
software
=
db
[
"software"
];
...
...
src/Secondary.cpp
View file @
4732004b
...
...
@@ -1240,7 +1240,7 @@ void DSSPImpl::calculateSecondaryStructure()
auto
r1
=
findRes
(
asym1
,
seq1
);
if
(
r1
==
mResidues
.
end
())
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Missing (incomplete?) residue for SS bond when trying to find "
<<
asym1
<<
'/'
<<
seq1
<<
std
::
endl
;
continue
;
// throw std::runtime_error("Invalid file, missing residue for SS bond");
...
...
@@ -1249,7 +1249,7 @@ void DSSPImpl::calculateSecondaryStructure()
auto
r2
=
findRes
(
asym2
,
seq2
);
if
(
r2
==
mResidues
.
end
())
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Missing (incomplete?) residue for SS bond when trying to find "
<<
asym2
<<
'/'
<<
seq2
<<
std
::
endl
;
continue
;
// throw std::runtime_error("Invalid file, missing residue for SS bond");
...
...
@@ -1300,7 +1300,7 @@ void DSSPImpl::calculateSecondaryStructure()
{
if
(
a
==
b
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"In the SS bonds list, the residue "
<<
a
->
mM
<<
" is bonded to itself"
<<
std
::
endl
;
continue
;
}
...
...
@@ -1483,7 +1483,7 @@ SecondaryStructureType DSSP::operator()(const std::string &inAsymID, int inSeqID
{
return
r
.
mM
.
asymID
()
==
inAsymID
and
r
.
mM
.
seqID
()
==
inSeqID
;
});
if
(
i
!=
mImpl
->
mResidues
.
end
())
result
=
i
->
mSecondaryStructure
;
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Could not find secondary structure for "
<<
inAsymID
<<
':'
<<
inSeqID
<<
std
::
endl
;
return
result
;
}
...
...
@@ -1501,7 +1501,7 @@ double DSSP::accessibility(const std::string &inAsymID, int inSeqID) const
{
return
r
.
mM
.
asymID
()
==
inAsymID
and
r
.
mM
.
seqID
()
==
inSeqID
;
});
if
(
i
!=
mImpl
->
mResidues
.
end
())
result
=
i
->
mSecondaryStructure
;
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Could not find secondary structure for "
<<
inAsymID
<<
':'
<<
inSeqID
<<
std
::
endl
;
return
result
;
}
...
...
@@ -1526,7 +1526,7 @@ bool DSSP::isAlphaHelixEndBeforeStart(const std::string &inAsymID, int inSeqID)
if
(
i
!=
mImpl
->
mResidues
.
end
()
and
i
+
1
!=
mImpl
->
mResidues
.
end
())
result
=
i
->
GetHelixFlag
(
HelixType
::
rh_alpha
)
==
Helix
::
End
and
(
i
+
1
)
->
GetHelixFlag
(
HelixType
::
rh_alpha
)
==
Helix
::
Start
;
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Could not find secondary structure for "
<<
inAsymID
<<
':'
<<
inSeqID
<<
std
::
endl
;
return
result
;
...
...
src/Structure.cpp
View file @
4732004b
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
*
* Copyright (c) 2020 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
...
...
@@ -108,8 +108,8 @@ void FileImpl::load_data(const char *data, size_t length)
// And validate, otherwise lots of functionality won't work
// if (mData.getValidator() == nullptr)
mData
.
loadDictionary
(
"mmcif_pdbx_v50"
);
if
(
not
mData
.
isValid
())
std
::
cerr
<<
"Invalid mmCIF file"
<<
(
cif
::
VERBOSE
?
"."
:
" use --verbose option to see errors"
)
<<
std
::
endl
;
if
(
not
mData
.
isValid
()
and
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Invalid mmCIF file"
<<
(
cif
::
VERBOSE
>
0
?
"."
:
" use --verbose option to see errors"
)
<<
std
::
endl
;
}
void
FileImpl
::
load
(
const
std
::
filesystem
::
path
&
path
)
...
...
@@ -140,14 +140,14 @@ void FileImpl::load(const std::filesystem::path &path)
{
try
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"unrecognized file extension, trying cif"
<<
std
::
endl
;
mData
.
load
(
in
);
}
catch
(
const
cif
::
CifParserError
&
e
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Not cif, trying plain old PDB"
<<
std
::
endl
;
// pffft...
...
...
@@ -169,7 +169,8 @@ void FileImpl::load(const std::filesystem::path &path)
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
"Error trying to load file "
<<
path
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Error trying to load file "
<<
path
<<
std
::
endl
;
throw
;
}
...
...
@@ -179,8 +180,8 @@ void FileImpl::load(const std::filesystem::path &path)
// And validate, otherwise lots of functionality won't work
// if (mData.getValidator() == nullptr)
mData
.
loadDictionary
(
"mmcif_pdbx_v50"
);
if
(
not
mData
.
isValid
())
std
::
cerr
<<
"Invalid mmCIF file"
<<
(
cif
::
VERBOSE
?
"."
:
" use --verbose option to see errors"
)
<<
std
::
endl
;
if
(
not
mData
.
isValid
()
and
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Invalid mmCIF file"
<<
(
cif
::
VERBOSE
>
0
?
"."
:
" use --verbose option to see errors"
)
<<
std
::
endl
;
}
void
FileImpl
::
save
(
const
std
::
filesystem
::
path
&
path
)
...
...
@@ -202,443 +203,237 @@ void FileImpl::save(const std::filesystem::path &path)
// --------------------------------------------------------------------
// Atom
struct
AtomImpl
Atom
::
AtomImpl
::
AtomImpl
(
cif
::
Datablock
&
db
,
const
std
::
string
&
id
,
cif
::
Row
row
)
:
mDb
(
db
)
,
mID
(
id
)
,
mRefcount
(
1
)
,
mRow
(
row
)
,
mCompound
(
nullptr
)
{
AtomImpl
(
const
AtomImpl
&
i
)
:
mDb
(
i
.
mDb
)
,
mID
(
i
.
mID
)
,
mType
(
i
.
mType
)
,
mLocation
(
i
.
mLocation
)
,
mRefcount
(
1
)
,
mRow
(
i
.
mRow
)
,
mCachedRefs
(
i
.
mCachedRefs
)
,
mCompound
(
i
.
mCompound
)
,
mRadius
(
i
.
mRadius
)
,
mSymmetryCopy
(
i
.
mSymmetryCopy
)
,
mClone
(
true
)
{
}
AtomImpl
(
cif
::
Datablock
&
db
,
const
std
::
string
&
id
)
:
mDb
(
db
)
,
mID
(
id
)
,
mRefcount
(
1
)
,
mCompound
(
nullptr
)
{
auto
&
cat
=
db
[
"atom_site"
];
mRow
=
cat
[
cif
::
Key
(
"id"
)
==
mID
];
}
AtomImpl
(
cif
::
Datablock
&
db
,
cif
::
Row
&
row
)
:
mDb
(
db
)
,
mID
(
row
[
"id"
].
as
<
std
::
string
>
())
,
mRefcount
(
1
)
,
mRow
(
row
)
,
mCompound
(
nullptr
)
{
}
prefetch
();
}
AtomImpl
(
cif
::
Datablock
&
db
,
const
std
::
string
&
id
,
cif
::
Row
row
)
:
mDb
(
db
)
,
mID
(
id
)
,
mRefcount
(
1
)
,
mRow
(
row
)
,
mCompound
(
nullptr
)
{
}
// constructor for a symmetry copy of an atom
Atom
::
AtomImpl
::
AtomImpl
(
const
AtomImpl
&
impl
,
const
Point
&
loc
,
const
std
::
string
&
sym_op
)
:
mDb
(
impl
.
mDb
)
,
mID
(
impl
.
mID
)
,
mType
(
impl
.
mType
)
AtomImpl
(
const
AtomImpl
&
impl
,
const
Point
&
loc
,
const
std
::
string
&
sym_op
)
:
mDb
(
impl
.
mDb
)
,
mID
(
impl
.
mID
)
,
mType
(
impl
.
mType
)
,
mLocation
(
loc
)
,
mRefcount
(
1
)
,
mRow
(
impl
.
mRow
)
,
mCachedRefs
(
impl
.
mCachedRefs
)
,
mCompound
(
impl
.
mCompound
)
,
mRadius
(
impl
.
mRadius
)
,
mSymmetryCopy
(
true
)
,
mSymmetryOperator
(
sym_op
)
{
}
,
mAtomID
(
impl
.
mAtomID
)
,
mCompID
(
impl
.
mCompID
)
,
mAsymID
(
impl
.
mAsymID
)
,
mSeqID
(
impl
.
mSeqID
)
,
mAltID
(
impl
.
mAltID
)
,
mAuthSeqID
(
impl
.
mAuthSeqID
)
void
prefetch
(
std
::
string
&
atomID
,
std
::
string
&
compID
,
std
::
string
&
asymID
,
int
&
seqID
,
std
::
string
&
altID
,
std
::
string
&
authSeqID
)
{
// Prefetch some data
std
::
string
symbol
;
cif
::
tie
(
symbol
,
atomID
,
compID
,
asymID
,
seqID
,
altID
,
authSeqID
)
=
mRow
.
get
(
"type_symbol"
,
"label_atom_id"
,
"label_comp_id"
,
"label_asym_id"
,
"label_seq_id"
,
"label_alt_id"
,
"auth_seq_id"
);
,
mLocation
(
loc
)
,
mRefcount
(
1
)
,
mRow
(
impl
.
mRow
)
,
mCachedRefs
(
impl
.
mCachedRefs
)
,
mCompound
(
impl
.
mCompound
)
,
mSymmetryCopy
(
true
)
,
mSymmetryOperator
(
sym_op
)
{
}
if
(
symbol
!=
"X"
)
mType
=
AtomTypeTraits
(
symbol
).
type
();
void
Atom
::
AtomImpl
::
prefetch
()
{
// Prefetch some data
std
::
string
symbol
;
cif
::
tie
(
symbol
,
mAtomID
,
mCompID
,
mAsymID
,
mSeqID
,
mAltID
,
mAuthSeqID
)
=
mRow
.
get
(
"type_symbol"
,
"label_atom_id"
,
"label_comp_id"
,
"label_asym_id"
,
"label_seq_id"
,
"label_alt_id"
,
"auth_seq_id"
);
float
x
,
y
,
z
;
cif
::
tie
(
x
,
y
,
z
)
=
mRow
.
get
(
"Cartn_x"
,
"Cartn_y"
,
"Cartn_z"
);
if
(
symbol
!=
"X"
)
mType
=
AtomTypeTraits
(
symbol
).
type
(
);
mLocation
=
Point
(
x
,
y
,
z
);
}
void
reference
()
{
++
mRefcount
;
}
float
x
,
y
,
z
;
cif
::
tie
(
x
,
y
,
z
)
=
mRow
.
get
(
"Cartn_x"
,
"Cartn_y"
,
"Cartn_z"
);
void
release
()
{
if
(
--
mRefcount
<=
0
)
delete
this
;
}
mLocation
=
Point
(
x
,
y
,
z
);
}
bool
getAnisoU
(
float
anisou
[
6
])
const
{
bool
result
=
false
;
int
Atom
::
AtomImpl
::
compare
(
const
AtomImpl
&
b
)
const
{
int
d
=
mAsymID
.
compare
(
b
.
mAsymID
);
if
(
d
==
0
)
d
=
mSeqID
-
b
.
mSeqID
;
if
(
d
==
0
)
d
=
mAtomID
.
compare
(
b
.
mAtomID
);
if
(
d
==
0
)
d
=
mAuthSeqID
.
compare
(
b
.
mAuthSeqID
);
auto
cat
=
mDb
.
get
(
"atom_site_anisotrop"
);
if
(
cat
)
{
try
{
auto
r
=
cat
->
find1
(
cif
::
Key
(
"id"
)
==
mID
);
cif
::
tie
(
anisou
[
0
],
anisou
[
1
],
anisou
[
2
],
anisou
[
3
],
anisou
[
4
],
anisou
[
5
])
=
r
.
get
(
"U[1][1]"
,
"U[1][2]"
,
"U[1][3]"
,
"U[2][2]"
,
"U[2][3]"
,
"U[3][3]"
);
result
=
true
;
}
catch
(
const
std
::
exception
&
e
)
{
}
}
return
d
;
}
return
result
;
}
bool
Atom
::
AtomImpl
::
getAnisoU
(
float
anisou
[
6
])
const
{
bool
result
=
false
;
void
moveTo
(
const
Point
&
p
)
auto
cat
=
mDb
.
get
(
"atom_site_anisotrop"
);
if
(
cat
)
{
assert
(
not
mSymmetryCopy
);
if
(
mSymmetryCopy
)
throw
std
::
runtime_error
(
"Moving symmetry copy"
);
if
(
not
mClone
)
try
{
property
(
"Cartn_x"
,
std
::
to_string
(
p
.
getX
()));
property
(
"Cartn_y"
,
std
::
to_string
(
p
.
getY
()));
property
(
"Cartn_z"
,
std
::
to_string
(
p
.
getZ
()));
auto
r
=
cat
->
find1
(
cif
::
Key
(
"id"
)
==
mID
);
cif
::
tie
(
anisou
[
0
],
anisou
[
1
],
anisou
[
2
],
anisou
[
3
],
anisou
[
4
],
anisou
[
5
])
=
r
.
get
(
"U[1][1]"
,
"U[1][2]"
,
"U[1][3]"
,
"U[2][2]"
,
"U[2][3]"
,
"U[3][3]"
);
result
=
true
;
}
// boost::format kPosFmt("%.3f");
//
// mRow["Cartn_x"] = (kPosFmt % p.getX()).str();
// mRow["Cartn_y"] = (kPosFmt % p.getY()).str();
// mRow["Cartn_z"] = (kPosFmt % p.getZ()).str();
mLocation
=
p
;
}
const
Compound
&
comp
()
const
{
if
(
mCompound
==
nullptr
)
catch
(
const
std
::
exception
&
e
)
{
std
::
string
compID
;
cif
::
tie
(
compID
)
=
mRow
.
get
(
"label_comp_id"
);
mCompound
=
CompoundFactory
::
instance
().
create
(
compID
);
if
(
cif
::
VERBOSE
and
mCompound
==
nullptr
)
std
::
cerr
<<
"Compound not found: '"
<<
compID
<<
'\''
<<
std
::
endl
;
}
if
(
mCompound
==
nullptr
)
throw
std
::
runtime_error
(
"no compound"
);
return
*
mCompound
;
}
float
radius
()
const
{
return
mRadius
;
}
const
std
::
string
property
(
const
std
::
string_view
name
)
const
{
for
(
auto
&&
[
tag
,
ref
]
:
mCachedRefs
)
{
if
(
tag
==
name
)
return
ref
.
as
<
std
::
string
>
();
}
return
result
;
}
mCachedRefs
.
emplace_back
(
name
,
mRow
[
name
]);
return
std
::
get
<
1
>
(
mCachedRefs
.
back
()).
as
<
std
::
string
>
();
}
void
Atom
::
AtomImpl
::
moveTo
(
const
Point
&
p
)
{
assert
(
not
mSymmetryCopy
);
if
(
mSymmetryCopy
)
throw
std
::
runtime_error
(
"Moving symmetry copy"
);
void
property
(
const
std
::
string_view
name
,
const
std
::
string
&
valu
e
)
if
(
not
mClon
e
)
{
for
(
auto
&&
[
tag
,
ref
]
:
mCachedRefs
)
{
if
(
tag
!=
name
)
continue
;
ref
=
value
;
return
;
}
mCachedRefs
.
emplace_back
(
name
,
mRow
[
name
]);
std
::
get
<
1
>
(
mCachedRefs
.
back
())
=
value
;
mRow
.
assign
(
"Cartn_x"
,
std
::
to_string
(
p
.
getX
()),
true
,
false
);
mRow
.
assign
(
"Cartn_y"
,
std
::
to_string
(
p
.
getY
()),
true
,
false
);
mRow
.
assign
(
"Cartn_z"
,
std
::
to_string
(
p
.
getZ
()),
true
,
false
);
}
const
cif
::
Datablock
&
mDb
;
std
::
string
mID
;
AtomType
mType
;
Point
mLocation
;
int
mRefcount
;
cif
::
Row
mRow
;
mutable
std
::
vector
<
std
::
tuple
<
std
::
string
,
cif
::
detail
::
ItemReference
>>
mCachedRefs
;
mutable
const
Compound
*
mCompound
=
nullptr
;
float
mRadius
=
std
::
nanf
(
"4"
);
bool
mSymmetryCopy
=
false
;
bool
mClone
=
false
;
std
::
string
mSymmetryOperator
=
"1_555"
;
// clipper::RTop_orth mRTop;
// Point mD;
// int32_t mRTix;
};
//Atom::Atom(const File& f, const std::string& id)
// : mImpl(new AtomImpl(f, id))
//{
//}
//
Atom
::
Atom
()
:
Atom
(
nullptr
)
{
mLocation
=
p
;
}
Atom
::
Atom
(
AtomImpl
*
impl
)
:
mImpl_
(
impl
)
const
Compound
&
Atom
::
AtomImpl
::
comp
()
const
{
if
(
mImpl_
)
mImpl_
->
prefetch
(
mAtomID
,
mCompID
,
mAsymID
,
mSeqID
,
mAltID
,
mAuthSeqID
);
}
if
(
mCompound
==
nullptr
)
{
std
::
string
compID
;
cif
::
tie
(
compID
)
=
mRow
.
get
(
"label_comp_id"
);
Atom
::
Atom
(
cif
::
Datablock
&
db
,
cif
::
Row
&
row
)
:
Atom
(
new
AtomImpl
(
db
,
row
))
{
}
mCompound
=
CompoundFactory
::
instance
().
create
(
compID
);
Atom
::
Atom
(
const
Atom
&
rhs
,
const
Point
&
loc
,
const
std
::
string
&
sym_op
)
:
Atom
(
new
AtomImpl
(
*
rhs
.
mImpl_
,
loc
,
sym_op
))
{
}
Atom
::
Atom
(
const
Atom
&
rhs
)
:
mImpl_
(
rhs
.
mImpl_
)
,
mAtomID
(
rhs
.
mAtomID
)
,
mCompID
(
rhs
.
mCompID
)
,
mAsymID
(
rhs
.
mAsymID
)
,
mSeqID
(
rhs
.
mSeqID
)
,
mAltID
(
rhs
.
mAltID
)
,
mAuthSeqID
(
rhs
.
mAuthSeqID
)
{
if
(
mImpl_
)
mImpl_
->
reference
();
}
if
(
cif
::
VERBOSE
>
0
and
mCompound
==
nullptr
)
std
::
cerr
<<
"Compound not found: '"
<<
compID
<<
'\''
<<
std
::
endl
;
}
Atom
::~
Atom
()
{
if
(
mImpl_
)
mImpl_
->
release
();
}
if
(
mCompound
==
nullptr
)
throw
std
::
runtime_error
(
"no compound"
);
AtomImpl
*
Atom
::
impl
()
{
if
(
mImpl_
==
nullptr
)
throw
std
::
runtime_error
(
"atom is not set"
);
return
mImpl_
;
return
*
mCompound
;
}
const
AtomImpl
*
Atom
::
impl
(
)
const
const
std
::
string
Atom
::
AtomImpl
::
get_property
(
const
std
::
string_view
name
)
const
{
if
(
mImpl_
==
nullptr
)
throw
std
::
runtime_error
(
"atom is not set"
);
return
mImpl_
;
}
for
(
auto
&&
[
tag
,
ref
]
:
mCachedRefs
)
{
if
(
tag
==
name
)
return
ref
.
as
<
std
::
string
>
();
}
Atom
Atom
::
clone
()
const
{
return
Atom
(
mImpl_
?
new
AtomImpl
(
*
mImpl_
)
:
nullptr
);
mCachedRefs
.
emplace_back
(
name
,
mRow
[
name
]);
return
std
::
get
<
1
>
(
mCachedRefs
.
back
()).
as
<
std
::
string
>
();
}
Atom
&
Atom
::
operator
=
(
const
Atom
&
rhs
)
void
Atom
::
AtomImpl
::
set_property
(
const
std
::
string_view
name
,
const
std
::
string
&
value
)
{
if
(
this
!=
&
rh
s
)
for
(
auto
&&
[
tag
,
ref
]
:
mCachedRef
s
)
{
if
(
mImpl_
)
mImpl_
->
release
();
mImpl_
=
rhs
.
mImpl_
;
mAtomID
=
rhs
.
mAtomID
;
mCompID
=
rhs
.
mCompID
;
mAsymID
=
rhs
.
mAsymID
;
mSeqID
=
rhs
.
mSeqID
;
mAltID
=
rhs
.
mAltID
;
mAuthSeqID
=
rhs
.
mAuthSeqID
;
if
(
tag
!=
name
)
continue
;
if
(
mImpl_
)
mImpl_
->
reference
()
;
ref
=
value
;
return
;
}
return
*
this
;
mCachedRefs
.
emplace_back
(
name
,
mRow
[
name
]);
std
::
get
<
1
>
(
mCachedRefs
.
back
())
=
value
;
}
Atom
::
Atom
(
cif
::
Datablock
&
db
,
cif
::
Row
&
row
)
:
Atom
(
std
::
make_shared
<
AtomImpl
>
(
db
,
row
[
"id"
].
as
<
std
::
string
>
(),
row
))
{
}
const
cif
::
Row
Atom
::
getRow
()
const
Atom
::
Atom
(
const
Atom
&
rhs
,
const
Point
&
loc
,
const
std
::
string
&
sym_op
)
:
Atom
(
std
::
make_shared
<
AtomImpl
>
(
*
rhs
.
mImpl
,
loc
,
sym_op
))
{
return
mImpl_
->
mRow
;
}
const
cif
::
Row
Atom
::
getRowAniso
()
const
{
auto
&
db
=
mImpl
_
->
mDb
;
auto
&
db
=
mImpl
->
mDb
;
auto
cat
=
db
.
get
(
"atom_site_anisotrop"
);
if
(
not
cat
)
return
{};
else
return
cat
->
find1
(
cif
::
Key
(
"id"
)
==
mImpl_
->
mID
);
}
template
<>
std
::
string
Atom
::
property
<
std
::
string
>
(
const
std
::
string_view
name
)
const
{
return
impl
()
->
property
(
name
);
}
template
<>
int
Atom
::
property
<
int
>
(
const
std
::
string_view
name
)
const
{
auto
v
=
impl
()
->
property
(
name
);
return
v
.
empty
()
?
0
:
stoi
(
v
);
}
template
<>
float
Atom
::
property
<
float
>
(
const
std
::
string_view
name
)
const
{
return
stof
(
impl
()
->
property
(
name
));
}
void
Atom
::
property
(
const
std
::
string_view
name
,
const
std
::
string
&
value
)
{
impl
()
->
property
(
name
,
value
);
}
const
std
::
string
&
Atom
::
id
()
const
{
return
impl
()
->
mID
;
}
AtomType
Atom
::
type
()
const
{
return
impl
()
->
mType
;
}
int
Atom
::
charge
()
const
{
return
property
<
int
>
(
"pdbx_formal_charge"
);
return
cat
->
find1
(
cif
::
Key
(
"id"
)
==
mImpl
->
mID
);
}
float
Atom
::
uIso
()
const
{
float
result
;
if
(
not
property
<
std
::
string
>
(
"U_iso_or_equiv"
).
empty
())
result
=
property
<
float
>
(
"U_iso_or_equiv"
);
else
if
(
not
property
<
std
::
string
>
(
"B_iso_or_equiv"
).
empty
())
result
=
property
<
float
>
(
"B_iso_or_equiv"
)
/
static_cast
<
float
>
(
8
*
kPI
*
kPI
);
if
(
not
get_
property
<
std
::
string
>
(
"U_iso_or_equiv"
).
empty
())
result
=
get_
property
<
float
>
(
"U_iso_or_equiv"
);
else
if
(
not
get_
property
<
std
::
string
>
(
"B_iso_or_equiv"
).
empty
())
result
=
get_
property
<
float
>
(
"B_iso_or_equiv"
)
/
static_cast
<
float
>
(
8
*
kPI
*
kPI
);
else
throw
std
::
runtime_error
(
"Missing B_iso or U_iso"
);
return
result
;
}
bool
Atom
::
getAnisoU
(
float
anisou
[
6
])
const
{
return
impl
()
->
getAnisoU
(
anisou
);
}
float
Atom
::
occupancy
()
const
std
::
string
Atom
::
labelID
()
const
{
return
property
<
float
>
(
"occupancy"
)
;
return
mImpl
->
mCompID
+
'_'
+
mImpl
->
mAsymID
+
'_'
+
std
::
to_string
(
mImpl
->
mSeqID
)
+
':'
+
mImpl
->
mAtomID
;
}
// const std::string& Atom::labelAtomID() const
// {
// return impl()->mAtomID;
// }
// const std::string& Atom::labelCompID() const
// {
// return impl()->mCompID;
// }
// const std::string& Atom::labelAsymID() const
// {
// return impl()->mAsymID;
// }
std
::
string
Atom
::
labelEntityID
()
const
std
::
string
Atom
::
pdbID
()
const
{
return
property
<
std
::
string
>
(
"label_entity_id"
);
return
get_property
<
std
::
string
>
(
"auth_comp_id"
)
+
'_'
+
get_property
<
std
::
string
>
(
"auth_asym_id"
)
+
'_'
+
get_property
<
std
::
string
>
(
"auth_seq_id"
)
+
get_property
<
std
::
string
>
(
"pdbx_PDB_ins_code"
);
}
std
::
string
Atom
::
authAsymID
()
const
int
Atom
::
charge
()
const
{
return
property
<
std
::
string
>
(
"auth_asym_id
"
);
return
get_property
<
int
>
(
"pdbx_formal_charge
"
);
}
std
::
string
Atom
::
authAtomID
()
const
float
Atom
::
occupancy
()
const
{
return
property
<
std
::
string
>
(
"auth_atom_id
"
);
return
get_property
<
float
>
(
"occupancy
"
);
}
std
::
string
Atom
::
pdbxAuthAlt
ID
()
const
std
::
string
Atom
::
labelEntity
ID
()
const
{
return
property
<
std
::
string
>
(
"pdbx_auth_alt
_id"
);
return
get_property
<
std
::
string
>
(
"label_entity
_id"
);
}
std
::
string
Atom
::
pdbxAuthInsCode
()
const
std
::
string
Atom
::
authAtomID
()
const
{
return
property
<
std
::
string
>
(
"pdbx_PDB_ins_code
"
);
return
get_property
<
std
::
string
>
(
"auth_atom_id
"
);
}
std
::
string
Atom
::
authCompID
()
const
{
return
property
<
std
::
string
>
(
"auth_comp_id"
);
return
get_
property
<
std
::
string
>
(
"auth_comp_id"
);
}
std
::
string
Atom
::
labelID
()
const
{
return
mCompID
+
'_'
+
mAsymID
+
'_'
+
std
::
to_string
(
mSeqID
)
+
':'
+
mAtomID
;
}
std
::
string
Atom
::
pdbID
()
const
std
::
string
Atom
::
authAsymID
()
const
{
return
property
<
std
::
string
>
(
"auth_comp_id"
)
+
'_'
+
property
<
std
::
string
>
(
"auth_asym_id"
)
+
'_'
+
property
<
std
::
string
>
(
"auth_seq_id"
)
+
property
<
std
::
string
>
(
"pdbx_PDB_ins_code"
);
return
get_property
<
std
::
string
>
(
"auth_asym_id"
);
}
Point
Atom
::
location
()
const
std
::
string
Atom
::
pdbxAuthInsCode
()
const
{
return
impl
()
->
mLocation
;
return
get_property
<
std
::
string
>
(
"pdbx_PDB_ins_code"
)
;
}
void
Atom
::
location
(
Point
p
)
std
::
string
Atom
::
pdbxAuthAltID
()
const
{
impl
()
->
moveTo
(
p
);
return
get_property
<
std
::
string
>
(
"pdbx_auth_alt_id"
);
}
void
Atom
::
translate
(
Point
t
)
...
...
@@ -655,89 +450,32 @@ void Atom::rotate(Quaternion q)
location
(
loc
);
}
// Atom Atom::symmetryCopy(const Point& d, const clipper::RTop_orth& rt)
// {
// return Atom(new AtomImpl(*impl(), d, rt));
// }
// bool Atom::isSymmetryCopy() const
// {
// return impl()->mSymmetryCopy;
// }
// std::string Atom::symmetry() const
// {
// return clipper::Symop(impl()->mRTop).format() + "\n" + impl()->mRTop.format();
// }
bool
Atom
::
isSymmetryCopy
()
const
{
return
mImpl_
->
mSymmetryCopy
;
}
std
::
string
Atom
::
symmetry
()
const
{
return
mImpl_
->
mSymmetryOperator
;
}
// const clipper::RTop_orth& Atom::symop() const
// {
// return impl()->mRTop;
// }
const
Compound
&
Atom
::
comp
()
const
void
Atom
::
translateAndRotate
(
Point
t
,
Quaternion
q
)
{
return
impl
()
->
comp
();
auto
loc
=
location
();
loc
+=
t
;
loc
.
rotate
(
q
);
location
(
loc
);
}
bool
Atom
::
isWater
()
const
void
Atom
::
translateRotateAndTranslate
(
Point
t1
,
Quaternion
q
,
Point
t2
)
{
(
void
)
impl
();
return
mCompID
==
"HOH"
or
mCompID
==
"H2O"
or
mCompID
==
"WAT"
;
auto
loc
=
location
();
loc
+=
t1
;
loc
.
rotate
(
q
);
loc
+=
t2
;
location
(
loc
);
}
bool
Atom
::
operator
==
(
const
Atom
&
rhs
)
const
{
return
impl
()
==
rhs
.
impl
()
or
(
&
impl
()
->
mDb
==
&
rhs
.
impl
()
->
mDb
and
impl
()
->
mID
==
rhs
.
impl
()
->
mID
);
}
// clipper::Atom Atom::toClipper() const
// {
// return impl()->toClipper();
// }
// void Atom::calculateRadius(float resHigh, float resLow, float perc)
// {
// AtomShape shape(*this, resHigh, resLow, false);
// impl()->mRadius = shape.radius();
// // verbose
// if (cif::VERBOSE > 1)
// cout << "Calculated radius for " << AtomTypeTraits(impl()->mType).name() << " with charge " << charge() << " is " << impl()->mRadius << std::endl;
// }
float
Atom
::
radius
()
const
{
return
impl
()
->
mRadius
;
}
int
Atom
::
compare
(
const
Atom
&
b
)
const
{
int
d
=
mAsymID
.
compare
(
b
.
mAsymID
);
if
(
d
==
0
)
d
=
mSeqID
-
b
.
mSeqID
;
if
(
d
==
0
)
d
=
mAtomID
.
compare
(
b
.
mAtomID
);
if
(
d
==
0
)
d
=
mAuthSeqID
.
compare
(
b
.
mAuthSeqID
);
return
d
;
return
mImpl
==
rhs
.
mImpl
or
(
&
mImpl
->
mDb
==
&
rhs
.
mImpl
->
mDb
and
mImpl
->
mID
==
rhs
.
mImpl
->
mID
);
}
void
Atom
::
setID
(
int
id
)
{
impl
()
->
mID
=
std
::
to_string
(
id
);
mImpl
->
mID
=
std
::
to_string
(
id
);
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Atom
&
atom
)
...
...
@@ -755,66 +493,6 @@ std::ostream &operator<<(std::ostream &os, const Atom &atom)
// --------------------------------------------------------------------
// residue
// First constructor used to be for waters only, but now accepts sugars as well.
Residue
::
Residue
(
const
Structure
&
structure
,
const
std
::
string
&
compoundID
,
const
std
::
string
&
asymID
,
const
std
::
string
&
authSeqID
)
:
mStructure
(
&
structure
)
,
mCompoundID
(
compoundID
)
,
mAsymID
(
asymID
)
,
mAuthSeqID
(
authSeqID
)
{
// for (auto &a : mStructure->atoms())
// {
// if (a.labelAsymID() != mAsymID or
// a.labelCompID() != mCompoundID)
// continue;
// if (compoundID == "HOH")
// {
// if (not mAuthSeqID.empty() and a.authSeqID() != mAuthSeqID)
// continue;
// }
// else
// {
// if (mSeqID > 0 and a.labelSeqID() != mSeqID)
// continue;
// }
// mAtoms.push_back(a);
// }
// assert(not mAtoms.empty());
}
Residue
::
Residue
(
const
Structure
&
structure
,
const
std
::
string
&
compoundID
,
const
std
::
string
&
asymID
)
:
Residue
(
structure
,
compoundID
,
asymID
,
0
,
{})
{
}
Residue
::
Residue
(
const
Structure
&
structure
,
const
std
::
string
&
compoundID
,
const
std
::
string
&
asymID
,
int
seqID
,
const
std
::
string
&
authSeqID
)
:
mStructure
(
&
structure
)
,
mCompoundID
(
compoundID
)
,
mAsymID
(
asymID
)
,
mSeqID
(
seqID
)
,
mAuthSeqID
(
authSeqID
)
{
assert
(
mCompoundID
!=
"HOH"
);
// for (auto &a : mStructure->atoms())
// {
// if (mSeqID > 0 and a.labelSeqID() != mSeqID)
// continue;
// if (a.labelAsymID() != mAsymID or
// a.labelCompID() != mCompoundID)
// continue;
// mAtoms.push_back(a);
// }
}
Residue
::
Residue
(
Residue
&&
rhs
)
:
mStructure
(
rhs
.
mStructure
)
,
mCompoundID
(
std
::
move
(
rhs
.
mCompoundID
))
...
...
@@ -823,13 +501,13 @@ Residue::Residue(Residue &&rhs)
,
mAuthSeqID
(
rhs
.
mAuthSeqID
)
,
mAtoms
(
std
::
move
(
rhs
.
mAtoms
))
{
//std::cerr << "move constructor residue" << std::endl;
//
std::cerr << "move constructor residue" << std::endl;
rhs
.
mStructure
=
nullptr
;
}
Residue
&
Residue
::
operator
=
(
Residue
&&
rhs
)
{
//std::cerr << "move assignment residue" << std::endl;
//
std::cerr << "move assignment residue" << std::endl;
mStructure
=
rhs
.
mStructure
;
rhs
.
mStructure
=
nullptr
;
mCompoundID
=
std
::
move
(
rhs
.
mCompoundID
);
...
...
@@ -843,7 +521,7 @@ Residue &Residue::operator=(Residue &&rhs)
Residue
::~
Residue
()
{
//std::cerr << "~Residue" << std::endl;
//
std::cerr << "~Residue" << std::endl;
}
std
::
string
Residue
::
entityID
()
const
...
...
@@ -957,7 +635,7 @@ AtomView Residue::unique_atoms() const
firstAlt
=
alt
;
else
if
(
alt
!=
firstAlt
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"skipping alternate atom "
<<
atom
<<
std
::
endl
;
continue
;
}
...
...
@@ -1163,7 +841,7 @@ float Monomer::phi() const
}
catch
(
const
std
::
exception
&
ex
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
ex
.
what
()
<<
std
::
endl
;
}
...
...
@@ -1185,7 +863,7 @@ float Monomer::psi() const
}
catch
(
const
std
::
exception
&
ex
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
ex
.
what
()
<<
std
::
endl
;
}
...
...
@@ -1209,7 +887,7 @@ float Monomer::alpha() const
}
catch
(
const
std
::
exception
&
ex
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
ex
.
what
()
<<
std
::
endl
;
}
...
...
@@ -1237,7 +915,7 @@ float Monomer::kappa() const
}
catch
(
const
std
::
exception
&
ex
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"When trying to calculate kappa for "
<<
asymID
()
<<
':'
<<
seqID
()
<<
": "
<<
ex
.
what
()
<<
std
::
endl
;
}
...
...
@@ -1260,7 +938,7 @@ float Monomer::tco() const
}
catch
(
const
std
::
exception
&
ex
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"When trying to calculate tco for "
<<
asymID
()
<<
':'
<<
seqID
()
<<
": "
<<
ex
.
what
()
<<
std
::
endl
;
}
...
...
@@ -1279,7 +957,7 @@ float Monomer::omega() const
}
catch
(
const
std
::
exception
&
ex
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"When trying to calculate omega for "
<<
asymID
()
<<
':'
<<
seqID
()
<<
": "
<<
ex
.
what
()
<<
std
::
endl
;
}
...
...
@@ -1350,7 +1028,7 @@ float Monomer::chi(size_t nr) const
}
catch
(
const
std
::
exception
&
e
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
e
.
what
()
<<
std
::
endl
;
result
=
0
;
}
...
...
@@ -1516,7 +1194,7 @@ Polymer::Polymer(const Structure &s, const std::string &entityID, const std::str
ix
[
seqID
]
=
index
;
emplace_back
(
*
this
,
index
,
seqID
,
authSeqID
,
compoundID
);
}
else
if
(
cif
::
VERBOSE
)
else
if
(
cif
::
VERBOSE
>
0
)
{
Monomer
m
{
*
this
,
index
,
seqID
,
authSeqID
,
compoundID
};
std
::
cerr
<<
"Dropping alternate residue "
<<
m
<<
std
::
endl
;
...
...
@@ -1598,7 +1276,7 @@ File::~File()
delete
mImpl
;
}
cif
::
Datablock
&
File
::
createDatablock
(
const
std
::
string_view
name
)
cif
::
Datablock
&
File
::
createDatablock
(
const
std
::
string_view
name
)
{
auto
db
=
new
cif
::
Datablock
(
name
);
...
...
@@ -1661,7 +1339,7 @@ Structure::Structure(File &f, size_t modelNr, StructureOpenOptions options)
cif
::
tie
(
model_nr
)
=
atomCat
.
front
().
get
(
"pdbx_PDB_model_num"
);
if
(
model_nr
and
*
model_nr
!=
mModelNr
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"No atoms loaded for model 1, trying model "
<<
*
model_nr
<<
std
::
endl
;
mModelNr
=
*
model_nr
;
loadAtomsForModel
(
options
);
...
...
@@ -1669,7 +1347,10 @@ Structure::Structure(File &f, size_t modelNr, StructureOpenOptions options)
}
if
(
mAtoms
.
empty
())
std
::
cerr
<<
"Warning: no atoms loaded"
<<
std
::
endl
;
{
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Warning: no atoms loaded"
<<
std
::
endl
;
}
else
loadData
();
}
...
...
@@ -1692,7 +1373,7 @@ void Structure::loadAtomsForModel(StructureOpenOptions options)
if
((
options
bitand
StructureOpenOptions
::
SkipHydrogen
)
and
type_symbol
==
"H"
)
continue
;
mAtoms
.
emplace_back
(
new
AtomImpl
(
*
db
,
id
,
a
));
mAtoms
.
emplace_back
(
std
::
make_shared
<
Atom
::
AtomImpl
>
(
*
db
,
id
,
a
));
}
}
...
...
@@ -1736,7 +1417,7 @@ void Structure::loadData()
r
.
get
(
"asym_id"
,
"mon_id"
,
"pdb_seq_num"
);
if
(
monID
==
"HOH"
)
mNonPolymers
.
emplace_back
(
*
this
,
monID
,
asymID
,
pdbSeqNum
);
mNonPolymers
.
emplace_back
(
*
this
,
monID
,
asymID
,
0
,
pdbSeqNum
);
else
if
(
mNonPolymers
.
empty
()
or
mNonPolymers
.
back
().
asymID
()
!=
asymID
)
mNonPolymers
.
emplace_back
(
*
this
,
monID
,
asymID
);
}
...
...
@@ -1749,42 +1430,42 @@ void Structure::loadData()
cif
::
tie
(
asymID
,
monID
,
num
)
=
r
.
get
(
"asym_id"
,
"mon_id"
,
"num"
);
mBranchResidues
.
emplace_back
(
*
this
,
monID
,
asymID
,
num
);
mBranchResidues
.
emplace_back
(
*
this
,
monID
,
asymID
,
0
,
num
);
}
// place atoms in residues
using
key_type
=
std
::
tuple
<
std
::
string
,
std
::
string
,
int
>
;
using
map_type
=
std
::
map
<
key_type
,
Residue
*>
;
using
key_type
=
std
::
tuple
<
std
::
string
,
std
::
string
,
int
>
;
using
map_type
=
std
::
map
<
key_type
,
Residue
*>
;
map_type
resMap
;
for
(
auto
&
poly
:
mPolymers
)
{
for
(
auto
&
res
:
poly
)
resMap
[{
res
.
asymID
(),
res
.
compoundID
(),
res
.
seqID
()
}]
=
&
res
;
resMap
[{
res
.
asymID
(),
res
.
compoundID
(),
res
.
seqID
()
}]
=
&
res
;
}
for
(
auto
&
res
:
mNonPolymers
)
resMap
[{
res
.
asymID
(),
res
.
compoundID
(),
(
res
.
isWater
()
?
std
::
stoi
(
res
.
mAuthSeqID
)
:
res
.
seqID
())
}]
=
&
res
;
resMap
[{
res
.
asymID
(),
res
.
compoundID
(),
(
res
.
isWater
()
?
std
::
stoi
(
res
.
mAuthSeqID
)
:
res
.
seqID
())
}]
=
&
res
;
for
(
auto
&
res
:
mBranchResidues
)
resMap
[{
res
.
asymID
(),
res
.
compoundID
(),
res
.
seqID
()
}]
=
&
res
;
resMap
[{
res
.
asymID
(),
res
.
compoundID
(),
res
.
seqID
()
}]
=
&
res
;
for
(
auto
&
atom
:
mAtoms
)
for
(
auto
&
atom
:
mAtoms
)
{
key_type
k
(
atom
.
labelAsymID
(),
atom
.
labelCompID
(),
atom
.
isWater
()
?
std
::
stoi
(
atom
.
authSeqID
())
:
atom
.
labelSeqID
());
auto
ri
=
resMap
.
find
(
k
);
if
(
ri
==
resMap
.
end
())
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Missing residue for atom "
<<
atom
<<
std
::
endl
;
assert
(
false
);
continue
;
}
ri
->
second
->
addAtom
(
atom
);
}
}
...
...
@@ -1836,7 +1517,7 @@ AtomView Structure::waters() const
for
(
auto
&
a
:
mAtoms
)
{
if
(
a
.
property
<
std
::
string
>
(
"label_entity_id"
)
==
waterEntityID
)
if
(
a
.
get_
property
<
std
::
string
>
(
"label_entity_id"
)
==
waterEntityID
)
result
.
push_back
(
a
);
}
...
...
@@ -1909,7 +1590,7 @@ Atom Structure::getAtomByPositionAndType(Point p, std::string_view type, std::st
if
(
a
.
labelCompID
()
!=
res_type
)
continue
;
if
(
a
.
labelAtomID
()
!=
type
)
continue
;
...
...
@@ -1965,7 +1646,7 @@ const Residue &Structure::getResidue(const std::string &asymID, const std::strin
Residue
&
Structure
::
getResidue
(
const
std
::
string
&
asymID
,
const
std
::
string
&
compID
,
int
seqID
)
{
return
const_cast
<
Residue
&>
(
const_cast
<
Structure
const
&>
(
*
this
).
getResidue
(
asymID
,
compID
,
seqID
));
return
const_cast
<
Residue
&>
(
const_cast
<
Structure
const
&>
(
*
this
).
getResidue
(
asymID
,
compID
,
seqID
));
}
const
Residue
&
Structure
::
getResidue
(
const
std
::
string
&
asymID
)
const
...
...
@@ -1983,7 +1664,7 @@ const Residue &Structure::getResidue(const std::string &asymID) const
Residue
&
Structure
::
getResidue
(
const
std
::
string
&
asymID
)
{
return
const_cast
<
Residue
&>
(
const_cast
<
Structure
const
&>
(
*
this
).
getResidue
(
asymID
));
return
const_cast
<
Residue
&>
(
const_cast
<
Structure
const
&>
(
*
this
).
getResidue
(
asymID
));
}
File
&
Structure
::
getFile
()
const
...
...
@@ -2169,8 +1850,7 @@ std::string Structure::insertCompound(const std::string &compoundID, bool isEnti
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
()},
...
...
@@ -2186,19 +1866,17 @@ std::string Structure::insertCompound(const std::string &compoundID, bool isEnti
{
entity_id
=
pdbxEntityNonpoly
.
find1
<
std
::
string
>
(
"comp_id"
_key
==
compoundID
,
"entity_id"
);
}
catch
(
const
std
::
exception
&
ex
)
catch
(
const
std
::
exception
&
ex
)
{
auto
&
entity
=
db
[
"entity"
];
entity_id
=
entity
.
getUniqueID
(
""
);
entity
.
emplace
({
{
"id"
,
entity_id
},
entity
.
emplace
({{
"id"
,
entity_id
},
{
"type"
,
"non-polymer"
},
{
"pdbx_description"
,
compound
->
name
()},
{
"formula_weight"
,
compound
->
formulaWeight
()}});
pdbxEntityNonpoly
.
emplace
({
{
"entity_id"
,
entity_id
},
pdbxEntityNonpoly
.
emplace
({{
"entity_id"
,
entity_id
},
{
"name"
,
compound
->
name
()},
{
"comp_id"
,
compoundID
}});
}
...
...
@@ -2207,65 +1885,6 @@ std::string Structure::insertCompound(const std::string &compoundID, bool isEnti
return
entity_id
;
}
// // --------------------------------------------------------------------
// Structure::residue_iterator::residue_iterator(const Structure* s, poly_iterator polyIter, size_t polyResIndex, size_t nonPolyIndex)
// : mStructure(*s), mPolyIter(polyIter), mPolyResIndex(polyResIndex), mNonPolyIndex(nonPolyIndex)
// {
// while (mPolyIter != mStructure.mPolymers.end() and mPolyResIndex == mPolyIter->size())
// ++mPolyIter;
// }
// auto Structure::residue_iterator::operator*() -> reference
// {
// if (mPolyIter != mStructure.mPolymers.end())
// return (*mPolyIter)[mPolyResIndex];
// else
// return mStructure.mNonPolymers[mNonPolyIndex];
// }
// auto Structure::residue_iterator::operator->() -> pointer
// {
// if (mPolyIter != mStructure.mPolymers.end())
// return &(*mPolyIter)[mPolyResIndex];
// else
// return &mStructure.mNonPolymers[mNonPolyIndex];
// }
// Structure::residue_iterator& Structure::residue_iterator::operator++()
// {
// if (mPolyIter != mStructure.mPolymers.end())
// {
// ++mPolyResIndex;
// if (mPolyResIndex >= mPolyIter->size())
// {
// ++mPolyIter;
// mPolyResIndex = 0;
// }
// }
// else
// ++mNonPolyIndex;
// return *this;
// }
// Structure::residue_iterator Structure::residue_iterator::operator++(int)
// {
// auto result = *this;
// operator++();
// return result;
// }
// bool Structure::residue_iterator::operator==(const Structure::residue_iterator& rhs) const
// {
// return mPolyIter == rhs.mPolyIter and mPolyResIndex == rhs.mPolyResIndex and mNonPolyIndex == rhs.mNonPolyIndex;
// }
// bool Structure::residue_iterator::operator!=(const Structure::residue_iterator& rhs) const
// {
// return mPolyIter != rhs.mPolyIter or mPolyResIndex != rhs.mPolyResIndex or mNonPolyIndex != rhs.mNonPolyIndex;
// }
// --------------------------------------------------------------------
void
Structure
::
removeAtom
(
Atom
&
a
)
...
...
@@ -2312,7 +1931,7 @@ void Structure::swapAtoms(Atom &a1, Atom &a2)
auto
l2
=
r2
[
"label_atom_id"
];
l1
.
swap
(
l2
);
std
::
swap
(
a1
.
m
AtomID
,
a2
.
mAtomID
);
std
::
swap
(
a1
.
m
Impl
->
mAtomID
,
a2
.
mImpl
->
mAtomID
);
auto
l3
=
r1
[
"auth_atom_id"
];
auto
l4
=
r2
[
"auth_atom_id"
];
...
...
@@ -2402,7 +2021,8 @@ void Structure::changeResidue(Residue &res, const std::string &newCompound,
{
return
a
.
labelAtomID
()
==
a1
;
});
if
(
i
==
atoms
.
end
())
{
std
::
cerr
<<
"Missing atom for atom ID "
<<
a1
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Missing atom for atom ID "
<<
a1
<<
std
::
endl
;
continue
;
}
...
...
@@ -2442,50 +2062,47 @@ std::string Structure::createNonpoly(const std::string &entity_id, const std::ve
auto
&
struct_asym
=
db
[
"struct_asym"
];
std
::
string
asym_id
=
struct_asym
.
getUniqueID
();
struct_asym
.
emplace
({
{
"id"
,
asym_id
},
{
"pdbx_blank_PDB_chainid_flag"
,
"N"
},
{
"pdbx_modified"
,
"N"
},
{
"entity_id"
,
entity_id
},
{
"details"
,
"?"
}
});
struct_asym
.
emplace
({{
"id"
,
asym_id
},
{
"pdbx_blank_PDB_chainid_flag"
,
"N"
},
{
"pdbx_modified"
,
"N"
},
{
"entity_id"
,
entity_id
},
{
"details"
,
"?"
}});
std
::
string
comp_id
=
db
[
"pdbx_entity_nonpoly"
].
find1
<
std
::
string
>
(
"entity_id"
_key
==
entity_id
,
"comp_id"
);
auto
&
atom_site
=
db
[
"atom_site"
];
for
(
auto
&
atom
:
atoms
)
auto
&
res
=
mNonPolymers
.
emplace_back
(
*
this
,
comp_id
,
asym_id
);
for
(
auto
&
atom
:
atoms
)
{
auto
atom_id
=
atom_site
.
getUniqueID
(
""
);
auto
&&
[
row
,
inserted
]
=
atom_site
.
emplace
({
{
"group_PDB"
,
atom
.
property
<
std
::
string
>
(
"group_PDB"
)
},
{
"id"
,
atom_id
},
{
"type_symbol"
,
atom
.
property
<
std
::
string
>
(
"type_symbol"
)
},
{
"label_atom_id"
,
atom
.
property
<
std
::
string
>
(
"label_atom_id"
)
},
{
"label_alt_id"
,
atom
.
property
<
std
::
string
>
(
"label_alt_id"
)
},
{
"label_comp_id"
,
comp_id
},
{
"label_asym_id"
,
asym_id
},
{
"label_entity_id"
,
entity_id
},
{
"label_seq_id"
,
"."
},
{
"pdbx_PDB_ins_code"
,
""
},
{
"Cartn_x"
,
atom
.
property
<
std
::
string
>
(
"Cartn_x"
)
},
{
"Cartn_y"
,
atom
.
property
<
std
::
string
>
(
"Cartn_y"
)
},
{
"Cartn_z"
,
atom
.
property
<
std
::
string
>
(
"Cartn_z"
)
},
{
"occupancy"
,
atom
.
property
<
std
::
string
>
(
"occupancy"
)
},
{
"B_iso_or_equiv"
,
atom
.
property
<
std
::
string
>
(
"B_iso_or_equiv"
)
},
{
"pdbx_formal_charge"
,
atom
.
property
<
std
::
string
>
(
"pdbx_formal_charge"
)
},
{
"auth_seq_id"
,
""
},
{
"auth_comp_id"
,
comp_id
},
{
"auth_asym_id"
,
asym_id
},
{
"auth_atom_id"
,
atom
.
property
<
std
::
string
>
(
"label_atom_id"
)
},
{
"pdbx_PDB_model_num"
,
1
}
});
mAtoms
.
emplace_back
(
new
AtomImpl
(
db
,
atom_id
,
row
));
}
mNonPolymers
.
emplace_back
(
*
this
,
comp_id
,
asym_id
);
auto
&&
[
row
,
inserted
]
=
atom_site
.
emplace
({{
"group_PDB"
,
atom
.
get_property
<
std
::
string
>
(
"group_PDB"
)},
{
"id"
,
atom_id
},
{
"type_symbol"
,
atom
.
get_property
<
std
::
string
>
(
"type_symbol"
)},
{
"label_atom_id"
,
atom
.
get_property
<
std
::
string
>
(
"label_atom_id"
)},
{
"label_alt_id"
,
atom
.
get_property
<
std
::
string
>
(
"label_alt_id"
)},
{
"label_comp_id"
,
comp_id
},
{
"label_asym_id"
,
asym_id
},
{
"label_entity_id"
,
entity_id
},
{
"label_seq_id"
,
"."
},
{
"pdbx_PDB_ins_code"
,
""
},
{
"Cartn_x"
,
atom
.
get_property
<
std
::
string
>
(
"Cartn_x"
)},
{
"Cartn_y"
,
atom
.
get_property
<
std
::
string
>
(
"Cartn_y"
)},
{
"Cartn_z"
,
atom
.
get_property
<
std
::
string
>
(
"Cartn_z"
)},
{
"occupancy"
,
atom
.
get_property
<
std
::
string
>
(
"occupancy"
)},
{
"B_iso_or_equiv"
,
atom
.
get_property
<
std
::
string
>
(
"B_iso_or_equiv"
)},
{
"pdbx_formal_charge"
,
atom
.
get_property
<
std
::
string
>
(
"pdbx_formal_charge"
)},
{
"auth_seq_id"
,
""
},
{
"auth_comp_id"
,
comp_id
},
{
"auth_asym_id"
,
asym_id
},
{
"auth_atom_id"
,
atom
.
get_property
<
std
::
string
>
(
"label_atom_id"
)},
{
"pdbx_PDB_model_num"
,
1
}});
auto
&
newAtom
=
mAtoms
.
emplace_back
(
std
::
make_shared
<
Atom
::
AtomImpl
>
(
db
,
atom_id
,
row
));
res
.
addAtom
(
newAtom
);
}
return
asym_id
;
}
...
...
@@ -2563,7 +2180,7 @@ void Structure::cleanupEmptyCategories()
{
// is this correct?
std
::
set
<
std
::
string
>
asym_ids
;
for
(
const
auto
&
[
asym_id
]
:
db
[
"pdbx_branch_scheme"
].
find
<
std
::
string
>
(
"entity_id"
_key
==
id
,
"asym_id"
))
for
(
const
auto
&
[
asym_id
]
:
db
[
"pdbx_branch_scheme"
].
find
<
std
::
string
>
(
"entity_id"
_key
==
id
,
"asym_id"
))
asym_ids
.
insert
(
asym_id
);
count
=
asym_ids
.
size
();
}
...
...
@@ -2574,14 +2191,26 @@ void Structure::cleanupEmptyCategories()
void
Structure
::
translate
(
Point
t
)
{
for
(
auto
&
a
:
mAtoms
)
for
(
auto
&
a
:
mAtoms
)
a
.
translate
(
t
);
}
void
Structure
::
rotate
(
Quaternion
q
)
{
for
(
auto
&
a
:
mAtoms
)
for
(
auto
&
a
:
mAtoms
)
a
.
rotate
(
q
);
}
void
Structure
::
translateAndRotate
(
Point
t
,
Quaternion
q
)
{
for
(
auto
&
a
:
mAtoms
)
a
.
translateAndRotate
(
t
,
q
);
}
void
Structure
::
translateRotateAndTranslate
(
Point
t1
,
Quaternion
q
,
Point
t2
)
{
for
(
auto
&
a
:
mAtoms
)
a
.
translateRotateAndTranslate
(
t1
,
q
,
t2
);
}
}
// namespace mmcif
src/TlsParser.cpp
View file @
4732004b
...
...
@@ -248,7 +248,7 @@ struct TLSSelectionNot : public TLSSelection
for
(
auto
&
r
:
residues
)
r
.
selected
=
not
r
.
selected
;
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
{
std
::
cout
<<
std
::
string
(
indentLevel
*
2
,
' '
)
<<
"NOT"
<<
std
::
endl
;
DumpSelection
(
residues
,
indentLevel
);
...
...
@@ -267,7 +267,7 @@ struct TLSSelectionAll : public TLSSelection
for
(
auto
&
r
:
residues
)
r
.
selected
=
true
;
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
{
std
::
cout
<<
std
::
string
(
indentLevel
*
2
,
' '
)
<<
"ALL"
<<
std
::
endl
;
DumpSelection
(
residues
,
indentLevel
);
...
...
@@ -287,7 +287,7 @@ struct TLSSelectionChain : public TLSSelectionAll
for
(
auto
&
r
:
residues
)
r
.
selected
=
allChains
or
r
.
chainID
==
m_chain
;
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
{
std
::
cout
<<
std
::
string
(
indentLevel
*
2
,
' '
)
<<
"CHAIN "
<<
m_chain
<<
std
::
endl
;
DumpSelection
(
residues
,
indentLevel
);
...
...
@@ -307,7 +307,7 @@ struct TLSSelectionResID : public TLSSelectionAll
for
(
auto
&
r
:
residues
)
r
.
selected
=
r
.
seqNr
==
m_seq_nr
and
r
.
iCode
==
m_icode
;
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
{
std
::
cout
<<
std
::
string
(
indentLevel
*
2
,
' '
)
<<
"ResID "
<<
m_seq_nr
<<
(
m_icode
?
std
::
string
{
m_icode
}
:
""
)
<<
std
::
endl
;
DumpSelection
(
residues
,
indentLevel
);
...
...
@@ -331,7 +331,7 @@ struct TLSSelectionRangeSeq : public TLSSelectionAll
(
r
.
seqNr
<=
m_last
or
m_last
==
kResidueNrWildcard
));
}
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
{
std
::
cout
<<
std
::
string
(
indentLevel
*
2
,
' '
)
<<
"Range "
<<
m_first
<<
':'
<<
m_last
<<
std
::
endl
;
DumpSelection
(
residues
,
indentLevel
);
...
...
@@ -374,7 +374,7 @@ struct TLSSelectionRangeID : public TLSSelectionAll
}
}
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
{
std
::
cout
<<
std
::
string
(
indentLevel
*
2
,
' '
)
<<
"Through "
<<
m_first
<<
':'
<<
m_last
<<
std
::
endl
;
DumpSelection
(
residues
,
indentLevel
);
...
...
@@ -407,7 +407,7 @@ struct TLSSelectionUnion : public TLSSelection
for
(
auto
ai
=
a
.
begin
(),
bi
=
b
.
begin
(),
ri
=
residues
.
begin
();
ri
!=
residues
.
end
();
++
ai
,
++
bi
,
++
ri
)
ri
->
selected
=
ai
->
selected
or
bi
->
selected
;
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
{
std
::
cout
<<
std
::
string
(
indentLevel
*
2
,
' '
)
<<
"Union"
<<
std
::
endl
;
DumpSelection
(
residues
,
indentLevel
);
...
...
@@ -440,7 +440,7 @@ struct TLSSelectionIntersection : public TLSSelection
for
(
auto
ai
=
a
.
begin
(),
bi
=
b
.
begin
(),
ri
=
residues
.
begin
();
ri
!=
residues
.
end
();
++
ai
,
++
bi
,
++
ri
)
ri
->
selected
=
ai
->
selected
and
bi
->
selected
;
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
{
std
::
cout
<<
std
::
string
(
indentLevel
*
2
,
' '
)
<<
"Intersection"
<<
std
::
endl
;
DumpSelection
(
residues
,
indentLevel
);
...
...
@@ -462,7 +462,7 @@ struct TLSSelectionByName : public TLSSelectionAll
for
(
auto
&
r
:
residues
)
r
.
selected
=
r
.
name
==
m_name
;
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
{
std
::
cout
<<
std
::
string
(
indentLevel
*
2
,
' '
)
<<
"Name "
<<
m_name
<<
std
::
endl
;
DumpSelection
(
residues
,
indentLevel
);
...
...
@@ -488,7 +488,7 @@ struct TLSSelectionByElement : public TLSSelectionAll
for
(
auto
&
r
:
residues
)
r
.
selected
=
iequals
(
r
.
name
,
m_element
);
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
{
std
::
cout
<<
std
::
string
(
indentLevel
*
2
,
' '
)
<<
"Element "
<<
m_element
<<
std
::
endl
;
DumpSelection
(
residues
,
indentLevel
);
...
...
@@ -890,7 +890,7 @@ TLSSelectionPtr TLSSelectionParserImplPhenix::Parse()
Match
(
pt_EOLN
);
if
(
extraParenthesis
)
if
(
extraParenthesis
and
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"WARNING: too many closing parenthesis in TLS selection statement"
<<
std
::
endl
;
return
result
;
...
...
@@ -931,7 +931,7 @@ TLSSelectionPtr TLSSelectionParserImplPhenix::ParseFactor()
case
'('
:
Match
(
'('
);
result
=
ParseAtomSelection
();
if
(
m_lookahead
==
pt_EOLN
)
if
(
m_lookahead
==
pt_EOLN
and
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"WARNING: missing closing parenthesis in TLS selection statement"
<<
std
::
endl
;
else
Match
(
')'
);
...
...
@@ -1033,7 +1033,7 @@ TLSSelectionPtr TLSSelectionParserImplPhenix::ParseFactor()
result
.
reset
(
new
TLSSelectionRangeID
(
from
,
to
,
icode_from
,
icode_to
));
else
{
if
(
cif
::
VERBOSE
and
(
icode_from
or
icode_to
))
if
(
cif
::
VERBOSE
>
0
and
(
icode_from
or
icode_to
))
std
::
cerr
<<
"Warning, ignoring insertion codes"
<<
std
::
endl
;
result
.
reset
(
new
TLSSelectionRangeSeq
(
from
,
to
));
...
...
@@ -1231,7 +1231,8 @@ TLSSelectionPtr TLSSelectionParserImplBuster::ParseGroup()
std
::
tie
(
chain2
,
seqNr2
)
=
ParseAtom
();
if
(
chain1
!=
chain2
)
{
std
::
cerr
<<
"Warning, ranges over multiple chains detected"
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Warning, ranges over multiple chains detected"
<<
std
::
endl
;
TLSSelectionPtr
sc1
(
new
TLSSelectionChain
(
chain1
));
TLSSelectionPtr
sr1
(
new
TLSSelectionRangeSeq
(
seqNr1
,
kResidueNrWildcard
));
...
...
@@ -1289,7 +1290,7 @@ std::tuple<std::string,int> TLSSelectionParserImplBuster::ParseAtom()
Match
(
':'
);
std
::
string
atom
=
m_value_s
;
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Warning: ignoring atom ID '"
<<
atom
<<
"' in TLS selection"
<<
std
::
endl
;
Match
(
bt_IDENT
);
...
...
@@ -1810,7 +1811,8 @@ class TLSSelectionParser
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
cerr
<<
"ParseError: "
<<
ex
.
what
()
<<
std
::
endl
;
if
(
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"ParseError: "
<<
ex
.
what
()
<<
std
::
endl
;
}
return
result
;
...
...
@@ -1834,14 +1836,14 @@ TLSSelectionPtr ParseSelectionDetails(const std::string& program, const std::str
if
(
not
result
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Falling back to old BUSTER"
<<
std
::
endl
;
result
=
busterOld
.
Parse
(
selection
);
}
if
(
not
result
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Falling back to PHENIX"
<<
std
::
endl
;
result
=
phenix
.
Parse
(
selection
);
}
...
...
@@ -1852,35 +1854,35 @@ TLSSelectionPtr ParseSelectionDetails(const std::string& program, const std::str
if
(
not
result
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Falling back to BUSTER"
<<
std
::
endl
;
result
=
buster
.
Parse
(
selection
);
}
if
(
not
result
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Falling back to old BUSTER"
<<
std
::
endl
;
result
=
busterOld
.
Parse
(
selection
);
}
}
else
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"No known program specified, trying PHENIX"
<<
std
::
endl
;
result
=
phenix
.
Parse
(
selection
);
if
(
not
result
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Falling back to BUSTER"
<<
std
::
endl
;
result
=
buster
.
Parse
(
selection
);
}
if
(
not
result
)
{
if
(
cif
::
VERBOSE
)
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Falling back to old BUSTER"
<<
std
::
endl
;
result
=
busterOld
.
Parse
(
selection
);
}
...
...
test/structure-test.cpp
View file @
4732004b
...
...
@@ -179,3 +179,23 @@ _struct_asym.details ?
<<
structure
.
getFile
().
data
()
<<
std
::
endl
;
}
}
// // --------------------------------------------------------------------
// BOOST_AUTO_TEST_CASE(test_load_1)
// {
// mmcif::File cf(gTestDir / "5v3g.cif.gz");
// mmcif::Structure s(cf);
// for (auto &poly : s.polymers())
// {
// std::cout << std::string(80, '=') << std::endl;
// for (auto &res : poly)
// {
// std::cout << res << std::endl;
// for (auto &atom : res.atoms())
// std::cout << " " << atom << std::endl;
// }
// }
// }
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