casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
VisBuffer.h
Go to the documentation of this file.
00001 //# VisBuffer.h: buffer for iterating through MS in large blocks
00002 //# Copyright (C) 1996,1997,1998,1999,2000,2002,2003
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: VisBuffer.h,v 19.14 2006/02/28 04:48:58 mvoronko Exp $
00027 
00028 #ifndef MSVIS_VISBUFFER_H
00029 #define MSVIS_VISBUFFER_H
00030 
00031 #include <casa/aips.h>
00032 #include <casa/Arrays/Cube.h>
00033 #include <casa/Arrays/Vector.h>
00034 #include <casa/Arrays/Matrix.h>
00035 #include <casa/BasicSL/Complex.h>
00036 #include <measures/Measures/MDirection.h>
00037 #include <measures/Measures/MEpoch.h>
00038 #include <synthesis/TransformMachines/VisModelData.h>
00039 #include <synthesis/MSVis/StokesVector.h>
00040 #include <synthesis/MSVis/VisibilityIterator.h>
00041 #include <synthesis/MSVis/VisBufferComponents.h>
00042 #include <synthesis/MSVis/MSCalEnums.h>
00043 #include <set>
00044 
00045 namespace casa { //# NAMESPACE CASA - BEGIN
00046 
00047 
00048 //#forward
00049 
00050 
00051 // <summary>
00052 // VbDirtyComponents allows marking portions of a VisBuffer as
00053 // modified (aka dirty).  This feature is needed for the Visibility
00054 // Processing Framework (VPF) which allows a sequence of data processing
00055 // nodes to work as a bucket brigade operating sequentially on a
00056 // VisBuffer.  A downstream output node needs to know what data,
00057 // if any, needs to be written out.
00058 //
00059 // <prerequisite>
00060 //   #<li><linkto class="VisBuffer">VisBuffer</linkto>
00061 // </prerequisite>
00062 //
00063 // </summary>
00064 //
00065 // <synopsis>
00066 //
00067 // </synopsis>
00068 // <example>
00069 //
00070 // <code>
00071 //
00072 // </code>
00073 // </example>
00074 //
00075 class VbDirtyComponents {
00076 
00077 public:
00078 
00079     typedef std::set<VisBufferComponents::EnumType> Set;
00080     typedef Set::const_iterator const_iterator;
00081 
00082     VbDirtyComponents operator+ (const VbDirtyComponents & other) const;
00083 
00084     const_iterator begin () const;
00085     Bool contains (VisBufferComponents::EnumType component) const;
00086     const_iterator end () const;
00087 
00088     static VbDirtyComponents all ();
00089     static VbDirtyComponents exceptThese (VisBufferComponents::EnumType component, ...);
00090     static VbDirtyComponents none ();
00091     static VbDirtyComponents singleton (VisBufferComponents::EnumType component);
00092     static VbDirtyComponents these (VisBufferComponents::EnumType component, ...);
00093 
00094 protected:
00095 
00096 private:
00097 
00098     Set set_p;
00099 
00100     static const VbDirtyComponents all_p;
00101 
00102     static VbDirtyComponents initializeAll ();
00103 
00104 };
00105 
00106 namespace asyncio {
00107     class VLAT;
00108 } // end namespace asyncio
00109 
00110 //<summary>VisBuffers encapsulate one chunk of visibility data for processing.</summary>
00111 //
00112 // <use visibility=export>
00113 //
00114 // <reviewed reviewer="" date="" tests="" demos="">
00115 
00116 // <prerequisite>
00117 //   <li> <linkto class="VisSet">VisSet</linkto>
00118 //   <li> <linkto class="VisibilityIterator">VisibilityIterator</linkto>
00119 //   <li> <linkto class="VisBufferAutoPtr">VisBufferAutoPtr</linkto>
00120 //   <li> <linkto class="VbDirtyComponents">VbDirtyComponents</linkto>
00121 // </prerequisite>
00122 //
00123 // <etymology>
00124 // VisBuffer is a buffer for visibility data
00125 // </etymology>
00126 //
00127 //<synopsis>
00128 // This class contains 'one iteration' of the
00129 // <linkto class="VisibilityIterator">VisibilityIterator</linkto>
00130 // It is a modifiable
00131 // buffer of values to which calibration and averaging can be applied.
00132 // This allows processing of the data in larger blocks, avoiding some
00133 // overheads for processing per visibility point or spectrum.
00134 //
00135 // See <linkto module="MeasurementEquations">MeasurementEquations</linkto>
00136 // for more details on how the VisBuffer is to be used.
00137 //
00138 // When the user intends to allow asynchronous I/O they will need to use
00139 // the VisBufferAsync and VisBufferAsyncWrapper classes; these are
00140 // publicly derived from VisBuffer.  Normally, the user should not
00141 // explicitly use these classes but should use the helper class
00142 // VisBufferAutoPtr which will ensure that the appropriate class is
00143 // used.
00144 //</synopsis>
00145 
00146 //<todo>
00147 // <li> reconcile vis/visCube usage: visCube, flagCube and weightMatrix
00148 // are currently only correct when this VisBuffer got them from a
00149 // VisIter, operations like -=, freqAverage() are only done for
00150 // visibility() and flag().
00151 //</todo>
00152 
00153 class VisBuffer {
00154 
00155     friend class asyncio::VLAT; // for async i/o
00156     friend class VisBufferAsync; // for async i/o
00157     friend class VisBufferAsyncWrapper; // for async i/o
00158     friend class ViReadImplAsync; // for async I/O
00159 
00160 public:
00161     // Create empty VisBuffer you can assign to or attach.
00162     VisBuffer();
00163     // Construct VisBuffer for a particular VisibilityIterator
00164     // The buffer will remain synchronized with the iterator.
00165     VisBuffer(ROVisibilityIterator & iter);
00166 
00167     // Copy construct, looses synchronization with iterator: only use buffer for
00168     // current iteration (or reattach).
00169     VisBuffer(const VisBuffer & vb);
00170 
00171     // Destructor (detaches from VisIter)
00172     virtual ~VisBuffer();
00173 
00174     // Assignment, loses synchronization with iterator: only use buffer for
00175     // current iteration (or reattach)
00176 
00177     virtual VisBuffer & operator=(const VisBuffer & vb);
00178 
00179     // Assignment, optionally without copying the data across; with copy=True
00180     // this is identical to normal assignment operator
00181 
00182     virtual VisBuffer & assign(const VisBuffer & vb, Bool copy = True);
00183 
00184     virtual VisBuffer * clone () const;
00185 
00186     // subtraction: return the difference of the visibilities, flags of
00187     // this and other are or-ed. An exception is thrown if the number of
00188     // rows or channels differs, but no further checks are done.
00189     VisBuffer & operator-=(const VisBuffer & vb);
00190 
00191     // Attach to a VisIter. Detaches itself first if already attached
00192     // to a VisIter. Will remain synchronized with iterator.
00193     virtual void attachToVisIter(ROVisibilityIterator & iter);
00194     virtual void detachFromVisIter ();
00195 
00196     // Invalidate the cache
00197     virtual void invalidate();
00198 
00199     // <group>
00200     // Access functions
00201     //
00202     virtual Int & nCorr() {
00203         return nCorrOK_p ? nCorr_p : fillnCorr();
00204     }
00205     virtual Int nCorr() const {
00206         return This->nCorr();
00207     }
00208 
00209     virtual Int & nChannel() {
00210         return nChannelOK_p ? nChannel_p : fillnChannel();
00211     }
00212     virtual Int nChannel() const {
00213         return This->nChannel();
00214     }
00215 
00216     virtual Vector<Int>& channel() {
00217         return channelOK_p ? channel_p : fillChannel();
00218     }
00219     virtual const Vector<Int>& channel() const {
00220         return This->channel();
00221     }
00222 
00223     // virtual Int & nCat() {
00224     //     return nCatOK_p ? nCat_p : fillnCat();
00225     // }
00226     // virtual Int nCat() const {
00227     //     return This->nCat();
00228     // }
00229 
00234     // Decide what is the right value (depending on where the vb is coming from) 
00235     // for you for the size of the buffer. i.e (nCorr(), nChannel(), nRow()) or vb.visCube().shape()
00236     // The latter comes from the VisIter state ...the former be careful...
00238     //without updating fillnrow 
00243     virtual Int & nRow() {
00244         return nRowOK_p ? nRow_p : fillnRow();
00245     }
00246     virtual Int nRow() const {
00247         return This->nRow();
00248     }
00249 
00250     virtual Int nRowChunk() const;
00251 
00252     virtual Vector<Int>& antenna1() {
00253         return antenna1OK_p ? antenna1_p : fillAnt1();
00254     }
00255     virtual const Vector<Int>& antenna1() const {
00256         return This->antenna1();
00257     }
00258 
00259     virtual Vector<Int>& antenna2() {
00260         return antenna2OK_p ? antenna2_p : fillAnt2();
00261     }
00262     virtual const Vector<Int>& antenna2() const {
00263         return This->antenna2();
00264     }
00265 
00266     virtual Vector<Int>& feed1() {
00267         return feed1OK_p ? feed1_p : fillFeed1();
00268     }
00269     virtual const Vector<Int>& feed1() const {
00270         return This->feed1();
00271     }
00272 
00273     virtual Vector<Int>& feed2() {
00274         return feed2OK_p ? feed2_p : fillFeed2();
00275     }
00276     virtual const Vector<Int>& feed2() const {
00277         return This->feed2();
00278     }
00279 
00280     virtual void dirtyComponentsAdd (const VbDirtyComponents & additionalDirtyComponents);
00281     virtual void dirtyComponentsAdd (VisBufferComponents::EnumType component);
00282     virtual void dirtyComponentsClear ();
00283     virtual VbDirtyComponents dirtyComponentsGet () const;
00284     virtual void dirtyComponentsSet (const VbDirtyComponents & dirtyComponents);
00285     virtual void dirtyComponentsSet (VisBufferComponents::EnumType component);
00286 
00287     virtual Bool fetch(const asyncio::PrefetchColumns *pfc);
00288 
00289     // feed1_pa() and feed2_pa() return an array of parallactic angles
00290     // (each corresponds to the first receptor of the feed) one for each
00291     // row in the current buffer. In contrast, feed_pa() calculates
00292     // the angles for each antenna. These methods are implemented for
00293     // VisBuffer only to benefit from caching of the feed and antenna IDs.
00294     virtual Vector<Float>& feed1_pa() {
00295         return feed1_paOK_p ? feed1_pa_p : fillFeed1_pa();
00296     }
00297     virtual const Vector<Float>& feed1_pa() const {
00298         return This->feed1_pa();
00299     }
00300 
00301     virtual Vector<Float>& feed2_pa() {
00302         return feed2_paOK_p ? feed2_pa_p : fillFeed2_pa();
00303     }
00304     virtual const Vector<Float>& feed2_pa() const {
00305         return This->feed2_pa();
00306     }
00307 
00308     virtual Vector<SquareMatrix<Complex, 2> >& CJones() {
00309         return cjonesOK_p ? cjones_p : fillCjones();
00310     }
00311     virtual const Vector<SquareMatrix<Complex, 2> >& CJones() const {
00312         return This->CJones();
00313     }
00314 
00315     // Note that feed_pa is a function instead of a cached value
00316     virtual Vector<Float> feed_pa(Double time) const;
00317 
00318     // direction1() and direction2() return arrays of directions where
00319     // the first and the second antenna/feed are pointed to. One value for
00320     // each row in the current buffer.
00321     virtual Vector<MDirection>& direction1() {
00322         return direction1OK_p ? direction1_p
00323                : fillDirection1();
00324     }
00325     virtual const Vector<MDirection>& direction1()  const {
00326         return This->direction1();
00327     }
00328 
00329     virtual Vector<MDirection>& direction2() {
00330         return direction2OK_p ? direction2_p :
00331                fillDirection2();
00332     }
00333     virtual const Vector<MDirection>& direction2()  const {
00334         return This->direction2();
00335     }
00336 
00337 
00338     // NOMINAL parallactic angle (feed p.a. offset NOT included)
00339     virtual Float parang0(Double time) const;
00340     virtual Vector<Float> parang(Double time) const;
00341 
00342     // Note that azel is a function instead of a cached value
00343     virtual MDirection azel0(Double time) const;
00344     virtual Vector<Double>& azel0Vec(Double time, Vector<Double>& azelVec) const;
00345     virtual Vector<MDirection> azel(Double time) const;
00346     virtual Matrix<Double>& azelMat(Double time, Matrix<Double>& azelMat) const;
00347 
00348     // Hour angle for specified time
00349     virtual Double hourang(Double time) const;
00350 
00351     virtual Int fieldId() const {
00352         return fieldIdOK_p ? fieldId_p : This->fillFieldId();
00353     }
00354 
00355     virtual Int& fieldIdRef() {
00356         return fieldIdOK_p ? fieldId_p : This->fillFieldId();
00357     }
00358 
00359     virtual Int& arrayIdRef() {
00360         return arrayIdOK_p ? arrayId_p : This->fillArrayId();
00361     }
00362 
00363     virtual Int arrayId() const {
00364         return arrayIdOK_p ? arrayId_p : This->fillArrayId();
00365     }
00366 
00367     // Return flag for each channel & row
00368     virtual Matrix<Bool>& flag() {
00369         return flagOK_p ? flag_p : fillFlag();
00370     }
00371     virtual const Matrix<Bool>& flag() const {
00372         return This->flag();
00373     }
00374 
00375     // Return flag for each polarization, channel and row
00376     virtual Cube<Bool>& flagCube() {
00377         return flagCubeOK_p ? flagCube_p : fillFlagCube();
00378     }
00379     virtual const Cube<Bool>& flagCube() const {
00380         return This->flagCube();
00381     }
00382 
00383     virtual Vector<Bool>& flagRow() {
00384         return flagRowOK_p ? flagRow_p : fillFlagRow();
00385     }
00386     virtual const Vector<Bool>& flagRow() const {
00387         return This->flagRow();
00388     }
00389 
00390     // Return flags for each polarization, channel, category, and row.
00391     virtual Array<Bool>& flagCategory() {
00392         return flagCategoryOK_p ? flagCategory_p : fillFlagCategory();
00393     }
00394     virtual const Array<Bool>& flagCategory() const {
00395         return This->flagCategory();
00396     }
00397 
00398     virtual Vector<Int>& scan() {
00399         return scanOK_p ? scan_p : fillScan();
00400     }
00401     virtual const Vector<Int>& scan() const {
00402         return This->scan();
00403     }
00404 
00405     // scalar version for convenience, when scan known constant for
00406     // entire iteration/buffer.
00407     virtual Int scan0() {
00408         return scan()(0);
00409     }
00410 
00411     virtual Vector<Int>& processorId() {
00412         return processorIdOK_p ? processorId_p : fillProcessorId();
00413     }
00414     virtual const Vector<Int>& processorId() const {
00415         return This->processorId();
00416     }
00417 
00418     virtual Vector<Int>& observationId() {
00419         return observationIdOK_p ? observationId_p : fillObservationId();
00420     }
00421     virtual const Vector<Int>& observationId() const {
00422         return This->observationId();
00423     }
00424 
00425     virtual Vector<Int>& stateId() {
00426         return stateIdOK_p ? stateId_p : fillStateId();
00427     }
00428     virtual const Vector<Int>& stateId() const {
00429         return This->stateId();
00430     }
00431 
00432     // Gets SPECTRAL_WINDOW/CHAN_FREQ (in Hz, acc. to the MS def'n v.2).
00433     virtual Vector<Double>& frequency() {
00434         return frequencyOK_p ? frequency_p : fillFreq();
00435     }
00436     virtual const Vector<Double>& frequency() const {
00437         return This->frequency();
00438     }
00439 
00440 //    virtual Vector<Double>& lsrFrequency() {
00441 //        return lsrFrequencyOK_p ? lsrFrequency_p : fillLSRFreq();
00442 //    }
00443 //    virtual const Vector<Double>& lsrFrequency() const {
00444 //        return This->lsrFrequency();
00445 //    }
00446 
00447 
00448     //the following method is to convert the observed frequencies
00449     // This conversion may not be accurate for some frame
00450     // conversion like topo to lsr except if the spw is in the actual buffer
00451 
00452     //if ignoreconv=True..frequency is served as is in the data frame
00453     virtual void lsrFrequency(const Int & spw, Vector<Double>& freq, Bool & convert, const Bool ignoreconv=False) const;
00454 
00455     virtual Int numberCoh () const;
00456 
00457     virtual MDirection & phaseCenter() {
00458         return phaseCenterOK_p ? phaseCenter_p : fillPhaseCenter();
00459     }
00460     virtual MDirection phaseCenter() const {
00461         return This->phaseCenter();
00462     }
00463 
00464     virtual Int polFrame() const {
00465         return polFrameOK_p ? polFrame_p : This->fillPolFrame();
00466     }
00467 
00468     virtual Vector<Int>& corrType() {
00469         return corrTypeOK_p ? corrType_p : fillCorrType();
00470     }
00471     virtual const Vector<Int>& corrType() const {
00472         return This->corrType();
00473     }
00474 
00475     virtual Vector<Float>& sigma() {
00476         return sigmaOK_p ? sigma_p : fillSigma();
00477     }
00478     virtual const Vector<Float>& sigma() const {
00479         return This->sigma();
00480     }
00481 
00482     virtual Matrix<Float>& sigmaMat() {
00483         return sigmaMatOK_p ? sigmaMat_p : fillSigmaMat();
00484     }
00485     virtual const Matrix<Float>& sigmaMat() const {
00486         return This->sigmaMat();
00487     }
00488 
00489     virtual Int & spectralWindow() {
00490         return spectralWindowOK_p ? spectralWindow_p : This->fillSpW();
00491     }
00492     virtual Int spectralWindow() const {
00493         return spectralWindowOK_p ? spectralWindow_p : This->fillSpW();
00494     }
00495     virtual Int polarizationId() const {
00496       return visIter_p->polarizationId();
00497     } 
00498     virtual Int& dataDescriptionIdRef() {
00499       return dataDescriptionIdOK_p ? dataDescriptionId_p : This->fillDataDescriptionId ();
00500     }
00501     virtual Int dataDescriptionId() const {
00502       return dataDescriptionIdOK_p ? dataDescriptionId_p : This->fillDataDescriptionId ();
00503     }
00504     virtual Vector<Double>& time() {
00505         return timeOK_p ? time_p : fillTime();
00506     }
00507     virtual const Vector<Double>& time() const {
00508         return This->time();
00509     }
00510 
00511     virtual Vector<Double>& timeCentroid() {
00512         return timeCentroidOK_p ? timeCentroid_p : fillTimeCentroid();
00513     }
00514     virtual const Vector<Double>& timeCentroid() const {
00515         return This->timeCentroid();
00516     }
00517 
00518     virtual Vector<Double>& timeInterval() {
00519         return timeIntervalOK_p ? timeInterval_p : fillTimeInterval();
00520     }
00521     virtual const Vector<Double>& timeInterval() const {
00522         return This->timeInterval();
00523     }
00524 
00525     virtual Vector<Double>& exposure() {
00526         return exposureOK_p ? exposure_p : fillExposure();
00527     }
00528     virtual const Vector<Double>& exposure() const {
00529         return This->exposure();
00530     }
00531 
00532     virtual Vector<RigidVector<Double, 3> >& uvw() {
00533         return uvwOK_p ? uvw_p : filluvw();
00534     }
00535     virtual const Vector<RigidVector<Double, 3> >& uvw() const {
00536         return This->uvw();
00537     }
00538 
00539     virtual Matrix<Double>& uvwMat() {
00540         return uvwMatOK_p ? uvwMat_p : filluvwMat();
00541     }
00542     virtual const Matrix<Double>& uvwMat() const {
00543         return This->uvwMat();
00544     }
00545 
00546     virtual Matrix<CStokesVector>& visibility() {
00547         return visibilityOK_p ? visibility_p : fillVis(VisibilityIterator::Observed);
00548     }
00549     virtual const Matrix<CStokesVector>& visibility() const {
00550         return This->visibility();
00551     }
00552 
00553     virtual Matrix<CStokesVector>& modelVisibility() {
00554         return modelVisibilityOK_p ? modelVisibility_p :
00555                fillVis(VisibilityIterator::Model);
00556     }
00557     virtual const Matrix<CStokesVector>& modelVisibility() const {
00558         return This->modelVisibility();
00559     }
00560 
00561     virtual Matrix<CStokesVector>& correctedVisibility() {
00562         return correctedVisibilityOK_p ? correctedVisibility_p :
00563                fillVis(VisibilityIterator::Corrected);
00564     }
00565     virtual const Matrix<CStokesVector>& correctedVisibility() const {
00566         return This->correctedVisibility();
00567     }
00568 
00569     virtual Cube<Complex>& visCube() {
00570         return visCubeOK_p ? visCube_p : fillVisCube(VisibilityIterator::Observed);
00571     }
00572     virtual const Cube<Complex>& visCube() const {
00573         return This->visCube();
00574     }
00575 
00576     virtual Cube<Complex>& modelVisCube() {
00577         return modelVisCubeOK_p ? modelVisCube_p :
00578                fillVisCube(VisibilityIterator::Model);
00579     }
00580 
00581     virtual Cube<Complex>& modelVisCube(const Bool & matchVisCubeShape) {
00582         // Avoids call to fillVisCube(VisIter::Model)
00583         modelVisCubeOK_p = True;
00584         if (matchVisCubeShape) {
00585             // shape it in memory like data
00586             modelVisCube_p.resize(visCube().shape());
00587             modelVisCube_p = Complex(0.0);
00588         }
00589         // ... and return it in the usual way
00590         return modelVisCube();
00591     }
00592 
00593     virtual const Cube<Complex>& modelVisCube() const {
00594         return This->modelVisCube();
00595     }
00596 
00597     virtual Cube<Complex>& correctedVisCube() {
00598         return correctedVisCubeOK_p ? correctedVisCube_p :
00599                fillVisCube(VisibilityIterator::Corrected);
00600     }
00601     virtual const Cube<Complex>& correctedVisCube() const {
00602         return This->correctedVisCube();
00603     }
00604 
00605     // Return visCube(), modelVisCube(), or correctedVisCube(),
00606     // according to whichcol.  They throw an exception if whichcol is
00607     // unsupported, but note the encouraged default.
00608     // TODO: Optionally return DATA if whichcol is unavailable.
00609     Cube<Complex>& dataCube(const MS::PredefinedColumns whichcol=MS::DATA);
00610     const Cube<Complex>& dataCube(const MS::PredefinedColumns
00611                                   whichcol=MS::DATA) const;
00612 
00613     virtual Cube<Float>& floatDataCube() {
00614         return floatDataCubeOK_p ? floatDataCube_p : fillFloatDataCube();
00615     }
00616     virtual const Cube<Float>& floatDataCube() const {
00617         return This->floatDataCube();
00618     }
00619 
00620     // Returns the weights for each row averaged over the parallel hand correlations.
00621     virtual Vector<Float>& weight() {
00622         return weightOK_p ? weight_p : fillWeight();
00623     }
00624     virtual const Vector<Float>& weight() const {
00625         return This->weight();
00626     }
00627 
00628     // Returns the nPol_p x curNumRow_p weight matrix.
00629     virtual Matrix<Float>& weightMat() {
00630         return weightMatOK_p ? weightMat_p : fillWeightMat();
00631     }
00632     virtual const Matrix<Float>& weightMat() const {
00633         return This->weightMat();
00634     }
00635 
00636     // Is a valid WEIGHT_SPECTRUM available?
00637     virtual Bool existsWeightSpectrum() const {
00638       return visIter_p ? visIter_p->existsWeightSpectrum() : false;
00639     }
00640 
00641     virtual Cube<Float>& weightSpectrum() {
00642         return weightSpectrumOK_p ? weightSpectrum_p : fillWeightSpectrum();
00643     }
00644     virtual const Cube<Float>& weightSpectrum() const {
00645         return This->weightSpectrum();
00646     }
00647 
00648     virtual Matrix<Float>& imagingWeight();
00649     virtual const Matrix<Float>& imagingWeight() const;
00650 
00651 
00652 //    virtual Matrix<Float>& imagingWeight() {
00653 //        return imagingWeightOK_p ? imagingWeight_p : fillImagingWeight();
00654 //    }
00655 //    virtual const Matrix<Float>& imagingWeight() const {
00656 //        return This->imagingWeight();
00657 //    }
00658 
00659     virtual Cube<Float>& weightCube() {
00660         return weightCube_p;
00661     }
00662     //</group>
00663 
00664     //<group>
00665     // Utility functions to provide coordinate or column ranges of the
00666     // data in the VisBuffer. Flagging is applied before computing the ranges.
00667     //
00668     // Generic accessor to column ranges of integer type, as specified by
00669     // enumerations defined in class MSCalEnums. Throws an exception
00670     // if the enum is not for a recognized integer column.
00671     virtual Vector<Int> vecIntRange(const MSCalEnums::colDef & calEnum) const;
00672 
00673     // Antenna id. range (includes both ANTENNA1 and ANTENNA2 columns)
00674     virtual Vector<Int> antIdRange() const;
00675 
00676     // Time range
00677     virtual Bool timeRange(MEpoch & rTime, MVEpoch & rTimeEP, MVEpoch & rInterval) const;
00678 
00679     // Return the row Ids from the original ms. If the ms used is a subset of
00680     // another ms then rowIds() return the row ids of the original ms.
00681     virtual Vector<uInt>& rowIds();
00682 
00683     virtual const Vector<uInt>& rowIds() const {
00684         return This->rowIds();
00685     };
00686 
00687     //</group>
00688 
00689     // Frequency average the buffer (visibility() column only)
00690     virtual void freqAverage();
00691 
00692     // Frequency average the buffer (visCube and [if present] modelVisCube)
00693     void freqAveCubes();
00694 
00695     // Average channel axis according to chanavebounds, for whichever of DATA,
00696     // MODEL_DATA, CORRECTED_DATA, FLOAT_DATA, FLAG, and WEIGHT_SPECTRUM are
00697     // present.  It will only treat the first 5 as present if they have already
00698     // been loaded into the buffer!
00699     void channelAve(const Matrix<Int>& chanavebounds);
00700 
00701     // Average channel axis by factor.
00702     template<class T> void chanAveVisCube(Cube<T>& data, Int nChanOut);
00703 
00704     // Accumulate channel axis by factor, without applying WEIGHT_SPECTRUM even
00705     // if it is present.
00706     // It is primarily intended for averaging WEIGHT_SPECTRUM itself.
00707     template<class T> void chanAccCube(Cube<T>& data, Int nChanOut);
00708 
00709     // This defaults to no conceptual side effects, but usually it is more
00710     // efficient to let it leave weightSpectrum() in a channel averaged state.
00711     // restoreWeightSpectrum has no effect if !existsWeightSpectrum().
00712     virtual void chanAveFlagCube(Cube<Bool>& flagcube, const Int nChanOut,
00713                          const Bool restoreWeightSpectrum = True);
00714 
00715     // Doesn't do anything if flagcat is degenerate.
00716     void chanAveFlagCategory(Array<Bool>& flagcat, const Int nChanOut);
00717 
00718     // Form Stokes parameters from correlations
00719     //  (these are preliminary versions)
00720     virtual void formStokes();
00721     virtual void formStokesWeightandFlag();
00722     virtual void formStokes(Cube<Complex>& vis);
00723     virtual void formStokes(Cube<Float>& fcube);    // Will throw up if asked to do all 4.
00724 
00725     // Sort/unsort the correlations, if necessary
00726     //  (Rudimentary handling of non-canonically sorted correlations--use with care!)
00727     virtual void sortCorr();
00728     virtual void unSortCorr();
00729 
00730     // Normalize the visCube by the modelVisCube
00731     //   (and optionally also divide visCube_p by its normalized amp)
00732     virtual void normalize(const Bool & phaseOnly = False);
00733 
00734     // Fill weightMat according to sigma column
00735     virtual void resetWeightMat();
00736 
00737     // Rotate visibility phase for given vector (dim = nrow of vb) of phases (metres)
00738     virtual void phaseCenterShift(const Vector<Double>& phase);
00739     // Rotate visibility phase for phase center offsets (arcsecs)
00740     virtual void phaseCenterShift(Double dx, Double dy);
00741 
00742     // Update coordinate info - useful for copied VisBuffers that need
00743     // to retain some state for later reference.
00744     // Presently this fills antenna, array, field and spectralWindow ids, time,
00745     // frequency and number of rows. 
00746     // if dirDependent is set to False the expensive direction dependent calculation of parallactic or direction of
00747     // antenna from pointing table is avoided
00748     //Add more as needed.
00749     virtual void updateCoordInfo(const VisBuffer * vb = NULL, const Bool dirDependent=True);
00750     void copyCoordInfo(const VisBuffer& other, Bool force=False);
00751 
00752     // Set the visibility to a constant, note that this only changes the buffer,
00753     // no values are written back to tables from here.
00754     virtual void setVisCube(Complex c);
00755     virtual void setModelVisCube(Complex c);
00756     virtual void setCorrectedVisCube(Complex c);
00757 
00758     // Set the visibility, note that this only changes the buffer,
00759     // no values are written back to tables from here.
00760     virtual void setVisCube(const Cube<Complex>& vis);
00761     virtual void setModelVisCube(const Cube<Complex>& vis);
00762     virtual void setCorrectedVisCube(const Cube<Complex>& vis);
00763 
00764     // Like the above, but for FLOAT_DATA, keeping it as real floats.
00765     virtual void setFloatDataCube(const Cube<Float>& fcube);
00766 
00767     // Set model according to a Stokes vector
00768     virtual void setModelVisCube(const Vector<Float>& stokes);
00769 
00770     // Reference external model visibilities
00771     virtual void refModelVis(const Matrix<CStokesVector>& mvis);
00772 
00773     // Remove scratch cols data from vb
00774     virtual void removeScratchCols();
00775 
00776     // Access the current ROMSColumns object via VisIter
00777     virtual const ROMSColumns & msColumns() const {
00778         return visIter_p->msColumns();
00779     }
00780 
00781     virtual  Int numberAnt () const;
00782 
00783 
00784 
00785     // Get all selected spectral windows not just the one in the actual buffer
00786     virtual void allSelectedSpectralWindows(Vector<Int>& spws, Vector<Int>& nvischan) {
00787         visIter_p->allSelectedSpectralWindows(spws, nvischan);
00788     }
00789 
00790   virtual void getChannelSelection(Block< Vector<Int> >& blockNGroup,
00791                                    Block< Vector<Int> >& blockStart,
00792                                    Block< Vector<Int> >& blockWidth,
00793                                    Block< Vector<Int> >& blockIncr,
00794                                    Block< Vector<Int> >& blockSpw) const {
00795     visIter_p->getChannelSelection(blockNGroup, blockStart, blockWidth, blockIncr, blockSpw);
00796   };
00797     void allSelectedSpectralWindows(Vector<Int>& spws, Vector<Int>& nvischan) const {
00798         This->allSelectedSpectralWindows(spws, nvischan);
00799     }
00800 
00801     // Return the actual msid, useful if using multiple ms to monitor which
00802     // ms in the  list is being dealt with
00803     virtual Int msId() const {
00804         This->checkMSId();
00805         return oldMSId_p;
00806     }
00807 
00808     //checked if the ms has changed since the last chunk processed
00809     virtual Bool newMS() const {
00810         This->checkMSId();
00811         return newMS_p;
00812     }
00813     //get the name of the ms the buffer is at empty string if no visiter is attached
00814     virtual String msName(Bool stripPath=False) const;
00815 
00816     virtual Bool newArrayId () const;
00817     virtual Bool newFieldId () const;
00818     virtual Bool newSpectralWindow () const;
00819 
00820     //
00821 
00822 protected:
00823 
00824     virtual Bool checkMSId();
00825     virtual void checkVisIter (const char * func, const char * file, int line, const char * extra = "") const;
00826     virtual void copyCache (const VisBuffer & other, Bool force);
00827     virtual void copyMsInfo (Int & msID, Bool & MsOk_p, Bool & newMs) const;
00828     virtual const Matrix<Float>& imagingWeight(const VisImagingWeight & weightGenerator) const;
00829     virtual Int getOldMsId () const;
00830     virtual ROVisibilityIterator * getVisibilityIterator () const;
00831 
00832     template <typename Coord>
00833     void updateCoord (const VisBuffer * other,
00834                       Bool otherOk,
00835                       const Coord & (VisBuffer::* getCoord) () const,
00836                       Coord & coord,
00837                       Bool & coordOk)
00838     {
00839         if (otherOk){
00840             coord.assign ((other ->* getCoord) ());
00841             coordOk = True;
00842         }
00843         else {
00844             ((this ->* getCoord) ());
00845         }
00846     }
00847 
00848     template <typename Scalar>
00849     void updateCoordS (const VisBuffer * other,
00850                        Bool otherOk,
00851                        Scalar (VisBuffer::* getCoord) () const,
00852                        Scalar & coord,
00853                        Bool & coordOk)
00854     {
00855         if (otherOk){
00856             coord = (other ->* getCoord) ();
00857             coordOk = True;
00858         }
00859         else {
00860             ((this ->* getCoord) ());
00861         }
00862     }
00863 
00864 
00865 private:
00866 
00867 
00868     // validate the cache
00869     virtual void validate();
00870 
00871     void checkVisIterBase (const char * func, const char * file, int line, const char * extra = "") const;
00872 
00873     template<typename T>
00874     static void cacheCopyArray (Bool & newStatus,
00875                                 Bool oldStatus,
00876                                 T & newCache,
00877                                 const VisBuffer & other,
00878                                 const T &  (VisBuffer::* oldCache) () const,
00879                                 Bool force) {
00880 
00881         // Leave things unchanged if the old status is false.  This will often
00882         // leave the value with an empty data structure and an OK status which
00883         // is needed in many cases.
00884         //
00885         // For copying Array<T> derived objects since the assign operator
00886         // doesn't work for these.
00887 
00888         newStatus = force || oldStatus;
00889 
00890         if (newStatus) {
00891             newCache.assign (((& other) ->* oldCache) ());
00892         }
00893     }
00894 
00895     template<typename T>
00896     static void cacheCopyNormal (Bool & newStatus,
00897                                  Bool oldStatus,
00898                                  T & newCache,
00899                                  const VisBuffer & other,
00900                                  T (VisBuffer::* oldCache) () const,
00901                                  Bool force) {
00902 
00903         // Leave things unchanged if the old status is false.  This will often
00904         // leave the value with an empty data structure and an OK status which
00905         // is needed in many cases.
00906         //
00907         // For copying "normal" cache status and values.  Normal means
00908         // the assign operator works (which it doesn't for classes based on Array<T>)
00909 
00910         newStatus = force || oldStatus;
00911 
00912         if (newStatus) {
00913 
00914             newCache = ((& other) ->* oldCache) ();
00915         }
00916     }
00917 
00918     virtual void setAllCacheStatuses (bool status);
00919 
00920     virtual Bool nonCanonCorr(); // Are correlations in non-canonical order?
00921 
00922     // Filter index arrays for unique elements
00923     virtual Vector<Int> unique(const Vector<Int>& indices) const;
00924 
00925     Bool corrSorted_p; // Have correlations been sorted by sortCorr?
00926     VbDirtyComponents dirtyComponents_p;
00927     Int lastPointTableRow_p;
00928     Int oldMSId_p;
00929     VisBuffer * This;
00930     Bool twoWayConnection_p;
00931     ROVisibilityIterator * visIter_p;
00932     VisModelData visModelData_p;
00933 
00934     // +-------------------------------------------------+
00935     // | Cache Declarations (fillers, statuses and data) |
00936     // +-------------------------------------------------+
00937     //
00938     // Preferred naming convention:
00939     //
00940     // T thing () --- returns the value of thing (public method)
00941     // T fillThing () --- fills thing cache variable and sets thingOK_p to true (private)
00942     // Bool thingOK_p --- true if the value of thing is currently cached  (private)
00943     // T thing_p --- holds cached value of thing (if thingOK_p is true)  (private)
00944     //
00945     // Example: Vector<Int>& feed1(); Vector<Int>& fillFeed1();
00946     //          Bool feed1OK_P; Vector<Int> feed1_p;
00947 
00948     // Cache filling routines in alphabetical order
00949     //
00950     // The first line in a fill routine should be the macro CheckVisIter.  This
00951     // will cause an AipsError to be throw when there is no visibilty iterator
00952     // associated with the VisBuffer.  This is especially important because the
00953     // fillers may be called on a VisBufferAsync in two contexts: filling
00954     // where there will be a VI attached and in normal use where there is no VI
00955     // attached.  The filler must also set the cache status variable to True during
00956     // its execution.
00957 
00958     virtual Vector<Int>& fillAnt1();
00959     virtual Vector<Int>& fillAnt2();
00960     virtual Int & fillArrayId();
00961     //virtual Matrix<Int>& fillChanAveBounds();
00962     virtual Vector<Int>& fillChannel();
00963     virtual Vector<SquareMatrix<Complex, 2> >& fillCjones();
00964     virtual Vector<Int>& fillCorrType();
00965     virtual Int & fillDataDescriptionId ();
00966     virtual Vector<MDirection>& fillDirection1();
00967     virtual Vector<MDirection>& fillDirection2();
00968     virtual Vector<Double>& fillExposure();
00969     virtual Vector<Int>& fillFeed1();
00970     virtual Vector<Float>& fillFeed1_pa();
00971     virtual Vector<Int>& fillFeed2();
00972     virtual Vector<Float>& fillFeed2_pa();
00973     virtual Int & fillFieldId();
00974     virtual Matrix<Bool>& fillFlag();
00975     virtual Array<Bool>& fillFlagCategory();
00976     virtual Cube<Bool>& fillFlagCube();
00977     virtual Vector<Bool> & fillFlagRow();
00978     virtual Cube<Float>& fillFloatDataCube();
00979     virtual Vector<Double>& fillFreq();         // Puts SPECTRAL_WINDOW/CHAN_FREQ in frequency_p.
00980     //virtual Matrix<Float>& fillImagingWeight();
00981     //virtual Vector<Double>& fillLSRFreq();
00982     virtual Int & fillnChannel();
00983     virtual Int & fillnCorr();
00984   //    virtual Int & fillnCat();
00985     virtual Int & fillnRow();
00986     virtual Vector<Int> & fillObservationId();
00987     virtual MDirection & fillPhaseCenter();
00988     virtual Int & fillPolFrame();
00989     virtual Vector<Int> & fillProcessorId();
00990     virtual Vector<Int> & fillScan();
00991     virtual Vector<Float>& fillSigma();
00992     virtual Matrix<Float>& fillSigmaMat();
00993     virtual Int & fillSpW();
00994     virtual Vector<Int> & fillStateId();
00995     virtual Vector<Double>& fillTime();
00996     virtual Vector<Double>& fillTimeCentroid();
00997     virtual Vector<Double>& fillTimeInterval();
00998     virtual Vector<RigidVector<Double, 3> >& filluvw();
00999     virtual Matrix<Double>& filluvwMat();
01000     virtual Matrix<CStokesVector>& fillVis(VisibilityIterator::DataColumn whichOne);
01001     virtual Cube<Complex>& fillVisCube(VisibilityIterator::DataColumn whichOne);
01002     virtual Vector<Float>& fillWeight();
01003     virtual Matrix<Float>& fillWeightMat();
01004     virtual Cube<Float>& fillWeightSpectrum();
01005 
01006     Bool newMS_p;
01007 
01008     // Variables to track validity of cache (alphabetical order)
01009 
01010 #define CacheStatus(item) \
01011 virtual Bool item ## OK () const\
01012 {\
01013     return item ## OK_p;\
01014 }\
01015 Bool item ## OK_p;
01016 
01017     // Define the cache statuses
01018     //
01019     // For example, CacheStatus (antenna1) defines:
01020     //
01021     // virtual Bool antenna1OK () const { return antenna1OK_p;}
01022     //
01023     // and
01024     //
01025     // Bool antenna1OK_p;
01026 
01027     CacheStatus (antenna1);
01028     CacheStatus (antenna2);
01029     CacheStatus (arrayId);
01030     CacheStatus (channel);
01031     CacheStatus (cjones);
01032     CacheStatus (correctedVisCube);
01033     CacheStatus (correctedVisibility);
01034     CacheStatus (corrType);
01035     CacheStatus (dataDescriptionId);
01036     CacheStatus (direction1);
01037     CacheStatus (direction2);
01038     CacheStatus (exposure);
01039     CacheStatus (feed1_pa);
01040     CacheStatus (feed1);
01041     CacheStatus (feed2_pa);
01042     CacheStatus (feed2);
01043     CacheStatus (fieldId);
01044     CacheStatus (flagCategory);
01045     CacheStatus (flagCube);
01046     CacheStatus (flag);
01047     CacheStatus (flagRow);
01048     CacheStatus (floatDataCube);
01049     CacheStatus (frequency);
01050     CacheStatus (imagingWeight);
01051     CacheStatus (modelVisCube);
01052     CacheStatus (modelVisibility);
01053     CacheStatus (ms);
01054     CacheStatus (nChannel);
01055     CacheStatus (nCorr);
01056     CacheStatus (nRow);
01057     CacheStatus (observationId);
01058     CacheStatus (phaseCenter);
01059     CacheStatus (polFrame);
01060     CacheStatus (processorId);
01061     CacheStatus (rowIds);
01062     CacheStatus (scan);
01063     CacheStatus (sigmaMat);
01064     CacheStatus (sigma);
01065     CacheStatus (spectralWindow);
01066     CacheStatus (stateId);
01067     CacheStatus (timeCentroid);
01068     CacheStatus (timeInterval);
01069     CacheStatus (time);
01070     CacheStatus (uvwMat);
01071     CacheStatus (uvw);
01072     CacheStatus (visCube);
01073     CacheStatus (visibility);
01074     CacheStatus (weightMat);
01075     CacheStatus (weight);
01076     CacheStatus (weightSpectrum);
01077 
01078     // Cached values (alphabetical order)
01079 
01080     Vector<Int> antenna1_p;
01081     Vector<Int> antenna2_p;
01082     Int arrayId_p;
01083     Matrix<Int> chanAveBounds_p;
01084     Vector<Int> channel_p;
01085     Vector<SquareMatrix<Complex, 2> > cjones_p;
01086     Cube<Complex> correctedVisCube_p;
01087     Matrix<CStokesVector> correctedVisibility_p;
01088     Vector<Int> corrType_p;
01089     Int dataDescriptionId_p;
01090     Vector<MDirection> direction1_p; //where the first antenna/feed is pointed to
01091     Vector<MDirection> direction2_p; //where the second antenna/feed is pointed to
01092     Vector<Double> exposure_p;
01093     Vector<Int> feed1_p;
01094     Vector<Float> feed1_pa_p;
01095     Vector<Int> feed2_p;
01096     Vector<Float> feed2_pa_p;
01097     Int fieldId_p;
01098     Matrix<Bool> flag_p;
01099     Array<Bool> flagCategory_p;
01100     Cube<Bool> flagCube_p;
01101     Vector<Bool> flagRow_p;
01102     Cube<Float> floatDataCube_p;
01103     Vector<Double> frequency_p;
01104     mutable Matrix<Float> imagingWeight_p;
01105     //Vector<Double> lsrFrequency_p;
01106     Cube<Complex> modelVisCube_p;
01107     Matrix<CStokesVector> modelVisibility_p;
01108     Int nChannel_p;
01109     Int nCorr_p;
01110   //    Int nCat_p;
01111     Int nRow_p;
01112     Vector<Int> observationId_p;
01113     MDirection phaseCenter_p;
01114     Int polFrame_p;
01115     Vector<Int> processorId_p;
01116     Vector<uInt> rowIds_p;
01117     Vector<Int> scan_p;
01118     Vector<Float> sigma_p;
01119     Matrix<Float> sigmaMat_p;
01120     Int spectralWindow_p;
01121     Vector<Int> stateId_p;
01122     Vector<Double> time_p;
01123     Vector<Double> timeCentroid_p;
01124     Vector<Double> timeInterval_p;
01125     Vector<RigidVector<Double, 3> > uvw_p;
01126     Matrix<Double> uvwMat_p;
01127     Cube<Complex> visCube_p;
01128     Matrix<CStokesVector> visibility_p;
01129     Vector<Float> weight_p;
01130     Cube<Float> weightCube_p;
01131     Matrix<Float> weightMat_p;
01132     Cube<Float> weightSpectrum_p;
01133 
01134 };
01135 
01136 // <summary>
01137 // A convenience class to assist in migrating code to potentially use
01138 // asynchronous I/O.
01139 //
01140 // <prerequisite>
01141 //   <li> <linkto class="VisBuffer">VisBuffer</linkto>
01142 //   <li> <linkto class="VisBufferAsync">VisBufferAsync</linkto>
01143 //   <li> <linkto class="ROVisibilityIterator">ROVisibilityIterator</linkto>
01144 // </prerequisite>
01145 //
01146 // </summary>
01147 //
01148 // <synopsis>
01149 //
01150 // When existing code is modified to potentially use asynchronous I/O the current
01151 // VisBuffer usage is probably using automatic (stack) storage which will have to
01152 // be replaced to allow VisBufferAsync objects (which derive from VisBuffer) to be
01153 // used with asynchronous I/O.  The goal of this class is to make that transition
01154 // easier.  The user will replace their existing declaration of a VisBuffer object
01155 // with a declaration of a VisBufferAutoPtr object.  Depending on the attributes
01156 // of the VisBuffer reference/pointer or the ROVisibilityIterator provided in the
01157 // VisBufferAutoPtr constructor, the appropriate type of VisBuffer will be created
01158 // dynamically.  The VisBufferAutoPtr will also function somewhat like an auto_ptr
01159 // and delete the underlying object when the VisBufferAutoPtr object is destroyed.
01160 //
01161 // Once the straight VisBuffer declaration is replaced, then the code in its scope
01162 // will need to be modified to dereference the VisBufferAutoPtr or to delete use
01163 // of the address-of operator, "&", applied to the previous VisBuffer variable.
01164 // See the example below.
01165 //
01166 // </synopsis>
01167 // <example>
01168 //
01169 // <code>
01170 // // Before adding asynchronous I/O support
01171 //
01172 // VisBuffer vb (vi);
01173 //
01174 // doSomething (vb);        // void doSomething (VisBuffer &);
01175 // doSomethingElse (& vb);  // void doSomethingElse (VisBuffer *);
01176 //
01177 // // After adding asynchronous I/O support
01178 //
01179 // VisBufferAutoPtr vb (vi);
01180 //
01181 // doSomething (* vb);
01182 // doSomethingElse (vb.get());
01183 //
01184 // </code>
01185 // </example>
01186 //
01187 class VisBufferAutoPtr {
01188 
01189 public:
01190 
01191     VisBufferAutoPtr ();
01192     VisBufferAutoPtr (VisBufferAutoPtr & other);
01193     explicit VisBufferAutoPtr (VisBuffer &);
01194     explicit VisBufferAutoPtr (VisBuffer *);
01195     explicit VisBufferAutoPtr (ROVisibilityIterator * rovi);
01196     explicit VisBufferAutoPtr (ROVisibilityIterator & rovi);
01197     ~VisBufferAutoPtr ();
01198 
01199     VisBufferAutoPtr & operator= (VisBufferAutoPtr & other);
01200     VisBuffer & operator* () const;
01201     VisBuffer * operator-> () const;
01202 
01203     VisBuffer * get () const;
01204     VisBuffer * release ();
01205     void set (VisBuffer &);
01206     void set (VisBuffer *);
01207     void set (ROVisibilityIterator * rovi, Bool attachIt = False);
01208     void set (ROVisibilityIterator & rovi, Bool attachIt = False);
01209 
01210 protected:
01211 
01212     void construct (ROVisibilityIterator * rovi, Bool attachVi);
01213     void constructVb (VisBuffer * rovi);
01214 
01215 private:
01216 
01217     VisBuffer * visBuffer_p;
01218 
01219 };
01220 
01221 } //# NAMESPACE CASA - END
01222 
01223 #ifndef AIPS_NO_TEMPLATE_SRC
01224 #include <synthesis/MSVis/VisBuffer.tcc>
01225 #endif //# AIPS_NO_TEMPLATE_SRC
01226 
01227 #endif
01228