Xmipp  v3.23.11-Nereus
Classes | Functions
symop-map-generator.cpp File Reference
#include <cassert>
#include <array>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <regex>
#include <map>
#include <filesystem>
#include <cstdlib>
Include dependency graph for symop-map-generator.cpp:

Go to the source code of this file.

Classes

class  SymopParser
 

Functions

std::regex kNameRx (R"(^(\) +(\) +(\) +(\) +(\) +(\) +'([^']+)'( +'([^']+)')?(?: +!.+)?$)")
 
std::array< int, 15 > move_symop (std::array< int, 15 > symop, const std::array< int, 15 > &cenop)
 
int main (int argc, char *const argv[])
 

Function Documentation

◆ kNameRx()

std::regex kNameRx ( R"(^(\+(\+(\+(\+(\+(\+'([^']+)'( +'([^']+)')?(?: +!.+)?$)"  )

◆ main()

int main ( int  argc,
char *const  argv[] 
)

Definition at line 225 of file symop-map-generator.cpp.

226 {
227  using namespace std::literals;
228 
229  fs::path tmpFile;
230 
231  try
232  {
233  if (argc != 3)
234  {
235  std::cerr << "Usage symop-map-generator <input-file> <output-file>" << std::endl;
236  exit(1);
237  }
238 
239  fs::path input(argv[1]);
240  fs::path output(argv[2]);
241 
242  tmpFile = output.parent_path() / (output.filename().string() + ".tmp");
243 
244  std::ofstream out(tmpFile);
245  if (not out.is_open())
246  throw std::runtime_error("Failed to open output file");
247 
248  // --------------------------------------------------------------------
249 
250  // store symop data here
251  std::vector<std::tuple<int,int,std::array<int,15>>> data;
252 
253  // -----------------------------------------------------------------------
254 
255  struct SymInfoBlock
256  {
257  int nr;
258  std::string xHM;
259  std::string Hall;
260  std::string old[2];
261  };
262 
263  std::map<int,SymInfoBlock> symInfo;
264  int symopnr, mysymnr = 10000;
265 
266  std::ifstream file(input);
267  if (not file.is_open())
268  throw std::runtime_error("Could not open syminfo.lib file");
269 
270  enum class State { skip, spacegroup } state = State::skip;
271 
272  std::string line;
273 
274  const std::regex rx(R"(^symbol +(Hall|xHM|old) +'(.+?)'(?: +'(.+?)')?$)"),
275  rx2(R"(symbol ccp4 (\d+))");;
276 
277  SymInfoBlock cur = {};
278 
279  std::vector<std::array<int,15>> symops, cenops;
280 
281  while (getline(file, line))
282  {
283  switch (state)
284  {
285  case State::skip:
286  if (line == "begin_spacegroup")
287  {
288  state = State::spacegroup;
289  symopnr = 1;
290  ++mysymnr;
291  cur = { mysymnr };
292  }
293  break;
294 
295  case State::spacegroup:
296  {
297  std::smatch m;
298  if (std::regex_match(line, m, rx))
299  {
300  if (m[1] == "old")
301  {
302  cur.old[0] = m[2];
303  if (m[3].matched)
304  cur.old[1] = m[3];
305  }
306  else if (m[1] == "xHM")
307  cur.xHM = m[2];
308  else if (m[1] == "Hall")
309  cur.Hall = m[2];
310  }
311  else if (regex_match(line, m, rx2))
312  {
313  int nr = stoi(m[1]);
314  if (nr != 0)
315  cur.nr = nr;
316  }
317  else if (line.compare(0, 6, "symop ") == 0)
318  {
319  SymopParser p;
320  symops.emplace_back(p.parse(line.substr(6)));
321  }
322  else if (line.compare(0, 6, "cenop ") == 0)
323  {
324  SymopParser p;
325  cenops.emplace_back(p.parse(line.substr(6)));
326  }
327  else if (line == "end_spacegroup")
328  {
329  for (auto& cenop: cenops)
330  {
331  for (auto symop: symops)
332  {
333  symop = move_symop(symop, cenop);
334 
335  data.emplace_back(cur.nr, symopnr, symop);
336  ++symopnr;
337  }
338  }
339 
340  symInfo.emplace(cur.nr, cur);
341  state = State::skip;
342 
343  symops.clear();
344  cenops.clear();
345  }
346  break;
347  }
348  }
349  }
350 
351  // --------------------------------------------------------------------
352 
353  sort(data.begin(), data.end());
354 
355  // --------------------------------------------------------------------
356 
357  out << R"(// This file was generated from $CLIBD/symop.lib
358 // and $CLIBD/syminfo.lib using symop-map-generator,
359 // part of the PDB-REDO suite of programs.
360 
361 #include "cif++/symmetry.hpp"
362 
363 namespace cif
364 {
365 
366 const space_group kSpaceGroups[] =
367 {
368 )";
369 
370  std::vector<std::tuple<std::string,int,std::string,std::string>> spacegroups;
371 
372  for (auto& [nr, info]: symInfo)
373  {
374  spacegroups.emplace_back(info.old[0], nr, info.xHM, info.Hall);
375  if (info.old[1].empty() == false)
376  spacegroups.emplace_back(info.old[1], nr, info.xHM, info.Hall);
377  }
378 
379  sort(spacegroups.begin(), spacegroups.end());
380 
381  for (auto [old, nr, xHM, Hall]: spacegroups)
382  {
383  old = '"' + old + '"' + std::string(20 - old.length(), ' ');
384  xHM = '"' + xHM + '"' + std::string(30 - xHM.length(), ' ');
385 
386  for (std::string::size_type p = Hall.length(); p > 0; --p)
387  {
388  if (Hall[p - 1] == '"')
389  Hall.insert(p - 1, "\\", 1);
390  }
391 
392  Hall = '"' + Hall + '"' + std::string(40 - Hall.length(), ' ');
393 
394  out << "\t{ " << old << ", " << xHM << ", " << Hall << ", " << nr << " }," << std::endl;
395  }
396 
397 out << R"(
398 };
399 
400 const size_t kNrOfSpaceGroups = sizeof(kSpaceGroups) / sizeof(space_group);
401 
402 const symop_datablock kSymopNrTable[] = {
403 )" << std::endl;
404 
405  int spacegroupNr = 0;
406  for (auto& sd: data)
407  {
408  int sp, o;
409  std::tie(sp, o, std::ignore) = sd;
410 
411  if (sp > spacegroupNr)
412  out << " // " << symInfo[sp].xHM << std::endl;
413  spacegroupNr = sp;
414 
415  out << " { " << std::setw(3) << sp
416  << ", " << std::setw(3) << o << ", { ";
417  for (auto& i: std::get<2>(sd))
418  out << std::setw(2) << i << ',';
419  out << " } }," << std::endl;
420  }
421 
422  out << R"(};
423 
424 const size_t kSymopNrTableSize = sizeof(kSymopNrTable) / sizeof(symop_datablock);
425 
426 } // namespace mmcif
427 )" << std::endl;
428 
429  out.close();
430  fs::rename(tmpFile, output);
431  }
432  catch (const std::exception& ex)
433  {
434  std::cerr << std::endl
435  << "Program terminated due to error:" << std::endl
436  << ex.what() << std::endl;
437  }
438 
439  return 0;
440 }
std::array< int, 15 > parse(const std::string &s)
#define i
std::array< int, 15 > move_symop(std::array< int, 15 > symop, const std::array< int, 15 > &cenop)
void sort(struct DCEL_T *dcel)
Definition: sorting.cpp:18
int m

