Commit 1a8d585b by maarten

betere validatie

git-svn-id: svn+ssh://gitlab/srv/svn-repos/pdb-redo/trunk@252 a1961a4f-ab94-4bcc-80e8-33b5a54de466
parent d4de02a2
...@@ -206,7 +206,7 @@ class Datablock ...@@ -206,7 +206,7 @@ class Datablock
std::tuple<iterator,bool> emplace(const std::string& name); std::tuple<iterator,bool> emplace(const std::string& name);
void validate(); bool isValid();
void setValidator(Validator* v); void setValidator(Validator* v);
// this one only looks up a Category, returns nullptr if it does not exist // this one only looks up a Category, returns nullptr if it does not exist
...@@ -1004,7 +1004,7 @@ class Category ...@@ -1004,7 +1004,7 @@ class Category
void erase(Row r); void erase(Row r);
void erase(iterator ri); void erase(iterator ri);
void validate(); bool isValid();
const Validator& getValidator() const; const Validator& getValidator() const;
const ValidateCategory* getCatValidator() const { return mCatValidator; } const ValidateCategory* getCatValidator() const { return mCatValidator; }
...@@ -1074,7 +1074,7 @@ class File ...@@ -1074,7 +1074,7 @@ class File
void loadDictionary(const char* dict); // load one of the compiled in dictionaries void loadDictionary(const char* dict); // load one of the compiled in dictionaries
void loadDictionary(std::istream& is); // load dictionary from input stream void loadDictionary(std::istream& is); // load dictionary from input stream
void validate(); bool isValid();
Datablock& firstDatablock() { return *mHead; } Datablock& firstDatablock() { return *mHead; }
void append(Datablock* e); void append(Datablock* e);
......
...@@ -115,9 +115,19 @@ struct Point ...@@ -115,9 +115,19 @@ struct Point
return clipper::Coord_orth(mX, mY, mZ); return clipper::Coord_orth(mX, mY, mZ);
} }
operator std::tuple<float,float,float>() const operator std::tuple<const float&, const float&, const float&>() const
{ {
return std::make_tuple(mX, mY, mZ); return std::make_tuple(std::ref(mX), std::ref(mY), std::ref(mZ));
}
operator std::tuple<float&,float&,float&>()
{
return std::make_tuple(std::ref(mX), std::ref(mY), std::ref(mZ));
}
bool operator==(const Point& rhs) const
{
return mX == rhs.mX and mY == rhs.mY and mZ == rhs.mZ;
} }
}; };
......
...@@ -346,13 +346,15 @@ Category* Datablock::get(const string& name) ...@@ -346,13 +346,15 @@ Category* Datablock::get(const string& name)
return i == end() ? nullptr : &*i; return i == end() ? nullptr : &*i;
} }
void Datablock::validate() bool Datablock::isValid()
{ {
if (mValidator == nullptr) if (mValidator == nullptr)
throw runtime_error("Validator not specified"); throw runtime_error("Validator not specified");
bool result = true;
for (auto& cat: *this) for (auto& cat: *this)
cat.validate(); result = cat.isValid() and result;
return result;
} }
void Datablock::setValidator(Validator* v) void Datablock::setValidator(Validator* v)
...@@ -598,7 +600,7 @@ class CatIndex ...@@ -598,7 +600,7 @@ class CatIndex
} }
size_t size() const; size_t size() const;
void validate() const; // bool isValid() const;
private: private:
...@@ -622,7 +624,7 @@ class CatIndex ...@@ -622,7 +624,7 @@ class CatIndex
entry* insert(entry* h, ItemRow* v); entry* insert(entry* h, ItemRow* v);
entry* erase(entry* h, ItemRow* k); entry* erase(entry* h, ItemRow* k);
void validate(entry* h, bool isParentRed, uint32 blackDepth, uint32& minBlack, uint32& maxBlack) const; // void validate(entry* h, bool isParentRed, uint32 blackDepth, uint32& minBlack, uint32& maxBlack) const;
entry* rotateLeft(entry* h) entry* rotateLeft(entry* h)
{ {
...@@ -961,64 +963,70 @@ size_t CatIndex::size() const ...@@ -961,64 +963,70 @@ size_t CatIndex::size() const
return result; return result;
} }
void CatIndex::validate() const //bool CatIndex::isValid() const
{ //{
if (mRoot != nullptr) // bool result = true;
{ //
uint32 minBlack = numeric_limits<uint32>::max(); // if (mRoot != nullptr)
uint32 maxBlack = 0; // {
// uint32 minBlack = numeric_limits<uint32>::max();
assert(not mRoot->mRed); // uint32 maxBlack = 0;
//
validate(mRoot, false, 0, minBlack, maxBlack); // assert(not mRoot->mRed);
assert(minBlack == maxBlack); //
} // result = isValid(mRoot, false, 0, minBlack, maxBlack);
} // assert(minBlack == maxBlack);
// }
void CatIndex::validate(entry* h, bool isParentRed, uint32 blackDepth, uint32& minBlack, uint32& maxBlack) const //
{ // return result;
if (h->mRed) //}
assert(not isParentRed); //
else //bool CatIndex::validate(entry* h, bool isParentRed, uint32 blackDepth, uint32& minBlack, uint32& maxBlack) const
++blackDepth; //{
// bool result = true;
if (isParentRed) //
assert(not h->mRed); // if (h->mRed)
// assert(not isParentRed);
if (h->mLeft != nullptr and h->mRight != nullptr) // else
{ // ++blackDepth;
if (isRed(h->mLeft)) //
assert(not isRed(h->mRight)); // if (isParentRed)
if (isRed(h->mRight)) // assert(not h->mRed);
assert(not isRed(h->mLeft)); //
} // if (h->mLeft != nullptr and h->mRight != nullptr)
// {
if (h->mLeft != nullptr) // if (isRed(h->mLeft))
{ // assert(not isRed(h->mRight));
assert(mComp(h->mLeft->mRow, h->mRow) < 0); // if (isRed(h->mRight))
validate(h->mLeft, h->mRed, blackDepth, minBlack, maxBlack); // assert(not isRed(h->mLeft));
} // }
else //
{ // if (h->mLeft != nullptr)
if (minBlack > blackDepth) // {
minBlack = blackDepth; // assert(mComp(h->mLeft->mRow, h->mRow) < 0);
if (maxBlack < blackDepth) // validate(h->mLeft, h->mRed, blackDepth, minBlack, maxBlack);
maxBlack = blackDepth; // }
} // else
// {
if (h->mRight != nullptr) // if (minBlack > blackDepth)
{ // minBlack = blackDepth;
assert(mComp(h->mRight->mRow, h->mRow) > 0); // if (maxBlack < blackDepth)
validate(h->mRight, h->mRight, blackDepth, minBlack, maxBlack); // maxBlack = blackDepth;
} // }
else //
{ // if (h->mRight != nullptr)
if (minBlack > blackDepth) // {
minBlack = blackDepth; // assert(mComp(h->mRight->mRow, h->mRow) > 0);
if (maxBlack < blackDepth) // validate(h->mRight, h->mRight, blackDepth, minBlack, maxBlack);
maxBlack = blackDepth; // }
} // else
} // {
// if (minBlack > blackDepth)
// minBlack = blackDepth;
// if (maxBlack < blackDepth)
// maxBlack = blackDepth;
// }
//}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -1120,10 +1128,10 @@ void Category::setValidator(Validator* v) ...@@ -1120,10 +1128,10 @@ void Category::setValidator(Validator* v)
{ {
mIndex = new CatIndex(this); mIndex = new CatIndex(this);
mIndex->reconstruct(); mIndex->reconstruct();
#if DEBUG //#if DEBUG
assert(mIndex->size() == size()); // assert(mIndex->size() == size());
mIndex->validate(); // mIndex->validate();
#endif //#endif
} }
} }
else else
...@@ -1465,8 +1473,10 @@ Category::iterator Category::end() ...@@ -1465,8 +1473,10 @@ Category::iterator Category::end()
return iterator(nullptr); return iterator(nullptr);
} }
void Category::validate() bool Category::isValid()
{ {
bool result = true;
if (mValidator == nullptr) if (mValidator == nullptr)
throw runtime_error("no Validator specified"); throw runtime_error("no Validator specified");
...@@ -1474,13 +1484,13 @@ void Category::validate() ...@@ -1474,13 +1484,13 @@ void Category::validate()
{ {
if (VERBOSE > 2) if (VERBOSE > 2)
cerr << "Skipping validation of empty Category " << mName << endl; cerr << "Skipping validation of empty Category " << mName << endl;
return; return true;
} }
if (mCatValidator == nullptr) if (mCatValidator == nullptr)
{ {
mValidator->reportError("undefined Category " + mName); mValidator->reportError("undefined Category " + mName);
return; return false;
} }
auto mandatory = mCatValidator->mMandatoryFields; auto mandatory = mCatValidator->mMandatoryFields;
...@@ -1489,7 +1499,10 @@ void Category::validate() ...@@ -1489,7 +1499,10 @@ void Category::validate()
{ {
auto iv = mCatValidator->getValidatorForItem(col.mName); auto iv = mCatValidator->getValidatorForItem(col.mName);
if (iv == nullptr) if (iv == nullptr)
{
mValidator->reportError("Field " + col.mName + " is not valid in Category " + mName); mValidator->reportError("Field " + col.mName + " is not valid in Category " + mName);
result = false;
}
col.mValidator = iv; col.mValidator = iv;
...@@ -1497,21 +1510,24 @@ void Category::validate() ...@@ -1497,21 +1510,24 @@ void Category::validate()
} }
if (not mandatory.empty()) if (not mandatory.empty())
mValidator->reportError("In Category " + mName + " the following mandatory fields are missing: " + ba::join(mandatory, ", "));
// check index?
if (mIndex)
{ {
#if not defined(NDEBUG) mValidator->reportError("In Category " + mName + " the following mandatory fields are missing: " + ba::join(mandatory, ", "));
mIndex->validate(); result = false;
for (auto r: *this)
{
if (mIndex->find(r.mData) != r.mData)
mValidator->reportError("Key not found in index for Category " + mName);
}
#endif
} }
//#if not defined(NDEBUG)
// // check index?
// if (mIndex)
// {
// mIndex->validate();
// for (auto r: *this)
// {
// if (mIndex->find(r.mData) != r.mData)
// mValidator->reportError("Key not found in index for Category " + mName);
// }
// }
//#endif
// validate all values // validate all values
mandatory = mCatValidator->mMandatoryFields; mandatory = mCatValidator->mMandatoryFields;
...@@ -1525,6 +1541,7 @@ void Category::validate() ...@@ -1525,6 +1541,7 @@ void Category::validate()
if (iv == nullptr) if (iv == nullptr)
{ {
mValidator->reportError("invalid field " + mColumns[cix].mName + " for Category " + mName); mValidator->reportError("invalid field " + mColumns[cix].mName + " for Category " + mName);
result = false;
continue; continue;
} }
...@@ -1537,13 +1554,18 @@ void Category::validate() ...@@ -1537,13 +1554,18 @@ void Category::validate()
} }
} }
if (seen) if (seen or ri != mHead)
continue; continue;
if (iv != nullptr and iv->mMandatory) if (iv != nullptr and iv->mMandatory)
{
mValidator->reportError("missing mandatory field " + mColumns[cix].mName + " for Category " + mName); mValidator->reportError("missing mandatory field " + mColumns[cix].mName + " for Category " + mName);
result = false;
}
} }
} }
return result;
} }
const Validator& Category::getValidator() const const Validator& Category::getValidator() const
...@@ -2257,7 +2279,7 @@ void File::load(istream& is) ...@@ -2257,7 +2279,7 @@ void File::load(istream& is)
if (saved != nullptr) if (saved != nullptr)
{ {
setValidator(saved); setValidator(saved);
validate(); (void)isValid();
} }
} }
...@@ -2299,7 +2321,7 @@ Datablock& File::operator[](const string& name) ...@@ -2299,7 +2321,7 @@ Datablock& File::operator[](const string& name)
return *result; return *result;
} }
void File::validate() bool File::isValid()
{ {
if (mValidator == nullptr) if (mValidator == nullptr)
{ {
...@@ -2309,8 +2331,10 @@ void File::validate() ...@@ -2309,8 +2331,10 @@ void File::validate()
loadDictionary(); loadDictionary();
} }
bool result = true;
for (auto d = mHead; d != nullptr; d = d->mNext) for (auto d = mHead; d != nullptr; d = d->mNext)
d->validate(); result = d->isValid() and result;
return result;
} }
const Validator& File::getValidator() const const Validator& File::getValidator() const
...@@ -2327,30 +2351,47 @@ void File::loadDictionary() ...@@ -2327,30 +2351,47 @@ void File::loadDictionary()
void File::loadDictionary(const char* dict) void File::loadDictionary(const char* dict)
{ {
fs::path dictFile = string("dictionaries/") + dict + ".dic"; for (;;)
#if defined(USE_RSRC)
mrsrc::rsrc dictData(dictFile.string());
if (not dictData)
throw invalid_argument("no such dictionary");
struct membuf : public streambuf
{ {
membuf(char* dict, size_t length) string name(dict);
if (fs::exists(name))
{ {
this->setg(dict, dict, dict + length); fs::ifstream is(name);
loadDictionary(is);
break;
}
fs::path dictFile = string("dictionaries/") + dict + ".dic";
if (fs::exists(dictFile))
{
fs::ifstream is(dictFile);
loadDictionary(is);
break;
} }
} buffer(const_cast<char*>(dictData.data()), dictData.size());
#if defined(USE_RSRC)
mrsrc::rsrc dictData(dictFile.string());
istream is(&buffer); if (dictData)
#else {
if (not fs::exists(dictFile)) struct membuf : public streambuf
throw runtime_error("Dictionary not found (" + dictFile.string() + ")"); {
fs::ifstream is(dictFile); membuf(char* dict, size_t length)
{
this->setg(dict, dict, dict + length);
}
} buffer(const_cast<char*>(dictData.data()), dictData.size());
istream is(&buffer);
loadDictionary(is);
break;
}
#endif #endif
loadDictionary(is); throw runtime_error("Dictionary not found or defined (" + name + ")");
}
} }
void File::loadDictionary(istream& is) void File::loadDictionary(istream& is)
......
...@@ -163,7 +163,7 @@ float CalculateEDIA(const Atom& atom, const clipper::Xmap<float>& xmap, ...@@ -163,7 +163,7 @@ float CalculateEDIA(const Atom& atom, const clipper::Xmap<float>& xmap,
float radius = kAtomRadius(atom.type(), 0, resolution); float radius = kAtomRadius(atom.type(), 0, resolution);
float x, y, z; float x, y, z;
tie(x, y, z) = (tuple<float,float,float>)atom.location(); tie(x, y, z) = atom.location();
// calculate min and max orthogonal coordinates first, based on atom position, radius and bfactor // calculate min and max orthogonal coordinates first, based on atom position, radius and bfactor
clipper::Coord_orth oMin = { x - radius * 2, y - radius * 2, z - radius * 2 }, clipper::Coord_orth oMin = { x - radius * 2, y - radius * 2, z - radius * 2 },
......
...@@ -5539,5 +5539,6 @@ void ReadPDBFile(istream& pdbFile, cif::File& cifFile) ...@@ -5539,5 +5539,6 @@ void ReadPDBFile(istream& pdbFile, cif::File& cifFile)
p.Parse(pdbFile, cifFile); p.Parse(pdbFile, cifFile);
cifFile.validate(); if (not cifFile.isValid())
throw runtime_error("Resulting mmCIF file is invalid");
} }
...@@ -109,8 +109,9 @@ void FileImpl::load(fs::path p) ...@@ -109,8 +109,9 @@ void FileImpl::load(fs::path p)
// And validate, otherwise lots of functionality won't work // And validate, otherwise lots of functionality won't work
// if (mData.getValidator() == nullptr) // if (mData.getValidator() == nullptr)
mData.loadDictionary("mmcif_pdbx"); mData.loadDictionary("mmcif_pdbx");
mData.validate(); if (not mData.isValid())
cerr << "Invalid mmCIF file" << (VERBOSE ? "." : " use --verbose option to see errors") << endl;
} }
void FileImpl::save(fs::path p) void FileImpl::save(fs::path p)
......
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