Commit 3460fe3701b612145b46e022de2769136004de28

Authored by Jürgen Knödlseder
1 parent bed0350a

Adjust sky rectangle code (#3248)

include/GSkyRegionRect.hpp
... ... @@ -30,10 +30,8 @@
30 30 /* __ Includes ___________________________________________________________ */
31 31 #include <vector>
32 32 #include <string>
33   -//#include "GMath.hpp"
34 33 #include "GSkyDir.hpp"
35 34 #include "GSkyRegion.hpp"
36   -//#include "GTools.hpp"
37 35  
38 36 /* __ Forward declarations _______________________________________________ */
39 37  
... ...
src/sky/GSkyRegionCircle.cpp
... ... @@ -28,9 +28,10 @@
28 28 #ifdef HAVE_CONFIG_H
29 29 #include <config.h>
30 30 #endif
  31 +#include "GTools.hpp"
31 32 #include "GSkyRegionCircle.hpp"
32 33 #include "GSkyRegionRect.hpp"
33   -#include "GTools.hpp"
  34 +#include "GSkyRegionMap.hpp"
34 35  
35 36 /* __ Method name definitions ____________________________________________ */
36 37 #define G_RADIUS "GSkyRegionCircle::radius(double&)"
... ... @@ -70,10 +71,10 @@ GSkyRegionCircle::GSkyRegionCircle(void) : GSkyRegion()
70 71 * @brief Direction constructor
71 72 *
72 73 * @param[in] centre Centre sky direction.
73   - * @param[in] radius Region radius [deg].
  74 + * @param[in] radius Region radius (degrees).
74 75 ***************************************************************************/
75   -GSkyRegionCircle::GSkyRegionCircle(const GSkyDir& centre, const double& radius) :
76   - GSkyRegion()
  76 +GSkyRegionCircle::GSkyRegionCircle(const GSkyDir& centre,
  77 + const double& radius) : GSkyRegion()
77 78 {
78 79 // Initialise members
79 80 init_members();
... ... @@ -93,11 +94,12 @@ GSkyRegionCircle::GSkyRegionCircle(const GSkyDir&amp; centre, const double&amp; radius)
93 94 /***********************************************************************//**
94 95 * @brief Direction constructor
95 96 *
96   - * @param[in] ra Right Ascension of region centre [deg].
97   - * @param[in] dec Declination of region centre [deg].
98   - * @param[in] radius Region radius [deg].
  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).
99 100 ***************************************************************************/
100   -GSkyRegionCircle::GSkyRegionCircle(const double& ra, const double& dec,
  101 +GSkyRegionCircle::GSkyRegionCircle(const double& ra,
  102 + const double& dec,
101 103 const double& radius) : GSkyRegion()
102 104 {
103 105 // Initialise members
... ... @@ -243,7 +245,7 @@ GSkyRegionCircle* GSkyRegionCircle::clone(void) const
243 245 /***********************************************************************//**
244 246 * @brief Set radius of circular region
245 247 *
246   - * @param[in] radius Radius [deg].
  248 + * @param[in] radius Radius (degrees).
247 249 *
248 250 * @exception GException::invalid_argument
249 251 * Radius value is less than 0.
... ... @@ -256,10 +258,9 @@ void GSkyRegionCircle::radius(const double&amp; radius)
256 258 // Check if radius is valid
257 259 if (radius < 0.0) {
258 260 std::string msg =
259   - "A radius of "+gammalib::str(radius)+" degrees has been"
260   - " specified for a circular sky region.\n"
261   - "The radius of a circular sky region can't be less than 0"
262   - " degrees.";
  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.";
263 264 throw GException::invalid_argument(G_RADIUS, msg);
264 265 }
265 266  
... ... @@ -296,8 +297,7 @@ void GSkyRegionCircle::read(const std::string&amp; line)
296 297 if (region_def.find("circle") == std::string::npos) {
297 298 std::string msg =
298 299 "Unable to find the key word \"circle\" in provided string"
299   - " \""+line+"\".\n"
300   - "The \"circle\" key word is mandatory.";
  300 + " \""+line+"\". The \"circle\" key word is mandatory.";
301 301 throw GException::invalid_value(G_READ, msg);
302 302 }
303 303  
... ... @@ -314,8 +314,8 @@ void GSkyRegionCircle::read(const std::string&amp; line)
314 314 std::vector<std::string> values = gammalib::split(circlestring,",");
315 315 if (values.size() != 3) {
316 316 std::string msg =
317   - "Invalid number of "+gammalib::str(values.size())+" arguments"
318   - " after the \"circle\" key word in provided string \""+line+"\".\n"
  317 + "Invalid number of "+gammalib::str(values.size())+" arguments "
  318 + "after the \"circle\" key word in provided string \""+line+"\". "
319 319 "Exactly 3 arguments are expected.";
320 320 throw GException::invalid_value(G_READ, msg);
321 321 }
... ... @@ -343,10 +343,9 @@ void GSkyRegionCircle::read(const std::string&amp; line)
343 343 }
344 344 else {
345 345 std::string msg =
346   - "Unsupported coordinate system \""+system+"\" in provided string"
347   - " \""+line+"\".\n"
348   - "Only the following coordinate systems are supported: "
349   - "\"fk5\", \"icrs\" and \"galactic\".";
  346 + "Unsupported coordinate system \""+system+"\" in provided string "
  347 + "\""+line+"\". Only the following coordinate systems are "
  348 + "supported: \"fk5\", \"icrs\" and \"galactic\".";
350 349 throw GException::invalid_value(G_READ, msg);
351 350 }
352 351  
... ... @@ -479,11 +478,11 @@ std::string GSkyRegionCircle::print(const GChatter&amp; chatter) const
479 478  
480 479 // Append sky circle information
481 480 result.append("\n"+gammalib::parformat("Right Ascension of centre"));
482   - result.append(gammalib::str(m_centre.ra_deg())+" deg");
  481 + result.append(gammalib::str(ra())+" deg");
483 482 result.append("\n"+gammalib::parformat("Declination of centre"));
484   - result.append(gammalib::str(m_centre.dec_deg())+" deg");
  483 + result.append(gammalib::str(dec())+" deg");
485 484 result.append("\n"+gammalib::parformat("Radius"));
486   - result.append(gammalib::str(m_radius)+" deg");
  485 + result.append(gammalib::str(radius())+" deg");
487 486  
488 487 } // endif: chatter was not silent
489 488  
... ... @@ -539,9 +538,6 @@ bool GSkyRegionCircle::contains(const GSkyRegion&amp; reg) const
539 538 // Calculate angular distance between the centres
540 539 double ang_dist = m_centre.dist_deg(regcirc->centre());
541 540  
542   - // Calculate angular distance between the centres
543   - double ang_dist = m_centre.dist_deg(regcirc->centre());
544   -
545 541 // Check if the region is contained in this
546 542 if ((ang_dist + regcirc->radius()) <= m_radius) {
547 543 fully_inside = true;
... ... @@ -557,16 +553,16 @@ bool GSkyRegionCircle::contains(const GSkyRegion&amp; reg) const
557 553 dynamic_cast<const GSkyRegionRect*>(&reg);
558 554  
559 555 // Check containment of all edges
560   - fully_inside = contains(regrect->get_corner(0)) &
561   - contains(regrect->get_corner(1)) &
562   - contains(regrect->get_corner(2)) &
  556 + fully_inside = contains(regrect->get_corner(0)) &&
  557 + contains(regrect->get_corner(1)) &&
  558 + contains(regrect->get_corner(2)) &&
563 559 contains(regrect->get_corner(3));
564 560 }
565 561  
566 562 // ... otherwise throw an exception
567 563 else {
568 564 throw GException::feature_not_implemented(G_CONTAINS,
569   - "Cannot compare to region type \""+reg.type()+"\" yet");
  565 + "Cannot compare to region type \""+reg.type()+"\" yet.");
570 566 }
571 567  
572 568 // Return value
... ... @@ -581,13 +577,16 @@ bool GSkyRegionCircle::contains(const GSkyRegion&amp; reg) const
581 577 *
582 578 * @exception GException::feature_not_implemented
583 579 * Regions differ in type.
  580 + *
  581 + * @todo Implement checks for rectangles and maps
584 582 ***************************************************************************/
585 583 bool GSkyRegionCircle::overlaps(const GSkyRegion& reg) const
586 584 {
587 585 // Initialise return value
588 586 bool overlap = false;
589 587  
590   - // If other region is circle use a simple way to calculate
  588 + // If region is circle then check overlap by comparing the centre
  589 + // distances
591 590 if (reg.type() == "Circle") {
592 591  
593 592 // Create circular region from reg
... ... @@ -602,12 +601,36 @@ bool GSkyRegionCircle::overlaps(const GSkyRegion&amp; reg) const
602 601 overlap = true;
603 602 }
604 603  
605   - }
  604 + } // endif: region was circle
  605 +
  606 + // ... otherwise if region is rectangle then check overlap
  607 + else if (reg.type() == "Rect") {
  608 +
  609 + // Create rectangular region from reg
  610 + const GSkyRegionRect* regrect =
  611 + dynamic_cast<const GSkyRegionRect*>(&reg);
  612 +
  613 + // Check overlap with circle
  614 + overlap = regrect->overlaps(*this);
  615 +
  616 + } // endif: region was rectangle
  617 +
  618 + // ... otherwise if region is map then check overlap with map
  619 + else if (reg.type() == "Map") {
  620 +
  621 + // Create map from reg
  622 + const GSkyRegionMap* regmap =
  623 + dynamic_cast<const GSkyRegionMap*>(&reg);
  624 +
  625 + // Check overlap with circle
  626 + overlap = regmap->overlaps(*this);
  627 +
  628 + } // endif: region was map
606 629  
607 630 // ... otherwise throw an exception
608 631 else {
609   - throw GException::feature_not_implemented(G_OVERLAPS,
610   - "Cannot compare two different region types yet");
  632 + throw GException::feature_not_implemented(G_CONTAINS,
  633 + "Cannot compare to region type \""+reg.type()+"\" yet.");
611 634 }
612 635  
613 636 // Return value
... ...
src/sky/GSkyRegionRect.cpp
... ... @@ -28,7 +28,6 @@
28 28 #ifdef HAVE_CONFIG_H
29 29 #include <config.h>
30 30 #endif
31   -//#include "GMath.hpp"
32 31 #include "GTools.hpp"
33 32 #include "GSkyRegionCircle.hpp"
34 33 #include "GSkyRegionRect.hpp"
... ... @@ -598,8 +597,7 @@ bool GSkyRegionRect::contains(const GSkyRegion&amp; reg) const
598 597 // ... otherwise throw an exception
599 598 else {
600 599 throw GException::feature_not_implemented(G_CONTAINS,
601   - "Cannot compare rectangular region with other than rectangle or"
602   - " circle yet.");
  600 + "Cannot compare to region type \""+reg.type()+"\" yet.");
603 601 }
604 602  
605 603 // Return value
... ... @@ -615,14 +613,15 @@ bool GSkyRegionRect::contains(const GSkyRegion&amp; reg) const
615 613 * @exception GException::feature_not_implemented
616 614 * Regions differ in type.
617 615 *
618   - * @todo: - Improve implementation for rectangle-rectangle
  616 + * @todo Improve implementation for rectangle-rectangle
  617 + * @todo Implement check for map
619 618 ***************************************************************************/
620 619 bool GSkyRegionRect::overlaps(const GSkyRegion& reg) const
621 620 {
622 621 // Initialise return value
623   - bool is_overlapping = false;
  622 + bool overlap = false;
624 623  
625   - // If other region is circle use a simple way to calculate
  624 + // If region is circle then check overlap between circle and rectangle
626 625 if (reg.type() == "Circle") {
627 626  
628 627 // Create circular region from reg
... ... @@ -641,33 +640,46 @@ bool GSkyRegionRect::overlaps(const GSkyRegion&amp; reg) const
641 640 // Check extension of circle along right ascension axis
642 641 if (std::abs(local_centre.ra_deg()) <= (0.5 * m_width + circ_rad)) {
643 642  
644   - // Circle is fully contained in this rectangle
645   - is_overlapping = true;
  643 + // Circle is overlapping with rectangle
  644 + overlap = true;
646 645 }
647 646 }
648   - } // Region was of type "Circle"
  647 + } // endif: region was of type "Circle"
649 648  
  649 + // ... otherwise if region is a rectangle then check overlap between
  650 + // two rectangles
650 651 else if (reg.type() == "Rect") {
651 652  
652 653 // Create rectangular region from reg
653 654 const GSkyRegionRect* regrect =
654 655 dynamic_cast<const GSkyRegionRect*>(&reg);
655 656  
656   - // Dirty kludge: compare vs map
  657 + // Dirty kludge: compare with map
657 658 GSkyRegionMap regmap = GSkyRegionMap(regrect);
658   - is_overlapping = regmap.overlaps(*this);
  659 + overlap = regmap.overlaps(*this);
659 660  
660   - } // Region was of type "Rect"
  661 + } // endif: region was of type "Rect"
  662 +
  663 + // ... otherwise if region is map then check overlap with map
  664 + else if (reg.type() == "Map") {
  665 +
  666 + // Create map from reg
  667 + const GSkyRegionMap* regmap =
  668 + dynamic_cast<const GSkyRegionMap*>(&reg);
  669 +
  670 + // Check overlap with circle
  671 + overlap = regmap->overlaps(*this);
  672 +
  673 + } // endif: region was map
