From 9d517e2765b9c6f0bdc6cce37f8f46e3343b2cff Mon Sep 17 00:00:00 2001 From: conradhuebler Date: Sat, 3 Jun 2023 12:27:49 +0200 Subject: [PATCH 01/10] visualise confscan results as graphs using dot (graphViz) Signed-off-by: conradhuebler --- src/capabilities/confscan.cpp | 89 ++++++++++++++++++++++++++++++++--- src/capabilities/confscan.h | 15 +++--- 2 files changed, 89 insertions(+), 15 deletions(-) diff --git a/src/capabilities/confscan.cpp b/src/capabilities/confscan.cpp index ae8933c..284c2ab 100644 --- a/src/capabilities/confscan.cpp +++ b/src/capabilities/confscan.cpp @@ -182,12 +182,10 @@ void ConfScan::LoadControlJson() m_energy_cutoff = Json2KeyWord(m_defaults, "maxenergy"); m_prevent_reorder = Json2KeyWord(m_defaults, "preventReorder"); - // double scaleLoose = Json2KeyWord(m_defaults, "scaleLoose"); m_sLE = Json2KeyWord(m_defaults, "sLE"); m_sLI = Json2KeyWord(m_defaults, "sLI"); m_sLH = Json2KeyWord(m_defaults, "sLH"); - // double scaleTight = Json2KeyWord(m_defaults, "scaleTight"); m_sTE = Json2KeyWord(m_defaults, "sTE"); m_sTI = Json2KeyWord(m_defaults, "sTI"); m_sTH = Json2KeyWord(m_defaults, "sTH"); @@ -567,6 +565,11 @@ void ConfScan::start() if (!m_skipfirst) { CheckRMSD(); PrintStatus("Result 1st pass:"); + std::ofstream result_file; + result_file.open(m_result_basename + ".first.dot"); + result_file << "digraph graphname \n {\n"; + result_file << m_first_content << std::endl; + result_file << "}"; } else { for (const auto& i : m_ordered_list) m_stored_structures.push_back(m_molecules.at(i.second).second); @@ -588,7 +591,11 @@ void ConfScan::start() } ReorderCheck(m_prevent_reorder, false); PrintStatus("Result 2nd pass:"); - + std::ofstream result_file; + result_file.open(m_result_basename + ".second.dot"); + result_file << "digraph graphname \n {\n"; + result_file << m_second_content << std::endl; + result_file << "}"; fmt::print("\n2nd Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); timer.Reset(); } @@ -602,7 +609,11 @@ void ConfScan::start() fmt::print("\n\n3rd Pass\nPerforming RMSD calculation with reordering, and less stricter threshold.\n\n"); ReorderTrained(); PrintStatus("Result 3rd pass:"); - + std::ofstream result_file; + result_file.open(m_result_basename + ".third.dot"); + result_file << "digraph graphname \n {\n"; + result_file << m_third_content << std::endl; + result_file << "}"; fmt::print("\n3rd Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); } } @@ -627,11 +638,23 @@ void ConfScan::start() index++; } #endif + std::ofstream dotfile; + dotfile.open(m_result_basename + ".dot"); + dotfile << "digraph graphname \n {\n"; + dotfile << "edge [color=green];" << std::endl; + dotfile << m_first_content << std::endl; + dotfile << "edge [color=red];" << std::endl; + dotfile << m_second_content << std::endl; + dotfile << "edge [color=blue];" << std::endl; + dotfile << m_third_content << std::endl; + dotfile << "}"; Finalise(); } void ConfScan::CheckRMSD() { + std::string content_dot; + std::string laststring; m_maxmol = m_ordered_list.size(); json rmsd = RMSDJson; @@ -694,6 +717,15 @@ void ConfScan::CheckRMSD() if (t->KeepMolecule() == false) { keep_molecule = false; writeStatisticFile(t->Reference(), mol1, t->RMSD()); + + if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) + m_first_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; + + m_first_content += "\"" + t->Reference()->Name() + "\" [shape=box, label=\"" + t->Reference()->Name() + "\"];\n"; + m_first_content += "\"" + mol1->Name() + "\" [label=\"" + mol1->Name() + "\"];\n"; + m_first_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\" [style=bold,label=" + std::to_string(t->RMSD()) + "];\n"; + laststring = t->Reference()->Name(); + #ifdef WriteMoreInfo m_dnn_data.push_back(t->getDNNInput()); #endif @@ -716,7 +748,8 @@ void ConfScan::CheckRMSD() void ConfScan::ReorderCheck(bool reuse_only, bool limit) { m_maxmol = m_stored_structures.size(); - + std::string content_dot; + std::string laststring; // To be finalised and tested /* @@ -845,6 +878,8 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) keep_molecule = false; break; } + m_exclude_list.push_back(std::pair(mol1->Name(), mol2->Name())); + } else { threads[t]->setEnabled(m_closeLoop); } @@ -893,6 +928,14 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) if (AddRules(t->ReorderRule())) rules.push_back(t->ReorderRule()); + if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) + m_second_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; + + m_second_content += "\"" + t->Reference()->Name() + "\" [shape=box, label=\"" + t->Reference()->Name() + "\"];\n"; + m_second_content += "\"" + mol1->Name() + "\" [label=\"" + mol1->Name() + "\"];\n"; + m_second_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\" [style=bold,label=" + std::to_string(t->RMSD()) + "];\n"; + laststring = t->Reference()->Name(); + writeStatisticFile(t->Reference(), mol1, t->RMSD(), true, t->ReorderRule()); break; } else { @@ -911,6 +954,15 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) m_reordered_worked += 1; m_reordered_reused += 1; writeStatisticFile(t->Reference(), mol1, driver.RMSD(), true, { 0, 0 }); + + if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) + m_second_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; + + m_second_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\";\n"; + m_second_content += "\"" + mol1->Name() + "\" [shape=box, style=filled,color=\".7 .3 1.0\"];\n"; + m_second_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\" [style=bold,label=" + std::to_string(driver.RMSD()) + "];\n"; + laststring = t->Reference()->Name(); + fmt::print(fg(fmt::color::yellow) | fmt::emphasis::bold, "... success!\n"); } else fmt::print(fg(fmt::color::yellow) | fmt::emphasis::bold, "... without effect!\n"); @@ -947,6 +999,8 @@ void ConfScan::ReorderTrained() m_molalign_success = 0; m_maxmol = m_stored_structures.size(); + std::string content_dot; + std::string laststring; // To be finalised and tested @@ -1051,6 +1105,11 @@ void ConfScan::ReorderTrained() return; } const Molecule* mol2 = threads[t]->Reference(); + std::pair names(mol1->Name(), mol2->Name()); + if (std::find(m_exclude_list.begin(), m_exclude_list.end(), names) != m_exclude_list.end()) { + m_duplicated++; + continue; + } double Ia = abs(mol1->Ia() - mol2->Ia()); double Ib = abs(mol1->Ib() - mol2->Ib()); double Ic = abs(mol1->Ic() - mol2->Ic()); @@ -1132,6 +1191,15 @@ void ConfScan::ReorderTrained() double diff_rot = (Ia + Ib + Ic) * third; double diff = (mol1->getPersisentImage() - t->Reference()->getPersisentImage()).cwiseAbs().sum(); writeStatisticFile(t->Reference(), mol1, t->RMSD(), true, t->ReorderRule()); + + if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) + m_third_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; + + m_third_content += "\"" + t->Reference()->Name() + "\" [shape=box, label=\"" + t->Reference()->Name() + "\"];\n"; + m_third_content += "\"" + mol1->Name() + "\" [label=\"" + mol1->Name() + "\"];\n"; + m_third_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\" [style=bold,label=" + std::to_string(t->RMSD()) + "];\n"; + + laststring = t->Reference()->Name(); break; } else { if ((m_domolalign > 1) && t->RMSD() < m_domolalign * m_rmsd_threshold) { @@ -1146,6 +1214,15 @@ void ConfScan::ReorderTrained() if (driver.RMSD() < m_rmsd_threshold) { m_molalign_success++; keep_molecule = false; + + if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) + m_third_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; + + m_third_content += "\"" + mol1->Name() + "\" [shape=box, style=filled,color=\".7 .3 1.0\"];\n"; + m_third_content += "\"" + t->Reference()->Name() + "\" [shape=box];\n"; + m_third_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\" [style=bold,label=" + std::to_string(driver.RMSD()) + "];\n"; + + laststring = t->Reference()->Name(); m_reordered_worked += 1; m_reordered_reused += 1; writeStatisticFile(t->Reference(), mol1, driver.RMSD(), true, { 0, 0 }); @@ -1251,7 +1328,7 @@ void ConfScan::PrintStatus(const std::string& info) std::cout << "# Successfully : " << m_reordered_worked << " (+ " << m_molalign_success << ")" << " "; std::cout << "# Reused Results : " << m_reordered_reused << " "; - std::cout << "# Reordering Skipped : " << m_skiped << " "; + std::cout << "# Reordering Skipped : " << m_skiped << " (+ " << m_duplicated << ")"; std::cout << "# Rejected Directly : " << m_rejected_directly << " "; std::cout << "# Current Energy [kJ/mol] : " << m_dE << std::endl; diff --git a/src/capabilities/confscan.h b/src/capabilities/confscan.h index dbb002e..6901742 100644 --- a/src/capabilities/confscan.h +++ b/src/capabilities/confscan.h @@ -54,13 +54,11 @@ static const json ConfScanJson = { { "energy", 1.0 }, { "maxenergy", -1.0 }, { "preventreorder", false }, - { "scaleLoose", 1.5 }, - { "scaleTight", 0.1 }, - { "sLE", 1.2 }, + { "sLE", 1.0 }, { "sTE", 0.1 }, - { "sLI", 1.2 }, + { "sLI", 1.0 }, { "sTI", 0.1 }, - { "sLH", 1.2 }, + { "sLH", 1.0 }, { "sTH", 0.1 }, { "skip", 0 }, { "allxyz", false }, @@ -309,7 +307,7 @@ class ConfScan : public CurcumaMethod { bool m_ok; std::size_t m_fail = 0, m_start = 0, m_end; std::vector m_global_temp_list; - int m_rejected = 0, m_accepted = 0, m_reordered = 0, m_reordered_worked = 0, m_reordered_failed_completely = 0, m_reordered_reused = 0, m_skip = 0, m_skiped = 0, m_rejected_directly = 0, m_molalign_count = 0, m_molalign_success = 0; + int m_rejected = 0, m_accepted = 0, m_reordered = 0, m_reordered_worked = 0, m_reordered_failed_completely = 0, m_reordered_reused = 0, m_skip = 0, m_skiped = 0, m_duplicated = 0, m_rejected_directly = 0, m_molalign_count = 0, m_molalign_success = 0; std::string m_filename, m_accepted_filename, m_1st_filename, m_2nd_filename, m_rejected_filename, m_result_basename, m_statistic_filename, m_prev_accepted, m_joined_filename, m_threshold_filename, m_current_filename; std::map m_ordered_list; @@ -326,15 +324,14 @@ class ConfScan : public CurcumaMethod { std::vector m_result, m_rejected_structures, m_stored_structures, m_previously_accepted; std::vector m_threshold; std::vector m_element_templates; - + std::vector> m_exclude_list; #ifdef WriteMoreInfo std::vector m_dnn_data; #endif - + std::string m_first_content, m_second_content, m_third_content; std::string m_rmsd_element_templates; std::string m_method = ""; std::string m_molalign = "molalign"; - double m_domolalign = -1; double m_lastDI = 0.0, m_lastDH = 0.0, m_lastdE = -1, m_dE = -1, m_damping = 0.8; int m_maxmol = 0; From c1e86b4e663c59dcbd7ee7dc51168870deb7802c Mon Sep 17 00:00:00 2001 From: conradhuebler Date: Wed, 7 Jun 2023 21:02:23 +0200 Subject: [PATCH 02/10] add fourth pass, now restructure is due Signed-off-by: conradhuebler --- src/capabilities/confscan.cpp | 230 ++++++++++++++++++++++++---------- src/capabilities/confscan.h | 10 +- src/core/molecule.cpp | 9 ++ src/core/molecule.h | 2 + 4 files changed, 182 insertions(+), 69 deletions(-) diff --git a/src/capabilities/confscan.cpp b/src/capabilities/confscan.cpp index 284c2ab..6cef7e1 100644 --- a/src/capabilities/confscan.cpp +++ b/src/capabilities/confscan.cpp @@ -243,7 +243,7 @@ void ConfScan::LoadControlJson() m_RMSDElement = Json2KeyWord(m_defaults, "RMSDElement"); m_rmsd_element_templates.push_back(m_RMSDElement); } - if (m_RMSDmethod.compare("hybrid") == 0 && m_element_templates.size() == 0) { + if (m_RMSDmethod.compare("hybrid") == 0 /* && m_rmsd_element_templates.compare("") == 0 */) { std::cout << "Reordering method hybrid has to be combined with element types. I will chose for you nitrogen and oxygen!" << std::endl; std::cout << "This is equivalent to adding:\' -rmsdelement 7,8 \' to your argument list!" << std::endl; m_rmsd_element_templates = "7,8"; @@ -463,6 +463,7 @@ void ConfScan::SetUp() m_accepted_filename = m_result_basename + ".accepted.xyz"; m_1st_filename = m_result_basename + ".1st.xyz"; m_2nd_filename = m_result_basename + ".2nd.xyz"; + m_3rd_filename = m_result_basename + ".3rd.xyz"; m_rejected_filename = m_result_basename + ".rejected.xyz"; m_statistic_filename = m_result_basename + ".statistic.log"; @@ -577,7 +578,6 @@ void ConfScan::start() #ifdef WriteMoreInfo std::cout << m_dnn_data.size() << std::endl; #endif - fmt::print("\n1st Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); if (m_prevent_reorder == false || m_do_third == true) { if (!CheckStop()) { @@ -601,6 +601,8 @@ void ConfScan::start() } if (!CheckStop() && m_do_third == true) { m_current_filename.clear(); + m_current_filename = m_3rd_filename; + if (m_writeFiles && !m_reduced_file) { result_file.open(m_statistic_filename, std::ios_base::app); result_file << "Results of 3rd Pass" << std::endl; @@ -615,6 +617,27 @@ void ConfScan::start() result_file << m_third_content << std::endl; result_file << "}"; fmt::print("\n3rd Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); + timer.Reset(); + } + + if (true) { + m_current_filename.clear(); + if (m_writeFiles && !m_reduced_file) { + result_file.open(m_statistic_filename, std::ios_base::app); + result_file << "Results of 4rd Pass" << std::endl; + result_file.close(); + } + m_result.clear(); + m_stored_structures.clear(); + fmt::print("\n\n4rd Pass\nPerforming RMSD calculation with stored reorder rules using all structures.\n\n"); + Check4th(); + PrintStatus("Result 4rd pass:"); + std::ofstream result_file; + result_file.open(m_result_basename + ".fourth.dot"); + result_file << "digraph graphname \n {\n"; + result_file << m_4th_content << std::endl; + result_file << "}"; + fmt::print("\n4rd Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); } } if (!CheckStop()) @@ -740,16 +763,16 @@ void ConfScan::CheckRMSD() AcceptMolecule(mol1); } else { RejectMolecule(mol1); + m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(mol1))); } PrintStatus(); } + p->clear(); + delete p; } -void ConfScan::ReorderCheck(bool reuse_only, bool limit) +void ConfScan::PrintSetUp() { - m_maxmol = m_stored_structures.size(); - std::string content_dot; - std::string laststring; // To be finalised and tested /* @@ -777,18 +800,7 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) "", 60, "Thresholds in rotational constants (averaged over Ia, Ib and Ic) and Ripser Image:"); */ - /* if ignore rotation or ignore barcode are true, the tight cutoffs are set to -1, that no difference is smaller - * than the tight threshold and the loose threshold is set to a big number, that every structure has to be reordered*/ - m_skiped = 0; - m_rejected_directly = 0; - if (m_ignoreRotation == true) { - m_dLI = 1e10; - m_dTI = -1; - } - if (m_ignoreBarCode == true) { - m_dLH = 1e10; - m_dTH = -1; - } + std::cout << "" << std::endl << "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" << std::endl; std::cout << " Thresholds in rotational constants (averaged over Ia, Ib and Ic): " << std::endl; @@ -804,6 +816,27 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) std::cout << "" << std::endl << "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" << std::endl << std::endl; +} + +void ConfScan::ReorderCheck(bool reuse_only, bool limit) +{ + m_maxmol = m_stored_structures.size(); + std::string content_dot; + std::string laststring; + PrintSetUp(); + /* if ignore rotation or ignore barcode are true, the tight cutoffs are set to -1, that no difference is smaller + * than the tight threshold and the loose threshold is set to a big number, that every structure has to be reordered*/ + m_skiped = 0; + m_rejected_directly = 0; + if (m_ignoreRotation == true) { + m_dLI = 1e10; + m_dTI = -1; + } + if (m_ignoreBarCode == true) { + m_dLH = 1e10; + m_dTH = -1; + } + TriggerWriteRestart(); m_rejected = 0, m_accepted = 0, m_reordered = 0, m_reordered_worked = 0, m_reordered_reused = 0; @@ -836,6 +869,8 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) threads.push_back(thread); p->addThread(thread); m_lowest_energy = mol1->Energy(); + m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(mol1))); + continue; } p->Reset(); @@ -862,7 +897,7 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) * ripser = 2 * energy = 4 */ int looseThresh = 1 * (dI < m_dLI) + 2 * (dH < m_dLH) + 4 * (std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < m_dLE); - if ((looseThresh & m_looseThresh) == m_looseThresh) { + if ((looseThresh & m_looseThresh) == m_looseThresh || (m_dLI == 0 && m_dLH == 0 && m_dLE == 0)) { reorder = true; threads[t]->setEnabled(m_openLoop); int tightThresh = 1 * (dI < m_dTI) + 2 * (dH < m_dTH) + 4 * ((std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < m_dTE)); @@ -937,6 +972,10 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) laststring = t->Reference()->Name(); writeStatisticFile(t->Reference(), mol1, t->RMSD(), true, t->ReorderRule()); + // mol1->print_geom(); + mol1->ApplyReorderRule(t->ReorderRule()); + // mol1->print_geom(); + break; } else { if ((m_domolalign > 1) && t->RMSD() < m_domolalign * m_rmsd_threshold) { @@ -948,6 +987,8 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) driver.setReference(t->Reference()); driver.setTarget(mol1); driver.start(); + // m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(driver.TargetReorderd()))); + mol1->LoadMolecule(driver.TargetReorderd()); if (driver.RMSD() < m_rmsd_threshold) { m_molalign_success++; keep_molecule = false; @@ -979,6 +1020,7 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) threads.push_back(thread); } else { RejectMolecule(mol1); + m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(mol1))); } PrintStatus(); @@ -988,6 +1030,7 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) break; } } + p->clear(); delete p; } @@ -1002,33 +1045,6 @@ void ConfScan::ReorderTrained() std::string content_dot; std::string laststring; - // To be finalised and tested - - /* - fmt::print( - "'{0:'^{1}}'\n" - "'{2: ^{1}}'\n" - "'{0: ^{1}}'\n" - "*{3: ^{1}}*\n" - "*{0: ^{1}}*\n" - "*{12: ^{1}}*\n" - "*{0: ^{1}}*\n" - "*{4: ^{1}}*\n" - "*{5: ^{1}}*\n" - "*{0: ^{1}}*\n" - "*{6: ^{1}}*\n" - "*{7: ^{1}}*\n" - "*{0: ^{1}}*\n" - "*{8: ^{1}}*\n" - "*{9: ^{1}}*\n" - "*{10: ^{1}}*\n" - "*{0: ^{1}}*\n" - "*{11: ^{1}}*\n" - "*{0: ^{1}}*\n" - "*{0:*^{1}}*\n", - "", 60, - "Thresholds in rotational constants (averaged over Ia, Ib and Ic) and Ripser Image:"); - */ /* if ignore rotation or ignore barcode are true, the tight cutoffs are set to -1, that no difference is smaller * than the tight threshold and the loose threshold is set to a big number, that every structure has to be reordered*/ m_skiped = 0; @@ -1045,21 +1061,8 @@ void ConfScan::ReorderTrained() m_dLH *= 2; m_dLE *= 2; - std::cout << "" << std::endl - << "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" << std::endl; - std::cout << " Thresholds in rotational constants (averaged over Ia, Ib and Ic): " << std::endl; - std::cout << " Loose Threshold: " << m_dLI << " MHz" << std::endl; - std::cout << " Tight Threshold: " << m_dTI << " MHz" << std::endl; - std::cout << " Thresholds in difference of ripser images: " << std::endl; - std::cout << " Loose Threshold: " << m_dLH << " " << std::endl; - std::cout << " Tight Threshold: " << m_dTH << " " << std::endl; - std::cout << " Thresholds for energy differences in kJ/mol: " << std::endl; - std::cout << " Loose Threshold: " << m_dLE << " " << std::endl; - std::cout << " Tight Threshold: " << m_dTE << " " << std::endl; + PrintSetUp(); - std::cout << "" << std::endl - << "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" << std::endl - << std::endl; TriggerWriteRestart(); m_rejected = 0, m_accepted = 0, m_reordered = 0, m_reordered_worked = 0, m_reordered_reused = 0; @@ -1122,7 +1125,7 @@ void ConfScan::ReorderTrained() * ripser = 2 * energy = 4 */ int looseThresh = 1 * (dI < m_dLI) + 2 * (dH < m_dLH) + 4 * (std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < m_dLE); - if ((looseThresh & m_looseThresh) == m_looseThresh) { + if ((looseThresh & m_looseThresh) == m_looseThresh || (m_dLI == 0 && m_dLH == 0 && m_dLE == 0)) { reorder = true; threads[t]->setEnabled(m_openLoop); int tightThresh = 1 * (dI < m_dTI) + 2 * (dH < m_dTH) + 4 * ((std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < m_dTE)); @@ -1184,13 +1187,9 @@ void ConfScan::ReorderTrained() if (AddRules(t->ReorderRule())) rules.push_back(t->ReorderRule()); - double Ia = abs(mol1->Ia() - t->Reference()->Ia()); - double Ib = abs(mol1->Ib() - t->Reference()->Ib()); - double Ic = abs(mol1->Ic() - t->Reference()->Ic()); - - double diff_rot = (Ia + Ib + Ic) * third; - double diff = (mol1->getPersisentImage() - t->Reference()->getPersisentImage()).cwiseAbs().sum(); writeStatisticFile(t->Reference(), mol1, t->RMSD(), true, t->ReorderRule()); + // m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(t->Target()))); + mol1->ApplyReorderRule(t->ReorderRule()); if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) m_third_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; @@ -1211,6 +1210,8 @@ void ConfScan::ReorderTrained() driver.setReference(t->Reference()); driver.setTarget(mol1); driver.start(); + // m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(driver.TargetReorderd()))); + mol1->LoadMolecule(driver.TargetReorderd()); if (driver.RMSD() < m_rmsd_threshold) { m_molalign_success++; keep_molecule = false; @@ -1237,6 +1238,8 @@ void ConfScan::ReorderTrained() if (keep_molecule) { AcceptMolecule(mol1); + // m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(mol1))); + ConfScanThread* thread = addThread(mol1, rmsd, reuse_only); p->addThread(thread); threads.push_back(thread); @@ -1250,9 +1253,102 @@ void ConfScan::ReorderTrained() if (m_dE > m_energy_cutoff && m_energy_cutoff != -1) { break; } + m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(mol1))); } + p->clear(); delete p; } + +void ConfScan::Check4th() +{ + m_stored_structures.clear(); + m_maxmol = m_final_batch.size(); + m_rejected = 0; + m_reordered_reused = 0; + m_reordered_worked = 0; + m_skiped = 0; + std::string content_dot; + std::string laststring; + m_maxmol = m_ordered_list.size(); + + json rmsd = RMSDJson; + rmsd["silent"] = true; + rmsd["check"] = CheckConnections(); + rmsd["heavy"] = m_heavy; + rmsd["noreorder"] = true; + + std::vector threads; + std::vector> rules; + CxxThreadPool* p = new CxxThreadPool; + p->setActiveThreadCount(m_threads); + + for (auto& i : m_final_batch) { + if (m_skip) { + m_skip--; + continue; + } + if (m_maxrank <= m_accepted && m_maxrank > -1) + continue; + + Molecule* mol1 = i.second; + if (mol1->Check() == 1) { + m_rejected++; + m_start++; + PrintStatus(); + continue; + } + if (m_result.size() == 0) { + AcceptMolecule(mol1); + ConfScanThreadNoReorder* thread = addThreadNoreorder(mol1, rmsd); + threads.push_back(thread); + p->addThread(thread); + + m_lowest_energy = mol1->Energy(); + continue; + } + p->Reset(); + m_current_energy = mol1->Energy(); + m_dE = (m_current_energy - m_lowest_energy) * 2625.5; + + bool keep_molecule = true; + for (int i = 0; i < threads.size(); ++i) { + threads[i]->setTarget(mol1); + } + p->StaticPool(); + p->StartAndWait(); + + for (auto* t : threads) { + + if (t->KeepMolecule() == false) { + keep_molecule = false; + writeStatisticFile(t->Reference(), mol1, t->RMSD()); + + if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) + m_4th_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; + + m_4th_content += "\"" + t->Reference()->Name() + "\" [shape=box, label=\"" + t->Reference()->Name() + "\"];\n"; + m_4th_content += "\"" + mol1->Name() + "\" [label=\"" + mol1->Name() + "\"];\n"; + m_4th_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\" [style=bold,label=" + std::to_string(t->RMSD()) + "];\n"; + laststring = t->Reference()->Name(); + + break; + } + } + + if (keep_molecule) { + ConfScanThreadNoReorder* thread = addThreadNoreorder(mol1, rmsd); + threads.push_back(thread); + p->addThread(thread); + AcceptMolecule(mol1); + } else { + RejectMolecule(mol1); + } + PrintStatus(); + } + p->clear(); + delete p; +} + ConfScanThreadNoReorder* ConfScan::addThreadNoreorder(const Molecule* reference, const json& config) { ConfScanThreadNoReorder* thread = new ConfScanThreadNoReorder(m_rmsd_threshold, m_MaxHTopoDiff, config); diff --git a/src/capabilities/confscan.h b/src/capabilities/confscan.h index 6901742..adff8a1 100644 --- a/src/capabilities/confscan.h +++ b/src/capabilities/confscan.h @@ -150,6 +150,8 @@ class ConfScanThread : public CxxThread { double RMSD() const { return m_rmsd; } const Molecule* Reference() const { return &m_reference; } + const Molecule* Target() const { return &m_target; } + double Energy() const { return m_energy; } #ifdef WriteMoreInfo void setPredRMSD(double rmsd) { m_pred_rmsd = rmsd; } @@ -267,12 +269,14 @@ class ConfScan : public CurcumaMethod { ConfScanThreadNoReorder* addThreadNoreorder(const Molecule* reference, const json& config); private: + void PrintSetUp(); void SetUp(); void CheckRMSD(); void ReorderCheck(bool reuse_only = false, bool limit = false); void ReorderTrained(); + void Check4th(); void writeStatisticFile(const Molecule* mol1, const Molecule* mol2, double rmsd, bool reason = true, const std::vector& rule = std::vector(0)); @@ -309,8 +313,10 @@ class ConfScan : public CurcumaMethod { std::vector m_global_temp_list; int m_rejected = 0, m_accepted = 0, m_reordered = 0, m_reordered_worked = 0, m_reordered_failed_completely = 0, m_reordered_reused = 0, m_skip = 0, m_skiped = 0, m_duplicated = 0, m_rejected_directly = 0, m_molalign_count = 0, m_molalign_success = 0; - std::string m_filename, m_accepted_filename, m_1st_filename, m_2nd_filename, m_rejected_filename, m_result_basename, m_statistic_filename, m_prev_accepted, m_joined_filename, m_threshold_filename, m_current_filename; + std::string m_filename, m_accepted_filename, m_1st_filename, m_2nd_filename, m_3rd_filename, m_rejected_filename, m_result_basename, m_statistic_filename, m_prev_accepted, m_joined_filename, m_threshold_filename, m_current_filename; std::map m_ordered_list; + std::map m_final_batch; + std::vector> m_molecules; double m_rmsd_threshold = 1.0, m_nearly_missed = 0.8, m_energy_cutoff = -1, m_reference_last_energy = 0, m_target_last_energy = 0, m_lowest_energy = 1, m_current_energy = 0; double m_sTE = 0.1, m_sLE = 1.5; @@ -328,7 +334,7 @@ class ConfScan : public CurcumaMethod { #ifdef WriteMoreInfo std::vector m_dnn_data; #endif - std::string m_first_content, m_second_content, m_third_content; + std::string m_first_content, m_second_content, m_third_content, m_4th_content; std::string m_rmsd_element_templates; std::string m_method = ""; std::string m_molalign = "molalign"; diff --git a/src/core/molecule.cpp b/src/core/molecule.cpp index 2d81e7a..aeaa915 100644 --- a/src/core/molecule.cpp +++ b/src/core/molecule.cpp @@ -156,6 +156,15 @@ Molecule::~Molecule() { } +void Molecule::ApplyReorderRule(const std::vector& rule) +{ + Molecule mol; + for (auto& i : rule) + mol.addPair(Atom(i)); + m_geometry = mol.m_geometry; + m_atoms = mol.m_atoms; +} + void Molecule::print_geom(bool moreinfo) const { std::cout << AtomCount() << std::endl; diff --git a/src/core/molecule.h b/src/core/molecule.h index 4c15ed5..2054476 100644 --- a/src/core/molecule.h +++ b/src/core/molecule.h @@ -60,6 +60,8 @@ class Molecule /* Molecule& operator=(const Molecule& molecule); Molecule& operator=(const Molecule* molecule); */ + void ApplyReorderRule(const std::vector& rule); + void print_geom(bool moreinfo = true) const; void printFragmente(); void printAtom(int i) const; From f29bbe1143c63bce35ffc0bba321785919e09fc9 Mon Sep 17 00:00:00 2001 From: conradhuebler Date: Tue, 13 Jun 2023 09:52:40 +0200 Subject: [PATCH 03/10] restructure some confscan code Signed-off-by: conradhuebler --- src/capabilities/confscan.cpp | 270 +++++++++++++++++----------------- src/capabilities/confscan.h | 36 +++-- src/capabilities/rmsd.cpp | 2 +- src/tools/general.h | 4 +- 4 files changed, 155 insertions(+), 157 deletions(-) diff --git a/src/capabilities/confscan.cpp b/src/capabilities/confscan.cpp index 6cef7e1..a8c9be2 100644 --- a/src/capabilities/confscan.cpp +++ b/src/capabilities/confscan.cpp @@ -182,9 +182,28 @@ void ConfScan::LoadControlJson() m_energy_cutoff = Json2KeyWord(m_defaults, "maxenergy"); m_prevent_reorder = Json2KeyWord(m_defaults, "preventReorder"); - m_sLE = Json2KeyWord(m_defaults, "sLE"); - m_sLI = Json2KeyWord(m_defaults, "sLI"); - m_sLH = Json2KeyWord(m_defaults, "sLH"); + if (m_defaults["sLE"].is_number()) + m_sLE = { Json2KeyWord(m_defaults, "sLE") }; + else if (m_defaults["sLE"].is_string()) + m_sLE = Tools::String2DoubleVec(Json2KeyWord(m_defaults, "sLE"), ";"); + + if (m_defaults["sLI"].is_number()) + m_sLI = { Json2KeyWord(m_defaults, "sLI") }; + else if (m_defaults["sLI"].is_string()) + m_sLI = Tools::String2DoubleVec(Json2KeyWord(m_defaults, "sLI"), ";"); + + if (m_defaults["sLH"].is_number()) + m_sLH = { Json2KeyWord(m_defaults, "sLH") }; + else if (m_defaults["sLH"].is_string()) + m_sLH = Tools::String2DoubleVec(Json2KeyWord(m_defaults, "sLH"), ";"); + + if (m_sLE.size() != m_sLI.size() || m_sLE.size() != m_sLH.size()) { + std::cout << "Inconsistent length of steps requested, will abort now." << std::endl; + exit(1); + } + + m_noreorderpass = Json2KeyWord(m_defaults, "noreorderpass"); + n_doreusepass = Json2KeyWord(m_defaults, "doreuse"); m_sTE = Json2KeyWord(m_defaults, "sTE"); m_sTI = Json2KeyWord(m_defaults, "sTI"); @@ -218,13 +237,8 @@ void ConfScan::LoadControlJson() m_molalign = Json2KeyWord(m_defaults, "molalignbin"); m_molaligntol = Json2KeyWord(m_defaults, "molaligntol"); - // if (Json2KeyWord(m_defaults, "skipless")) { m_openLoop = true; m_closeLoop = false; - // # } else { - // m_openLoop = true; - // m_closeLoop = true; - // } m_looseThresh = m_defaults["looseThresh"]; m_tightThresh = m_defaults["tightThresh"]; @@ -232,7 +246,7 @@ void ConfScan::LoadControlJson() #pragma message("these hacks to overcome the json stuff are not nice, TODO!") try { m_rmsd_element_templates = m_defaults["RMSDElement"].get(); - StringList elements = Tools::SplitString(m_rmsd_element_templates, ","); + StringList elements = Tools::SplitString(m_rmsd_element_templates, ";"); for (const std::string& str : elements) m_rmsd_element_templates.push_back(std::stod(str)); @@ -245,15 +259,13 @@ void ConfScan::LoadControlJson() } if (m_RMSDmethod.compare("hybrid") == 0 /* && m_rmsd_element_templates.compare("") == 0 */) { std::cout << "Reordering method hybrid has to be combined with element types. I will chose for you nitrogen and oxygen!" << std::endl; - std::cout << "This is equivalent to adding:\' -rmsdelement 7,8 \' to your argument list!" << std::endl; - m_rmsd_element_templates = "7,8"; + std::cout << "This is equivalent to adding:\' -rmsdelement 7;8 \' to your argument list!" << std::endl; + m_rmsd_element_templates = "7;8"; } m_prev_accepted = Json2KeyWord(m_defaults, "accepted"); if (m_useorders == -1) m_useorders = 10; - - m_do_third = Json2KeyWord(m_defaults, "dothird"); } bool ConfScan::openFile() @@ -387,22 +399,6 @@ bool ConfScan::LoadRestartInformation() error++; continue; } - try { - m_dLI = confscan["RotThreshLoose"]; - } catch (json::type_error& e) { - } - try { - m_dLH = confscan["RipserThreshLoose"]; - } catch (json::type_error& e) { - } - try { - m_dTI = confscan["RotThreshTight"]; - } catch (json::type_error& e) { - } - try { - m_dTH = confscan["RipserThreshTight"]; - } catch (json::type_error& e) { - } try { reorder_cached = Tools::String2VectorVector(confscan["ReorderRules"]); } catch (json::type_error& e) { @@ -461,9 +457,9 @@ void ConfScan::SetUp() m_result_basename.erase(m_result_basename.end() - 4, m_result_basename.end()); m_accepted_filename = m_result_basename + ".accepted.xyz"; - m_1st_filename = m_result_basename + ".1st.xyz"; - m_2nd_filename = m_result_basename + ".2nd.xyz"; - m_3rd_filename = m_result_basename + ".3rd.xyz"; + m_1st_filename = m_result_basename + ".initial.xyz"; + m_2nd_filename = m_result_basename + ".reorder"; + m_3rd_filename = m_result_basename + ".reuse.xyz"; m_rejected_filename = m_result_basename + ".rejected.xyz"; m_statistic_filename = m_result_basename + ".statistic.log"; @@ -523,9 +519,19 @@ void ConfScan::SetUp() std::cout << " Highest energy conformer allowed: " << m_energy_cutoff << " kJ/mol " << std::endl; std::cout << " Threshold multipliers are loose / tight " << std::endl; - std::cout << " Ripser Persitance Diagrams " << m_sLH << " " << m_sTH << std::endl; - std::cout << " Rotational Constants " << m_sLI << " " << m_sTI << std::endl; - std::cout << " Energy " << m_sLE << " " << m_sTE << std::endl; + std::cout << " Ripser Persitance Diagrams definition for loose "; + for (const auto& d : m_sLH) + std::cout << d << " "; + std::cout << " and tight thresholds " << m_sTH << std::endl; + std::cout << " Rotational Constants definition for loose "; + for (const auto& d : m_sLI) + std::cout << d << " "; + std::cout << " and tight thresholds " << m_sTI << std::endl; + + std::cout << " Energy definition for loose "; + for (const auto& d : m_sLE) + std::cout << d << " "; + std::cout << " and tight thresholds " << m_sTE << std::endl; std::cout << "" << std::endl << "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" << std::endl @@ -548,13 +554,21 @@ void ConfScan::RejectMolecule(Molecule* molecule) m_rejected++; } +void ConfScan::WriteDotFile(const std::string& filename, const std::string& content) +{ + std::ofstream result_file; + result_file.open(filename); + result_file << "digraph graphname \n {\n"; + result_file << content << std::endl; + result_file << "}"; +} + void ConfScan::start() { PrintController(m_controller); SetUp(); fmt::print("\n\n1st Pass\nPerforming RMSD calculation without reordering now!\n\n"); - RunTimer timer(false); m_current_filename = m_1st_filename; std::ofstream result_file; @@ -564,13 +578,14 @@ void ConfScan::start() result_file.close(); } if (!m_skipfirst) { - CheckRMSD(); + CheckOnly(m_sLE[0], m_sLI[0], m_sLH[0]); PrintStatus("Result 1st pass:"); - std::ofstream result_file; - result_file.open(m_result_basename + ".first.dot"); - result_file << "digraph graphname \n {\n"; - result_file << m_first_content << std::endl; - result_file << "}"; + WriteDotFile(m_result_basename + ".initial.dot", m_first_content); + m_sLE[0] = 1; + m_sLI[0] = 1; + m_sLH[0] = 1; + m_collective_content = "edge [color=green];\n"; + m_collective_content += m_first_content + "\n"; } else { for (const auto& i : m_ordered_list) m_stored_structures.push_back(m_molecules.at(i.second).second); @@ -578,70 +593,61 @@ void ConfScan::start() #ifdef WriteMoreInfo std::cout << m_dnn_data.size() << std::endl; #endif - fmt::print("\n1st Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); - if (m_prevent_reorder == false || m_do_third == true) { - if (!CheckStop()) { - timer.Reset(); - m_current_filename = m_2nd_filename; - fmt::print("\n\n2nd Pass\nPerforming RMSD calculation with reordering now!\n\n"); - if (m_writeFiles && !m_reduced_file) { - result_file.open(m_statistic_filename, std::ios_base::app); - result_file << "Results of 2nd Pass" << std::endl; - result_file.close(); + fmt::print("\nInitial Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); + + if (!m_noreorderpass) { + for (int run = 0; run < m_sLE.size(); ++run) { + double dLI = m_dLI; + double dLH = m_dLH; + double dLE = m_dLE; + + dLI = m_dLI * m_sLI[run]; + dLH = m_dLH * m_sLH[run]; + dLE = m_dLE * m_sLE[run]; + + if (!CheckStop()) { + timer.Reset(); + m_current_filename = m_2nd_filename + "." + std::to_string(run + 1) + ".xyz"; + fmt::print("\n\nReorder Pass\nPerforming RMSD calculation with reordering now!\n\n"); + if (m_writeFiles && !m_reduced_file) { + result_file.open(m_statistic_filename, std::ios_base::app); + result_file << "Results of Reorder Pass #" << run + 1 << std::endl; + result_file.close(); + } + Reorder(dLE, dLI, dLH, false); + PrintStatus("Result Reorder pass:"); + WriteDotFile(m_result_basename + ".reorder." + std::to_string(run + 1) + ".dot", m_second_content); + fmt::print("\nReorder Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); + timer.Reset(); + m_collective_content += "edge [color=red];\n"; + m_collective_content += m_second_content + "\n"; + m_second_content.clear(); } - ReorderCheck(m_prevent_reorder, false); - PrintStatus("Result 2nd pass:"); - std::ofstream result_file; - result_file.open(m_result_basename + ".second.dot"); - result_file << "digraph graphname \n {\n"; - result_file << m_second_content << std::endl; - result_file << "}"; - fmt::print("\n2nd Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); - timer.Reset(); } - if (!CheckStop() && m_do_third == true) { - m_current_filename.clear(); - m_current_filename = m_3rd_filename; + } else + fmt::print("\nReorder Pass skipped!\n"); + if (n_doreusepass) { + if (!CheckStop()) { + timer.Reset(); + m_current_filename = m_3rd_filename; + fmt::print("\n\nReuse Pass\nPerforming RMSD calculation with stored reorder rules using all structures.\n\n"); if (m_writeFiles && !m_reduced_file) { result_file.open(m_statistic_filename, std::ios_base::app); - result_file << "Results of 3rd Pass" << std::endl; + PrintStatus("Result Reuse pass:"); result_file.close(); } - fmt::print("\n\n3rd Pass\nPerforming RMSD calculation with reordering, and less stricter threshold.\n\n"); - ReorderTrained(); - PrintStatus("Result 3rd pass:"); - std::ofstream result_file; - result_file.open(m_result_basename + ".third.dot"); - result_file << "digraph graphname \n {\n"; - result_file << m_third_content << std::endl; - result_file << "}"; - fmt::print("\n3rd Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); + Reorder(-1, -1, -1, true); + PrintStatus("Result reuse pass:"); + WriteDotFile(m_result_basename + ".reuse.dot", m_second_content); + fmt::print("\nReuse Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); timer.Reset(); + m_collective_content += "edge [color=blue];\n"; + m_collective_content += m_second_content + "\n"; } + } else + fmt::print("\Reuse Pass skipped!\n"); - if (true) { - m_current_filename.clear(); - if (m_writeFiles && !m_reduced_file) { - result_file.open(m_statistic_filename, std::ios_base::app); - result_file << "Results of 4rd Pass" << std::endl; - result_file.close(); - } - m_result.clear(); - m_stored_structures.clear(); - fmt::print("\n\n4rd Pass\nPerforming RMSD calculation with stored reorder rules using all structures.\n\n"); - Check4th(); - PrintStatus("Result 4rd pass:"); - std::ofstream result_file; - result_file.open(m_result_basename + ".fourth.dot"); - result_file << "digraph graphname \n {\n"; - result_file << m_4th_content << std::endl; - result_file << "}"; - fmt::print("\n4rd Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); - } - } - if (!CheckStop()) - m_dE = -1; #ifdef WriteMoreInfo int index = 1; for (const auto& i : m_dnn_data) { @@ -664,17 +670,12 @@ void ConfScan::start() std::ofstream dotfile; dotfile.open(m_result_basename + ".dot"); dotfile << "digraph graphname \n {\n"; - dotfile << "edge [color=green];" << std::endl; - dotfile << m_first_content << std::endl; - dotfile << "edge [color=red];" << std::endl; - dotfile << m_second_content << std::endl; - dotfile << "edge [color=blue];" << std::endl; - dotfile << m_third_content << std::endl; + dotfile << m_collective_content; dotfile << "}"; Finalise(); } -void ConfScan::CheckRMSD() +void ConfScan::CheckOnly(double sLE, double sLI, double sLH) { std::string content_dot; std::string laststring; @@ -712,6 +713,7 @@ void ConfScan::CheckRMSD() ConfScanThreadNoReorder* thread = addThreadNoreorder(mol1, rmsd); threads.push_back(thread); p->addThread(thread); + m_all_structures.push_back(mol1); m_lowest_energy = mol1->Energy(); continue; @@ -733,9 +735,9 @@ void ConfScan::CheckRMSD() m_dTH = std::max(m_dTH, t->DH() * (t->RMSD() <= (m_sTH * m_rmsd_threshold))); m_dTE = std::max(m_dTE, (std::abs(t->Reference()->Energy() - mol1->Energy()) * 2625.5) * (t->RMSD() <= (m_sTE * m_rmsd_threshold))); - m_dLI = std::max(m_dLI, t->DI() * (t->RMSD() <= (m_sLI * m_rmsd_threshold))); - m_dLH = std::max(m_dLH, t->DH() * (t->RMSD() <= (m_sLH * m_rmsd_threshold))); - m_dLE = std::max(m_dLE, (std::abs(t->Reference()->Energy() - mol1->Energy()) * 2625.5) * (t->RMSD() <= (m_sLE * m_rmsd_threshold))); + m_dLI = std::max(m_dLI, t->DI() * (t->RMSD() <= (sLI * m_rmsd_threshold))); + m_dLH = std::max(m_dLH, t->DH() * (t->RMSD() <= (sLH * m_rmsd_threshold))); + m_dLE = std::max(m_dLE, (std::abs(t->Reference()->Energy() - mol1->Energy()) * 2625.5) * (t->RMSD() <= (sLE * m_rmsd_threshold))); if (t->KeepMolecule() == false) { keep_molecule = false; @@ -763,15 +765,15 @@ void ConfScan::CheckRMSD() AcceptMolecule(mol1); } else { RejectMolecule(mol1); - m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(mol1))); } PrintStatus(); + m_all_structures.push_back(mol1); } p->clear(); delete p; } -void ConfScan::PrintSetUp() +void ConfScan::PrintSetUp(double dLE, double dLI, double dLH) { // To be finalised and tested @@ -804,13 +806,13 @@ void ConfScan::PrintSetUp() std::cout << "" << std::endl << "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" << std::endl; std::cout << " Thresholds in rotational constants (averaged over Ia, Ib and Ic): " << std::endl; - std::cout << " Loose Threshold: " << m_dLI << " MHz" << std::endl; + std::cout << " Loose Threshold: " << dLI << " MHz" << std::endl; std::cout << " Tight Threshold: " << m_dTI << " MHz" << std::endl; std::cout << " Thresholds in difference of ripser images: " << std::endl; - std::cout << " Loose Threshold: " << m_dLH << " " << std::endl; + std::cout << " Loose Threshold: " << dLH << " " << std::endl; std::cout << " Tight Threshold: " << m_dTH << " " << std::endl; std::cout << " Thresholds for energy differences in kJ/mol: " << std::endl; - std::cout << " Loose Threshold: " << m_dLE << " " << std::endl; + std::cout << " Loose Threshold: " << dLE << " " << std::endl; std::cout << " Tight Threshold: " << m_dTE << " " << std::endl; std::cout << "" << std::endl @@ -818,12 +820,11 @@ void ConfScan::PrintSetUp() << std::endl; } -void ConfScan::ReorderCheck(bool reuse_only, bool limit) +void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only) { - m_maxmol = m_stored_structures.size(); std::string content_dot; std::string laststring; - PrintSetUp(); + PrintSetUp(dLE, dLI, dLH); /* if ignore rotation or ignore barcode are true, the tight cutoffs are set to -1, that no difference is smaller * than the tight threshold and the loose threshold is set to a big number, that every structure has to be reordered*/ m_skiped = 0; @@ -854,7 +855,13 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) rmsd["molalignbin"] = m_molalign; rmsd["molaligntol"] = m_molaligntol; - std::vector cached = m_stored_structures; + std::vector cached; + if (dLE < 0 && dLI < 0 && dLH < 0) + cached = m_all_structures; + else + cached = m_stored_structures; + m_maxmol = cached.size(); + m_result = m_previously_accepted; m_stored_structures.clear(); std::vector threads; @@ -869,8 +876,6 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) threads.push_back(thread); p->addThread(thread); m_lowest_energy = mol1->Energy(); - m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(mol1))); - continue; } p->Reset(); @@ -896,8 +901,8 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) /* rotational = 1 * ripser = 2 * energy = 4 */ - int looseThresh = 1 * (dI < m_dLI) + 2 * (dH < m_dLH) + 4 * (std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < m_dLE); - if ((looseThresh & m_looseThresh) == m_looseThresh || (m_dLI == 0 && m_dLH == 0 && m_dLE == 0)) { + int looseThresh = 1 * (dI < dLI) + 2 * (dH < dLH) + 4 * (std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < dLE); + if ((looseThresh & m_looseThresh) == m_looseThresh || (dLI <= 1e-8 && dLH <= 1e-8 && dLE <= 1e-8)) { reorder = true; threads[t]->setEnabled(m_openLoop); int tightThresh = 1 * (dI < m_dTI) + 2 * (dH < m_dTH) + 4 * ((std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < m_dTE)); @@ -972,10 +977,7 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) laststring = t->Reference()->Name(); writeStatisticFile(t->Reference(), mol1, t->RMSD(), true, t->ReorderRule()); - // mol1->print_geom(); mol1->ApplyReorderRule(t->ReorderRule()); - // mol1->print_geom(); - break; } else { if ((m_domolalign > 1) && t->RMSD() < m_domolalign * m_rmsd_threshold) { @@ -987,7 +989,6 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) driver.setReference(t->Reference()); driver.setTarget(mol1); driver.start(); - // m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(driver.TargetReorderd()))); mol1->LoadMolecule(driver.TargetReorderd()); if (driver.RMSD() < m_rmsd_threshold) { m_molalign_success++; @@ -1020,11 +1021,9 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) threads.push_back(thread); } else { RejectMolecule(mol1); - m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(mol1))); } - PrintStatus(); - if ((m_result.size() >= m_maxrank && limit) || (m_result.size() >= 2 * m_maxrank && !limit)) + if (m_result.size() >= m_maxrank) break; if (m_dE > m_energy_cutoff && m_energy_cutoff != -1) { break; @@ -1034,10 +1033,9 @@ void ConfScan::ReorderCheck(bool reuse_only, bool limit) delete p; } -void ConfScan::ReorderTrained() +void ConfScan::ReuseOnly() { bool reuse_only = false; - bool limit = false; m_molalign_count = 0; m_molalign_success = 0; @@ -1061,7 +1059,7 @@ void ConfScan::ReorderTrained() m_dLH *= 2; m_dLE *= 2; - PrintSetUp(); + PrintSetUp(m_dLI, m_dLH, m_dLE); TriggerWriteRestart(); @@ -1125,7 +1123,7 @@ void ConfScan::ReorderTrained() * ripser = 2 * energy = 4 */ int looseThresh = 1 * (dI < m_dLI) + 2 * (dH < m_dLH) + 4 * (std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < m_dLE); - if ((looseThresh & m_looseThresh) == m_looseThresh || (m_dLI == 0 && m_dLH == 0 && m_dLE == 0)) { + if ((looseThresh & m_looseThresh) == m_looseThresh /* || (m_dLI == 0 && m_dLH == 0 && m_dLE == 0)*/) { reorder = true; threads[t]->setEnabled(m_openLoop); int tightThresh = 1 * (dI < m_dTI) + 2 * (dH < m_dTH) + 4 * ((std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < m_dTE)); @@ -1188,7 +1186,6 @@ void ConfScan::ReorderTrained() rules.push_back(t->ReorderRule()); writeStatisticFile(t->Reference(), mol1, t->RMSD(), true, t->ReorderRule()); - // m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(t->Target()))); mol1->ApplyReorderRule(t->ReorderRule()); if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) @@ -1210,7 +1207,6 @@ void ConfScan::ReorderTrained() driver.setReference(t->Reference()); driver.setTarget(mol1); driver.start(); - // m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(driver.TargetReorderd()))); mol1->LoadMolecule(driver.TargetReorderd()); if (driver.RMSD() < m_rmsd_threshold) { m_molalign_success++; @@ -1238,7 +1234,6 @@ void ConfScan::ReorderTrained() if (keep_molecule) { AcceptMolecule(mol1); - // m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(mol1))); ConfScanThread* thread = addThread(mol1, rmsd, reuse_only); p->addThread(thread); @@ -1248,18 +1243,17 @@ void ConfScan::ReorderTrained() } PrintStatus(); - if ((m_result.size() >= m_maxrank && limit) || (m_result.size() >= 2 * m_maxrank && !limit)) + if (m_result.size() >= 2 * m_maxrank) break; if (m_dE > m_energy_cutoff && m_energy_cutoff != -1) { break; } - m_final_batch.insert(std::pair(mol1->Energy(), new Molecule(mol1))); } p->clear(); delete p; } - -void ConfScan::Check4th() +/* +void ConfScan::ReuseOnly() { m_stored_structures.clear(); m_maxmol = m_final_batch.size(); @@ -1348,7 +1342,7 @@ void ConfScan::Check4th() p->clear(); delete p; } - +*/ ConfScanThreadNoReorder* ConfScan::addThreadNoreorder(const Molecule* reference, const json& config) { ConfScanThreadNoReorder* thread = new ConfScanThreadNoReorder(m_rmsd_threshold, m_MaxHTopoDiff, config); diff --git a/src/capabilities/confscan.h b/src/capabilities/confscan.h index adff8a1..7961f90 100644 --- a/src/capabilities/confscan.h +++ b/src/capabilities/confscan.h @@ -50,15 +50,17 @@ static const json ConfScanJson = { { "rank", -1 }, { "writeXYZ", false }, { "forceReorder", false }, + { "noreorderpass", false }, + { "doreuse", false }, { "check", false }, { "energy", 1.0 }, { "maxenergy", -1.0 }, { "preventreorder", false }, - { "sLE", 1.0 }, + { "sLE", "1.0;2.0" }, { "sTE", 0.1 }, - { "sLI", 1.0 }, + { "sLI", "1.0;2.0" }, { "sTI", 0.1 }, - { "sLH", 1.0 }, + { "sLH", "1.0;2.0" }, { "sTH", 0.1 }, { "skip", 0 }, { "allxyz", false }, @@ -73,7 +75,6 @@ static const json ConfScanJson = { { "method", "" }, { "lastdE", -1 }, { "fewerFile", false }, - { "dothird", true }, { "skipfirst", false }, { "ignoreRotation", false }, { "ignoreBarCode", false }, @@ -265,18 +266,20 @@ class ConfScan : public CurcumaMethod { void ParametriseRotationalCutoffs(); void start() override; // TODO make pure virtual and move all main action here - ConfScanThread* addThread(const Molecule* reference, const json& config, bool reuse_only); + ConfScanThread* addThread(const Molecule* reference, const json& config, bool reuse_only = false); ConfScanThreadNoReorder* addThreadNoreorder(const Molecule* reference, const json& config); private: - void PrintSetUp(); + void PrintSetUp(double dLE, double dLI, double dLH); void SetUp(); void CheckRMSD(); - void ReorderCheck(bool reuse_only = false, bool limit = false); - void ReorderTrained(); - void Check4th(); + void CheckOnly(double sLE, double sLI, double sLH); + void Reorder(double dLE, double dLI, double dLH, bool reuse_only = false); + void ReuseOnly(); + + void WriteDotFile(const std::string& filename, const std::string& content); void writeStatisticFile(const Molecule* mol1, const Molecule* mol2, double rmsd, bool reason = true, const std::vector& rule = std::vector(0)); @@ -315,29 +318,29 @@ class ConfScan : public CurcumaMethod { std::string m_filename, m_accepted_filename, m_1st_filename, m_2nd_filename, m_3rd_filename, m_rejected_filename, m_result_basename, m_statistic_filename, m_prev_accepted, m_joined_filename, m_threshold_filename, m_current_filename; std::map m_ordered_list; - std::map m_final_batch; std::vector> m_molecules; double m_rmsd_threshold = 1.0, m_nearly_missed = 0.8, m_energy_cutoff = -1, m_reference_last_energy = 0, m_target_last_energy = 0, m_lowest_energy = 1, m_current_energy = 0; - double m_sTE = 0.1, m_sLE = 1.5; - double m_sTI = 0.1, m_sLI = 1.5; - double m_sTH = 0.1, m_sLH = 1.5; + double m_sTE = 0.1; /* m_sLE = 1.0; */ + double m_sTI = 0.1; /* m_sLI = 1.0; */ + double m_sTH = 0.1; /* m_sLH = 1.0; */ double m_reference_restored_energy = -1e10, m_target_restored_energy = -1e10; double m_dLI = 0.0, m_dLH = 0.0, m_dLE = 0.0; double m_dTI = 0.0, m_dTH = 0.0, m_dTE = 0.0; - std::vector m_result, m_rejected_structures, m_stored_structures, m_previously_accepted; + std::vector m_result, m_rejected_structures, m_stored_structures, m_previously_accepted, m_all_structures; std::vector m_threshold; std::vector m_element_templates; std::vector> m_exclude_list; #ifdef WriteMoreInfo std::vector m_dnn_data; #endif - std::string m_first_content, m_second_content, m_third_content, m_4th_content; + std::string m_first_content, m_second_content, m_third_content, m_4th_content, m_collective_content; std::string m_rmsd_element_templates; std::string m_method = ""; std::string m_molalign = "molalign"; + std::vector m_sLE = { 1.0 }, m_sLI = { 1.0 }, m_sLH = { 1.0 }; double m_domolalign = -1; double m_lastDI = 0.0, m_lastDH = 0.0, m_lastdE = -1, m_dE = -1, m_damping = 0.8; int m_maxmol = 0; @@ -364,7 +367,6 @@ class ConfScan : public CurcumaMethod { bool m_allxyz = false; bool m_update = false; bool m_reduced_file = false; - bool m_do_third = false; bool m_skipfirst = false; bool m_ignoreRotation = false; bool m_ignoreBarCode = false; @@ -373,4 +375,6 @@ class ConfScan : public CurcumaMethod { bool m_split = false; bool m_write = false; bool m_nomunkres = false; + bool m_noreorderpass = false; + bool n_doreusepass = false; }; diff --git a/src/capabilities/rmsd.cpp b/src/capabilities/rmsd.cpp index ffe4189..13c8b4a 100644 --- a/src/capabilities/rmsd.cpp +++ b/src/capabilities/rmsd.cpp @@ -173,7 +173,7 @@ void RMSDDriver::LoadControlJson() #pragma message("these hacks to overcome the json stuff are not nice, TODO!") try { std::string element = m_defaults["Element"].get(); - StringList elements = Tools::SplitString(element, ","); + StringList elements = Tools::SplitString(element, ";"); for (const std::string& str : elements) { try { m_element_templates.push_back(std::stod(str)); diff --git a/src/tools/general.h b/src/tools/general.h index eeca749..60a30ed 100644 --- a/src/tools/general.h +++ b/src/tools/general.h @@ -380,11 +380,11 @@ inline std::string DoublePtr2String(const double* array, int size) return result; } -inline std::vector String2DoubleVec(const std::string& str) +inline std::vector String2DoubleVec(const std::string& str, const char* delim = ";") { std::vector result; - StringList vectors = SplitString(str, "|"); + StringList vectors = SplitString(str, delim); for (const auto& element : vectors) result.push_back(std::stod(element)); From 9c0318bd6be42ebd3a89cb97a45a3c846cf0b9c5 Mon Sep 17 00:00:00 2001 From: conradhuebler Date: Thu, 15 Jun 2023 16:26:10 +0200 Subject: [PATCH 04/10] more work on confscan Signed-off-by: conradhuebler --- src/capabilities/confscan.cpp | 428 +++++----------------------------- src/capabilities/confscan.h | 25 +- src/capabilities/rmsd.cpp | 2 +- src/core/eigen_uff.cpp | 12 +- 4 files changed, 80 insertions(+), 387 deletions(-) diff --git a/src/capabilities/confscan.cpp b/src/capabilities/confscan.cpp index a8c9be2..8c9dc2e 100644 --- a/src/capabilities/confscan.cpp +++ b/src/capabilities/confscan.cpp @@ -180,30 +180,32 @@ void ConfScan::LoadControlJson() m_force_reorder = Json2KeyWord(m_defaults, "forceReorder"); m_check_connections = Json2KeyWord(m_defaults, "check"); m_energy_cutoff = Json2KeyWord(m_defaults, "maxenergy"); - m_prevent_reorder = Json2KeyWord(m_defaults, "preventReorder"); if (m_defaults["sLE"].is_number()) m_sLE = { Json2KeyWord(m_defaults, "sLE") }; else if (m_defaults["sLE"].is_string()) - m_sLE = Tools::String2DoubleVec(Json2KeyWord(m_defaults, "sLE"), ";"); + m_sLE = Tools::String2DoubleVec(Json2KeyWord(m_defaults, "sLE"), ","); if (m_defaults["sLI"].is_number()) m_sLI = { Json2KeyWord(m_defaults, "sLI") }; else if (m_defaults["sLI"].is_string()) - m_sLI = Tools::String2DoubleVec(Json2KeyWord(m_defaults, "sLI"), ";"); + m_sLI = Tools::String2DoubleVec(Json2KeyWord(m_defaults, "sLI"), ","); if (m_defaults["sLH"].is_number()) m_sLH = { Json2KeyWord(m_defaults, "sLH") }; else if (m_defaults["sLH"].is_string()) - m_sLH = Tools::String2DoubleVec(Json2KeyWord(m_defaults, "sLH"), ";"); + m_sLH = Tools::String2DoubleVec(Json2KeyWord(m_defaults, "sLH"), ","); if (m_sLE.size() != m_sLI.size() || m_sLE.size() != m_sLH.size()) { std::cout << "Inconsistent length of steps requested, will abort now." << std::endl; exit(1); } - m_noreorderpass = Json2KeyWord(m_defaults, "noreorderpass"); - n_doreusepass = Json2KeyWord(m_defaults, "doreuse"); + m_reset = Json2KeyWord(m_defaults, "reset"); + + m_skipinit = Json2KeyWord(m_defaults, "skipinit"); + m_skipreorder = Json2KeyWord(m_defaults, "skipreorder"); + m_skipreuse = Json2KeyWord(m_defaults, "skipreuse"); m_sTE = Json2KeyWord(m_defaults, "sTE"); m_sTI = Json2KeyWord(m_defaults, "sTI"); @@ -221,7 +223,6 @@ void ConfScan::LoadControlJson() m_useorders = Json2KeyWord(m_defaults, "UseOrders"); m_MaxHTopoDiff = Json2KeyWord(m_defaults, "MaxHTopoDiff"); m_threads = m_defaults["threads"].get(); - m_skipfirst = Json2KeyWord(m_defaults, "skipfirst"); m_RMSDmethod = Json2KeyWord(m_defaults, "RMSDMethod"); if (m_RMSDmethod == "molalign") { fmt::print(fg(fmt::color::green) | fmt::emphasis::bold, "\nPlease cite the follow research report!\nJ. Chem. Inf. Model. 2023, 63, 4, 1157–1165 - DOI: 10.1021/acs.jcim.2c01187\n\n"); @@ -237,16 +238,13 @@ void ConfScan::LoadControlJson() m_molalign = Json2KeyWord(m_defaults, "molalignbin"); m_molaligntol = Json2KeyWord(m_defaults, "molaligntol"); - m_openLoop = true; - m_closeLoop = false; - m_looseThresh = m_defaults["looseThresh"]; m_tightThresh = m_defaults["tightThresh"]; #pragma message("these hacks to overcome the json stuff are not nice, TODO!") try { m_rmsd_element_templates = m_defaults["RMSDElement"].get(); - StringList elements = Tools::SplitString(m_rmsd_element_templates, ";"); + StringList elements = Tools::SplitString(m_rmsd_element_templates, ","); for (const std::string& str : elements) m_rmsd_element_templates.push_back(std::stod(str)); @@ -259,8 +257,8 @@ void ConfScan::LoadControlJson() } if (m_RMSDmethod.compare("hybrid") == 0 /* && m_rmsd_element_templates.compare("") == 0 */) { std::cout << "Reordering method hybrid has to be combined with element types. I will chose for you nitrogen and oxygen!" << std::endl; - std::cout << "This is equivalent to adding:\' -rmsdelement 7;8 \' to your argument list!" << std::endl; - m_rmsd_element_templates = "7;8"; + std::cout << "This is equivalent to adding:\' -rmsdelement 7,8 \' to your argument list!" << std::endl; + m_rmsd_element_templates = "7,8"; } m_prev_accepted = Json2KeyWord(m_defaults, "accepted"); @@ -373,8 +371,7 @@ bool ConfScan::LoadRestartInformation() if (!Restart()) return false; StringList files = RestartFiles(); - if (!m_prevent_reorder) - m_prevent_reorder = files.size() > 1; + int error = 0; for (const auto& f : files) { std::vector> reorder_cached; @@ -391,7 +388,6 @@ bool ConfScan::LoadRestartInformation() error++; continue; } - json confscan; try { confscan = restart[MethodName()[0]]; @@ -422,7 +418,6 @@ bool ConfScan::LoadRestartInformation() m_reorder_rules.push_back(vector); } m_useRestart = files.size() == 1 && error != int(files.size()); - std::cout << "Starting with " << m_reorder_rules.size() << " initial reorder rules." << std::endl; return true; } @@ -501,12 +496,6 @@ void ConfScan::SetUp() st_file.close(); } - std::ofstream nd_file; - if (m_writeFiles && !m_reduced_file) { - nd_file.open(m_2nd_filename); - nd_file.close(); - } - std::cout << "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" << std::endl << "" << std::endl; @@ -568,35 +557,50 @@ void ConfScan::start() PrintController(m_controller); SetUp(); - fmt::print("\n\n1st Pass\nPerforming RMSD calculation without reordering now!\n\n"); - RunTimer timer(false); - m_current_filename = m_1st_filename; - std::ofstream result_file; - if (m_writeFiles && !m_reduced_file) { - result_file.open(m_statistic_filename, std::ios_base::app); - result_file << "Results of 1st Pass" << std::endl; - result_file.close(); - } - if (!m_skipfirst) { + if (!m_skipinit) { + fmt::print("\n\nInitial Pass\nPerforming RMSD calculation without reordering now!\n\n"); + RunTimer timer(false); + m_current_filename = m_1st_filename; + std::ofstream result_file; + if (m_writeFiles && !m_reduced_file) { + result_file.open(m_statistic_filename, std::ios_base::app); + result_file << "Results of 1st Pass" << std::endl; + result_file.close(); + } CheckOnly(m_sLE[0], m_sLI[0], m_sLH[0]); - PrintStatus("Result 1st pass:"); + PrintStatus("Result initial pass:"); WriteDotFile(m_result_basename + ".initial.dot", m_first_content); m_sLE[0] = 1; m_sLI[0] = 1; m_sLH[0] = 1; m_collective_content = "edge [color=green];\n"; m_collective_content += m_first_content + "\n"; +#ifdef WriteMoreInfo + std::cout << m_dnn_data.size() << std::endl; +#endif + fmt::print("\nInitial Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); + } else { + fmt::print("\n\nSkipping initial pass!\n\nSettings thresholds to high value ..."); + for (const auto& i : m_ordered_list) m_stored_structures.push_back(m_molecules.at(i.second).second); + m_dLI = 1e23; + m_dLH = 1e23; + m_dLE = 1e23; + m_looseThresh = 0; + m_skipreuse = true; } -#ifdef WriteMoreInfo - std::cout << m_dnn_data.size() << std::endl; -#endif - fmt::print("\nInitial Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); - if (!m_noreorderpass) { + if (!m_skipreorder) { for (int run = 0; run < m_sLE.size(); ++run) { + m_current_filename = m_2nd_filename + "." + std::to_string(run + 1) + ".xyz"; + + std::ofstream nd_file; + if (m_writeFiles && !m_reduced_file) { + nd_file.open(m_current_filename); + nd_file.close(); + } double dLI = m_dLI; double dLH = m_dLH; double dLE = m_dLE; @@ -607,7 +611,6 @@ void ConfScan::start() if (!CheckStop()) { timer.Reset(); - m_current_filename = m_2nd_filename + "." + std::to_string(run + 1) + ".xyz"; fmt::print("\n\nReorder Pass\nPerforming RMSD calculation with reordering now!\n\n"); if (m_writeFiles && !m_reduced_file) { result_file.open(m_statistic_filename, std::ios_base::app); @@ -626,18 +629,21 @@ void ConfScan::start() } } else fmt::print("\nReorder Pass skipped!\n"); - - if (n_doreusepass) { + if (!m_skipreuse) { if (!CheckStop()) { timer.Reset(); m_current_filename = m_3rd_filename; - fmt::print("\n\nReuse Pass\nPerforming RMSD calculation with stored reorder rules using all structures.\n\n"); + if (m_reset) + fmt::print("\n\nReuse Pass\nPerforming RMSD calculation with stored reorder rules using all structures.\n\n"); + else + fmt::print("\n\nReuse Pass\nPerforming RMSD calculation with stored reorder rules using previously accepted structures.\n\n"); + if (m_writeFiles && !m_reduced_file) { result_file.open(m_statistic_filename, std::ios_base::app); PrintStatus("Result Reuse pass:"); result_file.close(); } - Reorder(-1, -1, -1, true); + Reorder(-1, -1, -1, true, m_reset); PrintStatus("Result reuse pass:"); WriteDotFile(m_result_basename + ".reuse.dot", m_second_content); fmt::print("\nReuse Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); @@ -645,9 +651,7 @@ void ConfScan::start() m_collective_content += "edge [color=blue];\n"; m_collective_content += m_second_content + "\n"; } - } else - fmt::print("\Reuse Pass skipped!\n"); - + } #ifdef WriteMoreInfo int index = 1; for (const auto& i : m_dnn_data) { @@ -730,7 +734,6 @@ void ConfScan::CheckOnly(double sLE, double sLI, double sLH) p->StartAndWait(); for (auto* t : threads) { - m_dTI = std::max(m_dTI, t->DI() * (t->RMSD() <= (m_sTI * m_rmsd_threshold))); m_dTH = std::max(m_dTH, t->DH() * (t->RMSD() <= (m_sTH * m_rmsd_threshold))); m_dTE = std::max(m_dTE, (std::abs(t->Reference()->Energy() - mol1->Energy()) * 2625.5) * (t->RMSD() <= (m_sTE * m_rmsd_threshold))); @@ -820,7 +823,7 @@ void ConfScan::PrintSetUp(double dLE, double dLI, double dLH) << std::endl; } -void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only) +void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only, bool reset) { std::string content_dot; std::string laststring; @@ -856,7 +859,7 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only) rmsd["molaligntol"] = m_molaligntol; std::vector cached; - if (dLE < 0 && dLI < 0 && dLH < 0) + if (reset) cached = m_all_structures; else cached = m_stored_structures; @@ -891,10 +894,15 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only) return; } const Molecule* mol2 = threads[t]->Reference(); + std::pair names(mol1->Name(), mol2->Name()); + if (std::find(m_exclude_list.begin(), m_exclude_list.end(), names) != m_exclude_list.end()) { + m_duplicated++; + continue; + } + double Ia = abs(mol1->Ia() - mol2->Ia()); double Ib = abs(mol1->Ib() - mol2->Ib()); double Ic = abs(mol1->Ic() - mol2->Ic()); - double dI = (Ia + Ib + Ic) * third; double dH = (mol1->getPersisentImage() - mol2->getPersisentImage()).cwiseAbs().sum(); @@ -904,7 +912,7 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only) int looseThresh = 1 * (dI < dLI) + 2 * (dH < dLH) + 4 * (std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < dLE); if ((looseThresh & m_looseThresh) == m_looseThresh || (dLI <= 1e-8 && dLH <= 1e-8 && dLE <= 1e-8)) { reorder = true; - threads[t]->setEnabled(m_openLoop); + threads[t]->setEnabled(true); int tightThresh = 1 * (dI < m_dTI) + 2 * (dH < m_dTH) + 4 * ((std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < m_dTE)); if ((tightThresh & m_tightThresh) == m_tightThresh) { @@ -919,10 +927,8 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only) break; } m_exclude_list.push_back(std::pair(mol1->Name(), mol2->Name())); - - } else { - threads[t]->setEnabled(m_closeLoop); - } + } else + threads[t]->setEnabled(false); } if (reorder && keep_molecule) { @@ -1033,316 +1039,6 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only) delete p; } -void ConfScan::ReuseOnly() -{ - bool reuse_only = false; - m_molalign_count = 0; - m_molalign_success = 0; - - m_maxmol = m_stored_structures.size(); - std::string content_dot; - std::string laststring; - - /* if ignore rotation or ignore barcode are true, the tight cutoffs are set to -1, that no difference is smaller - * than the tight threshold and the loose threshold is set to a big number, that every structure has to be reordered*/ - m_skiped = 0; - m_rejected_directly = 0; - if (m_ignoreRotation == true) { - m_dLI = 1e10; - m_dTI = -1; - } - if (m_ignoreBarCode == true) { - m_dLH = 1e10; - m_dTH = -1; - } - m_dLI *= 2; - m_dLH *= 2; - m_dLE *= 2; - - PrintSetUp(m_dLI, m_dLH, m_dLE); - - TriggerWriteRestart(); - - m_rejected = 0, m_accepted = 0, m_reordered = 0, m_reordered_worked = 0, m_reordered_reused = 0; - - json rmsd = RMSDJson; - rmsd["silent"] = true; - rmsd["reorder"] = true; - rmsd["check"] = CheckConnections(); - rmsd["heavy"] = m_heavy; - rmsd["method"] = m_RMSDmethod; - rmsd["element"] = m_rmsd_element_templates; - rmsd["update-rotation"] = m_update_rotation; - rmsd["damping"] = m_damping; - rmsd["nomunkres"] = m_nomunkres; - rmsd["molalignbin"] = m_molalign; - std::vector cached = m_stored_structures; - m_result = m_previously_accepted; - m_stored_structures.clear(); - std::vector threads; - std::vector> rules; - CxxThreadPool* p = new CxxThreadPool; - p->setActiveThreadCount(m_threads); - - for (Molecule* mol1 : cached) { - if (m_result.size() == 0) { - AcceptMolecule(mol1); - ConfScanThread* thread = addThread(mol1, rmsd, reuse_only); - threads.push_back(thread); - p->addThread(thread); - m_lowest_energy = mol1->Energy(); - continue; - } - p->Reset(); - m_current_energy = mol1->Energy(); - m_dE = (m_current_energy - m_lowest_energy) * 2625.5; - - bool keep_molecule = true; - bool reorder = false; - for (int t = 0; t < threads.size(); ++t) { - if (CheckStop()) { - fmt::print("\n\n** Found stop file, will end now! **\n\n"); - // TriggerWriteRestart(); - return; - } - const Molecule* mol2 = threads[t]->Reference(); - std::pair names(mol1->Name(), mol2->Name()); - if (std::find(m_exclude_list.begin(), m_exclude_list.end(), names) != m_exclude_list.end()) { - m_duplicated++; - continue; - } - double Ia = abs(mol1->Ia() - mol2->Ia()); - double Ib = abs(mol1->Ib() - mol2->Ib()); - double Ic = abs(mol1->Ic() - mol2->Ic()); - - double dI = (Ia + Ib + Ic) * third; - - double dH = (mol1->getPersisentImage() - mol2->getPersisentImage()).cwiseAbs().sum(); - - /* rotational = 1 - * ripser = 2 - * energy = 4 */ - int looseThresh = 1 * (dI < m_dLI) + 2 * (dH < m_dLH) + 4 * (std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < m_dLE); - if ((looseThresh & m_looseThresh) == m_looseThresh /* || (m_dLI == 0 && m_dLH == 0 && m_dLE == 0)*/) { - reorder = true; - threads[t]->setEnabled(m_openLoop); - int tightThresh = 1 * (dI < m_dTI) + 2 * (dH < m_dTH) + 4 * ((std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < m_dTE)); - - if ((tightThresh & m_tightThresh) == m_tightThresh) { - std::cout << "Differences " << dI << " MHz and " << dH << " below tight threshold, reject molecule directly!" << std::endl; - m_lastDI = dI; - m_lastDH = dH; - writeStatisticFile(mol1, mol2, -1, false); - m_threshold.push_back(mol2); - m_rejected_directly++; - reorder = false; - keep_molecule = false; - break; - } - } else { - threads[t]->setEnabled(m_closeLoop); - } - } - - if (reorder && keep_molecule) { - int free_threads = m_threads; - if (threads.size()) - free_threads /= threads.size(); - - if (free_threads < 1) - free_threads = 1; - for (int i = 0; i < threads.size(); ++i) { - threads[i]->setTarget(mol1); - threads[i]->setReorderRules(m_reorder_rules); - threads[i]->setThreads(free_threads); - for (int j = 0; j < rules.size(); ++j) - threads[i]->addReorderRule(rules[j]); - } - - if (m_RMSDmethod.compare("molalign") != 0 || m_threads == 1) { - p->StaticPool(); - p->StartAndWait(); - } else { - for (auto* t : threads) { - t->execute(); - if (t->KeepMolecule() == false) - break; - } - } - - for (auto* t : threads) { - if (!t->isEnabled()) { - t->setEnabled(true); - m_skiped++; - continue; - } - - m_reordered++; - if (t->KeepMolecule() == false) { - keep_molecule = false; - m_reordered_worked += t->ReorderWorked(); - m_reordered_reused += t->ReusedWorked(); - if (AddRules(t->ReorderRule())) - rules.push_back(t->ReorderRule()); - - writeStatisticFile(t->Reference(), mol1, t->RMSD(), true, t->ReorderRule()); - mol1->ApplyReorderRule(t->ReorderRule()); - - if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) - m_third_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; - - m_third_content += "\"" + t->Reference()->Name() + "\" [shape=box, label=\"" + t->Reference()->Name() + "\"];\n"; - m_third_content += "\"" + mol1->Name() + "\" [label=\"" + mol1->Name() + "\"];\n"; - m_third_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\" [style=bold,label=" + std::to_string(t->RMSD()) + "];\n"; - - laststring = t->Reference()->Name(); - break; - } else { - if ((m_domolalign > 1) && t->RMSD() < m_domolalign * m_rmsd_threshold) { - fmt::print(fg(fmt::color::yellow) | fmt::emphasis::bold, "Starting molalign for more precise reordering ...\n"); - json molalign = rmsd; - molalign["method"] = "molalign"; - m_molalign_count++; - RMSDDriver driver(molalign); - driver.setReference(t->Reference()); - driver.setTarget(mol1); - driver.start(); - mol1->LoadMolecule(driver.TargetReorderd()); - if (driver.RMSD() < m_rmsd_threshold) { - m_molalign_success++; - keep_molecule = false; - - if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) - m_third_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; - - m_third_content += "\"" + mol1->Name() + "\" [shape=box, style=filled,color=\".7 .3 1.0\"];\n"; - m_third_content += "\"" + t->Reference()->Name() + "\" [shape=box];\n"; - m_third_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\" [style=bold,label=" + std::to_string(driver.RMSD()) + "];\n"; - - laststring = t->Reference()->Name(); - m_reordered_worked += 1; - m_reordered_reused += 1; - writeStatisticFile(t->Reference(), mol1, driver.RMSD(), true, { 0, 0 }); - fmt::print(fg(fmt::color::yellow) | fmt::emphasis::bold, "... success!\n"); - } else - fmt::print(fg(fmt::color::yellow) | fmt::emphasis::bold, "... without effect!\n"); - } - } - } - } else - m_skiped += threads.size(); - - if (keep_molecule) { - AcceptMolecule(mol1); - - ConfScanThread* thread = addThread(mol1, rmsd, reuse_only); - p->addThread(thread); - threads.push_back(thread); - } else { - RejectMolecule(mol1); - } - - PrintStatus(); - if (m_result.size() >= 2 * m_maxrank) - break; - if (m_dE > m_energy_cutoff && m_energy_cutoff != -1) { - break; - } - } - p->clear(); - delete p; -} -/* -void ConfScan::ReuseOnly() -{ - m_stored_structures.clear(); - m_maxmol = m_final_batch.size(); - m_rejected = 0; - m_reordered_reused = 0; - m_reordered_worked = 0; - m_skiped = 0; - std::string content_dot; - std::string laststring; - m_maxmol = m_ordered_list.size(); - - json rmsd = RMSDJson; - rmsd["silent"] = true; - rmsd["check"] = CheckConnections(); - rmsd["heavy"] = m_heavy; - rmsd["noreorder"] = true; - - std::vector threads; - std::vector> rules; - CxxThreadPool* p = new CxxThreadPool; - p->setActiveThreadCount(m_threads); - - for (auto& i : m_final_batch) { - if (m_skip) { - m_skip--; - continue; - } - if (m_maxrank <= m_accepted && m_maxrank > -1) - continue; - - Molecule* mol1 = i.second; - if (mol1->Check() == 1) { - m_rejected++; - m_start++; - PrintStatus(); - continue; - } - if (m_result.size() == 0) { - AcceptMolecule(mol1); - ConfScanThreadNoReorder* thread = addThreadNoreorder(mol1, rmsd); - threads.push_back(thread); - p->addThread(thread); - - m_lowest_energy = mol1->Energy(); - continue; - } - p->Reset(); - m_current_energy = mol1->Energy(); - m_dE = (m_current_energy - m_lowest_energy) * 2625.5; - - bool keep_molecule = true; - for (int i = 0; i < threads.size(); ++i) { - threads[i]->setTarget(mol1); - } - p->StaticPool(); - p->StartAndWait(); - - for (auto* t : threads) { - - if (t->KeepMolecule() == false) { - keep_molecule = false; - writeStatisticFile(t->Reference(), mol1, t->RMSD()); - - if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) - m_4th_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; - - m_4th_content += "\"" + t->Reference()->Name() + "\" [shape=box, label=\"" + t->Reference()->Name() + "\"];\n"; - m_4th_content += "\"" + mol1->Name() + "\" [label=\"" + mol1->Name() + "\"];\n"; - m_4th_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\" [style=bold,label=" + std::to_string(t->RMSD()) + "];\n"; - laststring = t->Reference()->Name(); - - break; - } - } - - if (keep_molecule) { - ConfScanThreadNoReorder* thread = addThreadNoreorder(mol1, rmsd); - threads.push_back(thread); - p->addThread(thread); - AcceptMolecule(mol1); - } else { - RejectMolecule(mol1); - } - PrintStatus(); - } - p->clear(); - delete p; -} -*/ ConfScanThreadNoReorder* ConfScan::addThreadNoreorder(const Molecule* reference, const json& config) { ConfScanThreadNoReorder* thread = new ConfScanThreadNoReorder(m_rmsd_threshold, m_MaxHTopoDiff, config); diff --git a/src/capabilities/confscan.h b/src/capabilities/confscan.h index 7961f90..970fc24 100644 --- a/src/capabilities/confscan.h +++ b/src/capabilities/confscan.h @@ -50,17 +50,17 @@ static const json ConfScanJson = { { "rank", -1 }, { "writeXYZ", false }, { "forceReorder", false }, + { "reset", false }, { "noreorderpass", false }, - { "doreuse", false }, { "check", false }, { "energy", 1.0 }, { "maxenergy", -1.0 }, { "preventreorder", false }, - { "sLE", "1.0;2.0" }, + { "sLE", "1.0,2.0" }, { "sTE", 0.1 }, - { "sLI", "1.0;2.0" }, + { "sLI", "1.0,2.0" }, { "sTI", 0.1 }, - { "sLH", "1.0;2.0" }, + { "sLH", "1.0,2.0" }, { "sTH", 0.1 }, { "skip", 0 }, { "allxyz", false }, @@ -75,10 +75,11 @@ static const json ConfScanJson = { { "method", "" }, { "lastdE", -1 }, { "fewerFile", false }, - { "skipfirst", false }, + { "skipinit", false }, + { "skipreorder", false }, + { "skipreuse", false }, { "ignoreRotation", false }, { "ignoreBarCode", false }, - { "skipless", false }, { "looseThresh", 7 }, { "tightThresh", 3 }, { "update-rotation", false }, @@ -276,8 +277,7 @@ class ConfScan : public CurcumaMethod { void CheckRMSD(); void CheckOnly(double sLE, double sLI, double sLH); - void Reorder(double dLE, double dLI, double dLH, bool reuse_only = false); - void ReuseOnly(); + void Reorder(double dLE, double dLI, double dLH, bool reuse_only = false, bool reset = false); void WriteDotFile(const std::string& filename, const std::string& content); @@ -367,14 +367,15 @@ class ConfScan : public CurcumaMethod { bool m_allxyz = false; bool m_update = false; bool m_reduced_file = false; - bool m_skipfirst = false; + bool m_skipinit = false; + bool m_skipreorder = false; + bool m_skipreuse = false; + bool m_ignoreRotation = false; bool m_ignoreBarCode = false; - bool m_openLoop = true, m_closeLoop = false; bool m_update_rotation = false; bool m_split = false; bool m_write = false; bool m_nomunkres = false; - bool m_noreorderpass = false; - bool n_doreusepass = false; + bool m_reset = false; }; diff --git a/src/capabilities/rmsd.cpp b/src/capabilities/rmsd.cpp index 13c8b4a..ffe4189 100644 --- a/src/capabilities/rmsd.cpp +++ b/src/capabilities/rmsd.cpp @@ -173,7 +173,7 @@ void RMSDDriver::LoadControlJson() #pragma message("these hacks to overcome the json stuff are not nice, TODO!") try { std::string element = m_defaults["Element"].get(); - StringList elements = Tools::SplitString(element, ";"); + StringList elements = Tools::SplitString(element, ","); for (const std::string& str : elements) { try { m_element_templates.push_back(std::stod(str)); diff --git a/src/core/eigen_uff.cpp b/src/core/eigen_uff.cpp index 50f5647..7484c75 100644 --- a/src/core/eigen_uff.cpp +++ b/src/core/eigen_uff.cpp @@ -108,7 +108,6 @@ double UFFThread::CalculateBondStretching() energy += (0.5 * bond.kij * (r0 - bond.r0) * (r0 - bond.r0)) * m_final_factor * m_bond_scaling; if (m_CalculateGradient) { if (m_calc_gradient == 0) { - double diff = (bond.kij) * (r0 - bond.r0) * m_final_factor * m_bond_scaling; m_gradient.row(i) += diff * derivate.row(0); m_gradient.row(j) += diff * derivate.row(1); @@ -166,11 +165,10 @@ double UFFThread::CalculateAngleBending() auto atom_k = Position(k); Matrix derivate; double costheta = AngleBending(atom_i, atom_j, atom_k, derivate, m_CalculateGradient); - double e = (angle.kijk * (angle.C0 + angle.C1 * costheta + angle.C2 * (2 * costheta * costheta - 1))) * m_final_factor * m_angle_scaling; + if (m_CalculateGradient) { if (m_calc_gradient == 0) { - double sintheta = sin(acos(costheta)); double dEdtheta = -angle.kijk * sintheta * (angle.C1 + 4 * angle.C2 * costheta) * m_final_factor * m_angle_scaling; m_gradient.row(i) += dEdtheta * derivate.row(0); @@ -407,6 +405,7 @@ double UFFThread::FullInversion(const int& i, const int& j, const int& k, const if (rji.norm() < 1e-5 || rjk.norm() < 1e-5 || rjl.norm() < 1e-5) return 0; + double dji = rji.norm(); double djk = rjk.norm(); double djl = rjl.norm(); @@ -465,7 +464,6 @@ double UFFThread::FullInversion(const int& i, const int& j, const int& k, const m_gradient(l, 1) += dEdY * dYdl(1); m_gradient(l, 2) += dEdY * dYdl(2); } else if (m_calc_gradient == 1) { - m_gradient(i, 0) += (Inversion(AddVector(atom_i, dx), atom_j, atom_k, atom_l, d_forceConstant, C0, C1, C2) - Inversion(SubVector(atom_i, dx), atom_j, atom_k, atom_l, d_forceConstant, C0, C1, C2)) / (2 * m_d); m_gradient(i, 1) += (Inversion(AddVector(atom_i, dy), atom_j, atom_k, atom_l, d_forceConstant, C0, C1, C2) - Inversion(SubVector(atom_i, dy), atom_j, atom_k, atom_l, d_forceConstant, C0, C1, C2)) / (2 * m_d); m_gradient(i, 2) += (Inversion(AddVector(atom_i, dz), atom_j, atom_k, atom_l, d_forceConstant, C0, C1, C2) - Inversion(SubVector(atom_i, dz), atom_j, atom_k, atom_l, d_forceConstant, C0, C1, C2)) / (2 * m_d); @@ -485,10 +483,10 @@ double UFFThread::FullInversion(const int& i, const int& j, const int& k, const } return energy; } + double UFFThread::CalculateInversion() { double energy = 0.0; - for (int index = 0; index < m_uffinversion.size(); ++index) { const auto& inversion = m_uffinversion[index]; const int i = inversion.i; @@ -538,7 +536,6 @@ double UFFThread::CalculateNonBonds() m_gradient(j, 1) -= diff * (atom_i(1) - atom_j(1)); m_gradient(j, 2) -= diff * (atom_i(2) - atom_j(2)); } else if (m_calc_gradient == 1) { - m_gradient(i, 0) += (NonBonds(AddVector(atom_i, dx), atom_j, vdw.Dij, vdw.xij) - NonBonds(SubVector(atom_i, dx), atom_j, vdw.Dij, vdw.xij)) / (2 * m_d); m_gradient(i, 1) += (NonBonds(AddVector(atom_i, dy), atom_j, vdw.Dij, vdw.xij) - NonBonds(SubVector(atom_i, dy), atom_j, vdw.Dij, vdw.xij)) / (2 * m_d); m_gradient(i, 2) += (NonBonds(AddVector(atom_i, dz), atom_j, vdw.Dij, vdw.xij) - NonBonds(SubVector(atom_i, dz), atom_j, vdw.Dij, vdw.xij)) / (2 * m_d); @@ -551,6 +548,7 @@ double UFFThread::CalculateNonBonds() } return energy; } + double UFFThread::CalculateElectrostatic() { double energy = 0.0; @@ -1027,7 +1025,6 @@ void eigenUFF::FindRings() void eigenUFF::AssignUffAtomTypes() { for (int i = 0; i < m_atom_types.size(); ++i) { - switch (m_atom_types[i]) { case 1: // Hydrogen if (m_stored_bonds[i].size() == 2) @@ -1756,7 +1753,6 @@ double eigenUFF::BondRestLength(int i, int j, double n) double eigenUFF::Calculate(bool grd, bool verbose) { - m_CalculateGradient = grd; hbonds4::atom_t geometry[m_atom_types.size()]; for (int i = 0; i < m_atom_types.size(); ++i) { From c307906a89010211e8897ed765da6d8176120d34 Mon Sep 17 00:00:00 2001 From: conradhuebler Date: Thu, 15 Jun 2023 16:32:12 +0200 Subject: [PATCH 05/10] fix build Signed-off-by: conradhuebler --- src/capabilities/confscan.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/capabilities/confscan.cpp b/src/capabilities/confscan.cpp index 8c9dc2e..1d39a7b 100644 --- a/src/capabilities/confscan.cpp +++ b/src/capabilities/confscan.cpp @@ -556,12 +556,12 @@ void ConfScan::start() { PrintController(m_controller); SetUp(); + RunTimer timer(false); + std::ofstream result_file; if (!m_skipinit) { fmt::print("\n\nInitial Pass\nPerforming RMSD calculation without reordering now!\n\n"); - RunTimer timer(false); m_current_filename = m_1st_filename; - std::ofstream result_file; if (m_writeFiles && !m_reduced_file) { result_file.open(m_statistic_filename, std::ios_base::app); result_file << "Results of 1st Pass" << std::endl; @@ -579,7 +579,6 @@ void ConfScan::start() std::cout << m_dnn_data.size() << std::endl; #endif fmt::print("\nInitial Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); - } else { fmt::print("\n\nSkipping initial pass!\n\nSettings thresholds to high value ..."); From a059cfad191e1d47e55971376ddd330d7d5075f3 Mon Sep 17 00:00:00 2001 From: conradhuebler Date: Fri, 16 Jun 2023 16:53:04 +0200 Subject: [PATCH 06/10] clean some code, and more confscan Signed-off-by: conradhuebler --- src/capabilities/confscan.cpp | 36 ++++++-- src/capabilities/confscan.h | 6 +- src/capabilities/rmsd.cpp | 8 -- src/core/eigen_uff.cpp | 156 ++++++++++++++++++++++------------ src/core/eigen_uff.h | 14 ++- 5 files changed, 146 insertions(+), 74 deletions(-) diff --git a/src/capabilities/confscan.cpp b/src/capabilities/confscan.cpp index 1d39a7b..ba9da41 100644 --- a/src/capabilities/confscan.cpp +++ b/src/capabilities/confscan.cpp @@ -55,11 +55,11 @@ int ConfScanThread::execute() m_reused_worked = false; m_reorder_rule.clear(); +#ifdef WriteMoreInfo double Ia = abs(m_reference.Ia() - m_target.Ia()); double Ib = abs(m_reference.Ib() - m_target.Ib()); double Ic = abs(m_reference.Ic() - m_target.Ic()); -#ifdef WriteMoreInfo m_input.dIa = Ia; m_input.dIb = Ib; m_input.dIc = Ic; @@ -206,6 +206,7 @@ void ConfScan::LoadControlJson() m_skipinit = Json2KeyWord(m_defaults, "skipinit"); m_skipreorder = Json2KeyWord(m_defaults, "skipreorder"); m_skipreuse = Json2KeyWord(m_defaults, "skipreuse"); + m_mapped = Json2KeyWord(m_defaults, "mapped"); m_sTE = Json2KeyWord(m_defaults, "sTE"); m_sTI = Json2KeyWord(m_defaults, "sTI"); @@ -603,11 +604,25 @@ void ConfScan::start() double dLI = m_dLI; double dLH = m_dLH; double dLE = m_dLE; + if (!m_mapped) { + std::cout << m_sLI[run] << " " << m_sLH[run] << " " << m_sLE[run] << std::endl; + std::cout << m_dLI << " " << m_dLH << " " << m_dLE << std::endl; - dLI = m_dLI * m_sLI[run]; - dLH = m_dLH * m_sLH[run]; - dLE = m_dLE * m_sLE[run]; + dLI = m_dLI * m_sLI[run]; + dLH = m_dLH * m_sLH[run]; + dLE = m_dLE * m_sLE[run]; + } else { + for (const auto& i : m_listThresh) { + if (i.first <= m_sLI[run] * m_rmsd_threshold) + dLI = std::max(dLI, i.second[2]); + if (i.first <= m_sLH[run] * m_rmsd_threshold) + dLH = std::max(dLH, i.second[1]); + + if (i.first <= m_sLE[run] * m_rmsd_threshold) + dLE = std::max(dLE, i.second[0]); + } + } if (!CheckStop()) { timer.Reset(); fmt::print("\n\nReorder Pass\nPerforming RMSD calculation with reordering now!\n\n"); @@ -642,6 +657,7 @@ void ConfScan::start() PrintStatus("Result Reuse pass:"); result_file.close(); } + m_exclude_list.clear(); Reorder(-1, -1, -1, true, m_reset); PrintStatus("Result reuse pass:"); WriteDotFile(m_result_basename + ".reuse.dot", m_second_content); @@ -733,14 +749,17 @@ void ConfScan::CheckOnly(double sLE, double sLI, double sLH) p->StartAndWait(); for (auto* t : threads) { + if (!m_mapped) { + m_dLI = std::max(m_dLI, t->DI() * (t->RMSD() <= (sLI * m_rmsd_threshold))); + m_dLH = std::max(m_dLH, t->DH() * (t->RMSD() <= (sLH * m_rmsd_threshold))); + m_dLE = std::max(m_dLE, (std::abs(t->Reference()->Energy() - mol1->Energy()) * 2625.5) * (t->RMSD() <= (sLE * m_rmsd_threshold))); + } else + m_listThresh.insert(std::pair>(t->RMSD(), { (std::abs(t->Reference()->Energy() - mol1->Energy()) * 2625.5), t->DH(), t->DI() })); + m_dTI = std::max(m_dTI, t->DI() * (t->RMSD() <= (m_sTI * m_rmsd_threshold))); m_dTH = std::max(m_dTH, t->DH() * (t->RMSD() <= (m_sTH * m_rmsd_threshold))); m_dTE = std::max(m_dTE, (std::abs(t->Reference()->Energy() - mol1->Energy()) * 2625.5) * (t->RMSD() <= (m_sTE * m_rmsd_threshold))); - m_dLI = std::max(m_dLI, t->DI() * (t->RMSD() <= (sLI * m_rmsd_threshold))); - m_dLH = std::max(m_dLH, t->DH() * (t->RMSD() <= (sLH * m_rmsd_threshold))); - m_dLE = std::max(m_dLE, (std::abs(t->Reference()->Energy() - mol1->Energy()) * 2625.5) * (t->RMSD() <= (sLE * m_rmsd_threshold))); - if (t->KeepMolecule() == false) { keep_molecule = false; writeStatisticFile(t->Reference(), mol1, t->RMSD()); @@ -831,6 +850,7 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only, bool * than the tight threshold and the loose threshold is set to a big number, that every structure has to be reordered*/ m_skiped = 0; m_rejected_directly = 0; + m_duplicated = 0; if (m_ignoreRotation == true) { m_dLI = 1e10; m_dTI = -1; diff --git a/src/capabilities/confscan.h b/src/capabilities/confscan.h index 970fc24..5f254a3 100644 --- a/src/capabilities/confscan.h +++ b/src/capabilities/confscan.h @@ -99,7 +99,8 @@ static const json ConfScanJson = { { "ripser_ratio", 1 }, { "ripser_dimension", 2 }, { "domolalign", -1 }, - { "molaligntol", 10 } + { "molaligntol", 10 }, + { "mapped", false } }; class ConfScanThread : public CxxThread { @@ -340,6 +341,8 @@ class ConfScan : public CurcumaMethod { std::string m_rmsd_element_templates; std::string m_method = ""; std::string m_molalign = "molalign"; + std::map m_listH, m_listI, m_listE; + std::map> m_listThresh; std::vector m_sLE = { 1.0 }, m_sLI = { 1.0 }, m_sLH = { 1.0 }; double m_domolalign = -1; double m_lastDI = 0.0, m_lastDH = 0.0, m_lastdE = -1, m_dE = -1, m_damping = 0.8; @@ -378,4 +381,5 @@ class ConfScan : public CurcumaMethod { bool m_write = false; bool m_nomunkres = false; bool m_reset = false; + bool m_mapped = false; }; diff --git a/src/capabilities/rmsd.cpp b/src/capabilities/rmsd.cpp index ffe4189..02eb5b2 100644 --- a/src/capabilities/rmsd.cpp +++ b/src/capabilities/rmsd.cpp @@ -183,7 +183,6 @@ void RMSDDriver::LoadControlJson() } if (m_element_templates.size()) m_element = m_element_templates[0]; - } catch (const nlohmann::detail::type_error& error) { m_element = Json2KeyWord(m_defaults, "element"); m_element_templates.push_back(m_element); @@ -1204,7 +1203,6 @@ std::vector RMSDDriver::DistanceReorderV1(const Molecule& reference, const for (int i = 0; i < ref.AtomCount(); ++i) { std::map result; for (int j = 0; j < tar.AtomCount(); ++j) { - if (tar.Atom(j).first != ref.Atom(i).first || std::find(new_order.begin(), new_order.end(), j) != new_order.end()) continue; @@ -1261,10 +1259,8 @@ std::pair, std::vector> RMSDDriver::DistanceReorderV3(cons tar.setGeometry(tar_matrix); double mix = 1 - m_damping; for (int i = 0; i < ref.AtomCount(); ++i) { - std::map result; for (int j = 0; j < tar.AtomCount(); ++j) { - if (tar.Atom(j).first != ref.Atom(i).first || std::find(new_order.begin(), new_order.end(), j) != new_order.end()) continue; @@ -1282,7 +1278,6 @@ std::pair, std::vector> RMSDDriver::DistanceReorderV3(cons Geometry rotated; auto iterator = result.begin(); for (int j = 0; j < result.size() && j < 5; ++j) { - if (new_order.size() >= 4 && i % 1 == 0) { Molecule w_ref, w_tar; for (int i = 0; i < new_order.size(); ++i) { @@ -1334,7 +1329,6 @@ std::vector RMSDDriver::FillOrder(const Molecule& reference, const Molecule } std::map result; for (int j = 0; j < tar.AtomCount(); ++j) { - if (tar.Atom(j).first != ref.Atom(i).first || std::find(new_order.begin(), new_order.end(), j) != new_order.end()) continue; @@ -1351,7 +1345,6 @@ std::vector RMSDDriver::FillOrder(const Molecule& reference, const Molecule Geometry rotated; auto iterator = result.begin(); for (int j = 0; j < result.size() && j < 5; ++j) { - if (new_order.size() >= 4 && i % 1 == 0) { Molecule w_ref, w_tar; for (int i = 0; i < order.size(); ++i) { @@ -1428,7 +1421,6 @@ std::vector RMSDDriver::Munkress(const Molecule& reference, const Molecule& bool RMSDDriver::MolAlignLib() { - m_reference.writeXYZFile("molaign_ref.xyz"); m_target.writeXYZFile("molalign_tar.xyz"); FILE* FileOpen; diff --git a/src/core/eigen_uff.cpp b/src/core/eigen_uff.cpp index 7484c75..3cd7103 100644 --- a/src/core/eigen_uff.cpp +++ b/src/core/eigen_uff.cpp @@ -1231,19 +1231,25 @@ void eigenUFF::AssignUffAtomTypes() void eigenUFF::writeParameterFile(const std::string& file) const { + json parameters = writeUFF(); + parameters["bonds"] = Bonds(); + parameters["angles"] = Angles(); + parameters["dihedrals"] = Dihedrals(); + parameters["inversions"] = Inversions(); + parameters["vdws"] = vdWs(); std::ofstream parameterfile(file); - parameterfile << writeParameter(); + parameterfile << parameters; } void eigenUFF::writeUFFFile(const std::string& file) const { + json parameters = writeUFF(); std::ofstream parameterfile(file); parameterfile << writeUFF(); } -json eigenUFF::writeParameter() const +json eigenUFF::Bonds() const { - json parameters; json bonds; for (int i = 0; i < m_uffbonds.size(); ++i) { json bond; @@ -1253,7 +1259,11 @@ json eigenUFF::writeParameter() const bond["kij"] = m_uffbonds[i].kij; bonds[i] = bond; } - parameters["bonds"] = bonds; + return bonds; +} + +json eigenUFF::Angles() const +{ json angles; for (int i = 0; i < m_uffangle.size(); ++i) { @@ -1269,10 +1279,12 @@ json eigenUFF::writeParameter() const angles[i] = angle; } - parameters["angles"] = angles; + return angles; +} +json eigenUFF::Dihedrals() const +{ json dihedrals; - for (int i = 0; i < m_uffdihedral.size(); ++i) { json dihedral; dihedral["i"] = m_uffdihedral[i].i; @@ -1285,10 +1297,12 @@ json eigenUFF::writeParameter() const dihedrals[i] = dihedral; } - parameters["dihedrals"] = dihedrals; + return dihedrals; +} +json eigenUFF::Inversions() const +{ json inversions; - for (int i = 0; i < m_uffinversion.size(); ++i) { json inversion; inversion["i"] = m_uffinversion[i].i; @@ -1302,8 +1316,11 @@ json eigenUFF::writeParameter() const inversions[i] = inversion; } - parameters["inversions"] = inversions; + return inversions; +} +json eigenUFF::vdWs() const +{ json vdws; for (int i = 0; i < m_uffvdwaals.size(); ++i) { json vdw; @@ -1313,7 +1330,18 @@ json eigenUFF::writeParameter() const vdw["xij"] = m_uffvdwaals[i].xij; vdws[i] = vdw; } - parameters["vdws"] = vdws; + return vdws; +} +/* +json eigenUFF::writeParameter() const +{ + json parameters; + + parameters["bonds"] = Bonds(); + parameters["angles"] = Angles(); + parameters["dihedrals"] = Dihedrals(); + parameters["inversions"] = Inversions(); + parameters["vdws"] = vdWs(); parameters["bond_scaling"] = m_bond_scaling; parameters["angle_scaling"] = m_angle_scaling; @@ -1365,7 +1393,7 @@ json eigenUFF::writeParameter() const #endif return parameters; } - +*/ json eigenUFF::writeUFF() const { json parameters; @@ -1467,50 +1495,62 @@ void eigenUFF::readUFF(const json& parameters) void eigenUFF::readParameter(const json& parameters) { m_gradient = Eigen::MatrixXd::Zero(m_atom_types.size(), 3); + readUFF(parameters); // while (m_gradient.size() < m_atom_types.size()) // m_gradient.push_back({ 0, 0, 0 }); // m_d = parameters["differential"].get(); + /* + #ifdef USE_D3 + if (m_use_d3) + m_d3->UpdateParameters(parameters); + #endif -#ifdef USE_D3 - if (m_use_d3) - m_d3->UpdateParameters(parameters); -#endif - -#ifdef USE_D4 - if (m_use_d4) - m_d4->UpdateParameters(parameters); -#endif - - m_bond_scaling = parameters["bond_scaling"].get(); - m_angle_scaling = parameters["angle_scaling"].get(); - m_dihedral_scaling = parameters["dihedral_scaling"].get(); - m_inversion_scaling = parameters["inversion_scaling"].get(); - m_vdw_scaling = parameters["vdw_scaling"].get(); - m_rep_scaling = parameters["rep_scaling"].get(); - - m_coulmob_scaling = parameters["coulomb_scaling"].get(); - - m_bond_force = parameters["bond_force"].get(); - m_angle_force = parameters["angle_force"].get(); - m_calc_gradient = parameters["gradient"].get(); - - m_h4_scaling = parameters["h4_scaling"].get(); - m_hh_scaling = parameters["hh_scaling"].get(); - - m_h4correction.set_OH_O(parameters["h4_oh_o"].get()); - m_h4correction.set_OH_N(parameters["h4_oh_n"].get()); - m_h4correction.set_NH_O(parameters["h4_nh_o"].get()); - m_h4correction.set_NH_N(parameters["h4_nh_n"].get()); + #ifdef USE_D4 + if (m_use_d4) + m_d4->UpdateParameters(parameters); + #endif + + m_bond_scaling = parameters["bond_scaling"].get(); + m_angle_scaling = parameters["angle_scaling"].get(); + m_dihedral_scaling = parameters["dihedral_scaling"].get(); + m_inversion_scaling = parameters["inversion_scaling"].get(); + m_vdw_scaling = parameters["vdw_scaling"].get(); + m_rep_scaling = parameters["rep_scaling"].get(); + + m_coulmob_scaling = parameters["coulomb_scaling"].get(); + + m_bond_force = parameters["bond_force"].get(); + m_angle_force = parameters["angle_force"].get(); + m_calc_gradient = parameters["gradient"].get(); + + m_h4_scaling = parameters["h4_scaling"].get(); + m_hh_scaling = parameters["hh_scaling"].get(); + + m_h4correction.set_OH_O(parameters["h4_oh_o"].get()); + m_h4correction.set_OH_N(parameters["h4_oh_n"].get()); + m_h4correction.set_NH_O(parameters["h4_nh_o"].get()); + m_h4correction.set_NH_N(parameters["h4_nh_n"].get()); + + m_h4correction.set_WH_O(parameters["h4_wh_o"].get()); + m_h4correction.set_NH4(parameters["h4_nh4"].get()); + m_h4correction.set_COO(parameters["h4_coo"].get()); + m_h4correction.set_HH_Rep_K(parameters["hh_rep_k"].get()); + m_h4correction.set_HH_Rep_E(parameters["hh_rep_e"].get()); + m_h4correction.set_HH_Rep_R0(parameters["hh_rep_r0"].get()); + */ + setBonds(parameters["bonds"]); + setAngles(parameters["angles"]); + setDihedrals(parameters["dihedrals"]); + setInversions(parameters["inversions"]); + setvdWs(parameters["vdws"]); - m_h4correction.set_WH_O(parameters["h4_wh_o"].get()); - m_h4correction.set_NH4(parameters["h4_nh4"].get()); - m_h4correction.set_COO(parameters["h4_coo"].get()); - m_h4correction.set_HH_Rep_K(parameters["hh_rep_k"].get()); - m_h4correction.set_HH_Rep_E(parameters["hh_rep_e"].get()); - m_h4correction.set_HH_Rep_R0(parameters["hh_rep_r0"].get()); + AutoRanges(); + m_initialised = true; +} - json bonds = parameters["bonds"]; +void eigenUFF::setBonds(const json& bonds) +{ m_uffbonds.clear(); for (int i = 0; i < bonds.size(); ++i) { json bond = bonds[i].get(); @@ -1522,8 +1562,10 @@ void eigenUFF::readParameter(const json& parameters) b.kij = bond["kij"].get(); m_uffbonds.push_back(b); } +} - json angles = parameters["angles"]; +void eigenUFF::setAngles(const json& angles) +{ m_uffangle.clear(); for (int i = 0; i < angles.size(); ++i) { json angle = angles[i].get(); @@ -1538,8 +1580,10 @@ void eigenUFF::readParameter(const json& parameters) a.kijk = angle["kijk"].get(); m_uffangle.push_back(a); } +} - json dihedrals = parameters["dihedrals"]; +void eigenUFF::setDihedrals(const json& dihedrals) +{ m_uffdihedral.clear(); for (int i = 0; i < dihedrals.size(); ++i) { json dihedral = dihedrals[i].get(); @@ -1554,8 +1598,10 @@ void eigenUFF::readParameter(const json& parameters) d.phi0 = dihedral["phi0"].get(); m_uffdihedral.push_back(d); } +} - json inversions = parameters["inversions"]; +void eigenUFF::setInversions(const json& inversions) +{ m_uffinversion.clear(); for (int i = 0; i < inversions.size(); ++i) { json inversion = inversions[i].get(); @@ -1572,8 +1618,10 @@ void eigenUFF::readParameter(const json& parameters) m_uffinversion.push_back(inv); } +} - json vdws = parameters["vdws"]; +void eigenUFF::setvdWs(const json& vdws) +{ m_uffvdwaals.clear(); for (int i = 0; i < vdws.size(); ++i) { json vdw = vdws[i].get(); @@ -1586,8 +1634,6 @@ void eigenUFF::readParameter(const json& parameters) m_uffvdwaals.push_back(v); } - AutoRanges(); - m_initialised = true; } void eigenUFF::readUFFFile(const std::string& file) @@ -1616,8 +1662,6 @@ void eigenUFF::readParameterFile(const std::string& file) void eigenUFF::AutoRanges() { - // auto parameter = writeParameter(); - for (int i = 0; i < m_threads; ++i) { UFFThread* thread = new UFFThread(i, m_threads); thread->readUFF(writeUFF()); diff --git a/src/core/eigen_uff.h b/src/core/eigen_uff.h index a253353..e15d085 100644 --- a/src/core/eigen_uff.h +++ b/src/core/eigen_uff.h @@ -239,9 +239,21 @@ class eigenUFF { void writeParameterFile(const std::string& file) const; void writeUFFFile(const std::string& file) const; - json writeParameter() const; + // json writeParameter() const; json writeUFF() const; + json Bonds() const; + json Angles() const; + json Dihedrals() const; + json Inversions() const; + json vdWs() const; + + void setBonds(const json& bonds); + void setAngles(const json& angles); + void setDihedrals(const json& dihedrals); + void setInversions(const json& inversions); + void setvdWs(const json& vdws); + void readParameterFile(const std::string& file); void readUFFFile(const std::string& file); From 2d4724618a278915eec9511638a6e5c370f0c104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Conrad=20H=C3=BCbler?= Date: Sat, 8 Jul 2023 16:13:37 +0200 Subject: [PATCH 07/10] restructure some source code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Conrad Hübler --- src/capabilities/analysenciplot.cpp | 2 - src/capabilities/confscan.cpp | 7 ++- src/capabilities/docking.h | 1 - src/capabilities/rmsd.cpp | 1 - src/capabilities/simplemd.cpp | 3 -- src/capabilities/simplemd.h | 1 - src/core/eigen_uff.cpp | 84 +++++++++++++++++++---------- src/core/eigen_uff.h | 9 ++++ src/core/energycalculator.cpp | 1 - src/core/molecule.cpp | 1 - src/main.cpp | 2 - 11 files changed, 70 insertions(+), 42 deletions(-) diff --git a/src/capabilities/analysenciplot.cpp b/src/capabilities/analysenciplot.cpp index 9832fa4..b71386f 100644 --- a/src/capabilities/analysenciplot.cpp +++ b/src/capabilities/analysenciplot.cpp @@ -52,7 +52,6 @@ void AnalyseNCIPlot::start() std::vector distances_1, distances_2; std::map::iterator> index_mapper_1, index_mapper_2; for (auto iter = m_NCI1.begin(); iter != m_NCI1.end(); ++iter) { - if (index_mapper_1.find(int(iter->first * scaling)) == index_mapper_1.end()) index_mapper_1.insert(std::pair::iterator>(int(iter->first * scaling), iter)); @@ -66,7 +65,6 @@ void AnalyseNCIPlot::start() index_mapper_1.insert(std::pair::iterator>(index_mapper_1.size(), m_NCI1.end())); for (auto iter = m_NCI2.begin(); iter != m_NCI2.end(); ++iter) { - if (index_mapper_2.find(int(iter->first * scaling)) == index_mapper_2.end()) index_mapper_2.insert(std::pair::iterator>(int(iter->first * scaling), iter)); diff --git a/src/capabilities/confscan.cpp b/src/capabilities/confscan.cpp index ba9da41..2ee4f1f 100644 --- a/src/capabilities/confscan.cpp +++ b/src/capabilities/confscan.cpp @@ -54,7 +54,12 @@ int ConfScanThread::execute() m_reorder_worked = false; m_reused_worked = false; m_reorder_rule.clear(); - + m_rmsd = m_driver->BestFitRMSD(); + if (m_rmsd < m_rmsd_threshold) { + m_keep_molecule = false; + m_break_pool = true; + return 0; + } #ifdef WriteMoreInfo double Ia = abs(m_reference.Ia() - m_target.Ia()); double Ib = abs(m_reference.Ib() - m_target.Ib()); diff --git a/src/capabilities/docking.h b/src/capabilities/docking.h index 8754318..77edc8d 100644 --- a/src/capabilities/docking.h +++ b/src/capabilities/docking.h @@ -98,7 +98,6 @@ static const json DockingJson = { }; class Docking : public CurcumaMethod { - public: Docking(const json& controller = DockingJson, bool silent = true); virtual ~Docking() = default; diff --git a/src/capabilities/rmsd.cpp b/src/capabilities/rmsd.cpp index 02eb5b2..0afefb6 100644 --- a/src/capabilities/rmsd.cpp +++ b/src/capabilities/rmsd.cpp @@ -1281,7 +1281,6 @@ std::pair, std::vector> RMSDDriver::DistanceReorderV3(cons if (new_order.size() >= 4 && i % 1 == 0) { Molecule w_ref, w_tar; for (int i = 0; i < new_order.size(); ++i) { - w_ref.addPair(ref.Atom(i)); w_tar.addPair(tar.Atom(new_order[i])); } diff --git a/src/capabilities/simplemd.cpp b/src/capabilities/simplemd.cpp index f8538ef..f124564 100644 --- a/src/capabilities/simplemd.cpp +++ b/src/capabilities/simplemd.cpp @@ -296,7 +296,6 @@ bool SimpleMD::LoadRestartInformation() StringList files = RestartFiles(); int error = 0; for (const auto& f : files) { - std::ifstream file(f); json restart; try { @@ -546,7 +545,6 @@ void SimpleMD::Verlet(double* coord, double* grad) // restart_file << fallback << std::endl; for (int i = 0; i < m_natoms; ++i) { - coord[3 * i + 0] = m_current_geometry[3 * i + 0] + m_timestep * m_velocities[3 * i + 0] - 0.5 * grad[3 * i + 0] * m_rmass[3 * i + 0] * m_dt2; coord[3 * i + 1] = m_current_geometry[3 * i + 1] + m_timestep * m_velocities[3 * i + 1] - 0.5 * grad[3 * i + 1] * m_rmass[3 * i + 1] * m_dt2; coord[3 * i + 2] = m_current_geometry[3 * i + 2] + m_timestep * m_velocities[3 * i + 2] - 0.5 * grad[3 * i + 2] * m_rmass[3 * i + 2] * m_dt2; @@ -773,7 +771,6 @@ void SimpleMD::PrintStatus() const remaining = (m_maxtime - m_currentStep) * duration; #pragma message("awfull, fix it ") if (m_writeUnique) { - #ifdef GCC std::cout << fmt::format("{1: ^{0}f} {2: ^{0}f} {3: ^{0}f} {4: ^{0}f} {5: ^{0}f} {6: ^{0}f} {7: ^{0}f} {8: ^{0}f} {9: ^{0}f} {10: ^{0}f} {11: ^{0}}\n", 15, m_currentStep / 1000, m_Epot, m_aver_Epot, m_Ekin, m_aver_Ekin, m_Etot, m_aver_Etot, m_T, m_aver_Temp, remaining, m_unqiue->StoredStructures()); #else diff --git a/src/capabilities/simplemd.h b/src/capabilities/simplemd.h index cbdca54..4181aaa 100644 --- a/src/capabilities/simplemd.h +++ b/src/capabilities/simplemd.h @@ -165,7 +165,6 @@ class SimpleMD : public CurcumaMethod { }; class MDThread : public CxxThread { - public: MDThread(int thread, const json& controller) : m_thread(thread) diff --git a/src/core/eigen_uff.cpp b/src/core/eigen_uff.cpp index 3cd7103..eabb992 100644 --- a/src/core/eigen_uff.cpp +++ b/src/core/eigen_uff.cpp @@ -613,7 +613,7 @@ void eigenUFF::Initialise() m_coordination = std::vector(m_atom_types.size(), 0); std::vector> ignored_vdw; m_topo = Eigen::MatrixXd::Zero(m_atom_types.size(), m_atom_types.size()); - TContainer bonds, nonbonds, angels, dihedrals, inversions; + TContainer bonds, nonbonds, angles, dihedrals, inversions; m_scaling = 1.4; m_gradient = Eigen::MatrixXd::Zero(m_atom_types.size(), 3); for (int i = 0; i < m_atom_types.size(); ++i) { @@ -649,7 +649,44 @@ void eigenUFF::Initialise() FindRings(); bonds.clean(); + setBonds(bonds, ignored_vdw, angles, dihedrals, inversions); + angles.clean(); + setAngles(angles, ignored_vdw); + + dihedrals.clean(); + setDihedrals(dihedrals); + + inversions.clean(); + setInversions(inversions); + + nonbonds.clean(); + setvdWs(ignored_vdw); + + m_h4correction.allocate(m_atom_types.size()); + +#ifdef USE_D3 + if (m_use_d3) + m_d3->InitialiseMolecule(m_atom_types); +#endif + +#ifdef USE_D4 + if (m_use_d4) + m_d4->InitialiseMolecule(m_atom_types); +#endif + + if (m_writeparam.compare("none") != 0) + writeParameterFile(m_writeparam + ".json"); + + if (m_writeuff.compare("none") != 0) + writeUFFFile(m_writeuff + ".json"); + + AutoRanges(); + m_initialised = true; +} + +void eigenUFF::setBonds(const TContainer& bonds, std::vector>& ignored_vdw, TContainer& angels, TContainer& dihedrals, TContainer& inversions) +{ for (const auto& bond : bonds.Storage()) { UFFBond b; @@ -714,9 +751,11 @@ void eigenUFF::Initialise() inversions.insert({ j, m_stored_bonds[j][0], m_stored_bonds[j][1], m_stored_bonds[j][2] }); } } +} - angels.clean(); - for (const auto& angle : angels.Storage()) { +void eigenUFF::setAngles(const TContainer& angles, const std::vector>& ignored_vdw) +{ + for (const auto& angle : angles.Storage()) { UFFAngle a; a.i = angle[0]; @@ -741,8 +780,10 @@ void eigenUFF::Initialise() a.C0 = a.C2 * (2 * cosTheta0 * cosTheta0 + 1); m_uffangle.push_back(a); } +} - dihedrals.clean(); +void eigenUFF::setDihedrals(const TContainer& dihedrals) +{ for (const auto& dihedral : dihedrals.Storage()) { UFFDihedral d; d.i = dihedral[0]; @@ -787,7 +828,10 @@ void eigenUFF::Initialise() m_uffdihedral.push_back(d); } - inversions.clean(); +} + +void eigenUFF::setInversions(const TContainer& inversions) +{ for (const auto& inversion : inversions.Storage()) { const int i = inversion[0]; if (m_coordination[i] != 3) @@ -819,17 +863,17 @@ void eigenUFF::Initialise() w0 *= 84.4339; break; - // if the central atom is arsenic + // if the central atom is arsenic case 33: w0 *= 86.9735; break; - // if the central atom is antimonium + // if the central atom is antimonium case 51: w0 *= 87.7047; break; - // if the central atom is bismuth + // if the central atom is bismuth case 83: w0 *= 90.0; break; @@ -845,8 +889,10 @@ void eigenUFF::Initialise() inv.kijkl = kijkl; m_uffinversion.push_back(inv); } - nonbonds.clean(); +} +void eigenUFF::setvdWs(const std::vector>& ignored_vdw) +{ for (int i = 0; i < m_atom_types.size(); ++i) { for (int j = i + 1; j < m_atom_types.size(); ++j) { if (std::find(ignored_vdw[i].begin(), ignored_vdw[i].end(), j) != ignored_vdw[i].end() || std::find(ignored_vdw[j].begin(), ignored_vdw[j].end(), i) != ignored_vdw[j].end()) @@ -866,26 +912,6 @@ void eigenUFF::Initialise() m_uffvdwaals.push_back(v); } } - m_h4correction.allocate(m_atom_types.size()); - -#ifdef USE_D3 - if (m_use_d3) - m_d3->InitialiseMolecule(m_atom_types); -#endif - -#ifdef USE_D4 - if (m_use_d4) - m_d4->InitialiseMolecule(m_atom_types); -#endif - - if (m_writeparam.compare("none") != 0) - writeParameterFile(m_writeparam + ".json"); - - if (m_writeuff.compare("none") != 0) - writeUFFFile(m_writeuff + ".json"); - - AutoRanges(); - m_initialised = true; } void eigenUFF::FindRings() diff --git a/src/core/eigen_uff.h b/src/core/eigen_uff.h index e15d085..6b2f93e 100644 --- a/src/core/eigen_uff.h +++ b/src/core/eigen_uff.h @@ -249,10 +249,19 @@ class eigenUFF { json vdWs() const; void setBonds(const json& bonds); + void setBonds(const TContainer& bonds, std::vector>& ignored_vdw, TContainer& angels, TContainer& dihedrals, TContainer& inversions); + void setAngles(const json& angles); + void setAngles(const TContainer& angles, const std::vector>& ignored_vdw); + void setDihedrals(const json& dihedrals); + void setDihedrals(const TContainer& dihedrals); + void setInversions(const json& inversions); + void setInversions(const TContainer& inversions); + void setvdWs(const json& vdws); + void setvdWs(const std::vector>& ignored_vdw); void readParameterFile(const std::string& file); void readUFFFile(const std::string& file); diff --git a/src/core/energycalculator.cpp b/src/core/energycalculator.cpp index 5c4cfde..40a74ea 100644 --- a/src/core/energycalculator.cpp +++ b/src/core/energycalculator.cpp @@ -140,7 +140,6 @@ void EnergyCalculator::setMolecule(const Molecule& molecule) #endif } else if (std::find(m_xtb_methods.begin(), m_xtb_methods.end(), m_method) != m_xtb_methods.end()) { // XTB energy calculator requested - #ifdef USE_XTB m_xtb->InitialiseMolecule(molecule); if (m_method.compare("xtb-gfn1") == 0) diff --git a/src/core/molecule.cpp b/src/core/molecule.cpp index aeaa915..d20d1db 100644 --- a/src/core/molecule.cpp +++ b/src/core/molecule.cpp @@ -278,7 +278,6 @@ void Molecule::setXYZComment(const std::string& comment) } } } else { - if (list.size() == 7) { setXYZComment_7(list); } else if (list.size() == 6) { diff --git a/src/main.cpp b/src/main.cpp index 5d35f39..31a1a78 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -339,7 +339,6 @@ int main(int argc, char **argv) { mapper.FindPairs(); } else if (strcmp(argv[1], "-nci") == 0) { - if (argc < 4) { std::cerr << "Please use curcuma to post-process two RDG vs rho plots from NCIPLOT as follows:\ncurcuma -nci file1.dat file2.dat" << std::endl; std::cerr << "Additonal arguments are:" << std::endl; @@ -696,7 +695,6 @@ int main(int argc, char **argv) { }else */ { - for (int i : A) std::cout << i << " "; std::cout << std::endl; From e0e6f4dcb576b88d4d5de0c60c2185f939d4a1c5 Mon Sep 17 00:00:00 2001 From: conradhuebler Date: Sat, 8 Jul 2023 16:18:38 +0200 Subject: [PATCH 08/10] some more parameter dump for confscan Signed-off-by: conradhuebler --- src/capabilities/confscan.cpp | 137 +++++++++++++++++++++++++++------- src/capabilities/confscan.h | 23 +++--- 2 files changed, 123 insertions(+), 37 deletions(-) diff --git a/src/capabilities/confscan.cpp b/src/capabilities/confscan.cpp index ba9da41..0a95b2d 100644 --- a/src/capabilities/confscan.cpp +++ b/src/capabilities/confscan.cpp @@ -49,13 +49,14 @@ int ConfScanThread::execute() m_driver->setThreads(m_threads); m_driver->setReference(m_reference); m_driver->setTarget(m_target); + + m_old_rmsd = m_driver->BestFitRMSD(); m_keep_molecule = true; m_break_pool = false; m_reorder_worked = false; m_reused_worked = false; m_reorder_rule.clear(); -#ifdef WriteMoreInfo double Ia = abs(m_reference.Ia() - m_target.Ia()); double Ib = abs(m_reference.Ib() - m_target.Ib()); double Ic = abs(m_reference.Ic() - m_target.Ic()); @@ -68,7 +69,6 @@ int ConfScanThread::execute() m_input.dH = diff_ripser; m_input.dHM = m; m_input.dE = std::abs(m_reference.Energy() - m_target.Energy()) * 2625.5; -#endif for (int i = 0; i < m_reorder_rules.size(); ++i) { if (m_reorder_rules[i].size() != m_reference.AtomCount() || m_reorder_rules[i].size() == 0) @@ -81,9 +81,7 @@ int ConfScanThread::execute() m_reused_worked = true; m_rmsd = tmp_rmsd; -#ifdef WriteMoreInfo m_input.rmsd = m_rmsd; -#endif m_reorder_rule = m_reorder_rules[i]; return 0; } @@ -96,9 +94,7 @@ int ConfScanThread::execute() m_driver->start(); m_rmsd = m_driver->RMSD(); -#ifdef WriteMoreInfo m_input.rmsd = m_rmsd; -#endif if (m_rmsd <= m_rmsd_threshold && (m_MaxHTopoDiff == -1 || m_driver->HBondTopoDifference() <= m_MaxHTopoDiff)) { m_keep_molecule = false; @@ -119,26 +115,20 @@ int ConfScanThreadNoReorder::execute() m_driver->start(); m_rmsd = m_driver->RMSD(); -#ifdef WriteMoreInfo m_input.rmsd = m_rmsd; -#endif double Ia = abs(m_reference.Ia() - m_target.Ia()); double Ib = abs(m_reference.Ib() - m_target.Ib()); double Ic = abs(m_reference.Ic() - m_target.Ic()); -#ifdef WriteMoreInfo m_input.dIa = Ia; m_input.dIb = Ib; m_input.dIc = Ic; -#endif m_DI = (Ia + Ib + Ic) * third; const Matrix m = (m_reference.getPersisentImage() - m_target.getPersisentImage()); m_DH = m.cwiseAbs().sum(); -#ifdef WriteMoreInfo m_input.dH = m_DH; m_input.dHM = m; m_input.dE = std::abs(m_reference.Energy() - m_target.Energy()) * 2625.5; -#endif if (m_rmsd <= m_rmsd_threshold && (m_MaxHTopoDiff == -1 || m_driver->HBondTopoDifference() <= m_MaxHTopoDiff)) { m_keep_molecule = false; m_break_pool = true; @@ -202,6 +192,7 @@ void ConfScan::LoadControlJson() } m_reset = Json2KeyWord(m_defaults, "reset"); + m_analyse = Json2KeyWord(m_defaults, "analyse"); m_skipinit = Json2KeyWord(m_defaults, "skipinit"); m_skipreorder = Json2KeyWord(m_defaults, "skipreorder"); @@ -461,6 +452,13 @@ void ConfScan::SetUp() m_statistic_filename = m_result_basename + ".statistic.log"; m_joined_filename = m_result_basename + ".joined.xyz"; m_threshold_filename = m_result_basename + ".thresh.xyz"; + + m_param_file = m_result_basename + ".param.dat"; + m_skip_file = m_result_basename + ".param.skip.dat"; + m_perform_file = m_result_basename + ".param.perf.dat"; + m_success_file = m_result_basename + ".param.success.dat"; + m_limit_file = m_result_basename + ".param.limit.dat"; + std::ofstream result_file; if (m_writeFiles) { result_file.open(m_accepted_filename); @@ -497,6 +495,25 @@ void ConfScan::SetUp() st_file.close(); } + std::ofstream parameters_file; + parameters_file.open(m_success_file); + parameters_file << "# RMSD(new)\tRMSD(old)\tDelta E\tDelta H\tDelta I" << std::endl; + parameters_file.close(); + + if (m_analyse) { + std::ofstream parameters_skipped; + parameters_skipped.open(m_skip_file); + parameters_skipped.close(); + + std::ofstream parameters_performed; + parameters_performed.open(m_perform_file); + parameters_performed.close(); + + std::ofstream parameters_limit; + parameters_limit.open(m_limit_file); + parameters_limit.close(); + } + std::cout << "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" << std::endl << "" << std::endl; @@ -576,9 +593,19 @@ void ConfScan::start() m_sLH[0] = 1; m_collective_content = "edge [color=green];\n"; m_collective_content += m_first_content + "\n"; -#ifdef WriteMoreInfo - std::cout << m_dnn_data.size() << std::endl; -#endif + + std::ofstream parameters_file; + parameters_file.open(m_param_file); + parameters_file << "# RMSD(old)\tDelta E\tDelta H\tDelta I" << std::endl; + bool breakline = false; + for (const auto& i : m_listThresh) { + if (i.first > m_rmsd_threshold && !breakline) { + parameters_file << std::endl; + breakline = true; + } + parameters_file << i.first << " " << i.second[0] << " " << i.second[1] << " " << i.second[2] << std::endl; + } + fmt::print("\nInitial Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); } else { fmt::print("\n\nSkipping initial pass!\n\nSettings thresholds to high value ..."); @@ -593,6 +620,13 @@ void ConfScan::start() } if (!m_skipreorder) { + std::ofstream parameters_skip; + parameters_skip.open(m_skip_file, std::ios_base::app); + parameters_skip << "# RMSD(old)\tDelta E\tDelta H\tDelta I" << std::endl; + + std::ofstream parameters_performed; + parameters_performed.open(m_perform_file, std::ios_base::app); + parameters_performed << "# RMSD(old)\tDelta E\tDelta H\tDelta I" << std::endl; for (int run = 0; run < m_sLE.size(); ++run) { m_current_filename = m_2nd_filename + "." + std::to_string(run + 1) + ".xyz"; @@ -631,6 +665,10 @@ void ConfScan::start() result_file << "Results of Reorder Pass #" << run + 1 << std::endl; result_file.close(); } + std::ofstream parameters_success; + parameters_success.open(m_success_file, std::ios_base::app); + parameters_success << "# " << run << " run" << std::endl; + Reorder(dLE, dLI, dLH, false); PrintStatus("Result Reorder pass:"); WriteDotFile(m_result_basename + ".reorder." + std::to_string(run + 1) + ".dot", m_second_content); @@ -639,8 +677,34 @@ void ConfScan::start() m_collective_content += "edge [color=red];\n"; m_collective_content += m_second_content + "\n"; m_second_content.clear(); + if (m_analyse) { + parameters_performed << "# " << run << " run" << std::endl + << std::endl; + parameters_skip << "# " << run << " run" << std::endl + << std::endl; + + for (const auto& i : m_listThresh) { + std::vector element = { i.second[0], i.second[1], i.second[2] }; + auto position = std::find(m_list_skipped.begin(), m_list_skipped.end(), element); + if (position != m_list_skipped.end()) { + parameters_skip << i.first << " " << i.second[0] << " " << i.second[1] << " " << i.second[2] << std::endl; + m_list_skipped.erase(position); + continue; + } + + position = std::find(m_list_performed.begin(), m_list_performed.end(), element); + if (position != m_list_performed.end()) { + parameters_performed << i.first << " " << i.second[0] << " " << i.second[1] << " " << i.second[2] << std::endl; + m_list_performed.erase(position); + } + } + parameters_performed << std::endl; + parameters_skip << std::endl; + } } } + parameters_skip.close(); + parameters_performed.close(); } else fmt::print("\nReorder Pass skipped!\n"); if (!m_skipreuse) { @@ -667,6 +731,7 @@ void ConfScan::start() m_collective_content += m_second_content + "\n"; } } + #ifdef WriteMoreInfo int index = 1; for (const auto& i : m_dnn_data) { @@ -753,8 +818,8 @@ void ConfScan::CheckOnly(double sLE, double sLI, double sLH) m_dLI = std::max(m_dLI, t->DI() * (t->RMSD() <= (sLI * m_rmsd_threshold))); m_dLH = std::max(m_dLH, t->DH() * (t->RMSD() <= (sLH * m_rmsd_threshold))); m_dLE = std::max(m_dLE, (std::abs(t->Reference()->Energy() - mol1->Energy()) * 2625.5) * (t->RMSD() <= (sLE * m_rmsd_threshold))); - } else - m_listThresh.insert(std::pair>(t->RMSD(), { (std::abs(t->Reference()->Energy() - mol1->Energy()) * 2625.5), t->DH(), t->DI() })); + } + m_listThresh.insert(std::pair>(t->RMSD(), { (std::abs(t->Reference()->Energy() - mol1->Energy()) * 2625.5), t->DH(), t->DI() })); m_dTI = std::max(m_dTI, t->DI() * (t->RMSD() <= (m_sTI * m_rmsd_threshold))); m_dTH = std::max(m_dTH, t->DH() * (t->RMSD() <= (m_sTH * m_rmsd_threshold))); @@ -832,13 +897,22 @@ void ConfScan::PrintSetUp(double dLE, double dLI, double dLH) std::cout << " Thresholds in difference of ripser images: " << std::endl; std::cout << " Loose Threshold: " << dLH << " " << std::endl; std::cout << " Tight Threshold: " << m_dTH << " " << std::endl; - std::cout << " Thresholds for energy differences in kJ/mol: " << std::endl; - std::cout << " Loose Threshold: " << dLE << " " << std::endl; - std::cout << " Tight Threshold: " << m_dTE << " " << std::endl; + std::cout << " Thresholds for energy differences: " << std::endl; + std::cout << " Loose Threshold: " << dLE << " kJ/mol" << std::endl; + std::cout << " Tight Threshold: " << m_dTE << " kJ/mol" << std::endl; std::cout << "" << std::endl << "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''" << std::endl << std::endl; + + if (dLE > 0 || dLH > 0 || dLI > 0) { + std::ofstream parameters_limit; + parameters_limit.open(m_limit_file, std::ios_base::app); + parameters_limit << "0\t" << dLE << "\t" << dLH << "\t" << dLI << std::endl; + parameters_limit << std::prev(m_listThresh.end())->first << "\t" << dLE << "\t" << dLH << "\t" << dLI << std::endl; + parameters_limit << std::endl; + parameters_limit.close(); + } } void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only, bool reset) @@ -891,6 +965,9 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only, bool CxxThreadPool* p = new CxxThreadPool; p->setActiveThreadCount(m_threads); + std::ofstream parameters_success; + parameters_success.open(m_success_file, std::ios_base::app); + for (Molecule* mol1 : cached) { if (m_result.size() == 0) { AcceptMolecule(mol1); @@ -914,10 +991,6 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only, bool } const Molecule* mol2 = threads[t]->Reference(); std::pair names(mol1->Name(), mol2->Name()); - if (std::find(m_exclude_list.begin(), m_exclude_list.end(), names) != m_exclude_list.end()) { - m_duplicated++; - continue; - } double Ia = abs(mol1->Ia() - mol2->Ia()); double Ib = abs(mol1->Ib() - mol2->Ib()); @@ -930,6 +1003,11 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only, bool * energy = 4 */ int looseThresh = 1 * (dI < dLI) + 2 * (dH < dLH) + 4 * (std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < dLE); if ((looseThresh & m_looseThresh) == m_looseThresh || (dLI <= 1e-8 && dLH <= 1e-8 && dLE <= 1e-8)) { + if (std::find(m_exclude_list.begin(), m_exclude_list.end(), names) != m_exclude_list.end()) { + m_duplicated++; + m_list_performed.push_back({ std::abs(mol1->Energy() - mol2->Energy()) * 2625.5, dH, dI }); + continue; + } reorder = true; threads[t]->setEnabled(true); int tightThresh = 1 * (dI < m_dTI) + 2 * (dH < m_dTH) + 4 * ((std::abs(mol1->Energy() - mol2->Energy()) * 2625.5 < m_dTE)); @@ -945,9 +1023,13 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only, bool keep_molecule = false; break; } + m_list_performed.push_back({ std::abs(mol1->Energy() - mol2->Energy()) * 2625.5, dH, dI }); m_exclude_list.push_back(std::pair(mol1->Name(), mol2->Name())); - } else + } else { threads[t]->setEnabled(false); + m_list_skipped.push_back({ std::abs(mol1->Energy() - mol2->Energy()) * 2625.5, dH, dI }); + // parameters_skip << std::abs(mol1->Energy() - mol2->Energy())* 2625.5 << " " << dH << " " << dI << std::endl; + } } if (reorder && keep_molecule) { @@ -1000,7 +1082,8 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only, bool m_second_content += "\"" + mol1->Name() + "\" [label=\"" + mol1->Name() + "\"];\n"; m_second_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\" [style=bold,label=" + std::to_string(t->RMSD()) + "];\n"; laststring = t->Reference()->Name(); - + auto i = t->getDNNInput(); + parameters_success << t->RMSD() << " " << t->OldRMSD() << " " << i.dE << " " << i.dH << " " << (i.dIa + i.dIb + i.dIc) * third << std::endl; writeStatisticFile(t->Reference(), mol1, t->RMSD(), true, t->ReorderRule()); mol1->ApplyReorderRule(t->ReorderRule()); break; @@ -1054,6 +1137,8 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only, bool break; } } + parameters_success.close(); + p->clear(); delete p; } diff --git a/src/capabilities/confscan.h b/src/capabilities/confscan.h index 5f254a3..1bf2135 100644 --- a/src/capabilities/confscan.h +++ b/src/capabilities/confscan.h @@ -35,12 +35,10 @@ #include "curcumamethod.h" constexpr double third = 1 / 3.0; -#ifdef WriteMoreInfo struct dnn_input { double dE, dIa, dIb, dIc, dH, rmsd; Matrix dHM; }; -#endif static const json ConfScanJson = { { "noname", true }, @@ -100,7 +98,8 @@ static const json ConfScanJson = { { "ripser_dimension", 2 }, { "domolalign", -1 }, { "molaligntol", 10 }, - { "mapped", false } + { "mapped", false }, + { "analyse", false } }; class ConfScanThread : public CxxThread { @@ -152,6 +151,7 @@ class ConfScanThread : public CxxThread { void setThreads(int threads) { m_threads = threads; } double RMSD() const { return m_rmsd; } + double OldRMSD() const { return m_old_rmsd; } const Molecule* Reference() const { return &m_reference; } const Molecule* Target() const { return &m_target; } @@ -159,13 +159,16 @@ class ConfScanThread : public CxxThread { #ifdef WriteMoreInfo void setPredRMSD(double rmsd) { m_pred_rmsd = rmsd; } double PredRMSD() const { return m_pred_rmsd; } - dnn_input getDNNInput() const { return m_input; } #endif + dnn_input getDNNInput() const + { + return m_input; + } private: bool m_keep_molecule = true, m_break_pool = false, m_reorder_worked = false, m_reuse_only = false, m_reused_worked = false; Molecule m_reference, m_target; - double m_rmsd = 0, m_rmsd_threshold = 1, m_energy = 0; + double m_rmsd = 0, m_old_rmsd = 0, m_rmsd_threshold = 1, m_energy = 0; int m_MaxHTopoDiff; int m_threads = 1; std::vector m_reorder_rule; @@ -174,8 +177,8 @@ class ConfScanThread : public CxxThread { json m_config; #ifdef WriteMoreInfo double m_pred_rmsd = 0; - dnn_input m_input; #endif + dnn_input m_input; }; class ConfScanThreadNoReorder : public CxxThread { @@ -217,12 +220,10 @@ class ConfScanThreadNoReorder : public CxxThread { } bool KeepMolecule() const { return m_keep_molecule; } -#ifdef WriteMoreInfo dnn_input getDNNInput() const { return m_input; } -#endif private: bool m_keep_molecule = true, m_break_pool = false; @@ -233,9 +234,7 @@ class ConfScanThreadNoReorder : public CxxThread { json m_config; double m_rmsd = 0, m_rmsd_threshold = 1; int m_MaxHTopoDiff; -#ifdef WriteMoreInfo dnn_input m_input; -#endif }; class ConfScan : public CurcumaMethod { @@ -317,7 +316,7 @@ class ConfScan : public CurcumaMethod { std::vector m_global_temp_list; int m_rejected = 0, m_accepted = 0, m_reordered = 0, m_reordered_worked = 0, m_reordered_failed_completely = 0, m_reordered_reused = 0, m_skip = 0, m_skiped = 0, m_duplicated = 0, m_rejected_directly = 0, m_molalign_count = 0, m_molalign_success = 0; - std::string m_filename, m_accepted_filename, m_1st_filename, m_2nd_filename, m_3rd_filename, m_rejected_filename, m_result_basename, m_statistic_filename, m_prev_accepted, m_joined_filename, m_threshold_filename, m_current_filename; + std::string m_filename, m_accepted_filename, m_1st_filename, m_2nd_filename, m_3rd_filename, m_rejected_filename, m_result_basename, m_statistic_filename, m_prev_accepted, m_joined_filename, m_threshold_filename, m_current_filename, m_param_file, m_skip_file, m_perform_file, m_success_file, m_limit_file; std::map m_ordered_list; std::vector> m_molecules; @@ -343,6 +342,7 @@ class ConfScan : public CurcumaMethod { std::string m_molalign = "molalign"; std::map m_listH, m_listI, m_listE; std::map> m_listThresh; + std::vector> m_list_skipped, m_list_performed; std::vector m_sLE = { 1.0 }, m_sLI = { 1.0 }, m_sLH = { 1.0 }; double m_domolalign = -1; double m_lastDI = 0.0, m_lastDH = 0.0, m_lastdE = -1, m_dE = -1, m_damping = 0.8; @@ -382,4 +382,5 @@ class ConfScan : public CurcumaMethod { bool m_nomunkres = false; bool m_reset = false; bool m_mapped = false; + bool m_analyse = false; }; From 76b26defc50f16e7ad4a951ec6f3e0ef332cf05d Mon Sep 17 00:00:00 2001 From: conradhuebler Date: Mon, 17 Jul 2023 16:53:01 +0200 Subject: [PATCH 09/10] update graph files Signed-off-by: conradhuebler --- src/capabilities/confscan.cpp | 39 +++++++++++++++++++++++++++-------- src/capabilities/confscan.h | 9 ++++---- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/capabilities/confscan.cpp b/src/capabilities/confscan.cpp index 8bef382..8a9f633 100644 --- a/src/capabilities/confscan.cpp +++ b/src/capabilities/confscan.cpp @@ -599,6 +599,9 @@ void ConfScan::start() m_sLI[0] = 1; m_sLH[0] = 1; m_collective_content = "edge [color=green];\n"; + for (auto node : m_nodes) + m_collective_content += node.second; + m_nodes.clear(); m_collective_content += m_first_content + "\n"; std::ofstream parameters_file; @@ -673,7 +676,8 @@ void ConfScan::start() } std::ofstream parameters_success; parameters_success.open(m_success_file, std::ios_base::app); - parameters_success << "# " << run << " run" << std::endl; + parameters_success << std::endl + << "# " << run << " run" << std::endl; Reorder(dLE, dLI, dLH, false); PrintStatus("Result Reorder pass:"); @@ -681,6 +685,9 @@ void ConfScan::start() fmt::print("\nReorder Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); timer.Reset(); m_collective_content += "edge [color=red];\n"; + for (auto node : m_nodes) + m_collective_content += node.second; + m_nodes.clear(); m_collective_content += m_second_content + "\n"; m_second_content.clear(); if (m_analyse) { @@ -728,12 +735,20 @@ void ConfScan::start() result_file.close(); } m_exclude_list.clear(); + std::ofstream parameters_success; + parameters_success.open(m_success_file, std::ios_base::app); + parameters_success << std::endl + << "# reuse run" << std::endl; + Reorder(-1, -1, -1, true, m_reset); PrintStatus("Result reuse pass:"); WriteDotFile(m_result_basename + ".reuse.dot", m_second_content); fmt::print("\nReuse Pass finished after {} seconds!\n", timer.Elapsed() / 1000.0); timer.Reset(); m_collective_content += "edge [color=blue];\n"; + for (auto node : m_nodes) + m_collective_content += node.second; + m_nodes.clear(); m_collective_content += m_second_content + "\n"; } } @@ -870,10 +885,12 @@ void ConfScan::CheckOnly(double sLE, double sLI, double sLH) writeStatisticFile(t->Reference(), mol1, t->RMSD()); if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) - m_first_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; - - m_first_content += "\"" + t->Reference()->Name() + "\" [shape=box, label=\"" + t->Reference()->Name() + "\"];\n"; - m_first_content += "\"" + mol1->Name() + "\" [label=\"" + mol1->Name() + "\"];\n"; + m_first_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted,arrowhead=onormal];\n"; + std::string node = "\"" + t->Reference()->Name() + "\" [shape=box, label=\"" + t->Reference()->Name() + "\"];\n"; + node += "\"" + mol1->Name() + "\" [label=\"" + mol1->Name() + "\"];\n"; + m_nodes.insert(std::pair(t->Reference()->Energy(), node)); + // m_first_content += + // m_first_content += m_first_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\" [style=bold,label=" + std::to_string(t->RMSD()) + "];\n"; laststring = t->Reference()->Name(); @@ -1118,10 +1135,14 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only, bool rules.push_back(t->ReorderRule()); if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) - m_second_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; + m_second_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted,arrowhead=onormal];\n"; + + std::string node = "\"" + t->Reference()->Name() + "\" [shape=box, label=\"" + t->Reference()->Name() + "\"];\n"; + node += "\"" + mol1->Name() + "\" [label=\"" + mol1->Name() + "\"];\n"; + m_nodes.insert(std::pair(t->Reference()->Energy(), node)); - m_second_content += "\"" + t->Reference()->Name() + "\" [shape=box, label=\"" + t->Reference()->Name() + "\"];\n"; - m_second_content += "\"" + mol1->Name() + "\" [label=\"" + mol1->Name() + "\"];\n"; + // m_second_content += "\"" + t->Reference()->Name() + "\" [shape=box, label=\"" + t->Reference()->Name() + "\"];\n"; + // m_second_content += "\"" + mol1->Name() + "\" [label=\"" + mol1->Name() + "\"];\n"; m_second_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\" [style=bold,label=" + std::to_string(t->RMSD()) + "];\n"; laststring = t->Reference()->Name(); auto i = t->getDNNInput(); @@ -1148,7 +1169,7 @@ void ConfScan::Reorder(double dLE, double dLI, double dLH, bool reuse_only, bool writeStatisticFile(t->Reference(), mol1, driver.RMSD(), true, { 0, 0 }); if (laststring.compare("") != 0 && laststring.compare(t->Reference()->Name()) != 0) - m_second_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted];\n"; + m_second_content += "\"" + laststring + "\" -> \"" + t->Reference()->Name() + "\"[style=dotted,arrowhead=onormal];\n"; m_second_content += "\"" + t->Reference()->Name() + "\" -> \"" + mol1->Name() + "\";\n"; m_second_content += "\"" + mol1->Name() + "\" [shape=box, style=filled,color=\".7 .3 1.0\"];\n"; diff --git a/src/capabilities/confscan.h b/src/capabilities/confscan.h index b967217..eda9a2d 100644 --- a/src/capabilities/confscan.h +++ b/src/capabilities/confscan.h @@ -259,7 +259,7 @@ class ConfScan : public CurcumaMethod { /*! \brief Check, if Reordering is forced */ inline bool PreventReorder() const { return m_prevent_reorder; } - inline std::string NamePattern(int index) const { return "input_" + std::to_string(index); } + inline std::string NamePattern(int index) const { return "#" + std::to_string(index); } std::vector Result() const { return m_result; } // std::vector Failed() const { return m_failed; } @@ -317,7 +317,7 @@ class ConfScan : public CurcumaMethod { int m_rejected = 0, m_accepted = 0, m_reordered = 0, m_reordered_worked = 0, m_reordered_failed_completely = 0, m_reordered_reused = 0, m_skip = 0, m_skiped = 0, m_duplicated = 0, m_rejected_directly = 0, m_molalign_count = 0, m_molalign_success = 0; std::string m_filename, m_accepted_filename, m_1st_filename, m_2nd_filename, m_3rd_filename, m_rejected_filename, m_result_basename, m_statistic_filename, m_prev_accepted, m_joined_filename, m_threshold_filename, m_current_filename, m_param_file, m_skip_file, m_perform_file, m_success_file, m_limit_file; - std::map m_ordered_list; + std::multimap m_ordered_list; std::vector> m_molecules; double m_rmsd_threshold = 1.0, m_print_rmsd = 0, m_nearly_missed = 0.8, m_energy_cutoff = -1, m_reference_last_energy = 0, m_target_last_energy = 0, m_lowest_energy = 1, m_current_energy = 0; @@ -340,8 +340,9 @@ class ConfScan : public CurcumaMethod { std::string m_rmsd_element_templates; std::string m_method = ""; std::string m_molalign = "molalign"; - std::map m_listH, m_listI, m_listE; - std::map> m_listThresh; + std::multimap m_listH, m_listI, m_listE; + std::multimap> m_listThresh; + std::map m_nodes; std::vector> m_list_skipped, m_list_performed; std::vector m_sLE = { 1.0 }, m_sLI = { 1.0 }, m_sLH = { 1.0 }; double m_domolalign = -1; From 51487d3a4928707ce5a646796dfaa6b9a855c05b Mon Sep 17 00:00:00 2001 From: Conrad Huebler Date: Fri, 6 Oct 2023 11:28:09 +0200 Subject: [PATCH 10/10] update tblite/xtb and extract dipole from xtb Signed-off-by: Conrad Huebler --- CMakeLists.txt | 1 + external/tblite | 2 +- external/xtb | 2 +- src/capabilities/curcumaopt.cpp | 23 +++++++++++++++++- src/capabilities/simplemd.cpp | 26 +++++++++++++++++--- src/capabilities/simplemd.h | 8 +++--- src/core/energycalculator.cpp | 43 +++++++++++++++++++++++++++++++++ src/core/energycalculator.h | 8 ++++++ src/core/tbliteinterface.cpp | 15 +++++++++++- src/core/tbliteinterface.h | 6 ++++- src/core/xtbinterface.cpp | 37 ++++++++++++++++++++++++++++ src/core/xtbinterface.h | 4 +++ 12 files changed, 164 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b465922..82e6688 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -206,6 +206,7 @@ if(USE_XTB) ) FetchContent_MakeAvailable("mctc-lib") endif() + include_directories(SYSTEM ${PROJECT_BINARY_DIR}/_deps/tblite-src/include/) if(HELPERS) add_executable(xtb_helper diff --git a/external/tblite b/external/tblite index 6ebded4..4ad71e5 160000 --- a/external/tblite +++ b/external/tblite @@ -1 +1 @@ -Subproject commit 6ebded4aa6ff1e84a13d545a0be68ea290c6e21d +Subproject commit 4ad71e5d821625ada9a468bb368d7cc5e3ce30c4 diff --git a/external/xtb b/external/xtb index 18b59f1..a62fe18 160000 --- a/external/xtb +++ b/external/xtb @@ -1 +1 @@ -Subproject commit 18b59f110e423d9643c8960b891acbd230180ba0 +Subproject commit a62fe184289f461e599827a8c2c000c710f43b66 diff --git a/src/capabilities/curcumaopt.cpp b/src/capabilities/curcumaopt.cpp index 360f80f..fa22f30 100644 --- a/src/capabilities/curcumaopt.cpp +++ b/src/capabilities/curcumaopt.cpp @@ -110,6 +110,7 @@ void CurcumaOpt::start() void CurcumaOpt::ProcessMoleculesSerial(const std::vector& molecules) { EnergyCalculator interface(Json2KeyWord(m_defaults, "method"), m_controller["sp"]); + std::string method = Json2KeyWord(m_defaults, "method"); auto iter = molecules.begin(); interface.setMolecule(*iter); @@ -122,6 +123,15 @@ void CurcumaOpt::ProcessMoleculesSerial(const std::vector& molecules) auto start = std::chrono::system_clock::now(); interface.updateGeometry(iter->Coords()); double energy = interface.CalculateEnergy(true, true); + std::cout << "dipole?" << std::endl; +#ifdef USE_TBLITE + if (method.compare("gfn2") == 0) { + std::vector dipole = interface.Dipole(); + std::cout << std::endl + << std::endl + << "Dipole momement " << dipole[0] << " " << dipole[1] << " " << dipole[2] << " : " << sqrt(dipole[0] * dipole[0] + dipole[1] * dipole[1] + dipole[2] * dipole[2]) << std::endl; + } +#endif if (m_hessian) { Hessian hess(m_method, m_defaults, m_threads); hess.setMolecule(*iter); @@ -215,7 +225,18 @@ double CurcumaOpt::SinglePoint(const Molecule* initial, const json& controller, EnergyCalculator interface(method, controller); interface.setMolecule(*initial); - return interface.CalculateEnergy(true, true); + double energy = interface.CalculateEnergy(true, true); + std::cout << "dipole1" << std::endl; + +#ifdef USE_TBLITE + if (method.compare("gfn2") == 0) { + std::vector dipole = interface.Dipole(); + std::cout << std::endl + << std::endl + << "Dipole momement " << dipole[0] << " " << dipole[1] << " " << dipole[2] << " : " << sqrt(dipole[0] * dipole[0] + dipole[1] * dipole[1] + dipole[2] * dipole[2]) * 2.5418 << std::endl; + } +#endif + return energy; } Molecule CurcumaOpt::LBFGSOptimise(const Molecule* initial, const json& controller, std::string& output, std::vector* intermediate) diff --git a/src/capabilities/simplemd.cpp b/src/capabilities/simplemd.cpp index f124564..3cdf402 100644 --- a/src/capabilities/simplemd.cpp +++ b/src/capabilities/simplemd.cpp @@ -85,6 +85,7 @@ void SimpleMD::LoadControlJson() m_writerestart = Json2KeyWord(m_defaults, "writerestart"); m_respa = Json2KeyWord(m_defaults, "respa"); + m_dipole = Json2KeyWord(m_defaults, "dipole"); m_writeXYZ = Json2KeyWord(m_defaults, "writeXYZ"); m_writeinit = Json2KeyWord(m_defaults, "writeinit"); @@ -530,7 +531,16 @@ void SimpleMD::start() } if (m_thermostat.compare("csvr") == 0) std::cout << "Exchange with heat bath " << m_Ekin_exchange << "Eh" << std::endl; - + if (m_dipole) { + /* + double dipole = 0.0; + for( auto d : m_collected_dipole) + dipole += d; + dipole /= m_collected_dipole.size(); + std::cout << dipole*2.5418 << " average dipole in Debye and " << dipole*2.5418*3.3356e-30 << " Cm" << std::endl; + */ + std::cout << "Calculated averaged dipole moment " << m_aver_dipol * 2.5418 << " Debye and " << m_aver_dipol * 2.5418 * 3.3356 << " Cm [e-30]" << std::endl; + } std::ofstream restart_file("curcuma_final.json"); restart_file << WriteRestartInformation() << std::endl; @@ -779,7 +789,10 @@ void SimpleMD::PrintStatus() const #endif } else { #ifdef GCC - std::cout << fmt::format("{1: ^{0}f} {2: ^{0}f} {3: ^{0}f} {4: ^{0}f} {5: ^{0}f} {6: ^{0}f} {7: ^{0}f} {8: ^{0}f} {9: ^{0}f} {10: ^{0}f}\n", 15, m_currentStep / 1000, m_Epot, m_aver_Epot, m_Ekin, m_aver_Ekin, m_Etot, m_aver_Etot, m_T, m_aver_Temp, remaining); + if (m_dipole) + std::cout << fmt::format("{1: ^{0}f} {2: ^{0}f} {3: ^{0}f} {4: ^{0}f} {5: ^{0}f} {6: ^{0}f} {7: ^{0}f} {8: ^{0}f} {9: ^{0}f} {10: ^{0}f} {11: ^{0}f}\n", 15, m_currentStep / 1000, m_Epot, m_aver_Epot, m_Ekin, m_aver_Ekin, m_Etot, m_aver_Etot, m_T, m_aver_Temp, m_aver_dipol * 2.5418 * 3.3356, remaining); + else + std::cout << fmt::format("{1: ^{0}f} {2: ^{0}f} {3: ^{0}f} {4: ^{0}f} {5: ^{0}f} {6: ^{0}f} {7: ^{0}f} {8: ^{0}f} {9: ^{0}f} {10: ^{0}f} \n", 15, m_currentStep / 1000, m_Epot, m_aver_Epot, m_Ekin, m_aver_Ekin, m_Etot, m_aver_Etot, m_T, m_aver_Temp, remaining); #else std::cout << m_currentStep * m_timestep / fs2amu / 1000 << " " << m_Epot << " " << m_Ekin << " " << m_Epot + m_Ekin << m_T << std::endl; @@ -802,6 +815,11 @@ double SimpleMD::Gradient(const double* coord, double* grad) double Energy = m_interface->CalculateEnergy(true); m_interface->getGradient(grad); + if (m_dipole) { + std::vector dipole = m_interface->Dipole(); + m_curr_dipole = sqrt(dipole[0] * dipole[0] + dipole[1] * dipole[1] + dipole[2] * dipole[2]); + m_collected_dipole.push_back(sqrt(dipole[0] * dipole[0] + dipole[1] * dipole[1] + dipole[2] * dipole[2])); + } return Energy; } @@ -819,7 +837,9 @@ double SimpleMD::EKin() m_aver_Epot = (m_Epot + (m_currentStep)*m_aver_Epot) / (m_currentStep + 1); m_aver_Ekin = (m_Ekin + (m_currentStep)*m_aver_Ekin) / (m_currentStep + 1); m_aver_Etot = (m_Etot + (m_currentStep)*m_aver_Etot) / (m_currentStep + 1); - + if (m_dipole) { + m_aver_dipol = (m_curr_dipole + (m_currentStep)*m_aver_dipol) / (m_currentStep + 1); + } return ekin; } diff --git a/src/capabilities/simplemd.h b/src/capabilities/simplemd.h index 4181aaa..85f7ade 100644 --- a/src/capabilities/simplemd.h +++ b/src/capabilities/simplemd.h @@ -62,7 +62,8 @@ static json CurcumaMDJson{ { "rattle", false }, { "rattle_tolerance", 1e-5 }, { "thermostat", "csvr" }, - { "respa", 1 } + { "respa", 1 }, + { "dipole", false } }; class SimpleMD : public CurcumaMethod { @@ -135,7 +136,7 @@ class SimpleMD : public CurcumaMethod { std::string m_basename; int m_natoms = 0; int m_dumb = 1; - double m_T = 0, m_Epot = 0, m_aver_Epot = 0, m_Ekin = 0, m_aver_Ekin = 0, m_Etot = 0, m_aver_Etot = 0; + double m_T = 0, m_Epot = 0, m_aver_Epot = 0, m_Ekin = 0, m_aver_Ekin = 0, m_Etot = 0, m_aver_Etot = 0, m_aver_dipol = 0, m_curr_dipole = 0; int m_hmass = 4; double m_single_step = 1; double m_timestep = 0.5, m_currentStep = 0, m_maxtime = 1000; @@ -157,11 +158,12 @@ class SimpleMD : public CurcumaMethod { double m_pos_conv = 0, m_scale_velo = 1.0, m_coupling = 10; double m_impuls = 0, m_impuls_scaling = 0.75, m_dt2 = 0; double m_rattle_tolerance = 1e-4; - + std::vector m_collected_dipole; Matrix m_topo_initial; std::vector m_unique_structures; std::string m_method = "UFF", m_initfile = "none", m_thermostat = "csvr"; bool m_unstable = false; + bool m_dipole = false; }; class MDThread : public CxxThread { diff --git a/src/core/energycalculator.cpp b/src/core/energycalculator.cpp index 40a74ea..6e5a5bf 100644 --- a/src/core/energycalculator.cpp +++ b/src/core/energycalculator.cpp @@ -32,6 +32,16 @@ EnergyCalculator::EnergyCalculator(const std::string& method, const json& controller) : m_method(method) { + m_charges = []() { + return std::vector{}; + }; + m_dipole = []() { + return std::vector{}; + }; + m_bonds = []() { + return std::vector>{ {} }; + }; + if (std::find(m_uff_methods.begin(), m_uff_methods.end(), m_method) != m_uff_methods.end()) { // UFF energy calculator requested m_uff = new eigenUFF(controller); m_ecengine = [this](bool gradient, bool verbose) { @@ -43,6 +53,15 @@ EnergyCalculator::EnergyCalculator(const std::string& method, const json& contro m_ecengine = [this](bool gradient, bool verbose) { this->CalculateTBlite(gradient, verbose); }; + m_charges = [this]() { + return this->m_tblite->Charges(); + }; + m_dipole = [this]() { + return this->m_tblite->Dipole(); + }; + m_bonds = [this]() { + return this->m_tblite->BondOrders(); + }; #else std::cout << "TBlite was not included ..." << std::endl; exit(1); @@ -54,6 +73,15 @@ EnergyCalculator::EnergyCalculator(const std::string& method, const json& contro m_ecengine = [this](bool gradient, bool verbose) { this->CalculateXTB(gradient, verbose); }; + m_charges = [this]() { + return this->m_xtb->Charges(); + }; + m_dipole = [this]() { + return this->m_xtb->Dipole(); + }; + m_bonds = [this]() { + return this->m_xtb->BondOrders(); + }; #else std::cout << "XTB was not included ..." << std::endl; exit(1); @@ -307,3 +335,18 @@ Matrix EnergyCalculator::Gradient() const { return m_eigen_gradient; } + +std::vector EnergyCalculator::Charges() const +{ + return m_charges(); +} + +std::vector EnergyCalculator::Dipole() const +{ + return m_dipole(); +} + +std::vector> EnergyCalculator::BondOrders() const +{ + return m_bonds(); +} diff --git a/src/core/energycalculator.h b/src/core/energycalculator.h index 16c6d07..72dfbdf 100644 --- a/src/core/energycalculator.h +++ b/src/core/energycalculator.h @@ -92,6 +92,11 @@ class EnergyCalculator { } #endif + std::vector Charges() const; + std::vector Dipole() const; + + std::vector> BondOrders() const; + private: void InitialiseUFF(); void CalculateUFF(bool gradient, bool verbose = false); @@ -131,6 +136,9 @@ class EnergyCalculator { StringList m_d3_methods = { "d3" }; StringList m_d4_methods = { "d4" }; std::function m_ecengine; + std::function()> m_charges, m_dipole; + std::function>()> m_bonds; + std::string m_method; std::vector> m_geometry, m_gradient; Matrix m_eigen_geometry, m_eigen_gradient; diff --git a/src/core/tbliteinterface.cpp b/src/core/tbliteinterface.cpp index fe2a1d9..4cb9944 100644 --- a/src/core/tbliteinterface.cpp +++ b/src/core/tbliteinterface.cpp @@ -17,7 +17,9 @@ * */ -#include "external/tblite/include/tblite.h" +#ifndef tblite_delete +#include "tblite.h" +#endif #include "src/core/global.h" #include "src/tools/general.h" @@ -181,6 +183,17 @@ std::vector TBLiteInterface::Charges() const return charges; } +std::vector TBLiteInterface::Dipole() const +{ + std::vector dipole(3); + double* c = new double[3]; + tblite_get_result_dipole(m_error, m_tblite_res, c); + for (int i = 0; i < 3; ++i) + dipole[i] = c[i]; + delete[] c; + return dipole; +} + std::vector> TBLiteInterface::BondOrders() const { std::vector> bond_orders(m_atomcount); diff --git a/src/core/tbliteinterface.h b/src/core/tbliteinterface.h index 8bcca17..55276ad 100644 --- a/src/core/tbliteinterface.h +++ b/src/core/tbliteinterface.h @@ -21,7 +21,9 @@ #include "src/tools/general.h" -#include "external/tblite/include/tblite.h" +#ifndef tblite_delete +#include "tblite.h" +#endif #include "src/core/molecule.h" @@ -59,6 +61,8 @@ class TBLiteInterface { void clear(); std::vector Charges() const; + std::vector Dipole() const; + std::vector> BondOrders() const; private: diff --git a/src/core/xtbinterface.cpp b/src/core/xtbinterface.cpp index b50ecfc..ba6b39a 100644 --- a/src/core/xtbinterface.cpp +++ b/src/core/xtbinterface.cpp @@ -142,6 +142,43 @@ double XTBInterface::GFNCalculation(int parameter, double* grad) return energy; } +std::vector XTBInterface::Charges() const +{ + std::vector charges(m_atomcount); + double* c = new double[m_atomcount]; + xtb_getCharges(m_env, m_xtb_res, c); + for (int i = 0; i < m_atomcount; ++i) + charges[i] = c[i]; + delete[] c; + return charges; +} + +std::vector XTBInterface::Dipole() const +{ + std::vector dipole(3); + double* c = new double[3]; + xtb_getDipole(m_env, m_xtb_res, c); + for (int i = 0; i < 3; ++i) + dipole[i] = c[i]; + delete[] c; + return dipole; +} + +std::vector> XTBInterface::BondOrders() const +{ + std::vector> bond_orders(m_atomcount); + double* bonds = new double[m_atomcount * m_atomcount]; + xtb_getBondOrders(m_env, m_xtb_res, bonds); + for (int i = 0; i < m_atomcount; ++i) { + std::vector b(m_atomcount); + for (int j = 0; j < m_atomcount; ++j) + b[j] = bonds[i * j]; + bond_orders[i] = b; + } + delete[] bonds; + return bond_orders; +} + void XTBInterface::clear() { xtb_delResults(&m_xtb_res); diff --git a/src/core/xtbinterface.h b/src/core/xtbinterface.h index 5b09094..1344968 100644 --- a/src/core/xtbinterface.h +++ b/src/core/xtbinterface.h @@ -53,6 +53,10 @@ class XTBInterface { double GFNCalculation(int parameter = 2, double* grad = 0); void clear(); + std::vector Charges() const; + std::vector Dipole() const; + + std::vector> BondOrders() const; private: int m_atomcount = 0;