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