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