/** * loads atom dynamics file * @author Tobias Weber * @date Dec-2019 * @license GPLv3, see 'LICENSE' file */ #ifndef __MOLDYN_H__ #define __MOLDYN_H__ #include #include #include #include #include "libs/str.h" template class MolFrame { public: MolFrame() { m_config.reserve(128); } void AddAtomConfig(std::vector&& config) { m_config.emplace_back(std::move(config)); } void AddAtomConfig(const std::vector& config) { m_config.push_back(config); } std::size_t GetNumAtoms() const { return m_config.size(); } const std::vector& GetCoords(std::size_t atomidx) const { return m_config[atomidx]; } private: // atoms -> coordinates std::vector> m_config; }; template class MolDyn { public: MolDyn() : m_baseA(3), m_baseB(3), m_baseC(3) { m_frames.reserve(16384); } void SetBaseA(t_real x, t_real y, t_real z) { m_baseA[0] = x; m_baseA[1] = y; m_baseA[2] = z; } void SetBaseB(t_real x, t_real y, t_real z) { m_baseB[0] = x; m_baseB[1] = y; m_baseB[2] = z; } void SetBaseC(t_real x, t_real y, t_real z) { m_baseC[0] = x; m_baseC[1] = y; m_baseC[2] = z; } void AddAtomType(const std::string& name, unsigned int number) { m_vecAtoms.push_back(name); m_vecAtomNums.push_back(number); } void AddFrame(MolFrame&& frame) { m_frames.emplace_back(std::move(frame)); } void AddFrame(const MolFrame& frame) { m_frames.push_back(frame); } bool LoadFile(const std::string& filename, unsigned int frameskip = 0) { const std::string strDelim{" \t"}; std::ifstream ifstr{filename}; if(!ifstr) { std::cerr << "Cannot open \"" << filename << "\"."; return 0; } // clear old data Clear(); std::string strSys; std::getline(ifstr, strSys); tl2::trim(strSys); std::cout << "System: " << strSys << std::endl; std::string strScale; std::getline(ifstr, strScale); t_real scale = tl2::str_to_var(strScale); std::cout << "scale: " << scale << std::endl; std::string strVecs1; std::string strVecs2; std::string strVecs3; std::getline(ifstr, strVecs1); std::getline(ifstr, strVecs2); std::getline(ifstr, strVecs3); std::vector _vecBase1, _vecBase2, _vecBase3; tl2::get_tokens(strVecs1, strDelim, _vecBase1); tl2::get_tokens(strVecs2, strDelim, _vecBase2); tl2::get_tokens(strVecs3, strDelim, _vecBase3); if(_vecBase1.size()!=3 || _vecBase2.size()!=3 || _vecBase3.size()!=3) { std::cerr << "Invalid base vectors." << std::endl; return 0; } SetBaseA(_vecBase1[0]*scale, _vecBase2[0]*scale, _vecBase3[0]*scale); SetBaseB(_vecBase1[1]*scale, _vecBase2[1]*scale, _vecBase3[1]*scale); SetBaseC(_vecBase1[2]*scale, _vecBase2[2]*scale, _vecBase3[2]*scale); std::string strAtoms; std::string strAtomNums; std::getline(ifstr, strAtoms); std::getline(ifstr, strAtomNums); tl2::get_tokens(strAtoms, strDelim, m_vecAtoms); tl2::get_tokens(strAtomNums, strDelim, m_vecAtomNums); if(m_vecAtoms.size() != m_vecAtomNums.size()) { std::cerr << "Atom size mismatch." << std::endl; return 0; } for(std::size_t i=0; i frame; for(std::size_t iAtomType=0; iAtomType atomconf; for(std::size_t iAtom=0; iAtom(strCoords, strDelim, vecCoords); if(vecCoords.size() != 3) { std::cerr << "Invalid coordinate." << std::endl; return 0; } atomconf.emplace_back(std::move(vecCoords)); } frame.AddAtomConfig(std::move(atomconf)); } AddFrame(std::move(frame)); ++iNumConfigs; // skip frames for(unsigned int skipped=0; skipped& GetFrame(std::size_t frame) const { return m_frames[frame]; } const std::string& GetAtomName(std::size_t idx) const { return m_vecAtoms[idx]; } private: t_vec m_baseA; t_vec m_baseB; t_vec m_baseC; std::vector m_vecAtoms; std::vector m_vecAtomNums; std::vector> m_frames; }; #endif