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

Generated by: LCOV version 1.16