//# VisChunkAverager.h: class to time average all columns of a VisBuffer //# Copyright (C) 2010 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA #ifndef MSVIS_VISCHUNKAVERAGER_H #define MSVIS_VISCHUNKAVERAGER_H #include <casacore/casa/aips.h> #include <msvis/MSVis/CalVisBuffer.h> #include <map> #include <vector> namespace casa { //# NAMESPACE CASA - BEGIN class CalVisBuffer; class VisBuffer; // <summary> // A class to time average all columns of a VisBuffer. // </summary> // // <use visibility=export> // // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> // </reviewed> // <prerequisite> // <li> VisBuffer // </prerequisite> // // <etymology> // From "VisBuffer", "Chunk", and "averaging". "Chunk" comes from // VisibilityIterator. // </etymology> // // <synopsis> // This class time averages complete rows of a VisBuffer. // </synopsis> // // <example> // See SubMS::doTimeAver(). // </example> // // <motivation> // VisBuffAccumulator also time averages VisBuffers, but only for a few // columns, as needed by calibration and plotms. casacore::Time averaging in split // requires (in principle) that all of the columns in the input casacore::MS be written // to the output MS. This is more work than required by calibration and // plotms, and split also has some differences in the details of the averaging. // </motivation> // // <note> // For many of the columns averaging is trivial, i.e. the VisBuffer should only // contain one ARRAY_ID, FIELD_ID, and DATA_DESC_ID, so they will all only have // one value each. // // TIME and INTERVAL will also be univalued in the output, for a different // reason. For most (all?) uses this is a feature. (See CAS-2422 + 2439 for // why.) // </note> // // <todo asof="2010/11/12"> // <li> averaging over other indices. // </todo> typedef std::map<casacore::uInt, std::vector<casacore::Int> > mapuIvIType; class VisChunkAverager //: public VisBuffAccumulator { public: // Construct from which *DATA column(s) to read and whether or not to use // WEIGHT_SPECTRUM. VisChunkAverager(const casacore::Vector<casacore::MS::PredefinedColumns>& dataCols, const casacore::Bool doSpWeight, const casacore::Vector<casacore::Matrix<casacore::Int> >& chBounds=casacore::Vector<casacore::Matrix<casacore::Int> >()); // Null destructor ~VisChunkAverager(); // Reset the averager void reset(); // casacore::Time average vi's current chunk, AND advance vi to the end of that chunk. // casacore::Input: // vi ROVisibilityIterator vi.setRowBlocking(0) will be // called to ensure that ++vi // advances by 1 integration at a // time. // Output from private data: // avBuf_p CalVisBuffer Output buffer for the averaged // "integration". VisBuffer& average(ROVisibilityIterator& vi); // Checks whether the interval of vi needs to be truncated in order to // prevent collisions where two rows have the same casacore::MS key (ignoring TIME) but // different SCAN_NUMBER, STATE_ID, and/or OBSERVATION_ID. ARRAY_ID is // already separated by the chunking. // // time_to_break is set to the TIME of the earliest collision, or the end of // the buffer if none are found. // static casacore::Bool check_chunk(ROVisibilityIterator& vi, casacore::Double& time_to_break, const casacore::Bool watch_obs, const casacore::Bool watch_scan, const casacore::Bool watch_state); // max(a, b) in Math.h is so overloaded, and (u)casacore::Int is so promotable, that // they're unusable together. casacore::uInt uIntMax(const casacore::uInt a, const casacore::uInt b) const { return a > b ? a : b; } private: // Prohibit null constructor, copy constructor and assignment for now VisChunkAverager(); VisChunkAverager& operator= (const VisChunkAverager&); VisChunkAverager (const VisChunkAverager&); // Initialize the next accumulation interval void initialize(VisBuffer& vb); // Normalize the accumulation (finish the average). void normalize(const casacore::Double minTime, const casacore::Double maxTime, const casacore::Double firstinterval, const casacore::Double lastinterval); // Force vb to read all the columns (modified by colEnums_p and // doSpWeight_p). // // Sets readyToHash_p to false. // void fill_vb(VisBuffer& vb); // Hash function to return a unique (within the VisBuffer) key (as defined by // the casacore::MS def'n) for an interferometer (ant1, ant2, feed1, feed2, // processor_id). Note that a VisBuffer only contains one ddid and fieldid, // and TIME is deliberately excluded this that is what will be averaged over. // // Sorting a set of the returned keys is equivalent to sorting by // (procid, ant1, ant2, feed1, feed2). // casacore::uInt hashFunction(const casacore::Int ant1, const casacore::Int ant2, const casacore::Int feed1, const casacore::Int feed2, const casacore::Int procid) const; // These return their success values. (They could fail if any of ant1, ant2, // feed1, feed2, or procid are < 0, but that shouldn't happen and isn't // checked for.) casacore::Bool setupHashFunction(ROVisibilityIterator& vi); casacore::Bool makeHashMap(ROVisibilityIterator& vi); // Check whether any of the unflagged rows in vi's current chunk have the // same casacore::MS key (not counting TIME) but different values for the columns in // colsToWatch. // // time_to_break will be set to the time of the earliest collision if any are // found, or the last TIME in vi's current chunk otherwise (assumes vi's // current chunk is ascendingly sorted in TIME). // // colsToWatch should contain casacore::MS::SCAN_NUMBER, casacore::MS::STATE_ID, // casacore::MS::OBSERVATION_ID, and/or nothing. Otherwise an casacore::AipsError will be // thrown. casacore::MS::ARRAY_ID is already separated by the chunking. // casacore::Bool findCollision(ROVisibilityIterator& vi, casacore::Double& time_to_break, const casacore::Bool watchObs, const casacore::Bool watchScan, const casacore::Bool watchState); // Helper function for findCollision(). casacore::Bool checkForBreak(casacore::Vector<casacore::Int>& firstVals, const casacore::Int i, const casacore::uInt slotnum, const casacore::uInt chunkletNum, const std::vector<casacore::Int>& inrows_for_slot) const; // Start of initialization list. // Which of DATA, MODEL_DATA, and/or CORRECTED_DATA to use. casacore::Vector<casacore::MS::PredefinedColumns> colEnums_p; // Use WEIGHT_SPECTRUM? casacore::Bool doSpWeight_p; // Used for both selecting and averaging channels. casacore::Vector<casacore::Matrix<casacore::Int> > chanAveBounds_p; // End of initialization list. // Is everything setup for hashFunction()? casacore::Bool readyToHash_p; // Is sphash_to_inprows_p OK? casacore::Bool haveHashMap_p; // Maxima for hashFunction(). casacore::uInt maxant1p1_p; casacore::uInt maxant2p1_p; casacore::uInt maxfeed1p1_p; casacore::uInt maxfeed2p1_p; // casacore::uInt maxprocp1_p; Not needed // A map from a sparse hash of "baseline" to a vector of input row numbers // matching that hash. // // The hash is calculated by hashFunction(). // // The vector has an entry, in order, for each chunklet (vb) in vi's current // chunk which is either -1 (the chunklet has no row matching the hash) or // the row number _relative_ to the starting row in that chunklet's vb. // mapuIvIType sphash_to_inprows_p; // Number of correlations and channels casacore::Int nCorr_p, nChan_p; // The number of flag categories. 0 if flagCategory() is invalid. casacore::Int nCat_p; // Averaging buffer CalVisBuffer avBuf_p; }; } //# NAMESPACE CASA - END #endif