#ifndef EQUIVALENCE_CLASS_BUILDER_HPP #define EQUIVALENCE_CLASS_BUILDER_HPP #include #include #include #include #include #include #include "cedar/TargetGroup.hpp" struct TGValue { TGValue(const TGValue& o) { weights = o.weights; combinedWeights = o.combinedWeights; count = o.count; } TGValue(std::vector& weightIn, uint64_t countIn) : weights(weightIn.begin(), weightIn.end()) { count = countIn; } // const is a lie void normalizeAux() const { double sumOfAux{0.0}; for (size_t i = 0; i < weights.size(); ++i) { sumOfAux += weights[i]; } double norm = 1.0 / sumOfAux; for (size_t i = 0; i < weights.size(); ++i) { weights[i] *= norm; } } mutable std::vector weights; // The combined auxiliary and position weights. These // are filled in by the inference algorithm. mutable std::vector combinedWeights; uint64_t count{0}; }; class EquivalenceClassBuilder { public: EquivalenceClassBuilder()//std::shared_ptr loggerIn) //: logger_(loggerIn) { { countMap_.reserve(1000000); } //~EquivalenceClassBuilder() {} void start() { active_ = true; } bool finish() { active_ = false; size_t totalCount{0}; countVec_.reserve(countMap_.size()); //auto lt = countMap_.lock_table(); for (auto& kv : countMap_) { kv.second.normalizeAux(); totalCount += kv.second.count; countVec_.push_back(kv); } /* logger_->info("Computed {} rich equivalence classes " "for further processing", countVec_.size()); logger_->info("Counted {} total reads in the equivalence classes ", totalCount); */ return true; } inline void addGroup(TargetGroup&& g, std::vector& weights) { auto it = countMap_.find(g); if (it != countMap_.end()) { it->second.count++; for (size_t i = 0; i < it->second.weights.size(); ++i) { it->second.weights[i] += weights[i]; } } else { TGValue v(weights, 1); countMap_.insert(std::make_pair(g,v)); } } inline void mergeUnfinishedEQB(EquivalenceClassBuilder& eqb) { for (auto &kv : eqb.countMap_) { auto it = countMap_.find(kv.first); if (it != countMap_.end()) { it->second.count+=kv.second.count; for (size_t i = 0; i < it->second.weights.size(); ++i) { it->second.weights[i] += kv.second.weights[i]; } } else { countMap_.insert(std::make_pair(kv.first,kv.second)); } } } std::vector>& eqVec() { return countVec_; } std::unordered_map& eqMap() { return countMap_; } private: std::atomic active_; std::unordered_map countMap_; std::vector> countVec_; //std::shared_ptr logger_; }; #endif // EQUIVALENCE_CLASS_BUILDER_HPP /** Unordered map implementation */ // spp::sparse_hash_map // countMap_; std::mutex mapMut_; /* bool finish() { // unordered_map implementation for (auto& kv : countMap_) { kv.second.normalizeAux(); countVec_.push_back(kv); } return true; } */ /* inline void addGroup(TranscriptGroup&& g, std::vector& weights) { // unordered_map implementation std::lock_guard lock(mapMut_); auto it = countMap_.find(g); if (it == countMap_.end()) { TGValue v(weights, 1); countMap_.emplace(g, v); } else { auto& x = it->second; x.count++; for (size_t i = 0; i < x.weights.size(); ++i) { x.weights[i] = salmon::math::logAdd(x.weights[i], weights[i]); } } } */