From a0c254a2bfc9a6e0da982025849a01b1890bb58f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20J=C3=BCrges?= <jurges@astron.nl>
Date: Mon, 4 Feb 2019 10:58:41 +0000
Subject: [PATCH] SW-561:  Change central freq container to std::map

This should avoid the awkward handling.  The map makes sure that only the
central frequencies are passed around which have been used in the observation.
---
 RTCP/Cobalt/OutputProc/src/TBB_Dipole.cc  |  9 +++------
 RTCP/Cobalt/OutputProc/src/TBB_Dipole.h   | 12 +++++-------
 RTCP/Cobalt/OutputProc/src/TBB_Station.cc | 20 +++++++++++++++++++-
 RTCP/Cobalt/OutputProc/src/TBB_Station.h  |  4 ++--
 RTCP/Cobalt/OutputProc/src/TBB_Writer.cc  | 14 ++++++++------
 RTCP/Cobalt/OutputProc/src/TBB_Writer.h   | 17 ++++++++++++-----
 6 files changed, 49 insertions(+), 27 deletions(-)

diff --git a/RTCP/Cobalt/OutputProc/src/TBB_Dipole.cc b/RTCP/Cobalt/OutputProc/src/TBB_Dipole.cc
index 1f02f903a4d..d60aee1ba64 100644
--- a/RTCP/Cobalt/OutputProc/src/TBB_Dipole.cc
+++ b/RTCP/Cobalt/OutputProc/src/TBB_Dipole.cc
@@ -241,7 +241,7 @@ namespace LOFAR
 
     void TBB_Dipole::init(const TBB_Header& header, const Parset& parset,
         const StationMetaData& stationMetaData,
-        const std::vector< double >& allSubbandCentralFreqs,
+        const std::map< uint32_t, double >& allSubbandCentralFreqs,
         const std::string& h5Filename, const std::size_t subBandSize,
         dal::TBB_Station& station, Mutex& h5Mutex)
     {
@@ -270,13 +270,11 @@ namespace LOFAR
                     "Observation.TBB.TBBsetting.subbandList", true)};
 
             std::ostringstream bands;
-            std::size_t index{0U};
             for(const auto subBand: subBandsToBeStored)
             {
                 subBandBookKeeping.insert(std::make_pair(subBand,
                     SubBandBookKeeping(subBand, subBandSize,
-                        allSubbandCentralFreqs.at(index))));
-                ++index;
+                        allSubbandCentralFreqs.at(subBand))));
                 bands << (boost::format("%03u, ") % subBand);
             }
             LOG_INFO_STR("TBB:  Storing the following sub-bands: "
@@ -288,7 +286,7 @@ namespace LOFAR
         {
             ScopedLock h5OutLock(h5Mutex);
             initTBB_DipoleGroupOrDataset(header, parset, stationMetaData,
-                allSubbandCentralFreqs, rawFilename, station);
+                rawFilename, station);
         }
     }
 
