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
f4506438
Unverified
Commit
f4506438
authored
Jan 22, 2024
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added remove column
parent
fc14a655
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
105 additions
and
40 deletions
+105
-40
include/cif++/category.hpp
+7
-5
src/category.cpp
+66
-31
src/datablock.cpp
+4
-0
src/pdb/reconstruct.cpp
+28
-4
No files found.
include/cif++/category.hpp
View file @
f4506438
...
@@ -31,8 +31,8 @@
...
@@ -31,8 +31,8 @@
#include "cif++/condition.hpp"
#include "cif++/condition.hpp"
#include "cif++/iterator.hpp"
#include "cif++/iterator.hpp"
#include "cif++/row.hpp"
#include "cif++/row.hpp"
#include "cif++/validate.hpp"
#include "cif++/text.hpp"
#include "cif++/text.hpp"
#include "cif++/validate.hpp"
#include <array>
#include <array>
...
@@ -776,8 +776,7 @@ class category
...
@@ -776,8 +776,7 @@ class category
/// @brief Return whether a row exists that matches condition @a cond
/// @brief Return whether a row exists that matches condition @a cond
/// @param cond The condition to match
/// @param cond The condition to match
/// @return True if a row exists
/// @return True if a row exists
[[
deprecated
(
"Use contains instead"
)]]
[[
deprecated
(
"Use contains instead"
)]]
bool
exists
(
condition
&&
cond
)
const
bool
exists
(
condition
&&
cond
)
const
{
{
return
contains
(
std
::
move
(
cond
));
return
contains
(
std
::
move
(
cond
));
}
}
...
@@ -941,7 +940,6 @@ class category
...
@@ -941,7 +940,6 @@ class category
/// result is unique in the context of this category
/// result is unique in the context of this category
std
::
string
get_unique_id
(
std
::
function
<
std
::
string
(
int
)
>
generator
=
cif
::
cif_id_for_number
);
std
::
string
get_unique_id
(
std
::
function
<
std
::
string
(
int
)
>
generator
=
cif
::
cif_id_for_number
);
/// @brief Generate a new, unique ID based on a string prefix followed by a number
/// @brief Generate a new, unique ID based on a string prefix followed by a number
/// @param prefix The string prefix
/// @param prefix The string prefix
/// @return a new unique ID
/// @return a new unique ID
...
@@ -1038,6 +1036,11 @@ class category
...
@@ -1038,6 +1036,11 @@ class category
return
result
;
return
result
;
}
}
/** @brief Remove column name @a colum_name
* @param column_name The column to be removed
*/
void
remove_column
(
std
::
string_view
column_name
);
/// @brief Return whether a column with name @a name exists in this category
/// @brief Return whether a column with name @a name exists in this category
/// @param name The name of the column
/// @param name The name of the column
/// @return True if the column exists
/// @return True if the column exists
...
@@ -1082,7 +1085,6 @@ class category
...
@@ -1082,7 +1085,6 @@ class category
void
write
(
std
::
ostream
&
os
,
const
std
::
vector
<
uint16_t
>
&
order
,
bool
includeEmptyColumns
)
const
;
void
write
(
std
::
ostream
&
os
,
const
std
::
vector
<
uint16_t
>
&
order
,
bool
includeEmptyColumns
)
const
;
public
:
public
:
/// friend function to make it possible to do:
/// friend function to make it possible to do:
/// @code {.cpp}
/// @code {.cpp}
/// std::cout << my_category;
/// std::cout << my_category;
...
...
src/category.cpp
View file @
f4506438
...
@@ -360,7 +360,8 @@ row *category_index::find_by_value(const category &cat, row_initializer k) const
...
@@ -360,7 +360,8 @@ row *category_index::find_by_value(const category &cat, row_initializer k) const
{
{
auto
fld
=
cat
.
get_column_name
(
f
);
auto
fld
=
cat
.
get_column_name
(
f
);
auto
ki
=
find_if
(
k
.
begin
(),
k
.
end
(),
[
&
fld
](
auto
&
i
)
{
return
i
.
name
()
==
fld
;
});
auto
ki
=
find_if
(
k
.
begin
(),
k
.
end
(),
[
&
fld
](
auto
&
i
)
{
return
i
.
name
()
==
fld
;
});
if
(
ki
==
k
.
end
())
if
(
ki
==
k
.
end
())
k2
.
emplace_back
(
fld
,
""
);
k2
.
emplace_back
(
fld
,
""
);
else
else
...
@@ -594,6 +595,25 @@ category::~category()
...
@@ -594,6 +595,25 @@ category::~category()
// --------------------------------------------------------------------
// --------------------------------------------------------------------
void
category
::
remove_column
(
std
::
string_view
column_name
)
{
for
(
size_t
ix
=
0
;
ix
<
m_columns
.
size
();
++
ix
)
{
if
(
not
iequals
(
column_name
,
m_columns
[
ix
].
m_name
))
continue
;
for
(
row
*
r
=
m_head
;
r
!=
nullptr
;
r
=
r
->
m_next
)
{
if
(
r
->
size
()
>
ix
)
r
->
erase
(
r
->
begin
()
+
ix
);
}
m_columns
.
erase
(
m_columns
.
begin
()
+
ix
);
break
;
}
}
iset
category
::
get_columns
()
const
iset
category
::
get_columns
()
const
{
{
iset
result
;
iset
result
;
...
@@ -919,7 +939,9 @@ condition category::get_parents_condition(row_handle rh, const category &parentC
...
@@ -919,7 +939,9 @@ condition category::get_parents_condition(row_handle rh, const category &parentC
condition
result
;
condition
result
;
auto
links
=
m_validator
->
get_links_for_child
(
m_name
);
auto
links
=
m_validator
->
get_links_for_child
(
m_name
);
links
.
erase
(
remove_if
(
links
.
begin
(),
links
.
end
(),
[
n
=
parentCat
.
m_name
](
auto
&
l
)
{
return
l
->
m_parent_category
!=
n
;
}),
links
.
end
());
links
.
erase
(
remove_if
(
links
.
begin
(),
links
.
end
(),
[
n
=
parentCat
.
m_name
](
auto
&
l
)
{
return
l
->
m_parent_category
!=
n
;
}),
links
.
end
());
if
(
not
links
.
empty
())
if
(
not
links
.
empty
())
{
{
...
@@ -959,7 +981,9 @@ condition category::get_children_condition(row_handle rh, const category &childC
...
@@ -959,7 +981,9 @@ condition category::get_children_condition(row_handle rh, const category &childC
mandatoryChildFields
=
childCatValidator
->
m_mandatory_fields
;
mandatoryChildFields
=
childCatValidator
->
m_mandatory_fields
;
auto
links
=
m_validator
->
get_links_for_parent
(
m_name
);
auto
links
=
m_validator
->
get_links_for_parent
(
m_name
);
links
.
erase
(
remove_if
(
links
.
begin
(),
links
.
end
(),
[
n
=
childCat
.
m_name
](
auto
&
l
)
{
return
l
->
m_child_category
!=
n
;
}),
links
.
end
());
links
.
erase
(
remove_if
(
links
.
begin
(),
links
.
end
(),
[
n
=
childCat
.
m_name
](
auto
&
l
)
{
return
l
->
m_child_category
!=
n
;
}),
links
.
end
());
if
(
not
links
.
empty
())
if
(
not
links
.
empty
())
{
{
...
@@ -1123,7 +1147,7 @@ category::iterator category::erase(iterator pos)
...
@@ -1123,7 +1147,7 @@ category::iterator category::erase(iterator pos)
return
result
;
return
result
;
}
}
template
<
typename
T
>
template
<
typename
T
>
class
save_value
class
save_value
{
{
public
:
public
:
...
@@ -1224,7 +1248,6 @@ void category::erase_orphans(condition &&cond, category &parent)
...
@@ -1224,7 +1248,6 @@ void category::erase_orphans(condition &&cond, category &parent)
std
::
cerr
<<
"Removing orphaned record:
\n
"
std
::
cerr
<<
"Removing orphaned record:
\n
"
<<
c
<<
'\n'
<<
c
<<
'\n'
<<
'\n'
;
<<
'\n'
;
}
}
remove
.
emplace_back
(
r
.
m_row
);
remove
.
emplace_back
(
r
.
m_row
);
...
@@ -1254,7 +1277,7 @@ std::string category::get_unique_id(std::function<std::string(int)> generator)
...
@@ -1254,7 +1277,7 @@ std::string category::get_unique_id(std::function<std::string(int)> generator)
for
(;;)
for
(;;)
{
{
if
(
m_index
->
find_by_value
(
*
this
,
{
{
id_tag
,
result
}
})
==
nullptr
)
if
(
m_index
->
find_by_value
(
*
this
,
{
{
id_tag
,
result
}
})
==
nullptr
)
break
;
break
;
result
=
generator
(
static_cast
<
int
>
(
m_last_unique_num
++
));
result
=
generator
(
static_cast
<
int
>
(
m_last_unique_num
++
));
}
}
...
@@ -1572,7 +1595,7 @@ row *category::clone_row(const row &r)
...
@@ -1572,7 +1595,7 @@ row *category::clone_row(const row &r)
if
(
not
i
)
if
(
not
i
)
continue
;
continue
;
result
->
append
(
ix
,
{
i
.
text
()
});
result
->
append
(
ix
,
{
i
.
text
()
});
}
}
}
}
catch
(...)
catch
(...)
...
@@ -1639,10 +1662,10 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
...
@@ -1639,10 +1662,10 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
if
(
n
==
nullptr
)
if
(
n
==
nullptr
)
throw
std
::
runtime_error
(
"Invalid pointer passed to insert"
);
throw
std
::
runtime_error
(
"Invalid pointer passed to insert"
);
// #ifndef NDEBUG
// #ifndef NDEBUG
// if (m_validator)
// if (m_validator)
// is_valid();
// is_valid();
// #endif
// #endif
try
try
{
{
...
@@ -1699,10 +1722,10 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
...
@@ -1699,10 +1722,10 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
throw
;
throw
;
}
}
// #ifndef NDEBUG
// #ifndef NDEBUG
// if (m_validator)
// if (m_validator)
// is_valid();
// is_valid();
// #endif
// #endif
}
}
void
category
::
swap_item
(
uint16_t
column_ix
,
row_handle
&
a
,
row_handle
&
b
)
void
category
::
swap_item
(
uint16_t
column_ix
,
row_handle
&
a
,
row_handle
&
b
)
...
@@ -1716,7 +1739,7 @@ void category::swap_item(uint16_t column_ix, row_handle &a, row_handle &b)
...
@@ -1716,7 +1739,7 @@ void category::swap_item(uint16_t column_ix, row_handle &a, row_handle &b)
std
::
swap
(
ra
.
at
(
column_ix
),
rb
.
at
(
column_ix
));
std
::
swap
(
ra
.
at
(
column_ix
),
rb
.
at
(
column_ix
));
}
}
void
category
::
sort
(
std
::
function
<
int
(
row_handle
,
row_handle
)
>
f
)
void
category
::
sort
(
std
::
function
<
int
(
row_handle
,
row_handle
)
>
f
)
{
{
if
(
m_head
==
nullptr
)
if
(
m_head
==
nullptr
)
return
;
return
;
...
@@ -2062,15 +2085,19 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
...
@@ -2062,15 +2085,19 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
bool
category
::
operator
==
(
const
category
&
rhs
)
const
bool
category
::
operator
==
(
const
category
&
rhs
)
const
{
{
// shortcut
if
(
this
==
&
rhs
)
return
true
;
auto
&
a
=
*
this
;
auto
&
a
=
*
this
;
auto
&
b
=
rhs
;
auto
&
b
=
rhs
;
using
namespace
std
::
placeholders
;
using
namespace
std
::
placeholders
;
// set<std::string> tagsA(a.fields()), tagsB(b.fields());
// set<std::string> tagsA(a.fields()), tagsB(b.fields());
//
//
// if (tagsA != tagsB)
// if (tagsA != tagsB)
// std::cout << "Unequal number of fields\n";
// std::cout << "Unequal number of fields\n";
const
category_validator
*
catValidator
=
nullptr
;
const
category_validator
*
catValidator
=
nullptr
;
...
@@ -2078,16 +2105,17 @@ bool category::operator==(const category &rhs) const
...
@@ -2078,16 +2105,17 @@ bool category::operator==(const category &rhs) const
if
(
validator
!=
nullptr
)
if
(
validator
!=
nullptr
)
catValidator
=
validator
->
get_validator_for_category
(
a
.
name
());
catValidator
=
validator
->
get_validator_for_category
(
a
.
name
());
typedef
std
::
function
<
int
(
std
::
string_view
,
std
::
string_view
)
>
compType
;
typedef
std
::
function
<
int
(
std
::
string_view
,
std
::
string_view
)
>
compType
;
std
::
vector
<
std
::
tuple
<
std
::
string
,
compType
>>
tags
;
std
::
vector
<
std
::
tuple
<
std
::
string
,
compType
>>
tags
;
std
::
vector
<
std
::
string
>
keys
;
std
::
vector
<
std
::
string
>
keys
;
std
::
vector
<
size_t
>
keyIx
;
std
::
vector
<
size_t
>
keyIx
;
if
(
catValidator
==
nullptr
)
if
(
catValidator
==
nullptr
)
{
{
for
(
auto
&
tag
:
a
.
get_columns
())
for
(
auto
&
tag
:
a
.
get_columns
())
{
{
tags
.
push_back
(
std
::
make_tuple
(
tag
,
[](
std
::
string_view
va
,
std
::
string_view
vb
)
{
return
va
.
compare
(
vb
);
}));
tags
.
push_back
(
std
::
make_tuple
(
tag
,
[](
std
::
string_view
va
,
std
::
string_view
vb
)
{
return
va
.
compare
(
vb
);
}));
keyIx
.
push_back
(
keys
.
size
());
keyIx
.
push_back
(
keys
.
size
());
keys
.
push_back
(
tag
);
keys
.
push_back
(
tag
);
}
}
...
@@ -2096,7 +2124,7 @@ bool category::operator==(const category &rhs) const
...
@@ -2096,7 +2124,7 @@ bool category::operator==(const category &rhs) const
{
{
keys
=
catValidator
->
m_keys
;
keys
=
catValidator
->
m_keys
;
for
(
auto
&
tag
:
a
.
key_fields
())
for
(
auto
&
tag
:
a
.
key_fields
())
{
{
auto
iv
=
catValidator
->
get_validator_for_item
(
tag
);
auto
iv
=
catValidator
->
get_validator_for_item
(
tag
);
if
(
iv
==
nullptr
)
if
(
iv
==
nullptr
)
...
@@ -2106,7 +2134,10 @@ bool category::operator==(const category &rhs) const
...
@@ -2106,7 +2134,10 @@ bool category::operator==(const category &rhs) const
throw
std
::
runtime_error
(
"missing type validator"
);
throw
std
::
runtime_error
(
"missing type validator"
);
tags
.
push_back
(
std
::
make_tuple
(
tag
,
std
::
bind
(
&
cif
::
type_validator
::
compare
,
tv
,
std
::
placeholders
::
_1
,
std
::
placeholders
::
_2
)));
tags
.
push_back
(
std
::
make_tuple
(
tag
,
std
::
bind
(
&
cif
::
type_validator
::
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
())
if
(
find_if
(
keys
.
begin
(),
keys
.
end
(),
pred
)
==
keys
.
end
())
keyIx
.
push_back
(
tags
.
size
()
-
1
);
keyIx
.
push_back
(
tags
.
size
()
-
1
);
}
}
...
@@ -2115,11 +2146,11 @@ bool category::operator==(const category &rhs) const
...
@@ -2115,11 +2146,11 @@ bool category::operator==(const category &rhs) const
// a.reorderByIndex();
// a.reorderByIndex();
// b.reorderByIndex();
// b.reorderByIndex();
auto
rowEqual
=
[
&
](
const
row_handle
&
a
,
const
row_handle
&
b
)
auto
rowEqual
=
[
&
](
const
row_handle
&
a
,
const
row_handle
&
b
)
{
{
int
d
=
0
;
int
d
=
0
;
for
(
auto
kix
:
keyIx
)
for
(
auto
kix
:
keyIx
)
{
{
std
::
string
tag
;
std
::
string
tag
;
compType
compare
;
compType
compare
;
...
@@ -2148,7 +2179,7 @@ bool category::operator==(const category &rhs) const
...
@@ -2148,7 +2179,7 @@ bool category::operator==(const category &rhs) const
std
::
vector
<
std
::
string
>
missingA
,
missingB
,
different
;
std
::
vector
<
std
::
string
>
missingA
,
missingB
,
different
;
for
(
auto
&
tt
:
tags
)
for
(
auto
&
tt
:
tags
)
{
{
std
::
string
tag
;
std
::
string
tag
;
compType
compare
;
compType
compare
;
...
@@ -2157,8 +2188,12 @@ bool category::operator==(const category &rhs) const
...
@@ -2157,8 +2188,12 @@ bool category::operator==(const category &rhs) const
// make it an option to compare unapplicable to empty or something
// make it an option to compare unapplicable to empty or something
auto
ta
=
ra
[
tag
].
text
();
if
(
ta
==
"."
or
ta
==
"?"
)
ta
=
""
;
auto
ta
=
ra
[
tag
].
text
();
auto
tb
=
rb
[
tag
].
text
();
if
(
tb
==
"."
or
tb
==
"?"
)
tb
=
""
;
if
(
ta
==
"."
or
ta
==
"?"
)
ta
=
""
;
auto
tb
=
rb
[
tag
].
text
();
if
(
tb
==
"."
or
tb
==
"?"
)
tb
=
""
;
if
(
compare
(
ta
,
tb
)
!=
0
)
if
(
compare
(
ta
,
tb
)
!=
0
)
return
false
;
return
false
;
...
...
src/datablock.cpp
View file @
f4506438
...
@@ -374,6 +374,10 @@ void datablock::write(std::ostream &os, const std::vector<std::string> &tag_orde
...
@@ -374,6 +374,10 @@ void datablock::write(std::ostream &os, const std::vector<std::string> &tag_orde
bool
datablock
::
operator
==
(
const
datablock
&
rhs
)
const
bool
datablock
::
operator
==
(
const
datablock
&
rhs
)
const
{
{
// shortcut
if
(
this
==
&
rhs
)
return
true
;
auto
&
dbA
=
*
this
;
auto
&
dbA
=
*
this
;
auto
&
dbB
=
rhs
;
auto
&
dbB
=
rhs
;
...
...
src/pdb/reconstruct.cpp
View file @
f4506438
...
@@ -239,13 +239,12 @@ void checkAtomRecords(datablock &db)
...
@@ -239,13 +239,12 @@ void checkAtomRecords(datablock &db)
// Rewrite the coordinates and other fields that look better in a fixed format
// Rewrite the coordinates and other fields that look better in a fixed format
// Be careful not to nuke invalidly formatted data here
// Be careful not to nuke invalidly formatted data here
for
(
auto
[
tag
,
prec
]
:
std
::
vector
<
std
::
tuple
<
std
::
string_view
,
std
::
string
::
size_type
>>
{
for
(
auto
[
tag
,
prec
]
:
std
::
vector
<
std
::
tuple
<
std
::
string_view
,
std
::
string
::
size_type
>>
{
{
"cartn_x"
,
3
},
{
"cartn_x"
,
3
},
{
"cartn_y"
,
3
},
{
"cartn_y"
,
3
},
{
"cartn_z"
,
3
},
{
"cartn_z"
,
3
},
{
"occupancy"
,
2
},
{
"occupancy"
,
2
},
{
"b_iso_or_equiv"
,
2
}
{
"b_iso_or_equiv"
,
2
}
})
})
{
{
if
(
row
[
tag
].
empty
())
if
(
row
[
tag
].
empty
())
continue
;
continue
;
...
@@ -260,10 +259,32 @@ void checkAtomRecords(datablock &db)
...
@@ -260,10 +259,32 @@ void checkAtomRecords(datablock &db)
char
b
[
12
];
char
b
[
12
];
if
(
auto
[
ptr
,
ec
]
=
cif
::
to_chars
(
b
,
b
+
sizeof
(
b
),
v
,
cif
::
chars_format
::
fixed
,
prec
);
ec
==
std
::
errc
())
if
(
auto
[
ptr
,
ec
]
=
cif
::
to_chars
(
b
,
b
+
sizeof
(
b
),
v
,
cif
::
chars_format
::
fixed
,
prec
);
ec
==
std
::
errc
())
row
.
assign
(
tag
,
{
b
,
static_cast
<
std
::
string
::
size_type
>
(
ptr
-
b
)
},
false
,
false
);
row
.
assign
(
tag
,
{
b
,
static_cast
<
std
::
string
::
size_type
>
(
ptr
-
b
)
},
false
,
false
);
}
}
}
}
}
}
auto
*
cv
=
atom_site
.
get_cat_validator
();
if
(
cv
)
{
// See if there are columns that are no longer known
for
(
auto
tag
:
atom_site
.
get_columns
())
{
if
(
cv
->
get_validator_for_item
(
tag
)
!=
nullptr
)
continue
;
auto
r
=
atom_site
.
find_first
(
key
(
tag
)
!=
null
);
if
(
not
r
)
{
if
(
cif
::
VERBOSE
>
0
)
std
::
clog
<<
"Dropping unknown column "
<<
tag
<<
'\n'
;
atom_site
.
remove_column
(
tag
);
}
else
if
(
cif
::
VERBOSE
>
0
)
std
::
clog
<<
"Keeping unknown column "
<<
std
::
quoted
(
tag
)
<<
" in atom_site since it is not empty
\n
"
;
}
}
}
}
void
createStructAsym
(
datablock
&
db
)
void
createStructAsym
(
datablock
&
db
)
...
@@ -662,6 +683,9 @@ void comparePolySeqSchemes(datablock &db)
...
@@ -662,6 +683,9 @@ void comparePolySeqSchemes(datablock &db)
}
}
}
}
}
}
if
(
ndb_poly_seq_scheme
.
empty
())
db
.
erase
(
std
::
remove
(
db
.
begin
(),
db
.
end
(),
ndb_poly_seq_scheme
),
db
.
end
());
}
}
void
reconstruct_pdbx
(
file
&
file
,
std
::
string_view
dictionary
)
void
reconstruct_pdbx
(
file
&
file
,
std
::
string_view
dictionary
)
...
...
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