Alexandria  2.16
Please provide a description of the project.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FitsSerialize.icpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2020 Euclid Science Ground Segment
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License as published by the Free
6  * Software Foundation; either version 3.0 of the License, or (at your option)
7  * 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 FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 
20 /*
21  * @file FitsSerialize.icpp
22  * @author nikoapos
23  */
24 
25 #include <valarray>
26 #include <type_traits>
27 #include <boost/filesystem.hpp>
28 #include <CCfits/CCfits>
30 #include "Table/Table.h"
31 #include "Table/FitsWriter.h"
33 #include "GridConstructionHelper.h"
34 
35 namespace Euclid {
36 namespace GridContainer {
37 
38 template <typename T>
40  static_assert(!std::is_same<T,T>::value, "FITS arrays of type T are not supported");
41 };
42 
43 template <>
44 struct FitsBpixTraits<std::int8_t> {
45  static constexpr int BPIX = BYTE_IMG;
46 };
47 
48 template <>
49 struct FitsBpixTraits<std::int16_t> {
50  static constexpr int BPIX = SHORT_IMG;
51 };
52 
53 template <>
54 struct FitsBpixTraits<std::int32_t> {
55  static constexpr int BPIX = LONG_IMG;
56 };
57 
58 template <>
59 struct FitsBpixTraits<std::int64_t> {
60  static constexpr int BPIX = LONGLONG_IMG;
61 };
62 
63 template <>
64 struct FitsBpixTraits<float> {
65  static constexpr int BPIX = FLOAT_IMG;
66 };
67 
68 template <>
69 struct FitsBpixTraits<double> {
70  static constexpr int BPIX = DOUBLE_IMG;
71 };
72 
73 template<typename T>
75  using FitsType = T;
76  static FitsType axisToFits(const T& value) {
77  return value;
78  }
79  static T FitsToAxis(const FitsType& value) {
80  return value;
81  }
82 };
83 
84 template<>
85 struct GridAxisValueFitsHelper<XYDataset::QualifiedName> {
88  return value.qualifiedName();
89  }
91  return value;
92  }
93 };
94 
95 template<typename... AxesTypes>
97 
98  template<int I>
99  static void addGridAxesToFitsFile(const boost::filesystem::path& filename,
100  const std::string& array_hdu_name,
101  const std::tuple<GridAxis<AxesTypes>...>& axes_tuple,
102  const TemplateLoopCounter<I>&) {
103  addGridAxesToFitsFile(filename, array_hdu_name, axes_tuple, TemplateLoopCounter<I-1>{});
104 
105  auto& axis = std::get<I-1>(axes_tuple);
107  using FitsType = typename GridAxisValueFitsHelper<AxisType>::FitsType;
108 
110  Table::ColumnInfo::info_type {"Index", typeid(int32_t)},
111  Table::ColumnInfo::info_type {"Value", typeid(FitsType)}
112  };
113  std::shared_ptr<Table::ColumnInfo> column_info {new Table::ColumnInfo {std::move(info_list)}};
114 
115  std::vector<Table::Row> row_list {};
116  for (size_t i=0; i<axis.size(); ++i) {
117  auto fits_value = GridAxisValueFitsHelper<AxisType>::axisToFits(axis[i]);
118  row_list.push_back(Table::Row{{(int)i, fits_value}, column_info});
119  }
120  Table::Table table {row_list};
121 
122  Table::FitsWriter{filename.string(), false}
124  .setHduName(axis.name()+"_"+array_hdu_name)
125  .addData(table);
126  }
127 
128  static void addGridAxesToFitsFile(const boost::filesystem::path&,
129  const std::string&,
130  const std::tuple<GridAxis<AxesTypes>...>&,
131  const TemplateLoopCounter<0>&) {
132  }
133 
134 };
135 
136 template<typename GridCellManager, typename... AxesTypes>
137 void gridFitsExport(const boost::filesystem::path& filename,
138  const std::string& hdu_name,
140  auto& axes = grid.getAxesTuple();
141 
142  // Create the first HDU with the array. We do that in a scope so the file is
143  // created and the data are flushed into it before we continue.
144  {
145  CCfits::FITS fits (filename.string(), CCfits::Write);
146 
148  axes, TemplateLoopCounter<sizeof...(AxesTypes)>{});
149  std::vector<long> ext_ax {ext_ax_size_t.begin(), ext_ax_size_t.end()};
150 
151  using cell_type = typename GridCellManagerTraits<GridCellManager>::data_type;
153  fits.addImage(hdu_name, bpix, ext_ax);
154  std::valarray<cell_type> data (grid.size());
155  int i = 0;
156  for (auto value : grid) {
157  data[i] = value;
158  ++i;
159  }
160  fits.currentExtension().write(1, grid.size(), data);
161  }
162 
164  axes, TemplateLoopCounter<sizeof...(AxesTypes)>{});
165 }
166 
167 template <typename GridType>
169 
170  template <int I>
171  using AxisType = typename std::remove_reference<decltype(std::declval<GridType>().template getAxis<I>())>::type;
172 
173  template <int I, typename=void>
174  struct AxesTupleType {
175  using previous = typename AxesTupleType<I-1>::type;
176  using type = decltype(std::tuple_cat(std::declval<previous>(), std::declval<std::tuple<AxisType<I>>>()));
177  };
178 
179  template <int I>
180  struct AxesTupleType<I, typename std::enable_if<I == -1>::type> {
182  };
183 
184  template <int I>
185  using GridAxisType = typename std::remove_reference<decltype(std::declval<GridType>().template getAxis<I>())>::type;
186 
187  template <int I>
188  static GridAxisType<I> readAxis(const std::string& grid_name, CCfits::ExtHDU& hdu) {
189  using KnotType = typename GridAxisType<I>::data_type;
190  using FitsType = typename GridAxisValueFitsHelper<KnotType>::FitsType;
191 
192  auto axis_name = hdu.name().substr(0, hdu.name().size() - grid_name.size() - 1);
193  std::vector<FitsType> data {};
194  try {
195  auto& column = hdu.column("Value");
196  column.read(data, 1, column.rows());
197  } catch (CCfits::FitsException e) {
198  throw Elements::Exception() << e.message();
199  }
200  std::vector<KnotType> knots {};
201  for (std::size_t i = 0; i < data.size(); ++i) {
203  }
204  return {std::move(axis_name), std::move(knots)};
205  }
206 
207  template <int I>
208  static typename AxesTupleType<I>::type readAxesTuple(CCfits::FITS& fits, const std::string& grid_name, int hdu_index, const TemplateLoopCounter<I>&) {
209  auto axis = readAxis<I>(grid_name, fits.extension(hdu_index));
210  auto previous = readAxesTuple(fits, grid_name, hdu_index-1, TemplateLoopCounter<I-1>{});
211  return std::tuple_cat(std::move(previous), std::tuple<decltype(axis)>{std::move(axis)});
212  }
213 
214  static std::tuple<> readAxesTuple(CCfits::FITS&, const std::string&, int, const TemplateLoopCounter<-1>&) {
215  return {};
216  }
217 
218 public:
219 
220  static typename AxesTupleType<GridType::axisNumber()-1>::type readAllAxes(CCfits::FITS& fits, int hdu_index) {
221  auto name = fits.extension(hdu_index).name();
222  return readAxesTuple(fits, name, hdu_index + GridType::axisNumber(), TemplateLoopCounter<GridType::axisNumber()-1>{});
223  }
224 
225 };
226 
227 template<typename GridType>
228 GridType gridFitsImport(const boost::filesystem::path& filename, int hdu_index) {
229  CCfits::FITS fits (filename.string(), CCfits::Read);
230 
231  auto axes = GridAxisFitsReader<GridType>::readAllAxes(fits, hdu_index);
232 
233  GridType grid {std::move(axes)};
234 
236  fits.extension(hdu_index).read(data);
237 
238  int i = 0;
239  for (auto iter = grid.begin(); iter != grid.end(); ++iter, ++i) {
240  *iter = data[i];
241  }
242 
243  return grid;
244 }
245 
246 } // end of namespace GridContainer
247 } // end of namespace Euclid
FitsWriter & setFormat(Format format)
Set the FITS table format.
Definition: FitsWriter.cpp:41
size_t size() const
Returns the total number of cells of the grid.
const std::string & qualifiedName() const
Returns the qualified name as a string.
FITS binary table HDU format.
const std::tuple< GridAxis< AxesTypes >...> & getAxesTuple() const
Returns a tuple containing the information of all the grid axes.
static void addGridAxesToFitsFile(const boost::filesystem::path &, const std::string &, const std::tuple< GridAxis< AxesTypes >...> &, const TemplateLoopCounter< 0 > &)
static FitsType axisToFits(const T &value)
constexpr double e
static void addGridAxesToFitsFile(const boost::filesystem::path &filename, const std::string &array_hdu_name, const std::tuple< GridAxis< AxesTypes >...> &axes_tuple, const TemplateLoopCounter< I > &)
static XYDataset::QualifiedName FitsToAxis(const FitsType &value)
TableWriter implementation for writing tables in FITS format.
Definition: FitsWriter.h:76
STL class.
typename std::remove_reference< decltype(std::declval< GridType >().template getAxis< I >())>::type AxisType
decltype(std::tuple_cat(std::declval< previous >(), std::declval< std::tuple< AxisType< I >>>())) type
typename std::remove_reference< decltype(std::declval< GridType >().template getAxis< I >())>::type GridAxisType
FitsWriter & setHduName(const std::string &name)
Set the HDU name where the table is written.
Definition: FitsWriter.cpp:50
Provides information related with an axis of a GridContainer.
Definition: GridAxis.h:49
void gridFitsExport(const boost::filesystem::path &filename, const std::string &hdu_name, const GridContainer< GridCellManager, AxesTypes...> &grid)
Exports a Grid as a FITS file.
STL class.
T declval(T...args)
T move(T...args)
static AxesTupleType< GridType::axisNumber()-1 >::type readAllAxes(CCfits::FITS &fits, int hdu_index)
static std::vector< size_t > createAxesSizesVector(const std::tuple< GridAxis< Axes >...> &axes, const TemplateLoopCounter< I > &)
Creates a vector which contains the sizes of the given axes.
Represents one row of a Table.
Definition: Row.h:64
Represents a table.
Definition: Table.h:49
static GridAxisType< I > readAxis(const std::string &grid_name, CCfits::ExtHDU &hdu)
T tuple_cat(T...args)
T size(T...args)
STL class.
Provides information about the columns of a Table.
Definition: ColumnInfo.h:52
T begin(T...args)
static std::tuple readAxesTuple(CCfits::FITS &, const std::string &, int, const TemplateLoopCounter<-1 > &)
GridCellManager::data_type data_type
The type of the data kept by the GridCellManager.
Represents a name qualified with a set of groups.
Definition: QualifiedName.h:66
GridType gridFitsImport(const boost::filesystem::path &filename, int hdu_index)
Imports a Grid from a FITS file.
Contains the description of a specific column of a Table.
static FitsType axisToFits(const XYDataset::QualifiedName &value)
static T FitsToAxis(const FitsType &value)
T emplace_back(T...args)
static AxesTupleType< I >::type readAxesTuple(CCfits::FITS &fits, const std::string &grid_name, int hdu_index, const TemplateLoopCounter< I > &)