casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
VisChunkAverager.h
Go to the documentation of this file.
00001 //# VisChunkAverager.h: class to time average all columns of a VisBuffer
00002 //# Copyright (C) 2010
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 
00026 #ifndef MSVIS_VISCHUNKAVERAGER_H
00027 #define MSVIS_VISCHUNKAVERAGER_H
00028 
00029 #include <casa/aips.h>
00030 #include <synthesis/MSVis/CalVisBuffer.h>
00031 #include <map>
00032 #include <vector>
00033 
00034 namespace casa { //# NAMESPACE CASA - BEGIN
00035 
00036 class CalVisBuffer;
00037 class VisBuffer;
00038 
00039 // <summary>
00040 // A class to time average all columns of a VisBuffer.
00041 // </summary>
00042 //
00043 // <use visibility=export>
00044 //
00045 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00046 // </reviewed>
00047 
00048 // <prerequisite>
00049 //   <li> VisBuffer
00050 // </prerequisite>
00051 //
00052 // <etymology>
00053 // From "VisBuffer", "Chunk", and "averaging".  "Chunk" comes from
00054 // VisibilityIterator.
00055 // </etymology>
00056 //
00057 // <synopsis>
00058 // This class time averages complete rows of a VisBuffer.
00059 // </synopsis>
00060 //
00061 // <example>
00062 // See SubMS::doTimeAver().
00063 // </example>
00064 //
00065 // <motivation>
00066 // VisBuffAccumulator also time averages VisBuffers, but only for a few
00067 // columns, as needed by calibration and plotms.  Time averaging in split
00068 // requires (in principle) that all of the columns in the input MS be written
00069 // to the output MS.  This is more work than required by calibration and
00070 // plotms, and split also has some differences in the details of the averaging.
00071 // </motivation>
00072 //
00073 // <note>
00074 // For many of the columns averaging is trivial, i.e. the VisBuffer should only
00075 // contain one ARRAY_ID, FIELD_ID, and DATA_DESC_ID, so they will all only have
00076 // one value each.
00077 //
00078 // TIME and INTERVAL will also be univalued in the output, for a different
00079 // reason.  For most (all?) uses this is a feature.  (See CAS-2422 + 2439 for
00080 // why.)
00081 // </note>
00082 //
00083 // <todo asof="2010/11/12">
00084 //   <li> averaging over other indices.
00085 // </todo>
00086 
00087 typedef std::map<uInt, std::vector<Int> > mapuIvIType;
00088 
00089 class VisChunkAverager //: public VisBuffAccumulator
00090 {
00091 public:
00092   // Construct from which *DATA column(s) to read and whether or not to use
00093   // WEIGHT_SPECTRUM.
00094   VisChunkAverager(const Vector<MS::PredefinedColumns>& dataCols,
00095                    const Bool doSpWeight,
00096                    const Vector<Matrix<Int> >& chBounds=Vector<Matrix<Int> >());
00097 
00098   // Null destructor
00099   ~VisChunkAverager();
00100 
00101   // Reset the averager
00102   void reset();
00103 
00104   // Time average vi's current chunk, AND advance vi to the end of that chunk.
00105   // Input:
00106   //    vi              ROVisibilityIterator  vi.setRowBlocking(0) will be
00107   //                                          called to ensure that ++vi
00108   //                                          advances by 1 integration at a
00109   //                                          time.
00110   // Output from private data:
00111   //    avBuf_p         CalVisBuffer          Output buffer for the averaged 
00112   //                                          "integration".
00113   VisBuffer& average(ROVisibilityIterator& vi);
00114 
00115   // Checks whether the interval of vi needs to be truncated in order to
00116   // prevent collisions where two rows have the same MS key (ignoring TIME) but
00117   // different SCAN_NUMBER, STATE_ID, and/or OBSERVATION_ID.  ARRAY_ID is
00118   // already separated by the chunking.
00119   //
00120   // time_to_break is set to the TIME of the earliest collision, or the end of
00121   // the buffer if none are found.
00122   //
00123   static Bool check_chunk(ROVisibilityIterator& vi, Double& time_to_break,
00124                           const Bool watch_obs, const Bool watch_scan,
00125                           const Bool watch_state);
00126 
00127 
00128   // max(a, b) in Math.h is so overloaded, and (u)Int is so promotable, that
00129   // they're unusable together.
00130   uInt uIntMax(const uInt a, const uInt b) const { return a > b ? a : b; }
00131 
00132 private:
00133   // Prohibit null constructor, copy constructor and assignment for now
00134   VisChunkAverager();
00135   VisChunkAverager& operator= (const VisChunkAverager&);
00136   VisChunkAverager (const VisChunkAverager&);
00137 
00138   // Initialize the next accumulation interval
00139   void initialize(VisBuffer& vb);
00140 
00141   // Normalize the accumulation (finish the average).
00142   void normalize(const Double minTime, const Double maxTime,
00143                  const Double firstinterval, const Double lastinterval);
00144 
00145   // Force vb to read all the columns (modified by colEnums_p and
00146   // doSpWeight_p).
00147   //
00148   // Sets readyToHash_p to false.
00149   //
00150   void fill_vb(VisBuffer& vb);
00151 
00152   // Hash function to return a unique (within the VisBuffer) key (as defined by
00153   // the MS def'n) for an interferometer (ant1, ant2, feed1, feed2,
00154   // processor_id).  Note that a VisBuffer only contains one ddid and fieldid,
00155   // and TIME is deliberately excluded this that is what will be averaged over.
00156   //
00157   // Sorting a set of the returned keys is equivalent to sorting by
00158   // (procid, ant1, ant2, feed1, feed2).
00159   //
00160   uInt hashFunction(const Int ant1, const Int ant2,
00161                     const Int feed1, const Int feed2,
00162                     const Int procid) const;
00163 
00164   // These return their success values.  (They could fail if any of ant1, ant2,
00165   // feed1, feed2, or procid are < 0, but that shouldn't happen and isn't
00166   // checked for.)
00167   Bool setupHashFunction(ROVisibilityIterator& vi);
00168   Bool makeHashMap(ROVisibilityIterator& vi);
00169 
00170   // Check whether any of the unflagged rows in vi's current chunk have the
00171   // same MS key (not counting TIME) but different values for the columns in
00172   // colsToWatch.
00173   //
00174   // time_to_break will be set to the time of the earliest collision if any are
00175   // found, or the last TIME in vi's current chunk otherwise (assumes vi's
00176   // current chunk is ascendingly sorted in TIME).
00177   //
00178   // colsToWatch should contain MS::SCAN_NUMBER, MS::STATE_ID,
00179   // MS::OBSERVATION_ID, and/or nothing.  Otherwise an AipsError will be
00180   // thrown.  MS::ARRAY_ID is already separated by the chunking.
00181   //
00182   Bool findCollision(ROVisibilityIterator& vi, Double& time_to_break,
00183                      const Bool watchObs, const Bool watchScan,
00184                      const Bool watchState);
00185 
00186   // Helper function for findCollision().
00187   Bool checkForBreak(Vector<Int>& firstVals, const Int i, const uInt slotnum,
00188                      const uInt chunkletNum,
00189                      const std::vector<Int>& inrows_for_slot) const;
00190 
00191   // Start of initialization list.
00192   // Which of DATA, MODEL_DATA, and/or CORRECTED_DATA to use.
00193   Vector<MS::PredefinedColumns> colEnums_p;
00194 
00195   // Use WEIGHT_SPECTRUM?
00196   Bool doSpWeight_p;
00197 
00198   // Used for both selecting and averaging channels.
00199   Vector<Matrix<Int> > chanAveBounds_p;
00200   // End of initialization list.
00201 
00202   // Is everything setup for hashFunction()?
00203   Bool readyToHash_p;
00204 
00205   // Is sphash_to_inprows_p OK?
00206   Bool haveHashMap_p;
00207 
00208   // Maxima for hashFunction().
00209   uInt maxant1p1_p;
00210   uInt maxant2p1_p;
00211   uInt maxfeed1p1_p;
00212   uInt maxfeed2p1_p;
00213   // uInt maxprocp1_p; Not needed
00214 
00215   // A map from a sparse hash of "baseline" to a vector of input row numbers
00216   // matching that hash.
00217   //
00218   // The hash is calculated by hashFunction().
00219   //
00220   // The vector has an entry, in order, for each chunklet (vb) in vi's current
00221   // chunk which is either -1 (the chunklet has no row matching the hash) or
00222   // the row number _relative_ to the starting row in that chunklet's vb.
00223   //
00224   mapuIvIType sphash_to_inprows_p;
00225 
00226   // Number of correlations and channels
00227   Int nCorr_p, nChan_p;
00228 
00229   // The number of flag categories.  0 if flagCategory() is invalid.
00230   Int nCat_p;
00231 
00232   // Averaging buffer
00233   CalVisBuffer avBuf_p;
00234 };
00235 
00236 
00237 } //# NAMESPACE CASA - END
00238 
00239 #endif
00240 
00241