HOPS
HOPS class reference
MHO_SelectRepack.hh
Go to the documentation of this file.
1 #ifndef MHO_SelectRepack_HH__
2 #define MHO_SelectRepack_HH__
3 
4 #include <map>
5 #include <vector>
6 
7 #include "MHO_NDArrayWrapper.hh"
8 #include "MHO_UnaryOperator.hh"
9 
11 
12 namespace hops
13 {
14 
29 template< class XArgType > class MHO_SelectRepack: public MHO_UnaryOperator< XArgType >
30 {
31  public:
33  {
34  fInitialized = false;
35  fAxisSelectionMap.clear();
36  };
37 
38  virtual ~MHO_SelectRepack(){};
39 
43  void Reset() { fAxisSelectionMap.clear(); }
44 
51  void SelectAxisItems(std::size_t axis_index, const std::vector< std::size_t >& valid_indexes)
52  {
53  fAxisSelectionMap[axis_index] = valid_indexes;
54  //sort to make sure the selected elements are given in increasing order
55  std::sort(fAxisSelectionMap[axis_index].begin(), fAxisSelectionMap[axis_index].end());
56  fInitialized = false;
57  }
58 
59  protected:
67  virtual bool InitializeInPlace(XArgType* in) override { return InitializeOutOfPlace(in, &fWorkspace); }
68 
76  virtual bool ExecuteInPlace(XArgType* in) override
77  {
78  bool status = ExecuteOutOfPlace(in, &fWorkspace);
79  //"in-place" execution requires a copy from the workspace back to the object we are modifying
80  in->Copy(fWorkspace);
81  return status;
82  }
83 
92  virtual bool InitializeOutOfPlace(const XArgType* in, XArgType* out) override
93  {
94  if(in != nullptr && out != nullptr)
95  {
96  std::array< std::size_t, XArgType::rank::value > out_dim = DetermineOutputDimensions(in);
97  ConditionallyResizeOutput(out_dim, out);
98  fInitialized = true;
99  return true;
100  }
101  else
102  {
103  fInitialized = false;
104  return false;
105  }
106  }
107 
116  virtual bool ExecuteOutOfPlace(const XArgType* in, XArgType* out) override
117  {
118  if(fInitialized)
119  {
120  std::array< std::size_t, XArgType::rank::value > out_dim;
121  std::array< std::size_t, XArgType::rank::value > out_loc;
122  std::array< std::size_t, XArgType::rank::value > in_loc;
123 
124  out->GetDimensions(&(out_dim[0]));
125  std::size_t total_size = out->GetSize();
126 
127  if(fAxisSelectionMap.size() == 0)
128  {
129  //no axis has indices specified, so by default all data is selected
130  out->Copy(*in);
131  }
132  else if(fAxisSelectionMap.size() == XArgType::rank::value)
133  {
134  //all axes have data selected that we need to extract
135  for(std::size_t i = 0; i < total_size; i++)
136  {
137  //compute the indexes into the 'out' array
138  MHO_NDArrayMath::RowMajorIndexFromOffset< XArgType::rank::value >(i, &(out_dim[0]), &(out_loc[0]));
139 
140  //compute the indexes into the 'in' array, remapping where needed
141  //from the selections
142  for(std::size_t a = 0; a < XArgType::rank::value; a++)
143  {
144  in_loc[a] = (fAxisSelectionMap[a])[out_loc[a]];
145  out->ValueAt(out_loc) = in->ValueAt(in_loc);
146  }
147  }
148  IfTableSelectOnAxes(in, out);
149  }
150  else
151  {
152  //some axes have data selected, and some do not (meaning all is passed)
153  //so we need to sort through the mess
154  for(std::size_t i = 0; i < total_size; i++)
155  {
156  //compute the indexes into the 'out' array
157  MHO_NDArrayMath::RowMajorIndexFromOffset< XArgType::rank::value >(i, &(out_dim[0]), &(out_loc[0]));
158 
159  //compute the indexes into the 'in' array, remapping where needed
160  //from the selections
161  for(std::size_t a = 0; a < XArgType::rank::value; a++)
162  {
163  if(fAxisSelectionMap.count(a) == 0)
164  {
165  in_loc[a] = out_loc[a];
166  }
167  else
168  {
169  in_loc[a] = (fAxisSelectionMap[a])[out_loc[a]];
170  }
171  }
172  out->ValueAt(out_loc) = in->ValueAt(in_loc);
173  }
174  }
175 
176  IfTableSelectOnAxes(in, out);
177 
178  return true;
179  }
180  else
181  {
182  return false;
183  }
184  }
185 
186  private:
193  std::array< std::size_t, XArgType::rank::value > DetermineOutputDimensions(const XArgType* in)
194  {
195  std::array< std::size_t, XArgType::rank::value > out_dim;
196  in->GetDimensions(&(out_dim[0])); //initialize all dimensions to be the same as input
197  for(std::size_t a = 0; a < XArgType::rank::value; a++)
198  {
199  //reduce output dimensions for those axes which have selections
200  if(fAxisSelectionMap.count(a) != 0)
201  {
202  out_dim[a] = fAxisSelectionMap[a].size();
203  }
204  }
205  return out_dim;
206  }
207 
214  void ConditionallyResizeOutput(const std::array< std::size_t, XArgType::rank::value >& dims, XArgType* out)
215  {
216  auto out_dim = out->GetDimensionArray();
217  bool have_to_resize = false;
218  for(std::size_t i = 0; i < XArgType::rank::value; i++)
219  {
220  if(out_dim[i] != dims[i])
221  {
222  have_to_resize = true;
223  }
224  }
225  if(have_to_resize)
226  {
227  out->Resize(&(dims[0]));
228  }
229  }
230 
231  //default...does nothing
239  template< typename XCheckType = XArgType >
240  typename std::enable_if< !std::is_base_of< MHO_TableContainerBase, XCheckType >::value, void >::type
241  IfTableSelectOnAxes(const XArgType* , XArgType* ){};
242 
243  //use SFINAE to generate specialization for MHO_TableContainer types
251  template< typename XCheckType = XArgType >
252  typename std::enable_if< std::is_base_of< MHO_TableContainerBase, XCheckType >::value, void >::type
253  IfTableSelectOnAxes(const XArgType* in, XArgType* out)
254  {
255  for(std::size_t a = 0; a < XArgType::rank::value; a++) //apply to all axes
256  {
257  SelectOnAxis axis_sub_sampler(fAxisSelectionMap[a]);
258  apply_at2< typename XArgType::axis_pack_tuple_type, SelectOnAxis >(*in, *out, a, axis_sub_sampler);
259  }
260  out->CopyTags(*in); //make sure the table tags get copied
261  }
262 
266  class SelectOnAxis
267  {
268  public:
269  SelectOnAxis(std::vector< std::size_t > selection): fSelection(selection){};
270  ~SelectOnAxis(){};
271 
272  template< typename XAxisType > void operator()(const XAxisType& axis1, XAxisType& axis2)
273  {
274  if(fSelection.size() != 0)
275  {
276  //copy all of the axis meta data
277  axis2.CopyTags(axis1);
278  //then remove the index labels
279  axis2.ClearIndexLabels();
280  //now copy back the selected index labels
281  for(std::size_t i = 0; i < fSelection.size(); i++)
282  {
283  axis2(i) = axis1(fSelection[i]);
284  mho_json obj = axis1.GetLabelObject(fSelection[i]);
285  axis2.SetLabelObject(obj, i);
286  }
287 
288  TODO_FIXME_MSG("TODO FIXME -- ensure that only the proper interval tags are selected/copied here.")
289  //axis2.ClearIntervalLabels();
290  //it doesn't make sense to copy the original interval labels since we have changed the organization of this axis
291  //what ought to do is figure out the overlap between previous interval labels and items of the new axis
292  //and create new overlapping intervals with the appropriate tags.
293  }
294  else
295  {
296  axis2.Copy(axis1); //no selection done on this axis, just copy everything
297  }
298  }
299 
300  private:
301  std::vector< std::size_t > fSelection;
302  };
303 
304  bool fInitialized;
305  XArgType fWorkspace;
306 
307  //map which holds the indexes selected from each axis
308  //if no item is present for a particular axis, the assumption is that all pre-existing
309  //elements are selected/passed in the selection process
310  std::map< std::size_t, std::vector< std::size_t > > fAxisSelectionMap;
311 };
312 
313 }; // namespace hops
314 
315 #endif
nlohmann::json mho_json
Definition: MHO_JSONHeaderWrapper.hh:5
#define TODO_FIXME_MSG(x)
Definition: MHO_Message.hh:35
Class MHO_SelectRepack.
Definition: MHO_SelectRepack.hh:30
virtual bool ExecuteOutOfPlace(const XArgType *in, XArgType *out) override
Function ExecuteOutOfPlace.
Definition: MHO_SelectRepack.hh:116
virtual ~MHO_SelectRepack()
Definition: MHO_SelectRepack.hh:38
virtual bool ExecuteInPlace(XArgType *in) override
Executes operation in-place by calling ExecuteOutOfPlace and copying result back to input.
Definition: MHO_SelectRepack.hh:76
virtual bool InitializeInPlace(XArgType *in) override
Initializes in-place by calling InitializeOutOfPlace with workspace.
Definition: MHO_SelectRepack.hh:67
virtual bool InitializeOutOfPlace(const XArgType *in, XArgType *out) override
Initializes out-of-place processing for given input and output arguments.
Definition: MHO_SelectRepack.hh:92
void SelectAxisItems(std::size_t axis_index, const std::vector< std::size_t > &valid_indexes)
Stores valid indexes for a given axis and marks selection as uninitialized.
Definition: MHO_SelectRepack.hh:51
MHO_SelectRepack()
Definition: MHO_SelectRepack.hh:32
void Reset()
Clears all entries from fAxisSelectionMap.
Definition: MHO_SelectRepack.hh:43
Class MHO_UnaryOperator.
Definition: MHO_UnaryOperator.hh:24
struct type_status status
Definition: fourfit3.c:53
Definition: MHO_ChannelLabeler.hh:17