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 4 : casacore::String const nro_tablename = "NRO_ARRAY"; 307 : 308 4 : 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 4 : casacore::String tabname = table.tableName() + "/" + nro_tablename; 314 4 : casacore::SetupNewTable newtab(tabname, td, casacore::Table::Scratch); 315 4 : table.rwKeywordSet().defineTable(nro_tablename, 316 4 : casacore::Table(newtab, reader.getNROArraySize())); 317 : 318 4 : casacore::Table nro_table = table.rwKeywordSet().asTable(nro_tablename); 319 4 : casacore::ScalarColumn<int> arr(nro_table, "ARRAY"); 320 4 : casacore::ScalarColumn<int> bea(nro_table, "BEAM"); 321 4 : casacore::ScalarColumn<int> pol(nro_table, "POLARIZATION"); 322 4 : 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_ */