int main (int argc, char **argv) { try { MailMessage msg; msg.addRecipient (MailRecipient (MailRecipient::PRIMARY_RECIPIENT, "*****@*****.**", "Alice Moralis")); msg.addRecipient (MailRecipient (MailRecipient::CC_RECIPIENT, "*****@*****.**", "Patrick Kilpatrick")); msg.addRecipient (MailRecipient (MailRecipient::BCC_RECIPIENT, "*****@*****.**", "Michael Carmichael")); msg.setSender ("Roy Kilroy <*****@*****.**>"); msg.setSubject ("Rosetta Code"); msg.setContent ("Sending mail from C++ using POCO C++ Libraries"); SMTPClientSession smtp ("mail.example.com"); // SMTP server name smtp.login (); smtp.sendMessage (msg); smtp.close (); std::cerr << "Sent mail successfully!" << std::endl; } catch (std::exception &e) { std::cerr << "failed to send mail: " << e.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
void SMTPClientSessionTest::testSendFailed() { DialogServer server; server.addResponse("220 localhost SMTP ready"); server.addResponse("250 Hello localhost"); server.addResponse("250 OK"); server.addResponse("250 OK"); server.addResponse("354 Send data"); server.addResponse("500 Error"); server.addResponse("221 Bye"); SMTPClientSession session("localhost", server.port()); session.login("localhost"); MailMessage message; message.setSender("*****@*****.**"); message.addRecipient(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, "*****@*****.**", "Jane Doe")); message.setSubject("Test Message"); message.setContent("Hello\r\nblah blah\r\n\r\nJohn\r\n"); server.clearCommands(); try { session.sendMessage(message); fail("internal error - must throw"); } catch (SMTPException&) { } session.close(); }
void MailMessageTest::testWrite8Bit() { MailMessage message; MailRecipient r1(MailRecipient::PRIMARY_RECIPIENT, "*****@*****.**", "John Doe"); message.addRecipient(r1); message.setSubject("Test Message"); message.setSender("*****@*****.**"); message.setContent( "Hello, world!\r\n" "This is a test for the MailMessage class.\r\n", MailMessage::ENCODING_8BIT ); Timestamp ts(0); message.setDate(ts); std::ostringstream str; message.write(str); std::string s = str.str(); assert (s == "Date: Thu, 1 Jan 1970 00:00:00 GMT\r\n" "Content-Type: text/plain\r\n" "Subject: Test Message\r\n" "From: [email protected]\r\n" "Content-Transfer-Encoding: 8bit\r\n" "To: John Doe <*****@*****.**>\r\n" "\r\n" "Hello, world!\r\n" "This is a test for the MailMessage class.\r\n" ); }
void MailMessageTest::testWriteBase64() { MailMessage message; MailRecipient r1(MailRecipient::PRIMARY_RECIPIENT, "*****@*****.**", "John Doe"); message.addRecipient(r1); message.setSubject("Test Message"); message.setSender("*****@*****.**"); message.setContent( "Hello, world!\r\n" "This is a test for the MailMessage class.\r\n", MailMessage::ENCODING_BASE64 ); Timestamp ts(0); message.setDate(ts); std::ostringstream str; message.write(str); std::string s = str.str(); assert (s == "Date: Thu, 1 Jan 1970 00:00:00 GMT\r\n" "Content-Type: text/plain\r\n" "Subject: Test Message\r\n" "From: [email protected]\r\n" "Content-Transfer-Encoding: base64\r\n" "To: John Doe <*****@*****.**>\r\n" "\r\n" "SGVsbG8sIHdvcmxkIQ0KVGhpcyBpcyBhIHRlc3QgZm9yIHRoZSBNYWlsTWVzc2FnZSBjbGFz\r\n" "cy4NCg==" ); }
void SendMail::sendMessage(const std::string& content) { try { const Poco::Util::AbstractConfiguration* config = Poco::Util::Application::instance().config().createView("ion.mail"); MailMessage message; message.setSender(config->getString("sender")); message.addRecipient(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, config->getString("recipient"))); message.setSubject(MailMessage::encodeWord(config->getString("subject"), "UTF-8")); message.setContentType("text/plain; charset=UTF-8"); message.addContent(new Poco::Net::StringPartSource(content)); Poco::Net::SocketAddress address(config->getString("host"), config->getInt("port")); Poco::SharedPtr<Poco::Net::StreamSocket> socket(nullptr); if (config->getBool("ssl")) { socket = new Poco::Net::SecureStreamSocket(address); } else { socket = new Poco::Net::StreamSocket(address); } _logger.debug("Connecting to %s", address.toString()); SMTPClientSession session(*socket); session.login(getLoginMethod(config->getString("loginmethod")), config->getString("user"), config->getString("password")); session.sendMessage(message); session.close(); _logger.debug("Message sent"); } catch (Poco::Exception& ex) { _logger.error(ex.displayText()); throw; } }
void MailMessageTest::testWriteMultiPart() { MailMessage message; MailRecipient r1(MailRecipient::PRIMARY_RECIPIENT, "*****@*****.**", "John Doe"); message.addRecipient(r1); message.setSubject("Test Message"); message.setSender("*****@*****.**"); Timestamp ts(0); message.setDate(ts); message.addContent(new StringPartSource("Hello World!\r\n", "text/plain"), MailMessage::ENCODING_8BIT); StringPartSource* pSPS = new StringPartSource("This is some binary data. Really.", "application/octet-stream", "sample.dat"); pSPS->headers().set("Content-ID", "abcd1234"); message.addAttachment("sample", pSPS); assert (message.isMultipart()); std::ostringstream str; message.write(str); std::string s = str.str(); std::string rawMsg( "Date: Thu, 1 Jan 1970 00:00:00 GMT\r\n" "Content-Type: multipart/mixed; boundary=$\r\n" "Subject: Test Message\r\n" "From: [email protected]\r\n" "To: John Doe <*****@*****.**>\r\n" "Mime-Version: 1.0\r\n" "\r\n" "--$\r\n" "Content-Type: text/plain\r\n" "Content-Transfer-Encoding: 8bit\r\n" "Content-Disposition: inline\r\n" "\r\n" "Hello World!\r\n" "\r\n" "--$\r\n" "Content-ID: abcd1234\r\n" "Content-Type: application/octet-stream; name=sample\r\n" "Content-Transfer-Encoding: base64\r\n" "Content-Disposition: attachment; filename=sample.dat\r\n" "\r\n" "VGhpcyBpcyBzb21lIGJpbmFyeSBkYXRhLiBSZWFsbHku\r\n" "--$--\r\n" ); std::string::size_type p1 = s.find('=') + 1; std::string::size_type p2 = s.find('\r', p1); std::string boundary(s, p1, p2 - p1); std::string msg; for (std::string::const_iterator it = rawMsg.begin(); it != rawMsg.end(); ++it) { if (*it == '$') msg += boundary; else msg += *it; } assert (s == msg); }
void MailMessageTest::testWriteQP() { MailMessage message; MailRecipient r1(MailRecipient::PRIMARY_RECIPIENT, "*****@*****.**", "John Doe"); MailRecipient r2(MailRecipient::CC_RECIPIENT, "*****@*****.**", "Jane Doe"); MailRecipient r3(MailRecipient::BCC_RECIPIENT, "*****@*****.**", "Frank Foo"); MailRecipient r4(MailRecipient::BCC_RECIPIENT, "*****@*****.**", "Bernie Bar"); message.addRecipient(r1); message.addRecipient(r2); message.addRecipient(r3); message.addRecipient(r4); message.setSubject("Test Message"); message.setSender("*****@*****.**"); message.setContent( "Hello, world!\r\n" "This is a test for the MailMessage class.\r\n" "To test the quoted-printable encoding, we'll put an extra long line here. This should be enough.\r\n" "And here is some more =fe.\r\n" ); Timestamp ts(0); message.setDate(ts); assert (!message.isMultipart()); std::ostringstream str; message.write(str); std::string s = str.str(); assert (s == "Date: Thu, 1 Jan 1970 00:00:00 GMT\r\n" "Content-Type: text/plain\r\n" "Subject: Test Message\r\n" "From: [email protected]\r\n" "Content-Transfer-Encoding: quoted-printable\r\n" "To: John Doe <*****@*****.**>\r\n" "CC: Jane Doe <*****@*****.**>\r\n" "\r\n" "Hello, world!\r\n" "This is a test for the MailMessage class.\r\n" "To test the quoted-printable encoding, we'll put an extra long line here. T=\r\n" "his should be enough.\r\n" "And here is some more =3Dfe.\r\n" ); }
void SMTPChannel::log(const Message& msg) { try { MailMessage message; message.setSender(_sender); message.addRecipient(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, _recipient)); message.setSubject("Log Message from " + _sender); std::stringstream content; content << "Log Message\r\n" << "===========\r\n\r\n" << "Host: " << Environment::nodeName() << "\r\n" << "Logger: " << msg.getSource() << "\r\n"; if (_local) { DateTime dt(msg.getTime()); content << "Timestamp: " << DateTimeFormatter::format(LocalDateTime(dt), DateTimeFormat::RFC822_FORMAT) << "\r\n"; } else content << "Timestamp: " << DateTimeFormatter::format(msg.getTime(), DateTimeFormat::RFC822_FORMAT) << "\r\n"; content << "Priority: " << NumberFormatter::format(msg.getPriority()) << "\r\n" << "Process ID: " << NumberFormatter::format(msg.getPid()) << "\r\n" << "Thread: " << msg.getThread() << " (ID: " << msg.getTid() << ")\r\n" << "Message text: " << msg.getText() << "\r\n\r\n"; message.addContent(new StringPartSource(content.str())); if (!_attachment.empty()) { { Poco::FileInputStream fis(_attachment, std::ios::in | std::ios::binary | std::ios::ate); if (fis.good()) { int size = fis.tellg(); char* pMem = new char [size]; fis.seekg(std::ios::beg); fis.read(pMem, size); message.addAttachment(_attachment, new StringPartSource(std::string(pMem, size), _type, _attachment)); delete [] pMem; } } if (_delete) File(_attachment).remove(); } SMTPClientSession session(_mailHost); session.login(); session.sendMessage(message); session.close(); } catch (Exception&) { if (_throw) throw; } }
int main(int argc, char** argv) { SSLInitializer sslInitializer; if (argc < 4) { Path p(argv[0]); std::cerr << "usage: " << p.getBaseName() << " <mailhost> <sender> <recipient> [<username> <password>]" << std::endl; std::cerr << " Send an email greeting from <sender> to <recipient>," << std::endl; std::cerr << " using a secure connection to the SMTP server at <mailhost>." << std::endl; return 1; } std::string mailhost(argv[1]); std::string sender(argv[2]); std::string recipient(argv[3]); std::string username(argc >= 5 ? argv[4] : ""); std::string password(argc >= 6 ? argv[5] : ""); try { // Note: we must create the passphrase handler prior Context SharedPtr<InvalidCertificateHandler> pCert = new ConsoleCertificateHandler(false); // ask the user via console Context::Ptr pContext = new Context(Context::CLIENT_USE, "", "", "", Context::VERIFY_RELAXED, 9, true, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); SSLManager::instance().initializeClient(0, pCert, pContext); MailMessage message; message.setSender(sender); message.addRecipient(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, recipient)); message.setSubject("Hello from the POCO C++ Libraries"); std::string content; content += "Hello "; content += recipient; content += ",\r\n\r\n"; content += "This is a greeting from the POCO C++ Libraries.\r\n\r\n"; std::string logo(reinterpret_cast<const char*>(PocoLogo), sizeof(PocoLogo)); message.addContent(new StringPartSource(content)); message.addAttachment("logo", new StringPartSource(logo, "image/gif")); SecureSMTPClientSession session(mailhost); session.login(); session.startTLS(pContext); if (!username.empty()) { session.login(SMTPClientSession::AUTH_LOGIN, username, password); } session.sendMessage(message); session.close(); } catch (Exception& exc) { std::cerr << exc.displayText() << std::endl; return 1; } return 0; }
void MailMessageTest::testWriteManyRecipients() { MailMessage message; MailRecipient r1(MailRecipient::PRIMARY_RECIPIENT, "*****@*****.**", "John Doe"); MailRecipient r2(MailRecipient::PRIMARY_RECIPIENT, "*****@*****.**", "Jane Doe"); MailRecipient r3(MailRecipient::PRIMARY_RECIPIENT, "*****@*****.**", "Frank Foo"); MailRecipient r4(MailRecipient::PRIMARY_RECIPIENT, "*****@*****.**", "Bernie Bar"); MailRecipient r5(MailRecipient::PRIMARY_RECIPIENT, "*****@*****.**", "Joe Spammer"); message.addRecipient(r1); message.addRecipient(r2); message.addRecipient(r3); message.addRecipient(r4); message.addRecipient(r5); message.setSubject("Test Message"); message.setSender("*****@*****.**"); message.setContent( "Hello, world!\r\n" "This is a test for the MailMessage class.\r\n", MailMessage::ENCODING_8BIT ); Timestamp ts(0); message.setDate(ts); std::ostringstream str; message.write(str); std::string s = str.str(); assert (s == "Date: Thu, 1 Jan 1970 00:00:00 GMT\r\n" "Content-Type: text/plain\r\n" "Subject: Test Message\r\n" "From: [email protected]\r\n" "Content-Transfer-Encoding: 8bit\r\n" "To: John Doe <*****@*****.**>, Jane Doe <*****@*****.**>, \r\n" "\tFrank Foo <*****@*****.**>, Bernie Bar <*****@*****.**>, \r\n" "\tJoe Spammer <*****@*****.**>\r\n" "\r\n" "Hello, world!\r\n" "This is a test for the MailMessage class.\r\n" ); }
void SMTPClientSessionTest::testSend() { DialogServer server; server.addResponse("220 localhost SMTP ready"); server.addResponse("250 Hello localhost"); server.addResponse("250 OK"); server.addResponse("250 OK"); server.addResponse("354 Send data"); server.addResponse("250 OK"); server.addResponse("221 Bye"); SMTPClientSession session("localhost", server.port()); session.login("localhost"); MailMessage message; message.setSender("*****@*****.**"); message.addRecipient(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, "*****@*****.**", "Jane Doe")); message.setSubject("Test Message"); message.setContent("Hello\r\nblah blah\r\n\r\nJohn\r\n"); server.clearCommands(); session.sendMessage(message); std::string cmd = server.popCommandWait(); assert (cmd == "MAIL FROM: <*****@*****.**>"); cmd = server.popCommandWait(); assert (cmd == "RCPT TO: <*****@*****.**>"); cmd = server.popCommandWait(); assert (cmd == "DATA"); cmd = server.popCommandWait(); assert (cmd.substr(0, 4) == "Date"); cmd = server.popCommandWait(); assert (cmd == "Content-Type: text/plain"); cmd = server.popCommandWait(); assert (cmd == "From: [email protected]"); cmd = server.popCommandWait(); assert (cmd == "Subject: Test Message"); cmd = server.popCommandWait(); assert (cmd == "Content-Transfer-Encoding: quoted-printable"); cmd = server.popCommandWait(); assert (cmd == "To: Jane Doe <*****@*****.**>"); cmd = server.popCommandWait(); assert (cmd == "Hello"); cmd = server.popCommandWait(); assert (cmd == "blah blah"); cmd = server.popCommandWait(); assert (cmd == "John"); cmd = server.popCommandWait(); assert (cmd == "."); session.close(); }
int main(int argc, char** argv) { if (argc != 4) { Path p(argv[0]); std::cerr << "usage: " << p.getBaseName() << " <mailhost> <sender> <recipient>" << std::endl; std::cerr << " Send an email greeting from <sender> to <recipient>," << std::endl; std::cerr << " the SMTP server at <mailhost>." << std::endl; return 1; } std::string mailhost(argv[1]); std::string sender(argv[2]); std::string recipient(argv[3]); try { MailMessage message; message.setSender(sender); message.addRecipient(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, recipient)); message.setSubject("Hello from the POCO C++ Libraries"); std::string content; content += "Hello "; content += recipient; content += ",\r\n\r\n"; content += "This is a greeting from the POCO C++ Libraries.\r\n\r\n"; std::string logo(reinterpret_cast<const char*>(PocoLogo), sizeof(PocoLogo)); message.addContent(new StringPartSource(content)); message.addAttachment("logo", new StringPartSource(logo, "image/gif")); SMTPClientSession session(mailhost); session.login(); session.sendMessage(message); session.close(); } catch (Exception& exc) { std::cerr << exc.displayText() << std::endl; return 1; } return 0; }
void Test_MailMessage() { std::string sender("*****@*****.**"); std::string recipient("*****@*****.**"); std::string subject("Generated email"); std::string content = "Hi "; content += recipient; content += ",\n\n"; content += "Have a good day!\n\n"; content += "Regards,\n"; content += "A-Team"; std::string attachment("C:\\DSC.jpg"); MailMessage message; message.setSender( sender ); message.addRecipient( MailRecipient(MailRecipient::PRIMARY_RECIPIENT, recipient) ); message.setSubject( subject ); message.setContent( content ); message.addAttachment( attachment ); send(message); }
int main(int argc, char* argv[]) { // Check the required number of command line arguments. if (argc != 5) { cout << "usr host user pwd jobs_path" << endl; return 0; } // Fetch command line arguments. const auto host = argv[1]; const auto user = argv[2]; const auto pwd = argv[3]; const path jobs_path = argv[4]; // Connect to host and authenticate user. DBClientConnection conn; { cout << local_time() << "Connecting to " << host << " and authenticating " << user << endl; string errmsg; if ((!conn.connect(host, errmsg)) || (!conn.auth("istar", user, pwd, errmsg))) { cerr << local_time() << errmsg << endl; return 1; } } // Initialize constants. cout << local_time() << "Initializing" << endl; const auto collection = "istar.usr"; const auto epoch = date(1970, 1, 1); const size_t num_usrs = 2; constexpr array<size_t, num_usrs> qn{{ 12, 60 }}; constexpr array<double, num_usrs> qv{{ 1.0 / qn[0], 1.0 / qn[1] }}; const size_t num_references = 4; const size_t num_subsets = 5; const array<string, num_subsets> SubsetSMARTS {{ "[!#1]", // heavy "[#6+0!$(*~[#7,#8,F]),SH0+0v2,s+0,S^3,Cl+0,Br+0,I+0]", // hydrophobic "[a]", // aromatic "[$([O,S;H1;v2]-[!$(*=[O,N,P,S])]),$([O,S;H0;v2]),$([O,S;-]),$([N&v3;H1,H2]-[!$(*=[O,N,P,S])]),$([N;v3;H0]),$([n,o,s;+0]),F]", // acceptor "[N!H0v3,N!H0+v4,OH+0,SH+0,nH+0]", // donor }}; // Initialize variables. array<array<double, qn.back()>, 1> qw; array<array<double, qn.back()>, 1> lw; auto q = qw[0]; auto l = lw[0]; // Read ZINC ID file. const string_array<size_t> zincids("16_zincid.txt"); const auto num_ligands = zincids.size(); // Read SMILES file. const string_array<size_t> smileses("16_smiles.txt"); assert(smileses.size() == num_ligands); // Read supplier file. const string_array<size_t> suppliers("16_supplier.txt"); assert(suppliers.size() == num_ligands); // Read property files of floating point types and integer types. const auto zfproperties = read<array<float, 4>>("16_zfprop.f32"); assert(zfproperties.size() == num_ligands); const auto ziproperties = read<array<int16_t, 5>>("16_ziprop.i16"); assert(ziproperties.size() == num_ligands); // Open files for subsequent reading. std::ifstream usrcat_bin("16_usrcat.f64"); stream_array<size_t> ligands("16_ligand.pdbqt"); assert(ligands.size() == num_ligands); array<vector<double>, 2> scores {{ vector<double>(num_ligands, 0), vector<double>(num_ligands, 0) }}; const auto& u0scores = scores[0]; const auto& u1scores = scores[1]; vector<size_t> scase(num_ligands); // Enter event loop. cout << local_time() << "Entering event loop" << endl; bool sleeping = false; while (true) { // Fetch an incompleted job in a first-come-first-served manner. if (!sleeping) cout << local_time() << "Fetching an incompleted job" << endl; BSONObj info; conn.runCommand("istar", BSON("findandmodify" << "usr" << "query" << BSON("done" << BSON("$exists" << false) << "started" << BSON("$exists" << false)) << "sort" << BSON("submitted" << 1) << "update" << BSON("$set" << BSON("started" << Date_t(duration_cast<std::chrono::milliseconds>(system_clock::now().time_since_epoch()).count())))), info); // conn.findAndModify() is available since MongoDB C++ Driver legacy-1.0.0 const auto value = info["value"]; if (value.isNull()) { // No incompleted jobs. Sleep for a while. if (!sleeping) cout << local_time() << "Sleeping" << endl; sleeping = true; this_thread::sleep_for(chrono::seconds(10)); continue; } sleeping = false; const auto job = value.Obj(); // Obtain job properties. const auto _id = job["_id"].OID(); cout << local_time() << "Executing job " << _id.str() << endl; const auto job_path = jobs_path / _id.str(); const auto format = job["format"].String(); const auto email = job["email"].String(); // Parse the user-supplied ligand. OBMol obMol; OBConversion obConversion; obConversion.SetInFormat(format.c_str()); obConversion.ReadFile(&obMol, (job_path / ("ligand." + format)).string()); const auto num_atoms = obMol.NumAtoms(); // obMol.AddHydrogens(); // Adding hydrogens does not seem to affect SMARTS matching. // Classify subset atoms. array<vector<int>, num_subsets> subsets; for (size_t k = 0; k < num_subsets; ++k) { auto& subset = subsets[k]; subset.reserve(num_atoms); OBSmartsPattern smarts; smarts.Init(SubsetSMARTS[k]); smarts.Match(obMol); for (const auto& map : smarts.GetMapList()) { subset.push_back(map.front()); } } const auto& subset0 = subsets.front(); // Check user-provided ligand validity. if (subset0.empty()) { // Record job completion time stamp. const auto millis_since_epoch = duration_cast<std::chrono::milliseconds>(system_clock::now().time_since_epoch()).count(); conn.update(collection, BSON("_id" << _id), BSON("$set" << BSON("done" << Date_t(millis_since_epoch)))); // Send error notification email. cout << local_time() << "Sending an error notification email to " << email << endl; MailMessage message; message.setSender("usr <*****@*****.**>"); message.setSubject("Your usr job has failed"); message.setContent("Description: " + job["description"].String() + "\nSubmitted: " + to_simple_string(ptime(epoch, boost::posix_time::milliseconds(job["submitted"].Date().millis))) + " UTC\nFailed: " + to_simple_string(ptime(epoch, boost::posix_time::milliseconds(millis_since_epoch))) + " UTC\nReason: failed to parse the provided ligand."); message.addRecipient(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, email)); SMTPClientSession session("137.189.91.190"); session.login(); session.sendMessage(message); session.close(); continue; } // Calculate the four reference points. const auto n = subset0.size(); const auto v = 1.0 / n; array<vector3, num_references> references{}; auto& ctd = references[0]; auto& cst = references[1]; auto& fct = references[2]; auto& ftf = references[3]; for (const auto i : subset0) { ctd += obMol.GetAtom(i)->GetVector(); } ctd *= v; double cst_dist = numeric_limits<double>::max(); double fct_dist = numeric_limits<double>::lowest(); double ftf_dist = numeric_limits<double>::lowest(); for (const auto i : subset0) { const auto& a = obMol.GetAtom(i)->GetVector(); const auto this_dist = a.distSq(ctd); if (this_dist < cst_dist) { cst = a; cst_dist = this_dist; } if (this_dist > fct_dist) { fct = a; fct_dist = this_dist; } } for (const auto i : subset0) { const auto& a = obMol.GetAtom(i)->GetVector(); const auto this_dist = a.distSq(fct); if (this_dist > ftf_dist) { ftf = a; ftf_dist = this_dist; } } // Precalculate the distances between each atom and each reference point. array<vector<double>, num_references> dista; for (size_t k = 0; k < num_references; ++k) { const auto& reference = references[k]; auto& dists = dista[k]; dists.resize(1 + num_atoms); // OpenBabel atom index starts from 1. dists[0] is dummy. for (size_t i = 0; i < n; ++i) { dists[subset0[i]] = sqrt(obMol.GetAtom(subset0[i])->GetVector().distSq(reference)); } } // Calculate USR and USRCAT features of the input ligand. size_t qo = 0; for (const auto& subset : subsets) { const auto n = subset.size(); for (size_t k = 0; k < num_references; ++k) { const auto& distp = dista[k]; vector<double> dists(n); for (size_t i = 0; i < n; ++i) { dists[i] = distp[subset[i]]; } array<double, 3> m{}; if (n > 2) { const auto v = 1.0 / n; for (size_t i = 0; i < n; ++i) { const auto d = dists[i]; m[0] += d; } m[0] *= v; for (size_t i = 0; i < n; ++i) { const auto d = dists[i] - m[0]; m[1] += d * d; } m[1] = sqrt(m[1] * v); for (size_t i = 0; i < n; ++i) { const auto d = dists[i] - m[0]; m[2] += d * d * d; } m[2] = cbrt(m[2] * v); } else if (n == 2) { m[0] = 0.5 * (dists[0] + dists[1]); m[1] = 0.5 * fabs(dists[0] - dists[1]); } else if (n == 1) { m[0] = dists[0]; } #pragma unroll for (const auto e : m) { q[qo++] = e; } } } assert(qo == qn.back()); // Compute USR and USRCAT scores. usrcat_bin.seekg(0); for (size_t k = 0; k < num_ligands; ++k) { usrcat_bin.read(reinterpret_cast<char*>(l.data()), sizeof(l)); double s = 0; #pragma unroll for (size_t i = 0, u = 0; u < num_usrs; ++u) { #pragma unroll for (const auto qnu = qn[u]; i < qnu; ++i) { s += fabs(q[i] - l[i]); } scores[u][k] = s; } } assert(usrcat_bin.tellg() == sizeof(l) * num_ligands); // Sort ligands by USRCAT score and then by USR score and then by ZINC ID. iota(scase.begin(), scase.end(), 0); sort(scase.begin(), scase.end(), [&](const size_t val0, const size_t val1) { const auto u1score0 = u1scores[val0]; const auto u1score1 = u1scores[val1]; if (u1score0 == u1score1) { const auto u0score0 = u0scores[val0]; const auto u0score1 = u0scores[val1]; if (u0score0 == u0score1) { return zincids[val0] < zincids[val1]; } return u0score0 < u0score1; } return u1score0 < u1score1; }); // Write results. filtering_ostream log_csv_gz; log_csv_gz.push(gzip_compressor()); log_csv_gz.push(file_sink((job_path / "log.csv.gz").string())); log_csv_gz.setf(ios::fixed, ios::floatfield); log_csv_gz << "ZINC ID,USR score,USRCAT score\n" << setprecision(8); filtering_ostream ligands_pdbqt_gz; ligands_pdbqt_gz.push(gzip_compressor()); ligands_pdbqt_gz.push(file_sink((job_path / "ligands.pdbqt.gz").string())); ligands_pdbqt_gz.setf(ios::fixed, ios::floatfield); for (size_t t = 0; t < 10000; ++t) { const size_t k = scase[t]; const auto zincid = zincids[k].substr(0, 8); // Take another substr() to get rid of the trailing newline. const auto u0score = 1 / (1 + scores[0][k] * qv[0]); const auto u1score = 1 / (1 + scores[1][k] * qv[1]); log_csv_gz << zincid << ',' << u0score << ',' << u1score << '\n'; // Only write conformations of the top ligands to ligands.pdbqt.gz. if (t >= 1000) continue; const auto zfp = zfproperties[k]; const auto zip = ziproperties[k]; ligands_pdbqt_gz << "MODEL " << '\n' << "REMARK 911 " << zincid << setprecision(3) << ' ' << setw(8) << zfp[0] << ' ' << setw(8) << zfp[1] << ' ' << setw(8) << zfp[2] << ' ' << setw(8) << zfp[3] << ' ' << setw(3) << zip[0] << ' ' << setw(3) << zip[1] << ' ' << setw(3) << zip[2] << ' ' << setw(3) << zip[3] << ' ' << setw(3) << zip[4] << '\n' << "REMARK 912 " << smileses[k] // A newline is already included in smileses[k]. << "REMARK 913 " << suppliers[k] // A newline is already included in suppliers[k]. << setprecision(8) << "REMARK 951 USR SCORE: " << setw(10) << u0score << '\n' << "REMARK 952 USRCAT SCORE: " << setw(10) << u1score << '\n' ; const auto lig = ligands[k]; ligands_pdbqt_gz.write(lig.data(), lig.size()); ligands_pdbqt_gz << "ENDMDL\n"; } // Update progress. cout << local_time() << "Setting done time" << endl; const auto millis_since_epoch = duration_cast<std::chrono::milliseconds>(system_clock::now().time_since_epoch()).count(); conn.update(collection, BSON("_id" << _id), BSON("$set" << BSON("done" << Date_t(millis_since_epoch)))); // Send completion notification email. cout << local_time() << "Sending a completion notification email to " << email << endl; MailMessage message; message.setSender("istar <*****@*****.**>"); message.setSubject("Your usr job has completed"); message.setContent("Description: " + job["description"].String() + "\nSubmitted: " + to_simple_string(ptime(epoch, boost::posix_time::milliseconds(job["submitted"].Date().millis))) + " UTC\nCompleted: " + to_simple_string(ptime(epoch, boost::posix_time::milliseconds(millis_since_epoch))) + " UTC\nResult: http://istar.cse.cuhk.edu.hk/usr/iview/?" + _id.str()); message.addRecipient(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, email)); SMTPClientSession session("137.189.91.190"); session.login(); session.sendMessage(message); session.close(); } }