Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
dssp
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
dssp
Commits
7460007b
Unverified
Commit
7460007b
authored
Jun 14, 2023
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New strand calculations
parent
2f352826
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
403 additions
and
349 deletions
+403
-349
include/dssp.hpp
+1
-0
src/dssp-io.cpp
+313
-349
src/dssp.cpp
+89
-0
No files found.
include/dssp.hpp
View file @
7460007b
...
...
@@ -172,6 +172,7 @@ class dssp
std
::
tuple
<
residue_info
,
int
,
bool
>
bridge_partner
(
int
i
)
const
;
int
sheet
()
const
;
int
strand
()
const
;
/// \brief return resinfo and the energy of the bond
std
::
tuple
<
residue_info
,
double
>
acceptor
(
int
i
)
const
;
...
...
src/dssp-io.cpp
View file @
7460007b
...
...
@@ -322,8 +322,9 @@ void writeBridgePairs(cif::datablock &db, const dssp &dssp)
void
writeSheets
(
cif
::
datablock
&
db
,
const
dssp
&
dssp
)
{
using
namespace
cif
::
literals
;
using
res_list
=
std
::
vector
<
dssp
::
residue_info
>
;
using
ss_type
=
dssp
::
structure_type
;
// clean up old info first
...
...
@@ -334,448 +335,411 @@ void writeSheets(cif::datablock &db, const dssp &dssp)
// create a list of strands, based on the SS info in DSSP. Store sheet number along with the strand.
std
::
vector
<
std
::
tuple
<
int
,
res_list
>>
strands
;
std
::
map
<
std
::
tuple
<
std
::
string
,
int
>
,
int
>
sheetMap
;
// mapping from bridge number (=info.sheet()) in DSSP to sheet ID
ss_type
ss
=
ss_type
::
Loop
;
std
::
map
<
std
::
tuple
<
int
,
int
>
,
res_list
>
strands
;
std
::
set
<
int
>
sheetNrs
;
for
(
auto
&
res
:
dssp
)
{
std
::
tuple
<
std
::
string
,
int
>
sheetID
{
res
.
asym_id
(),
res
.
sheet
()
};
ss_type
iss
=
res
.
type
();
if
(
iss
==
ss
and
ss
==
ss_type
::
Strand
and
sheetMap
.
count
(
sheetID
)
>
0
and
sheetMap
[
sheetID
]
==
std
::
get
<
0
>
(
strands
.
back
()))
{
std
::
get
<
1
>
(
strands
.
back
()).
emplace_back
(
res
);
continue
;
}
ss
=
iss
;
if
(
ss
!=
ss_type
::
Strand
)
if
(
res
.
type
()
!=
dssp
::
structure_type
::
Strand
)
continue
;
if
(
not
sheetMap
.
count
(
sheetID
))
sheetMap
[
sheetID
]
=
static_cast
<
int
>
(
sheetMap
.
size
());
strands
.
emplace_back
(
sheetMap
[
sheetID
],
res_list
{
res
});
strands
[{
res
.
sheet
(),
res
.
strand
()}].
emplace_back
(
res
);
sheetNrs
.
insert
(
res
.
sheet
());
}
// sort the strands vector
std
::
sort
(
strands
.
begin
(),
strands
.
end
(),
[](
auto
&
a
,
auto
&
b
)
{
const
auto
&
[
sheetA
,
strandsA
]
=
a
;
const
auto
&
[
sheetB
,
strandsB
]
=
b
;
int
d
=
sheetA
-
sheetB
;
if
(
d
==
0
)
d
=
strandsA
.
front
().
nr
()
-
strandsB
.
front
().
nr
();
return
d
<
0
;
});
// write out the struct_sheet, since all info is available now
auto
&
struct_sheet
=
db
[
"struct_sheet"
];
auto
&
struct_sheet_range
=
db
[
"struct_sheet_range"
];
auto
&
struct_sheet_order
=
db
[
"struct_sheet_order"
];
auto
&
struct_sheet_hbond
=
db
[
"struct_sheet_hbond"
];
// auto &pdbx_struct_sheet_hbond = db["pdbx_struct_sheet_hbond"];
// auto &pdbx_poly_seq_scheme = db["pdbx_poly_seq_scheme"];
int
lastSheet
=
-
1
;
for
(
const
auto
&
[
sheetNr
,
strand
]
:
strands
)
{
if
(
sheetNr
!=
lastSheet
)
{
struct_sheet
.
emplace
({
{
"id"
,
cif
::
cif_id_for_number
(
sheetNr
)
},
{
"number_strands"
,
std
::
count_if
(
strands
.
begin
(),
strands
.
end
(),
[
nr
=
sheetNr
](
std
::
tuple
<
int
,
res_list
>
const
&
s
)
{
return
std
::
get
<
0
>
(
s
)
==
nr
;
})
}
});
lastSheet
=
sheetNr
;
}
}
// Each residue resides in a single strand which is part of a single sheet
// this function returns the sequence number inside the sheet for the strand
// containing res
std
::
map
<
int
,
int
>
strandMap
;
int
strandNr
=
0
;
for
(
auto
&&
[
sheet
,
strand
]
:
strands
)
for
(
int
sheetNr
:
sheetNrs
)
{
for
(
auto
&
r
:
strand
)
{
if
(
r
.
type
()
!=
ss_type
::
Strand
)
continue
;
strandMap
[
r
.
nr
()]
=
strandNr
;
}
++
strandNr
;
}
auto
sheetID
=
cif
::
cif_id_for_number
(
sheetNr
-
1
);
// This map is used to record the sense of a ladder, and can be used
// to detect ladders already seen.
std
::
map
<
std
::
tuple
<
int
,
int
,
int
>
,
std
::
tuple
<
int
,
bool
>>
ladderSense
;
std
::
map
<
std
::
tuple
<
int
,
int
>
,
int
>
sheetOrder
;
for
(
auto
&
res
:
dssp
)
{
if
(
res
.
type
()
!=
ss_type
::
Strand
)
continue
;
int
s1
=
strandMap
[
res
.
nr
()];
struct_sheet
.
emplace
({
{
"id"
,
sheetID
},
{
"number_strands"
,
std
::
count_if
(
strands
.
begin
(),
strands
.
end
(),
[
nr
=
sheetNr
](
std
::
tuple
<
std
::
tuple
<
int
,
int
>
,
res_list
>
const
&
s
)
{
const
auto
&
[
strandID
,
strand
]
=
s
;
return
strand
.
front
().
sheet
()
==
nr
;
})
}
});
for
(
int
i
:
{
0
,
1
}
)
for
(
auto
&&
[
strandTuple
,
strand
]
:
strands
)
{
const
auto
&
[
p
,
ladder
,
parallel
]
=
res
.
bridge_partner
(
i
);
if
(
not
p
or
p
.
asym_id
()
!=
res
.
asym_id
()
or
p
.
sheet
()
!=
res
.
sheet
()
or
p
.
type
()
!=
ss_type
::
Strand
)
if
(
strand
.
front
().
sheet
()
!=
sheetNr
)
continue
;
std
::
string
strandID
=
"strand_"
+
cif
::
cif_id_for_number
(
strand
.
front
().
strand
()
-
1
);
int
s2
=
strandMap
[
p
.
nr
()];
// assert(s1 != s2);
if
(
s2
==
s1
)
continue
;
std
::
sort
(
strand
.
begin
(),
strand
.
end
(),
[](
dssp
::
residue_info
const
&
a
,
dssp
::
residue_info
const
&
b
)
{
return
a
.
nr
()
<
b
.
nr
();
});
std
::
tuple
<
std
::
string
,
int
>
sheetID
{
res
.
asym_id
(),
res
.
sheet
()
}
;
int
sheet
=
sheetMap
[
sheetID
]
;
auto
&
beg
=
strand
.
front
()
;
auto
&
end
=
strand
.
back
()
;
auto
k
=
s1
>
s2
?
std
::
make_tuple
(
sheet
,
s2
,
s1
)
:
std
::
make_tuple
(
sheet
,
s1
,
s2
);
if
(
ladderSense
.
count
(
k
))
struct_sheet_range
.
emplace
({
{
"sheet_id"
,
sheetID
},
{
"id"
,
strandID
},
{
"beg_label_comp_id"
,
beg
.
compound_id
()
},
{
"beg_label_asym_id"
,
beg
.
asym_id
()
},
{
"beg_label_seq_id"
,
beg
.
seq_id
()
},
{
"pdbx_beg_PDB_ins_code"
,
beg
.
pdb_ins_code
()
},
{
"end_label_comp_id"
,
end
.
compound_id
()
},
{
"end_label_asym_id"
,
end
.
asym_id
()
},
{
"end_label_seq_id"
,
end
.
seq_id
()
},
{
"pdbx_end_PDB_ins_code"
,
end
.
pdb_ins_code
()
},
{
"beg_auth_comp_id"
,
beg
.
compound_id
()
},
{
"beg_auth_asym_id"
,
beg
.
auth_asym_id
()
},
{
"beg_auth_seq_id"
,
beg
.
auth_seq_id
()
},
{
"end_auth_comp_id"
,
end
.
compound_id
()
},
{
"end_auth_asym_id"
,
end
.
auth_asym_id
()
},
{
"end_auth_seq_id"
,
end
.
auth_seq_id
()
}
});
// loop over the ladders for this strand and write out the struct_sheet_order
for
(
auto
&
res
:
strand
)
{
// assert(ladderSense[k] == std::make_tuple(ladder, parallel));
assert
(
std
::
get
<
1
>
(
ladderSense
[
k
])
==
parallel
);
continue
;
for
(
int
i
:
{
0
,
1
})
{
const
auto
&
[
bp
,
ladder
,
parallel
]
=
res
.
bridge_partner
(
i
);
if
(
not
bp
or
bp
.
type
()
!=
dssp
::
structure_type
::
Strand
)
continue
;
auto
s1
=
res
.
strand
();
auto
s2
=
bp
.
strand
();
if
(
s1
>
s2
)
std
::
swap
(
s1
,
s2
);
sheetOrder
[{
s1
,
s2
}]
+=
parallel
?
1
:
-
1
;
}
}
ladderSense
.
emplace
(
k
,
std
::
make_tuple
(
ladder
,
parallel
));
}
}
auto
&
struct_sheet_order
=
db
[
"struct_sheet_order"
];
auto
&
struct_sheet_hbond
=
db
[
"struct_sheet_hbond"
];
auto
&
pdbx_struct_sheet_hbond
=
db
[
"pdbx_struct_sheet_hbond"
];
auto
&
pdbx_poly_seq_scheme
=
db
[
"pdbx_poly_seq_scheme"
];
for
(
const
auto
&
[
k
,
parallel_test
]
:
sheetOrder
)
{
const
auto
&
[
s1
,
s2
]
=
k
;
for
(
const
auto
&
[
key
,
value
]
:
ladderSense
)
{
const
auto
&
[
sheet
,
s1
,
s2
]
=
key
;
const
auto
&
[
ladder
,
parallel
]
=
value
;
if
(
parallel_test
==
0
)
continue
;
bool
parallel
=
parallel_test
>
0
;
struct_sheet_order
.
emplace
({
{
"sheet_id"
,
cif
::
cif_id_for_number
(
sheet
)
},
// { "dssp_struct_ladder_id", cif::cifIdForNumber(ladder) },
{
"range_id_1"
,
s1
+
1
},
{
"range_id_2"
,
s2
+
1
},
{
"sense"
,
parallel
?
"parallel"
:
"anti-parallel"
}
});
std
::
string
strandID_1
=
"strand_"
+
cif
::
cif_id_for_number
(
s1
-
1
);
std
::
string
strandID_2
=
"strand_"
+
cif
::
cif_id_for_number
(
s2
-
1
);
res_list
strand1
,
strand2
;
struct_sheet_order
.
emplace
({
{
"sheet_id"
,
sheetID
},
{
"range_id_1"
,
"strand_"
+
strandID_1
},
{
"range_id_2"
,
"strand_"
+
strandID_2
},
{
"sense"
,
parallel
>
0
?
"parallel"
:
"anti-parallel"
}
});
for
(
int
strandIx
=
0
;
static_cast
<
size_t
>
(
strandIx
)
<
strands
.
size
();
++
strandIx
)
{
const
auto
&
[
sSheet
,
strand
]
=
strands
[
strandIx
];
if
(
sSheet
!=
sheet
)
continue
;
res_list
strand1
,
strand2
;
if
(
strandIx
==
s1
)
strand1
=
strand
;
else
if
(
strandIx
==
s2
)
for
(
auto
&&
[
strandTuple
,
strand
]
:
strands
)
{
strand2
=
strand
;
break
;
}
}
const
auto
&
[
sheet_nr
,
strand_nr
]
=
strandTuple
;
if
(
sheet_nr
!=
sheetNr
)
continue
;
assert
(
not
(
strand1
.
empty
()
or
strand2
.
empty
()));
if
(
strand_nr
==
s1
)
strand1
=
strand
;
else
if
(
strand_nr
==
s2
)
{
strand2
=
strand
;
break
;
}
}
int
beg1SeqID
=
0
,
beg2SeqID
=
0
,
end1SeqID
=
0
,
end2SeqID
=
0
;
std
::
string
beg1AtomID
,
beg2AtomID
,
end1AtomID
,
end2AtomID
;
assert
(
not
(
strand1
.
empty
()
or
strand2
.
empty
()));
if
(
parallel
)
{
// I. a d II. a d parallel
// \ /
// b e b e <= the residues forming the bridge
// / \ ..
// c f c f
int
beg1SeqID
=
0
,
beg2SeqID
=
0
,
end1SeqID
=
0
,
end2SeqID
=
0
;
std
::
string
beg1AtomID
,
beg2AtomID
,
end1AtomID
,
end2AtomID
;
for
(
auto
b
:
strand1
)
if
(
parallel
)
{
for
(
int
i
:
{
0
,
1
})
// I. a d II. a d parallel
// \ /
// b e b e <= the residues forming the bridge
// / \ ..
// c f c f
for
(
auto
b
:
strand1
)
{
const
auto
&
[
e
,
ladder1
,
parallel1
]
=
b
.
bridge_partner
(
i
);
auto
esi
=
std
::
find
(
strand2
.
begin
(),
strand2
.
end
(),
e
);
for
(
int
i
:
{
0
,
1
})
{
const
auto
&
[
e
,
ladder1
,
parallel1
]
=
b
.
bridge_partner
(
i
);
auto
esi
=
std
::
find
(
strand2
.
begin
(),
strand2
.
end
(),
e
);
if
(
esi
==
strand2
.
end
())
continue
;
if
(
esi
==
strand2
.
end
())
continue
;
auto
bi
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
b
);
assert
(
bi
!=
dssp
.
end
()
and
bi
!=
dssp
.
begin
());
auto
bi
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
b
);
assert
(
bi
!=
dssp
.
end
()
and
bi
!=
dssp
.
begin
());
auto
a
=
*
std
::
prev
(
bi
);
auto
c
=
*
std
::
next
(
bi
);
auto
a
=
*
std
::
prev
(
bi
);
auto
c
=
*
std
::
next
(
bi
);
auto
ei
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
e
);
assert
(
ei
!=
dssp
.
end
()
and
ei
!=
dssp
.
begin
());
auto
d
=
*
std
::
prev
(
ei
);
auto
f
=
*
std
::
next
(
ei
);
auto
ei
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
e
);
assert
(
ei
!=
dssp
.
end
()
and
ei
!=
dssp
.
begin
());
auto
d
=
*
std
::
prev
(
ei
);
auto
f
=
*
std
::
next
(
ei
);
if
(
test_bond
(
e
,
a
)
and
test_bond
(
c
,
e
))
// case I.
{
beg1SeqID
=
a
.
seq_id
();
beg2SeqID
=
e
.
seq_id
();
if
(
test_bond
(
e
,
a
)
and
test_bond
(
c
,
e
))
// case I.
{
beg1SeqID
=
a
.
seq_id
();
beg2SeqID
=
e
.
seq_id
();
beg1AtomID
=
"O"
;
beg2AtomID
=
"N"
;
}
else
if
(
test_bond
(
b
,
d
)
and
test_bond
(
f
,
b
))
// case II.
{
beg1SeqID
=
b
.
seq_id
();
beg2SeqID
=
d
.
seq_id
();
beg1AtomID
=
"O"
;
beg2AtomID
=
"N"
;
}
else
if
(
test_bond
(
b
,
d
)
and
test_bond
(
f
,
b
))
// case II.
{
beg1SeqID
=
b
.
seq_id
();
beg2SeqID
=
d
.
seq_id
();
beg1AtomID
=
"N"
;
beg2AtomID
=
"O"
;
beg1AtomID
=
"N"
;
beg2AtomID
=
"O"
;
}
break
;
}
break
;
if
(
beg1SeqID
)
break
;
}
if
(
beg1SeqID
)
break
;
}
std
::
reverse
(
strand1
.
begin
(),
strand1
.
end
());
std
::
reverse
(
strand2
.
begin
(),
strand2
.
end
());
std
::
reverse
(
strand1
.
begin
(),
strand1
.
end
());
std
::
reverse
(
strand2
.
begin
(),
strand2
.
end
());
for
(
auto
b
:
strand1
)
{
for
(
int
i
:
{
0
,
1
})
for
(
auto
b
:
strand1
)
{
const
auto
&
[
e
,
ladder1
,
parallel1
]
=
b
.
bridge_partner
(
i
);
auto
esi
=
std
::
find
(
strand2
.
begin
(),
strand2
.
end
(),
e
);
for
(
int
i
:
{
0
,
1
})
{
const
auto
&
[
e
,
ladder1
,
parallel1
]
=
b
.
bridge_partner
(
i
);
auto
esi
=
std
::
find
(
strand2
.
begin
(),
strand2
.
end
(),
e
);
if
(
esi
==
strand2
.
end
())
continue
;
if
(
esi
==
strand2
.
end
())
continue
;
auto
bi
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
b
);
assert
(
bi
!=
dssp
.
end
()
and
bi
!=
dssp
.
begin
());
auto
bi
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
b
);
assert
(
bi
!=
dssp
.
end
()
and
bi
!=
dssp
.
begin
());
auto
a
=
*
std
::
next
(
bi
);
auto
c
=
*
std
::
prev
(
bi
);
auto
a
=
*
std
::
next
(
bi
);
auto
c
=
*
std
::
prev
(
bi
);
auto
ei
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
e
);
assert
(
ei
!=
dssp
.
end
()
and
ei
!=
dssp
.
begin
());
auto
d
=
*
std
::
next
(
ei
);
auto
f
=
*
std
::
prev
(
ei
);
auto
ei
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
e
);
assert
(
ei
!=
dssp
.
end
()
and
ei
!=
dssp
.
begin
());
auto
d
=
*
std
::
next
(
ei
);
auto
f
=
*
std
::
prev
(
ei
);
if
(
test_bond
(
a
,
e
)
and
test_bond
(
e
,
c
))
// case I.
{
end1SeqID
=
a
.
seq_id
();
end2SeqID
=
e
.
seq_id
();
if
(
test_bond
(
a
,
e
)
and
test_bond
(
e
,
c
))
// case I.
{
end1SeqID
=
a
.
seq_id
();
end2SeqID
=
e
.
seq_id
();
end1AtomID
=
"N"
;
end2AtomID
=
"O"
;
}
else
if
(
test_bond
(
d
,
b
)
and
test_bond
(
b
,
f
))
// case II.
{
end1SeqID
=
b
.
seq_id
();
end2SeqID
=
d
.
seq_id
();
end1AtomID
=
"N"
;
end2AtomID
=
"O"
;
}
else
if
(
test_bond
(
d
,
b
)
and
test_bond
(
b
,
f
))
// case II.
{
end1SeqID
=
b
.
seq_id
();
end2SeqID
=
d
.
seq_id
();
end1AtomID
=
"O"
;
end2AtomID
=
"N"
;
}
end1AtomID
=
"O"
;
end2AtomID
=
"N"
;
break
;
}
break
;
if
(
end1SeqID
)
break
;
}
if
(
end1SeqID
)
break
;
}
}
else
{
// III. a <- f IV. a f antiparallel
//
// b e b <-> e <= the residues forming the bridge
//
// c -> d c d
else
{
// III. a <- f IV. a f antiparallel
//
// b e b <-> e <= the residues forming the bridge
//
// c -> d c d
std
::
reverse
(
strand2
.
begin
(),
strand2
.
end
());
std
::
reverse
(
strand2
.
begin
(),
strand2
.
end
());
for
(
auto
b
:
strand1
)
{
for
(
int
i
:
{
0
,
1
})
for
(
auto
b
:
strand1
)
{
const
auto
&
[
e
,
ladder1
,
parallel1
]
=
b
.
bridge_partner
(
i
);
auto
esi
=
std
::
find
(
strand2
.
begin
(),
strand2
.
end
(),
e
);
for
(
int
i
:
{
0
,
1
})
{
const
auto
&
[
e
,
ladder1
,
parallel1
]
=
b
.
bridge_partner
(
i
);
auto
esi
=
std
::
find
(
strand2
.
begin
(),
strand2
.
end
(),
e
);
if
(
esi
==
strand2
.
end
())
continue
;
if
(
esi
==
strand2
.
end
())
continue
;
auto
bi
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
b
);
assert
(
bi
!=
dssp
.
end
()
and
bi
!=
dssp
.
begin
());
auto
bi
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
b
);
assert
(
bi
!=
dssp
.
end
()
and
bi
!=
dssp
.
begin
());
auto
a
=
*
std
::
prev
(
bi
);
auto
c
=
*
std
::
next
(
bi
);
auto
a
=
*
std
::
prev
(
bi
);
auto
c
=
*
std
::
next
(
bi
);
auto
ei
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
e
);
assert
(
ei
!=
dssp
.
end
()
and
ei
!=
dssp
.
begin
());
auto
d
=
*
std
::
prev
(
ei
);
auto
f
=
*
std
::
next
(
ei
);
auto
ei
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
e
);
assert
(
ei
!=
dssp
.
end
()
and
ei
!=
dssp
.
begin
());
auto
d
=
*
std
::
prev
(
ei
);
auto
f
=
*
std
::
next
(
ei
);
if
(
test_bond
(
f
,
a
)
and
test_bond
(
c
,
d
))
// case III.
{
beg1SeqID
=
a
.
seq_id
();
beg2SeqID
=
f
.
seq_id
();
if
(
test_bond
(
f
,
a
)
and
test_bond
(
c
,
d
))
// case III.
{
beg1SeqID
=
a
.
seq_id
();
beg2SeqID
=
f
.
seq_id
();
beg1AtomID
=
"O"
;
beg2AtomID
=
"N"
;
}
else
if
(
test_bond
(
b
,
e
)
and
test_bond
(
e
,
b
))
// case IV.
{
beg1SeqID
=
b
.
seq_id
();
beg2SeqID
=
e
.
seq_id
();
beg1AtomID
=
"O"
;
beg2AtomID
=
"N"
;
}
else
if
(
test_bond
(
b
,
e
)
and
test_bond
(
e
,
b
))
// case IV.
{
beg1SeqID
=
b
.
seq_id
();
beg2SeqID
=
e
.
seq_id
();
beg1AtomID
=
"N"
;
beg2AtomID
=
"O"
;
}
beg1AtomID
=
"N"
;
beg2AtomID
=
"O"
;
break
;
}
break
;
if
(
beg1SeqID
)
break
;
}
if
(
beg1SeqID
)
break
;
}
std
::
reverse
(
strand1
.
begin
(),
strand1
.
end
());
std
::
reverse
(
strand2
.
begin
(),
strand2
.
end
());
std
::
reverse
(
strand1
.
begin
(),
strand1
.
end
());
std
::
reverse
(
strand2
.
begin
(),
strand2
.
end
());
for
(
auto
b
:
strand1
)
{
for
(
int
i
:
{
0
,
1
})
for
(
auto
b
:
strand1
)
{
const
auto
&
[
e
,
ladder1
,
parallel1
]
=
b
.
bridge_partner
(
i
);
auto
esi
=
std
::
find
(
strand2
.
begin
(),
strand2
.
end
(),
e
);
for
(
int
i
:
{
0
,
1
})
{
const
auto
&
[
e
,
ladder1
,
parallel1
]
=
b
.
bridge_partner
(
i
);
auto
esi
=
std
::
find
(
strand2
.
begin
(),
strand2
.
end
(),
e
);
if
(
esi
==
strand2
.
end
())
continue
;
if
(
esi
==
strand2
.
end
())
continue
;
auto
bi
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
b
);
assert
(
bi
!=
dssp
.
end
()
and
bi
!=
dssp
.
begin
());
auto
bi
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
b
);
assert
(
bi
!=
dssp
.
end
()
and
bi
!=
dssp
.
begin
());
auto
a
=
*
std
::
next
(
bi
);
auto
c
=
*
std
::
prev
(
bi
);
auto
a
=
*
std
::
next
(
bi
);
auto
c
=
*
std
::
prev
(
bi
);
auto
ei
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
e
);
assert
(
ei
!=
dssp
.
end
()
and
ei
!=
dssp
.
begin
());
auto
d
=
*
std
::
next
(
ei
);
auto
f
=
*
std
::
prev
(
ei
);
auto
ei
=
std
::
find
(
dssp
.
begin
(),
dssp
.
end
(),
e
);
assert
(
ei
!=
dssp
.
end
()
and
ei
!=
dssp
.
begin
());
auto
d
=
*
std
::
next
(
ei
);
auto
f
=
*
std
::
prev
(
ei
);
if
(
test_bond
(
a
,
f
)
and
test_bond
(
d
,
c
))
// case III.
{
end1SeqID
=
a
.
seq_id
();
end2SeqID
=
f
.
seq_id
();
if
(
test_bond
(
a
,
f
)
and
test_bond
(
d
,
c
))
// case III.
{
end1SeqID
=
a
.
seq_id
();
end2SeqID
=
f
.
seq_id
();
end1AtomID
=
"N"
;
end2AtomID
=
"O"
;
}
else
if
(
test_bond
(
b
,
e
)
and
test_bond
(
e
,
b
))
// case IV.
{
end1SeqID
=
b
.
seq_id
();
end2SeqID
=
e
.
seq_id
();
end1AtomID
=
"N"
;
end2AtomID
=
"O"
;
}
else
if
(
test_bond
(
b
,
e
)
and
test_bond
(
e
,
b
))
// case IV.
{
end1SeqID
=
b
.
seq_id
();
end2SeqID
=
e
.
seq_id
();
end1AtomID
=
"N"
;
end2AtomID
=
"O"
;
end1AtomID
=
"N"
;
end2AtomID
=
"O"
;
}
break
;
}
break
;
if
(
end1SeqID
)
break
;
}
if
(
end1SeqID
)
break
;
}
}
struct_sheet_hbond
.
emplace
({
{
"sheet_id"
,
cif
::
cif_id_for_number
(
sheet
)
},
{
"range_id_1"
,
s1
+
1
},
{
"range_id_2"
,
s2
+
1
},
{
"range_1_beg_label_seq_id"
,
beg1SeqID
},
{
"range_1_beg_label_atom_id"
,
beg1AtomID
},
{
"range_2_beg_label_seq_id"
,
beg2SeqID
},
{
"range_2_beg_label_atom_id"
,
beg2AtomID
},
{
"range_1_end_label_seq_id"
,
end1SeqID
},
{
"range_1_end_label_atom_id"
,
end1AtomID
},
{
"range_2_end_label_seq_id"
,
end2SeqID
},
{
"range_2_end_label_atom_id"
,
end2AtomID
}
});
using
namespace
cif
::
literals
;
auto
b1
=
pdbx_poly_seq_scheme
.
find_first
(
"asym_id"
_key
==
strand1
.
front
().
asym_id
()
and
"seq_id"
_key
==
beg1SeqID
);
auto
e1
=
pdbx_poly_seq_scheme
.
find_first
(
"asym_id"
_key
==
strand1
.
front
().
asym_id
()
and
"seq_id"
_key
==
end1SeqID
);
auto
b2
=
pdbx_poly_seq_scheme
.
find_first
(
"asym_id"
_key
==
strand2
.
front
().
asym_id
()
and
"seq_id"
_key
==
beg2SeqID
);
auto
e2
=
pdbx_poly_seq_scheme
.
find_first
(
"asym_id"
_key
==
strand2
.
front
().
asym_id
()
and
"seq_id"
_key
==
end2SeqID
);
if
(
not
(
b1
and
e1
and
b2
and
e2
))
{
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"error looking up strand ends"
<<
std
::
endl
;
continue
;
struct_sheet_hbond
.
emplace
({
{
"sheet_id"
,
sheetID
},
{
"range_id_1"
,
strandID_1
},
{
"range_id_2"
,
strandID_2
},
{
"range_1_beg_label_seq_id"
,
beg1SeqID
},
{
"range_1_beg_label_atom_id"
,
beg1AtomID
},
{
"range_2_beg_label_seq_id"
,
beg2SeqID
},
{
"range_2_beg_label_atom_id"
,
beg2AtomID
},
{
"range_1_end_label_seq_id"
,
end1SeqID
},
{
"range_1_end_label_atom_id"
,
end1AtomID
},
{
"range_2_end_label_seq_id"
,
end2SeqID
},
{
"range_2_end_label_atom_id"
,
end2AtomID
}
});
}
pdbx_struct_sheet_hbond
.
emplace
({
{
"sheet_id"
,
cif
::
cif_id_for_number
(
sheet
)
},
{
"range_id_1"
,
s1
+
1
},
{
"range_id_2"
,
s2
+
1
},
{
"range_1_label_atom_id"
,
beg1AtomID
},
{
"range_1_label_comp_id"
,
b1
[
"mon_id"
].
as
<
std
::
string
>
()
},
{
"range_1_label_asym_id"
,
b1
[
"asym_id"
].
as
<
std
::
string
>
()
},
{
"range_1_label_seq_id"
,
b1
[
"seq_id"
].
as
<
std
::
string
>
()
},
{
"range_1_PDB_ins_code"
,
b1
[
"pdb_ins_code"
].
as
<
std
::
string
>
()
},
{
"range_1_auth_atom_id"
,
beg1AtomID
},
{
"range_1_auth_comp_id"
,
b1
[
"auth_mon_id"
].
as
<
std
::
string
>
()
},
{
"range_1_auth_asym_id"
,
b1
[
"pdb_strand_id"
].
as
<
std
::
string
>
()
},
{
"range_1_auth_seq_id"
,
b1
[
"auth_seq_num"
].
as
<
std
::
string
>
()
},
{
"range_2_label_atom_id"
,
beg2AtomID
},
{
"range_2_label_comp_id"
,
b2
[
"mon_id"
].
as
<
std
::
string
>
()
},
{
"range_2_label_asym_id"
,
b2
[
"asym_id"
].
as
<
std
::
string
>
()
},
{
"range_2_label_seq_id"
,
b2
[
"seq_id"
].
as
<
std
::
string
>
()
},
{
"range_2_PDB_ins_code"
,
b2
[
"pdb_ins_code"
].
as
<
std
::
string
>
()
},
{
"range_2_auth_atom_id"
,
beg2AtomID
},
{
"range_2_auth_comp_id"
,
b2
[
"auth_mon_id"
].
as
<
std
::
string
>
()
},
{
"range_2_auth_asym_id"
,
b2
[
"pdb_strand_id"
].
as
<
std
::
string
>
()
},
{
"range_2_auth_seq_id"
,
b2
[
"auth_seq_num"
].
as
<
std
::
string
>
()
},
});
}
// Data items in the PDBX_STRUCT_SHEET_HBOND category record details
// about the hydrogen bonding between residue ranges in a beta sheet.
// This category is provided for cases where only a single hydrogen
// bond is used to register the two residue ranges. Category
// STRUCT_SHEET_HBOND should be used when the initial and terminal
// hydrogen bonds for strand pair are known.
auto
&
struct_sheet_range
=
db
[
"struct_sheet_range"
];
// // Okay, so that means we should write entries in that category only
// // when the ladder is size 1. Right? But those are called BetaBridges
// // in
for
(
const
auto
&
[
key
,
iSheet
]
:
sheetMap
)
{
for
(
auto
&&
[
sheet
,
strand
]
:
strands
)
{
if
(
sheet
!=
iSheet
)
continue
;
std
::
sort
(
strand
.
begin
(),
strand
.
end
(),
[](
dssp
::
residue_info
const
&
a
,
dssp
::
residue_info
const
&
b
)
{
return
a
.
nr
()
<
b
.
nr
();
});
auto
&
beg
=
strand
.
front
();
auto
&
end
=
strand
.
back
();
struct_sheet_range
.
emplace
({
{
"sheet_id"
,
cif
::
cif_id_for_number
(
sheet
)
},
{
"id"
,
strandMap
[
strand
.
front
().
nr
()]
+
1
},
{
"beg_label_comp_id"
,
beg
.
compound_id
()
},
{
"beg_label_asym_id"
,
beg
.
asym_id
()
},
{
"beg_label_seq_id"
,
beg
.
seq_id
()
},
{
"pdbx_beg_PDB_ins_code"
,
beg
.
pdb_ins_code
()
},
{
"end_label_comp_id"
,
end
.
compound_id
()
},
{
"end_label_asym_id"
,
end
.
asym_id
()
},
{
"end_label_seq_id"
,
end
.
seq_id
()
},
{
"pdbx_end_PDB_ins_code"
,
end
.
pdb_ins_code
()
},
{
"beg_auth_comp_id"
,
beg
.
compound_id
()
},
{
"beg_auth_asym_id"
,
beg
.
auth_asym_id
()
},
{
"beg_auth_seq_id"
,
beg
.
auth_seq_id
()
},
{
"end_auth_comp_id"
,
end
.
compound_id
()
},
{
"end_auth_asym_id"
,
end
.
auth_asym_id
()
},
{
"end_auth_seq_id"
,
end
.
auth_seq_id
()
}
});
}
// {
// auto b1 = pdbx_poly_seq_scheme.find_first("asym_id"_key == strand1.front().asym_id() and "seq_id"_key == beg1SeqID);
// auto e1 = pdbx_poly_seq_scheme.find_first("asym_id"_key == strand1.front().asym_id() and "seq_id"_key == end1SeqID);
// auto b2 = pdbx_poly_seq_scheme.find_first("asym_id"_key == strand2.front().asym_id() and "seq_id"_key == beg2SeqID);
// auto e2 = pdbx_poly_seq_scheme.find_first("asym_id"_key == strand2.front().asym_id() and "seq_id"_key == end2SeqID);
// if (not(b1 and e1 and b2 and e2))
// {
// if (cif::VERBOSE > 0)
// std::cerr << "error looking up strand ends" << std::endl;
// continue;
// }
// pdbx_struct_sheet_hbond.emplace({
// { "sheet_id", sheetID },
// { "range_id_1", strandID_1 },
// { "range_id_2", strandID_2 },
// { "range_1_label_atom_id", beg1AtomID },
// { "range_1_label_comp_id", b1["mon_id"].as<std::string>() },
// { "range_1_label_asym_id", b1["asym_id"].as<std::string>() },
// { "range_1_label_seq_id", b1["seq_id"].as<std::string>() },
// { "range_1_PDB_ins_code", b1["pdb_ins_code"].as<std::string>() },
// { "range_1_auth_atom_id", beg1AtomID },
// { "range_1_auth_comp_id", b1["auth_mon_id"].as<std::string>() },
// { "range_1_auth_asym_id", b1["pdb_strand_id"].as<std::string>() },
// { "range_1_auth_seq_id", b1["auth_seq_num"].as<std::string>() },
// { "range_2_label_atom_id", beg2AtomID },
// { "range_2_label_comp_id", b2["mon_id"].as<std::string>() },
// { "range_2_label_asym_id", b2["asym_id"].as<std::string>() },
// { "range_2_label_seq_id", b2["seq_id"].as<std::string>() },
// { "range_2_PDB_ins_code", b2["pdb_ins_code"].as<std::string>() },
// { "range_2_auth_atom_id", beg2AtomID },
// { "range_2_auth_comp_id", b2["auth_mon_id"].as<std::string>() },
// { "range_2_auth_asym_id", b2["pdb_strand_id"].as<std::string>() },
// { "range_2_auth_seq_id", b2["auth_seq_num"].as<std::string>() },
// });
// }
}
}
...
...
src/dssp.cpp
View file @
7460007b
...
...
@@ -421,6 +421,9 @@ struct dssp::residue
void
SetSheet
(
uint32_t
inSheet
)
{
mSheet
=
inSheet
;
}
uint32_t
GetSheet
()
const
{
return
mSheet
;
}
void
SetStrand
(
uint32_t
inStrand
)
{
mStrand
=
inStrand
;
}
uint32_t
GetStrand
()
const
{
return
mStrand
;
}
bool
IsBend
()
const
{
return
mBend
;
}
void
SetBend
(
bool
inBend
)
{
mBend
=
inBend
;
}
...
...
@@ -548,6 +551,7 @@ struct dssp::residue
HBond
mHBondDonor
[
2
]
=
{},
mHBondAcceptor
[
2
]
=
{};
bridge_partner
mBetaPartner
[
2
]
=
{};
uint32_t
mSheet
=
0
;
uint32_t
mStrand
=
0
;
// Added to ease the writing of mmCIF's struct_sheet and friends
helix_position_type
mHelixFlags
[
4
]
=
{
helix_position_type
::
None
,
helix_position_type
::
None
,
helix_position_type
::
None
,
helix_position_type
::
None
};
//
bool
mBend
=
false
;
chain_break_type
mChainBreak
=
chain_break_type
::
None
;
...
...
@@ -1099,6 +1103,86 @@ void CalculateBetaSheets(std::vector<residue> &inResidues, statistics &stats, st
inResidues
[
i
].
SetSheet
(
bridge
.
sheet
);
}
}
// Construct the 'strands'
// For mmCIF output, this is needed and since we now have the information available
// it is best to do the calculation here.
// strands are ranges of residues of length > 1 that form beta bridges in a sheet.
for
(
uint32_t
iSheet
=
1
;
iSheet
<
sheet
;
++
iSheet
)
{
std
::
vector
<
std
::
tuple
<
uint32_t
,
uint32_t
>>
strands
;
for
(
auto
&
bridge
:
bridges
)
{
if
(
bridge
.
sheet
!=
iSheet
)
continue
;
for
(
auto
&
range
:
{
bridge
.
i
,
bridge
.
j
})
{
auto
imin
=
range
.
front
();
auto
imax
=
range
.
back
();
if
(
imin
==
imax
)
continue
;
if
(
imin
>
imax
)
std
::
swap
(
imin
,
imax
);
auto
ii
=
find_if
(
strands
.
begin
(),
strands
.
end
(),
[
a
=
imin
,
b
=
imax
]
(
std
::
tuple
<
uint32_t
,
uint32_t
>
&
t
)
{
auto
&&
[
start
,
end
]
=
t
;
bool
result
=
false
;
if
(
start
<=
b
and
end
>=
a
)
{
result
=
true
;
if
(
start
>
a
)
start
=
a
;
if
(
end
<
b
)
end
=
b
;
}
return
result
;
});
if
(
ii
==
strands
.
end
())
strands
.
emplace_back
(
imin
,
imax
);
}
}
std
::
sort
(
strands
.
begin
(),
strands
.
end
());
// collapse ranges that overlap
if
(
strands
.
size
()
>
1
)
{
auto
si
=
strands
.
begin
();
while
(
std
::
next
(
si
)
!=
strands
.
end
())
{
auto
&&
[
afirst
,
alast
]
=
*
si
;
auto
&&
[
bfirst
,
blast
]
=
*
(
std
::
next
(
si
));
if
(
alast
>=
bfirst
)
{
bfirst
=
afirst
;
si
=
strands
.
erase
(
si
);
continue
;
}
++
si
;
}
}
for
(
size_t
i
=
0
;
i
<
strands
.
size
();
++
i
)
{
const
auto
&
[
first
,
last
]
=
strands
[
i
];
for
(
auto
nr
=
first
;
nr
<=
last
;
++
nr
)
{
assert
(
inResidues
[
nr
].
mStrand
==
0
);
inResidues
[
nr
].
SetStrand
(
i
+
1
);
}
}
}
}
// --------------------------------------------------------------------
...
...
@@ -2138,6 +2222,11 @@ int dssp::residue_info::sheet() const
return
m_impl
->
GetSheet
();
}
int
dssp
::
residue_info
::
strand
()
const
{
return
m_impl
->
GetStrand
();
}
std
::
tuple
<
dssp
::
residue_info
,
double
>
dssp
::
residue_info
::
acceptor
(
int
i
)
const
{
auto
&
a
=
m_impl
->
mHBondAcceptor
[
i
];
...
...
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