From e9e6a485534038653c6a4ef0b922eff3f19b8870 Mon Sep 17 00:00:00 2001
From: Robert Butora <robert.butora@inaf.it>
Date: Thu, 5 Sep 2024 12:49:18 +0300
Subject: [PATCH] vlkb: implements headerwcs which lists WCS-coords related
 keys

---
 .../engine/src/common/include/fitsfiles.hpp   |  1 +
 .../engine/src/common/src/fitsfiles.cpp       | 25 +++++++++++
 data-access/engine/src/vlkb/src/main.cpp      | 41 ++++++++++++++++++-
 3 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/data-access/engine/src/common/include/fitsfiles.hpp b/data-access/engine/src/common/include/fitsfiles.hpp
index 500e364..5fc90b0 100644
--- a/data-access/engine/src/common/include/fitsfiles.hpp
+++ b/data-access/engine/src/common/include/fitsfiles.hpp
@@ -55,6 +55,7 @@ namespace fitsfiles
    void        add_cards_if_missing(const std::string pathname, unsigned int hdunum, const std::vector<struct fits_card> cards);
    int         mod_value(std::string filename, std::string token, std::string keyvalue);
 
+   std::map<std::string, std::string> read_header_wcs_coord_type(const std::string pathname, unsigned int hdunum, char altwcs = ' ');
 
    double calc_nullvals(std::string pathname, unsigned int hdunum,
          unsigned long long & null_cnt, unsigned long long & total_cnt);
diff --git a/data-access/engine/src/common/src/fitsfiles.cpp b/data-access/engine/src/common/src/fitsfiles.cpp
index e33e0f3..df4c9d5 100644
--- a/data-access/engine/src/common/src/fitsfiles.cpp
+++ b/data-access/engine/src/common/src/fitsfiles.cpp
@@ -106,6 +106,31 @@ string fitsfiles::read_card(const std::string pathname, unsigned int hdunum, con
 }
 
 
+map<string, string> fitsfiles::read_header_wcs_coord_type(const std::string pathname, unsigned int hdunum, char altwcs)
+{
+   fits::header hdr(pathname, hdunum);
+
+   string alt{ ( altwcs == ' ' ? string{""} : string{altwcs} ) };
+
+   // FIXME does not support alternative calibration (one char at the end of keyname)
+
+   set<string> keys{"SPECSYS" + alt,"SSYSOBS" + alt};
+
+   string keyroot{"CTYPE"};
+   int i=1;
+   string istr{to_string(i)};
+   while( hdr.contains_card( keyroot + istr + alt) )
+   {
+      keys.insert("CTYPE" + istr + alt);
+      keys.insert("CUNIT" + istr + alt);
+      istr = to_string(i++);
+   }
+
+   return hdr.parse_string_cards(keys);
+}
+
+
+
 void fitsfiles::add_cards_if_missing(const std::string pathname, unsigned int hdunum, const std::vector<struct fits_card> cards)
 {
    fits::header hdr(pathname, hdunum, READWRITE);
diff --git a/data-access/engine/src/vlkb/src/main.cpp b/data-access/engine/src/vlkb/src/main.cpp
index cf0c17c..f044a12 100644
--- a/data-access/engine/src/vlkb/src/main.cpp
+++ b/data-access/engine/src/vlkb/src/main.cpp
@@ -43,7 +43,7 @@ namespace vlkb
          << "Usage: " << progname << " <command> [cmd-options] [cmd-args]" << endl
          << "\n where commands are:\n "
          << "\n\t cutout imcopy cutpixels multicutout mergefiles\n"
-         << "\n\t listbounds header headermodif skyvertices overlap\n"
+         << "\n\t listbounds header headermodif headerwcs skyvertices overlap\n"
          << "\n\t nullvals dropdegen checkcard addcard modcard rawdelcard\n"
          << std::endl
          << "Version: " << VERSIONSTR << " " << BUILD << std::endl;
@@ -55,7 +55,8 @@ namespace vlkb
 
    enum cmd_set {
       multicutout, mergefiles, cutout, imcopy, cutpixels,
-      listbounds, header, headermodif, overlap, skyvertices, nullvals, dropdegen, checkcard, addcard, modcard, rawdelcard};
+      listbounds, header, headermodif, headerwcs, overlap, skyvertices,
+      nullvals, dropdegen, checkcard, addcard, modcard, rawdelcard};
 
 
    // from bash or interpreters usually receive params as strings
@@ -72,6 +73,7 @@ namespace vlkb
       else if(cmdstr.compare("listbounds") == 0)   cmd = listbounds;
       else if(cmdstr.compare("header") == 0)       cmd = header;
       else if(cmdstr.compare("headermodif") == 0)  cmd = headermodif;
+      else if(cmdstr.compare("headerwcs") == 0)    cmd = headerwcs;
       else if(cmdstr.compare("overlap") == 0)      cmd = overlap;
       else if(cmdstr.compare("skyvertices") == 0)  cmd = skyvertices;
       else if(cmdstr.compare("nullvals") == 0)     cmd = nullvals;
@@ -320,6 +322,40 @@ int cmd_listbounds(int argc, char * argv[])
    return rc;
 }
 
+int cmd_header_wcs(int argc, char * argv[])
+{
+   int rc;
+
+   if (argc < 2)
+   {
+      std::cerr
+         << "Usage:  header_wcs <pathname.fits>...\n"
+         << "\n"
+         << "Prints current header WCS axes info.\n";
+      rc = EXIT_FAILURE;
+   }
+   else
+   {
+      unsigned int hdunum = 1;
+      char altwcs = ' ';
+
+      for(int i=1; i<argc; i++)
+      {
+         string pathname(argv[i]);
+
+         std::map<std::string, std::string> card_values{fitsfiles::read_header_wcs_coord_type(pathname, hdunum, altwcs)};
+
+         for(auto it = card_values.cbegin(); it != card_values.cend(); ++it)
+         {
+            std::cout << it->first << " " << it->second << ", ";
+         }
+         std::cout << pathname << std::endl;
+      }
+      rc = EXIT_SUCCESS;
+   }
+   return rc;
+}
+
 
 int cmd_header(int argc, char * argv[])
 {
@@ -679,6 +715,7 @@ int main (int argc, char * argv[])
          case vlkb::listbounds:  rc = cmd_listbounds(cmd_argc, cmd_argv); break;
          case vlkb::header:      rc = cmd_header(cmd_argc, cmd_argv); break;
          case vlkb::headermodif: rc = cmd_header_modif(cmd_argc, cmd_argv); break;
+         case vlkb::headerwcs:   rc = cmd_header_wcs(cmd_argc, cmd_argv); break;
          case vlkb::skyvertices: rc = cmd_skyvertices(cmd_argc, cmd_argv); break;
          case vlkb::overlap:     rc = cmd_overlap(cmd_argc, cmd_argv); break;
 
-- 
GitLab