casa  $Rev:20696$
PlotMSCache.h
Go to the documentation of this file.
00001 //# PlotMSCache.h: Data cache for plotms.
00002 //# Copyright (C) 2009
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: $
00027 #ifndef PLOTMSCACHE_H_
00028 #define PLOTMSCACHE_H_
00029 
00030 #include <plotms/PlotMS/PlotMSAveraging.h>
00031 #include <plotms/PlotMS/PlotMSConstants.h>
00032 #include <plotms/PlotMS/PlotMSFlagging.h>
00033 #include <plotms/Actions/PlotMSCacheThread.qo.h>
00034 #include <plotms/Data/PlotMSVBAverager.h>
00035 
00036 #include <casa/aips.h>
00037 #include <casa/Arrays.h>
00038 #include <casa/Containers/Block.h>
00039 #include <synthesis/MSVis/VisIterator.h>
00040 #include <synthesis/MSVis/VisBuffer.h>
00041 #include <synthesis/MSVis/VisBufferUtil.h>
00042 
00043 namespace casa {
00044 
00045 //# Forward declarations.
00046 class PlotMSApp;
00047 
00048 
00049 class PlotMSCache {
00050     
00051     // Friend class declarations.
00052     friend class PlotMSData;
00053   
00054 public:    
00055 
00056     // Varieties of cache
00057     enum Type {MS, CAL};
00058 
00059     static const PMS::Axis METADATA[];
00060     static const unsigned int N_METADATA;
00061     
00062     static bool axisIsMetaData(PMS::Axis axis);
00063     
00064     static const unsigned int THREAD_SEGMENT;
00065 
00066   // Constructor which takes parent PlotMS.
00067   PlotMSCache(PlotMSApp* parent);
00068   
00069   // Destructor
00070   virtual ~PlotMSCache();
00071 
00072   // Identify myself
00073   PlotMSCache::Type cacheType() { return PlotMSCache::MS; };
00074 
00075   // Report the number of chunks
00076   Int nChunk() const { return nChunk_; };
00077 
00078   // Report the data shapes
00079   inline Matrix<Int>& chunkShapes() {return chshapes_;};
00080 
00081 
00082   // Report the total number of points currently arranged for plotting
00083   //  (TBD: this is incorrect unless ALL cache spaces are full!!)
00084   Int nPoints() const { return nPoints_(nChunk_-1); };
00085 
00086   // Report the reference time for this cache (in seconds)
00087   inline Double refTime() { return refTime_p; };
00088 
00089   // Clears the cache of all stored values.  This should be called when the
00090   // underlying MS or MS selection is changed, thus invalidating stored data.
00091   void clear();
00092   
00093   // Loads the cache for the given axes and data
00094   // columns.  IMPORTANT: this method assumes that any currently loaded data is
00095   // valid for the given VisIter; i.e., if the meta-information or either of
00096   // the axes are already loaded, then they don't need to be reloaded.  If this
00097   // is not the case, then clear() should be called BEFORE append().  If a
00098   // PlotMSCacheThreadHelper object is given, it will be used to report
00099   // progress information.
00100   virtual void load(const vector<PMS::Axis>& axes,
00101                     const vector<PMS::DataColumn>& data,
00102                     const String& msname,
00103                     const PlotMSSelection& selection,
00104                     const PlotMSAveraging& averaging,
00105                     const PlotMSTransformations& transformations,
00106                     PlotMSCacheThread* thread = NULL);
00107 
00108   // Convenience method for loading x and y axes.
00109   void load(PMS::Axis xAxis, PMS::Axis yAxis,
00110             PMS::DataColumn xData, PMS::DataColumn yData,
00111             const String& msname,
00112             const PlotMSSelection& selection,
00113             const PlotMSAveraging& averaging,
00114             const PlotMSTransformations& transformations,
00115             PlotMSCacheThread* thread = NULL) {
00116 
00117     cout << "AHHHHHHHHHHHH*********************" << endl;
00118 
00119       vector<PMS::Axis> axes(2);
00120       axes[0] = xAxis; axes[1] = yAxis;
00121       vector<PMS::DataColumn> data(2);
00122       data[0] = xData; data[1] = yData;
00123       load(axes, data, msname, selection, averaging,transformations, thread);
00124   }
00125   
00126   // Releases the given axes from the cache.
00127   void release(const vector<PMS::Axis>& axes);
00128   
00129   // Set up indexing for the plot (amp vs freq hardwired version)
00130   void setUpCacheForPlot(PMS::Axis xAxis, PMS::Axis yAxis);
00131   void getAxesMask(PMS::Axis axis,Vector<Bool>& axismask);
00132   
00133   // Returns whether cache is filled
00134   bool cacheReady() const { return dataLoaded_; }
00135 
00136   // Returns whether the cache is filled AND ready to return plotting 
00137   //  data via the get methods or not.
00138   bool readyForPlotting() const { return cacheReady() && axesSet_; };
00139 
00140   // Get X and Y limits (amp vs freq hardwired version)
00141   void getRanges(Double& minX, Double& maxX, Double& minY, Double& maxY);
00142 
00143   // Get single values for x-y plotting 
00144   Double getX(Int i);
00145   Double getY(Int i);
00146   void getXY(Int i, Double& x, Double& y);
00147   Double get(PMS::Axis axis);
00148 
00149   Bool getFlagMask(Int i);
00150 
00151   // Access to flags per chunk
00152   inline Array<Bool>& flag(Int chunk) { return *flag_[chunk]; };
00153 
00154 
00155   // Axis-specific generic gets
00156   inline Double getScan(Int chnk,Int irel)     { return scan_(chnk);   (void)irel; };
00157   inline Double getField(Int chnk,Int irel)    { return field_(chnk);  (void)irel; };
00158   inline Double getTime(Int chnk,Int irel)     { return time_(chnk);  (void)irel; };
00159   inline Double getTimeIntr(Int chnk,Int irel) { return timeIntr_(chnk);  (void)irel; };
00160   inline Double getSpw(Int chnk,Int irel)      { return spw_(chnk);  (void)irel; };
00161 
00162   inline Double getFreq(Int chnk,Int irel) { return *(freq_[chnk]->data()+irel); };
00163   inline Double getVel(Int chnk,Int irel)  { return *(vel_[chnk]->data()+irel); };
00164   inline Double getChan(Int chnk,Int irel) { return *(chan_[chnk]->data()+irel); };
00165   inline Double getCorr(Int chnk,Int irel) { return *(corr_[chnk]->data()+irel); };
00166   inline Double getAnt1(Int chnk,Int irel) { return *(antenna1_[chnk]->data()+irel); };
00167   inline Double getAnt2(Int chnk,Int irel) { return *(antenna2_[chnk]->data()+irel); };
00168   inline Double getBsln(Int chnk,Int irel) { return *(baseline_[chnk]->data()+irel); };
00169   inline Double getUVDist(Int chnk,Int irel) { return *(uvdist_[chnk]->data()+irel); };
00170   inline Double getUVDistL(Int chnk,Int irel) { return *(uvdistL_[chnk]->data()+irel); };
00171   inline Double getU(Int chnk,Int irel) { return *(u_[chnk]->data()+irel); };
00172   inline Double getV(Int chnk,Int irel) { return *(v_[chnk]->data()+irel); };
00173   inline Double getW(Int chnk,Int irel) { return *(w_[chnk]->data()+irel); };
00174 
00175   inline Double getAmp(Int chnk,Int irel)  { return *(amp_[chnk]->data()+irel); };
00176   inline Double getPha(Int chnk,Int irel)  { return *(pha_[chnk]->data()+irel); };
00177   inline Double getReal(Int chnk,Int irel) { return *(real_[chnk]->data()+irel); };
00178   inline Double getImag(Int chnk,Int irel) { return *(imag_[chnk]->data()+irel); };
00179 
00180   inline Double getFlag(Int chnk,Int irel) { return *(flag_[chnk]->data()+irel); };
00181   inline Double getFlagRow(Int chnk,Int irel) { return *(flagrow_[chnk]->data()+irel); };
00182   inline Double getRow(Int chnk,Int irel) { return *(row_[chnk]->data()+irel); };
00183 
00184   // These are array-global (one value per chunk)
00185   inline Double getAz0(Int chnk,Int irel) { return az0_(chnk);  (void)irel; };
00186   inline Double getEl0(Int chnk,Int irel) { return el0_(chnk);  (void)irel; };
00187   inline Double getHA0(Int chnk,Int irel) { return ha0_(chnk);  (void)irel; };
00188   inline Double getPA0(Int chnk,Int irel) { return pa0_(chnk);  (void)irel; };
00189 
00190   // These are antenna-based
00191   inline Double getAntenna(Int chnk,Int irel) { return *(antenna_[chnk]->data()+irel); };
00192   inline Double getAz(Int chnk,Int irel)      { return *(az_[chnk]->data()+irel); };
00193   inline Double getEl(Int chnk,Int irel)      { return *(el_[chnk]->data()+irel); };
00194   inline Double getParAng(Int chnk,Int irel)  { return *(parang_[chnk]->data()+irel); };
00195 
00196   // Axis-specific gets
00197   inline Double getScan()      { return scan_(currChunk_); };
00198   inline Double getField()     { return field_(currChunk_); };
00199   inline Double getTime()      { return time_(currChunk_); };
00200   inline Double getTimeIntr()  { return timeIntr_(currChunk_); };
00201   inline Double getSpw()       { return spw_(currChunk_); };
00202   inline Double getFreq() { return *(freq_[currChunk_]->data()+(irel_/nperchan_(currChunk_))%ichanmax_(currChunk_)); };
00203   inline Double getVel() { return *(vel_[currChunk_]->data()+(irel_/nperchan_(currChunk_))%ichanmax_(currChunk_)); };
00204   inline Double getChan() { return *(chan_[currChunk_]->data()+(irel_/nperchan_(currChunk_))%ichanmax_(currChunk_)); };
00205   inline Double getCorr() { return *(corr_[currChunk_]->data()+(irel_%icorrmax_(currChunk_))); };
00206   inline Double getAnt1() { return *(antenna1_[currChunk_]->data()+(irel_/nperbsln_(currChunk_))%ibslnmax_(currChunk_)); };
00207   inline Double getAnt2() { return *(antenna2_[currChunk_]->data()+(irel_/nperbsln_(currChunk_))%ibslnmax_(currChunk_)); };
00208   inline Double getBsln() { return *(baseline_[currChunk_]->data()+(irel_/nperbsln_(currChunk_))%ibslnmax_(currChunk_)); };
00209   inline Double getUVDist() { return *(uvdist_[currChunk_]->data()+(irel_/nperbsln_(currChunk_))%ibslnmax_(currChunk_)); };
00210   inline Double getUVDistL() { return *(uvdistL_[currChunk_]->data()+(irel_/nperchan_(currChunk_))%ichanbslnmax_(currChunk_)); };
00211   inline Double getU() { return *(u_[currChunk_]->data()+(irel_/nperbsln_(currChunk_))%ibslnmax_(currChunk_)); };
00212   inline Double getV() { return *(v_[currChunk_]->data()+(irel_/nperbsln_(currChunk_))%ibslnmax_(currChunk_)); };
00213   inline Double getW() { return *(w_[currChunk_]->data()+(irel_/nperbsln_(currChunk_))%ibslnmax_(currChunk_)); };
00214 
00215   inline Double getAmp()  { return *(amp_[currChunk_]->data()+(irel_%idatamax_(currChunk_))); }; 
00216   inline Double getPha()  { return  *(pha_[currChunk_]->data()+(irel_%idatamax_(currChunk_))); };
00217   inline Double getReal() { return *(real_[currChunk_]->data()+(irel_%idatamax_(currChunk_))); };
00218   //  inline Double getImag() { return *(imag_[currChunk_]->data()+(irel_%idatamax_(currChunk_))); };
00219   inline Double getImag() { return getImag2(currChunk_,(irel_%idatamax_(currChunk_))); };
00220   inline Double getImag2(Int ch, Int i) { return *(imag_[ch]->data()+i); };
00221 
00222   inline Double getFlag() { return *(flag_[currChunk_]->data()+(irel_%idatamax_(currChunk_))); };
00223   inline Double getFlagRow() { return *(flagrow_[currChunk_]->data()+(irel_/nperbsln_(currChunk_))%ibslnmax_(currChunk_)); };
00224   inline Double getRow() { return *(row_[currChunk_]->data()+(irel_/nperbsln_(currChunk_))%ibslnmax_(currChunk_)); };
00225 
00226   inline Double getWt() { return *(wt_[currChunk_]->data()+(irel_/nperbsln_(currChunk_))*nperchan_(currChunk_) + irel_%nperchan_(currChunk_)); };
00227 
00228   // These are array-global (one value per chunk):
00229   inline Double getAz0() { return az0_(currChunk_); };
00230   inline Double getEl0() { return el0_(currChunk_); };
00231   inline Double getHA0() { return ha0_(currChunk_); };
00232   inline Double getPA0() { return pa0_(currChunk_); };
00233 
00234   // These are antenna-based
00235   inline Double getAntenna() { return *(antenna_[currChunk_]->data()+(irel_/nperant_(currChunk_))%iantmax_(currChunk_)); };
00236   inline Double getAz() { return *(az_[currChunk_]->data()+(irel_/nperant_(currChunk_))%iantmax_(currChunk_)); };
00237   inline Double getEl() { return *(el_[currChunk_]->data()+(irel_/nperant_(currChunk_))%iantmax_(currChunk_)); };
00238   inline Double getParAng() { return *(parang_[currChunk_]->data()+(irel_/nperant_(currChunk_))%iantmax_(currChunk_)); };
00239 
00240   // Locate datum nearest to specified x,y (amp vs freq hardwired versions)
00241   PlotLogMessage* locateNearest(Double x, Double y);
00242   PlotLogMessage* locateRange(const Vector<PlotRegion>& regions);
00243   PlotLogMessage* flagRange(const PlotMSFlagging& flagging,
00244           const Vector<PlotRegion>& regions, Bool flag = True);
00245 
00246   // Access to averaging state in the cache:
00247   PlotMSAveraging& averaging() { return averaging_; }
00248 
00249   // Access to transformations state in the cache
00250   PlotMSTransformations& transformations() { return transformations_; }
00251 
00252   // Access to channel averaging bounds
00253   Matrix<Int>& chanAveBounds(Int spw) { return chanAveBounds_p(spw); };
00254 
00255   // Set flags in the cache
00256   void flagInCache(const PlotMSFlagging& flagging,Bool flag);
00257 
00258   // Sets the plot mask for a single chunk
00259   void setPlotMask(Int chunk);
00260 
00261   // Set flags in the MS
00262   virtual void flagToDisk(const PlotMSFlagging& flagging,Vector<Int>& chunks, Vector<Int>& relids,Bool flag);
00263 
00264   // Returns which axes have been loaded into the cache, including metadata.
00265   // Also includes the size (number of points) for each axis (which will
00266   // eventually be used for a cache manager to let the user know the
00267   // relative memory use of each axis).
00268   vector<pair<PMS::Axis, unsigned int> > loadedAxes() const;
00269 
00270 protected:
00271     
00272   // Forbid copy for now
00273   PlotMSCache(const PlotMSCache& mc);
00274 
00275   // Increase the number of chunks
00276   void increaseChunks(Int nc=0);
00277 
00278   // Setup the VisIter
00279   void setUpVisIter(const String& msname,
00280                     const PlotMSSelection& selection,
00281                     Bool readonly=True,
00282                     Bool chanselect=True,
00283                     Bool corrselect=True);
00284 
00285 
00286   // Loop over VisIter, filling the cache
00287   void loadChunks(ROVisibilityIterator& vi,
00288                   const vector<PMS::Axis> loadAxes,
00289                   const vector<PMS::DataColumn> loadData,
00290                   const PlotMSAveraging& averaging,
00291                   PlotMSCacheThread* thread);
00292   void loadChunks(ROVisibilityIterator& vi,
00293                   const PlotMSAveraging& averaging,
00294                   const Vector<Int>& nIterPerAve,
00295                   const vector<PMS::Axis> loadAxes,
00296                   const vector<PMS::DataColumn> loadData,
00297                   PlotMSCacheThread* thread);
00298 
00299   // Force read on vb for requested axes 
00300   //   (so pre-cache averaging treats all data it should)
00301   void forceVBread(VisBuffer& vb,
00302                    vector<PMS::Axis> loadAxes,
00303                    vector<PMS::DataColumn> loadData);
00304 
00305   // Tell time averager which data column to read
00306   void discernData(vector<PMS::Axis> loadAxes,
00307                    vector<PMS::DataColumn> loadData,
00308                    PlotMSVBAverager& vba);
00309 
00310 
00311   // Count the chunks required in the cache
00312   void countChunks(ROVisibilityIterator& vi,PlotMSCacheThread* thread);  // old
00313   void countChunks(ROVisibilityIterator& vi, Vector<Int>& nIterPerAve,  // supports time-averaging 
00314                    const PlotMSAveraging& averaging,PlotMSCacheThread* thread);
00315 
00316   // Fill a chunk with a VisBuffer.  
00317   void append(const VisBuffer& vb, Int vbnum, PMS::Axis xAxis, PMS::Axis yAxis,
00318               PMS::DataColumn xData, PMS::DataColumn yData);
00319   
00320   // Issue meta info report to the given stringstream.
00321   void reportMeta(Double x, Double y, stringstream& ss);
00322 
00323   // Set currChunk_ according to a supplied index
00324   void setChunk(Int i);
00325 
00326   // Clean up the PtrBlocks
00327   void deleteCache();
00328   
00329   // Loads the specific axis/metadata into the cache using the given VisBuffer.
00330   void loadAxis(VisBuffer& vb, Int vbnum, PMS::Axis axis,
00331                 PMS::DataColumn data = PMS::DEFAULT_DATACOLUMN);
00332   
00333   // Returns the number of points loaded for the given axis or 0 if not loaded.
00334   unsigned int nPointsForAxis(PMS::Axis axis) const;
00335   
00336   // Computes the X and Y limits for the currently set axes.  In the future we
00337   // may want to cache ALL ranges for all loaded values to avoid recomputation.
00338   void computeRanges();
00339   
00340   // Convenience methods that call log() with the given method name and the
00341   // appropriate event type.
00342   // <group>
00343   void logInfo(const String& method, const String& message) {
00344       log(method, message, PlotLogger::MSG_INFO); }
00345   void logDebug(const String& method, const String& message) {
00346       log(method, message, PlotLogger::MSG_DEBUG); }
00347   void logWarn(const String& method, const String& message) {
00348       log(method, message, PlotLogger::MSG_WARN); }
00349   void logError(const String& method, const String& message) {
00350       log(method, message, PlotLogger::MSG_ERROR); }
00351   
00352   void logLoad(const String& message) {
00353       log(PMS::LOG_ORIGIN_LOAD_CACHE, message, PMS::LOG_EVENT_LOAD_CACHE); }
00354   void logFlag(const String& message) {
00355       log(PMS::LOG_ORIGIN_FLAG, message, PMS::LOG_EVENT_FLAG); }
00356   // </group>
00357   
00358   // Logs the given message from the given method name as the given event type
00359   // (see PlotLogger).
00360   void log(const String& method, const String& message, int eventType);
00361 
00362   // Private data
00363   
00364   // Parent plotms.
00365   PlotMSApp* plotms_;
00366 
00367   // The number of antennas
00368   Int nAnt_;
00369 
00370   // The number of chunks
00371   Int nChunk_;
00372 
00373   // The in-focus chunk and relative index offset
00374   Int currChunk_, irel_;
00375 
00376   // The cumulative running total of points
00377   Vector<Int> nPoints_;
00378 
00379   // the net number of flagged, unflagged, total points
00380   Int nTotalPoints_,nUnFlagPoints_, nFlagPoints_;
00381 
00382   // The reference time for this cache, in seconds
00383   Double refTime_p;
00384 
00385   // Axes mask
00386   Vector<Bool> netAxesMask_;
00387 
00388   Double minX_,maxX_,minY_,maxY_;
00389 
00390   // The fundamental meta-data cache
00391   Matrix<Int> chshapes_;
00392   Vector<Bool> goodChunk_;
00393   Vector<Double> time_, timeIntr_;
00394   Vector<Int> field_, spw_, scan_;
00395   PtrBlock<Vector<uInt>*> row_;
00396   PtrBlock<Vector<Int>*> antenna1_, antenna2_, baseline_;
00397   PtrBlock<Vector<Double>*> uvdist_, u_, v_, w_;
00398   PtrBlock<Matrix<Double>*> uvdistL_;
00399   PtrBlock<Vector<Double>*> freq_, vel_;
00400   PtrBlock<Vector<Int>*> chan_;
00401   PtrBlock<Vector<Int>*> corr_;
00402 
00403   // Optional parts of the cache
00404   PtrBlock<Vector<Float>*> pa_;
00405 
00406   // Data (the heavy part)
00407   PtrBlock<Array<Float>*> amp_, pha_, real_, imag_;
00408   PtrBlock<Array<Bool>*> flag_;
00409   PtrBlock<Vector<Bool>*> flagrow_;
00410   
00411   PtrBlock<Array<Float>*> wt_;
00412 
00413   PtrBlock<Array<Bool>*> plmask_;
00414 
00415   PtrBlock<Vector<Float>*> parang_;
00416   PtrBlock<Vector<Int>*> antenna_;
00417   PtrBlock<Vector<Double>*> az_,el_;
00418 
00419   Vector<Double> az0_,el0_,ha0_,pa0_;
00420 
00421   // Indexing help
00422   Vector<Int> icorrmax_, ichanmax_, ibslnmax_, idatamax_;
00423   Vector<Int> nperchan_, nperbsln_, nperant_;
00424   Vector<Int> ichanbslnmax_;
00425   Vector<Int> iantmax_;
00426 
00427   // Current setup/state.
00428   bool dataLoaded_;
00429   bool axesSet_;
00430   PMS::Axis currentX_, currentY_;
00431   map<PMS::Axis, bool> loadedAxes_;
00432   map<PMS::Axis, PMS::DataColumn> loadedAxesData_;
00433 
00434   // A copy of the Data parameters 
00435   String msname_;
00436   PlotMSSelection selection_;
00437   PlotMSAveraging averaging_;
00438   PlotMSTransformations transformations_;
00439 
00440   // meta info for locate output
00441   Vector<String> antnames_;      
00442   Vector<String> fldnames_;      
00443 
00444   // A container for channel averaging bounds
00445   Vector<Matrix<Int> > chanAveBounds_p;
00446 
00447   // Provisional flagging helpers
00448   Vector<Int> nVBPerAve_;
00449 
00450   // VisIterator pointer
00451   ROVisIterator* rvi_p;
00452   VisIterator* wvi_p;
00453 
00454   // VisBufferUtil for freq/vel calculations
00455   VisBufferUtil vbu_;
00456 
00457     
00458 };
00459 typedef CountedPtr<PlotMSCache> PlotMSCachePtr;
00460 
00461 
00462 }
00463 
00464 #endif /* PLOTMSCACHE_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines