MSAsRaster.h

Go to the documentation of this file.
00001 //# MSAsRaster.h: DisplayData (drawing layer) for raster displays of an MS
00002 //# Copyright (C) 2000,2001,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 //#
00027 //# $Id$
00028 
00029 #ifndef TRIALDISPLAY_MSASRASTER_H
00030 #define TRIALDISPLAY_MSASRASTER_H
00031 
00032 
00033 #include <casa/aips.h>
00034 #include <display/DisplayDatas/ActiveCaching2dDD.h>
00035 #include <ms/MeasurementSets.h>
00036 #include <images/Images/PagedImage.h>
00037 #include <casa/Arrays/Vector.h>
00038 #include <casa/Quanta/Unit.h>
00039 #include <casa/BasicSL/String.h>
00040 #include <display/Display/DParameterChoice.h>
00041 #include <display/Display/DParameterRange.h>
00042 #include <display/Display/DParameterString.h>
00043 #include <display/Display/DParameterButton.h>
00044 #include <display/DisplayCanvas/WCPowerScaleHandler.h>
00045 #include <msvis/MSVis/VisibilityIterator.h>
00046 #include <display/DisplayDatas/WorldAxesDD.h>
00047 #include <display/Display/DisplayEnums.h>
00048 #include <display/Display/WorldCanvasHolder.h>
00049 #include <display/DisplayDatas/CachingDisplayMethod.h>
00050 #include <display/DisplayDatas/DisplayDataOptions.h>
00051 #include <display/Display/Colormap.h>
00052 #include <display/region/Region.qo.h>
00053 
00054 namespace casa { //# NAMESPACE CASA - BEGIN
00055 
00056         class MSAsRasterDM;
00057 
00058 
00059 // <summary>
00060 // Class for displaying data within an MS as a raster (gridded) image.
00061 // </summary>
00062 
00063 // <prerequisite>
00064 //   <li> CachingDisplayData
00065 //   <li> WorldCanvas[Holder]
00066 //   <li> MeasurementSet
00067 //   <li> CoordinateSystem
00068 //   <li> Array
00069 // </prerequisite>
00070 
00071 // <etymology>
00072 // "MSAsRaster" is a implementation of a <linkto class=ActiveCaching2dDD>
00073 // ActiveCaching2dDD </linkto> which provides for the display of Measurement
00074 // Set data (visibilities) as a raster image.
00075 // </etymology>
00076 
00077 // <synopsis>
00078 // MSAsRaster displays Measurement Set data which can be presented as a
00079 // regular grid, on a WorldCanvas (data which is sparse and
00080 // irregular on its display axes would typically be plotted using MSAsXY
00081 // instead).  Display or iteration axes include time, baseline,
00082 // channels and polarizations.  Visibilities of the selected slice are drawn
00083 // as a Raster image.
00084 //
00085 // Unlike many DDs, MSAsRaster has _two_ levels of underlying data: the source
00086 // MS, and a hypercube of visibility data, which is extracted from the MS and
00087 // gridded onto 5 main axes: time, baseline, spectral window, frequency and
00088 // polarization.  Extracting the data is a more time-consuming operation
00089 // than display of various portions of gridded data, and is triggered only
00090 // through the extract_() method.  Data selection options do not take effect
00091 // until triggered in this way.  In contrast, many options affecting display
00092 // of the extracted data (such as zooms, and colormapping) affect
00093 // the display immediately, as with most DDs.  Setting new display axes will
00094 // trigger extract_() if the current extracted hypercube does not fill them.
00095 //
00096 // </synopsis>
00097 
00098 // <example>
00099 // <srcblock>
00100 //    MSAsRaster *mar = new MSAsRaster("filename_of.ms");
00101 //    wcHolder->addDisplayData(mar);
00102 // </srcblock>
00103 // </example>
00104 //
00105 // <motivation>
00106 // To move compute-intensive tasks of data handling
00107 // for Measurement Set display out of glish into C++
00108 // </motivation>
00109 
00110 // <todo asof="2001/02/01">
00111 //
00112 // The current user interface for triggering extract_ is the 'Apply' button,
00113 // which is detected internally when setOptions() is called with more than
00114 // one user option field to be updated.  This is not entirely satisfactory;
00115 // User interface could use improvement.
00116 //
00117 // Major items among other things left to to:
00118 //
00119 // * MS Selection and averaging.
00120 //
00121 // * World coordinates in axis labelling, position tracking and slice
00122 //   selection
00123 //
00124 // * Alternative orderings, especially along baseline and time axes
00125 //
00126 // </todo>
00127 
00128         class MSAsRaster: public ActiveCaching2dDD {
00129 
00130         public:
00131 
00132                 typedef Int Axis;
00133 
00134                 // constructor
00135                 // from the filename of an MS
00136                 MSAsRaster( const String msname, const viewer::DisplayDataOptions &ddo );
00137 
00138                 //# from an MS object
00139                 //# MSAsRaster(MeasurementSet* ms);
00140                 //#unneeded?--prefer to control permissions...
00141 
00142                 // Destructor
00143                 virtual ~MSAsRaster();
00144 
00145 
00146                 // Apply option values stored in <src>rec</src> to the DisplayData.  A
00147                 // return value of <src>True</src> means a refresh is needed.
00148                 // <src>recOut</src> contains any fields which were implicitly
00149                 // changed as a result of the call to this function.
00150                 // Parameters from the 'adjust' gui are sent through here,
00151                 // controlling and triggering many of
00152                 // MSAsRaster's actions.  (Other input is via the mouse on the
00153                 // canvas, which affects the object through the event handlers).
00154                 virtual Bool setOptions(Record &rec, Record &recOut);
00155 
00156                 // Retrieve the current options.  In addition to the values themselves, the
00157                 // returned record contains meta-information (prompts, help text,
00158                 // choices, defaults, etc.) useful in constructing gui elements to
00159                 // control the DD settings.
00160                 // Note: If the user interface is to be zero-based, you should call
00161                 // setUIBase(0) _before_ using this routine -- see setUIBase().
00162                 virtual Record getOptions( bool scrub=false ) const;
00163 
00164                 // set all options to default values (unused so far; incomplete
00165                 // support in base classes...incomplete here as well).
00166                 virtual void setDefaultOptions();
00167 
00168 
00169                 // Return the current options of this DisplayData as a 'restrictions'
00170                 // AttributeBuffer (only options that affect the way the image would
00171                 // be drawn are returned).  It is used to determine which (if any) of
00172                 // the cached drawings can be used to satisfy the current draw request.
00173                 virtual AttributeBuffer optionsAsAttributes();
00174 
00175 
00176                 // Determine whether DD is compatible with the WC[H]'s current
00177                 // world coordinates.  MSAsRaster DDs must be in charge (the CS master),
00178                 // Otherwise they will not respond.  Multiple MSARs on one canvas
00179                 // (blinking, etc.) is not supported, because of possible confusion
00180                 // about which one(s) should respond to flagging edits.
00181                 virtual Bool conformsToCS(const WorldCanvas& wc) {
00182                         csConformed_ = wc.isCSmaster(this);
00183                         return csConformed_;
00184                 }
00185 
00186                 // Format the data value at the given world position.
00187                 // Call setActiveImage(zindex) with the desired animator position
00188                 // before calling this routine.
00189                 virtual String showValue(const Vector<Double> &world);
00190 
00191                 // Format the position of the cursor.  Also requires previous call to
00192                 // setActiveImage(zindex); also used for position tracking.
00193                 virtual String showPosition(const Vector<Double> &world,
00194                                             const Bool &displayAxesOnly = False);
00195                 bool showPosition( viewer::RegionInfo::stats_t &stat_list, const Vector<Double> &world,
00196                                    const Bool& displayAxesOnly = False);
00197 
00198                 // get the Unit for displayed data values (visibilities)
00199                 virtual const Unit dataUnit() const;
00200                 const IPosition dataShape() const {
00201                         return IPosition( );
00202                 }
00203                 uInt dataDim() const {
00204                         return 0;
00205                 }
00206                 std::vector<int> displayAxes( ) const {
00207                         return std::vector<int>( );
00208                 }
00209 
00210 
00211                 // Return the type of this DisplayData.
00212                 virtual Display::DisplayDataType classType() {
00213                         return Display::Raster;
00214                 }
00215                 // Pure virtual function from DisplayData...
00216                 String dataType() const {
00217                         return "ms";
00218                 }
00219 
00220 
00221                 // return the size of the animation axis.
00222                 // <group>
00223                 virtual uInt nelements() const {
00224                         return msShape_[axisOn_(Z)];
00225                 }
00226                 virtual uInt nelements(const WorldCanvasHolder &) const {
00227                         return msShape_[axisOn_(Z)];
00228                 }
00229                 // </group>
00230 
00231                 // Handle axis labelling.
00232                 virtual Bool labelAxes(const WCRefreshEvent &ev);
00233                 virtual Bool canLabelAxes() const;
00234 
00235                 // Needed to enable or destroy drawlists and colormaps on corresp. canvas.
00236                 // (Only to be called by the relevant WCH).
00237                 // <group>
00238                 virtual void notifyRegister(WorldCanvasHolder *wch) ;
00239                 virtual void notifyUnregister(WorldCanvasHolder& wch,
00240                                               Bool ignoreRefresh = False) ;
00241                 // </group>
00242 
00243                 // handle flagging region selection events, via new-style (1/02)
00244                 // interface.
00245                 virtual void handleEvent(DisplayEvent& ev);
00246 
00247                 // Return the animator position setting preferred if this DD
00248                 // about to be registered on a new DisplayPanel.
00249                 virtual Bool zIndexHint(Int& preferredZIndex) const;
00250 
00251                 // Empty cache completely.
00252                 virtual void purgeCache() {
00253                         ActiveCaching2dDD::purgeCache();
00254                         itsAxisLabeller.purgeCache();
00255                 }               //# (include our labeller)
00256 
00257                 // Empty cache of all DMs for a given WCH.
00258                 virtual void purgeCache(const WorldCanvasHolder& wch) {
00259                         ActiveCaching2dDD::purgeCache(wch);
00260                         itsAxisLabeller.purgeCache(wch);
00261                 }               //# (include our labeller)
00262 
00263                 // DD 'Absolute Pixel Coordinates', e.g. channel numbers, are internally
00264                 // 0-based (they begin numbering at 0), but certain external user-interface
00265                 // methods (e.g. showPosition(), used for position tracking) have
00266                 // produced 1-based output traditionally for the glish-based viewer.
00267                 // uiBase_, and related methods uiBase() and setUIBase(), allow newer
00268                 // (python/Qt-based) code to cause external ui functions like showValue()
00269                 // to report 0-based values instead.  Unless setUIBase(0) is called, the
00270                 // traditional 1-based reporting behavior is retained by default.
00271                 // For this DD, in addition to tracking, this setting affects labelling,
00272                 // slider-based position setting, and MS selection on Field or Sp. Window.
00273                 //
00274                 // If you are using 0-basing in the user interface, you should call
00275                 // setUIBase(0) right after constructing this DisplayData, before other
00276                 // user interface operations such as getOptions(); the method has not
00277                 // been tested other than for a one-time setUIBase(0) call directly after
00278                 // DD construction.
00279                 virtual void setUIBase(Int uibase) {
00280                         Int oldUIBase = uiBase();
00281                         ActiveCaching2dDD::setUIBase(uibase);
00282                         if(oldUIBase != uiBase()) {
00283                                 setCS_();               // fixes axis labelling, among other things...
00284                                 purgeCache();
00285                         }
00286                 }
00287                 // In case it helps; the method should probably be called
00288                 // only before we've had a chance to cache anything though....
00289 
00290 
00291 
00292                 virtual const String &name( ) const {
00293                         return msName_;
00294                 }
00295 
00296                 // added to allow flagging control from mouse tools... <drs>
00297                 bool flag( WorldCanvas *wc, double blc_x, double blc_y, double trc_x, double trc_y );
00298 
00299                 std::string errorMessage( ) const { return ""; }
00300 
00301         protected:
00302 
00303                 // This routine is called to inform the DD of the current canvas's
00304                 // animator index.  Used by confromsTo() and related methods.
00305                 // Return value indicates whether the index is within the data's range.
00306                 virtual Bool setActiveZIndex_(Int zindex) {
00307                         activeZIndex_ = zindex;
00308                         // activeZIndex_ and zIndexConformed_ protected on the DD
00309                         // base level; they are intended to be set only by these
00310                         // [protected] setActiveZIndex_() methods, which are in turn
00311                         // called by DD::conformsToZIndex().
00312                         zIndexConformed_ = ( activeZIndex_>=0 && activeZIndex_<Int(nelements()) );
00313                         return zIndexConformed_;
00314                 }
00315 
00316                 // Construct and destroy the user option DisplayParameters.
00317                 // To be used by constructors/destructor only.
00318                 // <group>
00319                 void constructParameters_();
00320                 void deleteParameters_();
00321                 // </group>
00322 
00323                 // return a new MSAsRasterDM for the given WorldCanvas.
00324                 virtual CachingDisplayMethod *newDisplayMethod(WorldCanvas *worldCanvas,
00325                         AttributeBuffer *wchAttributes,
00326                         AttributeBuffer *ddAttributes,
00327                         CachingDisplayData *dd);
00328 
00329                 // Helper functions.
00330                 //# gcc-3.4.2 cannot distinguish between the 2 functions in complex.
00331                 // <group>
00332                 static Float real (const Complex& val) {
00333                         return val.real();
00334                 }
00335                 static Float imag (const Complex& val) {
00336                         return val.imag();
00337                 }
00338                 // </group>
00339 
00340         private:
00341 
00342 
00343                 // Constructs position information for non-deviation display
00344                 // state averaging...
00345                 String avgPos( const String &dim, int v );
00346 
00347                 // The (multiple) DMs which this DD creates just hold drawlist handles.
00348                 // They send the actual drawing chores back to MSAsRaster::draw_().
00349                 // The friend designation is so that draw_() can be made private.
00350                 friend class MSAsRasterDM;
00351 
00352                 // Default and copy constructors, and the assignment operator, are
00353                 // non-functional and should not be used.  Do not make copies of
00354                 // DisplayData objects, or pass them by value;
00355                 // use references or pointers instead.
00356                 // <group>
00357                 MSAsRaster(): mspos_(this) {  }
00358                 MSAsRaster(const MSAsRaster &other): ActiveCaching2dDD(other), mspos_(this) {  }
00359                 MSAsRaster& operator=(const MSAsRaster &/*other*/) {
00360                         return *this;
00361                 }
00362                 // </group>
00363 
00364                 // Initialization common to all useful constructors
00365                 void initMSAR_( const viewer::DisplayDataOptions &ddo );
00366 
00367                 // set/restore default option values on this level only.  (Not implemented).
00368                 void setDefaultMSAROptions_();
00369 
00370 
00371                 //#-------------------------------------------------------------------
00372                 //# The Workhorses--steps in producing the display from the MS and the
00373                 //# the user input settings.  (Most of the control logic is elsewhere).
00374 
00375                 // prepare the selection MS and its VisSet.
00376                 void selectVS_( const viewer::DisplayDataOptions &ddo=viewer::DisplayDataOptions( ) );
00377 
00378                 // find the ranges of the MS selection (VisSet) for the 5 hypercube axes
00379                 void findRanges_();
00380 
00381                 // update/set the (2d--canvas) coordinate system from the current MS
00382                 // selection and display axes.
00383                 DisplayCoordinateSystem setCS_();
00384 
00385                 // Extract the hypercube buffer of visibilities for the requested
00386                 // MS selection and axis settings (the most time-consuming operation).
00387                 void extract_();
00388 
00389                 // retrieve (2D) slice data Matrix, and corresponding mask/flag
00390                 // matrices, to send to the display canvas.
00391                 void createDisplaySlice_();
00392 
00393                 // Actually do the drawing.
00394                 // The return value indicates whether the DD was able to draw.
00395                 Bool draw_(Display::RefreshReason reason,
00396                            WorldCanvasHolder &wch, WorldCanvas &wc);
00397 
00398 
00399 
00400                 //#------baseline reordering routines-------------------------------------
00401 
00402                 // Called from findRanges_(), computes translation matrices between
00403                 // antenna1,antenna2 and baseline index  (a1A_, a2A_, a1L_, a2L_,
00404                 // bslA_, bslL_).
00405                 void computeBaselineSorts_();
00406 
00407 
00408                 // Set the baseline index translation Arrays a1_, a2_ and bsl_ by
00409                 // copying as appropriate according to the current sort.  (Source Arrays
00410                 // should already have been created by computeBaselineSorts_(), above).
00411                 // also sets total number of baselines, nbsl_, which becomes
00412                 // msShape_[BASELN] except in single dish case.
00413                 void setBslSort_();
00414 
00415 
00416                 // Shuffle vis_ into new baseline order, per user request for sort change.
00417                 // (Information needed to do this should already have been set up by
00418                 // the previous two routines).
00419                 void reSortVis_();
00420 
00421 
00422 
00423                 //#-----small helper routines.-----------------------------------------
00424 
00425                 // Return baseline index (for the ant1-ant2 sort _only_) from
00426                 // antenna numbers.  Input must have 0 <= a1 <= a2 < nAnt_.
00427                 // Mapping leaves room for autocorrelations plus a 1-pixel gap between
00428                 // successive antenna1 groups.
00429                 //
00430                 //# (Crude--needs improvement:  *Wasteful if some antennas have ANTENNA
00431                 //# table entries but don't appear in the visibility data.  *The gaps
00432                 //# really should appear only in the final display Matrix, when needed.
00433                 //# *Slots for autocorrs should also be inserted only if the selected
00434                 //# data includes them.  *Other baseline ordering options should exist).
00435                 Int bsln_(Int a1, Int a2) const {
00436                         return a1*(nAnt_+2) - a1*(a1+1)/2 + a2-a1;
00437                 }
00438 
00439                 // A corresponding inverse, this handles non-integer 'baseline indices'.
00440                 // Set abase to 1 to number ant1 and ant2 from 1.  (The baseline index
00441                 // bsl is always numbered from 0, internally).  The version with the
00442                 // Double return value returns a1 + a2/a1mult_() (for labelling --
00443                 // example: for baseline index corresp. to 13-24, returns 13.024).
00444                 // <group>
00445                 void a1a2_(Double& a1, Double& a2,  Double bsl, Int abase=0) const;
00446                 Double a1a2_(Double bsl, Int abase=0);
00447                 // </group>
00448 
00449                 // Subsidiary routine for above, determines (in effect) how many decimal
00450                 // places are needed for an antenna number (including one leading zero).
00451                 // Returns 1000 for 10-99 antennas, 10000 for 100-999 antennas, etc.
00452                 Double a1mult_() {
00453                         Double m=10.;
00454                         while(m <= nAnt_-1+uiBase()) m*=10.;
00455                         return 10*m;
00456                 }
00457 
00458 
00459                 // A small routine to return the label for the "Visibility Memory"
00460                 // slider widget.  The label includes feedback on the selected MS's
00461                 // total size, and is updated when that changes.
00462                 String visMbLabel_();
00463 
00464 
00465                 // Reset Block of relevant Spectral window IDs, and return
00466                 // correponding Vectors of channel frequencies.  freq_ is used for display
00467                 // of frequencies in position tracking.  spwId_ translates spw 'index'
00468                 // into the actual spectral window ID.
00469                 void resetFreq_() {
00470                         for(uInt s=0; s<freq_.nelements(); s++) {
00471                                 delete static_cast<Vector<Double>*>(freq_[s]);
00472                         }
00473                         freq_.resize(0, True);
00474                         spwId_.resize(0, True);
00475                 }
00476 
00477                 // Translate actual spectral window ID into the 'spw' index (zero-based
00478                 // pixel coordinate) along the spectral window axis.  Because the
00479                 // user can select specific spectral windows, these two may not be the same.
00480                 // Returns -1 if the spectral window ID is not in the selected MS data.
00481                 Int spw_(Int spwid) {
00482                         Int nspw=spwId_.nelements();
00483                         for(Int spw=0; spw<nspw; spw++) if(spwId_[spw]==spwid) return spw;
00484                         return -1;
00485                 }
00486 
00487                 // Compute vis_ array dimensions which fit into allowed memory.
00488                 // visShpA is the actual shape to be allocated to vis_; visShp is the
00489                 // portion which will actually be used at present; it may be smaller on the
00490                 // BASELN axis if baselines are currently sorted by length (no 'gaps').
00491                 void computeVisShape_(Block<Int>& visShp, Block<Int>& visShpA);
00492 
00493                 // Return how many of the given (sorted) animation frames
00494                 // can be displayed from a given window (strtfrm, nfrms) on that axis.
00495                 // In cases where nframes>0, margin will be the minimum padding on either
00496                 // side, from the edges of the interval to the frames of interest.
00497                 Int nframes_(const Block<Int>& frames, Int strtfrm, Int nfrms, Int& margin);
00498 
00499                 // Return the maximum number of the given (sorted) animation frames that
00500                 // can be displayed from a window or interval of a given size (nfrms).
00501                 // also returns where that interval should start (strtfrm).
00502                 Int maxframes_(const Block<Int>& frames, Int& strtfrm, Int nfrms);
00503 
00504                 // Reset data scaling DParameters to newly-computed data ranges.
00505                 void resetMinMax_();
00506 
00507 
00508         // represent channels with their frequency?
00509         bool freqAxis( Axis ) const;
00510 
00511                 //#------flagging routines----------------------------------------------
00512 
00513                 // Return or set a flag within the bitmapped flags_ vector, as if it were
00514                 // a 5-axis Array<Bool> corresponding in dimensions to vis_.
00515                 // (Note: flags_ is an internal array corresponding to the current state of
00516                 // flags in the MS, but these routines in themselves do not read or write
00517                 // any flags to disk).
00518                 // <group>
00519                 Bool flag_(IPosition& slot);
00520                 void setFlag_(IPosition& slot, Bool flag);
00521                 // </group>
00522 
00523                 // Add the edit request that just came in (from the mouse, via handleEvent)
00524                 // to the flagEdits_ List, then cause the display to be updated.
00525                 void addEdit_(WorldCanvas* wc, Int xStart, Int xShape,
00526                               Int yStart, Int yShape);
00527 
00528                 // Assure that the display matrices are up-to-date with the flagging edits
00529                 // list, to provide visual feedback of the edits.
00530                 void postEditsToDisp_();
00531 
00532                 // Undo unsaved edits.  Return value indicates whether there were any
00533                 // edits to undo.  extent=="all" means undo all, else just the last one.
00534                 // If feedback==True, a warning message will be printed about discarded
00535                 // edits.
00536                 Bool undoEdits_(String extent="all", Bool feedback=False);
00537 
00538                 // Save all edits permanently to the MS.  The return value indicates
00539                 // whether there were any edits to save.
00540                 Bool saveEdits_();
00541 
00542 
00543                 //#------visibility deviation (difference, RMS) routines----------------
00544 
00545                 // compute the lsTime_ and leTime_ vectors, which define the
00546                 // 'local neighborhoods' around each given time slot, for
00547                 // computing running averages.
00548                 void computeTimeBoxcars_();
00549 
00550                 // Return a single visibility point from vis_ or disp_, as a function
00551                 // of time slot only.  The row of times and mode must be predetermined by
00552                 // setting useVis_, dPos_, axlTm_ and flgdDev_ (below).  goodData_ is set
00553                 // True by this routine if the data exists, is loaded and is not flagged
00554                 // (False otherwise).
00555                 Float v_(Int t);
00556 
00557                 // Phase deviations are calculated both for the original phases
00558                 // (in [-180,180]), and for the phases 180 degrees opposite
00559                 // (also expressed within [-180,180]); the minimum result is displayed.
00560                 // This is so that phases clustered around +-180 do not show
00561                 // artificially high deviations.  (remainder(x,360) (from math.h)
00562                 // is always in [-180,180] -- wierd, but usable for this purpose).
00563                 Float vAlt_(Float v) {
00564                         return remainder(v-180., 360.);
00565                 }
00566 
00567                 // Return the visibility deviation for the time slot t.  visDev_
00568                 // determines whether this is an RMS deviation or absolute
00569                 // difference from the running mean.  Maintains state from the
00570                 // prior calculation to speed things up in some cases.  Must be
00571                 // initialized as for v_() above, and sT_ set to -1, at the
00572                 // beginning of a new row of times.
00573                 Float dev_(Int t);
00574 
00575                 // Calculate deviations throughout range of vis_.  Used to set
00576                 // data scaling sliders when visibility deviations are to be displayed.
00577                 void computeDevRange_();
00578 
00579                 // Create dispDev_ Matrix for displaying deviations.  Both this
00580                 // routine and the one above initialize and use dev_() to calculate
00581                 // individual deviations.
00582                 void createDevSlice_();
00583 
00584 
00585 
00586 
00587 //===================    Data    ======================= (mostly) ========
00588 
00589 
00590 
00591                 //------Main enums (and their conversions to strings)-------------------
00592 
00593                 // (or, rather, they _used_ to be enums, until the compiler started
00594                 // whining and moaning about their use as Ints, Vector/Array/Block
00595                 // indices, etc.  (Strong typing: grrr...)
00596 
00597                 static const Int INVALID;       // (==-1)  (fairly general purpose).
00598 
00599                 // The visibility hypercube (vis_) has 5 axes, in this order.
00600                 static const Axis TIME=0, BASELN=1, CHAN=2, POL=3, SP_W=4,
00601                                   NAXES=5,  INVALID_AXIS=-1;
00602 
00603                 // Each axis can placed on the canvas display (X or Y), the animator (Z),
00604                 // or on one of 2 auxiliary slider controls (SL0, SL1)
00605                 typedef Int AxisLoc;
00606                 static const AxisLoc X=0, Y=1, Z=2, SL0=3, SL1=4,   NLOCS=5;
00607 
00608                 typedef Int VisType;
00609                 static const VisType OBSERVED=VisibilityIterator::Observed,
00610                                      CORRECTED=VisibilityIterator::Corrected,
00611                                      MODEL=VisibilityIterator::Model,
00612                                      RESIDUAL=3,  // RATIO=4,
00613                                      NTYPES=4,   INVALID_VT=-1;
00614 
00615                 typedef Int VisComp;
00616                 static const VisComp AMPLITUDE=0, PHASE=1, REAL=2, IMAGINARY=3,
00617                                      NCOMPS=4,  // # of actual components (above)
00618                                      AMPDIFF=4, AMPRMS=5, PHDIFF=6, PHRMS=7,
00619                                      NCOMPNAMES=8,      // Number of choices in the
00620                                      // GUI choice box (itsVisComp).  itsVisComp is split into visComp_
00621                                      // (which must be one of the first four values above) and visDev_.
00622                                      // (see visDev_ below, and also setOptions()).
00623                                      INVALID_VC=-1;
00624 
00625                 typedef Int VisDev;
00626                 static const VisDev  NORMAL=0, DIFF=1, RMS=2,  INVALID_VD=-1;
00627 
00628                 // Generic string-to-index converter...
00629                 static Int ind_(const String& name, const Vector<String>& names) {
00630                         for(uInt i=0; i<names.nelements(); i++) if(names(i)==name) return i;
00631                         return -1;
00632                 }
00633 
00634                 // ...applied to 3 of the 'enums' used internally.
00635                 // <group>
00636                 Axis axisNum_(const String& axisName) const {
00637                         return Axis(ind_(axisName, axisName_));
00638                 }
00639 
00640                 VisType visTypeNum_(const String& visTypeName) const {
00641                         return VisType(ind_(visTypeName, visTypeName_));
00642                 }
00643 
00644                 VisComp visCompNum_(const String& visCompName) const {
00645                         return VisComp(ind_(visCompName, visCompName_));
00646                 }
00647                 // </group>
00648 
00649 
00650 //-----more constants and statics ----------------------------------------
00651 
00652                 // These should be static const, but there's no way to initialize them.
00653                 // Print strings, corresponding to Axis, VisType and VisComp enums above.
00654                 Vector<String> axisName_;
00655                 Vector<String> visTypeName_;
00656                 Vector<String> visCompName_;
00657 
00658                 static const Float NO_DATA;             // Arbitrary value commandeered
00659                 // to stand for 'no data in the selected MS at this position in
00660                 // the visibility cube'.  vis_ is initialized to this value before
00661                 // data is extracted into it from the selected MS.  After extract_,
00662                 // elements left with this value will be masked out during display.
00663                 static const Float NOT_LOADED;
00664                 // Very similar, but used only in the disp_ array, for data
00665                 // which is not loaded into memory (vis_) at present.
00666                 static const Float INSUF_DATA;
00667                 // Also similar.  Returned by dev_() when there are less than 2
00668                 // values in the local neighborhood from which to compute a
00669                 // meaningful deviation, or if the data is flagged.
00670 
00671                 // NB: The values above are large negative numbers which will not
00672                 // correspond to legitimate data values in the data arrays
00673                 // where they appear.  The dispFlags_ overlay matrix uses different
00674                 // values (NODATA, NOTLOAED, below) to indicate these same two
00675                 // conditions--small enum-like sequential integers which can be mapped to
00676                 // definite colors easily.
00677 
00678                 // dispFlags_ and the flagCM_ custom colormap use the following coding:
00679 
00680                 static const Float NOTLOADED,  // not in vis_ memory buffer (grey)
00681                        NODATA,  // no data in the MS selection (black)
00682                        OLDFLAG,  // old flag, from the MS file (medium blue)
00683                        NEWFLAG;  // newly edited, unsaved flag (lighter blue)
00684                 static const Int   NCOLORS=4;    // number of colors above.
00685 
00686                 //-----primary user input data-------------------------------------------
00687 
00688                 //  Passed in through constructors and setOpts parameters.
00689 
00690                 String msName_;         // MS filename.
00691 
00692                 // User option DisplayParameters specific to MSAsRaster
00693 
00694 
00695                 // Maximum memory to use for vis_ buffer.
00696                 DParameterRange<Int> *itsVisMb;
00697 
00698                 // Which axes will be on X, Y, Animator.  Chosen from
00699                 // time, baseline, channel, polarization and spectral window.
00700                 DParameterChoice *itsXAxis;
00701                 DParameterChoice *itsYAxis;
00702                 DParameterChoice *itsZAxis;
00703 
00704                 // Which slice to display, for the other two axes.
00705                 // The _label_ of the sliders (and the axes they control) vary.
00706                 // They control the slice position of the axes not selected above.
00707                 // Animator position is determined externally by WCH restriction 'zIndex'.
00708                 DParameterRange<Int> *itsSL0Pos;
00709                 DParameterRange<Int> *itsSL1Pos;
00710 
00711                 // Baseline sort (antenna1-antenna2 vs. baseline length).
00712                 DParameterChoice *itsBslnSort;
00713 
00714                 // Sent to scale handler for scaling data to color within these limits.
00715                 DParameterRange<Float> *itsDataMin;
00716                 DParameterRange<Float> *itsDataMax;
00717 
00718                 // Axis Labelling? (Yes/No).
00719                 DParameterChoice *itsAxisLabelling;
00720         // Units of display for Channels
00721         DParameterChoice *itsParamSpectralUnit;
00722 
00723                 // changes to these options require data extraction:
00724 
00725                 //#  // the MS selections record:
00726                 //#  DParameterRecord (or DParameterMSSelect) *itsSelections;
00727 
00728                 // Observed, Corrected, Model, etc.
00729                 DParameterChoice *itsVisType;
00730 
00731                 //Which real visibiliy component to display: Real, Imag, Amp, Phase.
00732                 DParameterChoice *itsVisComp;
00733 
00734                 // how many values to use (ideally) in moving averages.
00735                 DParameterRange<Int> *itsNAvg;
00736 
00737 
00738                 //----derived from above: what is now requested-----------------------
00739 
00740                 Vector<Int> axisOn_;    // the axis on each location.  This will be any
00741                 // permutation of (TIME, BASELN, CHAN, POL, SP_W), corresponding to the
00742                 // axis to display or control on X, Y, Z, SL0, and SL1, in that order.
00743 
00744                 Block<Int> pos_;        // The position setting on the animator and sliders.
00745                 // Zero-based (although the user sees 1-based values).
00746                 // pos_ is indexed by Axis (TIME, BASELN, etc).  For axes being
00747                 // displayed, the position is not immediately relevant, but serves
00748                 // as a memory of the last setting and is restored to a slice control
00749                 // whenever the axis moves off the display.  Corresponds somewhat to
00750                 // itsFixedPosition in PrincipalAxesDD.
00751 
00752                 VisType visType_;       // enums corresp. to strings in itsVisType/Comp
00753                 VisComp visComp_;       // and in sync with them.
00754                 VisDev  visDev_;        // (12/02) itsVisComp now maps into _two_ 'enums':
00755                 // visComp_ and visDev_.
00756                 // visComp_ is _only_ AMP, PHASE, REAL or IMAGINARY
00757                 // (above is what is stored in large vis_ Array)
00758                 // and visDev_ tells whether to display the
00759                 // straight vis component (NORMAL), a difference
00760                 // from a running average (DIFF) or a running
00761                 // RMS (RMS).
00762 
00763                 Int nDAvg_;             // RMS/Diff average value in itsNAvg (above).
00764                 Int nPAvg_;             // number of planes to average
00765 
00766                 Vector<Int> fieldIds_;  // user-selected field IDs and
00767                 Vector<Int> spwIds_;            // spectral window IDs (0-based).
00768 
00769 
00770                 //----current state of main internal data: what is already computed----
00771 
00772                 // (These are set (successively) in initMSAR_, selectVS_, findRanges_,
00773                 //  extract_, createDisplaySlice_, and createDevSlice_).
00774 
00775 
00776                 // The original, unselected MS
00777 
00778                 MeasurementSet *itsMS;          // The (unselected) MS to be displayed.
00779                 VisibilityIterator* vs_;                // VisSet of (unselected) itsMS
00780                 Bool msValid_;                  // valid, writable, non-null (unselected) MS?
00781                 // (should be set True (permanently) during
00782                 // construction, or this object will be useless,
00783                 // and do nothing).
00784                 ROMSColumns* msCols_;                   // utility object for (unselected) itsMS.
00785                 Int nFieldIds_;                 // Total number of fields, spectral windows,
00786                 Int nSpwIds_;                           // in the (unselected) MS.
00787                 Vector<Int> nChan_;                     // Number of channels, by Spectral window ID.
00788         Matrix<Double> chanFreq_;   // frequency mapping of channels, per Spectral window ID
00789                 Bool dish_;                             // true if the MS is 'single-dish' (has FLOAT_DATA,
00790                 // which will then be used instead of the DATA column).
00791 
00792 
00793                 // The selected MS.
00794 
00795                 MS* mssel_;                             // the selected MS and its VisSet--kept in sync
00796                 VisibilityIterator* wvi_p;              // with user input (itsMS, fieldIds_, spwIds_).
00797                 Bool msselValid_;                       // mssel_ and vssel_ are valid and non-null.  We will
00798                 // not draw until this is set True (in selectVS_).
00799 
00800                 Int nAnt_;                              // # rows in antenna table (for now).  Later: size
00801                 // of the set of antennas appearing in mssel_
00802                 // main data rows.
00803                 // NB: nAnt_==1 is tested, rather than dish_ (which
00804                 // should be equivalent), to determine whether feeds
00805                 // are displayed instead of baselines.
00806 
00807                 Block<Int> msShape_;                    // shape of visibilites of the whole selected MS
00808                 // = {nTime, nBsln, nChan, nPol, nSpw}.
00809                 // msShape_[BASELN] reflects the size requirement for
00810                 // the baseline sort in use (see antSort_, below).
00811                 Block<Int> msShapeA_;                   // Identical to msShape_, except possibly on BASELN
00812                 // axis when baselines are sorted by length
00813                 // (antSort==False).  In that case, msShapeA_[BASELN]
00814                 // is the number of baseline slots that _would_ be
00815                 // required if the antenna sort were used, including
00816                 // 1-element 'gaps' where antenna1 changes.
00817                 // msShape_[BASELN] is the number of actual baselines
00818                 // needed; the gaps are not needed when displaying the
00819                 // sort by baseline length.  However, when able to fit
00820                 // into memory, vis_ is sized according to the larger
00821                 // msShapeA_[BASELN] in any case, so that switching
00822                 // between sorts does not require resizing or
00823                 // reloading vis_, but only reshuffling of the
00824                 // baseline planes in memory.
00825 
00826                 Bool antSort_;                  // True (the default) means baselines are (to be)
00827                 // sorted by antenna1-antenna2.  False means sorting
00828                 // by (unprojected, uvw) baseline length.
00829 
00830                 Matrix<Double> bLen_;                   // (Unprojected) baseline lengths, indexed by antenna
00831                 // numbers (symmetric, 0 along diagonal).  Used to
00832                 // order baselines by length on request.
00833 
00834                 Vector<Int> a1_, a2_,                   // These Arrays provide quick conversions between
00835                        a1A_, a2A_,              // (antenna1,antenna2) and baseline index.  Of course
00836                        a1L_, a2L_,              // arguments ( a1_(bsl), a2_(bsl),  bsl_(a1, a2) )
00837                        len2ant_, ant2len_;                      // must be Ints within range; their values are
00838                 Matrix<Int> bsl_,                       // according to the _current_ baseline sort
00839                        bslA_, bslL_;                    // (antSort_).  (In contrast, methods a1a2_() and
00840                 Int         nbsl_,                      // bsln_() may take Float arguments, but convert
00841                             nbslA_, nbslL_;                     // _only_ according to the Antenna1-Antenna2 sort).
00842                 // The A and L versions are for antenna and length
00843                 // sorts, respectively; they are copied into a1_, a2_,
00844                 // and bsl_ in accordance with the current sort.
00845                 // len2ant_ and ant2len_ provide conversion between
00846                 // baseline indices for the two sorts.  nbsl* give
00847                 // the number of baselines for the applicable case
00848                 // (if sgl dish, they will be 1, but irrelevant;
00849                 // msShape_[BASELN] will be set to number of feeds
00850                 // instead).
00851 
00852 
00853                 Vector<Double> time_;                   // sorted vector of actual times in mssel_
00854                 // only first msShape_[TIME] ( <= time_.shape() )
00855                 // are valid.
00856                 Vector<Int> field_;                     // vector for field ids corresponding to time slots;
00857                 // indexed as time_ is, above.  For now, field id
00858                 // is assumed to be unique for a given time.  Used
00859                 // to avoid computing running averages across
00860                 // field boundaries.
00861                 Vector<Int> scan_;                      // same as above, for scan numbers.
00862                 Vector<String> fieldName_;              // Names corresponding to field_ above.
00863 
00864                 Block<Int> spwId_;                      // Spectral window index-to-ID translation.
00865                 // The user can select the spectral windows to
00866                 // view.  This Block holds the (sorted) spectral
00867                 // windows actually found in the selected MS--usually
00868                 // it will be identical to the user selection (spwIds_,
00869                 // above).  Its length is the size of the Spectral
00870                 // Window axis (msShape_[SP_W]).
00871                 // Note that throughout the code, the variable 'spw'
00872                 // refers to the _index_ into this block, not the
00873                 // Spectral window ID itself.  Actual IDs will have
00874                 // 'Id' in the variable name.
00875                 Block<void*> freq_;                     // *freq_[spw] is really a Vector<Double>.
00876                 // (*freq_[spw])[chan] holds the CHAN_FREQ for
00877                 // the given spw index and channel (in Hz).
00878 
00879                 // The following translate pol ID and the polarization index within a cell
00880                 // of data in the MS, to the 'pol' index within the internal visibility
00881                 // cube.  There is no 'polID axis' separate from the pol axis internally or
00882                 // for the display; it is flattened to a single pol axis, using these
00883                 // tables.  They are set up in findRanges_.
00884                 Int nPolIds_;                           // Number of rows in the POLARIZATION subtable
00885                 // (and the size of the next two vectors).
00886                 Vector<Int> nPolsIn_;                   // number of correlations in each polId.
00887                 Vector<Int> pidBase_;                   // difference between a visibility's 'pol' index
00888                 // within msShape_[POL] and its index within
00889                 // the MS table's visibility data cell, for given
00890                 // polId (or -1, if the polID is not in the
00891                 // selected data).
00892                 // The following 2 vectors will have sizes = msShape_[POL], and
00893                 // are indexed according to the internal polarization 'data pixel
00894                 // number' (generally referred to as 'pol').
00895                 Vector<Int> polId_;                     // polarizationId for given pol.
00896                 Vector<String> polName_;                // name of the pol.
00897 
00898 
00899                 // The visibility hypercube.
00900 
00901                 Array<Float> vis_;                      // the (large) memory buffer: 5-axis hypercube of
00902                 // gridded MS visibilities (for t, bsl, chan, pol, spw, in that
00903                 // order).  Conceptually, this is a (contiguous, hyper-rectangular)
00904                 // 'window' or 'cursor' into the whole gridded ms as characterized
00905                 // by msShape_ above.  It _will_ be the whole thing, if it fits
00906                 // into memory; in any case, the two display axes will be full size.
00907                 Bool visValid_;                 // Is vis_ valid for current selected MS?
00908                 Block<Int> visShape_;                   // shape of extracted vis_ Array (used*) and
00909                 Block<Int> visStart_;                   // start of extracted vis_ Array, within msShape_
00910 
00911                 Block<Int> visShapeA_;          // *Identical to visShape_ except possibly on the
00912                 // BASELN axis, and then only when computeVisShape_()
00913                 // determines that the entire msShapeA_[BASELN]
00914                 // will fit into memory, and the length sort
00915                 // is also in effect.  In that case,
00916                 // visShapeA_[BASELN] == msShapeA_[BASELN] and
00917                 // visShape_[BASELN] == msShape_[BASELN] (which is
00918                 // msShapeA_[BASELN] - (nAnt_-1) ).
00919                 // vis_ is actually sized according to visShapeA_.
00920 
00921                 VisType curVisType_;
00922                 VisComp curVisComp_;                    // type and component of current vis_.
00923 
00924                 Float dataRngMin_, dataRngMax_; // The 'data ranges' for vis_.
00925                 // Used (only) for scaling data values to colors; they are
00926                 // too expensive to compute except during extract_().
00927                 // Not the actual min/max of the data in general, since they
00928                 // may be sampled and/or clipped to 3-sigma limits.
00929                 Float devRngMin_, devRngMax_;           // same thing, for the case when
00930                 // visibility deviations are being displayed.  Both types
00931                 // of ranges are kept, in case the user switches from one
00932                 // type ot display to the other.  devRngMin_ is set to
00933                 // NO_DATA if these haven't been computed yet.
00934                 // computeDevRange_() is called from extract_ or
00935                 // setOptions to compute these when needed.
00936 
00937 
00938                 // The display matrices which are drawn on the canvas.
00939 
00940                 Matrix<Float> disp_;                    // Matrix of data values actually passed to the
00941                 // display canvas.
00942                 Axis dispX_, dispY_;                    // displayed axes that disp_ represents.
00943                 Block<Int> dispPos_;                    // non-display axis ('slice') positions disp_
00944                 // represents, by Axis.  Settings for display axes,
00945                 // (i.e. dispPos_[dispX_] and dispPos_[dispY_]),
00946                 // are irrelevant).
00947                 Bool dispValid_;                        // Has disp_ been created since extract_ was
00948                 // called?
00949                 Bool dispNotLoaded_;                    // Is the entire disp_ Matrix set to the
00950                 // NOT_LOADED value?
00951 
00952                 Matrix<Float> dispDev_;         // Similar to disp_, but for visibility deviation
00953                 // data displays.  (Filled by createDevSlice_()).
00954                 Bool dispDevValid_;                     // Is dispDev_ valid for current disp_ and
00955                 // (if necessary) the state of flag edits?
00956                 VisDev dispDevType_;                    // Type of deviation (RMS or DIFF) that dispDev_
00957                 // represents.
00958                 Int dispDevNAvg_;                       // Nominal number of values in running averages
00959                 // in effect when dispDev_ was last computed.
00960 
00961 
00962 
00963 
00964                 //---------------additional control state----------------------------------
00965                 //  ...for communication of control logic between various methods (mainly
00966                 //  setOptions, draw_ and extract_)
00967 
00968                 Bool visDataChg_;       // means that MS selection, visType_ or visComp_
00969                 // do not reflect current state of vis_.  Set by
00970                 // setOptions.  Indicates to extract_ that it should
00971                 // completely recalculate data ranges (and set
00972                 // the actual dataMin/Max_ sent to the scale handler
00973                 // accordingly).  setOptions also uses it to help
00974                 // determine whether it should call extract_.
00975 
00976                 Bool postDataRng_;      // A kind of reply to the above; set True after
00977                 // extract_ has recalculated data ranges from
00978                 // scratch (as opposed to merely expanding them).
00979                 // When True, setOptions will return these new
00980                 // ranges unaltered to the gui, via recOut.
00981 
00982 
00983                 //----translation between MS values and internal hypercube indices---------
00984 
00985                 struct MSpos_;
00986                 friend struct MSpos_;
00987                 struct MSpos_ {
00988 
00989                         // An MSpos_ holds information about a given position of interest within
00990                         // the main MS visibility Table.  Its data members are the values at
00991                         // that position as actually stored in the MS (times, antennas, etc.);
00992                         // these can be freely set and queried by MSAsRaster, the only user of
00993                         // this struct.  It provides translation between these values and the
00994                         // hypercube indices (pos_) used internally.  It was time to quit
00995                         // performing these translations ad hoc and consolidate them here (3/04).
00996                         // (Still to do: use this instead of old ad hoc methods in, e.g.,
00997                         // showPosition()).
00998 
00999                         // When MS selection changes, MSAsRaster::findRanges_() computes several
01000                         // tables (time_, spwId_, freq_, polId_, nAnt_, etc.) which [re-]define
01001                         // the correspondence of MS data to hypercube positions.  An MSpos_
01002                         // set up prior to this change can be queried afterward as to the data's
01003                         // position (if any) in the new hypercube.  It is also useful in
01004                         // determining whether flagging edits (which are stored in terms of
01005                         // hypercube positions) apply to MS data beyond what is currently
01006                         // selected.
01007 
01008                         // Below is the real content of an MSpos_: data for a position within
01009                         // an MS in terms of the values actually stored there.
01010                         // Note that, in its current version, MSAsRaster assumes that this
01011                         // data uniquely determines a visibility-and-flag within the MS (and
01012                         // feed is not considered either, when there is more than one antenna).
01013 
01014                         Double time;
01015                         Int ant1, ant2, feed, spwId, polId, chan;
01016                         String polName;
01017 
01018                         // IMO, a _nested_ struct/class should have visibility (and access
01019                         // permission(?)) into the nesting class, but it doesn't (except, rather
01020                         // oddly, for the static consts of MSAsRaster: TIME, NAXES, etc.,
01021                         // which are directly in scope and accessible here).   Hence the
01022                         // need to have a pointer to the nesting object and for it to declare
01023                         // this class a friend.  The nesting class's 'this' should be
01024                         // available implicitly to this class instead.  As is, it's
01025                         // rather clumsy to implement classes/structs that are purely in support
01026                         // of another class....
01027 
01028                         const MSAsRaster* m;    // parent dd, needed for access to the
01029                         //  MSAsRaster tables which it set up in
01030                         // findRanges_: nAnt_, time_, spwId_, freq_,
01031                         // polId_, etc.
01032 
01033                         Int ts, te;             // Ancillary output of t() (in terms of hypercube
01034                         // time-slot indices).  When t() returns INVALID (time
01035                         // not found) they are the bracketing time slots, i.e.
01036                         // ts+1==te and (where ts or te are in timeslot range)
01037                         // time_[ts] < time < time_[te].
01038 
01039 
01040                         // Construct MSpos_ with no valid values set (yet).
01041 
01042                         MSpos_(const MSAsRaster* msar):
01043                                 time(INVALID), ant1(INVALID), ant2(INVALID), feed(INVALID),
01044                                 spwId(INVALID), polId(INVALID), chan(INVALID), polName("Invalid"),
01045                                 m(msar), ts(INVALID), te(INVALID) {   }
01046 
01047 
01048                         // Construct MSpos_ according to 5-element Block corresponding to a
01049                         // position within the internal hypercube.
01050 
01051                         MSpos_(const MSAsRaster* msar, const Block<Int>& pos): m(msar) {
01052                                 set(pos);
01053                         }
01054 
01055 
01056                         // Translation methods (for times, baselines, channels,
01057                         // spectral windows, and polarizations).  All but the last seven
01058                         // set MSpos_ state to the appropriate values as stored in the MS.
01059 
01060                         // hypercube indices to MS values
01061 
01062                         void set(const Block<Int>& pos) {
01063                                 sett(pos[TIME]);
01064                                 setb(pos[BASELN]);
01065                                 sets(pos[SP_W]);
01066                                 setc(pos[CHAN]);
01067                                 setp(pos[POL]);
01068                         }
01069 
01070                         void sett(Int t);
01071                         void setb(Int b);
01072                         void sets(Int s);
01073                         void setc(Int c);
01074                         void setp(Int p);
01075 
01076                         // MS values to hypercube indices.
01077 
01078                         Int t(Double tm) {
01079                                 time=tm;
01080                                 return t();
01081                         }
01082                         Int b(Int a1, Int a2) {
01083                                 ant1=a1;
01084                                 ant2=a2;
01085                                 feed=INVALID;
01086                                 return b();
01087                         }
01088                         Int b(Int fd) {
01089                                 feed=fd;
01090                                 ant1=ant2=INVALID;
01091                                 return b();
01092                         }
01093                         Int s(Int sid) {
01094                                 spwId=sid;
01095                                 return s();
01096                         }
01097                         Int c(Int ch) {
01098                                 chan=ch;
01099                                 return c();
01100                         }
01101                         Int c(Int sid, Int ch) {
01102                                 spwId=sid;
01103                                 chan=ch;
01104                                 return c();
01105                         }
01106                         Int p(Int pid, Int pnm) {
01107                                 polId=pid;
01108                                 polName=pnm;
01109                                 return p();
01110                         }
01111                         Int p0(Int pid) {
01112                                 polId=pid;
01113                                 return p0();
01114                         }
01115 
01116                         Int p0() {
01117                                 if(polId<0 || polId>=Int(m->pidBase_.nelements())) return INVALID;
01118                                 return m->pidBase_[polId];
01119                         }
01120 
01121                         Int operator[](Axis ax) {
01122                                 switch(ax) {
01123                                 case   TIME:
01124                                         return t();
01125                                 case BASELN:
01126                                         return b();
01127                                 case   SP_W:
01128                                         return s();
01129                                 case   CHAN:
01130                                         return c();
01131                                 case    POL:
01132                                         return p();
01133                                 default:
01134                                         return INVALID;
01135                                 }
01136                         }
01137 
01138                         Int t();
01139                         Int b();
01140                         Int s();
01141                         Int c();
01142                         Int p();
01143                 };
01144 
01145 
01146 
01147                 MSpos_ mspos_;  // used by findRanges_() to maintain the MS 'slice'
01148                 // position being viewed as much as possible when
01149                 // MS selection is changed--e.g., to remain on the
01150                 // same time (if it is still in the selected MS),
01151                 // even though its time-slot index (slice position)
01152                 // may have changed.
01153 
01154 
01155                 //----flagging state-------------------------------------------------------
01156 
01157                 DParameterChoice *itsFlagColor;
01158                 Bool flagsInClr_;       // equivalent to  itsFlagColor->value()=="In Color"
01159 
01160                 DParameterChoice *itsUnflag;
01161                 Bool unflag_;           // equivalent to  itsUnflag->value()=="Unflag"
01162 
01163                 Block<Bool> flagAll_;    // from UI checkboxes for each axis (there is
01164                 // no checkbox-type DParameter yet)..
01165 
01166                 DParameterChoice *itsEntireAnt;
01167                 // choice box for applying edits to entire antenna.
01168                 Bool entireAnt_;          // equivalent to  itsEntireAnt->value()=="Yes"
01169 
01170                 DParameterButton *itsUndoOne;
01171                 // defines the button for undoing one edit.
01172                 DParameterButton *itsUndoAll;
01173                 // defines the button for undoing all edits.
01174                 DParameterChoice *itsEditEntireMS;
01175                 // choice box for using entire MS (vs. selected
01176                 // MS only) when saving edits.
01177                 DParameterButton *itsSaveEdits;
01178                 // defines the button for saving all edits.
01179 
01180                 Vector<uInt> flags_;       // Bitmapped storage for flags retrieved
01181                 // from the MS (only); not for new, unsaved flags.
01182                 // Virtually, this has the same shape as vis_.
01183 
01184                 Matrix<Bool> dispMask_;  // Mask for disp_ or dispFlags_.  Distinguishes
01185                 // good data from flagged/missing data.  Which
01186                 // is True and which False depends on flagsInClr_.
01187                 Matrix<Float> dispFlags_;  // For the (slower) 'color flags' option, this
01188                 // will overlay the main data array to show
01189                 // flags in color.
01190                 Bool dispFlagsInClr_;        // Are the current display matrices set up to
01191                 // draw flags in color?
01192                 uInt dispNEdits_;            // Number of flag edits already reflected
01193                 // in display matrices and masks.
01194 
01195 
01196 
01197                 // FlagEdit_ holds information about a single
01198                 // (new, unsaved) flagging edit command.
01199 
01200                 struct FlagEdit_;
01201                 friend struct FlagEdit_;
01202                 struct FlagEdit_ {
01203 
01204 
01205                         MSAsRaster* msar;       // parent dd, needed for access to its members.
01206 
01207                         // All 3 of these Blocks are indexed by Axis, and have NAXES elements.
01208                         Block<Bool> all;        // all[axis]==T: apply edit to entire axis.
01209                         Block<Int> start;   // all[axis]==F: apply edit from start[axis] up to
01210                         Block<Int> shape;   // (but not including) start[axis]+shape[axis].
01211 
01212                         // Note that all[axis] will imply start[axis]==0 &&
01213                         // shape[axis]==msShape_[axis], but _not vice-versa_.
01214                         // all[axis] has the _additional_ meaning that the
01215                         // edit should extend beyond hypercube (selected
01216                         // MS) boundaries, to the _entire_ MS, when saving
01217                         // flags (if itsEditEntireMS is turned on).
01218 
01219 
01220                         Bool unflag;    // T=unflag  F=flag
01221 
01222                         Bool entireAnt; // T=apply to all baselines with Antenna1 of selection.
01223 
01224                         // The following are set by appliesToChunk(spw, nChan, pol0, nPol) at
01225                         // the beginning of each chunk, within saveEdits_().
01226                         // A given chunk has a fixed polId and spwId, which imply a given
01227                         // shape (nPol, nChan) of visibilities and flags as actually stored in
01228                         // the MS.
01229 
01230                         Bool appChunk;  // Does the edit apply to the spectral window and
01231                         // at least some of the pols and channels implied by
01232                         // the chunk's data description ID?
01233                         Int sPol,ePol, sChan,eChan;             // If appChunk is True, (and the
01234                         // edit applies to the row's time and baseline -- tested
01235                         // elsewhere), then the visibilities in the MS row where
01236                         // the edit applies have pol and channel index ranges
01237                         // [sPol,ePol) and [sChan,eChan).  (Note that these are
01238                         // _different_ index ranges from those determined by
01239                         // start & shape, above, which are relative to the
01240                         // _internal hypercube_ shape, msShape_).
01241 
01242                         FlagEdit_(MSAsRaster* m):               // constructor.
01243                                 msar(m),
01244                                 all(NAXES, False), start(NAXES), shape(NAXES, 1),
01245                                 unflag(False), entireAnt(False),
01246                                 appChunk(False), sPol(0),ePol(0), sChan(0),eChan(0) {   }
01247 
01248                         // Return the range (half-open interval) over which the edit definitely
01249                         // applies*, on the given axis.  This is the range selected with the
01250                         // mouse or (when edit.all[ax]==True) the entire axis range.
01251                         //
01252                         // * Exception: when antenna-based editing is on (entireAnt==True),
01253                         // baselines of only one antenna will be edited regardless -- see
01254                         // appliesTo(Int bsln).  The interval returned is still as stated
01255                         // above, however).
01256                         void getSureRange(Axis ax,  Int& strt, Int& fin) {
01257                                 strt=start[ax];
01258                                 fin=strt+shape[ax];
01259                         }
01260 
01261                         // Is the given position within the range above, on the given axis?
01262                         Bool inSureRange(Axis ax, Int pos) {
01263                                 return start[ax]<=pos && pos<start[ax]+shape[ax];
01264                         }
01265 
01266                         // Retrieve ranges for loops.  Same as getSureRange(), except for
01267                         // antenna-based baseline testing, when the entire baseline range
01268                         // of the selected MS is returned.  In that case, applicability
01269                         // of the edit to the individual baselines must still be tested
01270                         // within the loop, with edit.appliesTo(bsln).
01271                         void getLoopRange(Int ax,  Int& strt, Int& fin) {
01272                                 if(entireAnt && ax==BASELN) {
01273                                         strt=0;
01274                                         fin=msar->msShape_[ax];
01275                                 } else getSureRange(ax, strt,fin);
01276                         }
01277 
01278                         // Is the given position in the 'loop range' on the given axis?
01279                         Bool inLoopRange(Int ax, Int pos) {
01280                                 Int strt, fin;
01281                                 getLoopRange(ax, strt,fin);
01282                                 return (strt<=pos && pos<fin);
01283                         }
01284 
01285                         // Does edit apply to given hypercube position (relative to
01286                         // entire MS)?  (pos must be NAXES in size).
01287                         Bool appliesTo(IPosition pos) {
01288                                 for(Axis ax=0; ax<NAXES; ax++) if(!appliesTo(ax, pos(ax))) return False;
01289                                 return True;
01290                         }
01291 
01292                         // Does edit apply to given position on given axis?
01293                         Bool appliesTo(Axis ax, Int pos) {
01294                                 return inLoopRange(ax, pos) && applies2(ax, pos);
01295                         }
01296 
01297                         // Same as above, but for use (only) where inLoopRange(ax, pos)
01298                         // is already known to be true.  This one is used within loops,
01299                         // for efficiency.
01300                         Bool applies2(Axis ax, Int pos) {
01301                                 return ax!=BASELN || !entireAnt || appliesTo(pos);
01302                         }
01303 
01304                         // Does edit apply to the given baseline?  (Also for use only where
01305                         // inLoopRange(BASELN, bsln) is already known to be True).  This is
01306                         // used mainly for testing baselines against antenna-based edits.
01307                         Bool appliesTo(Int bsln);
01308 
01309                         // Does the edit apply to the current MS iteration chunk?
01310                         Bool appliesToChunk(Int pol0, Int nPol, Int spw, Int nChan);
01311 
01312                         // Does the edit apply to a given (raw) time?
01313                         Bool appliesTo(Double time);
01314 
01315                         Bool operator==(FlagEdit_& other);
01316                 };
01317 
01318 
01319 
01320 
01321                 List<void*> flagEdits_;         // List of all the (so-far-unsaved) edits.
01322                 // (<void*> rather than <FlagEdit_*> just to avoid the extra templates)
01323 
01324 
01325                 //---state for computing [RMS] deviation from local visibility average---
01326                 // (Not very object-oriented--more like Fortran common.  Sorry, pressed
01327                 // for time.  To be reworked into object(s) sometime, if it can be
01328                 // done efficiently).
01329 
01330                 Vector<Int> lsTime_, leTime_,  lsvTime_, levTime_;
01331                 // Beginning and (1 beyond) ending time index defining the 'boxcar'
01332                 // or local neighborhood over which averages are computed, for given
01333                 // time slot.  (Note that, for now, these are assumed to be only a
01334                 // function of time.  Later, these may become Matrices, indexed
01335                 // also by Array ID or baseline).  Recomputed (computeTimeBoxcars_)
01336                 // when nAvg_ changes, and after extract_.
01337                 // lsv, lev versions are for vis_, i.e relative to visStart_[TIME],
01338                 // and of length visShape_[TIME].
01339 
01340                 Bool useVis_;
01341                 IPosition dPos_;
01342                 AxisLoc axlTm_;
01343                 Bool flgdDev_;
01344                 // Initializing input to dev_(t) and its subsidiary routine v_(t).
01345                 // These create something similar to an ArrayAccessor, in that
01346                 // vis_ (or disp_, depending on useVis_) can be accessed by giving
01347                 // only the value along the time axis.  dPos_ fixes the row of times
01348                 // to use within vis_ or disp_; axlTm_ gives the location of the
01349                 // time axis within dPos_.  The value of the index along that
01350                 // axis (only) will be varied as needed, by dev_() and v_().
01351 
01352                 // flgdDev_ should usually be set False, causing dev_ simply to
01353                 // return INSUF_DATA for flagged points.  In one obscure case, it
01354                 // is set True to request dev_ to calculate deviations even for
01355                 // the flagged points.
01356 
01357                 Bool goodData_;
01358                 // This really should be a return value from v_(); placed here for
01359                 // 'efficiency'.  Set after each call to v_(): True iff the data
01360                 // existed, was loaded, and was not flagged.
01361 
01362                 Int sT_, eT_;
01363                 Double sumv_, sumv2_, sumva_, sumv2a_;
01364                 Int nValid_;
01365                 Float d_;
01366                 // Saved state from the last call to dev_().  When moving along
01367                 // a time axis, it sometimes saves time to have these previous
01368                 // results handy.  d_ is the most recently computed deviation.
01369                 // sT_ (boxcar start time slot) must be set to -1 when starting to
01370                 // compute deviations on a new line of times, indicating that
01371                 // none of this 'saved state' is valid yet.
01372 
01373 
01374 
01375 
01376                 //----------helper objects and their control data-----------
01377 
01378                 // This does data scaling for WorldCanvas
01379                 WCPowerScaleHandler itsPowerScaleHandler;
01380 
01381                 // This labels the axes.  An actual CachingDisplayData itself, contained
01382                 // within MSAsRaster and controlled through it.  MSAsRaster propagates
01383                 // getOptions and setOptions calls and draw commands to it, and sets the
01384                 // WC DisplayCoordinateSystem which it uses.
01385                 WorldAxesDD itsAxisLabeller;
01386 
01387                 // A private internal colormap for showing colors for various conditions
01388                 // (flagged, no data, data not loaded).  This is not the colormap set
01389                 // by the user for mapping data values.  It has rigid single colors
01390                 // for the different conditions.
01391                 Colormap flagCM_;
01392 
01393         private:
01394 
01395                 bool adjustAvgRange( VisDev newstate, Record &outrec, bool force=false );
01396 
01397         };
01398 
01399 
01400 
01401 //#----------MSAsRasterDM----------------------------------------------------
01402 
01403 // <summary>
01404 // (Minimal) DisplayMethod for MSAsRaster.
01405 // </summary>
01406 
01407 // <prerequisite>
01408 //   <li> MSAsRaster
01409 //   <li> CachingDisplayMethod
01410 // </prerequisite>
01411 
01412 // <etymology>
01413 // "MSAsRasterDM" is a implementation of a <linkto class=CachingDisplayMethod>
01414 // CachingDisplayMethod </linkto> for <linkto class=MSAsRaster>
01415 // MSAsRaster </linkto>.
01416 // </etymology>
01417 
01418 // <synopsis>
01419 // MSAsRasterDM a minimal skeleton; it is implemented
01420 // in its entirety here.  Its only purpose is to hold the cached drawlist
01421 // and use it when appropriate via the mechanism and data structure
01422 // implemented on the CachingDisplayMethod level.  MSAsRasterDM just
01423 // turns the draw request back over to MSAsRaster, since that's where
01424 // the necessary data is.
01425 
01426 // This 'minimal' CachingDisplayMethod could be adapted and reused by any
01427 // other CachingDisplayData that wanted to do its own drawing.
01428 
01429 // </synopsis>
01430 
01431         class MSAsRasterDM : public CachingDisplayMethod {
01432 
01433         public:
01434 
01435                 // Constructor.  The parameters contain state that determines
01436                 // what should be drawn.
01437                 MSAsRasterDM(WorldCanvas *wc,   AttributeBuffer *wchAttrs,
01438                              AttributeBuffer *ddAttrs, CachingDisplayData *dd):
01439                         CachingDisplayMethod(wc, wchAttrs, ddAttrs, dd) {  }
01440 
01441                 // Destructor.
01442                 virtual ~MSAsRasterDM() {  }
01443 
01444         protected:
01445 
01446                 // The base CachingDM takes care of using any cached drawlist.
01447                 // When this method is called, we know that no drawlist applies,
01448                 // and that we must actually send drawing commands to the WC (though
01449                 // technically, they might _not_ actually be going into a drawlist).
01450                 // This skeleton DM just hands the drawing task back to the DD,
01451                 // where all the data has been created and maintained anyway.
01452 
01453                 virtual Bool drawIntoList(Display::RefreshReason reason,
01454                                           WorldCanvasHolder &wcHolder) {
01455                         MSAsRaster *msar = dynamic_cast<MSAsRaster *>(parentDisplayData());
01456                         if (!msar) throw(AipsError("invalid parent of MSAsRasterDM"));
01457 
01458                         return msar->draw_(reason, wcHolder, *(worldCanvas()) );
01459                 }
01460 
01461 
01462         private:
01463 
01464                 // Default and copy constructors, and the assignment operator, are
01465                 // mon-functional and should not be used.  Do not make copies of
01466                 // DisplayMethod objects, or pass them by value;
01467                 // use references or pointers instead.
01468                 // <group>
01469                 MSAsRasterDM() {  }
01470                 MSAsRasterDM(const MSAsRasterDM &other) : CachingDisplayMethod(other) {  }
01471                 MSAsRasterDM& operator=(const MSAsRasterDM &/*other*/) {
01472                         return *this;
01473                 }
01474                 // </group>
01475 
01476         };
01477 
01478 
01479 } //# NAMESPACE CASA - END
01480 
01481 #endif
01482 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1