casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
FlagAgentBase.h
Go to the documentation of this file.
00001 //# FlagAgentBase.h: This file contains the interface definition of the FlagAgentBase class.
00002 //#
00003 //#  CASA - Common Astronomy Software Applications (http://casa.nrao.edu/)
00004 //#  Copyright (C) Associated Universities, Inc. Washington DC, USA 2011, All rights reserved.
00005 //#  Copyright (C) European Southern Observatory, 2011, All rights reserved.
00006 //#
00007 //#  This library is free software; you can redistribute it and/or
00008 //#  modify it under the terms of the GNU Lesser General Public
00009 //#  License as published by the Free software Foundation; either
00010 //#  version 2.1 of the License, or (at your option) any later version.
00011 //#
00012 //#  This library is distributed in the hope that it will be useful,
00013 //#  but WITHOUT ANY WARRANTY, without even the implied warranty of
00014 //#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 //#  Lesser General Public License for more details.
00016 //#
00017 //#  You should have received a copy of the GNU Lesser General Public
00018 //#  License along with this library; if not, write to the Free Software
00019 //#  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00020 //#  MA 02111-1307  USA
00021 //# $Id: $
00022 
00023 #ifndef FlagAgentBase_H_
00024 #define FlagAgentBase_H_
00025 
00026 #include <flagging/Flagging/FlagMSHandler.h>
00027 #include <flagging/Flagging/FlagCalTableHandler.h>
00028 #include <flagging/Flagging/FlagReport.h>
00029 #include <casa/Containers/OrdMapIO.h>
00030 #include <measures/Measures/Stokes.h>
00031 #include <synthesis/MSVis/AsynchronousTools.h>
00032 
00033 namespace casa { //# NAMESPACE CASA - BEGIN
00034 
00035 // <summary>
00036 // A top level class defining the interface for flagging agents
00037 // </summary>
00038 //
00039 // <use visibility=export>
00040 //
00041 // <prerequisite>
00042 //   <li> <linkto class="VisBuffer2:description">FlagDataHandler</linkto>
00043 //   <li> <linkto class="VisBuffer2:description">FlagReport</linkto>
00044 // </prerequisite>
00045 //
00046 // <etymology>
00047 // FlagAgentBase stands for a generic class, specific to the flagging operations
00048 // </etymology>
00049 //
00050 // <synopsis>
00051 //
00052 // This is a top-level class defining the interface for flagging agents.
00053 // There are various methods (virtual) that must be re-implemented by the specific derived
00054 // classes, depending on the implemented algorithm. Here we find three categories:
00055 //
00056 // - Iteration approach methods:
00057 //
00058 //   - computeRowFlags(const VisBuffer &visBuffer, FlagMapper &flags, uInt row)
00059 //     - For agents that only depend on meta-data for their flagging operations (for FlagAgentManual,FlagAgentElevation,FlagAgentShadow,FlagAgentQuack)
00060 //     - This iteration method can also be used by agents that have to inspect the already existing flags (for FlagAgentSummary, FlagAgentExtension)
00061 //
00062 //   - computeInRowFlags(const VisBuffer &visBuffer, VisMapper &visibilities,FlagMapper &flags, uInt row);
00063 //     - For agents that have to look into the visibility points, but regardless of their source baseline, like FlagAgentDisplay
00064 //
00065 //   - computeAntennaPairFlags(const VisBuffer &visBuffer,FlagMapper &flags,Int antenna1,Int antenna2,vector<uInt> &rows);
00066 //     - For agents that have to look into the visibility points grouped by baseline (FlagAgentTimeFreqCrop,FlagAgentRFlag)
00067 //
00068 //   - computeAntennaPairFlags(const VisBuffer &visBuffer, VisMapper &visibilities,FlagMapper &flags,Int antenna1,Int antenna2,vector<uInt> &rows)
00069 //     - For agents that have to look into the visibility points grouped by baseline, allowing user-driven navigation (FlagAgentDisplay)
00070 //     - NOTE: This method has to be used in combination with iterateAntennaPairsInteractive(antennaPairMap *antennaPairMap_ptr)
00071 //
00072 // - Configuration methods:
00073 //
00074 //   - FlagAgentBase::FlagAgentBase
00075 //     - Even though each derived agent has its specific constructor, it is necessary to call the base class constructor to set:
00076 //       - The FlagDataHandler implementation pointer
00077 //       - The iteration approach: For this the FlagAgentBase class contains an enumeration FlagAgentBase::iteration with the following modes:
00078 //         - FlagAgentBase::ROWS: Iterate row by row and flag depending on the corresponding meta-data (for FlagAgentManual,FlagAgentQuack)
00079 //         - FlagAgentBase::ROWS_PREPROCESS_BUFFER: Iterate row by row doing a pre-processing common to all the rows of each chunk (for FlagAgentElevation, FlagAgentShadow, FlagAgentSummary)
00080 //         - FlagAgentBase::IN_ROWS: Iterate row by row and flag depending on the data column (for FlagAgentClipping)
00081 //         - FlagAgentBase::ANTENNA_PAIRS: Iterate per baselines and flag depending on the data column (for FlagAgentTimeFreqCrop, FlagAgentRFlag)
00082 //         - FlagAgentBase::ANTENNA_PAIRS_FLAGS: Iterate per baselines accessing the individual flag points (for  FlagAgentExtension)
00083 //         - FlagAgentBase::ANTENNA_PAIRS_INTERACTIVE: Iterate per baselines interactively accessing the data column (for FlagAgentDisplay)
00084 //
00085 //   - setAgentParameters(Record config)
00086 //     - To parse the agent-specific parameters, although there is also an implementation of
00087 //       this method in the base class which has to be called to handle the following parameters:
00088 //        - datacolumn: To specify the column in which the agent has to operate (see FlagAgentBase::datacolumn enumeration)
00089 //        - correlation: To specify the correlation to be inspected for flagging (this also includes visibility expressions)
00090 //        - meta-data selection parameters (field, spw, scan, baseline, etc): To feed the agent-level data selection engine (row filtering)
00091 //
00092 // - Information methods
00093 //
00094 //   - FlagReport getReport()
00095 //     - To return a specific report to be shown by the display agent, or containing accumulated information (e.g.: summaries, rflag tresholds)
00096 //
00097 // Additionally there are public non-virtual methods to:
00098 //
00099 // - Handle processing in 'background' mode (for parallel flagging)
00100 //   - start(): Start service (start thread run method)
00101 //   - terminate(): Terminate service (forcing run method to finish)
00102 //   - queueProcess(): To signal flagging of the current VisBuffer
00103 //   - completeProcess(): Wait until completion of flagging process for the current VisBuffer
00104 //
00105 // - Print out percentage of flags produced by chunk or in total
00106 //   - chunkSummary(): Accumulates statistics for each chunk
00107 //   - tableSummary(): Accumulates statistics across the entire table selection
00108 //
00109 // </synopsis>
00110 //
00111 // <motivation>
00112 // The motivation for the FlagAgentBase class is having all the iteration and filtering capabilities
00113 // grouped in one single class, with a common interface for all the agents w/o introducing anything
00114 // specific to the implementation of each algorithm, thus improving modularization and maintainability.
00115 // </motivation>
00116 //
00117 //
00118 // <example>
00119 // The top level interface of a flagging agent is quite simple once it is configured, this is due to
00120 // the fact that most of the complexity lies in the FlagDataHandler-FlagAgentBase interaction,
00121 // which is hidden from the application layer (already explained in the FlagDataHandler documentation).
00122 //
00123 // <srcblock>
00124 //
00125 // // Create FlagDataHandler
00126 // FlagDataHandler *dh = new FlagMSHandler(inputFile,iterationMode);
00127 //
00128 // // First of all define a configuration record (e.g.: quack)
00129 // Record agentConfig;
00130 // agentConfig.define("mode","quack");
00131 // agentConfig.define("quackinterval",(Double)20);
00132 //
00133 // // Use the factory method to create the agent, and put it into a FlagAgentList
00134 // FlagAgentList agentList;
00135 // FlagAgentBase *agent = FlagAgentBase::create(dh,agentConfig);
00136 // agentList.push_back(agent);
00137 //
00138 // // Iterate over chunks
00139 // while (dh->nextChunk())
00140 // {
00141 //    // Iterates over buffers
00142 //        while (dh->nextBuffer())
00143 //    {
00144 //       // Apply agents on current VisBuffer
00145 //       agentList.apply();
00146 //
00147 //       // Flush flags (only effective if there is a write access to the flag cube)
00148 //       dh->flushFlags();
00149 //    }
00150 //
00151 //      // Print chunk stats from each agent
00152 //      agentList.chunkSummary();
00153 // }
00154 //
00155 // // Print total stats from each agent
00156 // agentList.tableSummary();
00157 //
00158 // // Stop flag agent
00159 // agentList.terminate();
00160 //
00161 // </srcblock>
00162 // </example>
00163 
00164 
00165 class FlagAgentBase : public casa::async::Thread {
00166 
00167 public:
00168 
00169         enum datacolumn {
00170 
00171                 DATA=0,
00172                 CORRECTED,
00173                 MODEL,
00174                 RESIDUAL,
00175                 RESIDUAL_DATA,
00176                 FPARAM,
00177                 CPARAM,
00178                 PARAMERR,
00179                 SNR
00180         };
00181 
00182         enum iteration {
00183 
00184                 ROWS=0,
00185                 ROWS_PREPROCESS_BUFFER,
00186                 IN_ROWS,
00187                 IN_ROWS_PREPROCESS_BUFFER,
00188                 ANTENNA_PAIRS,
00189                 ANTENNA_PAIRS_FLAGS,
00190                 ANTENNA_PAIRS_INTERACTIVE,
00191                 ANTENNA_PAIRS_PREPROCESS_BUFFER
00192         };
00193 
00194         FlagAgentBase(FlagDataHandler *dh, Record config, uShort iterationApproach, Bool writePrivateFlagCube = false, Bool flag = true);
00195         virtual ~FlagAgentBase ();
00196         static FlagAgentBase *create (FlagDataHandler *dh,Record config);
00197 
00198         void start();
00199         void terminate ();
00200         void queueProcess();
00201         void chunkSummary();
00202         void tableSummary();
00203         void completeProcess();
00204         void * run ();
00205 
00206         // Set function to activate profiling
00207         void setProfiling(bool enable) {profiling_p = enable;}
00208 
00209         // Set function to activate check mode
00210         void setCheckMode(bool enable) {checkFlags_p = enable;}
00211 
00212         // Externally visible configuration
00213         Bool backgroundMode_p;
00214         LogIO::Command logLevel_p;
00215         Bool apply_p;
00216         Bool flag_p;
00217 
00218         // Get a report Record from the agent, at the end of the run
00219         // The report returned by getReport() can be of multiple types
00220         //   -- a single report of type "none"  : FlagReport("none",agentName_p)
00221         //   -- a single report of type "plot" : FlagReport("plot",agentName_p)
00222         //   -- a list of reports  : 
00223         //          FlagReport repList("list");
00224         //          repList.addReport( FlagReport("plot",agentName_p) );
00225         //          repList.addReport( FlagReport("plot",agentName_p) );
00226         virtual FlagReport getReport();
00227 
00228 protected:
00229 
00230         void initialize();
00231 
00232         // Convenience function to be shared by parallel/non-parallel mode
00233         void runCore();
00234 
00235         void setDataSelection(Record config);
00236         // TODO: This class must be re-implemented in the derived classes
00237         virtual void setAgentParameters(Record config);
00238         // Method to sanitize correlation expression and keep going
00239         String sanitizeCorrExpression(String corrExpression, std::vector<String> *corrProducts);
00240 
00241         void generateAllIndex();
00242         void generateRowsIndex(uInt nRows);
00243         void generateChannelIndex(uInt nChannels);
00244         void generatePolarizationIndex(uInt nPolarizations);
00245         std::vector<uInt> * generateAntennaPairRowsIndex(Int antenna1, Int antenna2);
00246 
00247         // Generate index for all rows
00248         void indigen(vector<uInt> &index, uInt size);
00249 
00250         // For checking ids
00251         bool find(Vector<Int> &validRange, Int element);
00252 
00253         // For checking ranges
00254         bool find(Matrix<Double> &validRange, Double element);
00255 
00256         // For checking pairs
00257         bool find(Matrix<Int> &validPairs, Int element1, Int element2);
00258 
00259         // For checking columns
00260         bool find(Block<int> &columns, int col);
00261 
00262         // Check if a given number is nan (for visibilities,gains and Tsys primarily)
00263         bool isNaN(Double number);
00264         bool isNaN(Float number);
00265         bool isZero(Double number);
00266         bool isZero(Float number);
00267         bool isNaNOrZero(Float number);
00268         bool isNaNOrZero(Double number);
00269 
00270         // Check if buffer has to be processed
00271         bool checkIfProcessBuffer();
00272 
00273         // Common functionality for each visBuffer (don't repeat at the row level)
00274         virtual void preProcessBuffer(const vi::VisBuffer2 &visBuffer);
00275 
00276         // Iterate trough list of rows
00277         void iterateRows();
00278 
00279         // Iterate trough visibilities mapper
00280         void iterateInRows();
00281 
00282         // Iterate trough list of antenna pairs
00283         void iterateAntennaPairs();
00284 
00285         // Iterate trough list of antenna pairs w/o loading visibilities
00286         void iterateAntennaPairsFlags();
00287 
00288         // Methods to interactively iterate trough list of antenna pairs
00289         void processAntennaPair(Int antenna1,Int antenna2);
00290         virtual void iterateAntennaPairsInteractive(antennaPairMap *antennaPairMap_ptr);
00291 
00292         // Iter-passes method
00293         virtual void passIntermediate(const vi::VisBuffer2 &visBuffer);
00294         virtual void passFinal(const vi::VisBuffer2 &visBuffer);
00295 
00296         // Mapping functions as requested by Urvashi
00297         void setVisibilitiesMap(std::vector<uInt> *rows,VisMapper *visMap);
00298         void setFlagsMap(std::vector<uInt> *rows, FlagMapper *flagMap);
00299         Bool checkVisExpression(polarizationMap *polMap);
00300 
00301         // Compute flags for a given visibilities point
00302         virtual bool computeRowFlags(const vi::VisBuffer2 &visBuffer, FlagMapper &flags, uInt row);
00303 
00304         // Compute flags for a given visibilities point
00305         virtual bool computeInRowFlags(const vi::VisBuffer2 &visBuffer, VisMapper &visibilities,FlagMapper &flags, uInt row);
00306 
00307         // Compute flags for a given (time,freq) antenna pair map
00308         virtual bool computeAntennaPairFlags(const vi::VisBuffer2 &visBuffer, VisMapper &visibilities,FlagMapper &flags,Int antenna1,Int antenna2,vector<uInt> &rows);
00309 
00310         // Compute flags for a given (time,freq) antenna pair map w/o using visibilities
00311         virtual bool computeAntennaPairFlags(const vi::VisBuffer2 &visBuffer,FlagMapper &flags,Int antenna1,Int antenna2,vector<uInt> &rows);
00312 
00313         // Common used members that must be accessible to derived classes
00314         FlagDataHandler *flagDataHandler_p;
00315         casa::LogIO *logger_p;
00316         String agentName_p;
00317         String mode_p;
00318 
00319         // Flag counters
00320         uInt64 chunkFlags_p;
00321         uInt64 chunkNaNs_p;
00322         uInt64 tableFlags_p;
00323         uInt64 tableNaNs_p;
00324         uInt64 visBufferFlags_p;
00325         bool flagRow_p;
00326 
00327         // Multithreading configuration and agent id
00328         Bool multiThreading_p;
00329         Int nThreads_p;
00330         Int threadId_p;
00331 
00332         // Running configuration
00333         Bool prepass_p;
00334 
00335 private:
00336         
00337         vi::VisBuffer2 *visibilityBuffer_p;
00338 
00339         // MS-related objects
00340         Cube<Bool> *commonFlagCube_p;
00341         Cube<Bool> *originalFlagCube_p;
00342         Cube<Bool> *privateFlagCube_p;
00343 
00344         Vector<Bool> *commonFlagRow_p;
00345         Vector<Bool> *originalFlagRow_p;
00346         Vector<Bool> *privateFlagRow_p;
00347 
00348         // Own data selection ranges
00349         casa::String arraySelection_p;
00350         casa::String fieldSelection_p;
00351         casa::String scanSelection_p;
00352         casa::String timeSelection_p;
00353         casa::String spwSelection_p;
00354         casa::String channelSelection_p;
00355         casa::String baselineSelection_p;
00356         casa::String uvwSelection_p;
00357         casa::String polarizationSelection_p;
00358         casa::String observationSelection_p;
00359         casa::String scanIntentSelection_p;
00360         bool filterRows_p;
00361         bool filterPols_p;
00362         bool filterChannels_p;
00363         Bool flagAutoCorrelations_p;
00364         Bool antennaNegation_p;
00365 
00366         // Own data selection indexes
00367         Vector<Int> arrayList_p;
00368         Vector<Int> fieldList_p;
00369         Vector<Int> scanList_p;
00370         Matrix<Double> timeList_p;
00371         Vector<Int> spwList_p;
00372         Matrix<Int> channelList_p;
00373         Vector<Int> antenna1List_p;
00374         Vector<Int> antenna2List_p;
00375         Matrix<Int> baselineList_p;
00376         Matrix<Double> uvwList_p;
00377         Bool uvwUnits_p;
00378         OrderedMap<Int, Vector<Int> > polarizationList_p;
00379         Vector<Int> observationList_p;
00380         Vector<Int> scanIntentList_p;
00381 
00382         // Thread state parameters
00383         volatile Bool terminationRequested_p;
00384         volatile Bool threadTerminated_p;
00385         volatile Bool processing_p;
00386 
00387         // Data source configuration
00388         String expression_p;
00389         String dataColumn_p;
00390         uShort dataReference_p;
00391 
00392         // Debugging configuration
00393         Bool profiling_p;
00394         Bool checkFlags_p;
00395 
00396         // Running mode configuration
00397         uShort iterationApproach_p;
00398 
00399         // Flagging mode configuration
00400         Bool writePrivateFlagCube_p;
00401 
00402 protected:
00403         // Lists of elements to be process
00404         // jagonzal (CAS-4312): We need channelIndex_p available for the Rflag agent,
00405         // in order to take into account channel selection for the frequency mapping
00406         vector<uInt> rowsIndex_p;
00407         vector<uInt> channelIndex_p;
00408         vector<uInt> polarizationIndex_p;
00409 };
00410 
00411 class FlagAgentList
00412 {
00413         public:
00414                 FlagAgentList();
00415                 ~FlagAgentList();
00416 
00417                 // Methods to mimic vector
00418                 void push_back(FlagAgentBase *agent_i);
00419                 void pop_back();
00420                 void clear();
00421                 bool empty();
00422                 size_t size();
00423 
00424                 // Methods to mimic FlagAgentBase
00425                 void start();
00426                 void terminate ();
00427                 void join ();
00428                 void apply(bool sequential = false);
00429                 void chunkSummary();
00430                 void tableSummary();
00431                 void setProfiling(bool enable);
00432                 void setCheckMode(bool enable);
00433 
00434                 // Method to accumulate reports from all agents
00435                 FlagReport gatherReports();
00436 
00437         protected:
00438 
00439         private:
00440                 vector<FlagAgentBase *> container_p;
00441                 vector<FlagAgentBase *>::iterator iterator_p;
00442 };
00443 
00444 } //# NAMESPACE CASA - END
00445 
00446 #endif /* FlagAgentBase_H_ */
00447