Commit 77e0b3f7 by maarten

symmetrie

git-svn-id: svn+ssh://gitlab/srv/svn-repos/pdb-redo/trunk@498 a1961a4f-ab94-4bcc-80e8-33b5a54de466
parent a7249eb2
...@@ -234,6 +234,19 @@ int GetSpacegroupNumber(std::string spacegroup) ...@@ -234,6 +234,19 @@ int GetSpacegroupNumber(std::string spacegroup)
} }
} }
// not found, see if we can find a match based on xHM name
if (result == 0)
{
for (auto& sp: kSpaceGroups)
{
if (sp.xHM == spacegroup)
{
result = sp.nr;
break;
}
}
}
if (result == 0) if (result == 0)
throw runtime_error("Spacegroup name " + spacegroup + " was not found in table"); throw runtime_error("Spacegroup name " + spacegroup + " was not found in table");
...@@ -244,28 +257,15 @@ int GetSpacegroupNumber(std::string spacegroup) ...@@ -244,28 +257,15 @@ int GetSpacegroupNumber(std::string spacegroup)
std::string SpacegroupToHall(std::string spacegroup) std::string SpacegroupToHall(std::string spacegroup)
{ {
if (spacegroup == "P 21 21 2 A") int nr = GetSpacegroupNumber(spacegroup);
spacegroup = "P 21 21 2 (a)";
else if (spacegroup.empty())
throw runtime_error("No spacegroup, cannot continue");
// yeah, sucks, I know, might be looping three times this way
string result; string result;
for (auto& sp: kSpaceGroups)
const size_t N = sizeof(kSpaceGroups) / sizeof(Spacegroup);
int32_t L = 0, R = static_cast<int32_t>(N - 1);
while (L <= R)
{ {
int32_t i = (L + R) / 2; if (sp.nr == nr)
int d = spacegroup.compare(kSpaceGroups[i].name);
if (d > 0)
L = i + 1;
else if (d < 0)
R = i - 1;
else
{ {
result = kSpaceGroups[i].Hall; result = sp.Hall;
break; break;
} }
} }
......
...@@ -157,9 +157,34 @@ class SymopParser ...@@ -157,9 +157,34 @@ class SymopParser
int m_trn[3][2] = {}; int m_trn[3][2] = {};
}; };
map<string,string> get_Hall_map(string path) int main()
{ {
ifstream file(path); try
{
const char* CLIBD = getenv("CLIBD");
if (CLIBD == nullptr)
throw runtime_error("CCP4 not sourced");
// --------------------------------------------------------------------
// store symop data here
vector<tuple<int,int,array<int,15>>> data;
// -----------------------------------------------------------------------
struct SymInfoBlock
{
int nr;
string xHM;
string Hall;
string old[2];
};
map<int,SymInfoBlock> symInfo;
int symopnr, mysymnr = 10000;
ifstream file(CLIBD + "/syminfo.lib"s);
if (not file.is_open()) if (not file.is_open())
throw runtime_error("Could not open syminfo.lib file"); throw runtime_error("Could not open syminfo.lib file");
...@@ -169,9 +194,10 @@ map<string,string> get_Hall_map(string path) ...@@ -169,9 +194,10 @@ map<string,string> get_Hall_map(string path)
string Hall; string Hall;
vector<string> old; vector<string> old;
const regex rx(R"(^symbol +(Hall|old) +'(.+?)'(?: +'(.+?)')?$)"); const regex rx(R"(^symbol +(Hall|xHM|old) +'(.+?)'(?: +'(.+?)')?$)"),
rx2(R"(symbol ccp4 (\d+))");;
map<string,string> result; SymInfoBlock cur = {};
while (getline(file, line)) while (getline(file, line))
{ {
...@@ -179,7 +205,12 @@ map<string,string> get_Hall_map(string path) ...@@ -179,7 +205,12 @@ map<string,string> get_Hall_map(string path)
{ {
case State::skip: case State::skip:
if (line == "begin_spacegroup") if (line == "begin_spacegroup")
{
state = State::spacegroup; state = State::spacegroup;
symopnr = 1;
++mysymnr;
cur = { mysymnr };
}
break; break;
case State::spacegroup: case State::spacegroup:
...@@ -189,141 +220,135 @@ map<string,string> get_Hall_map(string path) ...@@ -189,141 +220,135 @@ map<string,string> get_Hall_map(string path)
{ {
if (m[1] == "old") if (m[1] == "old")
{ {
old.push_back(m[2]); cur.old[0] = m[2];
if (m[3].matched) if (m[3].matched)
old.push_back(m[3]); cur.old[1] = m[3];
} }
else else if (m[1] == "xHM")
Hall = m[2]; cur.xHM = m[2];
else if (m[1] == "Hall")
cur.Hall = m[2];
} }
else if (line == "end_spacegroup") else if (regex_match(line, m, rx2))
{
if (not Hall.empty())
{ {
for (auto& o: old) int nr = stoi(m[1]);
result.emplace(o, Hall); if (nr != 0)
} cur.nr = nr;
state = State::skip;
old.clear();
Hall.clear();
} }
break; else if (line.compare(0, 6, "symop ") == 0)
}
}
}
return result;
}
int main()
{
try
{
const char* CLIBD = getenv("CLIBD");
if (CLIBD == nullptr)
throw runtime_error("CCP4 not sourced");
ifstream file(CLIBD + "/symop.lib"s);
if (not file.is_open())
throw runtime_error("Could not open symop.lib file");
// --------------------------------------------------------------------
// unfortunately, the data in symop.lib is not sorted, so we have to
// store the data in memory before writing out.
vector<tuple<int,int,string,array<int,15>>> data;
vector<tuple<string,int>> spacegroups;
// --------------------------------------------------------------------
string line;
string spacegroupName;
int spacegroupNr, symopnr;
enum class State { Initial, InSpacegroup, Error } state = State::Initial;
while (getline(file, line))
{
if (line.empty())
throw runtime_error("Invalid symop.lib file, contains empty line");
switch (state)
{
case State::Error:
case State::InSpacegroup:
if (line[0] == ' ')
{
if (state == State::Error)
continue;
try
{ {
SymopParser p; SymopParser p;
data.emplace_back(spacegroupNr, symopnr, spacegroupName, p.parse(line)); data.emplace_back(cur.nr, symopnr, p.parse(line.substr(6)));
++symopnr; ++symopnr;
} }
catch (const exception& e) else if (line == "end_spacegroup")
{
cerr << line << endl
<< e.what() << endl;
}
continue;
}
// fall through
case State::Initial:
{
smatch m;
if (not regex_match(line, m, kNameRx))
{ {
cerr << line << endl; symInfo.emplace(cur.nr, cur);
throw runtime_error("Name line does not match regular expression"); state = State::skip;
} }
spacegroupNr = stoi(m[1]);
spacegroupName = m[7];
symopnr = 1;
spacegroups.emplace_back(spacegroupName, spacegroupNr);
state = State::InSpacegroup;
break; break;
} }
} }
} }
// ----------------------------------------------------------------------- // // --------------------------------------------------------------------
auto Hall_map = get_Hall_map(CLIBD + "/syminfo.lib"s); // string line;
// string spacegroupName;
// int spacegroupNr, symopnr;
// enum class State { Initial, InSpacegroup, Error } state = State::Initial;
// while (getline(file, line))
// {
// if (line.empty())
// throw runtime_error("Invalid symop.lib file, contains empty line");
// switch (state)
// {
// case State::Error:
// case State::InSpacegroup:
// if (line[0] == ' ')
// {
// if (state == State::Error)
// continue;
// try
// {
// SymopParser p;
// data.emplace_back(spacegroupNr, symopnr, spacegroupName, p.parse(line));
// ++symopnr;
// }
// catch (const exception& e)
// {
// cerr << line << endl
// << e.what() << endl;
// }
// continue;
// }
// // fall through
// case State::Initial:
// {
// smatch m;
// if (not regex_match(line, m, kNameRx))
// {
// cerr << line << endl;
// throw runtime_error("Name line does not match regular expression");
// }
// spacegroupNr = stoi(m[1]);
// spacegroupName = m[7];
// symopnr = 1;
// if (not symInfo.count(spacegroupNr))
// throw runtime_error("Symmetry nr not found in syminfo.lib");
// if (symInfo[spacegroupNr].xHM != spacegroupName)
// cerr << "Inconsistent data between symop.lib and syminfo.lib for spacegroup nr " << to_string(spacegroupNr) << endl;
// state = State::InSpacegroup;
// break;
// }
// }
// }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
sort(data.begin(), data.end()); sort(data.begin(), data.end());
sort(spacegroups.begin(), spacegroups.end());
// -------------------------------------------------------------------- // --------------------------------------------------------------------
cout << R"(// This file was generated from $CLIBD/symop.lib cout << R"(// This file was generated from $CLIBD/symop.lib
// and $CLIBD/syminfo.lib using symop-map-generator,
// part of the PDB-REDO suite of programs.
struct Spacegroup struct Spacegroup
{ {
const char* name; const char* name;
const char* xHM;
const char* Hall; const char* Hall;
int nr; int nr;
} kSpaceGroups[] = } kSpaceGroups[] =
{ {
)"; )";
for (auto [name, nr]: spacegroups) vector<tuple<string,int,string,string>> spacegroups;
for (auto& [nr, info]: symInfo)
{ {
string Hall = Hall_map[name]; spacegroups.emplace_back(info.old[0], nr, info.xHM, info.Hall);
if (info.old[1].empty() == false)
spacegroups.emplace_back(info.old[1], nr, info.xHM, info.Hall);
}
name = '"' + name + '"' + string(20 - name.length(), ' '); sort(spacegroups.begin(), spacegroups.end());
for (auto [old, nr, xHM, Hall]: spacegroups)
{
old = '"' + old + '"' + string(20 - old.length(), ' ');
xHM = '"' + xHM + '"' + string(30 - xHM.length(), ' ');
for (string::size_type p = Hall.length(); p > 0; --p) for (string::size_type p = Hall.length(); p > 0; --p)
{ {
...@@ -333,7 +358,7 @@ struct Spacegroup ...@@ -333,7 +358,7 @@ struct Spacegroup
Hall = '"' + Hall + '"' + string(40 - Hall.length(), ' '); Hall = '"' + Hall + '"' + string(40 - Hall.length(), ' ');
cout << "\t{ " << name << ", " << Hall << ", " << nr << " }," << endl; cout << "\t{ " << old << ", " << xHM << ", " << Hall << ", " << nr << " }," << endl;
} }
cout << R"( cout << R"(
...@@ -370,20 +395,19 @@ struct SymopDataBlock ...@@ -370,20 +395,19 @@ struct SymopDataBlock
} kSymopNrTable[] = { } kSymopNrTable[] = {
)" << endl; )" << endl;
spacegroupNr = 0; int spacegroupNr = 0;
for (auto& sd: data) for (auto& sd: data)
{ {
int sp, o; int sp, o;
string n; tie(sp, o, ignore) = sd;
tie(sp, o, n, ignore) = sd;
if (sp > spacegroupNr) if (sp > spacegroupNr)
cout << " // " << n << endl; cout << " // " << symInfo[sp].xHM << endl;
spacegroupNr = sp; spacegroupNr = sp;
cout << " { " << setw(3) << sp cout << " { " << setw(3) << sp
<< ", " << setw(3) << o << ", { "; << ", " << setw(3) << o << ", { ";
for (auto i: get<3>(sd)) for (auto i: get<2>(sd))
cout << setw(2) << i << ','; cout << setw(2) << i << ',';
cout << " } }," << endl; cout << " } }," << endl;
} }
......
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