GammaLib  2.1.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GSkyRegionCircle.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GSkyRegionCircle.cpp - Circular sky region class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2013-2020 by Michael Mayer *
5  * ----------------------------------------------------------------------- *
6  * *
7  * This program is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 /**
22  * @file GSkyRegionCircle.hpp
23  * @brief Circular sky region implementation
24  * @author Michael Mayer
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include "GTools.hpp"
32 #include "GSkyRegionCircle.hpp"
33 #include "GSkyRegionRectangle.hpp"
34 #include "GSkyRegionMap.hpp"
35 
36 /* __ Method name definitions ____________________________________________ */
37 #define G_RADIUS "GSkyRegionCircle::radius(double&)"
38 #define G_READ "GSkyRegionCircle::read(std::string&)"
39 #define G_CONTAINS "GSkyRegionCircle::contains(GSkyRegion&)"
40 #define G_OVERLAPS "GSkyRegionCircle::overlaps(GSkyRegion&)"
41 
42 /* __ Macros _____________________________________________________________ */
43 
44 /* __ Coding definitions _________________________________________________ */
45 
46 /* __ Debug definitions __________________________________________________ */
47 
48 /* __ Prototype __________________________________________________________ */
49 
50 
51 /*==========================================================================
52  = =
53  = Constructors/destructors =
54  = =
55  ==========================================================================*/
56 
57 /***********************************************************************//**
58  * @brief Void constructor
59  ***************************************************************************/
61 {
62  // Initialise members
63  init_members();
64 
65  // Return
66  return;
67 }
68 
69 
70 /***********************************************************************//**
71  * @brief Direction constructor
72  *
73  * @param[in] centre Centre sky direction.
74  * @param[in] radius Region radius (degrees).
75  ***************************************************************************/
77  const double& radius) : GSkyRegion()
78 {
79  // Initialise members
80  init_members();
81 
82  // Set members
83  this->centre(centre);
84  this->radius(radius);
85 
86  // Compute solid angle
88 
89  // Return
90  return;
91 }
92 
93 
94 /***********************************************************************//**
95  * @brief Direction constructor
96  *
97  * @param[in] ra Right Ascension of region centre (degrees).
98  * @param[in] dec Declination of region centre (degrees).
99  * @param[in] radius Region radius (degrees).
100  ***************************************************************************/
102  const double& dec,
103  const double& radius) : GSkyRegion()
104 {
105  // Initialise members
106  init_members();
107 
108  // Set members
109  this->centre(ra, dec);
110  this->radius(radius);
111 
112  // Compute solid angle
114 
115  // Return
116  return;
117 }
118 
119 
120 /***********************************************************************//**
121  * @brief String constructor
122  *
123  * @param[in] line DS9 region file line.
124  *
125  * Constructs region from a DS9 region file line.
126  ***************************************************************************/
127 GSkyRegionCircle::GSkyRegionCircle(const std::string& line) : GSkyRegion()
128 {
129  // Initialise members
130  init_members();
131 
132  // Read information from DS9 region file line
133  read(line);
134 
135  // Return
136  return;
137 
138 }
139 
140 
141 /***********************************************************************//**
142  * @brief Copy constructor
143  *
144  * @param[in] region Circular sky region.
145  ***************************************************************************/
147  GSkyRegion(region)
148 {
149  // Initialise members
150  init_members();
151 
152  // Copy members
153  copy_members(region);
154 
155  // Return
156  return;
157 }
158 
159 
160 /***********************************************************************//**
161  * @brief Destructor
162  ***************************************************************************/
164 {
165  // Free members
166  free_members();
167 
168  // Return
169  return;
170 }
171 
172 
173 /*==========================================================================
174  = =
175  = Operators =
176  = =
177  ==========================================================================*/
178 
179 /***********************************************************************//**
180  * @brief Assignment operator
181  *
182  * @param[in] region Circular sky region.
183  * @return Circular sky region.
184  ***************************************************************************/
186 {
187  // Execute only if object is not identical
188  if (this != &region) {
189 
190  // Copy base class members
191  this->GSkyRegion::operator=(region);
192 
193  // Free members
194  free_members();
195 
196  // Initialise private members for clean destruction
197  init_members();
198 
199  // Copy members
200  copy_members(region);
201 
202  } // endif: object was not identical
203 
204  // Return this object
205  return *this;
206 }
207 
208 
209 /*==========================================================================
210  = =
211  = Public methods =
212  = =
213  ==========================================================================*/
214 
215 /***********************************************************************//**
216  * @brief Clear instance
217  ***************************************************************************/
219 {
220  // Free members
221  free_members();
222  this->GSkyRegion::free_members();
223 
224  // Initialise private members
225  this->GSkyRegion::init_members();
226  init_members();
227 
228  // Return
229  return;
230 }
231 
232 
233 /***********************************************************************//**
234  * @brief Clone circular sky region
235  *
236  * @return Deep copy to circular sky region.
237  ***************************************************************************/
239 {
240  // Clone circular sky region
241  return new GSkyRegionCircle(*this);
242 }
243 
244 
245 /***********************************************************************//**
246  * @brief Set radius of circular region
247  *
248  * @param[in] radius Radius (degrees).
249  *
250  * @exception GException::invalid_argument
251  * Radius value is less than 0.
252  *
253  * Sets the radius of the circular sky region. Only non-negative radii are
254  * allowed.
255  ***************************************************************************/
256 void GSkyRegionCircle::radius(const double& radius)
257 {
258  // Check if radius is valid
259  if (radius < 0.0) {
260  std::string msg =
261  "A negative radius of "+gammalib::str(radius)+" degrees has been "
262  "specified for a circular sky region. Please specify a "
263  "non-negative radius.";
265  }
266 
267  // Set radius value
268  m_radius = radius;
269 
270  // Compute the solid angle
272 
273  // Return
274  return;
275 }
276 
277 
278 /***********************************************************************//**
279  * @brief Read region from DS9 string
280  *
281  * @param[in] line String in DS9 format.
282  *
283  * @exception GException::invalid_value
284  * Invalid value found in DS9 format string.
285  ***************************************************************************/
286 void GSkyRegionCircle::read(const std::string& line)
287 {
288  // Clear the current instance
289  clear();
290 
291  // Split the string into 2 parts seperated by #
292  std::vector<std::string> substrings = gammalib::split(line,"#");
293  std::string region_def = (!substrings.empty()) ? substrings[0] : "";
294  std::string comment = (substrings.size() > 1) ? substrings[1] : "";
295 
296  // Finding the circle
297  if (region_def.find("circle") == std::string::npos) {
298  std::string msg =
299  "Unable to find the key word \"circle\" in provided string"
300  " \""+line+"\". The \"circle\" key word is mandatory.";
301  throw GException::invalid_value(G_READ, msg);
302  }
303 
304  // Get the the coordinate system of the values
305  std::string system = gammalib::split(region_def, ";")[0];
306 
307  // Get the substring of the important values
308  size_t pos = region_def.find("circle(");
309  size_t end = region_def.find(")");
310  std::string circlestring = region_def.substr(pos+7, end);
311  circlestring.erase(circlestring.find(")"), 1);
312 
313  // Get the values of the region x,y,and radius
314  std::vector<std::string> values = gammalib::split(circlestring,",");
315  if (values.size() != 3) {
316  std::string msg =
317  "Invalid number of "+gammalib::str(values.size())+" arguments "
318  "after the \"circle\" key word in provided string \""+line+"\". "
319  "Exactly 3 arguments are expected.";
320  throw GException::invalid_value(G_READ, msg);
321  }
322  double x = gammalib::todouble(values[0]);
323  double y = gammalib::todouble(values[1]);
324  double radius = gammalib::todouble(values[2]);
325 
326  // Get radius units
327  if (gammalib::contains(values[2], "'")) {
328  radius /= 60.0;
329  }
330  else if (gammalib::contains(values[2], "\"")) {
331  radius /= 3600.0;
332  }
333 
334  // Initialise centre direction
335  GSkyDir centre = GSkyDir();
336 
337  // Set the values in the correct system
338  if (system == "fk5" || system == "icrs") {
339  centre.radec_deg(x,y);
340  }
341  else if (system == "galactic") {
342  centre.lb_deg(x,y);
343  }
344  else {
345  std::string msg =
346  "Unsupported coordinate system \""+system+"\" in provided string "
347  "\""+line+"\". Only the following coordinate systems are "
348  "supported: \"fk5\", \"icrs\" and \"galactic\".";
349  throw GException::invalid_value(G_READ, msg);
350  }
351 
352  // Set members
353  this->centre(centre);
354  this->radius(radius);
355 
356  // Compute solid angle
358 
359  // Check if there is a given name for the region and set it. Strings may
360  // be quoted with " or ' or {}
361  pos = comment.find("text");
362  if (pos != std::string::npos) {
363  pos = comment.find("=", pos+4);
364  if (pos != std::string::npos) {
365 
366  // Set possible quotes
367  const std::string quotes_open = "{'\"";
368  const std::string quotes_close = "}'\"";
369 
370  // Set quotes found flag
371  bool found = false;
372 
373  // Search for possible quotes and extract name
374  for (int i = 0; i < quotes_open.size(); ++i) {
375  std::string quote_open = quotes_open.substr(i,1);
376  std::string quote_close = quotes_close.substr(i,1);
377  pos = comment.find(quote_open, pos+1);
378  if (pos != std::string::npos) {
379  end = comment.find(quote_close, pos+1);
380  if (end != std::string::npos) {
381  int length = end-pos-1;
382  if (length > 0) {
383  m_name = comment.substr(pos+1, length);
384  }
385  else {
386  m_name = "";
387  }
388  found = true;
389  }
390  else {
391  std::string msg = "Missing "+quote_open+" following "+
392  quote_close+" encountered after "
393  "text attribute. Please add closing "
394  "quotes to text="+quote_open+"Name"+
395  quote_close+" attribute.";
396  throw GException::invalid_value(G_READ, msg);
397  }
398  }
399  } // endfor: looped over possible quotes
400 
401  // Throw an exception if no quotes were found
402  if (!found) {
403  std::string msg = "Missing quotes \" or ' or {} following "
404  "text attribute. Please specify quotes "
405  "around the names of the text, for example "
406  "text={Name}.";
407  throw GException::invalid_value(G_READ, msg);
408  }
409 
410  } // endif: = character found
411 
412  // Signal that no = character was found after text
413  else {
414  std::string msg = "Missing = following text attribute. Please "
415  "specify the value for a text attribute, "
416  "for example text={Name}.";
417  throw GException::invalid_value(G_READ, msg);
418  }
419 
420  } // endif: text attribute found
421 
422  // Return
423  return;
424 }
425 
426 
427 /***********************************************************************//**
428  * @brief Write region into a string
429  *
430  * @return String to be written in a DS9 region file
431  *
432  * Writes a DS9 region into a string. The region name is only written if it
433  * is defined.
434  ***************************************************************************/
435 std::string GSkyRegionCircle::write(void) const
436 {
437  // Allocate string
438  std::string result;
439 
440  // Set string
441  result.append("fk5;circle(");
442  result.append(gammalib::str(m_centre.ra_deg()));
443  result.append(",");
444  result.append(gammalib::str(m_centre.dec_deg()));
445  result.append(",");
446  result.append(gammalib::str(m_radius));
447  result.append(")");
448 
449  // Optionally add region name
450  if (m_name.length() > 0) {
451  result.append(" # text=");
452  result.append("{");
453  result.append(m_name);
454  result.append("}");
455  }
456 
457  // Return string
458  return result;
459 }
460 
461 
462 /***********************************************************************//**
463  * @brief Print circular region
464  *
465  * @param[in] chatter Chattiness
466  * @return String containing region information.
467  ***************************************************************************/
468 std::string GSkyRegionCircle::print(const GChatter& chatter) const
469 {
470  // Initialise result string
471  std::string result;;
472 
473  // Continue only if chatter is not silent
474  if (chatter != SILENT) {
475 
476  // Append header
477  result.append("=== GSkyRegionCircle ===");
478 
479  // Append sky circle information
480  result.append("\n"+gammalib::parformat("Right Ascension of centre"));
481  result.append(gammalib::str(ra())+" deg");
482  result.append("\n"+gammalib::parformat("Declination of centre"));
483  result.append(gammalib::str(dec())+" deg");
484  result.append("\n"+gammalib::parformat("Radius"));
485  result.append(gammalib::str(radius())+" deg");
486 
487  } // endif: chatter was not silent
488 
489  // Return result
490  return result;
491 }
492 
493 /***********************************************************************//**
494  * @brief Checks if sky direction lies within region
495  *
496  * @param[in] dir Sky direction.
497  * @return True if sky direction is contained in region.
498  *
499  * A sky direction lies within a region when its distance to the region
500  * centre is not larger than the region radius.
501  ***************************************************************************/
502 bool GSkyRegionCircle::contains(const GSkyDir& dir) const
503 {
504  // Initialise containment flag
505  bool contains = false;
506 
507  // calculate distance from dir to centre
508  double distance = dir.dist_deg(m_centre);
509 
510  // Check if distance < radius
511  if (distance <= radius()) {
512  contains = true;
513  }
514 
515  // Return containment flag
516  return contains;
517 }
518 
519 /***********************************************************************//**
520  * @brief Checks if region is fully contained within this region
521  *
522  * @param[in] reg Sky region.
523  * @return True if region is contained in region.
524  *
525  * @exception GException::feature_not_implemented
526  * Regions differ in type.
527  ***************************************************************************/
529 {
530  // Initialise return value
531  bool contains = false;
532 
533  // If the other region is a circle then check whether it is fully
534  // container in the circle
535  if (reg.type() == "Circle") {
536 
537  // Create circular region from reg
538  const GSkyRegionCircle* circle =
539  static_cast<const GSkyRegionCircle*>(&reg);
540 
541  // Calculate angular distance between the centres
542  double ang_dist = m_centre.dist_deg(circle->centre());
543 
544  // Check if the region is contained in this
545  if ((ang_dist + circle->radius()) <= m_radius) {
546  contains = true;
547  }
548 
549  } // endif: other region was of type "Circle"
550 
551  // ... otherwise, if the other region is a rectangle then check whether
552  // all four corners are contained within the circle
553  else if (reg.type() == "Rectangle") {
554 
555  // Create rectangular region from reg
556  const GSkyRegionRectangle* rect =
557  static_cast<const GSkyRegionRectangle*>(&reg);
558 
559  // Check containment of all corners
560  contains = this->contains(rect->corner(0)) &&
561  this->contains(rect->corner(1)) &&
562  this->contains(rect->corner(2)) &&
563  this->contains(rect->corner(3));
564 
565  }
566 
567  // ... otherwise, if the other region is a map then check whether it
568  // is contained within the rectangle
569  else if (reg.type() == "Map") {
570 
571  // Create map from reg
572  const GSkyRegionMap* map = static_cast<const GSkyRegionMap*>(&reg);
573 
574  // Get non-zero indices
575  const std::vector<int>& indices = map->nonzero_indices();
576 
577  // Initialise containment flag to true
578  contains = true;
579 
580  // Loop over all indices
581  for (int i = 0; i < indices.size(); ++i) {
582 
583  // Get sky direction of map pixel
584  GSkyDir dir = map->map().inx2dir(indices[i]);
585 
586  // If pixel is not contained then set containment flag to false
587  // and break
588  if (!this->contains(dir)) {
589  contains = false;
590  break;
591  }
592 
593  } // endfor: looped over non-zero map indices
594 
595  } // endif: other region was of type "Map"
596 
597  // ... otherwise throw an exception
598  else {
600  "Cannot compare to region type \""+reg.type()+"\" yet.");
601  }
602 
603  // Return containment flag
604  return contains;
605 }
606 
607 
608 /***********************************************************************//**
609  * @brief Checks if region is overlapping with this region
610  *
611  * @param[in] reg Sky region.
612  * @return True if region overlaps with region.
613  *
614  * @exception GException::feature_not_implemented
615  * Regions differ in type.
616  ***************************************************************************/
618 {
619  // Initialise return value
620  bool overlap = false;
621 
622  // If region is circle then check overlap by comparing the centre
623  // distances
624  if (reg.type() == "Circle") {
625 
626  // Create circular region from reg
627  const GSkyRegionCircle* circle =
628  static_cast<const GSkyRegionCircle*>(&reg);
629 
630  // Calculate angular distance between the centres
631  double ang_dist = m_centre.dist_deg(circle->centre());
632 
633  // Check if the distance is smaller than the sum of both radii
634  if (ang_dist <= (m_radius + circle->radius())) {
635  overlap = true;
636  }
637 
638  } // endif: region was circle
639 
640  // ... otherwise if region is rectangle then check overlap
641  else if (reg.type() == "Rectangle") {
642 
643  // Create rectangular region from reg
644  const GSkyRegionRectangle* rect =
645  static_cast<const GSkyRegionRectangle*>(&reg);
646 
647  // Check overlap with circle
648  overlap = rect->overlaps(*this);
649 
650  } // endif: region was rectangle
651 
652  // ... otherwise if region is map then check overlap with map
653  else if (reg.type() == "Map") {
654 
655  // Create map from reg
656  const GSkyRegionMap* map = static_cast<const GSkyRegionMap*>(&reg);
657 
658  // Check overlap with circle
659  overlap = map->overlaps(*this);
660 
661  } // endif: region was map
662 
663  // ... otherwise throw an exception
664  else {
666  "Cannot compare to region type \""+reg.type()+"\" yet.");
667  }
668 
669  // Return value
670  return overlap;
671 }
672 
673 
674 /*==========================================================================
675  = =
676  = Private methods =
677  = =
678  ==========================================================================*/
679 
680 /***********************************************************************//**
681  * @brief Initialise class members
682  ***************************************************************************/
684 {
685  // Initialise members
686  m_centre = GSkyDir();
687  m_radius = 0.0;
688  m_type = "Circle";
689 
690  //Return
691  return;
692 }
693 
694 
695 /***********************************************************************//**
696  * @brief Copy class members
697  *
698  * @param[in] region Circular sky region.
699  ***************************************************************************/
701 {
702  // Copy attributes
703  m_centre = region.m_centre;
704  m_radius = region.m_radius;
705 
706  // Return
707  return;
708 }
709 
710 
711 /***********************************************************************//**
712  * @brief Delete class members
713  ***************************************************************************/
715 {
716  // Return
717  return;
718 }
719 
720 
721 /***********************************************************************//**
722  * @brief Compute solid angle
723  ***************************************************************************/
725 {
726  // Convert radius from degrees to radians
727  double radius_rad = m_radius * gammalib::deg2rad;
728 
729  // Compute solid angle
730  m_solid = gammalib::twopi * (1.0 - std::cos(radius_rad));
731 
732  // Return
733  return;
734 }
735 
736 
737 /***********************************************************************//**
738  * @brief Equality operator
739  *
740  * @param[in] a First sky region circle.
741  * @param[in] b Second sky region circle.
742  * @return True if both sky region circles are identical.
743  *
744  * Returns true if two sky region circles and identical.
745  ***************************************************************************/
747 {
748  // Return equality
749  return ((a.m_centre == b.m_centre) && (a.m_radius == b.m_radius));
750 }
751 
752 
753 /***********************************************************************//**
754  * @brief Non equality operator
755  *
756  * @param[in] a First sky region circle.
757  * @param[in] b Second sky region circle.
758  * @return True if both sky region circles are different.
759  ***************************************************************************/
761 {
762  // Return non equality
763  return ((a.m_centre != b.m_centre) || (a.m_radius != b.m_radius));
764 }
void free_members(void)
Delete class members.
std::string print(const GChatter &chatter=NORMAL) const
Print circular region.
bool contains(const std::string &str, const std::string &substring)
Checks if a substring is in a string.
Definition: GTools.cpp:1342
double dist_deg(const GSkyDir &dir) const
Compute angular distance between sky directions in degrees.
Definition: GSkyDir.hpp:286
double m_solid
Solid angle subtended by the region (sr)
Definition: GSkyRegion.hpp:96
Rectangular sky region class interface definition.
bool overlaps(const GSkyRegion &reg) const
Checks if region is overlapping with this region.
double dec_deg(void) const
Returns Declination in degrees.
Definition: GSkyDir.hpp:256
GSkyDir m_centre
Centre or reference point of the region.
void free_members(void)
Delete class members.
Definition: GSkyRegion.cpp:168
GVector cos(const GVector &vector)
Computes cosine of vector elements.
Definition: GVector.cpp:1190
void init_members(void)
Initialise class members.
Definition: GSkyRegion.cpp:136
const std::string & type(void) const
Return region type.
Definition: GSkyRegion.hpp:137
GSkyRegionCircle(void)
Void constructor.
#define G_RADIUS
std::vector< std::string > split(const std::string &s, const std::string &sep)
Split string.
Definition: GTools.cpp:983
Gammalib tools definition.
void read(const std::string &line)
Read region from DS9 string.
Interface for the circular sky region class.
Interface for the rectangular sky region class.
std::string m_type
Type of the region (circle, rectangle,...)
Definition: GSkyRegion.hpp:94
std::string centre(const std::string &s, const int &n, const char &c= ' ')
Centre string to achieve a length of n characters.
Definition: GTools.cpp:1118
const double & radius(void) const
Return circular region radius (in degrees)
void map(const GSkyMap &map)
Set sky map.
#define G_READ
virtual ~GSkyRegionCircle(void)
Destructor.
const double deg2rad
Definition: GMath.hpp:43
const std::vector< int > & nonzero_indices(void) const
Get non-zero index vector.
Abstract interface for the sky region class.
Definition: GSkyRegion.hpp:57
std::string write(void) const
Write region into a string.
std::string m_name
Name of the region.
Definition: GSkyRegion.hpp:95
double m_radius
Radius of circular the region (degrees)
bool overlaps(const GSkyRegion &reg) const
Checks if a given region is overlapping with this region.
void compute_solid_angle(void)
Compute solid angle.
virtual GSkyRegion & operator=(const GSkyRegion &region)
Assignment operator.
Definition: GSkyRegion.cpp:106
double ra_deg(void) const
Returns Right Ascension in degrees.
Definition: GSkyDir.hpp:229
GChatter
Definition: GTypemaps.hpp:33
Interface for a sky region map.
double dec(void) const
Return circular region centre Declination.
void radec_deg(const double &ra, const double &dec)
Set equatorial sky direction (degrees)
Definition: GSkyDir.cpp:224
#define G_CONTAINS
bool overlaps(const GSkyRegion &reg) const
Checks if region is overlapping with this region.
const GSkyDir & centre(void) const
Return circular region centre.
void copy_members(const GSkyRegionCircle &region)
Copy class members.
Sky region map class interface definition.
void lb_deg(const double &l, const double &b)
Set galactic sky direction (degrees)
Definition: GSkyDir.cpp:278
bool contains(const GSkyDir &dir) const
Checks if sky direction lies within region.
GSkyDir corner(const int &index) const
Return sky direction of one corner of the rectangle.
const double twopi
Definition: GMath.hpp:36
bool operator==(const GEnergy &a, const GEnergy &b)
Energy equality operator friend.
Definition: GEnergy.hpp:297
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1143
GSkyRegionCircle & operator=(const GSkyRegionCircle &region)
Assignment operator.
Sky direction class.
Definition: GSkyDir.hpp:62
Circular sky region class interface definition.
bool operator!=(const GEbounds &a, const GEbounds &b)
Energy boundaries inequality operator friend.
Definition: GEbounds.hpp:213
GSkyRegionCircle * clone(void) const
Clone circular sky region.
void clear(void)
Clear instance.
double todouble(const std::string &arg)
Convert string into double precision value.
Definition: GTools.cpp:926
void init_members(void)
Initialise class members.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:489
double ra(void) const
Return circular region centre Right Ascension.