Commit af930b23 by maarten

aniso density calculation

git-svn-id: svn+ssh://gitlab/srv/svn-repos/pdb-redo/trunk@300 a1961a4f-ab94-4bcc-80e8-33b5a54de466
parent 8047cda0
...@@ -25,6 +25,7 @@ class AtomShape ...@@ -25,6 +25,7 @@ class AtomShape
float radius() const; float radius() const;
float calculatedDensity(float r) const; float calculatedDensity(float r) const;
float calculatedDensity(Point p) const;
private: private:
struct AtomShapeImpl* mImpl; struct AtomShapeImpl* mImpl;
......
...@@ -101,6 +101,7 @@ class Atom ...@@ -101,6 +101,7 @@ class Atom
int charge() const; int charge() const;
float uIso() const; float uIso() const;
bool getAnisoU(float anisou[6]) const;
float occupancy() const; float occupancy() const;
template<typename T> template<typename T>
......
...@@ -328,10 +328,11 @@ double DensityIntegration::integrateRadius(float perc, float occupancy, double y ...@@ -328,10 +328,11 @@ double DensityIntegration::integrateRadius(float perc, float occupancy, double y
struct AtomShapeImpl struct AtomShapeImpl
{ {
AtomShapeImpl(AtomType symbol, int charge, float uIso, float occupancy, float resHigh, float resLow, bool electronScattering) AtomShapeImpl(Point location, AtomType symbol, int charge, float uIso, float occupancy, float resHigh, float resLow, bool electronScattering)
: mSymbol(symbol), mCharge(charge), mUIso(uIso), mOccupancy(occupancy) : mSymbol(symbol), mCharge(charge), mUIso(uIso), mOccupancy(occupancy)
, mResHigh(resHigh), mResLow(resLow) , mResHigh(resHigh), mResLow(resLow)
, mElectronScattering(electronScattering) , mElectronScattering(electronScattering)
, mLocation(location)
, mIntegrator(DensityIntegration::instance(resLow, resHigh)) , mIntegrator(DensityIntegration::instance(resLow, resHigh))
{ {
auto st = mIntegrator.st(); auto st = mIntegrator.st();
...@@ -373,11 +374,14 @@ struct AtomShapeImpl ...@@ -373,11 +374,14 @@ struct AtomShapeImpl
} }
} }
virtual ~AtomShapeImpl() {}
AtomType mSymbol; AtomType mSymbol;
int mCharge; int mCharge;
float mUIso, mOccupancy; float mUIso, mOccupancy;
float mResHigh, mResLow; float mResHigh, mResLow;
bool mElectronScattering; bool mElectronScattering;
Point mLocation;
const DensityIntegration& mIntegrator; const DensityIntegration& mIntegrator;
double mYi; double mYi;
...@@ -393,7 +397,7 @@ struct AtomShapeImpl ...@@ -393,7 +397,7 @@ struct AtomShapeImpl
return result; return result;
} }
float calculatedDensity(float r) const virtual float calculatedDensity(float r) const
{ {
float rsq = r * r; float rsq = r * r;
return mOccupancy * return mOccupancy *
...@@ -403,18 +407,82 @@ struct AtomShapeImpl ...@@ -403,18 +407,82 @@ struct AtomShapeImpl
mAW[4] * exp(mBW[4] * rsq) + mAW[5] * exp(mBW[5] * rsq) mAW[4] * exp(mBW[4] * rsq) + mAW[5] * exp(mBW[5] * rsq)
); );
} }
virtual float calculatedDensity(Point p) const
{
return calculatedDensity(Distance(mLocation, p));
}
};
struct AtomShapeAnisoImpl : public AtomShapeImpl
{
AtomShapeAnisoImpl(Point location, AtomType symbol, int charge, clipper::U_aniso_orth& anisou, float occupancy, float resHigh, float resLow, bool electronScattering)
: AtomShapeImpl(location, symbol, charge, anisou.u_iso(), occupancy, resHigh, resLow, electronScattering)
, mAnisoU(anisou)
{
auto& D =
mElectronScattering ? AtomTypeTraits(symbol).elsf() : AtomTypeTraits(symbol).wksf(charge);
const float fourpi2 = 4 * kPI * kPI;
const float pi3 = kPI * kPI * kPI;
for (int i = 0; i < 6; ++i)
{
mAnisoInv[i] = clipper::Mat33sym<>(
-2 * mAnisoU.mat00() - D.b[i] / fourpi2,
-2 * mAnisoU.mat11() - D.b[i] / fourpi2,
-2 * mAnisoU.mat22() - D.b[i] / fourpi2,
-2 * mAnisoU.mat01(),
-2 * mAnisoU.mat02(),
-2 * mAnisoU.mat12()).inverse();
double det = - mAnisoInv[i].det();
mAW[i] = D.a[i] * sqrt(det / pi3);
mBW[i] = -pow(det, 1.0/3);
}
}
virtual float calculatedDensity(Point p) const
{
const clipper::Coord_orth dxyz(p - mLocation);
return mOccupancy *
(
mAW[0] * exp(mAnisoInv[0].quad_form(dxyz)) +
mAW[1] * exp(mAnisoInv[1].quad_form(dxyz)) +
mAW[2] * exp(mAnisoInv[2].quad_form(dxyz)) +
mAW[3] * exp(mAnisoInv[3].quad_form(dxyz)) +
mAW[4] * exp(mAnisoInv[4].quad_form(dxyz)) +
mAW[5] * exp(mAnisoInv[5].quad_form(dxyz))
);
}
clipper::U_aniso_orth mAnisoU;
array<clipper::Mat33sym<>,6> mAnisoInv;
}; };
// -------------------------------------------------------------------- // --------------------------------------------------------------------
AtomShape::AtomShape(const Atom& atom, float resHigh, float resLow, bool electronScattering) AtomShape::AtomShape(const Atom& atom, float resHigh, float resLow, bool electronScattering)
: mImpl(new AtomShapeImpl(atom.type(), atom.charge(), atom.uIso(), : mImpl(nullptr)
atom.occupancy(), resHigh, resLow, electronScattering))
{ {
float anisou[6];
if (atom.getAnisoU(anisou))
{
clipper::U_aniso_orth u(anisou[0], anisou[3], anisou[5], anisou[1], anisou[2], anisou[4]);
while (u.det() < 1.0e-20)
u = u + clipper::U_aniso_orth(0.01, 0.01, 0.01, 0, 0, 0);
mImpl = new AtomShapeAnisoImpl(atom.location(), atom.type(), atom.charge(), u, atom.occupancy(), resHigh, resLow, electronScattering);
}
else
mImpl = new AtomShapeImpl(atom.location(), atom.type(), atom.charge(), atom.uIso(), atom.occupancy(), resHigh, resLow, electronScattering);
} }
AtomShape::AtomShape(const Atom& atom, float resHigh, float resLow, bool electronScattering, float bFactor) AtomShape::AtomShape(const Atom& atom, float resHigh, float resLow, bool electronScattering, float bFactor)
: mImpl(new AtomShapeImpl(atom.type(), atom.charge(), clipper::Util::b2u(bFactor), : mImpl(new AtomShapeImpl(atom.location(), atom.type(), atom.charge(), clipper::Util::b2u(bFactor),
1.0, resHigh, resLow, electronScattering)) 1.0, resHigh, resLow, electronScattering))
{ {
} }
...@@ -434,4 +502,9 @@ float AtomShape::calculatedDensity(float r) const ...@@ -434,4 +502,9 @@ float AtomShape::calculatedDensity(float r) const
return mImpl->calculatedDensity(r); return mImpl->calculatedDensity(r);
} }
float AtomShape::calculatedDensity(Point p) const
{
return mImpl->calculatedDensity(p);
}
} }
...@@ -240,6 +240,23 @@ struct AtomImpl ...@@ -240,6 +240,23 @@ struct AtomImpl
delete this; delete this;
} }
bool getAnisoU(float anisou[6]) const
{
auto& db = *mFile.impl().mDb;
auto& cat = db["atom_site_anisotrop"];
auto r = cat[cif::Key("id") == mId];
bool result = false;
if (not r.empty())
{
result = true;
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]");
}
return result;
}
void moveTo(const Point& p) void moveTo(const Point& p)
{ {
// mRow["Cartn_x"] = p.getX(); // mRow["Cartn_x"] = p.getX();
...@@ -411,6 +428,11 @@ float Atom::uIso() const ...@@ -411,6 +428,11 @@ float Atom::uIso() const
return result; return result;
} }
bool Atom::getAnisoU(float anisou[6]) const
{
return mImpl->getAnisoU(anisou);
}
float Atom::occupancy() const float Atom::occupancy() const
{ {
return property<float>("occupancy"); return property<float>("occupancy");
......
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