#ifndef SEQLIB_UTILS_H #define SEQLIB_UTILS_H #include <string> #include <time.h> #include <ctime> #include <vector> #include <unistd.h> #include <sstream> #include <cmath> #include <algorithm> #include <stdio.h> #include "SeqLib/SeqLibCommon.h" #if __cplusplus > 199711L #include <memory> #include <unordered_set> #include <unordered_map> #define SeqHashMap std::unordered_map #define SeqHashSet std::unordered_set #define SeqPointer std::shared_ptr #define HAVE_C11 1 #else #ifdef __APPLE__ #include <memory> #include <unordered_set> #include <unordered_map> #define SeqHashMap std::unordered_map #define SeqHashSet std::unordered_set #define SeqPointer std::shared_ptr #else #include <tr1/memory> #include <tr1/unordered_set> #include <tr1/unordered_map> #define SeqHashMap std::tr1::unordered_map #define SeqHashSet std::tr1::unordered_set #define SeqPointer std::tr1::shared_ptr #endif #endif namespace SeqLib { template<typename T> inline std::string tostring(T d) { std::stringstream ss; ss << d; return ss.str(); } /** Check if a file is readable and exists * @param name Name of a file to test * @return File is readable and exists */ inline bool read_access_test (const std::string& name) { return (access (name.c_str(), R_OK) == 0); } /** Format an integer to include commas * @param data Number to format * @return String with formatted number containing commas */ template <typename T> inline std::string AddCommas(T data) { std::stringstream ss; ss << data; std::string s = ss.str(); if (s.length() > 3) for (int i = s.length()-3; i > 0; i -= 3) s.insert(i,","); return s; } /** Display the runtime (CPU and Wall) * * @param start Running timer * @return Time formatted as "CPU: XmYs Wall: XmYs" * @note Does not work on OSX or Windows (returns "not configured") */ inline std::string displayRuntime( #ifndef __APPLE__ const timespec start #endif ) { #ifndef __APPLE__ struct timespec finish; clock_gettime(CLOCK_MONOTONIC, &finish); double elapsed = (finish.tv_sec - start.tv_sec); int t = clock()/CLOCKS_PER_SEC; int min = (int)std::floor(elapsed / 60.0); int sec = (int)(elapsed-min*60); char buffer[100]; sprintf (buffer, "CPU: %4dm%02ds Wall: %4dm%02ds", (int)floor( ((double)t) /60.0), t % 60, min, sec); buffer[99] = '\0'; return std::string(buffer); #else return "--- time not configured for apple\n"; #endif } /** Reverse complement in-place sequence containg upper/lower case ACTGN * @param a Sequence to be reverse complmented */ inline void rcomplement(std::string &a) { std::reverse(&a[0], &a[a.size()]); std::string::iterator it = a.begin(); for (; it != a.end(); it++) *it = RCOMPLEMENT_TABLE[(unsigned char)*it]; } /** Calculate the percentage and return as integer * @param numer Numerator * @param denom Denominator * @return Integer with the percentage floored */ template <typename T> inline int percentCalc(T numer, T denom) { if (denom <= 0) return 0; int perc = numer * 100 / denom; //int perc = static_cast<int>(floor((float)numer / (float)denom * 100.0)); return perc; } /** Remove substrings from a string * @param toscrub Input string to clean * @param toremove Substring to remove from input * @return Scrubbed string */ inline std::string scrubString(const std::string& toscrub, const std::string& toremove) { if (toscrub.empty() || toremove.empty()) return toscrub; std::string::size_type i = toscrub.find(toremove); if (i == std::string::npos) return toscrub; std::string ts = toscrub; while (i != std::string::npos) { ts.erase(i, toremove.length()); i = ts.find(toremove); } return ts; } // Generate a weighed random integer // @param cs Weighting for each integer (values must sum to one) // @return Random integer bounded on [0,cs.size()) // //int weightedRandom(const std::vector<double>& cs); } #endif