//# FlagAgentClipping.cc: This file contains the implementation of the FlagAgentClipping class. //# //# CASA - Common Astronomy Software Applications (http://casa.nrao.edu/) //# Copyright (C) Associated Universities, Inc. Washington DC, USA 2011, All rights reserved. //# Copyright (C) European Southern Observatory, 2011, All rights reserved. //# //# This library is free software; you can redistribute it and/or //# modify it under the terms of the GNU Lesser General Public //# License as published by the Free software Foundation; either //# version 2.1 of the License, or (at your option) any later version. //# //# This library is distributed in the hope that it will be useful, //# but WITHOUT ANY WARRANTY, without even the implied warranty of //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //# Lesser General Public License for more details. //# //# You should have received a copy of the GNU Lesser General Public //# License along with this library; if not, write to the Free Software //# Foundation, Inc., 59 Temple Place, Suite 330, Boston, //# MA 02111-1307 USA //# $Id: $ #include <flagging/Flagging/FlagAgentClipping.h> using namespace casacore; namespace casa { //# NAMESPACE CASA - BEGIN FlagAgentClipping::FlagAgentClipping(FlagDataHandler *dh, Record config, Bool writePrivateFlagCube, Bool flag): FlagAgentBase(dh,config,IN_ROWS,writePrivateFlagCube,flag) { setAgentParameters(config); // Request loading polarization map to FlagDataHandler flagDataHandler_p->setMapPolarizations(true); } FlagAgentClipping::~FlagAgentClipping() { // Compiler automagically calls FlagAgentBase::~FlagAgentBase() } void FlagAgentClipping::setAgentParameters(Record config) { logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE)); int exists; // First check basic configuration to see what modules are plugged in the check exists = config.fieldNumber ("clipzeros"); if (exists >= 0) { if( config.type(exists) != TpBool ) { throw( AipsError ( "Parameter 'clipzeros' must be of type 'bool'" ) ); } clipzeros_p = config.asBool("clipzeros"); } else { clipzeros_p = false; } *logger_p << logLevel_p << " clipzeros is " << clipzeros_p << LogIO::POST; exists = config.fieldNumber ("clipoutside"); if (exists >= 0) { if( config.type(exists) != TpBool ) { throw( AipsError ( "Parameter 'clipoutside' must be of type 'bool'" ) ); } clipoutside_p = config.asBool("clipoutside"); } else { clipoutside_p = true; } *logger_p << logLevel_p << " clipoutside is " << clipoutside_p << LogIO::POST; String datacol = ""; weightcol_p = false; exists = config.fieldNumber ("datacolumn"); if (exists >= 0) { datacol = config.asString("datacolumn"); } exists = config.fieldNumber ("clipminmax"); if (exists >= 0) { if( config.type(exists) != TpArrayDouble && config.type(exists) != TpArrayFloat && config.type(exists) != TpArrayInt ) { throw( AipsError ( "Parameter 'clipminmax' must be of type 'array double' : [minval,maxval]" ) ); } Array<Double> cliprange = config.asArrayDouble("clipminmax"); if (cliprange.size() == 2) { Bool deleteIt = false; clipmin_p = cliprange.getStorage(deleteIt)[0]; clipmax_p = cliprange.getStorage(deleteIt)[1]; *logger_p << logLevel_p << " clipmin is " << clipmin_p << LogIO::POST; *logger_p << logLevel_p << " clipmax is " << clipmax_p << LogIO::POST; clipminmax_p = true; // for the moment, treat WEIGHT as if it was WEIGHT_SPECTRUM, // so the clipminmax given by the user is divided by the // number of channels inside preProcessBuffer() if (datacol.compare("WEIGHT") == 0) { weightcol_p = true; original_clipmin_p = clipmin_p; original_clipmax_p = clipmax_p; } } else { clipminmax_p = false; *logger_p << logLevel_p << " clipminmax range not provided" << LogIO::POST; } } else { clipminmax_p = false; *logger_p << logLevel_p << " clipminmax range not provided" << LogIO::POST; } // Then, point to the function covering for all the modules selected if (clipminmax_p) { if (clipoutside_p) { if (clipzeros_p) { checkVis_p = &FlagAgentClipping::checkVisForClipOutsideAndZeros; *logger_p << logLevel_p << " Clipping outside [" << clipmin_p << "," << clipmax_p << "], plus NaNs and zeros" << LogIO::POST; } else { checkVis_p = &FlagAgentClipping::checkVisForClipOutside; *logger_p << logLevel_p << " Clipping outside [" << clipmin_p << "," << clipmax_p << "], plus NaNs" << LogIO::POST; } } else { if (clipzeros_p) { checkVis_p = &FlagAgentClipping::checkVisForClipInsideAndZeros; *logger_p << logLevel_p << " Clipping inside [" << clipmin_p << "," << clipmax_p << "], plus NaNs and zeros" << LogIO::POST; } else { checkVis_p = &FlagAgentClipping::checkVisForClipInside; *logger_p << logLevel_p << " Clipping inside [" << clipmin_p << "," << clipmax_p << "], plus NaNs" << LogIO::POST; } } } else { if (clipzeros_p) { checkVis_p = &FlagAgentClipping::checkVisForNaNsAndZeros; *logger_p << logLevel_p << " Clipping range not provided, clipping NaNs and zeros" << LogIO::POST; } else { checkVis_p = &FlagAgentClipping::checkVisForNaNs; *logger_p << logLevel_p << " Clipping range not provided, clipping only NaNs" << LogIO::POST; } } return; } // jagonzal: With the new WEIGHT/SIGMA convention it is not longer // necessary divide the clipping range between the number of channels /* void FlagAgentClipping::preProcessBuffer(const vi::VisBuffer2 &visBuffer) { logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE)); // Only done if datacolumn is WEIGHT if (weightcol_p) { Int nChannels; nChannels = visBuffer.nChannels(); clipmin_p = original_clipmin_p/nChannels; clipmax_p = original_clipmax_p/nChannels; } *logger_p << LogIO::DEBUG1 << " clipmin is " << clipmin_p << LogIO::POST; *logger_p << LogIO::DEBUG1 << " clipmax is " << clipmax_p << LogIO::POST; } */ bool FlagAgentClipping::computeInRowFlags(const vi::VisBuffer2 &/*visBuffer*/, VisMapper &visibilities, FlagMapper &flags, uInt row) { // Get flag cube size Float visExpression; Int nPols,nChannels,nTimesteps; visibilities.shape(nPols, nChannels, nTimesteps); for (uInt chan_i=0;chan_i<(uInt) nChannels;chan_i++) { for (uInt pol_i=0;pol_i<(uInt) nPols;pol_i++) { visExpression = visibilities(pol_i,chan_i,row); if ((*this.*checkVis_p)(visExpression)) { flags.applyFlag(pol_i,chan_i,row); visBufferFlags_p += 1; } } } return false; } bool FlagAgentClipping::checkVisForClipOutside(Float visExpression) { if ((visExpression > clipmax_p) or (visExpression < clipmin_p)) { return true; } else { return isNaN(visExpression); } } bool FlagAgentClipping::checkVisForClipInside(Float visExpression) { if ((visExpression <= clipmax_p) and (visExpression >= clipmin_p)) { return true; } else { return isNaN(visExpression); } } bool FlagAgentClipping::checkVisForClipOutsideAndZeros(Float visExpression) { if ((visExpression > clipmax_p) or (visExpression < clipmin_p)) { return true; } else { return isNaNOrZero(visExpression); } } bool FlagAgentClipping::checkVisForClipInsideAndZeros(Float visExpression) { if ((visExpression <= clipmax_p) and (visExpression >= clipmin_p)) { return true; } else { return isNaNOrZero(visExpression); } } bool FlagAgentClipping::checkVisForNaNs(Float visExpression) { return isNaN(visExpression); } bool FlagAgentClipping::checkVisForNaNsAndZeros(Float visExpression) { return isNaNOrZero(visExpression); } } //# NAMESPACE CASA - END