Rewrite integrator's peak storage to std::map of std::vectors containing
authorMichal Malý <madcatxster@devoid-pointer.net>
Wed, 2 Jul 2014 17:12:58 +0000 (19:12 +0200)
committerMichal Malý <madcatxster@devoid-pointer.net>
Wed, 2 Jul 2014 17:12:58 +0000 (19:12 +0200)
peaks with the same peakIdx

integrationtablemodel.cpp
integrator.cpp
integrator.h

index de3cccea580e608c2982a2911e882532a7b12fec..f7166a93d901a46e71b51833469d2f188b152240 100644 (file)
@@ -38,7 +38,7 @@ QVariant IntegrationTableModel::data(const QModelIndex& index, int role) const
   if (index.row() >= m_integrator->peakCount())
     return QVariant();
 
-  std::shared_ptr<const IntegratedPeak> peak = m_integrator->peakByListIdx(index.row());
+  Integrator::IntegratedPeakCSPtr peak = m_integrator->peakByLinearIdx(index.row());
   if (peak == nullptr) {
     Logger::log(Logger::Level::CRITICAL, ME_SENDER_STR, "Null pointer to peak");
     return QVariant();
index 41b1d275d6d2011a8db80f6aeba78eab690680d8..98b775ffc00fb55ac411193f704743e877a535f3 100644 (file)
@@ -29,55 +29,61 @@ const QString Integrator::ME_SENDER_STR("Integrator");
 
 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;
@@ -183,109 +189,42 @@ Integrator::ReturnCode Integrator::integrate(size_t startIdx, size_t stopIdx, do
   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;
-}
index 2dce9acd77f5d18b3ffbe5eec7967cf7180cfdaf..b5248d58dff1bb08978d3c1d11f21f615e444b7c 100644 (file)
@@ -34,6 +34,11 @@ class Integrator : public QObject
 {
   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,
@@ -43,41 +48,21 @@ public:
   };
 
   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;