@@ -779,7 +777,6 @@ namespace LOFAR
 
         void TBB_Dipole::initTBB_DipoleGroupOrDataset(const TBB_Header& header,
             const Parset& parset, const StationMetaData& stationMetaData,
-            const vector< double >& /*allSubbandCentralFreqs*/,
             const string& rawFilename, dal::TBB_Station& station)
         {
             const bool transientMode{doTransient()};
diff --git a/RTCP/Cobalt/OutputProc/src/TBB_Dipole.h b/RTCP/Cobalt/OutputProc/src/TBB_Dipole.h
index 9f4a399a076..c86fb9121ba 100644
--- a/RTCP/Cobalt/OutputProc/src/TBB_Dipole.h
+++ b/RTCP/Cobalt/OutputProc/src/TBB_Dipole.h
@@ -32,7 +32,6 @@
 #include <Stream/FileStream.h>
 #include <CoInterface/Parset.h>
 #include <CoInterface/SmartPtr.h> // when switching to C++11, replace SmartPtr with unique_ptr
-#include "Parset.h"
 
 #include <dal/lofar/TBB_File.h>   // https://github.com/nextgen-astrodata/DAL
 
@@ -52,7 +51,7 @@ namespace LOFAR
       inline dal::TBB_DipoleDataset* itsDipoleDataset() { return dynamic_cast<dal::TBB_DipoleDataset*>(itsDALDipole.get()); }
       inline dal::TBB_DipoleGroup* itsDipoleGroup() { return dynamic_cast<dal::TBB_DipoleGroup*>(itsDALDipole.get()); }
 
-      std::vector<double> itsAllSubbandCentralFreqs; // size: transient mode: 0, spectral mode: RSP_NR_SUBBANDS
+      std::map< uint32_t, double > itsAllSubbandCentralFreqs; // size: transient mode: 0, spectral mode: != 0
 
       std::string itsH5Filename;
 
@@ -94,7 +93,7 @@ namespace LOFAR
       // All TBB_Dipole objects are default constructed in a vector, so have init().
       void init(const TBB_Header& header, const Parset& parset,
           const StationMetaData& stationMetaData,
-          const std::vector< double >& allSubbandCentralFreqs,
+          const std::map< uint32_t, double >& allSubbandCentralFreqs,
           const std::string& h5Filename,
           const std::size_t subbandDataSizeInBytes, dal::TBB_Station& station,
           Mutex& h5Mutex);
@@ -110,10 +109,9 @@ namespace LOFAR
         void appendFlags(DumpInfo& di, size_t offset, size_t len);
 
       // initTBB_DipoleGroupOrDataset() must be called with the global h5Mutex held.
-      void initTBB_DipoleGroupOrDataset(const TBB_Header& header, const Parset& parset,
-                                        const StationMetaData& stationMetaData,
-                                        const std::vector<double>& allSubbandCentralFreqs,
-                                        const std::string& rawFilename, dal::TBB_Station& station);
+            void initTBB_DipoleGroupOrDataset(const TBB_Header& header,
+                const Parset& parset, const StationMetaData& stationMetaData,
+                const std::string& rawFilename, dal::TBB_Station& station);
 
         bool crc32tbb(const TBB_Payload* payload, size_t nTrSamples);
 
diff --git a/RTCP/Cobalt/OutputProc/src/TBB_Station.cc b/RTCP/Cobalt/OutputProc/src/TBB_Station.cc
index 8854d6f7a26..0663af9a47f 100644
--- a/RTCP/Cobalt/OutputProc/src/TBB_Station.cc
+++ b/RTCP/Cobalt/OutputProc/src/TBB_Station.cc
@@ -31,6 +31,9 @@
 #include <Common/LofarConstants.h>
 #include "CommonLofarAttributes.h"
 
+#include <sstream>
+
+
 namespace LOFAR
 {
   namespace Cobalt
@@ -39,7 +42,7 @@ namespace LOFAR
     using namespace std;
 
     TBB_Station::TBB_Station(const string& stationName, Mutex& h5Mutex, const Parset& parset,
-                             const vector<double>& allSubbandCentralFreqs,
+                             const std::map < uint32_t, double >& allSubbandCentralFreqs,
                              const StationMetaData& stationMetaData, const string& h5Filename,
                              const std::size_t _subbandSize)
       : itsH5File(dal::TBB_File(h5Filename, dal::TBB_File::CREATE)),
@@ -54,6 +57,21 @@ namespace LOFAR
     {
       LOG_INFO_STR("TBB: Created HDF5 file " << LOFAR::basename(h5Filename));
 
+      // Debug CentralFreqs
+      std::ostringstream s;
+      for(const auto& freq: allSubbandCentralFreqs)
+      {
+          s << "f["
+              << freq.first
+              << "] = "
+              << freq.second
+              << "Hz, ";
+      }
+      LOG_INFO_STR("*** TBB: size of central freqs input = "
+          << allSubbandCentralFreqs.size()
+          << ", values = "
+          << s.str());
+
       writeCommonLofarAttributes(itsH5File, parset);
       initTBB_RootAttributesAndGroups(stationName);
     }
diff --git a/RTCP/Cobalt/OutputProc/src/TBB_Station.h b/RTCP/Cobalt/OutputProc/src/TBB_Station.h
index 7aa19d3a43b..107239e6558 100644
--- a/RTCP/Cobalt/OutputProc/src/TBB_Station.h
+++ b/RTCP/Cobalt/OutputProc/src/TBB_Station.h
@@ -36,7 +36,7 @@ namespace LOFAR
       dal::TBB_Station itsStation;
       std::vector<TBB_Dipole> itsDipoles;
       const Parset& itsParset;
-      const std::vector<double>& itsAllSubbandCentralFreqs; // size: transient mode: 0, spectral mode: RSP_NR_SUBBANDS
+      const std::map< uint32_t, double >& itsAllSubbandCentralFreqs; // size: transient mode: 0, spectral mode: != 0
       const StationMetaData& itsStationMetaData;
       const std::string itsH5Filename;
       const std::size_t subbandSize;
@@ -51,7 +51,7 @@ namespace LOFAR
       // The caller must still unlock after the return, the constructor does not use the passed ref to unlock.
             TBB_Station(const std::string& stationName, Mutex& h5Mutex,
                 const Parset& parset,
-                const std::vector< double >& allSubbandCentralFreqs,
+                const std::map< uint32_t, double >& allSubbandCentralFreqs,
                 const StationMetaData& stationMetaData,
                 const std::string& h5Filename,
                 const std::size_t subbandSize);
diff --git a/RTCP/Cobalt/OutputProc/src/TBB_Writer.cc b/RTCP/Cobalt/OutputProc/src/TBB_Writer.cc
index 1e96894b555..f8cb2998c1c 100644
--- a/RTCP/Cobalt/OutputProc/src/TBB_Writer.cc
+++ b/RTCP/Cobalt/OutputProc/src/TBB_Writer.cc
@@ -22,6 +22,7 @@
 
 #include "TBB_Writer.h"
 
+#include <map>
 #include <cmath>
 #include <cerrno>
 #include <sys/types.h>
@@ -65,9 +66,9 @@ namespace LOFAR
       }
     }
 
