casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
RFFlagCube.h
Go to the documentation of this file.
00001 
00002 //# RFFlagCube.h: this defines RFFlagCube
00003 //# Copyright (C) 2000,2001,2002
00004 //# Associated Universities, Inc. Washington DC, USA.
00005 //#
00006 //# This library is free software; you can redistribute it and/or modify it
00007 //# under the terms of the GNU Library General Public License as published by
00008 //# the Free Software Foundation; either version 2 of the License, or (at your
00009 //# option) any later version.
00010 //#
00011 //# This library is distributed in the hope that it will be useful, but WITHOUT
00012 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00014 //# License for more details.
00015 //#
00016 //# You should have received a copy of the GNU Library General Public License
00017 //# along with this library; if not, write to the Free Software Foundation,
00018 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00019 //#
00020 //# Correspondence concerning AIPS++ should be addressed as follows:
00021 //#        Internet email: aips2-request@nrao.edu.
00022 //#        Postal address: AIPS++ Project Office
00023 //#                        National Radio Astronomy Observatory
00024 //#                        520 Edgemont Road
00025 //#                        Charlottesville, VA 22903-2475 USA
00026 //#
00027 //# $Id$
00028 #ifndef FLAGGING_RFFLAGCUBE_H
00029 #define FLAGGING_RFFLAGCUBE_H
00030     
00031 //#include <flagging/Flagging/RedFlagger.h>
00032 #include <flagging/Flagging/RFCubeLattice.h>
00033 #include <flagging/Flagging/RFChunkStats.h>
00034 #include <casa/Arrays/ArrayLogical.h>
00035 #include <casa/Arrays/LogiMatrix.h>
00036 #include <casa/Arrays/LogiVector.h>
00037 #include <casa/Logging/LogIO.h>
00038 #include <boost/dynamic_bitset.hpp>
00039 #include <stdexcept>
00040 
00041 namespace casa { //# NAMESPACE CASA - BEGIN
00042 
00043 typedef RFCubeLatticeIterator<RFlagWord> FlagCubeIterator;
00044 
00045 // special row flag masks. RowFlagged for flagged rows, 
00046 // RowAbsent for absent rows
00047 const RFlagWord RowFlagged=1,RowAbsent=2;
00048 
00049 // Function for working with bitmasks. Does a bitwise-AND
00050 // on every element, returns True if !=0 or False if ==0
00051 template<class T> Array<T> operator & ( const Array<T> &,const T &);
00052 // returns a LogicalArray corresponding to (ARR&MASK)!=0
00053 template<class T> LogicalArray  maskBits  ( const Array<T> &,const T &);
00054 
00055 // <summary>
00056 // RFFlagCube: a cube of flags
00057 // </summary>
00058 
00059 // <use visibility=local>
00060 
00061 // <reviewed reviewer="" date="" tests="" demos="">
00062 // </reviewed>
00063 
00064 // <prerequisite>
00065 //   <li> RFCubeLattice
00066 // </prerequisite>
00067 //
00068 // <synopsis>
00069 // RFFlagCube implements an [NCHAN,NIFR,NTIME] cube of flags, stored in
00070 // a TempLattice that is iterated alog the TIME axis.  One static
00071 // (i.e. global) cube is used to hold the actual flags. Individual
00072 // instances (instantiated by flagging agents) have individual unique
00073 // bitmasks and, possibly, individual iterators.
00074 //
00075 // It was/is a design mistake to use a global/static buffer to hold the
00076 // shared flags. Instead, every agent should point to the unique dynamically
00077 // allocated buffer. 
00078 // </synopsis>
00079 //
00080 // <example>
00081 // </example>
00082 //
00083 // <motivation>
00084 // </motivation>
00085 //
00086 // <todo asof="2001/04/16">
00087 //   <li> add this feature
00088 //   <li> fix this bug
00089 //   <li> start discussion of this possible extension
00090 // </todo>
00091 
00092 class RFFlagCube : public FlaggerEnums
00093 {
00094 public:
00095   // default log sink
00096   static LogIO default_sink;
00097     
00098   // constructor
00099   RFFlagCube ( RFChunkStats &ch,Bool ignore=False,Bool reset=False,LogIO &os=default_sink );
00100   ~RFFlagCube ();
00101 
00102   // returns reference to logsink
00103   LogIO & logSink ();
00104 
00105   // returns estimated size of flag cube for a given chunk.
00106   static uInt estimateMemoryUse ( const RFChunkStats &ch );
00107 
00108   // creates flag cube for current chunk. name is name of agent.
00109   // nAgent is total number of agents
00110   void init ( RFlagWord polmsk, uInt nAgent, bool is_selector, const String &name = "" );
00111 
00112   // cleans up at end of chunk
00113   void cleanup ();
00114 
00115   // returns summary of stats in text form
00116   String getSummary ();
00117 
00118   // prints flagging stats to stderr
00119   void printStats ();
00120 
00121   // resets at start of pass
00122   void reset ();
00123 
00124   // advances global flag iterator to time slot it (if required), sets
00125   // the flag cursor from the iterator (see below). If getflags is true,
00126   // also calls getDataFlags().
00127   void advance   ( uInt it,Bool getFlags=False );
00128 
00129   // fills global flag lattice with apriori flags from a VisBuffer (if required)
00130   void getMSFlags  (uInt it);
00131 
00132   // transfers all flags from lattice into VisBuffer
00133   void setMSFlags  (uInt itime);
00134 
00135   // creates a custom iterator
00136   FlagCubeIterator newCustomIter ();
00137 
00138   // Returns full flag matrix (i.e. cursor of global iterator)
00139   const FlagMatrix & flagMatrix ();
00140   
00141   // sets or clears a flag at the given flag cursor
00142   Bool setFlag      ( uInt ich,uInt ifr,FlagCubeIterator &iter );
00143   Bool clearFlag    ( uInt ich,uInt ifr,FlagCubeIterator &iter );
00144 
00145   // Gets full flag word at the given flag cursor.
00146   RFlagWord getFlag ( uInt ich,uInt ifr,FlagCubeIterator &iter );
00147 
00148   // Versions of above that use global flag cursor
00149   Bool setFlag      ( uInt ich,uInt ifr );
00150   Bool clearFlag    ( uInt ich,uInt ifr );
00151   RFlagWord getFlag ( uInt ich,uInt ifr );
00152   
00153   // the preFlagged() function uses the corr-mask to tell if any of this
00154   // agent's correlations are pre-flagged. Uses internal cursor.
00155   Bool preFlagged   ( uInt ich,uInt ifr );
00156 
00157   // The anyFlagged() uses the corr-flagmask to tell if any of my
00158   // correlations are flagged either by any agent or pre-flagged
00159   // Uses internal cursor.
00160   Bool anyFlagged   ( uInt ich,uInt ifr );
00161   
00162   // Sets or clears a row flag
00163   Bool setRowFlag      ( uInt ifr,uInt itime );
00164   Bool clearRowFlag    ( uInt ifr,uInt itime );
00165 
00166   // Gets full row flag word
00167   RFlagWord getRowFlag ( uInt ifr,uInt itime );
00168   
00169   // tells if a row is pre-flagged in the MS (or does not exist)
00170   Bool rowPreFlagged   ( uInt ifr,uInt itime );  
00171 
00172   // tells if a row is flagged by any agent
00173   Bool rowAgentFlagged ( uInt ifr,uInt itime );  
00174 
00175   // preFlagged OR agentFlagged  
00176   Bool rowFlagged      ( uInt ifr,uInt itime );
00177   
00178   // returns reference to internal iterator
00179   FlagCubeIterator &  iterator ();
00180   
00181   // returns flag mask for this agent
00182   RFlagWord flagMask ();      
00183 
00184   // returns correlations mask for this agent
00185   RFlagWord corrMask ();
00186 
00187   // returns the checked-correlations mask for this agent
00188   // (=0 for RESET/IGNORE policies, or =corrMask() for HONOR policy).
00189   RFlagWord checkCorrMask ();
00190 
00191   // returns mask of all correlations
00192   static RFlagWord fullCorrMask ();
00193 
00194   // returns the number of instances of the flag cube
00195   static Int numInstances ();
00196 
00197   // sets the maximum memory usage for the flag cube  
00198   static void setMaxMem ( Int maxmem );
00199   // returns the current maximum memory usage
00200   static int  getMaxMem ();
00201       
00202  private:
00203   RFChunkStats &chunk;                  // chunk
00204 
00205   bool kiss;  // do things simpler (faster) if there is nothing but RFAselector agents
00206   bool kiss_flagrow;  // Use boost::dynamic_bitset for 'flagrow' if only RFA agents and
00207                       // more than 32 (or so) agents
00208 
00209   static Cube<Bool> in_flags;
00210   static int in_flags_time;  //time stamp that in_flags has reached
00211   static bool in_flags_flushed; // do we need to write the flags back for this time stamp?
00212 
00213   // shortcut to RFChunkStats::num
00214   uInt num ( StatEnums which ) { return chunk.num(which); }
00215       
00216   static RFCubeLattice<RFlagWord> flag; // global flag lattice
00217   static FlagMatrix flagrow;             // (nIfr,nTime) matrix of row flags
00218   static Matrix<boost::dynamic_bitset<> > flagrow_kiss;
00219   static Int pos_get_flag,pos_set_flag; 
00220 
00221   static Bool reset_preflags; // flag: RESET policy specified for at least one instance
00222   
00223   static uInt npol,nchan;
00224   
00225   // Flag mask used by this instance. Each instance has a unique 1-bit mask.
00226   // This is assigned automatically in the constructor, by updating the 
00227   // instance count and the nextmask member.
00228   // Note that the low N bits of a mask are assigned to pre-flags (one per
00229   // each correlation in the MS); so the agents start at bit N+1.
00230   RFlagWord flagmask,       // flagmask of this instance
00231     corrmask,        // corrmask of this instance (corrs used/flagged by it)
00232     check_corrmask,  // mask checked by preFlagged() & co. Set to 0 for
00233     // RESET or IGNORE policy, or to corrmask for HONOR
00234     check_rowmask,   // same for row flags: 0 or RowFlagged
00235     my_corrflagmask; // see above
00236   unsigned long flagmask_kiss; // represents a bitmask with only bit number <n> set where 
00237                           // <n> is the value of this variable
00238   static Int agent_count;    // # of agents instantiated
00239   static RFlagWord base_flagmask, // flagmask of first agent instance
00240     full_corrmask;          // bitmask for all correlations in MS (low N bits)
00241 
00242   // corr_flagmask is a mapping from corrmasks into masks of agents that flag the
00243   // given corrmask
00244   static Vector<RFlagWord> corr_flagmask;
00245   
00246   // log sink
00247   LogIO os;
00248 
00249   // pre-flag policy (can be set on a per-instance basis)
00250   PreFlagPolicy pfpolicy;
00251   
00252   // flagging stats for this instance
00253   uInt tot_fl_raised,fl_raised,fl_cleared,
00254     tot_row_fl_raised,row_fl_raised,row_fl_cleared;
00255     
00256   // local flag cursor used by this instance (setFlag and clearFlag). 
00257   // Normally, set to flag.cursor() in advance(), but can be overridden
00258   // by setFlagCursor();
00259   FlagMatrix * flag_curs;
00260   uInt flag_itime;
00261   
00262   // number of instances in use
00263   static Int num_inst;
00264 };
00265 
00266 inline RFlagWord RFFlagCube::flagMask ()
00267   { 
00268      if (kiss) {
00269        throw std::logic_error("Cannot do this in kiss mode (program bug, please report)");
00270      }
00271      return flagmask; 
00272   }
00273  
00274 inline RFlagWord RFFlagCube::corrMask ()
00275    { 
00276      return corrmask; 
00277    }
00278 
00279 inline RFlagWord RFFlagCube::checkCorrMask ()
00280    { return check_corrmask; }
00281 
00282 inline RFlagWord RFFlagCube::fullCorrMask ()
00283    { return full_corrmask; }
00284 
00285 inline RFlagWord RFFlagCube::getFlag ( uInt ich,uInt ifr,FlagCubeIterator &iter )
00286    { 
00287      if (kiss) {
00288        /* Create the bitmap (integer) from the correlation flags
00289           relevant for this agent */
00290        RFlagWord f = 0;
00291        uInt c = 1;
00292 
00293        for (uInt icorr = 0; icorr < num(CORR); icorr++, c<<=1) {
00294          if ((c & corrmask) && 
00295              in_flags(icorr, ich, ifr)) {
00296            f |= c;
00297          }
00298        }
00299        return f;
00300      }
00301      else {
00302        return (iter)(ich,ifr); 
00303      }
00304    }
00305 
00306 inline Bool RFFlagCube::setFlag ( uInt ich,uInt ifr ) 
00307    { return setFlag(ich,ifr,flag.iterator()); } 
00308 
00309 inline Bool RFFlagCube::clearFlag ( uInt ich,uInt ifr ) 
00310    { return clearFlag(ich,ifr,flag.iterator()); } 
00311 
00312 inline RFlagWord RFFlagCube::getFlag ( uInt ich,uInt ifr ) 
00313    { return getFlag(ich,ifr,flag.iterator()); } 
00314 
00315 inline FlagCubeIterator RFFlagCube::newCustomIter ()
00316    { return flag.newIter(); }
00317 
00318 inline const FlagMatrix & RFFlagCube::flagMatrix ()
00319    { return *flag_curs; }
00320 
00321 inline Bool RFFlagCube::preFlagged ( uInt ich,uInt ifr )
00322    { return getFlag(ich,ifr)&check_corrmask != 0; }    
00323 
00324 inline Bool RFFlagCube::anyFlagged ( uInt ich,uInt ifr )
00325    { 
00326      if (kiss) {
00327        throw std::logic_error("Cannot do this in kiss mode (program bug, please report)");
00328      }
00329      return getFlag(ich,ifr)&(check_corrmask|my_corrflagmask) != 0; 
00330    }
00331 
00332 // Gets full row flag word
00333 inline RFlagWord RFFlagCube::getRowFlag ( uInt ifr,uInt itime )
00334   {
00335     if (kiss) {
00336       throw std::logic_error("Cannot do this in kiss mode (program bug, please report)");
00337     }
00338     return flagrow(ifr,itime); 
00339   }
00340 
00341 // tells if a row is pre-flagged in the MS (or does not exist)
00342 inline Bool RFFlagCube::rowPreFlagged   ( uInt ifr,uInt itime )
00343    { return getRowFlag(ifr,itime)&check_rowmask; }
00344 
00345 // tells if a row is flagged by any agent
00346 inline Bool RFFlagCube::rowAgentFlagged ( uInt ifr,uInt itime )
00347    { return getRowFlag(ifr,itime)&~(RowFlagged|RowAbsent); }
00348 
00349 // preFlagged OR agentFlagged  
00350 inline Bool RFFlagCube::rowFlagged      ( uInt ifr,uInt itime )
00351    { return getRowFlag(ifr,itime)&(check_rowmask?~0:~RowFlagged); }
00352 
00353 inline FlagCubeIterator & RFFlagCube::iterator ()
00354    { return flag.iterator(); }
00355 
00356 inline int RFFlagCube::numInstances ()
00357    { return num_inst; }
00358 
00359 inline LogIO & RFFlagCube::logSink ()
00360    { return os; }
00361 
00362 
00363 } //# NAMESPACE CASA - END
00364 
00365 #ifndef AIPS_NO_TEMPLATE_SRC
00366 #include <flagging/Flagging/RFFlagCube.tcc>
00367 #endif //# AIPS_NO_TEMPLATE_SRC
00368 #endif