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