-    vector<double> TBB_Writer::createAllSubbandCentralFreqs(const Parset& parset) const
+    std::map< uint32_t, double > TBB_Writer::createAllSubbandCentralFreqs(const Parset& parset) const
     {
-      vector<double> centralFreqs;
+      std::map< uint32_t, double > centralFreqs;
 
       int operatingMode = parset.getInt("Observation.TBB.TBBsetting.operatingMode", 0);
       if (operatingMode == TBB_SPECTRAL_MODE) {
@@ -87,9 +88,10 @@ namespace LOFAR
 
         unsigned nyquistZone = parset.settings.nyquistZone();
         unsigned sampleFreq = parset.settings.clockMHz;
-        centralFreqs.resize(RSP_NR_SUBBANDS);
-        for (unsigned i = 0; i < tbbSubbandList.size(); ++i) {
-          centralFreqs[tbbSubbandList[i]] = subbandCentralFreq(tbbSubbandList[i], nyquistZone, sampleFreq);
+        for(const auto subBandNumber: tbbSubbandList)
+        {
+            centralFreqs.insert(std::make_pair(subBandNumber,
+                subbandCentralFreq(subBandNumber, nyquistZone, sampleFreq)));
         }
       } else if (operatingMode != TBB_TRANSIENT_MODE) {
         throw APSException("TBB: invalid Observation.TBB.TBBsetting.operatingMode");
@@ -217,7 +219,7 @@ namespace LOFAR
       return itsParset.settings.clockMHz;
     }
 
-    const vector<double>& TBB_Writer::getAllSubbandCentralFreqs() const
+    const std::map< uint32_t, double>& TBB_Writer::getAllSubbandCentralFreqs() const
     {
       return itsAllSubbandCentralFreqs;
     }
diff --git a/RTCP/Cobalt/OutputProc/src/TBB_Writer.h b/RTCP/Cobalt/OutputProc/src/TBB_Writer.h
index cf17173133b..34adf441ad7 100644
--- a/RTCP/Cobalt/OutputProc/src/TBB_Writer.h
+++ b/RTCP/Cobalt/OutputProc/src/TBB_Writer.h
@@ -24,6 +24,8 @@
 #include "TBB_Station.h"
 #include "TBB_StreamWriter.h"
 
+#include <map>
+
 namespace LOFAR
 {
   namespace Cobalt
@@ -40,7 +42,7 @@ namespace LOFAR
       Mutex itsStationsMutex;
 
       const Parset& itsParset;
-      const std::vector<double> itsAllSubbandCentralFreqs; // size: transient mode: 0, spectral mode: RSP_NR_SUBBANDS
+      const std::map< uint32_t, double > itsAllSubbandCentralFreqs; // size: transient mode: 0, spectral mode: != 0
       const StationMetaDataMap& itsStationMetaDataMap;
       StationMetaData itsUnknownStationMetaData; // referred to for data from unknown stations (fallback)
       const std::string& itsOutDir;
@@ -71,12 +73,17 @@ namespace LOFAR
       std::string createNewTBB_H5Filename(const TBB_Header& header, const std::string& stationName);
 
       unsigned getSampleFreqMHz() const;
-      const std::vector<double>& getAllSubbandCentralFreqs() const;
+      const std::map< uint32_t, double >& getAllSubbandCentralFreqs() const;
 
     private:
-      // Returns vector of size RSP_NR_SUBBANDS for easy indexing.
-      // NOTE: only sets freqs of used subbands, others are 0.0.
-      std::vector<double> createAllSubbandCentralFreqs(const Parset& parset) const; // MHz
+      /**
+       * Returns a @std::map that contains the central frequencies of used
+       * bands only.
+       * @param parset Parset for the incoming data.
+       * @return A map that contains the central frequencies of the bands used
+       * in the observation.
+       */
+      std::map< uint32_t, double > createAllSubbandCentralFreqs(const Parset& parset) const; // MHz
       static double subbandCentralFreq(unsigned subbandNr, unsigned nyquistZone, double sampleFreq);
 
       static std::string formatFilenameTimestamp(const struct timeval& tv, const char* output_format,
-- 
GitLab