Commit 51b6c7eb by maarten

meer snelheid

git-svn-id: svn+ssh://gitlab/srv/svn-repos/pdb-redo/trunk@345 a1961a4f-ab94-4bcc-80e8-33b5a54de466
parent 1cf8e7b7
...@@ -46,9 +46,10 @@ class DistanceMap ...@@ -46,9 +46,10 @@ class DistanceMap
} }
}; };
std::unordered_map<std::tuple<size_t,size_t>,std::tuple<float,size_t>,key_hash> dist; std::vector<std::tuple<float,size_t>> mA;
Point mD; // needed to move atoms to center std::vector<size_t> mIA, mJA;
std::vector<clipper::RTop_orth> mRtOrth; Point mD; // needed to move atoms to center
std::vector<clipper::RTop_orth> mRtOrth;
}; };
} }
...@@ -389,12 +389,14 @@ class Structure ...@@ -389,12 +389,14 @@ class Structure
cif::Datablock& datablock() const; cif::Datablock& datablock() const;
void insertCompound(const std::string& compoundID, bool isEntity); void insertCompound(const std::string& compoundID, bool isEntity);
void updateAtomIndex();
File& mFile; File& mFile;
uint32 mModelNr; uint32 mModelNr;
AtomView mAtoms; AtomView mAtoms;
std::vector<size_t> mAtomIndex;
std::list<Polymer> mPolymers; std::list<Polymer> mPolymers;
// std::vector<Residue*> mResidues;
}; };
} }
...@@ -130,9 +130,6 @@ DistanceMap::DistanceMap(const Structure& p, const clipper::Spacegroup& spacegro ...@@ -130,9 +130,6 @@ DistanceMap::DistanceMap(const Structure& p, const clipper::Spacegroup& spacegro
mD.mY = calculateD(my, cell.b()); mD.mY = calculateD(my, cell.b());
mD.mZ = calculateD(mz, cell.c()); mD.mZ = calculateD(mz, cell.c());
if (VERBOSE)
cerr << "Calculated d: " << mD.mX << ", " << mD.mY << " and " << mD.mZ << endl;
if (mD.mX != 0 or mD.mY != 0 or mD.mZ != 0) if (mD.mX != 0 or mD.mY != 0 or mD.mZ != 0)
{ {
if (VERBOSE) if (VERBOSE)
...@@ -153,6 +150,8 @@ DistanceMap::DistanceMap(const Structure& p, const clipper::Spacegroup& spacegro ...@@ -153,6 +150,8 @@ DistanceMap::DistanceMap(const Structure& p, const clipper::Spacegroup& spacegro
atomic<size_t> next(0); atomic<size_t> next(0);
mutex m; mutex m;
map<tuple<size_t,size_t>,tuple<float,size_t>> dist;
for (size_t i = 0; i < N; ++i) for (size_t i = 0; i < N; ++i)
t.create_thread([&]() t.create_thread([&]()
{ {
...@@ -185,13 +184,6 @@ DistanceMap::DistanceMap(const Structure& p, const clipper::Spacegroup& spacegro ...@@ -185,13 +184,6 @@ DistanceMap::DistanceMap(const Structure& p, const clipper::Spacegroup& spacegro
minR2 = r2; minR2 = r2;
kb = k; kb = k;
} }
#if defined(DEBUG_VOOR_BART)
if (r2 < 3.5 * 3.5 and not rt.equals(clipper::RTop<>::identity(), 0.1))
cout << "symmetry contact between "
<< atoms[i] << " at " << pi << " and "
<< atoms[j] << " at " << pj << endl;
#endif
} }
if (minR2 < kMaxDistanceSQ) if (minR2 < kMaxDistanceSQ)
...@@ -209,27 +201,107 @@ DistanceMap::DistanceMap(const Structure& p, const clipper::Spacegroup& spacegro ...@@ -209,27 +201,107 @@ DistanceMap::DistanceMap(const Structure& p, const clipper::Spacegroup& spacegro
}); });
t.join_all(); t.join_all();
}
// Store as a sparse CSR compressed matrix
size_t nnz = dist.size();
mA.reserve(nnz);
mIA.reserve(dim + 1);
mJA.reserve(nnz);
size_t lastR = 0;
mIA.push_back(0);
for (auto& di: dist)
{
size_t c, r;
tie(r, c) = di.first;
if (r != lastR) // new row
{
for (size_t ri = lastR; ri < r; ++ri)
mIA.push_back(mA.size());
lastR = r;
}
mA.push_back(di.second);
mJA.push_back(c);
}
for (size_t ri = lastR; ri < dim; ++ri)
mIA.push_back(mA.size());
//DistanceMap::DistanceMap(const Structure& p, const vector<Atom>& atoms) //// debug code
// : structure(p), dim(0) //
//{ // assert(mIA.size() == dim + 1);
// dim = atoms.size(); // assert(mA.size() == nnz);
// assert(mJA.size() == nnz);
//
//cerr << "nnz: " << nnz << endl;
// //
// for (auto& atom: atoms) // auto get = [&](size_t i, size_t j)
// { // {
// size_t ix = index.size(); // if (i > j)
// index[atom.id()] = ix; // std::swap(i, j);
//
// for (size_t cix = mIA[i]; cix < mIA[i + 1]; ++cix)
// {
// if (mJA[cix] == j)
// return std::get<0>(mA[cix]);
// }
//
// return 100.f;
// }; // };
//
// auto get2 = [&](size_t ixa, size_t ixb)
// {
// if (ixb < ixa)
// std::swap(ixa, ixb);
//
// int32 L = mIA[ixa];
// int32 R = mIA[ixa + 1] - 1;
//
// while (L <= R)
// {
// int32 i = (L + R) / 2;
//
// if (mJA[i] == ixb)
// return std::get<0>(mA[i]);
//
// if (mJA[i] < ixb)
// L = i + 1;
// else
// R = i - 1;
// }
// //
// return 100.f;
// };
//
// // test all values
// for (size_t i = 0; i < dim; ++i) // for (size_t i = 0; i < dim; ++i)
// { // for (size_t j = 0; j < dim; ++j)
// for (size_t j = i + 1; j < dim; ++j)
// { // {
// dist[make_tuple(i, j)] = Distance(atoms[i].location(), atoms[j].location()); // float a = get(i, j);
//
// auto ixa = i, ixb = j;
// if (ixb < ixa)
// std::swap(ixa, ixb);
//
// tuple<size_t,size_t> k{ ixa, ixb };
//
// auto ii = dist.find(k);
//
// float b = 100;
//
// if (ii != dist.end())
// b = std::get<0>(ii->second);
//
// assert(a == b);
//
// float c = get2(i, j);
// assert(a == c);
// } // }
// } }
//}
float DistanceMap::operator()(const Atom& a, const Atom& b) const float DistanceMap::operator()(const Atom& a, const Atom& b) const
{ {
...@@ -255,23 +327,28 @@ float DistanceMap::operator()(const Atom& a, const Atom& b) const ...@@ -255,23 +327,28 @@ float DistanceMap::operator()(const Atom& a, const Atom& b) const
if (ixb < ixa) if (ixb < ixa)
std::swap(ixa, ixb); std::swap(ixa, ixb);
size_t L = mIA[ixa];
size_t R = mIA[ixa + 1] - 1;
tuple<size_t,size_t> k{ ixa, ixb }; while (L <= R)
{
size_t i = (L + R) / 2;
auto ii = dist.find(k); if (mJA[i] == ixb)
return get<0>(mA[i]);
float result = 100; if (mJA[i] < ixb)
L = i + 1;
if (ii != dist.end()) else
result = get<0>(ii->second); R = i - 1;
}
return result; return 100.f;
} }
vector<Atom> DistanceMap::near(const Atom& a, float maxDistance) const vector<Atom> DistanceMap::near(const Atom& a, float maxDistance) const
{ {
vector<Atom> result;
size_t ixa; size_t ixa;
try try
{ {
...@@ -282,27 +359,43 @@ vector<Atom> DistanceMap::near(const Atom& a, float maxDistance) const ...@@ -282,27 +359,43 @@ vector<Atom> DistanceMap::near(const Atom& a, float maxDistance) const
throw runtime_error("atom " + a.id() + " not found in distance map"); throw runtime_error("atom " + a.id() + " not found in distance map");
} }
for (auto& di: dist) set<tuple<size_t,size_t>> bix;
for (size_t bi = mIA[ixa]; bi < mIA[ixa + 1]; ++bi)
{ {
size_t dixa, dixb; float d;
tie(dixa, dixb) = di.first;
if (dixa != ixa and dixb != ixa)
continue;
float distance;
size_t rti; size_t rti;
tie(distance, rti) = di.second; tie(d, rti) = mA[bi];
if (d <= maxDistance)
if (distance > maxDistance) bix.insert(make_tuple(mJA[bi], rti));
continue; }
size_t ixb = dixa; for (size_t i = 0; i + 1 < dim; ++i)
if (ixb == ixa) {
ixb = dixb; for (size_t j = mIA[i]; j < mIA[i + 1]; ++j)
{
Atom a = structure.getAtomById(rIndex.at(ixb)); if (mJA[j] != ixa)
continue;
float d;
size_t rti;
tie(d, rti) = mA[j];
if (d > maxDistance)
continue;
bix.insert(make_tuple(i, rti));
}
}
vector<Atom> result;
result.reserve(bix.size());
for (auto& i: bix)
{
size_t ix, rti;
tie(ix, rti) = i;
Atom a = structure.getAtomById(rIndex.at(ix));
result.push_back(a.symmetryCopy(mD, mRtOrth.at(rti))); result.push_back(a.symmetryCopy(mD, mRtOrth.at(rti)));
} }
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#include "cif++/Structure.h" #include "cif++/Structure.h"
#include <numeric>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/iostreams/filtering_stream.hpp> #include <boost/iostreams/filtering_stream.hpp>
...@@ -1259,6 +1261,8 @@ Structure::Structure(File& f, uint32 modelNr) ...@@ -1259,6 +1261,8 @@ Structure::Structure(File& f, uint32 modelNr)
// sort(mAtoms.begin(), mAtoms.end(), [](auto& a, auto& b) { return a.id() < b.id(); }); // sort(mAtoms.begin(), mAtoms.end(), [](auto& a, auto& b) { return a.id() < b.id(); });
updateAtomIndex();
// polymers // polymers
auto& polySeqScheme = category("pdbx_poly_seq_scheme"); auto& polySeqScheme = category("pdbx_poly_seq_scheme");
...@@ -1280,6 +1284,8 @@ Structure::Structure(const Structure& s) ...@@ -1280,6 +1284,8 @@ Structure::Structure(const Structure& s)
for (auto& atom: s.mAtoms) for (auto& atom: s.mAtoms)
mAtoms.emplace_back(atom.clone()); mAtoms.emplace_back(atom.clone());
updateAtomIndex();
auto& polySeqScheme = category("pdbx_poly_seq_scheme"); auto& polySeqScheme = category("pdbx_poly_seq_scheme");
for (auto& r: polySeqScheme) for (auto& r: polySeqScheme)
...@@ -1297,6 +1303,15 @@ Structure::~Structure() ...@@ -1297,6 +1303,15 @@ Structure::~Structure()
{ {
} }
void Structure::updateAtomIndex()
{
mAtomIndex = vector<size_t>(mAtoms.size());
iota(mAtomIndex.begin(), mAtomIndex.end(), 0);
sort(mAtomIndex.begin(), mAtomIndex.end(), [this](size_t a, size_t b) { return mAtoms[a].id() < mAtoms[b].id(); });
}
const AtomView& Structure::atoms() const const AtomView& Structure::atoms() const
{ {
return mAtoms; return mAtoms;
...@@ -1357,16 +1372,16 @@ vector<Residue> Structure::nonPolymers() const ...@@ -1357,16 +1372,16 @@ vector<Residue> Structure::nonPolymers() const
Atom Structure::getAtomById(string id) const Atom Structure::getAtomById(string id) const
{ {
// auto i = lower_bound(mAtoms.begin(), mAtoms.end(), auto i = lower_bound(mAtomIndex.begin(), mAtomIndex.end(),
// id, [](auto& a, auto& b) { return a.id() < b; }); id, [this](auto& a, auto& b) { return mAtoms[a].id() < b; });
auto i = find_if(mAtoms.begin(), mAtoms.end(), // auto i = find_if(mAtoms.begin(), mAtoms.end(),
[&id](auto& a) { return a.id() == id; }); // [&id](auto& a) { return a.id() == id; });
if (i == mAtoms.end() or i->id() != id) if (i == mAtomIndex.end() or mAtoms[*i].id() != id)
throw out_of_range("Could not find atom with id " + id); throw out_of_range("Could not find atom with id " + id);
return *i; return mAtoms[*i];
} }
File& Structure::getFile() const File& Structure::getFile() const
...@@ -1580,6 +1595,8 @@ void Structure::removeAtom(Atom& a) ...@@ -1580,6 +1595,8 @@ void Structure::removeAtom(Atom& a)
} }
mAtoms.erase(remove(mAtoms.begin(), mAtoms.end(), a), mAtoms.end()); mAtoms.erase(remove(mAtoms.begin(), mAtoms.end(), a), mAtoms.end());
updateAtomIndex();
} }
void Structure::swapAtoms(Atom& a1, Atom& a2) void Structure::swapAtoms(Atom& a1, Atom& a2)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment