LCOV - code coverage report
Current view: top level - synthesis/MeasurementComponents - CalibratingVi2.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 217 316 68.7 %
Date: 2024-12-11 20:54:31 Functions: 31 44 70.5 %

          Line data    Source code
       1             : //# CalibratingVi2.cc: Implementation of the CalibratingVi2 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 <synthesis/MeasurementComponents/CalibratingVi2.h>
      24             : #include <synthesis/MeasurementComponents/Calibrater.h>
      25             : #include <synthesis/CalLibrary/CalLibraryTools.h>
      26             : #include <casacore/casa/Arrays/ArrayPartMath.h>
      27             : #include <casacore/casa/Arrays/MaskArrMath.h>
      28             : 
      29             : #ifdef _OPENMP
      30             : #include <omp.h>
      31             : #endif
      32             : 
      33             : using namespace casacore;
      34             : namespace casa { //# NAMESPACE CASA - BEGIN
      35             : 
      36             : namespace vi { //# NAMESPACE VI - BEGIN
      37             : 
      38             : 
      39             : 
      40             : 
      41             : // -----------------------------------------------------------------------
      42             : //
      43             : 
      44           9 : CalibratingParameters::CalibratingParameters() :
      45           9 :   byCalLib_p(false),
      46           9 :   calLibRecord_p(Record()),
      47           9 :   corrFactor_p(1.0)  // temporary, for initial testing  (default is a non-trivial factor)
      48           9 : {}
      49             : 
      50           9 : CalibratingParameters::CalibratingParameters(const Record& calLibRecord) :
      51           9 :   byCalLib_p(false),
      52           9 :   calLibRecord_p(calLibRecord),
      53           9 :   corrFactor_p(1.0)  
      54             : {
      55             : 
      56           9 :   if (calLibRecord_p.isDefined("calfactor")) {
      57             :     //cout << "CalibratingParameters::ctor:  found calfactor." << endl;
      58             :     // Detect calfactor in the specified Record
      59           0 :     corrFactor_p=calLibRecord_p.asFloat("calfactor");
      60           0 :     byCalLib_p = false;  // signal not using a real callib
      61             :   }
      62           9 :   else if (calLibRecord_p.nfields()>0) {
      63             :     //cout << "CalibratingParameters::ctor:  found non-trivial callib." << endl;
      64             :     // Apparently this will be a real callib
      65           9 :     byCalLib_p = true;   // signal using a real callib
      66             :   }
      67             :   else
      68           0 :     throw(AipsError("Invalid use of callib Record"));
      69           9 :   validate();
      70           9 : }
      71             : 
      72             : // Construct using callib parser
      73           0 : CalibratingParameters::CalibratingParameters(const String& callib) :
      74           0 :   byCalLib_p(true),
      75           0 :   calLibRecord_p(callibSetParams(callib)),
      76           0 :   corrFactor_p(1.0)  
      77             : {
      78           0 :   validate();
      79           0 : }
      80             : 
      81           0 : CalibratingParameters::CalibratingParameters(Float corrFactor) :
      82           0 :   byCalLib_p(false),
      83           0 :   calLibRecord_p(Record()),
      84           0 :   corrFactor_p(corrFactor)  // temporary, for initial testing
      85             : {
      86           0 :   validate();
      87           0 : }
      88             : 
      89           0 : CalibratingParameters::CalibratingParameters(const CalibratingParameters& other)
      90             : {
      91           0 :   *this = other;
      92           0 : }
      93             : 
      94           9 : CalibratingParameters& CalibratingParameters::operator=(const CalibratingParameters& other)
      95             : {
      96           9 :   if (this != &other) {
      97           9 :     byCalLib_p = other.byCalLib_p;
      98           9 :     calLibRecord_p = other.calLibRecord_p;
      99           9 :     corrFactor_p = other.corrFactor_p;
     100           9 :     validate();
     101             :   }
     102           9 :   return *this;
     103             : }
     104             : 
     105           9 : Bool CalibratingParameters::byCalLib() const
     106             : {
     107           9 :   return byCalLib_p;
     108             : }
     109             : 
     110          18 : const Record& CalibratingParameters::getCalLibRecord() const
     111             : {
     112          18 :   return calLibRecord_p;
     113             : }
     114             : 
     115             : // temporary, for initial testing
     116           0 : Float CalibratingParameters::getCorrFactor() const
     117             : {
     118           0 :   return corrFactor_p;
     119             : }
     120             : 
     121             : 
     122           0 : void CalibratingParameters::setCalLibRecord(const Record& calLibRecord)
     123             : {
     124           0 :   calLibRecord_p = calLibRecord;
     125           0 : }
     126             : 
     127             : // temporary, for initial testing
     128           0 : void CalibratingParameters::setCorrFactor(Float corrFactor)
     129             : {
     130           0 :   corrFactor_p = corrFactor;
     131           0 : }
     132             : 
     133          18 : void CalibratingParameters::validate() const
     134             : {
     135             :   // nothing meaningful to do yet
     136          18 : }
     137             : 
     138             : 
     139             : 
     140             : // -----------------------------------------------------------------------
     141           0 : CalibratingVi2::CalibratingVi2( vi::ViImplementation2 * inputVii,
     142           0 :                                 const CalibratingParameters& calpar) :
     143             :   TransformingVi2 (inputVii),
     144           0 :   cb_p(0),
     145           0 :   ve_p(0),
     146           0 :   corrFactor_p(calpar.getCorrFactor()), // temporary
     147           0 :   visCalibrationOK_p(False)
     148             : {
     149             : 
     150             :   // Initialize underlying ViImpl2
     151           0 :   getVii()->originChunks();
     152           0 :   getVii()->origin();
     153             :  
     154             :   // Make the internal VisBuffer2 for CalibratingVi2 clients
     155           0 :   setVisBuffer(createAttachedVisBuffer (VbRekeyable));
     156             : 
     157           0 : }
     158             : 
     159             : // -----------------------------------------------------------------------
     160           9 : CalibratingVi2::CalibratingVi2( vi::ViImplementation2 * inputVii,
     161             :                                 const CalibratingParameters& calpar,
     162           9 :                                 String msname) :
     163             :   TransformingVi2 (inputVii),
     164             :   //cb_p(new OldCalibrater(msname)),
     165           9 :   cb_p(Calibrater::factory(msname)),
     166           9 :   ve_p(0),
     167           9 :   corrFactor_p(1.0),
     168           9 :   visCalibrationOK_p(False)
     169             : {
     170             : 
     171           9 :   if (calpar.byCalLib()) {
     172             :     // Arrange calibration
     173           9 :     cb_p->validatecallib(calpar.getCalLibRecord());
     174           9 :     cb_p->setcallib2(calpar.getCalLibRecord(),&(inputVii->ms())); // Use underlying MS!
     175           9 :     cb_p->applystate();
     176             :     // Point to VisEquation
     177           9 :     ve_p = cb_p->ve();
     178             :   }
     179             :   else {
     180             :     // Simple mode using only the calfactor (good for tests)
     181           0 :     corrFactor_p=calpar.getCorrFactor();
     182             :   }
     183             : 
     184             :   // Initialize underlying ViImpl2
     185           9 :   getVii()->originChunks();
     186           9 :   getVii()->origin();
     187             :  
     188             :   // Make a VisBuffer for CalibratingVi2 clients 
     189           9 :   setVisBuffer(createAttachedVisBuffer (VbRekeyable));
     190             : 
     191           9 : }
     192             : // -----------------------------------------------------------------------
     193         168 : CalibratingVi2::CalibratingVi2( vi::ViImplementation2 * inputVii,
     194         168 :                                 VisEquation *ve) :
     195             :   TransformingVi2 (inputVii),
     196         168 :   cb_p(0),
     197         168 :   ve_p(ve),
     198         168 :   corrFactor_p(1.0),
     199         168 :   visCalibrationOK_p(False)
     200             : {
     201             : 
     202             :   // Initialize underlying ViImpl2
     203         168 :   getVii()->originChunks();
     204         168 :   getVii()->origin();
     205             :  
     206             :   // Make a VisBuffer for CalibratingVi2 clients
     207         168 :   setVisBuffer(createAttachedVisBuffer (VbRekeyable));
     208             : 
     209         168 : }
     210             : 
     211             : // -----------------------------------------------------------------------
     212             : //
     213             : // -----------------------------------------------------------------------
     214         186 : CalibratingVi2::~CalibratingVi2()
     215             : {
     216             :   //  cout << "  ~CalVi2:      " << this << endl;
     217             :   // ve_p is a borrowed pointer, so need not delete here
     218         177 :   ve_p=0;
     219             : 
     220             :   // Delete Calibrater object if present
     221         177 :   if (cb_p) delete cb_p;
     222         177 :   cb_p=0;
     223             : 
     224         186 : }
     225             : 
     226             : 
     227             : 
     228             : // -----------------------------------------------------------------------
     229             : //
     230             : // -----------------------------------------------------------------------
     231             : void
     232          21 : CalibratingVi2::origin() 
     233             : {
     234             : 
     235             :   // Drive underlying VII2
     236          21 :   getVii()->origin();
     237             : 
     238             :   // Keep my VB2 happily synchronized
     239             :   //  (this comes from TransformingVi2)
     240          21 :   configureNewSubchunk();
     241             : 
     242             :   // Data/wts not yet corrected
     243          21 :   visCalibrationOK_p=False;
     244          21 : }
     245             : 
     246             : // -----------------------------------------------------------------------
     247             : //
     248             : // -----------------------------------------------------------------------
     249         180 : void CalibratingVi2::next() 
     250             : {
     251             : 
     252             :   // Drive underlying VII2
     253         180 :   getVii()->next();
     254             : 
     255             :   // Keep my VB2 happily synchronized
     256             :   //  (this comes from TransformingVi2)
     257         180 :   configureNewSubchunk();
     258             : 
     259             :   // Data/wts not yet corrected
     260         180 :   visCalibrationOK_p=False;
     261             : 
     262         180 : }
     263             : 
     264             : // -----------------------------------------------------------------------
     265             : //
     266             : // -----------------------------------------------------------------------
     267      272005 : void CalibratingVi2::flag(Cube<Bool>& flagC) const
     268             : {
     269             :   //  cout << "CVI2::flag(Cube)...";
     270             : 
     271             :   // Call for correction, which might set some flags
     272      272005 :   calibrateCurrentVB();
     273             : 
     274             :   // copy result to caller's Cube<Bool>
     275      272005 :   flagC.assign(getVii()->getVisBuffer()->flagCube());
     276             : 
     277      272005 : }
     278             : 
     279             : 
     280             : // -----------------------------------------------------------------------
     281             : //
     282             : // -----------------------------------------------------------------------
     283       31701 : void CalibratingVi2::weight(Matrix<Float>& wt) const
     284             : {
     285             :  
     286             :   //  cout << "CVI2::weight...";
     287             : 
     288             :   // Call for correction
     289             :   //   TBD: optimize w.r.t. calibrating only the weights?
     290       31701 :   calibrateCurrentVB();
     291             : 
     292             :   // copy result to caller's Matrix<Float>
     293       31701 :   wt.assign(getVii()->getVisBuffer()->weight());
     294             : 
     295       31701 : }
     296             : 
     297             : 
     298             : // -----------------------------------------------------------------------
     299             : //
     300             : // -----------------------------------------------------------------------
     301      264697 : void CalibratingVi2::weightSpectrum(Cube<Float>& wtsp) const
     302             : {
     303             : 
     304             :   //  cout << "CVI2::weightSpectrum...";
     305             : 
     306      264697 :   if (this->weightSpectrumExists()) {
     307             : 
     308             :     // Call for correction
     309             :     //   TBD: optimize w.r.t. calibrating only the weights?
     310      264697 :     calibrateCurrentVB();
     311             :     
     312             :     // copy result to caller's Matrix<Float>
     313      264697 :     wtsp.assign(getVii()->getVisBuffer()->weightSpectrum());
     314             : 
     315             :   }
     316             :   else {
     317             :     // same as ordinary VisibilityIteratorImpl2
     318           0 :     wtsp.resize(0,0,0);
     319             :   }
     320      264697 : }
     321             : 
     322             : 
     323             : 
     324             : 
     325             : // -----------------------------------------------------------------------
     326             : //
     327             : // -----------------------------------------------------------------------
     328      264697 : void CalibratingVi2::visibilityCorrected(Cube<Complex>& vis) const
     329             : {
     330             : 
     331             :   //  cout << "CVI2::visibilityCorrected...";
     332             : 
     333             :   // TBD:
     334             :   //  o consider if underlying VisBuffer should be maintained const? 
     335             :   //       (and this layer's VB set and adjusted)
     336             :   //       (will this break on-demand VB stuff?)
     337             :   //  o make corresponding visibilityModel method...  (solve context)
     338             : 
     339             :   // Call the actual correction method
     340             :   //  (only does the actual work, if needed)
     341      264697 :   calibrateCurrentVB();
     342             : 
     343             :   // copy result to caller's Cube<Complex>
     344      264697 :   vis.assign(getVii()->getVisBuffer()->visCubeCorrected());
     345             : 
     346      264697 : }
     347             : 
     348             : 
     349             : 
     350             : // -----------------------------------------------------------------------
     351             : //
     352             : // -----------------------------------------------------------------------
     353       27312 : Bool CalibratingVi2::existsColumn(VisBufferComponent2 id) const
     354             : {
     355             :     Bool result;
     356       27312 :     switch (id){
     357             : 
     358       16990 :     case VisBufferComponent2::VisibilityCorrected:
     359             :     case VisBufferComponent2::VisibilityCubeCorrected:
     360             :     case VisBufferComponent2::VisibilityCubeModel:
     361             : 
     362       16990 :         result = true;
     363       16990 :         break;
     364             : 
     365       10322 :     default:
     366       10322 :         result = getVii()->existsColumn(id);
     367       10322 :         break;
     368             :     }
     369             : 
     370       27312 :     return result;
     371             : 
     372             : }
     373             : 
     374             : // -----------------------------------------------------------------------
     375             : //
     376             : // -----------------------------------------------------------------------
     377         720 : void CalibratingVi2::calibrateCurrentVB() const
     378             : {
     379             :   // This method must call NO ordinary VB2 accessors that require ViImpl 
     380             :   //   methods that are defined in this class, _even_implicitly_, because 
     381             :   //   the VB2 uses the VI2 that has its ViImpl overridden by these local 
     382             :   //   methods.  This causes infinite loops!!!
     383             :   // One way to avoid this is to ensure that every method in this class 
     384             :   //   initializes the VB2 fields via getVii() methods.....
     385             : 
     386             :   //  cout << " calibrateCurrentVB(): " << boolalpha << visCalibrationOK_p;
     387             : 
     388             :   // Do the correction, if not done yet
     389         720 :   if (!visCalibrationOK_p) {
     390             : 
     391             :     // We will operate on the underlying VB
     392         180 :     VisBuffer2 *vb = getVii()->getVisBuffer();
     393             : 
     394             :     // sense if WEIGHT_SPECTRUM exists
     395         180 :     Bool doWtSp = getVii()->weightSpectrumExists();
     396             : 
     397             :     // Fill current flags, raw weights, and raw vis
     398         180 :     vb->flagCube();
     399         180 :     vb->resetWeightsUsingSigma();  //  this is smart re spec weights or not
     400             : 
     401             :     // Initialize "corrected" data from "raw" data
     402         180 :     initCorrected(vb);
     403             : 
     404             :     // If the VisEquation is set, use it, otherwise use the corrFactor_p
     405         180 :     if (ve_p) {
     406             :       // Apply calibration via the VisEquation
     407         180 :       ve_p->correct2(*vb,False,doWtSp);
     408             : 
     409             :       // Set unchan'd weights, in case they are requested
     410         180 :       if (doWtSp)
     411         180 :         vb->setWeight(partialMedians(vb->weightSpectrum(),IPosition(1,1)));
     412             :         
     413             :     }
     414             :     else {
     415             :     
     416             :       // Use supplied corrFactor_p to make this corrected data look changed
     417           0 :       Cube<Complex> vCC(vb->visCubeCorrected());
     418           0 :       vCC*=corrFactor_p;
     419           0 :       vb->setVisCubeCorrected(vCC);
     420             :       
     421           0 :       if (doWtSp) {
     422             :         // Calibrate the WS
     423           0 :         Cube<Float> wS(vb->weightSpectrum());   // Was set above
     424           0 :         wS/=(corrFactor_p*corrFactor_p);
     425           0 :         vb->setWeightSpectrum(wS);
     426             :         // Set W via median on chan axis
     427           0 :         vb->setWeight(partialMedians(wS,IPosition(1,1)));
     428           0 :       }
     429             :       else {
     430             :         // Just calibrate the W
     431           0 :         Matrix<Float> w(vb->weight());          // Was set above
     432           0 :         w/=(corrFactor_p*corrFactor_p);
     433           0 :         vb->setWeight(w);
     434           0 :       }
     435           0 :     }
     436             : 
     437             :     // Signal that we have applied the correction, to avoid unnecessary redundancy
     438         180 :     visCalibrationOK_p=True;
     439             : 
     440             :     //    cout << "-->" << visCalibrationOK_p;
     441             : 
     442             :   }    
     443             :   //  cout << endl;
     444         720 : }
     445             : 
     446      264697 : void CalibratingVi2::initCorrected(casa::vi::VisBuffer2* vb) const {
     447             : 
     448      264697 :   if (getVii()->existsColumn(VisBufferComponent2::VisibilityCubeFloat)) {
     449             :     // Convert FLOAT_DATA to Complex, and assign
     450        1658 :     Cube<Float> f(vb->visCubeFloat());
     451        1658 :     Cube<Complex> c;
     452        1658 :     c.resize(f.shape());
     453        1658 :     convertArray(c,f);
     454        1658 :     vb->setVisCubeCorrected(c);
     455        1658 :   }
     456             :   else
     457             :     // Just copy the (already-Complex DATA column)
     458      263039 :     vb->setVisCubeCorrected(vb->visCube());
     459             : 
     460             :   //  cout << "CalVi2::setCorrected()" << endl;
     461      264697 : }
     462             : 
     463           0 : CalVi2LayerFactory::CalVi2LayerFactory(const CalibratingParameters& pars)
     464             :   : ViiLayerFactory(),
     465           0 :     calpars_(pars)
     466           0 : {}
     467             : 
     468             : 
     469             : // CalVi2-specific layer-creater
     470           0 : ViImplementation2 * CalVi2LayerFactory::createInstance (ViImplementation2* vii0) const {
     471             :   // Make the CalibratingVi2, using supplied ViImplementation2, and return it
     472           0 :   ViImplementation2 *vii = new CalibratingVi2(vii0,calpars_);
     473           0 :   return vii;
     474             : }
     475             : 
     476             : 
     477             :  /********************************/
     478             : 
     479             : 
     480             : // -----------------------------------------------------------------------
     481           0 : CalSolvingVi2::CalSolvingVi2(   vi::ViImplementation2 * inputVii,
     482           0 :                                 const CalibratingParameters& calpar) :
     483             :   CalibratingVi2 (inputVii,calpar),
     484           0 :   corrDepFlags_(false)
     485             : {
     486           0 :   corrFactor_p=sqrt(corrFactor_p);
     487           0 : }
     488             : 
     489             : // -----------------------------------------------------------------------
     490           0 : CalSolvingVi2::CalSolvingVi2( vi::ViImplementation2 * inputVii,
     491             :                                 const CalibratingParameters& calpar,
     492           0 :                                 String msname) :
     493             :   CalibratingVi2 (inputVii,calpar,msname),
     494           0 :   corrDepFlags_(false)
     495             : {
     496             :   // Nothing specialized to do here (except ctor parent, above)
     497           0 : }
     498             : 
     499             : // -----------------------------------------------------------------------
     500         168 : CalSolvingVi2::CalSolvingVi2( vi::ViImplementation2 * inputVii,
     501             :                               VisEquation *ve,
     502         168 :                               const Bool& corrDepFlags) :
     503             :   CalibratingVi2 (inputVii,ve),
     504         168 :   corrDepFlags_(corrDepFlags)
     505             : {
     506             :   // Nothing specialized to do here (except ctor parent, above)
     507         168 : }
     508             : 
     509             : //#define REPORTTIMING
     510             : 
     511             : // -----------------------------------------------------------------------
     512             : //
     513             : // -----------------------------------------------------------------------
     514         336 : CalSolvingVi2::~CalSolvingVi2()
     515             : {
     516             :   //  cout << "   ~CalSolVi2:  " << this << endl;
     517             :   //  cout << "CSVi2::calibrateCurrentVB: Is WtSpec automatic?" << endl;
     518             :   // Nothing specialized to do here (except ctor parent, above)
     519             : 
     520             : #ifdef REPORTTIMEING
     521             :   cout << "CalSolvingVi2 stats: " << endl;
     522             :   cout << " nVB_=" << nVB_
     523             :        << " nVB0_=" << nVB0_ << endl;
     524             : 
     525             :   cout << " Tcal_=" 
     526             :        << Tcalws_ 
     527             :        << "+" << Tcalfl_ 
     528             :        << "+" << Tcal2_ 
     529             :        << "=" << Tcalws_+Tcalfl_+Tcal2_
     530             :        << endl;
     531             : 
     532             :   cout << " Tio_=" << Tio_ 
     533             :        << endl;
     534             :   cout << "  Samples=" 
     535             :        << " total=" << ntotal_ 
     536             :        << " flagged=" << nflagged_ << " (" << Double(nflagged_)/Double(ntotal_) << " of total)"
     537             :        << " skippable=" << nskipped_ << " (" << Double(nskipped_)/Double(nflagged_) << " of flagged)"
     538             :        << endl;
     539             :   cout << " spurious fraction=" << Double(nflagged_-nskipped_)/Double(ntotal_-nskipped_) << endl;
     540             :   cout << " good     fraction=" << Double(ntotal_-nflagged_)/Double(ntotal_-nskipped_) << endl;
     541             : #endif
     542             : 
     543             : 
     544         336 : }
     545             : 
     546             : // -----------------------------------------------------------------------
     547             : //
     548             : // -----------------------------------------------------------------------
     549             : void
     550         552 : CalSolvingVi2::originChunks(casacore::Bool forceRewind) 
     551             : {
     552             : 
     553             :   // Zero counters/timers
     554         552 :   ntotal_=nflagged_=nskipped_=nVB_=nVB0_=0;
     555         552 :   Tio_=Tcalws_=Tcalfl_=Tcal2_=0.0;
     556             : 
     557             :   // Call next layer
     558         552 :   getVii()->originChunks(forceRewind);
     559         552 : }
     560             : 
     561             : // -----------------------------------------------------------------------
     562             : //
     563             : // -----------------------------------------------------------------------
     564             : void
     565       19847 : CalSolvingVi2::origin() 
     566             : {
     567             : 
     568             :   // Drive underlying VII2
     569       19847 :   getVii()->origin();
     570             : 
     571             :   //ntotal_+=getVii()->getVisBuffer()->flagCube().nelements();
     572             :   //nflagged_+=ntrue(getVii()->getVisBuffer()->flagCube());
     573             : 
     574             :   //  if (nfalse(getVii()->getVisBuffer()->flagCube())==0) {
     575             :   //    cout << "Using (origin)..." << endl;
     576             :   //  }
     577             : 
     578             :   /*
     579             : 
     580             :   // Step over completely flagged VB2s in the current chunk
     581             :   // NB: last one will be used in any case
     582             :   if (getVii()->more()) {  // not already the last VB2 in this chunk
     583             :     while (getVii()->more()) { 
     584             :       if (nfalse(getVii()->getVisBuffer()->flagCube())==0) {
     585             :         // This VB2 is entirely flagged, step to next one
     586             :         getVii()->next();
     587             :         cout << "skipping (origin)..." << endl;
     588             :       }
     589             :       else
     590             :         // This VB2 has some unflagged data, so use it
     591             :         break;
     592             :     }
     593             :   }
     594             :   */
     595             :   /*
     596             :   cout << "Samples (origin) =" 
     597             :        << " total=" << ntotal_ 
     598             :        << " flagged=" << nflagged_ 
     599             :        << " skipped=" << nskipped_ 
     600             :        << endl;
     601             :   */
     602             :   // Keep my VB2 happily synchronized
     603             :   //  (this comes from TransformingVi2)
     604       19847 :   configureNewSubchunk();
     605             : 
     606             :   // Data/wts not yet corrected
     607       19847 :   visCalibrationOK_p=False;
     608       19847 : }
     609             : 
     610             : // -----------------------------------------------------------------------
     611             : //
     612             : // -----------------------------------------------------------------------
     613      264517 : void CalSolvingVi2::next() 
     614             : {
     615             : 
     616             :   // Drive underlying VII2
     617      264517 :   getVii()->next();
     618             : 
     619             :   /*
     620             : 
     621             :   // Step over completely flagged VB2s in the current chunk
     622             :   // NB: last one will be used in any case
     623             :   if (getVii()->more()) {  // not already the last VB2 in this chunk
     624             :     while (getVii()->more()) { 
     625             :       if (nfalse(getVii()->getVisBuffer()->flagCube())==0) {
     626             :         // This VB2 is entirely flagged, step to next one
     627             :         ntotal_+=getVii()->getVisBuffer()->flagCube().nelements();
     628             :         nflagged_+=ntrue(getVii()->getVisBuffer()->flagCube());
     629             :         nskipped_+=ntrue(getVii()->getVisBuffer()->flagCube());
     630             :         getVii()->next();
     631             :       }
     632             :       else
     633             :         // This VB2 has some unflagged data, so use it
     634             :         break;
     635             :     }
     636             :   }
     637             :   */
     638             : 
     639             :   // Keep my VB2 happily synchronized
     640             :   //  (this comes from TransformingVi2)
     641      264517 :   configureNewSubchunk();
     642             : 
     643             :   // Data/wts not yet corrected
     644      264517 :   visCalibrationOK_p=False;
     645             : 
     646             :   /*
     647             :   cout << "Samples (next)   =" 
     648             :        << " total=" << ntotal_ 
     649             :        << " flagged=" << nflagged_ 
     650             :        << " skipped=" << nskipped_ 
     651             :        << endl;
     652             :   */
     653             : 
     654      264517 : }
     655             : 
     656             : 
     657             : 
     658             : // -----------------------------------------------------------------------
     659      264517 : void CalSolvingVi2::visibilityModel(Cube<Complex>& mod) const
     660             : {
     661             : 
     662             :   //  cout << "CSVI2::visibilityModel...";
     663             : 
     664             :   // Call the actual correction method
     665             :   //  (only does the actual work, if needed)
     666      264517 :   calibrateCurrentVB();
     667             : 
     668             :   // copy result to caller's Cube<Complex>
     669             :   //  (this is no-op when mod has same data address as visCubeModel())
     670      264517 :   mod.assign(getVii()->getVisBuffer()->visCubeModel());
     671             : 
     672      264517 : }
     673             : 
     674             : // -----------------------------------------------------------------------
     675     1096897 : void CalSolvingVi2::calibrateCurrentVB() const
     676             : {
     677             : 
     678             :   //cout << " CalSolvingVi2::calibrateCurrentVB(): " << boolalpha << visCalibrationOK_p;
     679             : 
     680             : 
     681             :   // Do the correction, if not done yet
     682     1096897 :   if (!visCalibrationOK_p) {
     683             : 
     684             : #ifdef _OPENMP
     685      264517 :     Double time0=omp_get_wtime();
     686             : #endif
     687             : 
     688             :     // Count the VBs that we are processing
     689      264517 :     ++nVB_;
     690             : 
     691             :     // Get the underlying ViImpl2's VisBuffer, to munge it
     692      264517 :     VisBuffer2 *vb = getVii()->getVisBuffer();
     693             : 
     694             :     // sense if WEIGHT_SPECTRUM exists
     695             :     //  (should be true in CalSolvingVi2!)
     696      264517 :     Bool doWtSp = this->weightSpectrumExists();
     697             : 
     698             :     // Fill flags
     699      264517 :     Cube<Bool> fl(vb->flagCube());
     700             : 
     701             :     // Fill model
     702             :     // NB:  model-filling handled below, in ve_p (or on-demand)
     703      264517 :     vb->visCubeModel();
     704             : 
     705             :     // Initialize the to-be-calibrated weights 
     706             :     //   (this fills WS, if available from below)
     707             :     //  TBD: better semantics: vb->setCorrDataWtSpec(vb->dataWtSpec()); 
     708      264517 :     vb->resetWeightsUsingSigma();
     709             : 
     710             :     // Initialize corrected data w/ data
     711      264517 :     initCorrected(vb);
     712             : 
     713             :     // Counting
     714      264517 :     Int64 nsamp=fl.nelements();
     715      264517 :     if (nfalse(fl)==0) {
     716        1887 :       nskipped_+=nsamp;
     717        1887 :       ++nVB0_;
     718             :     }
     719      264517 :     ntotal_+=nsamp;
     720      264517 :     nflagged_+=ntrue(fl);
     721             : 
     722             : #ifdef _OPENMP
     723      264517 :     Double time1a=omp_get_wtime();
     724             : #endif
     725             : 
     726             :     // Ensure we got weightSpectrum (fill it, if not)
     727      264517 :     verifyWeightSpectrum(vb);
     728             : 
     729             : #ifdef _OPENMP
     730      264517 :     Double time1b=omp_get_wtime();
     731             : #endif
     732             : 
     733             :     // Set old-style flags, FOR NOW
     734      264517 :     if (!corrDepFlags_)
     735      262341 :       corrIndepFlags(vb);
     736             :     
     737             : #ifdef _OPENMP
     738      264517 :     Double time2=omp_get_wtime();
     739             : #endif
     740             : 
     741             :     // If the VisEquation is set, use it, otherwise use the corrFactor_p
     742      264517 :     if (ve_p) {
     743             :       
     744             :       // Apply calibration via the VisEquation
     745      264517 :       ve_p->collapse2(*vb);   // ,False,doWtSp);
     746             : 
     747             :       // Set unchan'd weights, in case they are requested
     748             :       //if (doWtSp)
     749             :       //  vb->setWeight(partialMedians(vb->weightSpectrum(),IPosition(1,1)));
     750             :         
     751             :     }
     752             :     else {
     753             :     
     754             :       // Use supplied corrFactor_p to make this corrected data look changed
     755             :       //  In leiu of working VisEquation that is TBD
     756             : 
     757             :       // Correct data
     758           0 :       Cube<Complex> vCC(vb->visCubeCorrected());
     759           0 :       vCC*=corrFactor_p;
     760           0 :       vb->setVisCubeCorrected(vCC);
     761             : 
     762             :       // Corrupt the model
     763           0 :       Cube<Complex> vCM(vb->visCubeModel());
     764           0 :       vCM/=corrFactor_p;
     765           0 :       vb->setVisCubeModel(vCM);
     766             : 
     767           0 :       Cube<Float> modA2(square(amplitude(vCM)));
     768           0 :       Cube<Bool> modmask(modA2>0.0f);
     769             : 
     770           0 :       MaskedArray<Complex> vCCm=vCC(modmask);
     771           0 :       MaskedArray<Complex> vCMm=vCM(modmask);
     772           0 :       MaskedArray<Float> modA2m(modA2(modmask));
     773             : 
     774             :       // Divide corr data by mod data (where mod non-zero)
     775           0 :       vCCm=vCCm/vCMm;
     776           0 :       vCMm=Complex(1.0);  // model now unity
     777             :       //vCMm=vCMm/vCMm;        // less efficient?
     778             :      
     779           0 :       if (doWtSp) {
     780             :         // Calibrate the WS
     781           0 :         Cube<Float> wS(vb->weightSpectrum());   // Was set above
     782           0 :         wS/=(corrFactor_p*corrFactor_p);
     783             : 
     784             :         // adjust for model division
     785           0 :         MaskedArray<Float> wSm(wS(modmask));
     786           0 :         wSm=wSm*modA2m;
     787             : 
     788           0 :         vb->setWeightSpectrum(wS);
     789             :         // Set W via median on chan axis
     790           0 :         vb->setWeight(partialMedians(wS,IPosition(1,1)));
     791           0 :       }
     792             :       else {
     793             :         // Just calibrate the W
     794           0 :         Matrix<Float> w(vb->weight());          // Was set above
     795           0 :         w/=(corrFactor_p*corrFactor_p);
     796           0 :         vb->setWeight(w);
     797           0 :       }
     798           0 :     }
     799             : 
     800             :     // Signal that we have applied the correction, to avoid unnecessary redundancy
     801      264517 :     visCalibrationOK_p=True;
     802             :     
     803             : #ifdef _OPENMP
     804      264517 :     Double time3=omp_get_wtime();
     805             : 
     806      264517 :     Double dTio=time1a-time0;
     807      264517 :     Double dTcalws=time1b-time1a;
     808      264517 :     Double dTcalfl=time2-time1b;
     809      264517 :     Double dTcal2=time3-time2;
     810      264517 :     Tio_+=dTio;
     811      264517 :     Tcalws_+=dTcalws;
     812      264517 :     Tcalfl_+=dTcalfl;
     813      264517 :     Tcal2_+=dTcal2;
     814             : #endif
     815             :     
     816             :     /*
     817             :     cout << "nVB_=" << nVB_
     818             :          << " dTio = " << dTio
     819             :          << " dTcal1 = " << dTcal1
     820             :          << " dTcal2 = " << dTcal2
     821             :          << " Tio_ = " << Tio_ 
     822             :          << " Tcal = " << Tcal1 
     823             :          << "+" << Tcal2_ 
     824             :          << "=" << Tcal1_+Tcal2_
     825             :          << endl;
     826             :     */
     827             : 
     828      264517 :   }
     829             :   
     830             :   //  cout << endl;
     831     1096897 : }
     832             : 
     833      262341 : void CalSolvingVi2::corrIndepFlags(casa::vi::VisBuffer2* vb) const {
     834             : 
     835      262341 :   if (vb->nCorrelations()==1)
     836             :     // Nothing to do if only one correlation
     837        7534 :     return;
     838             : 
     839             :   // If more than one correlation, if any is flagged, all are (per row, chan)
     840      254807 :   Cube<Bool> flc(vb->flagCube());
     841             : 
     842      254807 :   VectorIterator<Bool> fvi(flc,0);
     843      254807 :   Vector<Bool>& fviv(fvi.vector());  // stays sync'd!
     844      254807 :   Int nCor=fviv.nelements();
     845    98891460 :   while (!fvi.pastEnd()) {
     846   454613575 :     for (Int icor=0;icor<nCor;++icor) {
     847   355976922 :       if (fviv(icor)) {
     848    23764880 :         fviv.set(true);
     849    23764880 :         continue;  // jump out of icor loop if flag=T found
     850             :       }
     851             :     }
     852    98636653 :     fvi.next();
     853             :   }
     854             : 
     855      254807 :   return;
     856      254807 : }
     857             : 
     858      264517 : void CalSolvingVi2::verifyWeightSpectrum(casa::vi::VisBuffer2* vb) const {
     859             : 
     860             :   // If we didn't get WS from below, populate it in the specified vb
     861      264517 :   if (!getVii()->weightSpectrumExists()) {
     862      244213 :     IPosition sh=vb->getShape();
     863      244213 :     Cube<Float> wtsp(sh,0.0f);
     864             : 
     865             :     // Unchan'd weight as Cube w/ degenerate chan axis
     866      488426 :     Cube<Float> wtsp0(vb->weight().reform(IPosition(3,sh(0),1,sh(2))));
     867             :     
     868      244213 :     VectorIterator<Float> ivi(wtsp0,1);
     869      244213 :     Vector<Float>& iviv(ivi.vector());   // stays sync'd!
     870      244213 :     VectorIterator<Float> ovi(wtsp,1);
     871      244213 :     Vector<Float>& oviv(ovi.vector());   // stays sync'd!
     872             :     
     873    39178205 :     while (!ivi.pastEnd()) {
     874    38933992 :       oviv.set(iviv(0));
     875    38933992 :       ivi.next();
     876    38933992 :       ovi.next();
     877             :     }
     878             :     
     879             :     // Set it in the vb
     880      244213 :     vb->setWeightSpectrum(wtsp);
     881      244213 :   }
     882             :   
     883             :   // In all cases set flagged cells' weights to zero
     884             :   //  (This is ok in solving context.)
     885      264517 :   Cube<Float> wtsp(vb->weightSpectrum());
     886      264517 :   wtsp(vb->flagCube())=0.0;
     887             : 
     888      264517 : }
     889             : 
     890           0 : CalSolvingVi2LayerFactory::CalSolvingVi2LayerFactory(const CalibratingParameters& pars)
     891           0 :   : CalVi2LayerFactory(pars)
     892           0 : {}
     893             : 
     894             : 
     895             : // CalSolvingVi2-specific layer-creater
     896           0 : ViImplementation2 * CalSolvingVi2LayerFactory::createInstance (ViImplementation2* vii0) const {
     897             :   // Make the CalibratingVi2, using supplied ViImplementation2, and return it
     898           0 :   ViImplementation2 *vii = new CalSolvingVi2(vii0,calpars_);
     899           0 :   return vii;
     900             : }
     901             : 
     902             : 
     903             : 
     904         168 : CalSolvingVi2LayerFactoryByVE::CalSolvingVi2LayerFactoryByVE(VisEquation *ve,const casacore::Bool& corrDepFlags)
     905             :   : ViiLayerFactory(),
     906         168 :     ve_p(ve),
     907         168 :     corrDepFlags_(corrDepFlags)
     908             : {
     909             :   //  ve_p->state();
     910             : 
     911         168 : }
     912             : 
     913             : // CalSolvingVi2-specific layer-creater
     914         168 : ViImplementation2 * CalSolvingVi2LayerFactoryByVE::createInstance (ViImplementation2* vii0) const {
     915             :   // Make the CalibratingVi2, using supplied ViImplementation2, and return it
     916         168 :   ViImplementation2 *vii = new CalSolvingVi2(vii0,ve_p,corrDepFlags_);
     917         168 :   return vii;
     918             : }
     919             : 
     920             : 
     921             : 
     922             : 
     923             : 
     924             : 
     925             : 
     926             : 
     927             : } //# NAMESPACE VI - END
     928             : } //# NAMESPACE CASA - END
     929             : 
     930             : 

Generated by: LCOV version 1.16