LCOV - code coverage report
Current view: top level - flagging/Flagging - FlagAgentBase.cc (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 957 1358 70.5 %
Date: 2023-11-06 10:06:49 Functions: 50 67 74.6 %

          Line data    Source code
       1             : //# FlagAgentBase.h: This file contains the implementation of the FlagAgentBase class.
       2             : //#
       3             : //#  CASA - Common Astronomy Software Applications (http://casa.nrao.edu/)
       4             : //#  Copyright (C) Associated Universities, Inc. Washington DC, USA 2011, All rights reserved.
       5             : //#  Copyright (C) European Southern Observatory, 2011, All rights reserved.
       6             : //#
       7             : //#  This library is free software; you can redistribute it and/or
       8             : //#  modify it under the terms of the GNU Lesser General Public
       9             : //#  License as published by the Free software Foundation; either
      10             : //#  version 2.1 of the License, or (at your option) any later version.
      11             : //#
      12             : //#  This library is distributed in the hope that it will be useful,
      13             : //#  but WITHOUT ANY WARRANTY, without even the implied warranty of
      14             : //#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             : //#  Lesser General Public License for more details.
      16             : //#
      17             : //#  You should have received a copy of the GNU Lesser General Public
      18             : //#  License along with this library; if not, write to the Free Software
      19             : //#  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
      20             : //#  MA 02111-1307  USA
      21             : //# $Id: $
      22             : 
      23             : #include <flagging/Flagging/FlagAgentBase.h>
      24             : 
      25             : #include <stdcasa/StdCasa/CasacSupport.h>
      26             : #include <casacore/ms/MSSel/MSSelectionTools.h>
      27             : 
      28             : // Headers of every concrete agent, needed for the factory method (create)
      29             : #include <flagging/Flagging/FlagAgentTimeFreqCrop.h>
      30             : #include <flagging/Flagging/FlagAgentClipping.h>
      31             : #include <flagging/Flagging/FlagAgentSummary.h>
      32             : #include <flagging/Flagging/FlagAgentManual.h>
      33             : #include <flagging/Flagging/FlagAgentElevation.h>
      34             : #include <flagging/Flagging/FlagAgentQuack.h>
      35             : #include <flagging/Flagging/FlagAgentShadow.h>
      36             : #include <flagging/Flagging/FlagAgentExtension.h>
      37             : #include <flagging/Flagging/FlagAgentRFlag.h>
      38             : #include <flagging/Flagging/FlagAgentAntennaIntegrations.h>
      39             : #ifdef USE_GRPC
      40             : #include <flagging/Flagging/grpcFlagAgentDisplay.h>
      41             : #endif
      42             : 
      43             : using namespace casacore;
      44             : namespace casa { //# NAMESPACE CASA - BEGIN
      45             : 
      46             : ////////////////////////////////////
      47             : /// FlagAgentBase implementation ///
      48             : ////////////////////////////////////
      49             : 
      50        2251 : FlagAgentBase::FlagAgentBase(FlagDataHandler *dh, Record config, uShort iterationApproach, Bool writePrivateFlagCube, Bool flag):
      51        2356 :     logger_p(new LogIO(LogOrigin("FlagAgentBase",__FUNCTION__,WHERE)))
      52             : {
      53             :         // Initialize logger
      54        2251 :         if (config.fieldNumber ("loglevel") >= 0)
      55             :         {
      56           0 :                 logLevel_p = (LogIO::Command)config.asuChar("loglevel");
      57             :         }
      58        2251 :         else if (agentName_p.empty())
      59             :         {
      60        2251 :                 logLevel_p = LogIO::NORMAL;
      61             :         }
      62             : 
      63             :         // Initialize members
      64        2251 :         initialize();
      65             : 
      66             :         // Set iteration approach
      67        2251 :         iterationApproach_p = iterationApproach;
      68             : 
      69             :         // Set private flag cube (needed for flag extension)
      70        2251 :         writePrivateFlagCube_p = writePrivateFlagCube;
      71             : 
      72             :         // Retrieve apply mode
      73        2251 :         if (config.fieldNumber ("apply") >= 0)
      74             :         {
      75        2251 :                 apply_p = config.asBool("apply");
      76             :         }
      77             :         else
      78             :         {
      79           0 :                 apply_p = true;
      80             :         }
      81             : 
      82             :         // Set apply/unapply
      83        2251 :         if (apply_p == true)
      84             :         {
      85        2241 :                 flag_p = flag;
      86             :         }
      87             :         else
      88             :         {
      89          10 :                 flag_p = !flag;
      90             :         }
      91             : 
      92             :         // Set flag data handler
      93        2251 :         flagDataHandler_p = dh;
      94             : 
      95             :         // Set vis buffer
      96        2251 :         visibilityBuffer_p = flagDataHandler_p->visibilityBuffer_p;
      97             : 
      98             :         // Set agent parameters
      99        2251 :         setAgentParameters(config);
     100             : 
     101             :         // Set data selection
     102        2254 :         setDataSelection(config);
     103             : 
     104             :         // Setup time/channel average iterator parameters
     105        2248 :         if (timeavg_p)
     106             :         {
     107          32 :             flagDataHandler_p->timeAverageBin_p = timebin_p;
     108          32 :             flagDataHandler_p->dataColumnType_p = dataColumn_p;
     109          32 :         flagDataHandler_p->setTimeAverageIter(true);
     110             :         }
     111             : 
     112             :         // Setup time/channel average iterator parameters
     113        2248 :         if (channelavg_p)
     114             :         {
     115          33 :                 flagDataHandler_p->setChanAverageIter(chanbin_p);
     116          33 :                 filterChannels_p=false; // Done in the iterator
     117             :         }
     118             : 
     119             : 
     120             :         // Check if async processing is enabled
     121        2248 :         backgroundMode_p = false;
     122        2248 :         AipsrcValue<Bool>::find (backgroundMode_p,"FlagAgent.background", false);
     123             : 
     124        2248 :         if (backgroundMode_p)
     125             :         {
     126           0 :                 *logger_p << LogIO::DEBUG1 << " Background mode enabled" << LogIO::POST;
     127             :         }
     128             :         else
     129             :         {
     130        2248 :                 *logger_p << LogIO::DEBUG1 << " Background mode disabled" << LogIO::POST;
     131             :         }
     132        2248 : }
     133             : 
     134        2248 : FlagAgentBase::~FlagAgentBase()
     135             : {
     136        2248 :         if (privateFlagCube_p) delete privateFlagCube_p;
     137        2248 : }
     138             : 
     139             : void
     140        2251 : FlagAgentBase::initialize()
     141             : {
     142             :    // Initialize members
     143        2251 :    flagDataHandler_p = NULL;
     144        2251 :    visibilityBuffer_p = NULL;
     145        2251 :    privateFlagCube_p = NULL;
     146        2251 :    commonFlagCube_p = NULL;
     147        2251 :    originalFlagCube_p = NULL;
     148        2251 :    privateFlagRow_p = NULL;
     149        2251 :    commonFlagRow_p = NULL;
     150        2251 :    originalFlagRow_p = NULL;
     151             : 
     152             :    // Initialize selection ranges
     153        2251 :    timeSelection_p = String("");
     154        2251 :    baselineSelection_p = String("");
     155        2251 :    fieldSelection_p = String("");
     156             :    // NOTE (first implementation): According to MS selection syntax, spw must be at least *
     157             :    // but since we are parsing it only if it was provided it should not be a problem
     158             :    // NOTE (after Dec 2011 testing): As far as I know spw selection does not have to be *
     159             :    // (can be empty) and in fact applying a spw selection slows down the MSSelection class
     160        2251 :    spwSelection_p = String("");
     161        2251 :    uvwSelection_p = String("");
     162        2251 :    polarizationSelection_p = String("");
     163        2251 :    scanSelection_p = String("");
     164        2251 :    arraySelection_p = String("");
     165        2251 :    observationSelection_p = String("");
     166        2251 :    scanIntentSelection_p = String("");
     167             : 
     168             :    // Clear up indexes
     169        2251 :    rowsIndex_p.clear();
     170        2251 :    channelIndex_p.clear();
     171        2251 :    polarizationIndex_p.clear();
     172             : 
     173             :    // Initialize filters
     174        2251 :    antennaNegation_p = false;
     175        2251 :    filterChannels_p = false;
     176        2251 :    filterRows_p = false;
     177        2251 :    filterPols_p = false;
     178        2251 :    flagAutoCorrelations_p = false;
     179        2251 :    uvwUnits_p = true; // Meters
     180             : 
     181             :         // Initialize state
     182        2251 :    terminationRequested_p = false;
     183        2251 :    threadTerminated_p = false;
     184        2251 :    processing_p = false;
     185             : 
     186             :    // Initialize counters
     187        2251 :    chunkFlags_p = 0;
     188        2251 :    chunkNaNs_p = 0;
     189        2251 :    tableFlags_p = 0;
     190        2251 :    tableNaNs_p = 0;
     191        2251 :    visBufferFlags_p = 0;
     192             : 
     193             :    // Pre-averaging parameters
     194        2251 :    timeavg_p = false;
     195        2251 :    timebin_p = 0.0;
     196        2251 :    channelavg_p = false;
     197        2251 :    chanbin_p = Vector<Int>(1, 1);
     198             : 
     199             :    //// Initialize configuration ////
     200             : 
     201             :    /// Running config
     202        2251 :    profiling_p = false;
     203        2251 :    backgroundMode_p = false;
     204        2251 :    iterationApproach_p = ROWS;
     205        2251 :    multiThreading_p = false;
     206        2251 :    prepass_p = false;
     207        2251 :    nThreads_p = 0;
     208        2251 :    threadId_p = 0;
     209             : 
     210        2251 :    agentName_p = String("");
     211        2251 :    summaryName_p = String("");
     212             :    /// Flag/Unflag config
     213        2251 :    writePrivateFlagCube_p = false;
     214        2251 :    flag_p = true;
     215             :    /// Mapping config
     216        2251 :    dataColumn_p = "data";
     217        2251 :    expression_p = "ABS ALL";
     218        2251 :    dataReference_p = DATA;
     219             :    /// Profiling and testing config
     220        2251 :    profiling_p = false;
     221        2251 :    checkFlags_p = false;
     222             : 
     223             :    /////////////////////////////////
     224             : 
     225        2251 :    return;
     226             : }
     227             : 
     228             : FlagAgentBase *
     229        2251 : FlagAgentBase::create (FlagDataHandler *dh,Record config)
     230             : {
     231        4502 :         String mode;
     232        2251 :         FlagAgentBase *ret = NULL;
     233             : 
     234             :         // Retrieve mode
     235        2251 :         if (config.fieldNumber ("mode") >= 0)
     236             :         {
     237        2251 :                 mode = config.asString("mode");
     238             :         }
     239             :         else
     240             :         {
     241           0 :                 cerr << "FlagAgentFactory::" << __FUNCTION__ << " Mode not provided" << endl;
     242           0 :                 return ret;
     243             :         }
     244             : 
     245             :         // Write private flags only if extension is required
     246        2251 :         bool writePrivateFlags = false;
     247        2251 :         if ((config.fieldNumber ("extend")>=0) and (config.asBool("extend")==true))
     248             :         {
     249           0 :                 writePrivateFlags = true;
     250             :         }
     251             :         // Manual mode
     252        2251 :         else if (mode.compare("manual")==0)
     253             :         {
     254        1123 :                 FlagAgentManual* agent = new FlagAgentManual(dh,config,writePrivateFlags,true);
     255        1114 :                 return agent;
     256             :         }
     257             :         // Unflag mode
     258        1134 :         else if (mode.compare("unflag")==0)
     259             :         {
     260         407 :                 FlagAgentManual* agent = new FlagAgentManual(dh,config,writePrivateFlags,false);
     261         407 :                 return agent;
     262             :         }
     263             :         // TimeFreqCrop
     264         727 :         else if (mode.compare("tfcrop")==0)
     265             :         {
     266          86 :                 FlagAgentTimeFreqCrop* agent = new FlagAgentTimeFreqCrop(dh,config,writePrivateFlags,true);
     267          86 :                 return agent;
     268             :         }
     269             :         // Clip
     270         641 :         else if (mode.compare("clip")==0)
     271             :         {
     272         106 :                 FlagAgentClipping* agent = new FlagAgentClipping(dh,config,writePrivateFlags,true);
     273         106 :                 return agent;
     274             :         }
     275             :         // Summary
     276         535 :         else if (mode.compare("summary")==0)
     277             :         {
     278         401 :                 FlagAgentSummary* agent = new FlagAgentSummary(dh,config);
     279         401 :                 return agent;
     280             :         }
     281             :         // Elevation
     282         134 :         else if (mode.compare("elevation")==0)
     283             :         {
     284           8 :                 FlagAgentElevation* agent = new FlagAgentElevation(dh,config,writePrivateFlags,true);
     285           8 :                 return agent;
     286             :         }
     287             :         // Quack
     288         126 :         else if (mode.compare("quack")==0)
     289             :         {
     290          20 :                 FlagAgentQuack* agent = new FlagAgentQuack(dh,config,writePrivateFlags,true);
     291          17 :                 return agent;
     292             :         }
     293             :         // Shadow
     294         108 :         else if (mode.compare("shadow")==0)
     295             :         {
     296          16 :                 FlagAgentShadow* agent = new FlagAgentShadow(dh,config,writePrivateFlags,true);
     297          16 :                 return agent;
     298             :         }
     299             :         // Extension
     300          92 :         else if (mode.compare("extend")==0)
     301             :         {
     302          29 :                 FlagAgentExtension* agent = new FlagAgentExtension(dh,config);
     303          29 :                 return agent;
     304             :         }
     305             :         // Rflag
     306          63 :         else if (mode.compare("rflag")==0)
     307             :         {
     308          53 :                 FlagAgentRFlag* agent = new FlagAgentRFlag(dh,config);
     309          53 :                 return agent;
     310             :         }
     311             :         // Antint
     312          10 :         else if (mode.compare("antint")==0)
     313             :         {
     314          10 :                 FlagAgentAntennaIntegrations* agent = new FlagAgentAntennaIntegrations(dh,config,writePrivateFlags, true);
     315          10 :                 return agent;
     316             :         }
     317             :         // Display
     318           0 :         else if (mode.compare("display")==0)
     319             :         {
     320           0 :                 FlagAgentDisplay* agent = new FlagAgentDisplay(dh,config,writePrivateFlags);
     321           0 :                 return agent;
     322             :         }
     323             :         else
     324             :         {
     325           0 :                 cerr << "FlagAgentFactory::" << __FUNCTION__ << " Mode " << mode << " not supported" << endl;
     326             :         }
     327             : 
     328           0 :         return ret;
     329             : }
     330             : 
     331             : void
     332        2241 : FlagAgentBase::start()
     333             : {
     334        2241 :         if (backgroundMode_p)
     335             :         {
     336           0 :                 casa::async::Thread::startThread();
     337             :         }
     338             : 
     339        2241 :         return;
     340             : }
     341             : 
     342             : void
     343        2241 : FlagAgentBase::terminate ()
     344             : {
     345        2241 :         if (backgroundMode_p)
     346             :         {
     347           0 :                 terminationRequested_p = true;
     348           0 :                 while (!threadTerminated_p)
     349             :                 {
     350           0 :                         sched_yield();
     351             :                 }
     352             : 
     353           0 :                 casa::async::Thread::terminate();
     354             :         }
     355             : 
     356        2241 :         return;
     357             : }
     358             : 
     359             : void
     360      794155 : FlagAgentBase::queueProcess()
     361             : {
     362      794155 :         if (backgroundMode_p)
     363             :         {
     364             :                 // Wait until we are done with previous buffer
     365           0 :                 while (processing_p)
     366             :                 {
     367           0 :                         sched_yield();
     368             :                 }
     369             : 
     370             :                 // Enable processing to trigger flagging
     371           0 :                 processing_p = true;
     372             :         }
     373             :         else
     374             :         {
     375      794155 :                 runCore();
     376             :         }
     377             : 
     378      794155 :         return;
     379             : }
     380             : 
     381             : void
     382      794155 : FlagAgentBase::completeProcess()
     383             : {
     384      794155 :         if (backgroundMode_p)
     385             :         {
     386             :                 // Wait until we are done with previous buffer
     387           0 :                 while (processing_p)
     388             :                 {
     389           0 :                         sched_yield();
     390             :                 }
     391             :         }
     392             : 
     393      794155 :         return;
     394             : }
     395             : 
     396             : void *
     397           0 : FlagAgentBase::run ()
     398             : {
     399           0 :         if (backgroundMode_p)
     400             :         {
     401           0 :                 while (!terminationRequested_p)
     402             :                 {
     403             : 
     404           0 :                         if (processing_p) // NOTE: This races with queueProcess but it is harmless
     405             :                         {
     406             :                                 // Carry out processing
     407           0 :                                 runCore();
     408             : 
     409             :                                 // Disable processing to enter in idle mode
     410           0 :                                 processing_p = false;
     411             :                         }
     412             :                         else
     413             :                         {
     414           0 :                                 sched_yield();
     415             :                         }
     416             :                 }
     417             :         }
     418             : 
     419           0 :         processing_p = false;
     420           0 :         threadTerminated_p = true;
     421             : 
     422           0 :         return NULL;
     423             : }
     424             : 
     425             : void
     426      794155 : FlagAgentBase::runCore()
     427             : {
     428             :         // Set pointer to common flag cube
     429      794155 :         commonFlagCube_p = flagDataHandler_p->getModifiedFlagCube();
     430      794155 :         originalFlagCube_p = flagDataHandler_p->getOriginalFlagCube();
     431             : 
     432             :         // Set pointer to common flag row
     433      794155 :         commonFlagRow_p = flagDataHandler_p->getModifiedFlagRow();
     434      794155 :         originalFlagRow_p = flagDataHandler_p->getOriginalFlagRow();
     435             : 
     436             :         // Set vis buffer
     437      794155 :         visibilityBuffer_p = flagDataHandler_p->visibilityBuffer_p;
     438             : 
     439             :         // Reset VisBuffer flag counters
     440      794155 :         visBufferFlags_p = 0;
     441             : 
     442      794155 :         if (checkIfProcessBuffer())
     443             :         {
     444             :                 // Generate indexes applying data selection filters
     445      567914 :                 generateAllIndex();
     446             : 
     447      567914 :                 if ((!rowsIndex_p.size()) || (!channelIndex_p.size()) || (!polarizationIndex_p.size()))
     448             :                 {
     449        3028 :                         return;
     450             :                 }
     451             : 
     452             :                 // Set pointer to private flag cube
     453      564886 :                 if (writePrivateFlagCube_p)
     454             :                 {
     455           0 :                         if (privateFlagCube_p) delete privateFlagCube_p;
     456           0 :                         privateFlagCube_p = new Cube<Bool>(commonFlagCube_p->shape(),!flag_p);
     457             :                 }
     458             : 
     459      564886 :                 switch (iterationApproach_p)
     460             :                 {
     461             :                         // Iterate inside every row (i.e. channels) applying a mapping expression
     462             :                         // clipping
     463       29849 :                         case IN_ROWS:
     464             :                         {
     465       29849 :                                 preProcessBuffer(*(flagDataHandler_p->visibilityBuffer_p));
     466       29849 :                                 iterateInRows();
     467       29849 :                                 break;
     468             :                         }
     469             :                         // Iterate through rows (i.e. baselines)
     470             :                         // manual, quack
     471      423013 :                         case ROWS:
     472             :                         {
     473      423013 :                                 iterateRows();
     474      423013 :                                 break;
     475             :                         }
     476             :                         // Iterate through rows (i.e. baselines) doing a common pre-processing before
     477             :                         // elevation, shadow, summary, antint
     478      110512 :                         case ROWS_PREPROCESS_BUFFER:
     479             :                         {
     480      110512 :                                 preProcessBuffer(*(flagDataHandler_p->visibilityBuffer_p));
     481      110512 :                                 iterateRows();
     482      110512 :                                 postProcessBuffer();
     483      110512 :                                 break;
     484             :                         }
     485             :                         // Iterate through (time,freq) maps per antenna pair
     486             :                         // tfcrop,rflag
     487        1070 :                         case ANTENNA_PAIRS:
     488             :                         {
     489        1070 :                                 prepass_p = false;
     490             : 
     491        1070 :                                 iterateAntennaPairs();
     492             : 
     493             :                                 // Do a second pass if the previous one was a pre-pass
     494        1070 :                                 if (prepass_p)
     495             :                                 {
     496         152 :                                         prepass_p = false;
     497         152 :                                         passIntermediate(*(flagDataHandler_p->visibilityBuffer_p));
     498         152 :                                         iterateAntennaPairs();
     499         152 :                                         passFinal(*(flagDataHandler_p->visibilityBuffer_p));
     500             :                                 }
     501             : 
     502        1070 :                                 break;
     503             :                         }
     504             :                         // Iterate through (time,freq) maps per antenna pair
     505             :                         // extension
     506         442 :                         case ANTENNA_PAIRS_FLAGS:
     507             :                         {
     508         442 :                                 iterateAntennaPairsFlags();
     509         442 :                                 break;
     510             :                         }
     511             :                         // Navigate through (time,freq) maps per antenna pair
     512             :                         // display
     513           0 :                         case ANTENNA_PAIRS_INTERACTIVE:
     514             :                         {
     515           0 :                                 preProcessBuffer(*(flagDataHandler_p->visibilityBuffer_p));
     516           0 :                                 iterateAntennaPairsInteractive(flagDataHandler_p->getAntennaPairMap());
     517           0 :                                 break;
     518             :                         }
     519             :                         // Iterate through (time,freq) maps per antenna pair doing a common pre-processing before
     520             :                         // Not used by any of the available agents at the moment
     521           0 :                         case ANTENNA_PAIRS_PREPROCESS_BUFFER:
     522             :                         {
     523           0 :                                 preProcessBuffer(*(flagDataHandler_p->visibilityBuffer_p));
     524           0 :                                 iterateAntennaPairs();
     525           0 :                                 break;
     526             :                         }
     527             :                         // Iterate inside every row (i.e. channels) applying a mapping expression doing a common pre-processing before
     528             :                         // Not used by any of the available agents at the moment
     529           0 :                         case IN_ROWS_PREPROCESS_BUFFER:
     530             :                         {
     531           0 :                                 preProcessBuffer(*(flagDataHandler_p->visibilityBuffer_p));
     532           0 :                                 iterateInRows();
     533           0 :                                 break;
     534             :                         }
     535           0 :                         default:
     536             :                         {
     537           0 :                                 throw AipsError("Unknown iteration approach requested");
     538             :                                 break;
     539             :                         }
     540             :                 }
     541             : 
     542             :                 // If any row was flag, then we have to flush the flagRow
     543      564886 :                 if (flagRow_p) flagDataHandler_p->flushFlagRow_p = true;
     544             : 
     545             :                 // jagonzal: CAS-3913 We have to reset flagRow
     546      564886 :                 flagRow_p = false;
     547             : 
     548             :                 // If any flag was raised, then we have to flush the flagCube
     549      564886 :                 if (visBufferFlags_p>0) flagDataHandler_p->flushFlags_p = true;
     550             : 
     551             :                 // Update chunk counter
     552      564886 :                 chunkFlags_p += visBufferFlags_p;
     553     1129772 :                 if (logger_p->priority() >= LogMessage::DEBUG2 &&
     554      564886 :                     visBufferFlags_p > 0) {
     555     1268121 :                     LogIO os(LogOrigin("FlagAgentBase", __FUNCTION__));
     556             :                     os << LogIO::DEBUG2 << " buffer -> chunk flag counter += "
     557             :                        << visBufferFlags_p << " (chunk flags: " << chunkFlags_p << ")"
     558      422707 :                        << LogIO::POST;
     559             :                 }
     560             :         }
     561             : 
     562      791127 :         return;
     563             : }
     564             : 
     565             : // -----------------------------------------------------------------------
     566             : // Set Data Selection parameters
     567             : // -----------------------------------------------------------------------
     568             : void
     569        2251 : FlagAgentBase::setDataSelection(Record config)
     570             : {
     571        2251 :         logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
     572             : 
     573             :         int exists;
     574             :         // Set the MS Selection error handler to catch spw IDs or names that are
     575             :     // not present in the MS in an expression that contains valid spw values.
     576             :         // This will issue a WARNING and not fail.
     577        4502 :     MSSelectionLogError mssLESPW;
     578        4502 :         MSSelection parser;
     579             : 
     580        2251 :         exists = config.fieldNumber ("array");
     581        2251 :         if (exists >= 0)
     582             :         {
     583          21 :                 config.get (config.fieldNumber ("array"), arraySelection_p);
     584             : 
     585          21 :                 if (arraySelection_p.empty())
     586             :                 {
     587          21 :                         *logger_p << LogIO::DEBUG1 << " no array selection" << LogIO::POST;
     588             :                 }
     589             :                 else
     590             :                 {
     591           0 :                         parser.setArrayExpr(arraySelection_p);
     592           0 :                         if (flagDataHandler_p->parseExpression(parser))
     593             :                         {
     594           0 :                                 arrayList_p=parser.getSubArrayList();
     595           0 :                                 filterRows_p=true;
     596             : 
     597             :                                 // Request to pre-load ArrayId
     598           0 :                                 flagDataHandler_p->preLoadColumn(VisBufferComponent2::ArrayId);
     599             : 
     600           0 :                                 *logger_p << LogIO::DEBUG1 << " array selection is " << arraySelection_p << LogIO::POST;
     601           0 :                                 *logger_p << LogIO::DEBUG1 << " array ids are " << arrayList_p << LogIO::POST;
     602             :                         }
     603             :                 }
     604             :         }
     605             :         else
     606             :         {
     607        2230 :                 *logger_p << LogIO::DEBUG1 << " no array selection" << LogIO::POST;
     608             :         }
     609             : 
     610        2251 :         exists = config.fieldNumber ("field");
     611        2251 :         if (exists >= 0)
     612             :         {
     613          23 :                 config.get (config.fieldNumber ("field"), fieldSelection_p);
     614             : 
     615          23 :                 if (fieldSelection_p.empty())
     616             :                 {
     617          23 :                         *logger_p << LogIO::DEBUG1 << " no field selection" << LogIO::POST;
     618             :                 }
     619             :                 else
     620             :                 {
     621           0 :                         parser.setFieldExpr(fieldSelection_p);
     622           0 :                         if (flagDataHandler_p->parseExpression(parser))
     623             :                         {
     624           0 :                                 fieldList_p=parser.getFieldList();
     625           0 :                                 filterRows_p=true;
     626             : 
     627             :                                 // Request to pre-load FieldId
     628           0 :                                 flagDataHandler_p->preLoadColumn(VisBufferComponent2::FieldId);
     629             : 
     630           0 :                                 *logger_p << LogIO::DEBUG1 << " field selection is " << fieldSelection_p << LogIO::POST;
     631           0 :                                 *logger_p << LogIO::DEBUG1 << " field ids are " << fieldList_p << LogIO::POST;
     632             :                         }
     633             : 
     634             :                 }
     635             :         }
     636             :         else
     637             :         {
     638        2228 :                 *logger_p << LogIO::DEBUG1 << " no field selection" << LogIO::POST;
     639             :         }
     640             : 
     641        2251 :         exists = config.fieldNumber ("scan");
     642        2251 :         if (exists >= 0)
     643             :         {
     644          88 :                 config.get (config.fieldNumber ("scan"), scanSelection_p);
     645             : 
     646          88 :                 if (scanSelection_p.empty())
     647             :                 {
     648          21 :                         *logger_p << LogIO::DEBUG1 << " no scan selection" << LogIO::POST;
     649             :                 }
     650             :                 else
     651             :                 {
     652          67 :                         parser.setScanExpr(scanSelection_p);
     653          67 :                         if (flagDataHandler_p->parseExpression(parser))
     654             :                         {
     655          67 :                                 scanList_p=parser.getScanList();
     656          67 :                                 filterRows_p=true;
     657             : 
     658             :                                 // Request to pre-load scan
     659          67 :                                 flagDataHandler_p->preLoadColumn(VisBufferComponent2::Scan);
     660             : 
     661          67 :                                 *logger_p << LogIO::DEBUG1 << " scan selection is " << scanSelection_p << LogIO::POST;
     662          67 :                                 *logger_p << LogIO::DEBUG1 << " scan ids are " << scanList_p << LogIO::POST;
     663             :                         }
     664             :                 }
     665             :         }
     666             :         else
     667             :         {
     668        2163 :                 *logger_p << LogIO::DEBUG1 << " no scan selection" << LogIO::POST;
     669             :         }
     670             : 
     671        2251 :         exists = config.fieldNumber ("timerange");
     672        2251 :         if (exists >= 0)
     673             :         {
     674         889 :                 config.get (config.fieldNumber ("timerange"), timeSelection_p);
     675             : 
     676         889 :                 if (timeSelection_p.empty())
     677             :                 {
     678          21 :                         *logger_p << LogIO::DEBUG1 << " no time selection" << LogIO::POST;
     679             :                 }
     680             :                 else
     681             :                 {
     682         868 :                         parser.setTimeExpr(timeSelection_p);
     683         868 :                         if (flagDataHandler_p->parseExpression(parser))
     684             :                         {
     685         868 :                                 timeList_p=parser.getTimeList();
     686         868 :                                 filterRows_p=true;
     687             : 
     688             :                                 // Request to pre-load time
     689         868 :                                 flagDataHandler_p->preLoadColumn(VisBufferComponent2::Time);
     690             : 
     691         868 :                                 *logger_p << LogIO::DEBUG1 << " timerange selection is " << timeSelection_p << LogIO::POST;
     692         868 :                                 *logger_p << LogIO::DEBUG1 << " time ranges in MJD are " << timeList_p << LogIO::POST;
     693             :                         }
     694             :                 }
     695             :         }
     696             :         else
     697             :         {
     698        1362 :                 *logger_p << LogIO::DEBUG1 << " no time selection" << LogIO::POST;
     699             :         }
     700             : 
     701        2251 :         exists = config.fieldNumber ("spw");
     702        2251 :         if (exists >= 0)
     703             :         {
     704        1377 :                 config.get (config.fieldNumber ("spw"), spwSelection_p);
     705             : 
     706        1377 :                 if (spwSelection_p.empty())
     707             :                 {
     708         769 :                         *logger_p << LogIO::DEBUG1 << " no spw selection" << LogIO::POST;
     709             :                 }
     710             :                 else
     711             :                 {
     712         608 :                     parser.setErrorHandler(MSSelection::SPW_EXPR, &mssLESPW, true);
     713         608 :                         parser.setSpwExpr(spwSelection_p);
     714         608 :                         if (flagDataHandler_p->parseExpression(parser))
     715             :                         {
     716         608 :                                 spwList_p=parser.getSpwList();
     717         608 :                                 filterRows_p=true;
     718             : 
     719         608 :                                 channelList_p=parser.getChanList();
     720         608 :                                 filterChannels_p=true;
     721             : 
     722             :                                 // Request to pre-load spw
     723         608 :                                 flagDataHandler_p->preLoadColumn(VisBufferComponent2::SpectralWindows);
     724             : 
     725         608 :                                 *logger_p << LogIO::DEBUG1 << " spw selection is " << spwSelection_p << LogIO::POST;
     726         608 :                                 *logger_p << LogIO::DEBUG1 << " channel selection are " << channelList_p << LogIO::POST;
     727             :                         }
     728             :                 }
     729             :         }
     730             :         else
     731             :         {
     732         874 :                 *logger_p << LogIO::DEBUG1 << " no spw selection" << LogIO::POST;
     733             :         }
     734             : 
     735        2251 :         exists = config.fieldNumber ("antenna");
     736        2251 :         if (exists >= 0)
     737             :         {
     738         883 :                 config.get (config.fieldNumber ("antenna"), baselineSelection_p);
     739             : 
     740         883 :                 if (baselineSelection_p.empty())
     741             :                 {
     742          22 :                         *logger_p << LogIO::DEBUG1 << " no antenna selection" << LogIO::POST;
     743             :                 }
     744             :                 else
     745             :                 {
     746             : 
     747             :                         // Remove antenna negation operator (!) and set antenna negation flag
     748         861 :                         size_t pos = baselineSelection_p.find(String("!"));
     749         861 :                         while (pos != String::npos)
     750             :                         {
     751           0 :                                 antennaNegation_p = true;
     752           0 :                                 baselineSelection_p.replace(pos,1,String(""));
     753           0 :                                 *logger_p << LogIO::DEBUG1 << " antenna selection is the negation of " << baselineSelection_p << LogIO::POST;
     754           0 :                                 pos = baselineSelection_p.find(String("!"));
     755             :                         }
     756             : 
     757         861 :                         parser.setAntennaExpr(baselineSelection_p);
     758         861 :                         if (flagDataHandler_p->parseExpression(parser))
     759             :                         {
     760         861 :                                 antenna1List_p=parser.getAntenna1List();
     761         861 :                                 antenna2List_p=parser.getAntenna2List();
     762         861 :                                 baselineList_p=parser.getBaselineList();
     763         861 :                                 filterRows_p=true;
     764             : 
     765             :                                 // Request to pre-load antenna1/2
     766         861 :                                 flagDataHandler_p->preLoadColumn(VisBufferComponent2::Antenna1);
     767         861 :                                 flagDataHandler_p->preLoadColumn(VisBufferComponent2::Antenna2);
     768             : 
     769         861 :                                 *logger_p << LogIO::DEBUG1 << " selected antenna1 list is " << antenna1List_p << LogIO::POST;
     770         861 :                                 *logger_p << LogIO::DEBUG1 << " selected antenna2 list is " << antenna2List_p << LogIO::POST;
     771         861 :                                 *logger_p << LogIO::DEBUG1 << " selected baselines are " << baselineList_p << LogIO::POST;
     772             :                         }
     773             :                 }
     774             :         }
     775             :         else
     776             :         {
     777        1368 :                 *logger_p << LogIO::DEBUG1 << " no baseline selection" << LogIO::POST;
     778             :         }
     779             : 
     780        2251 :         exists = config.fieldNumber ("uvrange");
     781        2251 :         if (exists >= 0)
     782             :         {
     783          22 :                 config.get (config.fieldNumber ("uvrange"), uvwSelection_p);
     784             : 
     785          22 :                 if (uvwSelection_p.empty())
     786             :                 {
     787          21 :                         *logger_p << LogIO::DEBUG1 << " no uvw selection" << LogIO::POST;
     788             :                 }
     789             :                 else
     790             :                 {
     791           1 :                         parser.setUvDistExpr(uvwSelection_p);
     792           1 :                         if (flagDataHandler_p->parseExpression(parser))
     793             :                         {
     794           1 :                                 uvwList_p=parser.getUVList();
     795           2 :                                 Vector<Bool> units = parser.getUVUnitsList();
     796           1 :                                 if (units[0]==1)
     797             :                                 {
     798           0 :                                         uvwUnits_p = true; //Meters
     799             :                                 }
     800             :                                 else
     801             :                                 {
     802           1 :                                         uvwUnits_p = false; //Lambda
     803             :                                 }
     804             : 
     805           1 :                                 filterRows_p=true;
     806             : 
     807             :                                 // Request to pre-load uvw
     808           1 :                                 flagDataHandler_p->preLoadColumn(VisBufferComponent2::Uvw);
     809             : 
     810           1 :                                 *logger_p << LogIO::DEBUG1 << " uvrange selection is " << uvwSelection_p << LogIO::POST;
     811           1 :                                 *logger_p << LogIO::DEBUG1 << " uvrange ids are " << uvwList_p << LogIO::POST;
     812           1 :                                 *logger_p << LogIO::DEBUG1 << " uvunits are " << units << LogIO::POST;
     813             :                         }
     814             :                 }
     815             :         }
     816             :         else
     817             :         {
     818        2229 :                 *logger_p << LogIO::DEBUG1 << " no uvw selection" << LogIO::POST;
     819             :         }
     820             : 
     821        2251 :         exists = config.fieldNumber ("correlation");
     822        2251 :         if (exists >= 0)
     823             :         {
     824         737 :                 config.get (config.fieldNumber ("correlation"), polarizationSelection_p);
     825             : 
     826         737 :                 if (polarizationSelection_p.empty())
     827             :                 {
     828          21 :                         *logger_p << LogIO::DEBUG1 << " no correlation selection" << LogIO::POST;
     829             :                 }
     830             : 
     831             : 
     832             :                 // Only process the polarization selection as in-row selection if there is no complex operator
     833        1427 :                 else if ((polarizationSelection_p.find("REAL") == string::npos) and
     834        1422 :                                 (polarizationSelection_p.find("IMAG") == string::npos) and
     835        1422 :                                 (polarizationSelection_p.find("ARG") == string::npos) and
     836        2138 :                                 (polarizationSelection_p.find("ABS") == string::npos) and
     837         606 :                                 (polarizationSelection_p.find("NORM") == string::npos))
     838             :                 {
     839             :                         // jagonzal (CAS-4234): Sanitize correlation expressions
     840        1210 :                         String sanitizedExpression;
     841         605 :                         if (flagDataHandler_p->tableTye_p == FlagDataHandler::MEASUREMENT_SET)
     842             :                         {
     843         594 :                                 sanitizedExpression = sanitizeCorrExpression(polarizationSelection_p,flagDataHandler_p->corrProducts_p);
     844             :                         }
     845             :                         else
     846             :                         {
     847          11 :                                 sanitizedExpression = polarizationSelection_p;
     848             :                         }
     849             : 
     850         605 :                         if (sanitizedExpression.size() > 0)
     851             :                         {
     852         605 :                                 polarizationSelection_p = sanitizedExpression;
     853         605 :                                 parser.setPolnExpr(polarizationSelection_p);
     854             :                                 // parseExpression should not be called for a Cal table
     855             :                                 // until MS Selection can handle correlation parameter for
     856             :                                 // cal tables.
     857        1199 :                                 if (flagDataHandler_p->tableTye_p == FlagDataHandler::MEASUREMENT_SET and
     858         594 :                                                 flagDataHandler_p->parseExpression(parser))
     859             :                                 {
     860             : 
     861         594 :                                         polarizationList_p=parser.getPolMap();
     862         594 :                                         filterPols_p=true;
     863             : 
     864             :                                         // Request to pre-load CorrType
     865         594 :                                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::CorrType);
     866             : 
     867         594 :                                         ostringstream polarizationListToPrint (ios::in | ios::out);
     868        1188 :                                         for (const auto &item : polarizationList_p)
     869         594 :                                             polarizationListToPrint << item.first << "=" << item.second << " ";
     870         594 :                                         *logger_p << LogIO::DEBUG1 << " correlation selection is " << polarizationSelection_p << LogIO::POST;
     871         594 :                                         *logger_p << LogIO::DEBUG1 << " correlation ids are " << polarizationListToPrint.str() << LogIO::POST;
     872             :                                 }
     873             :                                 else {
     874          11 :                                         *logger_p << LogIO::DEBUG1 << " solution selection is " << polarizationSelection_p << LogIO::POST;
     875             :                                 }
     876             : 
     877             :                         }
     878             :                         else
     879             :                         {
     880           0 :                                 AipsError exception(String("None of the requested correlation products (" + polarizationSelection_p + ") is available"));
     881           0 :                                 throw (exception);
     882             :                         }
     883             :                 }
     884             :         }
     885             :         else
     886             :         {
     887        1514 :                 *logger_p << LogIO::DEBUG1 << " no polarization selection" << LogIO::POST;
     888             :         }
     889             : 
     890        2251 :         exists = config.fieldNumber ("observation");
     891        2251 :         if (exists >= 0)
     892             :         {
     893          21 :                 config.get (config.fieldNumber ("observation"), observationSelection_p);
     894             : 
     895          21 :                 if (observationSelection_p.empty())
     896             :                 {
     897          21 :                         *logger_p << LogIO::DEBUG1 << " no observation selection" << LogIO::POST;
     898             :                 }
     899             :                 else
     900             :                 {
     901           0 :                         parser.setObservationExpr(observationSelection_p);
     902           0 :                         if (flagDataHandler_p->parseExpression(parser))
     903             :                         {
     904           0 :                                 observationList_p=parser.getObservationList();
     905           0 :                                 filterRows_p=true;
     906             : 
     907             :                                 // Request to pre-load ObservationId
     908           0 :                                 flagDataHandler_p->preLoadColumn(VisBufferComponent2::ObservationId);
     909             : 
     910           0 :                                 *logger_p << LogIO::DEBUG1 << " observation selection is " << observationList_p << LogIO::POST;
     911           0 :                                 *logger_p << LogIO::DEBUG1 << " observation ids are " << observationList_p << LogIO::POST;
     912             :                         }
     913             :                 }
     914             :         }
     915             :         else
     916             :         {
     917        2230 :                 *logger_p << LogIO::DEBUG1 << " no observation selection" << LogIO::POST;
     918             :         }
     919             : 
     920        2251 :         exists = config.fieldNumber ("intent");
     921        2251 :         if (exists >= 0)
     922             :         {
     923          26 :                 config.get (config.fieldNumber ("intent"), scanIntentSelection_p);
     924             : 
     925          26 :                 if (scanIntentSelection_p.empty())
     926             :                 {
     927          21 :                         *logger_p << LogIO::DEBUG1 << " no intent selection" << LogIO::POST;
     928             :                 }
     929             :                 else
     930             :                 {
     931           5 :                         parser.setStateExpr(scanIntentSelection_p);
     932           5 :                         if (flagDataHandler_p->parseExpression(parser))
     933             :                         {
     934           2 :                                 scanIntentList_p=parser.getStateObsModeList();
     935           2 :                                 filterRows_p=true;
     936             : 
     937             :                                 // Request to pre-load StateId
     938           2 :                                 flagDataHandler_p->preLoadColumn(VisBufferComponent2::StateId);
     939             : 
     940           2 :                                 *logger_p << LogIO::DEBUG1 << " scan intent selection is " << scanIntentList_p << LogIO::POST;
     941           2 :                                 *logger_p << LogIO::DEBUG1 << " scan intent ids are " << scanIntentList_p << LogIO::POST;
     942             :                         }
     943             :                 }
     944             :         }
     945             :         else
     946             :         {
     947        2225 :                 *logger_p << LogIO::DEBUG1 << " no scan intent selection" << LogIO::POST;
     948             :         }
     949             : 
     950        4496 :         return;
     951             : }
     952             : 
     953             : // -----------------------------------------------------------------------
     954             : // Sanitize correlation expression
     955             : // -----------------------------------------------------------------------
     956             : String
     957         594 : FlagAgentBase::sanitizeCorrExpression(String corrExpression, std::vector<String> *corrProducts)
     958             : {
     959         594 :         logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
     960             : 
     961         594 :         String sanitizedExpression = String("");
     962         594 :         bool didSanitize = false;
     963             : 
     964         594 :         if (corrExpression.find("RR") != string::npos)
     965             :         {
     966         264 :                 if (std::find(corrProducts->begin(),corrProducts->end(),String("RR")) != corrProducts->end())
     967             :                 {
     968         264 :                         if (sanitizedExpression.size() == 0)
     969             :                         {
     970         264 :                                 sanitizedExpression += String("RR");
     971             :                         }
     972             :                         else
     973             :                         {
     974           0 :                                 sanitizedExpression += String(",RR");
     975             :                         }
     976             :                 }
     977             :                 else
     978             :                 {
     979           0 :                         didSanitize = true;
     980           0 :                         *logger_p << LogIO::WARN <<  "Correlation product [RR] not available " << LogIO::POST;
     981             :                 }
     982             :         }
     983             : 
     984         594 :         if (corrExpression.find("LL") != string::npos)
     985             :         {
     986         316 :                 if (std::find(corrProducts->begin(),corrProducts->end(),String("LL")) != corrProducts->end())
     987             :                 {
     988         316 :                         if (sanitizedExpression.size() == 0)
     989             :                         {
     990         313 :                                 sanitizedExpression += String("LL");
     991             :                         }
     992             :                         else
     993             :                         {
     994           3 :                                 sanitizedExpression += String(",LL");
     995             :                         }
     996             :                 }
     997             :                 else
     998             :                 {
     999           0 :                         didSanitize = true;
    1000           0 :                         *logger_p << LogIO::WARN <<  "Correlation product [LL] not available " << LogIO::POST;
    1001             :                 }
    1002             :         }
    1003             : 
    1004         594 :         if (corrExpression.find("RL") != string::npos)
    1005             :         {
    1006         565 :                 if (std::find(corrProducts->begin(),corrProducts->end(),String("RL")) != corrProducts->end())
    1007             :                 {
    1008         564 :                         if (sanitizedExpression.size() == 0)
    1009             :                         {
    1010           2 :                                 sanitizedExpression += String("RL");
    1011             :                         }
    1012             :                         else
    1013             :                         {
    1014         562 :                                 sanitizedExpression += String(",RL");
    1015             :                         }
    1016             :                 }
    1017             :                 else
    1018             :                 {
    1019           1 :                         didSanitize = true;
    1020           1 :                         *logger_p << LogIO::WARN <<  "Correlation product [RL] not available " << LogIO::POST;
    1021             :                 }
    1022             :         }
    1023             : 
    1024         594 :         if (corrExpression.find("LR") != string::npos)
    1025             :         {
    1026         562 :                 if (std::find(corrProducts->begin(),corrProducts->end(),String("LR")) != corrProducts->end())
    1027             :                 {
    1028         561 :                         if (sanitizedExpression.size() == 0)
    1029             :                         {
    1030           0 :                                 sanitizedExpression += String("LR");
    1031             :                         }
    1032             :                         else
    1033             :                         {
    1034         561 :                                 sanitizedExpression += String(",LR");
    1035             :                         }
    1036             :                 }
    1037             :                 else
    1038             :                 {
    1039           1 :                         didSanitize = true;
    1040           1 :                         *logger_p << LogIO::WARN <<  "Correlation product [LR] not available " << LogIO::POST;
    1041             :                 }
    1042             :         }
    1043             : 
    1044         594 :         if (corrExpression.find("XX") != string::npos)
    1045             :         {
    1046          13 :                 if (std::find(corrProducts->begin(),corrProducts->end(),String("XX")) != corrProducts->end())
    1047             :                 {
    1048          12 :                         if (sanitizedExpression.size() == 0)
    1049             :                         {
    1050          12 :                                 sanitizedExpression += String("XX");
    1051             :                         }
    1052             :                         else
    1053             :                         {
    1054           0 :                                 sanitizedExpression += String(",XX");
    1055             :                         }
    1056             :                 }
    1057             :                 else
    1058             :                 {
    1059           1 :                         didSanitize = true;
    1060           1 :                         *logger_p << LogIO::WARN <<  "Correlation product [XX] not available " << LogIO::POST;
    1061             :                 }
    1062             :         }
    1063             : 
    1064         594 :         if (corrExpression.find("YY") != string::npos)
    1065             :         {
    1066           2 :                 if (std::find(corrProducts->begin(),corrProducts->end(),String("YY")) != corrProducts->end())
    1067             :                 {
    1068           2 :                         if (sanitizedExpression.size() == 0)
    1069             :                         {
    1070           2 :                                 sanitizedExpression += String("YY");
    1071             :                         }
    1072             :                         else
    1073             :                         {
    1074           0 :                                 sanitizedExpression += String(",YY");
    1075             :                         }
    1076             :                 }
    1077             :                 else
    1078             :                 {
    1079           0 :                         didSanitize = true;
    1080           0 :                         *logger_p << LogIO::WARN <<  "Correlation product [YY] not available " << LogIO::POST;
    1081             :                 }
    1082             :         }
    1083             : 
    1084         594 :         if (corrExpression.find("XY") != string::npos)
    1085             :         {
    1086           2 :                 if (std::find(corrProducts->begin(),corrProducts->end(),String("XY")) != corrProducts->end())
    1087             :                 {
    1088           2 :                         if (sanitizedExpression.size() == 0)
    1089             :                         {
    1090           0 :                                 sanitizedExpression += String("XY");
    1091             :                         }
    1092             :                         else
    1093             :                         {
    1094           2 :                                 sanitizedExpression += String(",XY");
    1095             :                         }
    1096             :                 }
    1097             :                 else
    1098             :                 {
    1099           0 :                         didSanitize = true;
    1100           0 :                         *logger_p << LogIO::WARN <<  "Correlation product [XY] not available " << LogIO::POST;
    1101             :                 }
    1102             :         }
    1103             : 
    1104         594 :         if (corrExpression.find("YX") != string::npos)
    1105             :         {
    1106           3 :                 if (std::find(corrProducts->begin(),corrProducts->end(),String("YX")) != corrProducts->end())
    1107             :                 {
    1108           3 :                         if (sanitizedExpression.size() == 0)
    1109             :                         {
    1110           0 :                                 sanitizedExpression += String("YX");
    1111             :                         }
    1112             :                         else
    1113             :                         {
    1114           3 :                                 sanitizedExpression += String(",YX");
    1115             :                         }
    1116             :                 }
    1117             :                 else
    1118             :                 {
    1119           0 :                         didSanitize = true;
    1120           0 :                         *logger_p << LogIO::WARN <<  "Correlation product [YX] not available " << LogIO::POST;
    1121             :                 }
    1122             :         }
    1123             : 
    1124         594 :         if (corrExpression.find("I") != string::npos)
    1125             :         {
    1126           1 :                 if (std::find(corrProducts->begin(),corrProducts->end(),String("I")) != corrProducts->end())
    1127             :                 {
    1128           1 :                         if (sanitizedExpression.size() == 0)
    1129             :                         {
    1130           1 :                                 sanitizedExpression += String("I");
    1131             :                         }
    1132             :                         else
    1133             :                         {
    1134           0 :                                 sanitizedExpression += String(",I");
    1135             :                         }
    1136             :                 }
    1137             :                 else
    1138             :                 {
    1139           0 :                         didSanitize = true;
    1140           0 :                         *logger_p << LogIO::WARN <<  "Correlation product [I] not available " << LogIO::POST;
    1141             :                 }
    1142             :         }
    1143             : 
    1144         594 :         if ( (didSanitize) and (sanitizedExpression.size() > 0) )
    1145             :         {
    1146           3 :                 *logger_p << LogIO::NORMAL <<  "Sanitized correlation expression is: " << sanitizedExpression << LogIO::POST;
    1147             :         }
    1148             : 
    1149             : 
    1150         594 :         return sanitizedExpression;
    1151             : }
    1152             : 
    1153             : void
    1154        2251 : FlagAgentBase::setAgentParameters(Record config)
    1155             : {
    1156             :         // NOTE: This method must be re-implemented in the derived classes for
    1157             :         // the specific parameters although here we handle the common ones
    1158             : 
    1159             :         int exists;
    1160             : 
    1161             :     // Retrieve agent name
    1162        2251 :     exists = config.fieldNumber ("agentname");
    1163        2251 :     if (exists >= 0)
    1164             :     {
    1165        2251 :         agentName_p = config.asString("agentname");
    1166             :     }
    1167           0 :     else if (agentName_p.empty())
    1168             :     {
    1169           0 :         agentName_p = "FlagAgentUnknown";
    1170             :     }
    1171        2251 :     logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
    1172             : 
    1173             :     // Retrieve name for summary report
    1174        2251 :     exists = config.fieldNumber ("name");
    1175        2251 :     if (exists >= 0)
    1176             :     {
    1177         397 :         summaryName_p = config.asString("name");
    1178             :     }
    1179        1854 :     else if (summaryName_p.empty())
    1180             :     {
    1181        1854 :         summaryName_p = agentName_p;
    1182             :     }
    1183             : 
    1184             :         // Retrieve mode
    1185        2251 :         exists = config.fieldNumber ("mode");
    1186        2251 :         if (config.fieldNumber ("mode") >= 0)
    1187             :         {
    1188        2251 :                 mode_p = config.asString("mode");
    1189             :         }
    1190             :         else
    1191             :         {
    1192           0 :                 mode_p = config.asString("manual");
    1193           0 :                 *logger_p << LogIO::WARN << " Mode not specified, defaulting to manual" << LogIO::POST;
    1194             :         }
    1195             : 
    1196        2251 :         exists = config.fieldNumber ("nThreads");
    1197        2251 :         if (exists >= 0)
    1198             :         {
    1199           0 :                 nThreads_p = atoi(config.asString("nThreads").c_str());
    1200           0 :                 *logger_p << logLevel_p << " nThreads is " << nThreads_p << LogIO::POST;
    1201             : 
    1202           0 :                 if (nThreads_p > 0)
    1203             :                 {
    1204           0 :                         multiThreading_p = true;
    1205           0 :                         exists = config.fieldNumber ("threadId");
    1206           0 :                         if (exists >= 0)
    1207             :                         {
    1208           0 :                                 threadId_p = atoi(config.asString("threadId").c_str());
    1209           0 :                                 *logger_p << logLevel_p << " threadId is " << threadId_p << LogIO::POST;
    1210             : 
    1211           0 :                                 if (threadId_p < 0 or threadId_p>=nThreads_p)
    1212             :                                 {
    1213           0 :                                         *logger_p << LogIO::WARN << " Thread Id range is [0,nThreads-1], disabling multithreading" << LogIO::POST;
    1214             :                                 }
    1215             :                         }
    1216             :                         else
    1217             :                         {
    1218           0 :                                 *logger_p << LogIO::WARN << " Thread Id not provided, disabling multithreading" << LogIO::POST;
    1219           0 :                                 multiThreading_p = false;
    1220             :                         }
    1221             :                 }
    1222             :                 else
    1223             :                 {
    1224           0 :                         *logger_p << LogIO::WARN << " Number of threads must be positive, disabling multithreading" << LogIO::POST;
    1225           0 :                         dataColumn_p = "data";
    1226             :                 }
    1227             :         }
    1228             : 
    1229             : 
    1230        2251 :         if (    (iterationApproach_p == IN_ROWS) or
    1231        2145 :                         (iterationApproach_p == ANTENNA_PAIRS) or
    1232        2006 :                         (iterationApproach_p == ANTENNA_PAIRS_INTERACTIVE) or
    1233        2006 :                         (iterationApproach_p == IN_ROWS_PREPROCESS_BUFFER) or
    1234        2006 :                         (iterationApproach_p == ANTENNA_PAIRS_PREPROCESS_BUFFER))
    1235             :         {
    1236             : 
    1237         245 :                 exists = config.fieldNumber ("datacolumn");
    1238         245 :                 if (exists >= 0)
    1239             :                 {
    1240         245 :                         dataColumn_p = config.asString("datacolumn");
    1241             :                 }
    1242           0 :                 else if (flagDataHandler_p->tableTye_p == FlagDataHandler::MEASUREMENT_SET)
    1243             :                 {
    1244           0 :                         dataColumn_p = "data";
    1245             :                 }
    1246             :                 else
    1247             :                 {
    1248           0 :                         dataColumn_p = "fparam";
    1249             :                 }
    1250             : 
    1251         245 :                 dataColumn_p.upcase();
    1252             : 
    1253             :                 // Check if dataColumn_p is one of the supported columns (or residues)
    1254         245 :                 if (dataColumn_p.compare("DATA") == 0)
    1255             :                 {
    1256         175 :                         dataReference_p = DATA;
    1257             : 
    1258             :                         // Request to pre-load ObservedCube
    1259         175 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::VisibilityCubeObserved);
    1260             :                 }
    1261          70 :                 else if (dataColumn_p.compare("CORRECTED") == 0)
    1262             :                 {
    1263           1 :                         dataReference_p = CORRECTED;
    1264             : 
    1265             :                         // Request to pre-load CorrectedCube
    1266           1 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::VisibilityCubeCorrected);
    1267             :                 }
    1268          69 :                 else if (dataColumn_p.compare("MODEL") == 0)
    1269             :                 {
    1270           0 :                         dataReference_p = MODEL;
    1271             : 
    1272             :                         // Request to pre-load ModelCube
    1273           0 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::VisibilityCubeModel);
    1274             :                 }
    1275          69 :                 else if (dataColumn_p.compare("RESIDUAL") == 0)
    1276             :                 {
    1277           7 :                         dataReference_p = RESIDUAL;
    1278             : 
    1279             :                         // Request to pre-load CorrectedCube and ModelCube
    1280           7 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::VisibilityCubeCorrected);
    1281           7 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::VisibilityCubeModel);
    1282             :                 }
    1283          62 :                 else if (dataColumn_p.compare("RESIDUAL_DATA") == 0)
    1284             :                 {
    1285           7 :                         dataReference_p = RESIDUAL_DATA;
    1286             : 
    1287             :                         // Request to pre-load ObservedCube and ModelCube
    1288           7 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::VisibilityCubeObserved);
    1289           7 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::VisibilityCubeModel);
    1290             :                 }
    1291          55 :                 else if (dataColumn_p.compare("FPARAM") == 0)
    1292             :                 {
    1293          13 :                         dataReference_p = DATA;
    1294             : 
    1295             :                         // Request to pre-load ObservedCube
    1296          13 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::VisibilityCubeObserved);
    1297             :                 }
    1298          42 :                 else if (dataColumn_p.compare("CPARAM") == 0)
    1299             :                 {
    1300          21 :                         dataReference_p = CORRECTED;
    1301             : 
    1302             :                         // Request to pre-load CorrectedCube
    1303          21 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::VisibilityCubeCorrected);
    1304             :                 }
    1305          21 :                 else if (dataColumn_p.compare("SNR") == 0)
    1306             :                 {
    1307           4 :                         dataReference_p = MODEL;
    1308             : 
    1309             :                         // Request to pre-load ModelCube
    1310           4 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::VisibilityCubeModel);
    1311             :                 }
    1312          17 :                 else if (dataColumn_p.compare("WEIGHT_SPECTRUM") == 0)
    1313             :                 {
    1314           7 :                         dataReference_p = WEIGHT_SPECTRUM;
    1315             : 
    1316             :                         // Request to pre-load WeightSpectrum
    1317           7 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::WeightSpectrum);
    1318             :                 }
    1319          10 :                 else if (dataColumn_p.compare("WEIGHT") == 0)
    1320             :                 {
    1321           5 :                         dataReference_p = WEIGHT_SPECTRUM;
    1322             : 
    1323             :                         // Request to pre-load WeightSpectrum instead of Weight
    1324           5 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::WeightSpectrum);
    1325             :                 }
    1326           5 :                 else if (dataColumn_p.compare("FLOAT_DATA") == 0)
    1327             : 
    1328             :                 {
    1329           5 :                         dataReference_p = DATA;
    1330             : 
    1331             :                         // Request to pre-load ObservedCube
    1332           5 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::VisibilityCubeObserved);
    1333             :                 }
    1334             :                 else
    1335             :                 {
    1336           0 :                         *logger_p << LogIO::WARN <<
    1337             :                                         " Unsupported data column: " <<
    1338           0 :                                         dataColumn_p << ", using data by default. Supported columns: data,corrected,model,residual,residual_data" << LogIO::POST;
    1339           0 :                         dataColumn_p = "data";
    1340             : 
    1341             :                         // Request to pre-load ObservedCube
    1342           0 :                         flagDataHandler_p->preLoadColumn(VisBufferComponent2::VisibilityCubeObserved);
    1343             :                 }
    1344             : 
    1345         245 :                 *logger_p << logLevel_p << " data column is " << dataColumn_p << LogIO::POST;
    1346             : 
    1347             :                 // Check if user provided an expression
    1348         245 :                 exists = config.fieldNumber ("correlation");
    1349         245 :                 if (exists >= 0)
    1350             :                 {
    1351         125 :                         expression_p = config.asString("correlation");
    1352             :                 }
    1353         225 :                 else if (flagDataHandler_p->tableTye_p == FlagDataHandler::MEASUREMENT_SET and
    1354         105 :                         dataColumn_p.compare("FLOAT_DATA") == 0)
    1355             :                 {
    1356           2 :                     expression_p = "REAL ALL";
    1357             :                 }
    1358         118 :                 else if (flagDataHandler_p->tableTye_p == FlagDataHandler::MEASUREMENT_SET)
    1359             :                 {
    1360         103 :                         expression_p = "ABS ALL";
    1361             :                 }
    1362          15 :                 else if (dataColumn_p.compare("CPARAM") == 0)
    1363             :                 {
    1364             :                         // CPARAM is a complex column
    1365           7 :                         expression_p = "ABS ALL";
    1366             :                 }
    1367             :                 else {
    1368           8 :                         expression_p = "REAL ALL";
    1369             :                 }
    1370             : 
    1371             :                 // Replace empty correlation with default
    1372         245 :                 if (expression_p.compare("") == 0)
    1373           0 :                         expression_p = "ALL";
    1374             : 
    1375         245 :                 expression_p.upcase();
    1376             : 
    1377             :                 // These are the float columns that do not support complex operators
    1378             :                 // It should fall back to the default REAL
    1379         477 :                 if (    (dataColumn_p.compare("FPARAM") == 0) or
    1380         460 :                                 (dataColumn_p.compare("SNR") == 0) or
    1381         449 :                                 (dataColumn_p.compare("WEIGHT_SPECTRUM") == 0) or
    1382         698 :                                 (dataColumn_p.compare("WEIGHT") == 0) or
    1383         216 :                                 (dataColumn_p.compare("FLOAT_DATA") == 0))
    1384             :                 {
    1385             :                         // Check if expression is one of the supported operators
    1386          68 :                         if (    (expression_p.find("IMAG") != string::npos) or
    1387          68 :                                         (expression_p.find("ARG") != string::npos) or
    1388         102 :                                         (expression_p.find("ABS") != string::npos) or
    1389          19 :                                         (expression_p.find("NORM") != string::npos))
    1390             :                         {
    1391          15 :                                 *logger_p       << LogIO::WARN
    1392          15 :                                                         << " Unsupported visibility expression: " << expression_p
    1393             :                                                         << "; selecting REAL by default. "
    1394             :                                                         << " Complex operators are not supported for FLOAT_DATA/FPARAM/SNR/WEIGHT_SPECTRUM/WEIGHT"
    1395          15 :                                                         << LogIO::POST;
    1396             : 
    1397          15 :                                 String new_expression;
    1398          15 :                                 if (expression_p.find("_") != string::npos)
    1399           5 :                                         new_expression = expression_p.after("_");
    1400             :                                 else
    1401          10 :                                         new_expression = expression_p.after(" ");
    1402             : 
    1403          15 :                                 expression_p = "REAL " + new_expression;
    1404             :                         }
    1405          19 :                         else if (expression_p.find("REAL") == string::npos)
    1406             :                         {
    1407           6 :                                 expression_p = "REAL " + expression_p;
    1408             :                         }
    1409             :                 }
    1410             :                 else
    1411             :                 {
    1412             :                         // Check if expression is one of the supported operators
    1413         420 :                         if ((expression_p.find("REAL") == string::npos) and
    1414         418 :                                         (expression_p.find("IMAG") == string::npos) and
    1415         418 :                                         (expression_p.find("ARG") == string::npos) and
    1416         218 :                                         (expression_p.find("ABS") == string::npos) and
    1417         429 :                                         (expression_p.find("NORM") == string::npos) and
    1418             :                                         // jagonzal: Rflag does not need complex operator
    1419           8 :                                         (mode_p.find("rflag") == string::npos) )
    1420             :                         {
    1421           6 :                                 *logger_p       << LogIO::WARN
    1422           6 :                                                         << " Unsupported complex operator: " << expression_p
    1423             :                                                         << "; using ABS by default. "
    1424             :                                                         << " Supported expressions: REAL,IMAG,ARG,ABS,NORM."
    1425           6 :                                                         << LogIO::POST;
    1426           6 :                                 expression_p = "ABS " + expression_p;
    1427             :                         }
    1428             :                 }
    1429             : 
    1430             : 
    1431             :                 // Replace "ALL" by applicable correlations
    1432         245 :                 if (expression_p.find("ALL") != string::npos)
    1433             :                 {
    1434         126 :                         if (expression_p.find("REAL") != string::npos)
    1435             :                         {
    1436          21 :                                 expression_p = String("REAL ");
    1437             :                         }
    1438         105 :                         else if (expression_p.find("IMAG") != string::npos)
    1439             :                         {
    1440           0 :                                 expression_p = String("IMAG ");
    1441             :                         }
    1442         105 :                         else if (expression_p.find("ARG") != string::npos)
    1443             :                         {
    1444           0 :                                 expression_p = String("ARG ");
    1445             :                         }
    1446         105 :                         else if (expression_p.find("ABS") != string::npos)
    1447             :                         {
    1448         105 :                                 expression_p = String("ABS ");
    1449             :                         }
    1450           0 :                         else if (expression_p.find("NORM") != string::npos)
    1451             :                         {
    1452           0 :                                 expression_p = String("NORM ");
    1453             :                         }
    1454             : 
    1455         126 :                         bool expressionInitialized = false;
    1456         571 :                         for (uInt corr_i=0;corr_i<flagDataHandler_p->corrProducts_p->size();corr_i++)
    1457             :                         {
    1458             :                                 // jagonzal (CAS-4234): Now we have the I corr product in the list
    1459             :                                 // but we have to skip it when expanding the "ABS ALL" expressions
    1460             :                                 // because the user must specify WVR implicitly
    1461         445 :                                 if (flagDataHandler_p->corrProducts_p->at(corr_i) != "I")
    1462             :                                 {
    1463         444 :                                         if (expressionInitialized)
    1464             :                                         {
    1465         318 :                                                 expression_p += String(",") + flagDataHandler_p->corrProducts_p->at(corr_i);
    1466             :                                         }
    1467             :                                         else
    1468             :                                         {
    1469         126 :                                                 expression_p += flagDataHandler_p->corrProducts_p->at(corr_i);
    1470         126 :                                                 expressionInitialized = true;
    1471             :                                         }
    1472             :                                 }
    1473             :                         }
    1474             :                 }
    1475             : 
    1476         245 :                 expression_p.upcase();
    1477             : 
    1478         245 :                 *logger_p << logLevel_p << " Visibility expression is " << expression_p << LogIO::POST;
    1479             : 
    1480             :                 // Request to pre-load spw and corrType
    1481         245 :                 flagDataHandler_p->preLoadColumn(VisBufferComponent2::SpectralWindows);
    1482         245 :                 flagDataHandler_p->preLoadColumn(VisBufferComponent2::CorrType);
    1483             : 
    1484             :         }
    1485             : 
    1486        2251 :         exists = config.fieldNumber ("autocorr");
    1487        2251 :         if (exists >= 0)
    1488             :         {
    1489         138 :                 flagAutoCorrelations_p = config.asBool("autocorr");
    1490         138 :                 *logger_p << logLevel_p << "autocorr is " << flagAutoCorrelations_p
    1491         138 :                                 << LogIO::POST;
    1492         138 :                 if (flagAutoCorrelations_p) {
    1493           8 :                         filterRows_p=true;
    1494           8 :                         *logger_p << logLevel_p << "Will only apply auto-correlation flagging to data with processor==CORRELATOR"
    1495           8 :                                         << LogIO::POST;
    1496             :                 }
    1497             :         }
    1498             : 
    1499             :         // Channel average parameters
    1500        2251 :         exists = config.fieldNumber ("channelavg");
    1501        2251 :         if (exists >= 0)
    1502             :         {
    1503         201 :                 if( config.type(exists) != TpBool )
    1504             :                 {
    1505           0 :                         throw( AipsError ( "Parameter 'channelavg' must be of type 'bool'" ) );
    1506             :                 }
    1507             : 
    1508         201 :                 channelavg_p = config.asBool("channelavg");
    1509             :         }
    1510             :         else
    1511             :         {
    1512        2050 :                 channelavg_p = false;
    1513             :         }
    1514             : 
    1515             : 
    1516        2251 :         if (channelavg_p)
    1517             :         {
    1518          33 :                 exists = config.fieldNumber ("chanbin");
    1519          33 :                 if (exists >= 0)
    1520             :                 {
    1521          33 :                         if ( config.type(exists) == casacore::TpInt )
    1522             :                         {
    1523             :                                 Int chanbin;
    1524          33 :                                 config.get (exists, chanbin);
    1525          33 :                                 chanbin_p = Vector<Int>(1,chanbin);
    1526             :                         }
    1527           0 :                         else if ( config.type(exists) == casacore::TpArrayInt)
    1528             :                         {
    1529           0 :                                 config.get (exists, chanbin_p);
    1530             :                         }
    1531             :                         else
    1532             :                         {
    1533           0 :                                 *logger_p       << LogIO::WARN
    1534             :                                                         << "Wrong format for chanbin parameter "
    1535           0 :                                                         << " (only Int and arrayInt are supported)" << LogIO::POST;
    1536             :                         }
    1537             : 
    1538          33 :                         *logger_p       << LogIO::NORMAL << "Channel average bin is " << chanbin_p << LogIO::POST;
    1539             :                 }
    1540             :         }
    1541             : 
    1542             : 
    1543             :         // Time average parameters
    1544        2251 :     exists = config.fieldNumber ("timeavg");
    1545        2251 :     if (exists >= 0)
    1546             :     {
    1547         204 :         if( config.type(exists) != TpBool )
    1548             :         {
    1549           0 :             throw( AipsError ( "Parameter 'timeavg' must be of type 'bool'" ) );
    1550             :         }
    1551             : 
    1552         204 :         timeavg_p = config.asBool("timeavg");
    1553             : 
    1554             :     }
    1555             :     else
    1556             :     {
    1557        2047 :         timeavg_p = false;
    1558             :     }
    1559             : 
    1560        2251 :     if (timeavg_p)
    1561             :     {
    1562          32 :         exists = config.fieldNumber ("timebin");
    1563          32 :         if (exists >= 0)
    1564             :         {
    1565          32 :             String timebin;
    1566          32 :             config.get(exists, timebin);
    1567          32 :             timebin_p = casaQuantity(timebin).get("s").getValue();
    1568             :         }
    1569             : 
    1570          32 :                 *logger_p       << LogIO::NORMAL << "Time average bin is " << timebin_p << LogIO::POST;
    1571             : 
    1572             :      }
    1573             : 
    1574        2251 :         return;
    1575             : }
    1576             : 
    1577             : void
    1578      567914 : FlagAgentBase::generateAllIndex()
    1579             : {
    1580             :         Int nPolarizations,nChannels,nRows;
    1581      567914 :         commonFlagCube_p->shape(nPolarizations,nChannels,nRows);
    1582      567914 :         generateRowsIndex(nRows);
    1583      567914 :         generateChannelIndex(nChannels);
    1584      567914 :         generatePolarizationIndex(nPolarizations);
    1585             : 
    1586     1135828 :         return;
    1587             : }
    1588             : 
    1589             : void
    1590      567914 : FlagAgentBase::generateRowsIndex(uInt nRows)
    1591             : {
    1592             :         // For uvw range filter
    1593     1135828 :         Matrix<Double> uvw;
    1594             : 
    1595      567914 :         rowsIndex_p.clear();
    1596      567914 :         if (filterRows_p)
    1597             :         {
    1598             :                 Double u,v,uvDistance;
    1599     4109129 :                 for (uInt row_i=0;row_i<nRows;row_i++)
    1600             :                 {
    1601             :                         // Check observation id
    1602     4060821 :                         if ((observationList_p.size()>0) and (find(flagDataHandler_p->sortOrder_p,MS::OBSERVATION_ID)==false) )
    1603             :                         {
    1604           0 :                                 if (!find(observationList_p,visibilityBuffer_p->observationId()[row_i])) continue;
    1605             :                         }
    1606             : 
    1607             :                         // Check scan intent
    1608     4060821 :                         if (scanIntentList_p.size())
    1609             :                         {
    1610        3604 :                                 if (!find(scanIntentList_p,visibilityBuffer_p->stateId()[row_i])) continue;
    1611             :                         }
    1612             : 
    1613             :                         // Check scan id
    1614     4058925 :                         if ( (scanList_p.size()>0) and (find(flagDataHandler_p->sortOrder_p,MS::SCAN_NUMBER)==false) )
    1615             :                         {
    1616           0 :                                 if (!find(scanList_p,visibilityBuffer_p->scan()[row_i])) continue;
    1617             :                         }
    1618             : 
    1619             :                         // Check time range
    1620     4058925 :                         if ( (timeList_p.size()>0) and (flagDataHandler_p->groupTimeSteps_p==true) )
    1621             :                         {
    1622           0 :                                 if (!find(timeList_p,visibilityBuffer_p->time()[row_i])) continue;
    1623             :                         }
    1624             : 
    1625             :                         // Check baseline
    1626     4058925 :                         if (baselineList_p.size() and (flagDataHandler_p->tableTye_p == FlagDataHandler::MEASUREMENT_SET))
    1627             :                         {
    1628     2599014 :                                 if (!find(baselineList_p,visibilityBuffer_p->antenna1()[row_i],visibilityBuffer_p->antenna2()[row_i])) continue;
    1629             :                         }
    1630     1459911 :                         else if (antenna1List_p.size() and (flagDataHandler_p->tableTye_p == FlagDataHandler::CALIBRATION_TABLE))
    1631             :                         {
    1632         750 :                                 if (!find(antenna1List_p,visibilityBuffer_p->antenna1()[row_i])) continue;
    1633             :                         }
    1634             : 
    1635             :                         // Check uvw range
    1636     1673982 :                         if (uvwList_p.size())
    1637             :                         {
    1638             :                                 // NOTE: uvw from vis buffer is in meters, so we only support uv distance
    1639             :                                 // (MS Selection does not return normalized ranges)
    1640       17184 :                                 uvw = visibilityBuffer_p->uvw();
    1641       17184 :                                 u = uvw(0,row_i);
    1642       17184 :                                 v = uvw(1,row_i);
    1643       17184 :                                 uvDistance = sqrt(u*u + v*v);
    1644             : 
    1645             :                                 // CAS-4270: Convert uvdist in lambda units
    1646       17184 :                                 if (uvwUnits_p == false)
    1647             :                                 {
    1648       17184 :                                         Int spw = visibilityBuffer_p->spectralWindows()(0);
    1649       17184 :                                         Double Lambda = (*flagDataHandler_p->getLambdaMap())[spw];
    1650       17184 :                                         uvDistance /= Lambda;
    1651             :                                 }
    1652             : 
    1653       17184 :                                 if (!find(uvwList_p,uvDistance)) continue;
    1654             :                         }
    1655             : 
    1656             :                         // Check auto-correlations
    1657     1662526 :                         if (flagAutoCorrelations_p)
    1658             :                         {
    1659             :                                 // if not an auto-corr, do not add row to the vector
    1660       60982 :                                 if (visibilityBuffer_p->antenna1()[row_i] != visibilityBuffer_p->antenna2()[row_i]) {
    1661       54906 :                                         continue;
    1662             :                                 }
    1663             :                                 // Only for MSs, not for cal tables
    1664        6076 :                                 if (flagDataHandler_p->tableTye_p == FlagDataHandler::MEASUREMENT_SET){
    1665             : 
    1666             :                                         // CAS-5286: only flag auto-corrs when processor TYPE is CORRELATOR
    1667        6076 :                                         int proc_id = visibilityBuffer_p->processorId()[row_i];
    1668             : 
    1669        8159 :                                         if (flagDataHandler_p->processorTableExist_p == true and
    1670        2083 :                                                         flagDataHandler_p->isCorrelatorType_p(proc_id) == false){
    1671             :                                                 // skip non-CORRELATOR data
    1672        1819 :                                                 continue;
    1673             :                                         }
    1674             :                                 }
    1675             : 
    1676             :                         }
    1677             : 
    1678             :                         // If all the filters passed, add the row to the list
    1679     1605801 :                         rowsIndex_p.push_back(row_i);
    1680             :                 }
    1681             : 
    1682             :         }
    1683             :         else
    1684             :         {
    1685      519606 :                 indigen(rowsIndex_p,nRows);
    1686             :         }
    1687             : 
    1688     1135828 :         return;
    1689             : }
    1690             : 
    1691             : void
    1692      567914 : FlagAgentBase::generateChannelIndex(uInt nChannels)
    1693             : {
    1694      567914 :         channelIndex_p.clear();
    1695      567914 :         if (filterChannels_p)
    1696             :         {
    1697             :                 // First find channel start and stop for this spw
    1698       38196 :                 Int currentSpw = visibilityBuffer_p->spectralWindows()(0);
    1699             :                 Int nSpw,width;
    1700       38196 :                 uInt channelStart = 0,channelStop = UINT_MAX;
    1701       38196 :                 channelList_p.shape(nSpw,width);
    1702      135548 :                 for (uShort spw_i=0;spw_i<nSpw;spw_i++)
    1703             :                 {
    1704       97352 :                         if (channelList_p(spw_i,0) == currentSpw)
    1705             :                         {
    1706       37269 :                                 channelStart = channelList_p(spw_i,1);
    1707       37269 :                                 channelStop = channelList_p(spw_i,2);
    1708     2207446 :                                 for (uInt channel_i=0;channel_i<nChannels;channel_i++)
    1709             :                                 {
    1710     2170177 :                                         if ((channel_i>=channelStart) and (channel_i<=channelStop)) channelIndex_p.push_back(channel_i);
    1711             :                                 }
    1712             :                         }
    1713             :                 }
    1714             :         }
    1715             :         else
    1716             :         {
    1717      529718 :                 indigen(channelIndex_p,nChannels);
    1718             :         }
    1719             : 
    1720      567914 :         return;
    1721             : }
    1722             : 
    1723             : void
    1724      567914 : FlagAgentBase::generatePolarizationIndex(uInt nPolarizations)
    1725             : {
    1726      567914 :         polarizationIndex_p.clear();
    1727      567914 :         if (filterPols_p)
    1728             :         {
    1729             :                 // NOTE: Polarization ID should be accessible from the visibility buffer
    1730             :                 // but this functionality is not implemented yet, therefore we are getting
    1731             :                 // it from the RW Visibility Iterator which is always a conventional one
    1732             :                 // (not asyn I/O which does not implement it)
    1733       22223 :                 Int polId = visibilityBuffer_p->polarizationId();
    1734             : 
    1735             :                 // This will be empty when the 'correlation=' selection takes only
    1736             :                 // polarizations that are not present in the current SPW.
    1737       22223 :                 const auto &polarizations = polarizationList_p[polId];
    1738             : 
    1739             :                 // Get accepted polarizations
    1740       91653 :                 for (uInt polarization_i=0;polarization_i<nPolarizations;polarization_i++)
    1741             :                 {
    1742       69430 :                         if (!find(polarizations,polarization_i)) continue;
    1743       39582 :                         polarizationIndex_p.push_back(polarization_i);
    1744             :                 }
    1745             : 
    1746             :         }
    1747             :         else
    1748             :         {
    1749      545691 :                 indigen(polarizationIndex_p,nPolarizations);
    1750             :         }
    1751             : 
    1752      567914 :         return;
    1753             : }
    1754             : 
    1755             : std::vector<uInt> *
    1756       22399 : FlagAgentBase::generateAntennaPairRowsIndex(Int antenna1, Int antenna2)
    1757             : {
    1758             :         // Retrieve common rows for this antenna pair from FlagDataHandler
    1759       22399 :         std::vector<uInt> commonRows = (*flagDataHandler_p->getAntennaPairMap())[std::make_pair(antenna1,antenna2)];
    1760             : 
    1761             :         // Second step: Filter out unnecessary rows
    1762       22399 :         std::vector<uInt> *privateRows = NULL;
    1763       22399 :         if (filterRows_p)
    1764             :         {
    1765        1368 :                 privateRows = new std::vector<uInt>();
    1766      108558 :                 for (std::vector<uInt>::iterator iter=commonRows.begin();iter!=commonRows.end();iter++)
    1767             :                 {
    1768      107190 :                         if (std::find(rowsIndex_p.begin(),rowsIndex_p.end(),*iter) != rowsIndex_p.end())
    1769             :                         {
    1770      107190 :                                 privateRows->push_back(*iter);
    1771             :                         }
    1772             :                 }
    1773             :         }
    1774             :         else
    1775             :         {
    1776       21031 :                 privateRows = new std::vector<uInt>((*flagDataHandler_p->getAntennaPairMap())[std::make_pair(antenna1,antenna2)]);
    1777             :         }
    1778             : 
    1779       44798 :         return privateRows;
    1780             : }
    1781             : 
    1782             : void
    1783     1595015 : FlagAgentBase::indigen(vector<uInt> &index, uInt size)
    1784             : {
    1785     1595015 :         index.reserve(size);
    1786    49839711 :         for (uInt i=0; i<size; i++ )
    1787             :         {
    1788    48244696 :                 index.push_back(i);
    1789             :         }
    1790             : 
    1791     1595015 :         return;
    1792             : }
    1793             : 
    1794             : bool
    1795           0 : FlagAgentBase::isZero(Float number)
    1796             : {
    1797           0 :         int type = std::fpclassify(number);
    1798           0 :         switch (type)
    1799             :         {
    1800           0 :                 case FP_NORMAL:
    1801           0 :                         if (number <= FLT_MIN)
    1802             :                         {
    1803           0 :                                 return true;
    1804             :                         }
    1805             :                         else
    1806             :                         {
    1807           0 :                                 return false;
    1808             :                         }
    1809           0 :                 case FP_ZERO:
    1810           0 :                         return true;
    1811           0 :                 case FP_SUBNORMAL:
    1812           0 :                         return true;
    1813           0 :                 case FP_INFINITE:
    1814           0 :                         return false;
    1815           0 :                 case FP_NAN:
    1816           0 :                         return false;
    1817           0 :                 default:
    1818           0 :                         return false;
    1819             :         }
    1820             : }
    1821             : 
    1822             : bool
    1823           0 : FlagAgentBase::isZero(Double number)
    1824             : {
    1825           0 :         int type = std::fpclassify(number);
    1826           0 :         switch (type)
    1827             :         {
    1828           0 :                 case FP_NORMAL:
    1829           0 :                         if (number <= FLT_EPSILON)
    1830             :                         {
    1831           0 :                                 return true;
    1832             :                         }
    1833             :                         else
    1834             :                         {
    1835           0 :                                 return false;
    1836             :                         }
    1837           0 :                 case FP_ZERO:
    1838           0 :                         return true;
    1839           0 :                 case FP_SUBNORMAL:
    1840           0 :                         return true;
    1841           0 :                 case FP_INFINITE:
    1842           0 :                         return false;
    1843           0 :                 case FP_NAN:
    1844           0 :                         return false;
    1845           0 :                 default:
    1846           0 :                         return false;
    1847             :         }
    1848             : }
    1849             : 
    1850             : bool
    1851    46037687 : FlagAgentBase::isNaN(Float number)
    1852             : {
    1853    46037687 :         int type = std::fpclassify(number);
    1854    46037687 :         switch (type)
    1855             :         {
    1856    44821538 :                 case FP_NORMAL:
    1857    44821538 :                         return false;
    1858     1175357 :                 case FP_ZERO:
    1859     1175357 :                         return false;
    1860       40792 :                 case FP_SUBNORMAL:
    1861       40792 :                         return false;
    1862           0 :                 case FP_INFINITE:
    1863           0 :                         chunkNaNs_p += 1;
    1864           0 :                         return true;
    1865           0 :                 case FP_NAN:
    1866           0 :                         chunkNaNs_p += 1;
    1867           0 :                         return true;
    1868           0 :                 default:
    1869           0 :                         chunkNaNs_p += 1;
    1870           0 :                         return true;
    1871             :         }
    1872             : }
    1873             : 
    1874             : bool
    1875           0 : FlagAgentBase::isNaN(Double number)
    1876             : {
    1877           0 :         int type = std::fpclassify(number);
    1878           0 :         switch (type)
    1879             :         {
    1880           0 :                 case FP_NORMAL:
    1881           0 :                         return false;
    1882           0 :                 case FP_ZERO:
    1883           0 :                         return false;
    1884           0 :                 case FP_SUBNORMAL:
    1885           0 :                         return false;
    1886           0 :                 case FP_INFINITE:
    1887           0 :                         chunkNaNs_p += 1;
    1888           0 :                         return true;
    1889           0 :                 case FP_NAN:
    1890           0 :                         chunkNaNs_p += 1;
    1891           0 :                         return true;
    1892           0 :                 default:
    1893           0 :                         chunkNaNs_p += 1;
    1894           0 :                         return true;
    1895             :         }
    1896             : }
    1897             : 
    1898             : bool
    1899    60993357 : FlagAgentBase::isNaNOrZero(Float number)
    1900             : {
    1901    60993357 :         int type = std::fpclassify(number);
    1902    60993357 :         switch (type)
    1903             :         {
    1904    59964092 :                 case FP_NORMAL:
    1905    59964092 :                         if (number <= FLT_EPSILON)
    1906             :                         {
    1907        7629 :                                 return true;
    1908             :                         }
    1909             :                         else
    1910             :                         {
    1911    59956463 :                                 return false;
    1912             :                         }
    1913      965238 :                 case FP_ZERO:
    1914      965238 :                         return true;
    1915       64027 :                 case FP_SUBNORMAL:
    1916       64027 :                         return true;
    1917           0 :                 case FP_INFINITE:
    1918           0 :                         chunkNaNs_p += 1;
    1919           0 :                         return true;
    1920           0 :                 case FP_NAN:
    1921           0 :                         chunkNaNs_p += 1;
    1922           0 :                         return true;
    1923           0 :                 default:
    1924           0 :                         chunkNaNs_p += 1;
    1925           0 :                         return true;
    1926             :         }
    1927             : }
    1928             : 
    1929             : bool
    1930           0 : FlagAgentBase::isNaNOrZero(Double number)
    1931             : {
    1932           0 :         int type = std::fpclassify(number);
    1933           0 :         switch (type)
    1934             :         {
    1935           0 :                 case FP_NORMAL:
    1936           0 :                         if (number <= FLT_EPSILON)
    1937             :                         {
    1938           0 :                                 return true;
    1939             :                         }
    1940             :                         else
    1941             :                         {
    1942           0 :                                 return false;
    1943             :                         }
    1944           0 :                 case FP_ZERO:
    1945           0 :                         return true;
    1946           0 :                 case FP_SUBNORMAL:
    1947           0 :                         return true;
    1948           0 :                 case FP_INFINITE:
    1949           0 :                         chunkNaNs_p += 1;
    1950           0 :                         return true;
    1951           0 :                 case FP_NAN:
    1952           0 :                         chunkNaNs_p += 1;
    1953           0 :                         return true;
    1954           0 :                 default:
    1955           0 :                         chunkNaNs_p += 1;
    1956           0 :                         return true;
    1957             :         }
    1958             : }
    1959             : 
    1960             : void
    1961       19900 : FlagAgentBase::chunkSummary()
    1962             : {
    1963       19900 :     logger_p->origin(LogOrigin(agentName_p,__FUNCTION__));
    1964             : 
    1965             :     // With this check we skip cases like summary or display
    1966       19900 :     if (chunkFlags_p > 0)
    1967             :     {
    1968       10501 :         tableFlags_p +=  chunkFlags_p;
    1969       10501 :         std::string flagStr = "unflagged";
    1970       10501 :         if (flag_p) {
    1971        4194 :             flagStr = "flagged";
    1972             :         }
    1973       10501 :         *logger_p << LogIO::NORMAL << "=> "  << "Data " << flagStr << " so far "
    1974       10501 :                   << 100.0*chunkFlags_p/flagDataHandler_p->progressCounts_p<< "%"
    1975       10501 :                   << " (" << chunkFlags_p << "/" << flagDataHandler_p->progressCounts_p
    1976       10501 :                   << ")" << LogIO::POST;
    1977             :         }
    1978             : 
    1979             :     // Only the clipping agent is capable of detecting this, and besides in general
    1980             :     // we should not have NaNs, so it is better not to print this log if possible
    1981       19900 :     if (chunkNaNs_p > 0)
    1982             :     {
    1983           0 :         tableNaNs_p += chunkNaNs_p;
    1984           0 :         *logger_p << LogIO::NORMAL << "=> "  << "Number of NaNs detected so far: " <<  (Double)chunkNaNs_p << LogIO::POST;
    1985             :     }
    1986             : 
    1987       19900 :     chunkFlags_p = 0;
    1988       19900 :     chunkNaNs_p = 0;
    1989       19900 :     visBufferFlags_p = 0;
    1990       19900 : }
    1991             : 
    1992             : void
    1993        2241 : FlagAgentBase::tableSummary()
    1994             : {
    1995        2241 :         logger_p->origin(LogOrigin(agentName_p,__FUNCTION__));
    1996             : 
    1997             :         // Update values just in case chunkSummary was not called before
    1998        2241 :         tableFlags_p +=  chunkFlags_p;
    1999        2241 :         tableNaNs_p += chunkNaNs_p;
    2000             : 
    2001             :         // With this check we skip cases like summary or display
    2002        2241 :         if (tableFlags_p > 0)
    2003             :         {
    2004        1167 :                 if (flag_p)
    2005             :                 {
    2006         754 :                         *logger_p << LogIO::NORMAL << "=> "  << "Percentage of data flagged in table selection: " <<  100.0*tableFlags_p/flagDataHandler_p->msCounts_p<< "%" << LogIO::POST;
    2007             :                 }
    2008             :                 else
    2009             :                 {
    2010         413 :                         *logger_p << LogIO::NORMAL << "=> "  << "Percentage of data un-flagged in table selection: " <<  100.0*tableFlags_p/flagDataHandler_p->msCounts_p<< "%" << LogIO::POST;
    2011             :                 }
    2012             :         }
    2013             : 
    2014        2241 :         if (tableNaNs_p > 0)
    2015             :         {
    2016           0 :                 *logger_p << LogIO::NORMAL << "=> "  << "Total number NaNs detected in table selection: " <<  (Double)tableNaNs_p << LogIO::POST;
    2017             :         }
    2018             : 
    2019        2241 :         tableFlags_p = 0;
    2020        2241 :         tableNaNs_p = 0;
    2021        2241 :         return;
    2022             : }
    2023             : 
    2024             : bool
    2025      185141 : FlagAgentBase::find(const Vector<Int> &validRange, Int element)
    2026             : {
    2027      399348 :         for (uShort idx=0;idx<validRange.size(); idx++)
    2028             :         {
    2029      303962 :                 if (element == validRange[idx]) return true;
    2030             :         }
    2031       95386 :         return false;
    2032             : }
    2033             : 
    2034             : bool
    2035      189918 : FlagAgentBase::find(const Matrix<Double> &validRange, Double element)
    2036             : {
    2037      379836 :         IPosition size = validRange.shape();
    2038             : 
    2039    23005981 :         for (uInt timeSel_i=0;timeSel_i<size(1);timeSel_i++)
    2040             :         {
    2041    22831926 :                 if (element>=validRange(0,timeSel_i) and element<=validRange(1,timeSel_i)) return true;
    2042             :         }
    2043             : 
    2044      174055 :         return false;
    2045             : }
    2046             : 
    2047             : bool
    2048     2599014 : FlagAgentBase::find(const Matrix<Int> &validPairs, Int element1, Int element2)
    2049             : {
    2050             :         Int x,y;
    2051     2599014 :         validPairs.shape(x,y);
    2052             : 
    2053    63324921 :         for (Int i=0;i<x;i++)
    2054             :         {
    2055    60939978 :                 if ((validPairs(i,0) == element1) and (validPairs(i,1) == element2)) return !antennaNegation_p;
    2056    60813447 :                 if ((validPairs(i,0) == element2) and (validPairs(i,1) == element1)) return !antennaNegation_p;
    2057             :         }
    2058             : 
    2059     2384943 :         return antennaNegation_p;
    2060             : }
    2061             : 
    2062             : bool
    2063      253808 : FlagAgentBase::find(const Block<int> &columns, int col)
    2064             : {
    2065      761424 :         for (uInt i=0; i<columns.nelements(); i++)
    2066             :         {
    2067      761424 :                 if (columns[i] == col) return true;
    2068             :         }
    2069           0 :         return false;
    2070             : }
    2071             : 
    2072             : bool
    2073      794155 : FlagAgentBase::checkIfProcessBuffer()
    2074             : {
    2075             :         // array,field and spw are common and unique in a given vis buffer,
    2076             :         // so we can use them to discard all the rows in a vis buffer.
    2077             : 
    2078      794155 :         if (arrayList_p.size())
    2079             :         {
    2080           0 :                 if (!find(arrayList_p,visibilityBuffer_p->arrayId()(0))) return false;
    2081             :         }
    2082             : 
    2083      794155 :         if (fieldList_p.size())
    2084             :         {
    2085           0 :                 if (!find(fieldList_p,visibilityBuffer_p->fieldId()(0))) return false;
    2086             :         }
    2087             : 
    2088      794155 :         if (spwList_p.size())
    2089             :         {
    2090      104511 :                 if (!find(spwList_p,visibilityBuffer_p->spectralWindows()(0))) return false;
    2091             :         }
    2092             : 
    2093             :         // If scan is constant check only 1st row
    2094      736608 :         if ( (scanList_p.size()>0) and (find(flagDataHandler_p->sortOrder_p,MS::SCAN_NUMBER)==true) )
    2095             :         {
    2096        6846 :                 if (!find(scanList_p,visibilityBuffer_p->scan()[0])) return false;
    2097             :         }
    2098             : 
    2099             :         // If observation is constant check only 1st row
    2100      730513 :         if ((observationList_p.size()>0) and (find(flagDataHandler_p->sortOrder_p,MS::OBSERVATION_ID)==true) )
    2101             :         {
    2102           0 :                 if (!find(observationList_p,visibilityBuffer_p->observationId()[0])) return false;
    2103             :         }
    2104             : 
    2105             :         // If time is constant check only 1st row
    2106      730513 :         if ( (timeList_p.size()>0) and (flagDataHandler_p->groupTimeSteps_p==false) )
    2107             :         {
    2108      172734 :                 if (!find(timeList_p,visibilityBuffer_p->time()[0])) return false;
    2109             :         }
    2110             : 
    2111      567914 :         return true;
    2112             : }
    2113             : 
    2114             : void
    2115       29849 : FlagAgentBase::preProcessBuffer(const vi::VisBuffer2 &/*visBuffer*/)
    2116             : {
    2117       29849 : }
    2118             : 
    2119             : void
    2120        3724 : FlagAgentBase::postProcessBuffer()
    2121             : {
    2122        3724 : }
    2123             : 
    2124             : void
    2125      533525 : FlagAgentBase::iterateRows()
    2126             : {
    2127      533525 :         logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
    2128             : 
    2129             :         // Create FlagMapper objects and parse the correlation selection
    2130     1067050 :         vector< vector<uInt> > selectedCorrelations;
    2131     2534020 :         for (uInt pol_i=0;pol_i<polarizationIndex_p.size();pol_i++)
    2132             :         {
    2133     4000990 :                 vector<uInt> correlationProduct;
    2134     2000495 :                 correlationProduct.push_back(polarizationIndex_p[pol_i]);
    2135     2000495 :                 selectedCorrelations.push_back(correlationProduct);
    2136             :         }
    2137     1067050 :         FlagMapper flagsMap = FlagMapper(flag_p,selectedCorrelations);
    2138             : 
    2139             :         // Set CubeViews in FlagMapper
    2140      533525 :         setFlagsMap(NULL,&flagsMap);
    2141             : 
    2142             :         // Activate check mode
    2143      533525 :         if (checkFlags_p) flagsMap.activateCheckMode();
    2144             : 
    2145             :         // Some log info
    2146      533525 :         const auto logprio = logger_p->priority();
    2147      533525 :         if (logprio <= LogMessage::DEBUG2) {
    2148           0 :             if (multiThreading_p)
    2149             :             {
    2150           0 :                 *logger_p << LogIO::DEBUG2 << agentName_p.c_str() << "::" << __FUNCTION__
    2151             :                           <<  " Thread Id " << threadId_p << ":" << nThreads_p
    2152             :                           << " Will process every " << nThreads_p << " rows starting with row " << threadId_p << " from a total of " <<
    2153           0 :                     rowsIndex_p.size() << " rows (" << rowsIndex_p[0] << "-" << rowsIndex_p[rowsIndex_p.size()-1] << ") " <<
    2154           0 :                     channelIndex_p.size() << " channels (" << channelIndex_p[0] << "-" << channelIndex_p[channelIndex_p.size()-1] << ") " <<
    2155           0 :                     polarizationIndex_p.size() << " polarizations (" << polarizationIndex_p[0] << "-" << polarizationIndex_p[polarizationIndex_p.size()-1] << ")" << LogIO::POST;
    2156             :             }
    2157             :             else
    2158             :             {
    2159             :                 // Some logging info
    2160           0 :                 *logger_p       << LogIO::DEBUG2 << " Going to process a buffer with: " <<
    2161           0 :                     rowsIndex_p.size() << " rows (" << rowsIndex_p[0] << "-" << rowsIndex_p[rowsIndex_p.size()-1] << ") " <<
    2162           0 :                     channelIndex_p.size() << " channels (" << channelIndex_p[0] << "-" << channelIndex_p[channelIndex_p.size()-1] << ") " <<
    2163           0 :                     polarizationIndex_p.size() << " polarizations (" << polarizationIndex_p[0] << "-" << polarizationIndex_p[polarizationIndex_p.size()-1] << ")" << LogIO::POST;
    2164             :             }
    2165             :         }
    2166             : 
    2167             :         // Loop through selected rows
    2168      533525 :         Int rowIdx = 0;
    2169      533525 :         bool flagRow = false;
    2170      533525 :         vector<uInt>::iterator rowIter;
    2171    14571141 :         for (rowIter = rowsIndex_p.begin(); rowIter != rowsIndex_p.end(); ++rowIter)
    2172             :         {
    2173    14037616 :                 if (multiThreading_p and (rowIdx % nThreads_p != threadId_p))
    2174             :                 {
    2175             :                         // Increment row index
    2176           0 :                         rowIdx++;
    2177             : 
    2178             :                         // Continue with next row
    2179           0 :                         continue;
    2180             :                 }
    2181             : 
    2182             :                 // Compute flags for this row
    2183    14037616 :                 flagRow = false;
    2184    14037616 :                 flagRow = computeRowFlags(*(flagDataHandler_p->visibilityBuffer_p), flagsMap,*rowIter);
    2185    14037616 :                 if (flagRow)
    2186             :                 {
    2187     8611719 :                         flagsMap.applyFlagInRow(*rowIter);
    2188     8611719 :                         visBufferFlags_p += flagsMap.flagsPerRow();
    2189     8611719 :                         if ((filterChannels_p == false) and (filterPols_p == false))
    2190             :                         {
    2191     7284245 :                                 flagsMap.applyFlagRow(*rowIter);
    2192     7284245 :                                 flagRow_p = true;
    2193             :                         }
    2194             :                 }
    2195             : 
    2196             :                 // Increment row index
    2197    14037616 :                 rowIdx++;
    2198             :         }
    2199             : 
    2200     1067050 :         return;
    2201             : }
    2202             : 
    2203             : void
    2204       29849 : FlagAgentBase::iterateInRows()
    2205             : {
    2206       29849 :         logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
    2207             : 
    2208             :         // Check if the visibility expression is suitable for this spw
    2209       29849 :         if (!checkVisExpression(flagDataHandler_p->getPolarizationMap())) return;
    2210             : 
    2211             :         // Create VisMapper and FlagMapper objects and parse the polarization expression
    2212       59338 :         VisMapper visibilitiesMap = VisMapper(expression_p,flagDataHandler_p->getPolarizationMap());
    2213       59338 :         FlagMapper flagsMap = FlagMapper(flag_p,visibilitiesMap.getSelectedCorrelations());
    2214             : 
    2215             :         // Set CubeViews in VisMapper
    2216       29669 :         setVisibilitiesMap(NULL,&visibilitiesMap);
    2217             : 
    2218             :         // Set CubeViews in FlagMapper
    2219       29669 :         setFlagsMap(NULL,&flagsMap);
    2220             : 
    2221             :         // Activate check mode
    2222       29669 :         if (checkFlags_p) flagsMap.activateCheckMode();
    2223             : 
    2224             :         // Some log info
    2225       29669 :         if (multiThreading_p)
    2226             :         {
    2227           0 :                 *logger_p << LogIO::DEBUG2 << agentName_p.c_str() << "::" << __FUNCTION__
    2228             :                                 <<  " Thread Id " << threadId_p << ":" << nThreads_p
    2229             :                                 << " Will process every " << nThreads_p << " rows starting with row " << threadId_p
    2230             :                                 << " from a total of " << rowsIndex_p.size() << " rows with " << channelIndex_p.size() << " channels ("
    2231           0 :                                 << channelIndex_p[0] << "-" << channelIndex_p[channelIndex_p.size()-1] << ") each one" << LogIO::POST;
    2232             :         }
    2233             :         else
    2234             :         {
    2235             :                 // Some logging info
    2236       29669 :                 *logger_p       << LogIO::DEBUG2 << " Going to process a buffer with: " <<
    2237       29669 :                                 rowsIndex_p.size() << " rows (" << rowsIndex_p[0] << "-" << rowsIndex_p[rowsIndex_p.size()-1] << ") " <<
    2238       59338 :                                 channelIndex_p.size() << " channels (" << channelIndex_p[0] << "-" << channelIndex_p[channelIndex_p.size()-1] << ") "<< LogIO::POST;
    2239             :         }
    2240             : 
    2241             :         // Iterate through rows
    2242       29669 :         Int rowIdx = 0;
    2243       29669 :         vector<uInt>::iterator rowIter;
    2244      777499 :         for (rowIter = rowsIndex_p.begin();rowIter != rowsIndex_p.end();rowIter++)
    2245             :         {
    2246      747830 :                 if (multiThreading_p and (rowIdx % nThreads_p != threadId_p))
    2247             :                 {
    2248             :                         // Increment row index
    2249           0 :                         rowIdx++;
    2250             : 
    2251             :                         // Continue with next row
    2252           0 :                         continue;
    2253             :                 }
    2254             : 
    2255             :                 // Compute flags for this row
    2256      747830 :                 computeInRowFlags(*(flagDataHandler_p->visibilityBuffer_p),visibilitiesMap,flagsMap,*rowIter);
    2257             : 
    2258             :                 // jagonzal (CAS-4913, CAS-5344): If we are unflagging FLAG_ROWS must be unset
    2259      747830 :                 if (not flag_p)
    2260             :                 {
    2261         756 :                         flagsMap.applyFlagRow(rowIdx);
    2262         756 :                         flagRow_p = true;
    2263             :                 }
    2264             : 
    2265             :                 // Increment row index
    2266      747830 :                 rowIdx++;
    2267             :         }
    2268             : 
    2269       29669 :         return;
    2270             : }
    2271             : 
    2272             : void
    2273        1222 : FlagAgentBase::iterateAntennaPairs()
    2274             : {
    2275        1222 :         logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
    2276             : 
    2277             :         // Check if the visibility expression is suitable for this spw
    2278        1222 :         if (!checkVisExpression(flagDataHandler_p->getPolarizationMap())) return;
    2279             : 
    2280        1099 :         antennaPairMapIterator myAntennaPairMapIterator;
    2281        1099 :         std::pair<Int,Int> antennaPair;
    2282        1099 :         std::vector<uInt> *antennaRows = NULL;
    2283        2198 :         IPosition cubeShape;
    2284             : 
    2285             :         // Create VisMapper and FlagMapper objects and parse the polarization expression
    2286        2198 :         VisMapper visibilitiesMap = VisMapper(expression_p,flagDataHandler_p->getPolarizationMap());
    2287        2198 :         FlagMapper flagsMap = FlagMapper(flag_p,visibilitiesMap.getSelectedCorrelations());
    2288             : 
    2289             :         // Activate check mode
    2290        1099 :         if (checkFlags_p) flagsMap.activateCheckMode();
    2291             : 
    2292             :         // Some log info
    2293        1099 :         if (multiThreading_p)
    2294             :         {
    2295           0 :                 *logger_p << LogIO::DEBUG2 << agentName_p.c_str() << "::" << __FUNCTION__
    2296             :                                 <<  " Thread Id " << threadId_p << ":" << nThreads_p
    2297             :                                 << " Will process every " << nThreads_p << " baselines starting with baseline " << threadId_p
    2298           0 :                                 << " from a total of " << flagDataHandler_p->getAntennaPairMap()->size() << LogIO::POST;
    2299             :         }
    2300             :         else
    2301             :         {
    2302        1099 :                 *logger_p << LogIO::DEBUG2 <<  " Iterating through " << flagDataHandler_p->getAntennaPairMap()->size() <<  " antenna pair maps " << LogIO::POST;
    2303             :         }
    2304             : 
    2305             : 
    2306        1099 :         uShort antennaPairdIdx = 0;
    2307       18686 :         for (myAntennaPairMapIterator=flagDataHandler_p->getAntennaPairMap()->begin(); myAntennaPairMapIterator != flagDataHandler_p->getAntennaPairMap()->end(); ++myAntennaPairMapIterator)
    2308             :         {
    2309       17587 :                 if (multiThreading_p and (antennaPairdIdx % nThreads_p != threadId_p))
    2310             :                 {
    2311             :                         // Increment antenna pair index
    2312           0 :                         antennaPairdIdx++;
    2313             : 
    2314             :                         // Continue with next antenna pair
    2315           0 :                         continue;
    2316             :                 }
    2317             : 
    2318             :                 // Get antenna pair from map
    2319       17587 :                 antennaPair = myAntennaPairMapIterator->first;
    2320             : 
    2321             :                 // Check if antenna pair is in the baselines list of this agent
    2322       17587 :                 if (baselineList_p.size()>0)
    2323             :                 {
    2324           0 :                         if (!find(baselineList_p,antennaPair.first,antennaPair.second)) continue;
    2325             :                 }
    2326             : 
    2327             :                 // Get rows corresponding to this antenna pair
    2328       17587 :                 antennaRows = generateAntennaPairRowsIndex(antennaPair.first,antennaPair.second);
    2329             : 
    2330             :                 // If none of the antenna pair rows were eligible then go to next pair
    2331       17587 :                 if (antennaRows->empty())
    2332             :                 {
    2333           0 :                         *logger_p << LogIO::WARN <<  " Requested baseline (" << antennaPair.first << "," << antennaPair.second << ") does not have any rows in this chunk" << LogIO::POST;
    2334             : 
    2335             :                         // Increment antenna pair index
    2336           0 :                         antennaPairdIdx++;
    2337             : 
    2338             :                         // Delete antenna pair rows
    2339           0 :                         delete antennaRows;
    2340             : 
    2341             :                         // Continue with next antenna pair
    2342           0 :                         continue;
    2343             :                 }
    2344             : 
    2345             :                 // Set CubeViews in VisMapper
    2346       17587 :                 setVisibilitiesMap(antennaRows,&visibilitiesMap);
    2347             : 
    2348             :                 // Set CubeViews in FlagMapper
    2349       17587 :                 setFlagsMap(antennaRows,&flagsMap);
    2350             : 
    2351             :                 // Flag map
    2352       17587 :                 computeAntennaPairFlags(*(flagDataHandler_p->visibilityBuffer_p),visibilitiesMap,flagsMap,antennaPair.first,antennaPair.second,*antennaRows);
    2353             : 
    2354             :                 // Increment antenna pair index
    2355       17587 :                 antennaPairdIdx++;
    2356             : 
    2357             :                 // jagonzal (CAS-4913, CAS-5344): If we are unflagging FLAG_ROWS must be unset
    2358       17587 :                 if (not flag_p)
    2359             :                 {
    2360        4536 :                         for (uInt baselineRowIdx=0;baselineRowIdx<antennaRows->size();baselineRowIdx++)
    2361             :                         {
    2362        3024 :                                 flagsMap.applyFlagRow(baselineRowIdx);
    2363             :                         }
    2364        1512 :                         flagRow_p = true;
    2365             :                 }
    2366             : 
    2367             : 
    2368             :                 // Delete antenna pair rows
    2369       17587 :                 delete antennaRows;
    2370             :         }
    2371             : 
    2372        1099 :         return;
    2373             : }
    2374             : 
    2375             : void
    2376         442 : FlagAgentBase::iterateAntennaPairsFlags()
    2377             : {
    2378         442 :         logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
    2379             : 
    2380         442 :         antennaPairMapIterator myAntennaPairMapIterator;
    2381         442 :         std::pair<Int,Int> antennaPair;
    2382         442 :         std::vector<uInt> *antennaRows = NULL;
    2383         884 :         IPosition cubeShape;
    2384             : 
    2385             :         // Create VisMapper and FlagMapper objects and parse the polarization expression
    2386         884 :         vector< vector<uInt> > selectedCorrelations;
    2387        1827 :         for (uInt pol_i=0;pol_i<polarizationIndex_p.size();pol_i++)
    2388             :         {
    2389        2770 :                 vector<uInt> correlationProduct;
    2390        1385 :                 correlationProduct.push_back(polarizationIndex_p[pol_i]);
    2391        1385 :                 selectedCorrelations.push_back(correlationProduct);
    2392             :         }
    2393         884 :         FlagMapper flagsMap = FlagMapper(flag_p,selectedCorrelations);
    2394             : 
    2395             :         // Activate check mode
    2396         442 :         if (checkFlags_p) flagsMap.activateCheckMode();
    2397             : 
    2398             :         // Some log info
    2399         442 :         if (multiThreading_p)
    2400             :         {
    2401           0 :                 *logger_p << LogIO::DEBUG2 << agentName_p.c_str() << "::" << __FUNCTION__
    2402             :                                 <<  " Thread Id " << threadId_p << ":" << nThreads_p
    2403             :                                 << " Will process every " << nThreads_p << " baselines starting with baseline " << threadId_p
    2404           0 :                                 << " from a total of " << flagDataHandler_p->getAntennaPairMap()->size() << LogIO::POST;
    2405             :         }
    2406             :         else
    2407             :         {
    2408         442 :                 *logger_p << LogIO::DEBUG2 <<  " Iterating through " << flagDataHandler_p->getAntennaPairMap()->size() <<  " antenna pair maps " << LogIO::POST;
    2409             :         }
    2410             : 
    2411             : 
    2412         442 :         uShort antennaPairdIdx = 0;
    2413        5254 :         for (myAntennaPairMapIterator=flagDataHandler_p->getAntennaPairMap()->begin(); myAntennaPairMapIterator != flagDataHandler_p->getAntennaPairMap()->end(); ++myAntennaPairMapIterator)
    2414             :         {
    2415        4812 :                 if (multiThreading_p and (antennaPairdIdx % nThreads_p != threadId_p))
    2416             :                 {
    2417             :                         // Increment antenna pair index
    2418           0 :                         antennaPairdIdx++;
    2419             : 
    2420             :                         // Continue with next antenna pair
    2421           0 :                         continue;
    2422             :                 }
    2423             : 
    2424             :                 // Get antenna pair from map
    2425        4812 :                 antennaPair = myAntennaPairMapIterator->first;
    2426             : 
    2427             :                 // Check if antenna pair is in the baselines list of this agent
    2428        4812 :                 if (baselineList_p.size()>0)
    2429             :                 {
    2430           0 :                         if (!find(baselineList_p,antennaPair.first,antennaPair.second)) continue;
    2431             :                 }
    2432             : 
    2433             :                 // Get rows corresponding to this antenna pair
    2434        4812 :                 antennaRows = generateAntennaPairRowsIndex(antennaPair.first,antennaPair.second);
    2435             : 
    2436             :                 // If none of the antenna pair rows were eligible then go to next pair
    2437        4812 :                 if (antennaRows->empty())
    2438             :                 {
    2439           0 :                         *logger_p << LogIO::WARN <<  " Requested baseline (" << antennaPair.first << "," << antennaPair.second << ") does not have any rows in this chunk" << LogIO::POST;
    2440             : 
    2441             :                         // Increment antenna pair index
    2442           0 :                         antennaPairdIdx++;
    2443             : 
    2444             :                         // Delete antenna pair rows
    2445           0 :                         delete antennaRows;
    2446             : 
    2447             :                         // Continue with next antenna pair
    2448           0 :                         continue;
    2449             :                 }
    2450             : 
    2451             :                 // Set CubeViews in FlagMapper
    2452        4812 :                 setFlagsMap(antennaRows,&flagsMap);
    2453             : 
    2454             :                 // Flag map
    2455        4812 :                 computeAntennaPairFlags(*(flagDataHandler_p->visibilityBuffer_p),flagsMap,antennaPair.first,antennaPair.second,*antennaRows);
    2456             : 
    2457             :                 // Increment antenna pair index
    2458        4812 :                 antennaPairdIdx++;
    2459             : 
    2460             :                 // jagonzal (CAS-4913, CAS-5344): If we are unflagging FLAG_ROWS must be unset
    2461        4812 :                 if (not flag_p)
    2462             :                 {
    2463           0 :                         for (uInt baselineRowIdx=0;baselineRowIdx<antennaRows->size();baselineRowIdx++)
    2464             :                         {
    2465           0 :                                 flagsMap.applyFlagRow(baselineRowIdx);
    2466             :                         }
    2467           0 :                         flagRow_p = true;
    2468             :                 }
    2469             : 
    2470             :                 // Delete antenna pair rows
    2471        4812 :                 delete antennaRows;
    2472             :         }
    2473             : 
    2474         884 :         return;
    2475             : }
    2476             : 
    2477             : void
    2478           0 : FlagAgentBase::iterateAntennaPairsInteractive(antennaPairMap *antennaPairMap_ptr)
    2479             : {
    2480             :         // Check if the visibility expression is suitable for this spw
    2481           0 :         if (!checkVisExpression(flagDataHandler_p->getPolarizationMap())) return;
    2482             : 
    2483             :         // Iterate through antenna pair map
    2484           0 :         std::pair<Int,Int> antennaPair;
    2485           0 :         antennaPairMapIterator myAntennaPairMapIterator;
    2486           0 :         for (myAntennaPairMapIterator=antennaPairMap_ptr->begin(); myAntennaPairMapIterator != antennaPairMap_ptr->end(); ++myAntennaPairMapIterator)
    2487             :         {
    2488             :                 // Get antenna pair from map
    2489           0 :                 antennaPair = myAntennaPairMapIterator->first;
    2490             : 
    2491             :                 // Process antenna pair
    2492           0 :                 processAntennaPair(antennaPair.first,antennaPair.second);
    2493             :         }
    2494             : 
    2495           0 :         return;
    2496             : }
    2497             : 
    2498             : void
    2499           0 : FlagAgentBase::processAntennaPair(Int antenna1,Int antenna2)
    2500             : {
    2501           0 :         logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
    2502             : 
    2503           0 :         std::pair<Int,Int> antennaPair = std::make_pair(antenna1,antenna2);
    2504           0 :         antennaPairMapIterator index = flagDataHandler_p->getAntennaPairMap()->find(antennaPair);
    2505           0 :         if (index != flagDataHandler_p->getAntennaPairMap()->end())
    2506             :         {
    2507           0 :                 std::vector<uInt> *antennaRows = generateAntennaPairRowsIndex(antennaPair.first,antennaPair.second);
    2508           0 :                 if (antennaRows->empty())
    2509             :                 {
    2510           0 :                         *logger_p << LogIO::WARN <<  " Requested baseline (" << antennaPair.first << "," << antennaPair.second << ") does not have any rows in this chunk" << LogIO::POST;
    2511             :                 }
    2512             :                 else
    2513             :                 {
    2514             :                         // Check if antenna pair is in the baselines list of this agent
    2515           0 :                         if ((baselineList_p.size()>0) and (!find(baselineList_p,antennaPair.first,antennaPair.second)))
    2516             :                         {
    2517           0 :                                 *logger_p << logLevel_p <<  "Requested baseline (" << antennaPair.first << "," << antennaPair.second << ") is not included in the selected baseline range" << LogIO::POST;
    2518             :                         }
    2519             :                         else
    2520             :                         {
    2521           0 :                                 *logger_p << logLevel_p <<  " Going to process requested baseline (" << antennaPair.first << "," << antennaPair.second << ") " << LogIO::POST;
    2522             : 
    2523             :                                 // Create VisMapper and FlagMapper objects and parse the polarization expression
    2524           0 :                                 VisMapper visibilitiesMap = VisMapper(expression_p,flagDataHandler_p->getPolarizationMap());
    2525           0 :                                 FlagMapper flagsMap = FlagMapper(flag_p,visibilitiesMap.getSelectedCorrelations());
    2526             : 
    2527             :                                 // Set CubeViews in VisMapper
    2528           0 :                                 setVisibilitiesMap(antennaRows,&visibilitiesMap);
    2529             : 
    2530             :                                 // Set CubeViews in FlagMapper
    2531           0 :                                 setFlagsMap(antennaRows,&flagsMap);
    2532             : 
    2533             :                                 // Flag map
    2534           0 :                                 computeAntennaPairFlags(*(flagDataHandler_p->visibilityBuffer_p),visibilitiesMap,flagsMap,antennaPair.first,antennaPair.second,*antennaRows);
    2535             :                         }
    2536             :                 }
    2537             : 
    2538             :                 // Delete antenna pair rows - prob generateAntennaPairRowsIndex should
    2539             :                 // not return a pointer, but that requires a long cascade of changes elsewhere
    2540           0 :                 delete antennaRows;
    2541             : 
    2542             :         }
    2543             :         else
    2544             :         {
    2545           0 :                 *logger_p << LogIO::WARN <<  " Requested baseline (" << antennaPair.first << "," << antennaPair.second << ") is not available in this chunk " << LogIO::POST;
    2546             :         }
    2547             : 
    2548           0 :         return;
    2549             : }
    2550             : 
    2551             : void
    2552           0 : FlagAgentBase::passIntermediate(const vi::VisBuffer2 & /*visBuffer*/)
    2553             : {
    2554             :         // TODO: This method must be re-implemented in the derived classes
    2555           0 :         return;
    2556             : }
    2557             : 
    2558             : void
    2559           0 : FlagAgentBase::passFinal(const vi::VisBuffer2 & /*visBuffer*/)
    2560             : {
    2561             :         // TODO: This method must be re-implemented in the derived classes
    2562           0 :         return;
    2563             : }
    2564             : 
    2565             : void
    2566       47256 : FlagAgentBase::setVisibilitiesMap(std::vector<uInt> *rows,VisMapper *visMap)
    2567             : {
    2568             :         // First step: Get reference visibility cubes
    2569       47256 :         Cube<Complex> *leftVisCube = NULL;
    2570       47256 :         Cube<Complex> *rightVisCube = NULL;
    2571       47256 :         switch (dataReference_p)
    2572             :         {
    2573       32165 :                 case DATA:
    2574             :                 {
    2575       32165 :                         leftVisCube = const_cast<Cube<Complex> *>(&(visibilityBuffer_p->visCube()));
    2576       32165 :                         break;
    2577             :                 }
    2578       11349 :                 case CORRECTED:
    2579             :                 {
    2580       11349 :                         leftVisCube = const_cast<Cube<Complex> *>(&(visibilityBuffer_p->visCubeCorrected()));
    2581       11349 :                         break;
    2582             :                 }
    2583         236 :                 case MODEL:
    2584             :                 {
    2585         236 :                         leftVisCube = const_cast<Cube<Complex> *>(&(visibilityBuffer_p->visCubeModel()));
    2586         236 :                         break;
    2587             :                 }
    2588        3080 :                 case RESIDUAL:
    2589             :                 {
    2590        3080 :                         leftVisCube = const_cast<Cube<Complex> *>(&(visibilityBuffer_p->visCubeCorrected()));
    2591        3080 :                         rightVisCube = const_cast<Cube<Complex> *>(&(visibilityBuffer_p->visCubeModel()));
    2592        3080 :                         break;
    2593             :                 }
    2594         396 :                 case RESIDUAL_DATA:
    2595             :                 {
    2596         396 :                         leftVisCube = const_cast<Cube<Complex> *>(&(visibilityBuffer_p->visCube()));
    2597         396 :                         rightVisCube = const_cast<Cube<Complex> *>(&(visibilityBuffer_p->visCubeModel()));
    2598         396 :                         break;
    2599             :                 }
    2600           0 :                 case FPARAM:
    2601             :                 {
    2602           0 :                         leftVisCube = const_cast<Cube<Complex> *>(&(visibilityBuffer_p->visCube()));
    2603           0 :                         break;
    2604             :                 }
    2605           0 :                 case CPARAM:
    2606             :                 {
    2607           0 :                         leftVisCube = const_cast<Cube<Complex> *>(&(visibilityBuffer_p->visCubeCorrected()));
    2608           0 :                         break;
    2609             :                 }
    2610           0 :                 case SNR:
    2611             :                 {
    2612           0 :                         leftVisCube = const_cast<Cube<Complex> *>(&(visibilityBuffer_p->visCubeModel()));
    2613           0 :                         break;
    2614             :                 }
    2615          30 :                 case WEIGHT_SPECTRUM:
    2616             :                 {
    2617             :                         // Cast the Cube<Float> to Cube<Complex> in the DataHandler
    2618          30 :                         leftVisCube = const_cast<Cube<Complex> *>(&(flagDataHandler_p->weightVisCube()));
    2619          30 :                         break;
    2620             :                 }
    2621           0 :                 default:
    2622             :                 {
    2623           0 :                         leftVisCube = const_cast<Cube<Complex> *>(&(visibilityBuffer_p->visCube()));
    2624           0 :                         break;
    2625             :                 }
    2626             :         }
    2627             : 
    2628             :         // Second step create CubeViews from selected vis cubes
    2629       47256 :         CubeView<Complex> *leftVisCubeView = NULL;
    2630       47256 :         CubeView<Complex> *rightVisCubeView = NULL;
    2631       47256 :         leftVisCubeView = new CubeView<Complex>(leftVisCube,rows,&channelIndex_p);
    2632       47256 :         if (rightVisCube != NULL) rightVisCubeView = new CubeView<Complex>(rightVisCube,rows,&channelIndex_p);
    2633             : 
    2634             :         // Third step: Set CubeViews in mapper
    2635       47256 :         visMap->setParentCubes(leftVisCubeView,rightVisCubeView);
    2636       47256 :         return;
    2637             : }
    2638             : 
    2639             : void
    2640      585593 : FlagAgentBase::setFlagsMap(std::vector<uInt> *rows,FlagMapper *flagMap)
    2641             : {
    2642             :         // First step create common/private CubeViews
    2643      585593 :         CubeView<Bool> *commonFlagCube = NULL;
    2644      585593 :         CubeView<Bool> *originalFlagCube = NULL;
    2645      585593 :         CubeView<Bool> *privateFlagCube = NULL;
    2646             : 
    2647             :         // Second step create CubeViews from selected vis cubes
    2648      585593 :         commonFlagCube= new CubeView<Bool>(commonFlagCube_p,rows,&channelIndex_p);
    2649      585593 :         originalFlagCube= new CubeView<Bool>(originalFlagCube_p,rows,&channelIndex_p);
    2650      585593 :         if (writePrivateFlagCube_p) privateFlagCube= new CubeView<Bool>(privateFlagCube_p,rows,&channelIndex_p);
    2651             : 
    2652             :         // Third step: Set CubeViews in mapper
    2653      585593 :         flagMap->setParentCubes(commonFlagCube,originalFlagCube,privateFlagCube);
    2654             : 
    2655             :         // 4th step create common/private CubeViews
    2656      585593 :         VectorView<Bool> *commonFlagRow = NULL;
    2657      585593 :         VectorView<Bool> *originalFlagRow = NULL;
    2658      585593 :         VectorView<Bool> *privateFlagRow = NULL;
    2659             : 
    2660             :         // 5th step create CubeViews from selected vis cubes
    2661      585593 :         commonFlagRow= new VectorView<Bool>(commonFlagRow_p,rows);
    2662      585593 :         originalFlagRow= new VectorView<Bool>(originalFlagRow_p,rows);
    2663      585593 :         if (writePrivateFlagCube_p) privateFlagRow= new VectorView<Bool>(privateFlagRow_p,rows);
    2664             : 
    2665             :         // 6th step: Set CubeViews in mapper
    2666      585593 :         flagMap->setParentFlagRow(commonFlagRow,originalFlagRow,privateFlagRow);
    2667             : 
    2668      585593 :         return;
    2669             : }
    2670             : 
    2671             : Bool
    2672       31071 : FlagAgentBase::checkVisExpression(polarizationMap *polMap)
    2673             : {
    2674       31071 :         logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
    2675             : 
    2676             :         // If we find I directly in the polarization map we assume is ALMA Water Vapor Radiometer data
    2677             :         // And we only process it if the user requested WVR
    2678       31071 :         if (expression_p.find("WVR") != string::npos)
    2679             :         {
    2680         142 :                 if (polMap->find(Stokes::I) != polMap->end())
    2681             :                 {
    2682          76 :                         *logger_p << LogIO::DEBUG1 <<  " Detected Water Vapor data in spw (" <<
    2683          76 :                                         visibilityBuffer_p->spectralWindows()(0) << "), will be flagged" << LogIO::POST;
    2684          76 :                         return true;
    2685             :                 }
    2686             :                 else
    2687             :                 {
    2688          66 :                         return false;
    2689             :                 }
    2690             :         }
    2691       30929 :         else if (polMap->find(Stokes::I) != polMap->end())
    2692             :         {
    2693          76 :                 *logger_p << LogIO::DEBUG1 <<  " Detected Water Vapor data in spw (" <<
    2694          76 :                                         visibilityBuffer_p->spectralWindows()(0) << "), won't be flagged" << LogIO::POST;
    2695          76 :                 return false;
    2696             :         }
    2697             : 
    2698             :         // After WVR - I products check we go ahead with the rest of the generic cases
    2699       30853 :         if (expression_p.find("XX") != string::npos)
    2700             :         {
    2701          52 :                 if (polMap->find(Stokes::XX) != polMap->end())
    2702             :                 {
    2703          52 :                         return true;
    2704             :                 }
    2705             :                 else
    2706             :                 {
    2707           0 :                         *logger_p << LogIO::WARN <<  " Requested correlation (XX) not available in current spectral window (" <<
    2708           0 :                                         visibilityBuffer_p->spectralWindows()(0) << ") " << LogIO::POST;
    2709           0 :                         return false;
    2710             :                 }
    2711             :         }
    2712       30801 :         else if (expression_p.find("YY") != string::npos)
    2713             :         {
    2714          16 :                 if (polMap->find(Stokes::YY) != polMap->end())
    2715             :                 {
    2716          13 :                         return true;
    2717             :                 }
    2718             :                 else
    2719             :                 {
    2720           3 :                         *logger_p << LogIO::WARN <<  " Requested correlation (YY) not available in current spectral window (" <<
    2721           3 :                                         visibilityBuffer_p->spectralWindows()(0) << ") " << LogIO::POST;
    2722           3 :                         return false;
    2723             :                 }
    2724             : 
    2725             :         }
    2726       30785 :         else if (expression_p.find("XY") != string::npos)
    2727             :         {
    2728           0 :                 if (polMap->find(Stokes::XY) != polMap->end())
    2729             :                 {
    2730           0 :                         return true;
    2731             :                 }
    2732             :                 else
    2733             :                 {
    2734           0 :                         *logger_p << LogIO::WARN <<  " Requested correlation (XY) not available in current spectral window (" <<
    2735           0 :                                         visibilityBuffer_p->spectralWindows()(0) << ") " << LogIO::POST;
    2736           0 :                         return false;
    2737             :                 }
    2738             :         }
    2739       30785 :         else if (expression_p.find("YX") != string::npos)
    2740             :         {
    2741           0 :                 if (polMap->find(Stokes::YX) != polMap->end())
    2742             :                 {
    2743           0 :                         return true;
    2744             :                 }
    2745             :                 else
    2746             :                 {
    2747           0 :                         *logger_p << LogIO::WARN <<  " Requested correlation (YX) not available in current spectral window (" <<
    2748           0 :                                         visibilityBuffer_p->spectralWindows()(0) << ") " << LogIO::POST;
    2749           0 :                         return false;
    2750             :                 }
    2751             :         }
    2752       30785 :         else if (expression_p.find("RR") != string::npos)
    2753             :         {
    2754       28299 :                 if (polMap->find(Stokes::RR) != polMap->end())
    2755             :                 {
    2756       28261 :                         return true;
    2757             :                 }
    2758             :                 else
    2759             :                 {
    2760          38 :                         *logger_p << LogIO::WARN <<  " Requested correlation (RR) not available in current spectral window (" <<
    2761          38 :                                         visibilityBuffer_p->spectralWindows()(0) << ") " << LogIO::POST;
    2762          38 :                         return false;
    2763             :                 }
    2764             :         }
    2765        2486 :         else if (expression_p.find("LL") != string::npos)
    2766             :         {
    2767         182 :                 if (polMap->find(Stokes::LL) != polMap->end())
    2768             :                 {
    2769         182 :                         return true;
    2770             :                 }
    2771             :                 else
    2772             :                 {
    2773           0 :                         *logger_p << LogIO::WARN <<  " Requested correlation (LL) not available in current spectral window (" <<
    2774           0 :                                         visibilityBuffer_p->spectralWindows()(0) << ") " << LogIO::POST;
    2775           0 :                         return false;
    2776             :                 }
    2777             :         }
    2778        2304 :         else if (expression_p.find("LR") != string::npos)
    2779             :         {
    2780         119 :                 if (polMap->find(Stokes::LR) != polMap->end())
    2781             :                 {
    2782         119 :                         return true;
    2783             :                 }
    2784             :                 else
    2785             :                 {
    2786           0 :                         *logger_p << LogIO::WARN <<  " Requested correlation (LR) not available in current spectral window (" <<
    2787           0 :                                         visibilityBuffer_p->spectralWindows()(0) << ") " << LogIO::POST;
    2788           0 :                         return false;
    2789             :                 }
    2790             :         }
    2791        2185 :         else if (expression_p.find("RL") != string::npos)
    2792             :         {
    2793         119 :                 if (polMap->find(Stokes::RL) != polMap->end())
    2794             :                 {
    2795         119 :                         return true;
    2796             :                 }
    2797             :                 else
    2798             :                 {
    2799           0 :                         *logger_p << LogIO::WARN <<  " Requested correlation (RL) not available in current spectral window (" <<
    2800           0 :                                         visibilityBuffer_p->spectralWindows()(0) << ") " << LogIO::POST;
    2801           0 :                         return false;
    2802             :                 }
    2803             :         }
    2804        2066 :         else if (expression_p.find("I") != string::npos)
    2805             :         {
    2806          33 :                 if (polMap->find(Stokes::I) != polMap->end())
    2807             :                 {
    2808           0 :                         return true;
    2809             :                 }
    2810          33 :                 else if ((polMap->find(Stokes::XX) != polMap->end()) and (polMap->find(Stokes::YY) != polMap->end()))
    2811             :                 {
    2812          33 :                         return true;
    2813             :                 }
    2814           0 :                 else if ((polMap->find(Stokes::RR) != polMap->end()) and (polMap->find(Stokes::LL) != polMap->end()))
    2815             :                 {
    2816             : 
    2817           0 :                         return true;
    2818             :                 }
    2819             :                 else
    2820             :                 {
    2821           0 :                         *logger_p << LogIO::WARN <<  " Requested Stokes parameter (I) cannot be computed from available polarizations in current spectral window (" <<
    2822           0 :                                         visibilityBuffer_p->spectralWindows()(0) << ") " << LogIO::POST;
    2823           0 :                         return false;
    2824             :                 }
    2825             :         }
    2826        2033 :         else if (expression_p.find("Q") != string::npos)
    2827             :         {
    2828           0 :                 if (polMap->find(Stokes::Q) != polMap->end())
    2829             :                 {
    2830           0 :                         return true;
    2831             :                 }
    2832           0 :                 else if ((polMap->find(Stokes::XX) != polMap->end()) and (polMap->find(Stokes::YY) != polMap->end()))
    2833             :                 {
    2834           0 :                         return true;
    2835             :                 }
    2836           0 :                 else if ((polMap->find(Stokes::RL) != polMap->end()) and (polMap->find(Stokes::LR) != polMap->end()))
    2837             :                 {
    2838           0 :                         return true;
    2839             :                 }
    2840             :                 else
    2841             :                 {
    2842           0 :                         *logger_p << LogIO::WARN <<  " Requested Stokes parameter (Q) cannot be computed from available polarizations in current spectral window (" <<
    2843           0 :                                         visibilityBuffer_p->spectralWindows()(0) << ") " << LogIO::POST;
    2844           0 :                         return false;
    2845             :                 }
    2846             :         }
    2847        2033 :         else if (expression_p.find("U") != string::npos)
    2848             :         {
    2849           0 :                 if (polMap->find(Stokes::U) != polMap->end())
    2850             :                 {
    2851           0 :                         return true;
    2852             :                 }
    2853           0 :                 else if ((polMap->find(Stokes::XY) != polMap->end()) and (polMap->find(Stokes::YX) != polMap->end()))
    2854             :                 {
    2855           0 :                         return true;
    2856             :                 }
    2857           0 :                 else if ((polMap->find(Stokes::RL) != polMap->end()) and (polMap->find(Stokes::LR) != polMap->end()))
    2858             :                 {
    2859           0 :                         return true;
    2860             :                 }
    2861             :                 else
    2862             :                 {
    2863           0 :                         *logger_p << LogIO::WARN <<  " Requested Stokes parameter (U) cannot be computed from available polarizations in current spectral window (" <<
    2864           0 :                                         visibilityBuffer_p->spectralWindows()(0) << ") " << LogIO::POST;
    2865           0 :                         return false;
    2866             :                 }
    2867             :         }
    2868        2033 :         else if ((expression_p.find("V") != string::npos) and (expression_p.find("WVR") == string::npos))
    2869             :         {
    2870           0 :                 if (polMap->find(Stokes::V) != polMap->end())
    2871             :                 {
    2872           0 :                         return true;
    2873             :                 }
    2874           0 :                 else if ((polMap->find(Stokes::XY) != polMap->end()) and (polMap->find(Stokes::YX) != polMap->end()))
    2875             :                 {
    2876           0 :                         return true;
    2877             :                 }
    2878           0 :                 else if ((polMap->find(Stokes::RR) != polMap->end()) and (polMap->find(Stokes::LL) != polMap->end()))
    2879             :                 {
    2880           0 :                         return true;
    2881             :                 }
    2882             :                 else
    2883             :                 {
    2884           0 :                         *logger_p << LogIO::WARN <<  " Requested Stokes parameter (V) cannot be computed from available polarizations in current spectral window (" <<
    2885           0 :                                         visibilityBuffer_p->spectralWindows()(0) << ") " << LogIO::POST;
    2886           0 :                         return false;
    2887             :                 }
    2888             :         }
    2889        2033 :         else if (expression_p.find("SOL1") != string::npos)
    2890             :         {
    2891        1518 :                 if (polMap->find(VisMapper::CALSOL1) != polMap->end())
    2892             :                 {
    2893        1518 :                         return true;
    2894             :                 }
    2895             :                 else
    2896             :                 {
    2897           0 :                         *logger_p << LogIO::WARN <<  " Requested Calibration solution element (SOL1) not available" << LogIO::POST;
    2898           0 :                         return false;
    2899             :                 }
    2900             :         }
    2901         515 :         else if (expression_p.find("SOL2") != string::npos)
    2902             :         {
    2903         395 :                 if (polMap->find(VisMapper::CALSOL2) != polMap->end())
    2904             :                 {
    2905         395 :                         return true;
    2906             :                 }
    2907             :                 else
    2908             :                 {
    2909           0 :                         *logger_p << LogIO::WARN <<  " Requested Calibration solution element (SOL2) not available" << LogIO::POST;
    2910           0 :                         return false;
    2911             :                 }
    2912             :         }
    2913         120 :         else if (expression_p.find("SOL3") != string::npos)
    2914             :         {
    2915          60 :                 if (polMap->find(VisMapper::CALSOL3) != polMap->end())
    2916             :                 {
    2917           0 :                         return true;
    2918             :                 }
    2919             :                 else
    2920             :                 {
    2921          60 :                         *logger_p << LogIO::WARN <<  " Requested Calibration solution element (SOL3) not available" << LogIO::POST;
    2922          60 :                         return false;
    2923             :                 }
    2924             :         }
    2925          60 :         else if (expression_p.find("SOL4") != string::npos)
    2926             :         {
    2927          60 :                 if (polMap->find(VisMapper::CALSOL4) != polMap->end())
    2928             :                 {
    2929           0 :                         return true;
    2930             :                 }
    2931             :                 else
    2932             :                 {
    2933          60 :                         *logger_p << LogIO::WARN <<  " Requested Calibration solution element (SOL4) not available" << LogIO::POST;
    2934          60 :                         return false;
    2935             :                 }
    2936             :         }
    2937             :         else
    2938             :         {
    2939           0 :                 throw AipsError("Unknown polarization requested, (" + expression_p + ") supported types are: XX,YY,XY,YX,RR,LL,RL,LR,I,Q,U,V");
    2940             :                 return false;
    2941             :         }
    2942             :         return false;
    2943             : }
    2944             : 
    2945             : bool
    2946           0 : FlagAgentBase::computeRowFlags(const vi::VisBuffer2 &/*visBuffer*/, FlagMapper &/*flags*/, uInt /*row*/)
    2947             : {
    2948             :         // TODO: This method must be re-implemented in the derived classes
    2949           0 :         return false;
    2950             : }
    2951             : 
    2952             : bool
    2953           0 : FlagAgentBase::computeInRowFlags(const vi::VisBuffer2 &/*visBuffer*/, VisMapper &/*visibilities*/,
    2954             :                                  FlagMapper &/*flags*/, uInt /*row*/)
    2955             : {
    2956             :         // TODO: This method must be re-implemented in the derived classes
    2957           0 :         return false;
    2958             : }
    2959             : 
    2960             : bool
    2961           0 : FlagAgentBase::computeAntennaPairFlags(const vi::VisBuffer2 &/*visBuffer*/, VisMapper &/*visibilities*/,
    2962             :                                        FlagMapper &/*flags*/,Int /*antenna1*/,Int /*antenna2*/,
    2963             :                                        vector<uInt> &/*rows*/)
    2964             : {
    2965             :         // TODO: This method must be re-implemented in the derived classes
    2966           0 :         return false;
    2967             : }
    2968             : 
    2969             : bool
    2970           0 : FlagAgentBase::computeAntennaPairFlags(const vi::VisBuffer2 &/*visBuffer*/,FlagMapper &/*flags*/,
    2971             :                                        Int /*antenna1*/,Int /*antenna2*/,vector<uInt> &/*rows*/)
    2972             : {
    2973             :         // TODO: This method must be re-implemented in the derived classes
    2974           0 :         return false;
    2975             : }
    2976             : 
    2977             : FlagReport
    2978        1787 : FlagAgentBase::getReport()
    2979             : {
    2980             :         // TODO: This method must be re-implemented in the derived classes
    2981        1787 :         return FlagReport(String("none"),agentName_p);
    2982             : }
    2983             : 
    2984             : 
    2985             : ////////////////////////////////////
    2986             : /// FlagAgentList implementation ///
    2987             : ////////////////////////////////////
    2988             : 
    2989        1729 : FlagAgentList::FlagAgentList()
    2990             : {
    2991        1729 :         container_p.clear();
    2992        1729 : }
    2993             : 
    2994        1729 : FlagAgentList::~FlagAgentList()
    2995             : {
    2996        1729 :         clear();
    2997        1729 : }
    2998             : 
    2999        2247 : void FlagAgentList::push_back(FlagAgentBase *agent_i)
    3000             : {
    3001        2247 :         container_p.push_back(agent_i);
    3002             : 
    3003        2247 :         return;
    3004             : }
    3005             : 
    3006           0 : void FlagAgentList::pop_back()
    3007             : {
    3008           0 :         container_p.pop_back();
    3009             : 
    3010           0 :         return;
    3011             : }
    3012             : 
    3013        6431 : void FlagAgentList::clear()
    3014             : {
    3015        8678 :         for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3016             :         {
    3017        2247 :                 delete (*iterator_p);
    3018             :         }
    3019        6431 :         container_p.clear();
    3020             : 
    3021        6431 :         return;
    3022             : }
    3023             : 
    3024        1245 : bool FlagAgentList::empty()
    3025             : {
    3026        1245 :         return container_p.empty();
    3027             : }
    3028             : 
    3029        3734 : size_t FlagAgentList::size()
    3030             : {
    3031        3734 :         return container_p.size();
    3032             : }
    3033             : 
    3034        1244 : void FlagAgentList::start()
    3035             : {
    3036        3485 :         for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3037             :         {
    3038        2241 :                 (*iterator_p)->start();
    3039             :         }
    3040        1244 :         return;
    3041             : }
    3042             : 
    3043        1244 : void FlagAgentList::terminate()
    3044             : {
    3045        3485 :         for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3046             :         {
    3047        2241 :                 (*iterator_p)->terminate();
    3048             :         }
    3049             : 
    3050        1244 :         return;
    3051             : }
    3052             : 
    3053        1244 : void FlagAgentList::join()
    3054             : {
    3055        3485 :         for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3056             :         {
    3057        2241 :                 if ((*iterator_p)->backgroundMode_p)
    3058             :                 {
    3059           0 :                         (*iterator_p)->join();
    3060             :                 }
    3061             :         }
    3062             : 
    3063        1244 :         return;
    3064             : }
    3065             : 
    3066      600713 : void FlagAgentList::apply(bool sequential)
    3067             : {
    3068      600713 :         if (sequential)
    3069             :         {
    3070     1394868 :                 for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3071             :                 {
    3072      794155 :                         (*iterator_p)->queueProcess();
    3073      794155 :                         (*iterator_p)->completeProcess();
    3074             :                 }
    3075             :         }
    3076             :         else
    3077             :         {
    3078           0 :                 for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3079             :                 {
    3080           0 :                         if ((*iterator_p)->flag_p == false) (*iterator_p)->queueProcess();
    3081             :                 }
    3082             : 
    3083           0 :                 for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3084             :                 {
    3085           0 :                         if ((*iterator_p)->flag_p == false) (*iterator_p)->completeProcess();
    3086             :                 }
    3087             : 
    3088           0 :                 for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3089             :                 {
    3090           0 :                         if ((*iterator_p)->flag_p == true) (*iterator_p)->queueProcess();
    3091             :                 }
    3092             : 
    3093           0 :                 for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3094             :                 {
    3095           0 :                         if ((*iterator_p)->flag_p == true) (*iterator_p)->completeProcess();
    3096             :                 }
    3097             :         }
    3098             : 
    3099      600713 :         return;
    3100             : }
    3101             : 
    3102       15778 : void FlagAgentList::chunkSummary()
    3103             : {
    3104       35678 :         for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3105             :         {
    3106       19900 :                 (*iterator_p)->chunkSummary();
    3107             :         }
    3108             : 
    3109       15778 :         return;
    3110             : }
    3111             : 
    3112        1244 : void FlagAgentList::tableSummary()
    3113             : {
    3114        3485 :         for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3115             :         {
    3116        2241 :                 (*iterator_p)->tableSummary();
    3117             :         }
    3118             : 
    3119        1244 :         return;
    3120             : }
    3121             : 
    3122           0 : void FlagAgentList::setProfiling(bool enable)
    3123             : {
    3124           0 :         for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3125             :         {
    3126           0 :                 (*iterator_p)->setProfiling(enable);
    3127             :         }
    3128             : 
    3129           0 :         return;
    3130             : }
    3131             : 
    3132           0 : void FlagAgentList::setCheckMode(bool enable)
    3133             : {
    3134           0 :         for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3135             :         {
    3136           0 :                 (*iterator_p)->setCheckMode(enable);
    3137             :         }
    3138             : 
    3139           0 :         return;
    3140             : }
    3141             : 
    3142        1244 : FlagReport FlagAgentList::gatherReports()
    3143             : {
    3144        2488 :         FlagReport combinedReport("list");
    3145             : 
    3146        3485 :         for (iterator_p = container_p.begin();iterator_p != container_p.end(); iterator_p++)
    3147             :         {
    3148        2241 :                 combinedReport.addReport( (*iterator_p)->getReport() );
    3149             :         }
    3150             : 
    3151        1244 :         return combinedReport;
    3152             : }
    3153             : 
    3154             : 
    3155             : } //# NAMESPACE CASA - END
    3156             : 
    3157             : 

Generated by: LCOV version 1.16