MUQ  0.4.3
H5Object.cpp
Go to the documentation of this file.
2 #include <iostream>
3 
4 using namespace muq::Utilities;
5 
6 void H5Object::DeepCopy(H5Object const& otherObj)
7 {
8  file->Copy(path, otherObj.file, otherObj.path);
9  children = otherObj.children;
10  isDataset = otherObj.isDataset;
11 }
12 
14 {
15  DeepCopy(otherObj);
16  return *this;
17 }
18 
19 void H5Object::ExactCopy(H5Object const& otherObj)
20 {
21  file = otherObj.file;
22  attrs = otherObj.attrs;
23 
24  path = otherObj.path;
25  children = otherObj.children;
26  isDataset = otherObj.isDataset;
27 }
28 
29 H5Object& H5Object::CreatePlaceholder(std::string const& grpName)
30 {
31  auto pathParts = SplitString(grpName);
32 
33  if(pathParts.second.length()==0)
34  {
35  children[pathParts.first].ExactCopy( H5Object(file, path+grpName, true) );
36  return children[pathParts.first];
37  }
38 
39  if(children.find( pathParts.first ) == children.end()){
40  if((path.length()==1) && (path.at(0)=='/')){
41  file->CreateGroup(pathParts.first);
42  children[pathParts.first].ExactCopy( H5Object(file, pathParts.first ,false) );
43  }else{
44  file->CreateGroup(path + pathParts.first);
45  children[pathParts.first].ExactCopy( H5Object(file, path + pathParts.first ,false) );
46  }
47 
48  return children[pathParts.first].CreatePlaceholder(pathParts.second);
49 
50  }else{
51  return children[pathParts.first].CreatePlaceholder(pathParts.second);
52  }
53 };
54 
55 
56 H5Object& H5Object::CreateGroup(std::string const& grpName)
57 {
58  // If the group already exists, just return it.
59  if(file->DoesGroupExist(path + grpName))
60  return (*this)[grpName];
61 
62  // Otherwise, recursively create the necessary groups.
63  auto pathParts = SplitString(grpName);
64 
65  if(children.find( pathParts.first ) == children.end())
66  {
67  file->CreateGroup(path + pathParts.first);
68  children[pathParts.first].ExactCopy( H5Object(file, path + pathParts.first, false) );
69 
70  if(pathParts.second.length()!=0){
71  return children[pathParts.first].CreateGroup(pathParts.second);
72  }else{
73  return children[pathParts.first];
74  }
75 
76  }else{
77  return children[pathParts.first].CreateGroup(pathParts.second);
78  }
79 };
80 
81 
82 
83 
84 H5Object& H5Object::operator[](std::string const& targetPath)
85 {
86  if(targetPath.length()==0){
87  return *this;
88  }else if(isDataset){
89  throw std::runtime_error("Error in H5Object::operator[], can't return child \"" + targetPath + "\" because this object (\"" + path + "\" is a dataset not a group.");
90  }else{
91  auto pathParts = SplitString(targetPath);
92 
93  if(children.find( pathParts.first ) != children.end()){
94  return children.at(pathParts.first)[pathParts.second];
95  }else{
96  return CreatePlaceholder(targetPath);
97  }
98  }
99 };
100 
101 
102 // const H5Object& H5Object::operator[](std::string const& path) const
103 // {
104 // // If the full path is /this/is/the/path, then the split path will be
105 // // /this and /is/the/path
106 
107 // if(isDataset || (path.length()==0))
108 // {
109 // return *this;
110 // }
111 // else
112 // {
113 // auto pathParts = SplitString(path);
114 
115 // return children.at(pathParts.first)[pathParts.second];
116 // }
117 // };
118 
119 BlockDataset H5Object::block(unsigned startRow, unsigned startCol, unsigned numRows, unsigned numCols) const
120 {
121  assert(isDataset);
122 
123  Eigen::VectorXi shape = file->GetDataSetSize(path);
124  assert(shape.size()>0);
125  assert(startRow+numRows <= shape(0));
126  if(shape.size()>1){
127  assert(startCol+numCols <= shape(1));
128  }else{
129  assert(numCols==1);
130  }
131 
132  return BlockDataset(path, file, startRow, startCol, numRows, numCols);
133 }
134 
135 BlockDataset H5Object::topLeftCorner(unsigned numRows, unsigned numCols) const
136 {
137  return block(0,0,numRows,numCols);
138 }
139 
140 BlockDataset H5Object::bottomLeftCorner(unsigned numRows, unsigned numCols) const
141 {
142  return block(rows()-numRows,0,numRows,numCols);
143 }
144 
145 BlockDataset H5Object::topRightCorner(unsigned numRows, unsigned numCols) const
146 {
147  return block(0, cols()-numCols, numRows, numCols);
148 }
149 
150 BlockDataset H5Object::bottomRightCorner(unsigned numRows, unsigned numCols) const
151 {
152  return block(rows()-numRows, cols()-numCols, numRows, numCols);
153 }
154 
155 BlockDataset H5Object::topRows(unsigned numRows) const
156 {
157  return block(0, 0, numRows, cols());
158 }
159 
160 BlockDataset H5Object::bottomRows(unsigned numRows) const
161 {
162  return block(0, cols()-numRows, numRows, cols());
163 }
164 
165 BlockDataset H5Object::leftCols(unsigned numCols) const
166 {
167  return block(0, 0, rows(), numCols);
168 }
169 
170 BlockDataset H5Object::rightCols(unsigned numCols) const
171 {
172  return block(0,cols()-numCols, rows(), numCols);
173 }
174 
175 BlockDataset H5Object::col(unsigned col) const
176 {
177  assert(isDataset);
178  Eigen::VectorXi shape = file->GetDataSetSize(path);
179 
180  return block(0,col,shape(0),1);
181 }
182 
183 BlockDataset H5Object::row(unsigned row) const
184 {
185  assert(isDataset);
186  Eigen::VectorXi shape = file->GetDataSetSize(path);
187 
188  return block(row,0,1,shape(1));
189 }
190 
191 BlockDataset H5Object::segment(unsigned startInd, unsigned numInds) const
192 {
193  return block(startInd, 0, numInds, 1);
194 }
195 
196 BlockDataset H5Object::head(unsigned numInds) const
197 {
198  // Make sure the object is one dimensional
199  Eigen::VectorXi shape = file->GetDataSetSize(path);
200 
201  if(shape.size()==0){
202  std::cerr << "\nERROR: The dataset, " << path << ", does not exist.\n" << std::endl;
203  assert(shape.size()>0);
204  }
205 
206  if(shape.size()==1){
207  return block(0,0,numInds,1);
208  }else if(shape(0)==1){
209  return block(0,0,1,numInds);
210  }else if(shape(1)==1){
211  return block(0,0,numInds,1);
212  }else{
213  std::cerr << "\nERROR: The head() function requires the dataset to be one dimensional and \"" << path << "\" does not seem to be one dimensional.\n" << std::endl;
214  assert(false);
215  return block(0,0,numInds,1);
216  }
217 }
218 
219 BlockDataset H5Object::tail(unsigned numInds) const
220 {
221  return block(rows()-numInds, 0, numInds, 1);
222 }
223 
224 
225 unsigned H5Object::rows() const
226 {
227  if(!isDataset)
228  throw std::runtime_error("Attempted to call H5Object::rows() on a group object.");
229 
230  Eigen::VectorXi shape = file->GetDataSetSize(path);
231  return shape(0);
232 }
233 
234 unsigned H5Object::cols() const
235 {
236  if(!isDataset)
237  throw std::runtime_error("Attempted to call H5Object::cols() on a group object.");
238 
239  Eigen::VectorXi shape = file->GetDataSetSize(path);
240  if(shape.size()==1)
241  return 1;
242  else
243  return shape(1);
244 }
245 
246 unsigned H5Object::size() const
247 {
248  if(!isDataset)
249  throw std::runtime_error("Attempted to call H5Object::size() on a group object.");
250 
251  Eigen::VectorXi shape = file->GetDataSetSize(path);
252  return shape.prod();
253 }
254 
255 double H5Object::operator()(int i) const
256 {
257  if(isDataset){
258  return file->ReadPartialMatrix(path,i,0,1,1)(0);
259  }else{
260  assert(false);
261  }
262 };
263 
264 double H5Object::operator()(int i, int j) const
265 {
266  if(isDataset){
267  return file->ReadPartialMatrix(path, i,j,1,1)(0,0);
268  }else{
269  assert(false);
270  }
271 };
272 
273 
274 
276 {
277  file->FlushFile();
278 }
279 
280 
281 void H5Object::Print(std::string prefix) const
282 {
283  std::cout << prefix + path << std::endl;
284  for(auto& child : children)
285  child.second.Print(prefix + " ");
286 }
287 
288 
290 H5Object muq::Utilities::AddChildren(std::shared_ptr<HDF5File> file,
291  std::string const& groupName)
292 {
293 
294  if(file->IsDataSet(groupName))
295  return H5Object(file,groupName,true);
296 
297  // Set up the current object
298  H5Object output(file, groupName, false);
299 
300  // Add the children
301  std::vector<std::string> children = file->GetChildren(groupName);
302 
303  for(auto& childPath : children)
304  {
305  std::string fullChildPath = groupName;
306 
307  if(groupName.at(fullChildPath.length()-1)!='/')
308  fullChildPath += "/";
309  fullChildPath += childPath;
310 
311  output.children[fullChildPath].ExactCopy( AddChildren(file, fullChildPath) );
312  }
313 
314  return output;
315 }
316 
318 
321 H5Object muq::Utilities::OpenFile(std::string const& filename)
322 {
323  std::shared_ptr<HDF5File> file = std::make_shared<HDF5File>(filename);
324  return AddChildren(file, "/");
325 }
BlockDataset rightCols(unsigned numCols) const
Definition: H5Object.cpp:170
unsigned size() const
Definition: H5Object.cpp:246
H5Object & CreateGroup(std::string const &grpName)
Definition: H5Object.cpp:56
BlockDataset bottomLeftCorner(unsigned numRows, unsigned numCols) const
Definition: H5Object.cpp:140
BlockDataset topRows(unsigned numRows) const
Definition: H5Object.cpp:155
BlockDataset col(unsigned col) const
Definition: H5Object.cpp:175
H5Object & CreatePlaceholder(std::string const &grpName)
Definition: H5Object.cpp:29
AttributeList attrs
Definition: H5Object.h:205
std::map< std::string, H5Object > children
Definition: H5Object.h:221
void Print(std::string prefix="") const
Definition: H5Object.cpp:281
BlockDataset segment(unsigned startInd, unsigned numInds) const
Definition: H5Object.cpp:191
BlockDataset row(unsigned row) const
Definition: H5Object.cpp:183
unsigned cols() const
Definition: H5Object.cpp:234
unsigned rows() const
Definition: H5Object.cpp:225
void ExactCopy(H5Object const &otherObj)
Creates an exact copy.
Definition: H5Object.cpp:19
BlockDataset topLeftCorner(unsigned numRows, unsigned numCols) const
Definition: H5Object.cpp:135
BlockDataset topRightCorner(unsigned numRows, unsigned numCols) const
Definition: H5Object.cpp:145
H5Object & operator[](std::string const &targetPath)
Definition: H5Object.cpp:84
BlockDataset head(unsigned numInds) const
Definition: H5Object.cpp:196
BlockDataset block(unsigned startRow, unsigned startCol, unsigned numRows, unsigned numCols) const
Definition: H5Object.cpp:119
BlockDataset tail(unsigned numInds) const
Definition: H5Object.cpp:219
std::shared_ptr< HDF5File > file
Definition: H5Object.h:201
void DeepCopy(H5Object const &otherObj)
Definition: H5Object.cpp:6
BlockDataset bottomRightCorner(unsigned numRows, unsigned numCols) const
Definition: H5Object.cpp:150
double operator()(int i) const
Definition: H5Object.cpp:255
H5Object & operator=(boost::any const &val)
BlockDataset bottomRows(unsigned numRows) const
Definition: H5Object.cpp:160
BlockDataset leftCols(unsigned numCols) const
Definition: H5Object.cpp:165
std::pair< std::string, std::string > SplitString(std::string const &path)
Splits a string on the first forward slash.
Definition: PathTools.cpp:19
H5Object OpenFile(std::string const &filename)
Open an HDF5 file and return the root object.
Definition: H5Object.cpp:321
H5Object AddChildren(std::shared_ptr< HDF5File > file, std::string const &groupName)
Recursively add children to create an HDF5 file hierarchy.
Definition: H5Object.cpp:290