◆ move_symop()

std::array<int,15> move_symop ( std::array< int, 15 >  symop,
const std::array< int, 15 > &  cenop 
)

Definition at line 181 of file symop-map-generator.cpp.

182 {
183  for (int i = 9; i < 15; i += 2)
184  {
185  if (cenop[i] == 0)
186  continue;
187 
188  assert(cenop[i + 1] != 0);
189 
190  if (symop[i] == 0)
191  {
192  assert(symop[i + 1] == 0);
193  symop[i] = cenop[i];
194  symop[i + 1] = cenop[i + 1];
195  continue;
196  }
197 
198  if (symop[i + 1] == cenop[i + 1])
199  symop[i] += cenop[i];
200  else
201  {
202  int d = symop[i + 1] * cenop[i + 1];
203  int n = symop[i] * cenop[i + 1] + symop[i + 1] * cenop[i];
204 
205  symop[i] = n;
206  symop[i + 1] = d;
207  }
208 
209  for (int j = 5; j > 1; --j)
210  if (symop[i] % j == 0 and symop[i + 1] % j == 0)
211  {
212  symop[i] /= j;
213  symop[i + 1] /= j;
214  }
215 
216  symop[i] = (symop[i] + symop[i + 1]) % symop[i + 1];
217 
218  if (symop[i] == 0)
219  symop[i + 1] = 0;
220  }
221 
222  return symop;
223 }
#define i
doublereal * d
#define j
int * n