Line data Source code
1 : //# Copyright (C) 1998,1999,2000,2001
2 : //# Associated Universities, Inc. Washington DC, USA.
3 : //#
4 : //# This library is free software; you can redistribute it and/or modify it
5 : //# under the terms of the GNU Library General Public License as published by
6 : //# the Free Software Foundation; either version 2 of the License, or (at your
7 : //# option) any later version.
8 : //#
9 : //# This library is distributed in the hope that it will be useful, but WITHOUT
10 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 : //# License for more details.
13 : //#
14 : //# You should have received a copy of the GNU Library General Public License
15 : //# along with this library; if not, write to the Free Software Foundation,
16 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
17 : //#
18 : //# Correspondence concerning AIPS++ should be addressed as follows:
19 : //# Internet email: aips2-request@nrao.edu.
20 : //# Postal address: AIPS++ Project Office
21 : //# National Radio Astronomy Observatory
22 : //# 520 Edgemont Road
23 : //# Charlottesville, VA 22903-2475 USA
24 : //#
25 :
26 : #ifndef ANNOTATIONS_ANNOTATIONBASE_H
27 : #define ANNOTATIONS_ANNOTATIONBASE_H
28 :
29 : #include <casacore/coordinates/Coordinates/CoordinateSystem.h>
30 : #include <casacore/casa/Utilities/Regex.h>
31 : #include <casacore/measures/Measures/Stokes.h>
32 :
33 : #include <list>
34 :
35 : namespace casa {
36 :
37 : // <summary>Base class for annotations</summary>
38 :
39 : // <use visibility=export>
40 :
41 : // <reviewed reviewer="" date="yyyy/mm/dd">
42 : // </reviewed>
43 :
44 : // <synopsis>
45 : // Base class for annotations
46 :
47 : // In order to minimize maintainability, many parameters are not
48 : // set in the constructor but can be set by mutator methods.
49 : //
50 : // casacore::Input directions will be converted to the reference frame of the
51 : // input coordinate system upon construction if necessary. The coordinate
52 : // system specified in the constructor should be that associated with the
53 : // image to which the region/annotation is being applied.
54 : // </synopsis>
55 :
56 : class AnnotationBase {
57 : public:
58 :
59 : using RGB = std::vector<float>;
60 :
61 : // The pairs have longitude as the first member and latitude as the second
62 : using Direction = casacore::Vector<std::pair<casacore::Quantity,casacore::Quantity> >;
63 :
64 : enum Type {
65 : // annotations only
66 : LINE,
67 : VECTOR,
68 : TEXT,
69 : SYMBOL,
70 : // regions
71 : RECT_BOX,
72 : CENTER_BOX,
73 : ROTATED_BOX,
74 : POLYGON,
75 : POLYLINE,
76 : CIRCLE,
77 : ANNULUS,
78 : ELLIPSE
79 : };
80 :
81 : enum Keyword {
82 : COORD,
83 : RANGE,
84 : FRAME,
85 : CORR,
86 : VELTYPE,
87 : RESTFREQ,
88 : LINEWIDTH,
89 : LINESTYLE,
90 : SYMSIZE,
91 : SYMTHICK,
92 : COLOR,
93 : FONT,
94 : FONTSIZE,
95 : FONTSTYLE,
96 : USETEX,
97 : LABEL,
98 : LABELCOLOR,
99 : LABELPOS,
100 : LABELOFF,
101 : UNKNOWN_KEYWORD,
102 : N_KEYS
103 : };
104 :
105 : enum LineStyle {
106 : SOLID,
107 : DASHED,
108 : DOT_DASHED,
109 : DOTTED
110 : };
111 :
112 : enum FontStyle {
113 : NORMAL,
114 : BOLD,
115 : ITALIC,
116 : ITALIC_BOLD
117 : };
118 :
119 : static const RGB BLACK;
120 : static const RGB BLUE;
121 : static const RGB CYAN;
122 : static const RGB GRAY;
123 : static const RGB GREEN;
124 : static const RGB MAGENTA;
125 : static const RGB ORANGE;
126 : static const RGB RED;
127 : static const RGB WHITE;
128 : static const RGB YELLOW;
129 :
130 : static const casacore::String DEFAULT_LABEL;
131 : static const RGB DEFAULT_COLOR;
132 : static const LineStyle DEFAULT_LINESTYLE;
133 : static const casacore::uInt DEFAULT_LINEWIDTH;
134 : static const casacore::uInt DEFAULT_SYMBOLSIZE;
135 : static const casacore::uInt DEFAULT_SYMBOLTHICKNESS;
136 : static const casacore::String DEFAULT_FONT;
137 : static const casacore::uInt DEFAULT_FONTSIZE;
138 : static const FontStyle DEFAULT_FONTSTYLE;
139 : static const casacore::Bool DEFAULT_USETEX;
140 : static const RGB DEFAULT_LABELCOLOR;
141 : static const casacore::String DEFAULT_LABELPOS;
142 : static const std::vector<casacore::Int> DEFAULT_LABELOFF;
143 :
144 : static const casacore::Regex rgbHexRegex;
145 :
146 : virtual ~AnnotationBase();
147 :
148 : Type getType() const;
149 :
150 : static LineStyle lineStyleFromString(const casacore::String& ls);
151 :
152 : // Given a string, return the corresponding annotation type or throw
153 : // an error if the string does not correspond to an allowed type.
154 : static Type typeFromString(const casacore::String& type);
155 :
156 : static casacore::String typeToString(const Type type);
157 :
158 : static casacore::String keywordToString(const Keyword key);
159 :
160 : static casacore::String lineStyleToString(const LineStyle linestyle);
161 :
162 : static FontStyle fontStyleFromString(const casacore::String& fs);
163 :
164 : static casacore::String fontStyleToString(const FontStyle fs);
165 :
166 : void setLabel(const casacore::String& label);
167 :
168 : casacore::String getLabel() const;
169 :
170 : // <src>color</src> must either be a recognized color name or
171 : // a valid rgb hex string, else an expection is thrown
172 : void setColor(const casacore::String& color);
173 :
174 : // color must have three elements all with values between 0 and 255 inclusive
175 : // or an exception is thrown.
176 : void setColor(const RGB& color);
177 :
178 : // returns the color name if it is recognized or its rgb hex string
179 : casacore::String getColorString() const;
180 :
181 : static casacore::String colorToString(const RGB& color);
182 :
183 : // get the color associated with this object
184 : RGB getColor() const;
185 :
186 : void setLineStyle(const LineStyle lineStyle);
187 :
188 : LineStyle getLineStyle() const;
189 :
190 : void setLineWidth(const casacore::uInt linewidth);
191 :
192 : casacore::uInt getLineWidth() const;
193 :
194 : void setSymbolSize(const casacore::uInt symbolsize);
195 :
196 : casacore::uInt getSymbolSize() const;
197 :
198 : void setSymbolThickness(const casacore::uInt symbolthickness);
199 :
200 : casacore::uInt getSymbolThickness() const;
201 :
202 : void setFont(const casacore::String& font);
203 :
204 : casacore::String getFont() const;
205 :
206 : void setFontSize(const casacore::uInt fontsize);
207 :
208 : casacore::uInt getFontSize() const;
209 :
210 : void setFontStyle(const FontStyle& fontstyle);
211 :
212 : FontStyle getFontStyle() const;
213 :
214 : void setUseTex(const casacore::Bool usetex);
215 :
216 : casacore::Bool isUseTex() const;
217 :
218 : // is the object a region?
219 : virtual casacore::Bool isRegion() const;
220 :
221 : // is the object only an annotation? Can only be false if the object
222 : // is a region
223 0 : inline virtual casacore::Bool isAnnotationOnly() const { return true; }
224 :
225 : // set "pix" as valid unit. This should be called externally
226 : // before creating quantities which have pixel units.
227 : static void unitInit();
228 :
229 : // <src>color</src> must either be a recognized color name or
230 : // a valid rgb hex string, else an expection is thrown
231 : void setLabelColor(const casacore::String& color);
232 :
233 : // color must have three elements all with values between 0 and 255 inclusive
234 : // or an exception is thrown.
235 : void setLabelColor(const RGB& color);
236 :
237 : // returns the color name if it is recognized or its rgb hex string
238 :
239 : casacore::String getLabelColorString() const;
240 :
241 : // get the color associated with this object's label
242 : RGB getLabelColor() const;
243 :
244 : // returns one of top, bottom, left, or right.
245 : casacore::String getLabelPosition() const;
246 :
247 : // <src>position</src> must have a value in top, bottom, left, or right.
248 : // case is ignored.
249 : void setLabelPosition(const casacore::String& position);
250 :
251 : // <src>offset</src> must have two elements
252 : void setLabelOffset(const std::vector<casacore::Int>& offset);
253 :
254 : std::vector<casacore::Int> getLabelOffset() const;
255 :
256 : virtual std::ostream& print(std::ostream &os) const = 0;
257 :
258 : // These parameters are included at the global scope. Multiple runs
259 : // on the same object are cumulative; if a key exists in the current
260 : // settings but not in <src>globalKeys</src> that key will still exist
261 : // in the globals after setGlobals has run.
262 : void setGlobals(const casacore::Vector<Keyword>& globalKeys);
263 :
264 : // print a set of keyword value pairs
265 : static std::ostream& print(
266 : std::ostream& os, const std::map<Keyword, casacore::String>& params
267 : );
268 :
269 : // print a line style representation
270 : static std::ostream& print(
271 : std::ostream& os, const LineStyle ls
272 : );
273 :
274 : // print a font style representation
275 : static std::ostream& print(
276 : std::ostream& os, const FontStyle fs
277 : );
278 :
279 : static std::ostream& print(
280 : std::ostream& os, const Direction d
281 : );
282 :
283 : // Get a list of the user-friendly color names supported
284 : static std::list<std::string> colorChoices();
285 :
286 : // get the coordinate system associated with this object.
287 : // This is the same coordinate system used to construct the object.
288 0 : inline const casacore::CoordinateSystem& getCsys() const {
289 0 : return _csys;
290 : }
291 :
292 : // DEPRECATED Please use getConvertedDirections()
293 : // the pair elements have longitude as the first member and latitude as the second.
294 : // FIXME make this return of vector of MVDirections
295 : // Returns the same angles as getConvertedDirections()
296 : Direction getDirections() const;
297 :
298 : // get the frequency limits converted to the spectral frame of the coordinate
299 : // system of this object. An empty casacore::Vector implies all applicable frequencies
300 : // have been selected.
301 : casacore::Vector<casacore::MFrequency> getFrequencyLimits() const;
302 :
303 : // Get the stokes for which the selection applies. An empty casacore::Vector implies
304 : // all applicable stokes have been selected.
305 : casacore::Vector<casacore::Stokes::StokesTypes> getStokes() const;
306 :
307 : // if freqRefFrame=="" -> use the reference frame of the coordinate system
308 : // if dopplerString=="" -> use the doppler system associated with the coordinate system
309 : // if restfreq=casacore::Quantity(0, "Hz") -> use the rest frequency associated with the coordinate system
310 : // Tacitly does nothing if the coordinate system has no spectral axis.
311 : // Returns true if frequencies actually need to be set and were set.
312 : virtual casacore::Bool setFrequencyLimits(
313 : const casacore::Quantity& beginFreq,
314 : const casacore::Quantity& endFreq,
315 : const casacore::String& freqRefFrame,
316 : const casacore::String& dopplerString,
317 : const casacore::Quantity& restfreq
318 : );
319 :
320 : // same as getDirections, only returns proper MDirections
321 0 : inline const casacore::Vector<casacore::MDirection>& getConvertedDirections() const {
322 0 : return _convertedDirections;
323 : }
324 :
325 : protected:
326 : // <group>
327 : // if <src>freqRefFrame</src> or <src>dopplerString</src> are empty,
328 : // the values from the spectral coordinate of csys will be used, if one
329 : // exists. if restfreq=casacore::Quantity(0, "Hz") -> use the rest frequency
330 : // associated with the coordinate system.
331 : // The provided coordinate system should be that of the image to which
332 : // the region/annotation is being applied.
333 : AnnotationBase(
334 : const Type type, const casacore::String& dirRefFrameString,
335 : const casacore::CoordinateSystem& csys, const casacore::Quantity& beginFreq,
336 : const casacore::Quantity& endFreq,
337 : const casacore::String& freqRefFrame,
338 : const casacore::String& dopplerString,
339 : const casacore::Quantity& restfreq,
340 : const casacore::Vector<casacore::Stokes::StokesTypes>& stokes
341 : );
342 :
343 : // use only if the frame of the input directions is the
344 : // same as the frame of the coordinate system. All frequencies
345 : // are used.
346 : AnnotationBase(
347 : const Type type, const casacore::CoordinateSystem& csys,
348 : const casacore::Vector<casacore::Stokes::StokesTypes>& stokes
349 : );
350 : // <group>
351 :
352 : // assignment operator
353 : AnnotationBase& operator= (const AnnotationBase& other);
354 :
355 : static void _checkMixed(
356 : const casacore::String& origin,
357 : const Direction& dirs
358 : );
359 :
360 : casacore::MDirection _directionFromQuantities(
361 : const casacore::Quantity& q0, const casacore::Quantity& q1
362 : );
363 :
364 : void _checkAndConvertDirections(
365 : const casacore::String& origin,
366 : const Direction& dirs
367 : );
368 :
369 : virtual void _printPairs(std::ostream& os) const;
370 :
371 0 : inline const casacore::IPosition& _getDirectionAxes() const {
372 0 : return _directionAxes;
373 : }
374 :
375 : // direction to string, precision of 0.1 mas
376 : // ra and dec in sexigesimal format, non-equatorial coords in degrees
377 : casacore::String _printDirection(
378 : const casacore::Quantity& longitude, const casacore::Quantity& latitude
379 : ) const;
380 :
381 : // convert angle to arcsec, precision 0.1 mas
382 : static casacore::String _toArcsec(const casacore::Quantity& angle);
383 :
384 : // convert angle to degrees, precision 0.1 mas
385 : static casacore::String _toDeg(const casacore::Quantity& angle);
386 :
387 0 : inline void _setParam(const Keyword k, const casacore::String& s) {
388 0 : _params[k] = s;
389 0 : }
390 :
391 : // return a string representing a pixel value, precision 1.
392 : static casacore::String _printPixel(const casacore::Double& d);
393 :
394 0 : casacore::MDirection::Types _getDirectionRefFrame() const { return _directionRefFrame; }
395 :
396 : private:
397 : Type _type;
398 : casacore::MDirection::Types _directionRefFrame;
399 : casacore::CoordinateSystem _csys;
400 : casacore::IPosition _directionAxes;
401 : casacore::String _label, _font, _labelPos;
402 : RGB _color, _labelColor;
403 : FontStyle _fontstyle;
404 : LineStyle _linestyle;
405 : casacore::uInt _fontsize, _linewidth, _symbolsize,
406 : _symbolthickness;
407 : casacore::Bool _usetex;
408 : casacore::Vector<casacore::MDirection> _convertedDirections;
409 : casacore::Vector<casacore::MFrequency> _convertedFreqLimits;
410 : casacore::Quantity _beginFreq, _endFreq, _restFreq;
411 : casacore::Vector<casacore::Stokes::StokesTypes> _stokes;
412 : casacore::MFrequency::Types _freqRefFrame;
413 : casacore::MDoppler::Types _dopplerType;
414 :
415 : std::map<Keyword, casacore::Bool> _globals;
416 : std::map<Keyword, casacore::String> _params;
417 : casacore::Bool _printGlobals;
418 : std::vector<casacore::Int> _labelOff;
419 :
420 : static casacore::Bool _doneUnitInit, _doneColorInit;
421 : static std::map<casacore::String, LineStyle> _lineStyleMap;
422 : static std::map<casacore::String, Type> _typeMap;
423 : static std::map<string, RGB> _colors;
424 : static std::map<RGB, string> _rgbNameMap;
425 : static std::list<std::string> _colorNames;
426 :
427 : const static casacore::String _class;
428 :
429 : void _init();
430 : void _initParams();
431 :
432 : static void _initColors();
433 :
434 : static RGB _colorStringToRGB(const casacore::String& s);
435 :
436 : static casacore::Bool _isRGB(const RGB& rgb);
437 :
438 : void _testConvertToPixel() const;
439 :
440 : static void _initTypeMap();
441 :
442 : void _checkAndConvertFrequencies();
443 :
444 : casacore::String _printFreqRange() const;
445 :
446 : static casacore::String _printFreq(const casacore::Quantity& freq);
447 :
448 : };
449 :
450 0 : inline std::ostream &operator<<(std::ostream& os, const AnnotationBase& annotation) {
451 0 : return annotation.print(os);
452 : };
453 :
454 0 : inline std::ostream &operator<<(std::ostream& os, const AnnotationBase::LineStyle& ls) {
455 0 : return AnnotationBase::print(os, ls);
456 : };
457 :
458 : inline std::ostream &operator<<(std::ostream& os, const AnnotationBase::FontStyle& fs) {
459 : return AnnotationBase::print(os, fs);
460 : };
461 :
462 0 : inline std::ostream &operator<<(std::ostream& os, const std::map<AnnotationBase::Keyword, casacore::String>& x) {
463 0 : return AnnotationBase::print(os, x);
464 : };
465 :
466 : inline std::ostream &operator<<(std::ostream& os, const AnnotationBase::Direction x) {
467 : return AnnotationBase::print(os, x);
468 : };
469 :
470 : // Just need a identifiable exception class for exception handling.
471 : class WorldToPixelConversionError : public casacore::AipsError {
472 : public:
473 0 : WorldToPixelConversionError(casacore::String msg) : casacore::AipsError(msg) {}
474 : };
475 :
476 : }
477 :
478 : #endif
|