Alexandria  2.18
Please provide a description of the project.
serialize.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2021 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  * @file serialize.h
21  * @author nikoapos
22  */
23 
24 #ifndef SOM_SERIALIZE_H
25 #define SOM_SERIALIZE_H
26 
28 #include "SOM/Distance.h"
29 #include "SOM/serialization/SOM.h"
30 #include <CCfits/CCfits>
31 #include <boost/archive/binary_iarchive.hpp>
32 #include <boost/archive/binary_oarchive.hpp>
33 #include <iostream>
34 
35 namespace Euclid {
36 namespace SOM {
37 
38 template <typename OArchive, std::size_t ND, typename DistFunc>
39 void somExport(std::ostream& out, const SOM<ND, DistFunc>& som) {
40  // Do NOT delete this pointer!!! It points to the actual som
41  const SOM<ND, DistFunc>* ptr = &som;
42  OArchive boa{out};
43  boa << ptr;
44 }
45 
46 template <std::size_t ND, typename DistFunc>
48  somExport<boost::archive::binary_oarchive>(out, som);
49 }
50 
51 template <typename IArchive, std::size_t ND, typename DistFunc = Distance::L2<ND>>
53  IArchive bia{in};
54  // Do NOT delete manually this pointer. It is wrapped with a unique_ptr later.
55  SOM<ND, DistFunc>* ptr;
56  bia >> ptr;
57  std::unique_ptr<SOM<ND, DistFunc>> smart_ptr{ptr};
58  // We move out to the result the som pointed by the pointer. The unique_ptr
59  // will delete the (now empty) pointed object
60  return std::move(*smart_ptr);
61 }
62 
63 template <std::size_t ND, typename DistFunc = Distance::L2<ND>>
65  return somImport<boost::archive::binary_iarchive, ND, DistFunc>(in);
66 }
67 
68 template <std::size_t ND, typename DistFunc>
69 void somFitsExport(const std::string& filename, const SOM<ND, DistFunc>& som) {
70 
71  // Create the output file and the array HDU
72  int n_axes = 3;
73  std::size_t x;
74  std::size_t y;
75  std::tie(x, y) = som.getSize();
76  long ax_sizes[3] = {(long)x, (long)y, (long)ND};
77  CCfits::FITS fits(filename, DOUBLE_IMG, n_axes, ax_sizes);
78 
79  // Write in the header the DistFunc type
80  fits.pHDU().addKey("DISTFUNC", typeid(DistFunc).name(), "");
81 
82  // Create a valarray with the SOM data
83  std::size_t total_size = x * y * ND;
84  std::valarray<double> data(total_size);
85  int i = 0;
86  for (std::size_t w_i = 0; w_i < ND; ++w_i) {
87  for (auto& w_arr : som) {
88  data[i] = w_arr[w_i];
89  ++i;
90  }
91  }
92  fits.pHDU().write(1, total_size, data);
93 }
94 
95 template <std::size_t ND, typename DistFunc = Distance::L2<ND>>
97 
98  CCfits::FITS fits(filename, CCfits::Read);
99 
100  // Check that the type of the DistFunc is correct
101  std::string dist_func_type;
102  fits.pHDU().readKey("DISTFUNC", dist_func_type);
103  if (dist_func_type != typeid(DistFunc).name()) {
104  throw Elements::Exception() << "Incompatible DistFunc parameter. File contains SOM with " << dist_func_type
105  << " and is read as " << typeid(DistFunc).name();
106  }
107 
108  // Get the dimensions of the data in the file
109  if (fits.pHDU().axes() != 3) {
110  throw Elements::Exception() << "Data array in file " << filename << " does not have 3 dimensions";
111  }
112  if (fits.pHDU().axis(2) != ND) {
113  throw Elements::Exception() << "Weights dimension of array in file " << filename << " should have size " << ND << " but was "
114  << fits.pHDU().axis(2);
115  }
116  std::size_t x = fits.pHDU().axis(0);
117  std::size_t y = fits.pHDU().axis(1);
118 
119  // Read the data from the file
121  fits.pHDU().read(data);
122 
123  // Copy the data in a SOM object
124  SOM<ND, DistFunc> result{x, y};
125  int i = 0;
126  for (std::size_t w_i = 0; w_i < ND; ++w_i) {
127  for (auto& w_arr : result) {
128  w_arr[w_i] = data[i];
129  ++i;
130  }
131  }
132 
133  return std::move(result);
134 }
135 
136 } // namespace SOM
137 } // namespace Euclid
138 
139 #endif /* SOM_SERIALIZE_H */
Euclid::SOM::somBinaryExport
void somBinaryExport(std::ostream &out, const SOM< ND, DistFunc > &som)
Definition: serialize.h:47
std::string
STL class.
std::move
T move(T... args)
Distance.h
std::tie
T tie(T... args)
std::ostream
STL class.
SOM.h
Exception.h
Euclid::SOM::somExport
void somExport(std::ostream &out, const SOM< ND, DistFunc > &som)
Definition: serialize.h:39
Euclid::SOM::SOM
Definition: SOM.h:46
std::valarray
STL class.
Elements::Exception
Euclid::SOM::somFitsImport
SOM< ND, DistFunc > somFitsImport(const std::string &filename)
Definition: serialize.h:96
std::size_t
Euclid::SOM::somFitsExport
void somFitsExport(const std::string &filename, const SOM< ND, DistFunc > &som)
Definition: serialize.h:69
Euclid::SOM::somBinaryImport
SOM< ND, DistFunc > somBinaryImport(std::istream &in)
Definition: serialize.h:64
Euclid::SOM::somImport
SOM< ND, DistFunc > somImport(std::istream &in)
Definition: serialize.h:52
std::istream
STL class.
std::unique_ptr
STL class.
Euclid
Definition: InstOrRefHolder.h:29