LCOV - code coverage report
Current view: top level - singledishfiller/Filler - NRO2MSReader.h (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 119 127 93.7 %
Date: 2024-12-11 20:54:31 Functions: 41 41 100.0 %

          Line data    Source code
       1             : /*
       2             :  * NROReader.h
       3             :  *
       4             :  *  Created on: May 9, 2016
       5             :  *      Author: wataru kawasaki
       6             :  */
       7             : 
       8             : #ifndef SINGLEDISH_FILLER_NRO2MSREADER_H_
       9             : #define SINGLEDISH_FILLER_NRO2MSREADER_H_
      10             : 
      11             : #define STRING2CHAR(s) const_cast<char *>((s).c_str())
      12             : 
      13             : #include <casacore/measures/Measures/Stokes.h>
      14             : #include <casacore/tables/Tables/Table.h>
      15             : #include <casacore/tables/Tables/ScaColDesc.h>
      16             : #include <casacore/tables/Tables/SetupNewTab.h>
      17             : 
      18             : #include <singledishfiller/Filler/ReaderInterface.h>
      19             : #include <singledishfiller/Filler/NROData.h>
      20             : #include <string>
      21             : #include <memory>
      22             : #include <functional>
      23             : 
      24             : using namespace std;
      25             : 
      26             : namespace casa { //# NAMESPACE CASA - BEGIN
      27             : 
      28             : // forward declaration
      29             : class NROOptionalTables;
      30             : 
      31             : class NRO2MSReader final : public ReaderInterface {
      32             : public:
      33             :   // NROOptionalTables generates optional tables
      34             :   // required for NRO data
      35             :   using OptionalTables = NROOptionalTables;
      36             : 
      37             :   NRO2MSReader(std::string const &scantable_name);
      38             :   virtual ~NRO2MSReader();
      39             : 
      40             :   // get number of rows
      41             :   size_t getNumberOfRows() const override;
      42             : 
      43             :   casacore::MDirection::Types getDirectionFrame() const override;
      44             : 
      45           2 :   casacore::Bool isFloatData() const override {
      46           2 :     return true;
      47             :   }
      48             : 
      49           2 :   casacore::String getDataUnit() const override {
      50           2 :     return "K";
      51             :   }
      52             : 
      53             :   // to get OBSERVATION table
      54           4 :   casacore::Bool getObservationRow(sdfiller::ObservationRecord &record) override {
      55             :     POST_START;
      56           4 :     casacore::Bool return_value = get_observation_row_(record);
      57             :     POST_END;
      58           4 :     return return_value;
      59             :   }
      60             : 
      61             :   // to get ANTENNA table
      62          10 :   casacore::Bool getAntennaRow(sdfiller::AntennaRecord &record) override {
      63             :     POST_START;
      64          10 :     casacore::Bool return_value = get_antenna_row_(record);
      65             :     POST_END;
      66          10 :     return return_value;
      67             :   }
      68             : 
      69             :   // to get PROCESSOR table
      70           4 :   casacore::Bool getProcessorRow(sdfiller::ProcessorRecord &record) override {
      71             :     POST_START;
      72           4 :     casacore::Bool return_value = get_processor_row_(record);
      73             :     POST_END;
      74           4 :     return return_value;
      75             :   }
      76             : 
      77             :   // to get SOURCE table
      78           6 :   casacore::Bool getSourceRow(sdfiller::SourceRecord &record) override {
      79             :     POST_START;
      80           6 :     casacore::Bool return_value = get_source_row_(record);
      81             :     POST_END;
      82           6 :     return return_value;
      83             :   }
      84             : 
      85             :   // to get FIELD table
      86           4 :   casacore::Bool getFieldRow(sdfiller::FieldRecord &record) override {
      87             :     POST_START;
      88           4 :     casacore::Bool return_value = get_field_row_(record);
      89             :     POST_END;
      90           4 :     return return_value;
      91             :   }
      92             : 
      93             :   // to get SOURCE table
      94           6 :   casacore::Bool getSpectralWindowRow(sdfiller::SpectralWindowRecord &record) override {
      95             :     POST_START;
      96           6 :     casacore::Bool return_value = get_spw_row_(record);
      97             :     POST_END;
      98           6 :     return return_value;
      99             :   }
     100             : 
     101             :   // for DataAccumulator
     102             :   casacore::Bool getData(size_t irow, sdfiller::DataRecord &record) override;
     103             : 
     104             : protected:
     105             :   void initializeSpecific() override;
     106             :   void finalizeSpecific() override;
     107             : 
     108             : private:
     109             :   FILE *fp_;
     110             :   sdfiller::NRODataObsHeader obs_header_;
     111             :   void readObsHeader();
     112             :   void readScanData(int const irow, sdfiller::NRODataScanData &data);
     113             :   void checkEndian();
     114             :   template<typename T>
     115     1036116 :   void convertEndian(T &value) {
     116     1036116 :     char volatile *first = reinterpret_cast<char volatile *>(&value) ;
     117     1036116 :     char volatile *last = first + sizeof(T) ;
     118     1036116 :     std::reverse(first, last) ;
     119     1036116 :   }
     120             : 
     121             :   bool same_endian_;
     122             : 
     123             :   template<typename T>
     124     1036116 :   void readHeader(T &v) {
     125     1036116 :     if ((int)fread(&v, 1, sizeof(T), fp_) != sizeof(T)) {
     126           0 :       cout << "read failed." << endl;
     127             :     }
     128     1036116 :     if (!same_endian_) {
     129     1036116 :       convertEndian(v);
     130             :     }
     131     1036116 :   }
     132             : 
     133             :   template<typename T>
     134       81768 :   void readHeader(T *v, size_t numArray) {
     135      302650 :     for (size_t i = 0; i < numArray; ++i) {
     136      220882 :       readHeader<T>(v[i]);
     137             :     }
     138       81768 :   }
     139             : 
     140      190622 :   void readHeader(string &v, size_t strLength) {
     141      190622 :     v.resize(strLength);
     142      190622 :     if (fread(STRING2CHAR(v), 1, strLength, fp_) != strLength) {
     143           0 :       cout << "read failed." << endl;
     144             :     }
     145      190622 :     v.resize(strlen(v.c_str())); // remove trailing null characters
     146      190622 :   }
     147             : 
     148          12 :   void readHeader(string *v, size_t strLength, size_t numArray) {
     149         386 :     for (size_t i = 0; i < numArray; ++i) {
     150         374 :       readHeader(v[i], strLength);
     151             :     }
     152          12 :   }
     153             : 
     154             :   struct NROArrayData {
     155             :           int beam_id=-1;
     156             :           casacore::Stokes::StokesTypes stokes_type = casacore::Stokes::Undefined;
     157             :           string pol_name="";
     158             :           int spw_id=-1;
     159             :           bool is_used=false;
     160          70 :           void set(int16_t const arr_data, string const *pol_data) {
     161             :                   // indices in NOSTAR data are 1-base
     162          70 :                   if (arr_data < 1101) {
     163          38 :                     is_used = false;
     164          38 :                     beam_id = -1;
     165          38 :                     spw_id = -1;
     166          38 :                     pol_name = "";
     167          38 :                     stokes_type = casacore::Stokes::Undefined;
     168          38 :                     return;
     169             :                   }
     170          32 :                   is_used = true;
     171          32 :                   beam_id = static_cast<int>(arr_data/1000) - 1;
     172          32 :                   int pol_id = static_cast<int>((arr_data % 1000)/100) - 1;
     173          32 :                   spw_id = static_cast<int>(arr_data % 100) -1;
     174          32 :                   pol_name = pol_data[pol_id];
     175          32 :                   stokes_type = casacore::Stokes::type(pol_name);
     176          32 :                   if (stokes_type == casacore::Stokes::Undefined) {
     177           0 :                           throw casacore::AipsError("Got unsupported polarization type\n");
     178             :                   }
     179             :           }
     180       54368 :           int getBeamId() const {
     181       54368 :                   if (beam_id < 0)
     182           0 :                     throw casacore::AipsError("Array data is not set yet\n");
     183       54368 :                   return beam_id;}
     184       27200 :           casacore::Stokes::StokesTypes getPol() const {
     185       27200 :                   if (stokes_type == casacore::Stokes::Undefined)
     186           0 :                     throw casacore::AipsError("Array data is not set yet\n");
     187       27200 :                   return stokes_type;}
     188       54368 :           int getSpwId() const {
     189       54368 :                   if (spw_id < 0)
     190           0 :                     throw casacore::AipsError("Array data is not set yet\n");
     191       54368 :                   return spw_id;}
     192       27168 :           string getPolName() const {
     193       27168 :                   if (pol_name.size() == 0)
     194           0 :                     throw casacore::AipsError("Array data is not set yet\n");
     195       27168 :                   return pol_name;}
     196         140 :           bool isUsed() const {
     197         140 :             return is_used;
     198             :           }
     199             :   };
     200             : 
     201             :   std::vector<NROArrayData> array_mapper_;
     202             : 
     203             :   void constructArrayTable();
     204             :   bool checkScanArray(string const scan_array, NROArrayData const *header_array);
     205             :   // Returns the first array ID whose SPW ID is spwid.
     206           8 :   int getFirstArrayIdWithSpwID(int spwid) {
     207          12 :           for (int iarr = 0; iarr < obs_header_.ARYNM0 ; ++iarr) {
     208          12 :             if (spwid == array_mapper_[iarr].spw_id) {
     209           8 :               return iarr;
     210             :             }
     211             :           }
     212             :           // no array with spwid found
     213           0 :           throw casacore::AipsError("Internal ERROR: Could not find array ID corresponds to an SPW ID\n");
     214             :   }
     215             : 
     216             :   int beam_id_counter_;
     217             :   int source_spw_id_counter_;
     218             :   int spw_id_counter_;
     219             :   casacore::Vector<casacore::Double> time_range_sec_;
     220             :   int const len_obs_header_ = 15136;
     221             :   double getMJD(string const &time);
     222             :   double getIntMiddleTimeSec(sdfiller::NRODataScanData const &data);
     223             :   double getIntStartTimeSec(int const scanno);
     224             :   double getIntEndTimeSec(int const scanno);
     225             :   void getFullTimeRange();
     226             :   double getMiddleOfTimeRangeSec();
     227             : 
     228             :   casacore::Double const posx_ = -3.8710235e6;
     229             :   casacore::Double const posy_ =  3.4281068e6;
     230             :   casacore::Double const posz_ =  3.7240395e6;
     231             : 
     232             :   double getRestFrequency(int const spwno);
     233             :   string convertVRefName(string const &vref0);
     234             :   void shiftFrequency(string const &vdef,
     235             :                       double const v,
     236             :                       std::vector<double> &freqs);
     237             : 
     238             :   std::vector<double> getSpectrum(int const irow, sdfiller::NRODataScanData const &data);
     239             : //  casacore::Int getPolNo(string const &rx);
     240             : 
     241             :   std::function<casacore::Bool(sdfiller::AntennaRecord &)> get_antenna_row_;
     242             :   std::function<casacore::Bool(sdfiller::FieldRecord &)> get_field_row_;
     243             :   std::function<casacore::Bool(sdfiller::ObservationRecord &)> get_observation_row_;
     244             :   std::function<casacore::Bool(sdfiller::ProcessorRecord &)> get_processor_row_;
     245             :   std::function<casacore::Bool(sdfiller::SourceRecord &)> get_source_row_;
     246             :   std::function<casacore::Bool(sdfiller::SpectralWindowRecord &)> get_spw_row_;
     247             : 
     248             :   casacore::Bool getAntennaRowImpl(sdfiller::AntennaRecord &record);
     249             :   casacore::Bool getFieldRowImpl(sdfiller::FieldRecord &record);
     250             :   casacore::Bool getObservationRowImpl(sdfiller::ObservationRecord &record);
     251             :   casacore::Bool getProcessorRowImpl(sdfiller::ProcessorRecord &record);
     252             :   casacore::Bool getSourceRowImpl(sdfiller::SourceRecord &record);
     253             :   casacore::Bool getSpectralWindowRowImpl(sdfiller::SpectralWindowRecord &record);
     254             : 
     255             :   template<class _Record>
     256          12 :   casacore::Bool noMoreRowImpl(_Record &) {
     257             :     POST_START;POST_END;
     258          12 :     return false;
     259             :   }
     260             : 
     261             :   // methods that are only accessible from NROOptionalTables
     262          74 :   int getNROArraySize() const {
     263             : //    return obs_header_.ARYNM0; //obs_header_.NBEAM * obs_header_.NPOL * obs_header_.NSPWIN;
     264          74 :     return NRO_ARYMAX;
     265             :   }
     266             :   int getNRONumBeam() const {
     267             :     return obs_header_.NBEAM;
     268             :   }
     269             :   int getNRONumPol() const {
     270             :     return obs_header_.NPOL;
     271             :   }
     272             :   int getNRONumSpw() const {
     273             :     return obs_header_.NSPWIN;
     274             :   }
     275             : 
     276          70 :   bool isNROArrayUsed(int array_id) const {
     277          70 :     return array_mapper_[array_id].isUsed();
     278             :   }
     279       27200 :   int getNROArrayBeamId(int array_id) const {
     280             : //        assert(array_id >= 0 && array_id < getNROArraySize());
     281       27200 :     return array_mapper_[array_id].getBeamId();
     282             :   }
     283       27200 :   casacore::Stokes::StokesTypes getNROArrayPol(int array_id) const {
     284             : //        assert(array_id >= 0 && array_id < getNROArraySize());
     285       27200 :     return array_mapper_[array_id].getPol();
     286             :   }
     287       27200 :   int getNROArraySpwId(int array_id) const {
     288             : //        assert(array_id >= 0 && array_id < getNROArraySize());
     289       27200 :     return array_mapper_[array_id].getSpwId();
     290             :   }
     291             : 
     292             :   // friend: NROOptionalTables
     293             :   friend NROOptionalTables;
     294             : };
     295             : 
     296             : // OptionalTables class for NRO data
     297             : class NROOptionalTables {
     298             : public:
     299           2 :   static void Generate(casacore::Table &table, NRO2MSReader const &reader) {
     300             :     // generate NRO_ARRAY table
     301           2 :     Generate_NRO_ARRAY(table, reader);
     302           2 :   }
     303             : 
     304             : private:
     305           2 :   static void Generate_NRO_ARRAY(casacore::Table &table, NRO2MSReader const &reader) {
     306           2 :     casacore::String const nro_tablename = "NRO_ARRAY";
     307             : 
     308           2 :     casacore::TableDesc td(nro_tablename, casacore::TableDesc::Scratch);
     309           2 :     td.addColumn(casacore::ScalarColumnDesc<casacore::Int>("ARRAY"));
     310           2 :     td.addColumn(casacore::ScalarColumnDesc<casacore::Int>("BEAM"));
     311           2 :     td.addColumn(casacore::ScalarColumnDesc<casacore::Int>("POLARIZATION"));
     312           2 :     td.addColumn(casacore::ScalarColumnDesc<casacore::Int>("SPECTRAL_WINDOW"));
     313           2 :     casacore::String tabname = table.tableName() + "/" + nro_tablename;
     314           2 :     casacore::SetupNewTable newtab(tabname, td, casacore::Table::Scratch);
     315           4 :     table.rwKeywordSet().defineTable(nro_tablename,
     316           4 :         casacore::Table(newtab, reader.getNROArraySize()));
     317             : 
     318           2 :     casacore::Table nro_table = table.rwKeywordSet().asTable(nro_tablename);
     319           2 :     casacore::ScalarColumn<int> arr(nro_table, "ARRAY");
     320           2 :     casacore::ScalarColumn<int> bea(nro_table, "BEAM");
     321           2 :     casacore::ScalarColumn<int> pol(nro_table, "POLARIZATION");
     322           2 :     casacore::ScalarColumn<int> spw(nro_table, "SPECTRAL_WINDOW");
     323          72 :     for (int iarr = 0; iarr < reader.getNROArraySize(); ++iarr) {
     324          70 :       arr.put(iarr, iarr);
     325          70 :       if (reader.isNROArrayUsed(iarr)) {
     326          32 :         bea.put(iarr, reader.getNROArrayBeamId(iarr));
     327          32 :         pol.put(iarr, reader.getNROArrayPol(iarr));
     328          32 :         spw.put(iarr, reader.getNROArraySpwId(iarr));
     329             :       } else {
     330             :         // array is not used, fill with -1
     331          38 :         bea.put(iarr, -1);
     332          38 :         pol.put(iarr, -1);
     333          38 :         spw.put(iarr, -1);
     334             :       }
     335             :     }
     336           2 :   }
     337             : };
     338             : 
     339             : } //# NAMESPACE CASA - END
     340             : 
     341             : #endif /* SINGLEDISH_FILLER_NRO2MSREADER_H_ */

Generated by: LCOV version 1.16