661 674  
662 675 // ... otherwise throw an exception
663 676 else {
664   - throw GException::feature_not_implemented(G_OVERLAPS,
665   - "Cannot compare rectangular region with other than rectangle or"
666   - " circle yet.");
  677 + throw GException::feature_not_implemented(G_CONTAINS,
  678 + "Cannot compare to region type \""+reg.type()+"\" yet.");
667 679 }
668 680  
669 681 // Return value
670   - return is_overlapping;
  682 + return overlap;
671 683 }
672 684  
673 685  
... ...
src/sky/GSkyRegions.cpp
1 1 /***************************************************************************
2 2 * GSkyRegions.cpp - Sky region container class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2013-2018 by Pierrick Martin *
  4 + * copyright (C) 2013-2020 by Pierrick Martin *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -536,7 +536,7 @@ void GSkyRegions::load(const GFilename&amp; filename)
536 536 coordsys = "icrs";
537 537 }
538 538  
539   - // If region is a circle
  539 + // If region is a circle then read circle
540 540 if (std::string::npos != fileline.find("circle")) {
541 541  
542 542 // Create instance of GSkyRegion object
... ... @@ -558,32 +558,14 @@ void GSkyRegions::load(const GFilename&amp; filename)
558 558 region.read(newfileline);
559 559 append(region);
560 560 }
561   - }
562 561  
563   - // If region is a rectangle
564   - if (std::string::npos != fileline.find("box")) {
  562 + } // endif: region was circle
565 563  
566   - // Create instance of GSkyRegion object
567   - GSkyRegionRect region;
568   -
569   - // If coordinate system and region defined on the same line
570   - if ((std::string::npos != fileline.find("fk5")) ||
571   - (std::string::npos != fileline.find("icrs")) ||
572   - (std::string::npos != fileline.find("galactic"))) {
573   - region.read(fileline);
574   - append(region);
575   - }
576   -
577   - // else, prepend the coordinate system
578   - else {
579   - coordsys = "icrs";
580   - }
581   -
582   - // If region is a circle
583   - if (std::string::npos != fileline.find("circle")) {
  564 + // ... otherwise if region is a box then read rectangle
  565 + else if (std::string::npos != fileline.find("box")) {
584 566  
585 567 // Create instance of GSkyRegion object
586   - GSkyRegionCircle region;
  568 + GSkyRegionRect region;
587 569  
588 570 // If coordinate system and region defined on the same line
589 571 if ((std::string::npos != fileline.find("fk5")) ||
... ... @@ -601,8 +583,10 @@ void GSkyRegions::load(const GFilename&amp; filename)
601 583 region.read(newfileline);
602 584 append(region);
603 585 }
604   - }
605   - }
  586 +
  587 + } // endif: region was box
  588 +
  589 + } // endwhile: looped over file
606 590  
607 591 // Close file
608 592 ds9file.close();
... ...
test/test_GSky.cpp
... ... @@ -1913,7 +1913,7 @@ void TestGSky::test_GSkyRegionRect(void)
1913 1913 test_try("Test posang assignment after");
1914 1914 try {
1915 1915 GSkyRegionRect rect(refdir_radeczerozero, ref_width, ref_height, ref_pa_deg);
1916   - rect.posang_deg(-1.0);
  1916 + rect.posang(-1.0);
1917 1917 test_try_success();
1918 1918 }
1919 1919 catch (GException::invalid_argument &e) {
... ... @@ -1932,7 +1932,7 @@ void TestGSky::test_GSkyRegionRect(void)
1932 1932 double check_height = rect.width();
1933 1933 test_value(ref_height, check_height, 1.0e-10, "Test height assignment");
1934 1934  
1935   - double check_pa_deg = rect.posang_deg();
  1935 + double check_pa_deg = rect.posang();
1936 1936 test_value(ref_pa_deg, check_pa_deg, 1.0e-10, "Test posang assignment");
1937 1937  
1938 1938 // Check solid angle assignment
... ... @@ -1941,7 +1941,7 @@ void TestGSky::test_GSkyRegionRect(void)
1941 1941 test_value(solidangle_check, solidangle, 1.0e-10, "Test solid angle");
1942 1942  
1943 1943 // Initialise objects
1944   - GSkyDir refdir_radeczerozero = GSkyDir();
  1944 + refdir_radeczerozero = GSkyDir();
1945 1945 GSkyDir test_dir_0 = GSkyDir();
1946 1946 GSkyDir test_dir_1 = GSkyDir();
1947 1947 GSkyDir test_dir_2 = GSkyDir();
... ... @@ -2050,7 +2050,6 @@ void TestGSky::test_GSkyRegionRect(void)
2050 2050 test_assert(refregion.overlaps(refregion_raoffset),"test3 for overlap");
2051 2051 test_assert(!refregion.overlaps(refregion_decpole),"test4 for overlap");
2052 2052  
2053   -
2054 2053 // Exit test
2055 2054 return;
2056 2055 }
... ...