Integrator::Integrator(std::shared_ptr<Signal> signal, QObject* parent) :
QObject(parent),
+ m_peakCount(0),
m_signal(signal)
{}
-void Integrator::addPeak(std::shared_ptr<IntegratedPeak> peak)
+void Integrator::addPeak(IntegratedPeakCSPtr peak)
{
- emit addingPeak(m_peaksList.count());
- m_peaksList.append(peak);
+ emit addingPeak(m_peakCount);
+ addPeakToMap(peak);
emit peakAdded();
}
-std::shared_ptr<const IntegratedPeak> Integrator::deletePeak(size_t idx)
+Integrator::IntegratedPeakCSPtr Integrator::deletePeak(size_t idx)
{
- size_t ctr = 0;
- std::shared_ptr<IntegratedPeak> peak;
-
- m_peaksList.setToFirst();
- while ((peak = m_peaksList.getCurrent()) != nullptr) {
- if (peak->fromIdx() <= idx && peak->toIdx() >= idx) { /* Peak is surrounding the cursor */
- qDebug() << "Deleting peak ctr" << ctr << "auc" << peak->auc();
- std::shared_ptr<IntegratedPeak> copyPeak = peak;
- emit deletingPeak(ctr);
- m_peaksList.removeCurrent();
- emit peakRemoved();
- return copyPeak;
+ PeakMap::iterator mit = m_peakMap.begin();
+
+ for (; mit != m_peakMap.end(); mit++) {
+ PeakList& list = mit->second;
+ PeakList::iterator lit = list.begin();
+ IntegratedPeakCSPtr peak = nullptr;
+
+ for (; lit != list.end(); lit++) {
+ /* Peak is surrounding the selection */
+ if ((*lit)->fromIdx() <= idx && (*lit)->toIdx() >= idx) {
+ peak = *lit;
+ list.erase(lit);
+ break;
+ }
+ }
+ /* We have a peak */
+ if (peak != nullptr) {
+ qDebug() << "Deleting peak" << idx << "area" << peak->auc();
+ if (list.empty())
+ m_peakMap.erase(mit);
+ m_peakCount--;
+ return peak;
}
- m_peaksList.next();
-
- qDebug() << "Going through peaks to delete, ctr " << ctr << "peak auc" << peak->auc();
- ctr++;
}
+ /* No peak matches the selection */
return nullptr;
}
-std::vector<std::shared_ptr<const IntegratedPeak>> Integrator::allPeaks()
+Integrator::PeakList Integrator::allPeaks()
{
- std::shared_ptr<const IntegratedPeak> peak;
- std::vector<std::shared_ptr<const IntegratedPeak>> allPeaks;
+ PeakList allPeaks;
- m_peaksList.setToFirst();
- while ((peak = m_peaksList.getCurrent()) != nullptr) {
- allPeaks.push_back(peak);
- m_peaksList.next();
+ for (const PeakMapPair& lp : m_peakMap) {
+ for (IntegratedPeakCSPtr peak : lp.second)
+ allPeaks.push_back(peak);
}
return allPeaks;
}
-Integrator::ReturnCode Integrator::integrate(size_t startIdx, size_t stopIdx, double startY, double stopY, std::shared_ptr<IntegratedPeak>& peak,
+Integrator::ReturnCode Integrator::integrate(size_t startIdx, size_t stopIdx, double startY, double stopY, IntegratedPeakSPtr& peak,
double relBlSlope, double relBlQ)
{
size_t peakValueIdx;
peak = std::shared_ptr<IntegratedPeak>(new IntegratedPeak(peakType, auc, peakValueIdx, m_signal->timeAt(peakValueIdx), m_signal->valueAt(peakValueIdx),
startIntersIdx, stopIntersIdx, m_signal->timeAt(startIntersIdx), m_signal->timeAt(stopIntersIdx),
startYVal, stopYVal, relBlSlope, relBlQ));
- emit addingPeak(m_peaksList.count());
- m_peaksList.append(peak);
+ emit addingPeak(m_peakCount);
+ addPeakToMap(peak);
emit peakAdded();
- qDebug() << "Peak added, count" << m_peaksList.count();
+ qDebug() << "Peak added, count" << m_peakCount;
return ReturnCode::SUCCESS;
}
-std::shared_ptr<const IntegratedPeak> Integrator::peakByListIdx(const size_t idx)
+Integrator::IntegratedPeakCSPtr Integrator::peakByLinearIdx(const size_t idx)
{
- if (m_peaksList.count() == 0)
- return nullptr;
- if (idx >= m_peaksList.count())
- return nullptr;
-
- m_peaksList.setToFirst();
-
- /*while (ctr++ != idx && (peak = m_peaksList.getCurrent()) != nullptr) {
- peak = m_peaksList.getCurrent();
- m_peaksList.next();
- }*/
- for (size_t i = 0; i < idx; i++)
- m_peaksList.next();
+ size_t total = 0;
- return m_peaksList.getCurrent();
-}
-
-/* Linked list methods */
-Integrator::PeaksLinkedList::PeaksLinkedList() :
- first(nullptr),
- current(nullptr),
- last(nullptr),
- ctr(0)
-{}
+ for (const PeakMapPair& lp : m_peakMap) {
+ PeakList l = lp.second;
-void Integrator::PeaksLinkedList::append(std::shared_ptr<IntegratedPeak> peak)
-{
- ListItem* item = new ListItem(peak);
-
- if (first == nullptr) {
- first = item;
- item->prev = nullptr;
- } else {
- last->next = item;
- item->prev = last;
+ size_t ridx = idx - total;
+ if (l.size() > ridx)
+ return l.at(ridx);
+ total += l.size();
}
- last = item;
- ctr++;
-}
-
-std::shared_ptr<IntegratedPeak> Integrator::PeaksLinkedList::getCurrent()
-{
- if (current == nullptr)
- return nullptr;
-
- return current->m_peak;
-}
-
-std::shared_ptr<IntegratedPeak> Integrator::PeaksLinkedList::getFirst()
-{
- if (first == nullptr)
- return nullptr;
-
- return first->m_peak;
+ return nullptr;
}
-void Integrator::PeaksLinkedList::removeCurrent()
+/** Private functions **/
+void Integrator::addPeakToMap(IntegratedPeakCSPtr peak)
{
- ListItem* deleteMe;
-
- if (current == nullptr)
- return;
-
- if (ctr == 1) {
- first = nullptr;
- last = nullptr;
- } else if (current == first) {
- first = first->next;
- if (first != nullptr)
- first->prev = nullptr;
- } else if (current == last) {
- last = current->prev;
- last->next = nullptr;
- } else {
- ListItem* prev = current->prev;
- prev->next = current->next;
- }
+ const size_t idx = peak->peakIdx();
+ PeakMap::iterator it = m_peakMap.find(idx);
- deleteMe = current;
- current = current->next;
- ctr--;
- delete deleteMe;
-}
+ if (it == m_peakMap.end()) {
+ PeakList list;
+ list.push_back(peak);
+ m_peakMap.insert(std::pair<size_t, PeakList>(idx, list));
+ } else
+ it->second.push_back(peak);
-void Integrator::PeaksLinkedList::next()
-{
- if (current == nullptr)
- current = first;
- else
- current = current->next;
+ m_peakCount++;
}
-void Integrator::PeaksLinkedList::setToFirst()
-{
- current = first;
-}
{
Q_OBJECT
public:
+ typedef std::shared_ptr<IntegratedPeak> IntegratedPeakSPtr;
+ typedef std::shared_ptr<const IntegratedPeak> IntegratedPeakCSPtr;
+ typedef std::vector<IntegratedPeakCSPtr> PeakList;
+ typedef std::map<size_t, PeakList> PeakMap;
+ typedef std::pair<size_t, PeakList> PeakMapPair;
enum class ReturnCode {
SUCCESS,
E_NO_FIRST_INTERSECT,
};
explicit Integrator(std::shared_ptr<Signal> signal, QObject* parent = nullptr);
- void addPeak(std::shared_ptr<IntegratedPeak> peak);
- std::shared_ptr<const IntegratedPeak> deletePeak(size_t idx);
- std::vector<std::shared_ptr<const IntegratedPeak>> allPeaks();
+ void addPeak(IntegratedPeakCSPtr peak);
+ PeakList allPeaks();
+ IntegratedPeakCSPtr deletePeak(size_t idx);
ReturnCode integrate(size_t startIdx, size_t stopIdx, double startY, double stopY, std::shared_ptr<IntegratedPeak>& peak,
double relBlSlope, double relBlQ);
- std::shared_ptr<const IntegratedPeak> peakByListIdx(const size_t idx);
+ IntegratedPeakCSPtr peakByLinearIdx(const size_t idx);
//std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator peaksCBegin() const { return m_peaks.cbegin(); }
//std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator peaksCEnd() const { return m_peaks.cend(); }
- size_t peakCount() const { return m_peaksList.count(); }
+ size_t peakCount() const { return m_peakCount; }
private:
- struct ListItem {
- ListItem(std::shared_ptr<IntegratedPeak> peak) : m_peak(peak), next(nullptr) {}
- std::shared_ptr<IntegratedPeak> m_peak;
- ListItem* prev;
- ListItem* next;
- };
- class PeaksLinkedList {
- public:
- explicit PeaksLinkedList();
- void append(std::shared_ptr<IntegratedPeak> peak);
- size_t count() const { return ctr; }
- std::shared_ptr<IntegratedPeak> getCurrent();
- std::shared_ptr<IntegratedPeak> getFirst();
- void next();
- void removeCurrent();
- void setToFirst();
- private:
- ListItem* first;
- ListItem* current;
- ListItem* last;
- size_t ctr;
- };
+ void addPeakToMap(IntegratedPeakCSPtr peak);
- PeaksLinkedList m_peaksList;
+ size_t m_peakCount;
+ PeakMap m_peakMap;
std::shared_ptr<Signal> m_signal;
static const QString ME_SENDER_STR;