| 1 | #include <iostream> |
|---|
| 2 | #include <string> |
|---|
| 3 | #include <sstream> |
|---|
| 4 | #include <cstring> |
|---|
| 5 | #include <cstdlib> |
|---|
| 6 | #include <cstdio> |
|---|
| 7 | #include <vector> |
|---|
| 8 | #include <map> |
|---|
| 9 | #include "napiconfig.h" |
|---|
| 10 | #include "NeXusFile.hpp" |
|---|
| 11 | |
|---|
| 12 | using std::cout; |
|---|
| 13 | using std::endl; |
|---|
| 14 | using std::map; |
|---|
| 15 | using std::multimap; |
|---|
| 16 | using std::string; |
|---|
| 17 | using std::vector; |
|---|
| 18 | |
|---|
| 19 | static std::string relativePathOf(const std::string& filenamestr) { |
|---|
| 20 | char cwd[1024]; |
|---|
| 21 | |
|---|
| 22 | getcwd(cwd, sizeof(cwd)); |
|---|
| 23 | |
|---|
| 24 | if ( filenamestr.compare(0, strlen(cwd), cwd) == 0 ) |
|---|
| 25 | { |
|---|
| 26 | return filenamestr.substr(strlen(cwd)+1); // +1 to skip trailing / |
|---|
| 27 | } |
|---|
| 28 | else |
|---|
| 29 | { |
|---|
| 30 | return filenamestr; |
|---|
| 31 | } |
|---|
| 32 | } |
|---|
| 33 | |
|---|
| 34 | static int writeTest(const string& filename, NXaccess create_code) { |
|---|
| 35 | NeXus::File file(filename, create_code); |
|---|
| 36 | // create group |
|---|
| 37 | file.makeGroup("entry", "NXentry", true); |
|---|
| 38 | // group attributes |
|---|
| 39 | file.putAttr("hugo", "namenlos"); |
|---|
| 40 | file.putAttr("cucumber", "passion"); |
|---|
| 41 | // put string |
|---|
| 42 | file.writeData("ch_data", "NeXus_data"); |
|---|
| 43 | |
|---|
| 44 | // 2d array |
|---|
| 45 | vector<int> array_dims; |
|---|
| 46 | array_dims.push_back(5); |
|---|
| 47 | array_dims.push_back(4); |
|---|
| 48 | char c1_array[5][4] = {{'a', 'b', 'c' ,'d'}, {'e', 'f', 'g' ,'h'}, |
|---|
| 49 | {'i', 'j', 'k', 'l'}, {'m', 'n', 'o', 'p'}, |
|---|
| 50 | {'q', 'r', 's' , 't'}}; |
|---|
| 51 | file.makeData("c1_data", NeXus::CHAR, array_dims, true); |
|---|
| 52 | file.putData(c1_array); |
|---|
| 53 | file.closeData(); |
|---|
| 54 | |
|---|
| 55 | // 1d uint8 array |
|---|
| 56 | vector<uint8_t> i1_array; |
|---|
| 57 | for (size_t i = 0; i < 4; i++) { |
|---|
| 58 | i1_array.push_back(static_cast<uint8_t>(i+1)); |
|---|
| 59 | } |
|---|
| 60 | file.writeData("i1_data", i1_array); |
|---|
| 61 | |
|---|
| 62 | // 1d int16 array |
|---|
| 63 | vector<int16_t> i2_array; |
|---|
| 64 | for (size_t i = 0; i < 4; i++) { |
|---|
| 65 | i2_array.push_back(1000*(i+1)); |
|---|
| 66 | } |
|---|
| 67 | file.writeData("i2_data", i2_array); |
|---|
| 68 | |
|---|
| 69 | // 1d int32 data |
|---|
| 70 | vector<int32_t> i4_array; |
|---|
| 71 | for (size_t i = 0; i < 4; i++) { |
|---|
| 72 | i4_array.push_back(1000000*(i+1)); |
|---|
| 73 | } |
|---|
| 74 | file.writeData("i4_data", i4_array); |
|---|
| 75 | |
|---|
| 76 | // 2d float data |
|---|
| 77 | vector<float> r4_array; |
|---|
| 78 | for (size_t i = 0; i < 5*4; i++) { |
|---|
| 79 | r4_array.push_back(static_cast<float>(i)); |
|---|
| 80 | } |
|---|
| 81 | file.writeData("r4_data", r4_array, array_dims); |
|---|
| 82 | |
|---|
| 83 | // 2d double data - slab test |
|---|
| 84 | vector<double> r8_array; |
|---|
| 85 | for (size_t i = 0; i < 5*4; i++) { |
|---|
| 86 | r8_array.push_back(static_cast<double>(i+20)); |
|---|
| 87 | } |
|---|
| 88 | file.makeData("r8_data", NeXus::FLOAT64, array_dims, true); |
|---|
| 89 | vector<int> slab_start; |
|---|
| 90 | slab_start.push_back(4); |
|---|
| 91 | slab_start.push_back(0); |
|---|
| 92 | vector<int> slab_size; |
|---|
| 93 | slab_size.push_back(1); |
|---|
| 94 | slab_size.push_back(4); |
|---|
| 95 | file.putSlab(&(r8_array[16]), slab_start, slab_size); |
|---|
| 96 | slab_start[0] = 0; |
|---|
| 97 | slab_start[1] = 0; |
|---|
| 98 | slab_size[0]=4; |
|---|
| 99 | slab_size[1]=4; |
|---|
| 100 | file.putSlab(&(r8_array[0]), slab_start, slab_size); |
|---|
| 101 | |
|---|
| 102 | // add some attributes |
|---|
| 103 | file.putAttr("ch_attribute", "NeXus"); |
|---|
| 104 | file.putAttr("i4_attribute", 42); |
|---|
| 105 | file.putAttr("r4_attribute", 3.14159265); |
|---|
| 106 | |
|---|
| 107 | // set up for creating a link |
|---|
| 108 | NXlink link = file.getDataID(); |
|---|
| 109 | file.closeData(); |
|---|
| 110 | |
|---|
| 111 | // int64 tests |
|---|
| 112 | vector<int64_t> grossezahl; |
|---|
| 113 | #if HAVE_LONG_LONG_INT |
|---|
| 114 | grossezahl.push_back(12); |
|---|
| 115 | grossezahl.push_back(555555555555LL); |
|---|
| 116 | grossezahl.push_back(23); |
|---|
| 117 | grossezahl.push_back(777777777777LL); |
|---|
| 118 | #else |
|---|
| 119 | grossezahl.push_back(12); |
|---|
| 120 | grossezahl.push_back(555555); |
|---|
| 121 | grossezahl.push_back(23); |
|---|
| 122 | grossezahl.push_back(77777); |
|---|
| 123 | #endif |
|---|
| 124 | if (create_code != NXACC_CREATE) { |
|---|
| 125 | file.writeData("grosszahl", grossezahl); |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | // create a new group inside this one |
|---|
| 129 | file.makeGroup("data", "NXdata", true); |
|---|
| 130 | |
|---|
| 131 | // create a link |
|---|
| 132 | file.makeLink(link); |
|---|
| 133 | |
|---|
| 134 | // compressed data |
|---|
| 135 | array_dims[0] = 100; |
|---|
| 136 | array_dims[1] = 20; |
|---|
| 137 | vector<int> comp_array; |
|---|
| 138 | for (int i = 0; i < array_dims[0]; i++) { |
|---|
| 139 | for (int j = 0; j < array_dims[1]; j++) { |
|---|
| 140 | comp_array.push_back(i); |
|---|
| 141 | } |
|---|
| 142 | } |
|---|
| 143 | vector<int> cdims; |
|---|
| 144 | cdims.push_back(20); |
|---|
| 145 | cdims.push_back(20); |
|---|
| 146 | file.writeCompData("comp_data", comp_array, array_dims, NeXus::LZW, cdims); |
|---|
| 147 | |
|---|
| 148 | // ---------- Test write Extendible Data -------------------------- |
|---|
| 149 | std::vector<int> data(10, 123); |
|---|
| 150 | file.makeGroup("extendible_data", "NXdata", 1); |
|---|
| 151 | file.writeExtendibleData("mydata1", data); |
|---|
| 152 | file.writeExtendibleData("mydata2", data, 1000); |
|---|
| 153 | std::vector<int64_t> dims(2); |
|---|
| 154 | dims[0] = 5; |
|---|
| 155 | dims[1] = 2; |
|---|
| 156 | std::vector<int64_t> chunk(2, 2); |
|---|
| 157 | file.writeExtendibleData("my2Ddata", data, dims, chunk); |
|---|
| 158 | file.putAttr("string_attrib", "some short string"); |
|---|
| 159 | |
|---|
| 160 | // Data vector can grow |
|---|
| 161 | for (size_t i=0; i<6; i++) |
|---|
| 162 | data.push_back(456); |
|---|
| 163 | data[0]=789; |
|---|
| 164 | file.writeUpdatedData("mydata1", data); |
|---|
| 165 | |
|---|
| 166 | dims[0] = 8; |
|---|
| 167 | dims[1] = 2; |
|---|
| 168 | file.writeUpdatedData("my2Ddata", data, dims); |
|---|
| 169 | |
|---|
| 170 | // Data vector can also shrink! |
|---|
| 171 | data.clear(); |
|---|
| 172 | data.resize(5, 234); |
|---|
| 173 | file.writeUpdatedData("mydata2", data); |
|---|
| 174 | |
|---|
| 175 | // Exit the group |
|---|
| 176 | file.closeGroup(); |
|---|
| 177 | // ---------- End Test write Extendible Data -------------------------- |
|---|
| 178 | |
|---|
| 179 | // simple flush test |
|---|
| 180 | file.flush(); |
|---|
| 181 | |
|---|
| 182 | // real flush test |
|---|
| 183 | file.makeData("flush_data", NeXus::getType<int>(), NX_UNLIMITED, true); |
|---|
| 184 | vector<int> slab_array; |
|---|
| 185 | slab_array.push_back(0); |
|---|
| 186 | for (int i = 0 ; i < 7; i++) { |
|---|
| 187 | slab_array[0] = i; |
|---|
| 188 | file.putSlab(slab_array, i, 1); |
|---|
| 189 | file.flush(); |
|---|
| 190 | file.openData("flush_data"); |
|---|
| 191 | } |
|---|
| 192 | file.closeData(); |
|---|
| 193 | file.closeGroup(); |
|---|
| 194 | |
|---|
| 195 | // create a sample |
|---|
| 196 | file.makeGroup("sample", "NXsample", true); |
|---|
| 197 | file.writeData("ch_data", "NeXus sample"); |
|---|
| 198 | |
|---|
| 199 | // make more links |
|---|
| 200 | NXlink glink = file.getGroupID(); |
|---|
| 201 | file.openPath("/"); |
|---|
| 202 | file.makeGroup("link", "NXentry", true); |
|---|
| 203 | file.makeLink(glink); |
|---|
| 204 | file.makeNamedLink("renLinkGroup", glink); |
|---|
| 205 | file.makeNamedLink("renLinkData", link); |
|---|
| 206 | |
|---|
| 207 | return 0; |
|---|
| 208 | } |
|---|
| 209 | |
|---|
| 210 | template <typename NumT> |
|---|
| 211 | string toString(const vector<NumT> & data) { |
|---|
| 212 | std::stringstream result; |
|---|
| 213 | result << "["; |
|---|
| 214 | size_t size = data.size(); |
|---|
| 215 | for (size_t i = 0; i < size; i++) { |
|---|
| 216 | result << data[i]; |
|---|
| 217 | if (i+1 < size) { |
|---|
| 218 | result << ","; |
|---|
| 219 | } |
|---|
| 220 | } |
|---|
| 221 | result << "]"; |
|---|
| 222 | return result.str(); |
|---|
| 223 | } |
|---|
| 224 | |
|---|
| 225 | int readTest(const string & filename) { |
|---|
| 226 | const string SDS("SDS"); |
|---|
| 227 | // top level file information |
|---|
| 228 | NeXus::File file(filename); |
|---|
| 229 | cout << "NXinquirefile found: " << relativePathOf(file.inquireFile()) << endl; |
|---|
| 230 | vector<NeXus::AttrInfo> attr_infos = file.getAttrInfos(); |
|---|
| 231 | cout << "Number of global attributes: " << attr_infos.size() << endl; |
|---|
| 232 | for (vector<NeXus::AttrInfo>::iterator it = attr_infos.begin(); |
|---|
| 233 | it != attr_infos.end(); it++) { |
|---|
| 234 | if (it->name != "file_time" && it->name != "HDF_version" && it->name != "HDF5_Version" && it->name != "XML_version") { |
|---|
| 235 | cout << " " << it->name << " = "; |
|---|
| 236 | if (it->type == NeXus::CHAR) { |
|---|
| 237 | cout << file.getStrAttr(*it); |
|---|
| 238 | } |
|---|
| 239 | cout << endl; |
|---|
| 240 | } |
|---|
| 241 | } |
|---|
| 242 | |
|---|
| 243 | // check group attributes |
|---|
| 244 | file.openGroup("entry", "NXentry"); |
|---|
| 245 | attr_infos = file.getAttrInfos(); |
|---|
| 246 | cout << "Number of group attributes: " << attr_infos.size() << endl; |
|---|
| 247 | for (vector<NeXus::AttrInfo>::iterator it = attr_infos.begin(); |
|---|
| 248 | it != attr_infos.end(); it++) { |
|---|
| 249 | cout << " " << it->name << " = "; |
|---|
| 250 | if (it->type == NeXus::CHAR) { |
|---|
| 251 | cout << file.getStrAttr(*it); |
|---|
| 252 | } |
|---|
| 253 | cout << endl; |
|---|
| 254 | } |
|---|
| 255 | |
|---|
| 256 | // print out the entry level fields |
|---|
| 257 | map<string, string> entries = file.getEntries(); |
|---|
| 258 | cout << "Group contains " << entries.size() << " items" << endl; |
|---|
| 259 | NeXus::Info info; |
|---|
| 260 | for (map<string,string>::const_iterator it = entries.begin(); |
|---|
| 261 | it != entries.end(); it++) { |
|---|
| 262 | cout << " " << it->first; |
|---|
| 263 | if (it->second == SDS) { |
|---|
| 264 | file.openData(it->first); |
|---|
| 265 | info = file.getInfo(); |
|---|
| 266 | cout << toString(info.dims) << " = "; |
|---|
| 267 | if (info.type == NeXus::CHAR) { |
|---|
| 268 | if (info.dims.size()==1) { |
|---|
| 269 | cout << file.getStrData(); |
|---|
| 270 | } |
|---|
| 271 | else { |
|---|
| 272 | cout << "2d character array"; |
|---|
| 273 | } |
|---|
| 274 | } |
|---|
| 275 | else if (info.type == NeXus::FLOAT32) { |
|---|
| 276 | vector<float> * result = file.getData<float>(); |
|---|
| 277 | cout << toString(*result); |
|---|
| 278 | delete result; |
|---|
| 279 | } |
|---|
| 280 | else if (info.type == NeXus::FLOAT64) { |
|---|
| 281 | vector<double> * result = file.getData<double>(); |
|---|
| 282 | cout << toString(*result); |
|---|
| 283 | delete result; |
|---|
| 284 | } |
|---|
| 285 | else if (info.type == NeXus::INT8) { |
|---|
| 286 | vector<int8_t> result; |
|---|
| 287 | file.getData(result); |
|---|
| 288 | cout << toString(result); |
|---|
| 289 | } |
|---|
| 290 | else if (info.type == NeXus::UINT8) { |
|---|
| 291 | vector<uint8_t> result; |
|---|
| 292 | file.getData(result); |
|---|
| 293 | cout << toString(result); |
|---|
| 294 | } |
|---|
| 295 | else if (info.type == NeXus::INT16) { |
|---|
| 296 | vector<int16_t> result; |
|---|
| 297 | file.getData(result); |
|---|
| 298 | cout << toString(result); |
|---|
| 299 | } |
|---|
| 300 | else if (info.type == NeXus::UINT16) { |
|---|
| 301 | vector<uint16_t> result; |
|---|
| 302 | file.getData(result); |
|---|
| 303 | cout << toString(result); |
|---|
| 304 | } |
|---|
| 305 | else if (info.type == NeXus::INT32) { |
|---|
| 306 | vector<int32_t> result; |
|---|
| 307 | file.getData(result); |
|---|
| 308 | cout << toString(result); |
|---|
| 309 | } |
|---|
| 310 | else if (info.type == NeXus::UINT32) { |
|---|
| 311 | vector<uint32_t> result; |
|---|
| 312 | file.getData(result); |
|---|
| 313 | cout << toString(result); |
|---|
| 314 | } |
|---|
| 315 | else if (info.type == NeXus::INT64) { |
|---|
| 316 | vector<int64_t> result; |
|---|
| 317 | file.getData(result); |
|---|
| 318 | cout << toString(result); |
|---|
| 319 | } |
|---|
| 320 | else if (info.type == NeXus::UINT64) { |
|---|
| 321 | vector<uint64_t> result; |
|---|
| 322 | file.getData(result); |
|---|
| 323 | cout << toString(result); |
|---|
| 324 | } |
|---|
| 325 | cout << endl; |
|---|
| 326 | cout << " Path = " << file.getPath() << endl; |
|---|
| 327 | file.closeData(); |
|---|
| 328 | } |
|---|
| 329 | else { |
|---|
| 330 | cout << ":" << it->second << endl; |
|---|
| 331 | } |
|---|
| 332 | } |
|---|
| 333 | |
|---|
| 334 | // Test getDataCoerce() ------------------- |
|---|
| 335 | std::vector<int> ints; |
|---|
| 336 | std::vector<double> doubles; |
|---|
| 337 | |
|---|
| 338 | ints.clear(); |
|---|
| 339 | file.openData("i1_data"); |
|---|
| 340 | file.getDataCoerce(ints); |
|---|
| 341 | if (ints.size() != 4) return 1; |
|---|
| 342 | if (ints[0] != 1) return 1; |
|---|
| 343 | file.closeData(); |
|---|
| 344 | |
|---|
| 345 | ints.clear(); |
|---|
| 346 | file.openData("i2_data"); |
|---|
| 347 | file.getDataCoerce(ints); |
|---|
| 348 | if (ints.size() != 4) return 1; |
|---|
| 349 | if (ints[0] != 1000) return 1; |
|---|
| 350 | file.closeData(); |
|---|
| 351 | |
|---|
| 352 | ints.clear(); |
|---|
| 353 | file.openData("i4_data"); |
|---|
| 354 | file.getDataCoerce(ints); |
|---|
| 355 | if (ints.size() != 4) return 1; |
|---|
| 356 | if (ints[0] != 1000000) return 1; |
|---|
| 357 | file.closeData(); |
|---|
| 358 | |
|---|
| 359 | doubles.clear(); |
|---|
| 360 | file.openData("r4_data"); |
|---|
| 361 | file.getDataCoerce(doubles); |
|---|
| 362 | if (doubles.size() != 20) return 1; |
|---|
| 363 | if (doubles[1] != 1.0) return 1; |
|---|
| 364 | file.closeData(); |
|---|
| 365 | |
|---|
| 366 | doubles.clear(); |
|---|
| 367 | file.openData("r8_data"); |
|---|
| 368 | file.getDataCoerce(doubles); |
|---|
| 369 | if (doubles.size() != 20) return 1; |
|---|
| 370 | if (doubles[1] != 21.0) return 1; |
|---|
| 371 | file.closeData(); |
|---|
| 372 | |
|---|
| 373 | // Throws when you coerce to int from a real/double source |
|---|
| 374 | bool didThrow = false; |
|---|
| 375 | try |
|---|
| 376 | { |
|---|
| 377 | ints.clear(); |
|---|
| 378 | file.openData("r8_data"); |
|---|
| 379 | file.getDataCoerce(ints); |
|---|
| 380 | file.closeData(); |
|---|
| 381 | cout << "getDataCoerce(int) of doubles did not throw (it is supposed to throw)." << endl; |
|---|
| 382 | } |
|---|
| 383 | catch (...) |
|---|
| 384 | { |
|---|
| 385 | // Good! It is supposed to throw |
|---|
| 386 | didThrow = true; |
|---|
| 387 | file.closeData(); |
|---|
| 388 | } |
|---|
| 389 | if (!didThrow) return 1; |
|---|
| 390 | |
|---|
| 391 | |
|---|
| 392 | // Close the "entry" group |
|---|
| 393 | file.closeGroup(); |
|---|
| 394 | |
|---|
| 395 | // check links |
|---|
| 396 | file.openGroup("entry", "NXentry"); |
|---|
| 397 | file.openGroup("sample", "NXsample"); |
|---|
| 398 | NXlink glink = file.getGroupID(); |
|---|
| 399 | file.closeGroup(); |
|---|
| 400 | file.openGroup("data", "NXdata"); |
|---|
| 401 | file.openData("r8_data"); |
|---|
| 402 | NXlink dlink = file.getDataID(); |
|---|
| 403 | file.closeData(); |
|---|
| 404 | file.closeGroup(); |
|---|
| 405 | file.openData("r8_data"); |
|---|
| 406 | NXlink d2link = file.getDataID(); |
|---|
| 407 | file.closeData(); |
|---|
| 408 | if (!file.sameID(dlink, d2link)) { |
|---|
| 409 | cout << "Link check FAILED (r8_data)" << endl; |
|---|
| 410 | cout << " original data = "; |
|---|
| 411 | file.printLink(dlink); |
|---|
| 412 | cout << " linked data = "; |
|---|
| 413 | file.printLink(d2link); |
|---|
| 414 | return 1; |
|---|
| 415 | } |
|---|
| 416 | file.closeGroup(); |
|---|
| 417 | |
|---|
| 418 | file.openGroup("link", "NXentry"); |
|---|
| 419 | file.openGroup("sample", "NXsample"); |
|---|
| 420 | NXlink g2link = file.getGroupID(); |
|---|
| 421 | if (!file.sameID(glink, g2link)) { |
|---|
| 422 | cout << "Link check FAILED (sample)" << endl; |
|---|
| 423 | cout << " original group = "; |
|---|
| 424 | file.printLink(glink); |
|---|
| 425 | cout << " linked group = "; |
|---|
| 426 | file.printLink(g2link); |
|---|
| 427 | return 1; |
|---|
| 428 | } |
|---|
| 429 | file.closeGroup(); |
|---|
| 430 | |
|---|
| 431 | file.openGroup("renLinkGroup", "NXsample"); |
|---|
| 432 | g2link = file.getGroupID(); |
|---|
| 433 | file.closeGroup(); |
|---|
| 434 | if (!file.sameID(glink, g2link)) { |
|---|
| 435 | cout << "Link check FAILED (renLinkGroup)" << endl; |
|---|
| 436 | cout << " original group = "; |
|---|
| 437 | file.printLink(glink); |
|---|
| 438 | cout << " linked group = "; |
|---|
| 439 | file.printLink(g2link); |
|---|
| 440 | return 1; |
|---|
| 441 | } |
|---|
| 442 | |
|---|
| 443 | file.openData("renLinkData"); |
|---|
| 444 | d2link = file.getDataID(); |
|---|
| 445 | file.closeData(); |
|---|
| 446 | if (!file.sameID(dlink, d2link)) { |
|---|
| 447 | cout << "Link check FAILED (renLinkData)" << endl; |
|---|
| 448 | cout << " original data = "; |
|---|
| 449 | file.printLink(dlink); |
|---|
| 450 | cout << " linked data = "; |
|---|
| 451 | file.printLink(d2link); |
|---|
| 452 | return 1; |
|---|
| 453 | } |
|---|
| 454 | |
|---|
| 455 | file.closeGroup(); |
|---|
| 456 | cout << "Link check OK" << endl; |
|---|
| 457 | |
|---|
| 458 | // openpath checks |
|---|
| 459 | file.openPath("/entry/data/comp_data"); |
|---|
| 460 | file.openPath("/entry/data/comp_data"); |
|---|
| 461 | file.openPath("../r8_data"); |
|---|
| 462 | printf("NXopenpath checks OK\n"); |
|---|
| 463 | |
|---|
| 464 | // everything went fine |
|---|
| 465 | return 0; |
|---|
| 466 | } |
|---|
| 467 | |
|---|
| 468 | int testLoadPath(const string & filename) { |
|---|
| 469 | if(getenv("NX_LOAD_PATH") != NULL){ |
|---|
| 470 | NeXus::File file(filename); |
|---|
| 471 | cout << "Success loading NeXus file from path" << endl; |
|---|
| 472 | // cout << file.inquireFile() << endl; // DEBUG print |
|---|
| 473 | } |
|---|
| 474 | return 0; |
|---|
| 475 | } |
|---|
| 476 | |
|---|
| 477 | int testExternal(const string & fileext, NXaccess create_code){ |
|---|
| 478 | string filename("nxext_cpp" + fileext); |
|---|
| 479 | string exturl1("nxfile://data/dmc01" + fileext+"#entry1"); |
|---|
| 480 | string exturl2("nxfile://data/dmc02" + fileext+"#entry1"); |
|---|
| 481 | |
|---|
| 482 | // create the external link |
|---|
| 483 | NeXus::File fileout(filename, create_code); |
|---|
| 484 | fileout.linkExternal("entry1", "NXentry", exturl1); |
|---|
| 485 | fileout.linkExternal("entry2", "NXentry", exturl2); |
|---|
| 486 | fileout.close(); |
|---|
| 487 | |
|---|
| 488 | // read the file to make sure things worked |
|---|
| 489 | NeXus::File filein(filename); |
|---|
| 490 | filein.openPath("/entry1/start_time"); |
|---|
| 491 | cout << "First file time: " << filein.getStrData() << endl; |
|---|
| 492 | cout << "NXinquirefile found: " << relativePathOf(filein.inquireFile()) << endl; |
|---|
| 493 | filein.openPath("/entry2/sample/sample_name"); |
|---|
| 494 | cout << "Second file sample: " << filein.getStrData() << endl; |
|---|
| 495 | cout << "NXinquirefile found: " << relativePathOf(filein.inquireFile()) << endl; |
|---|
| 496 | filein.openPath("/entry2/start_time"); |
|---|
| 497 | cout << "Second file time: " << filein.getStrData() << endl; |
|---|
| 498 | filein.openPath("/"); |
|---|
| 499 | cout << "entry1 external URL = " |
|---|
| 500 | << filein.isExternalGroup("entry1", "NXentry") << endl; |
|---|
| 501 | |
|---|
| 502 | return 0; |
|---|
| 503 | } |
|---|
| 504 | |
|---|
| 505 | static int streamTest(const std::string& fname, NXaccess create_mode) |
|---|
| 506 | { |
|---|
| 507 | using namespace NeXus; |
|---|
| 508 | using namespace NeXus::Stream; |
|---|
| 509 | std::vector<double> w; |
|---|
| 510 | std::vector<double> w1; |
|---|
| 511 | w.push_back(1.0); |
|---|
| 512 | double d, d1; |
|---|
| 513 | int i; |
|---|
| 514 | // create an entry and a data item |
|---|
| 515 | File nf(fname, create_mode); |
|---|
| 516 | nf << Group("entry1", "NXentry") << Data("dat1", w, "int_attr", 3); |
|---|
| 517 | nf.close(); |
|---|
| 518 | File nf1(fname, NXACC_RDWR); |
|---|
| 519 | // add a double_attr to an existing setup |
|---|
| 520 | nf1 >> Group("entry1", "NXentry") >> Data("dat1") << Attr("double_attr", 6.0) << Close; |
|---|
| 521 | nf1.close(); |
|---|
| 522 | // read back data items |
|---|
| 523 | File nf2(fname, NXACC_READ); |
|---|
| 524 | nf2 >> Group("entry1", "NXentry") >> Data("dat1", w1, "int_attr", i, "double_attr", d); |
|---|
| 525 | // alternative way to read d1 |
|---|
| 526 | nf2 >> Data("dat1") >> Attr("double_attr", d1); |
|---|
| 527 | nf2.close(); |
|---|
| 528 | if (i != 3 || w != w1 || d != 6.0 || d1 != 6.0) |
|---|
| 529 | { |
|---|
| 530 | return 1; |
|---|
| 531 | } |
|---|
| 532 | return 0; |
|---|
| 533 | } |
|---|
| 534 | |
|---|
| 535 | int testTypeMap(const std::string &fname) |
|---|
| 536 | { |
|---|
| 537 | NeXus::File file(fname); |
|---|
| 538 | multimap<string, string> *map = file.getTypeMap(); |
|---|
| 539 | size_t mapsize = 25; |
|---|
| 540 | // HDF4 does not have int64 capability, so resulting map is one shorter than HDF5 and XML files |
|---|
| 541 | if (fname == string("napi_test_cpp.hdf")) { |
|---|
| 542 | if (map->size() != (mapsize - 1)) |
|---|
| 543 | { |
|---|
| 544 | cout << "TypeMap is incorrect" << endl; |
|---|
| 545 | return 1; |
|---|
| 546 | } |
|---|
| 547 | } |
|---|
| 548 | else { |
|---|
| 549 | if (map->size() != mapsize) |
|---|
| 550 | { |
|---|
| 551 | cout << "TypeMap is incorrect" << endl; |
|---|
| 552 | return 1; |
|---|
| 553 | } |
|---|
| 554 | } |
|---|
| 555 | |
|---|
| 556 | cout << "TypeMap is correct size" << endl; |
|---|
| 557 | |
|---|
| 558 | return 0; |
|---|
| 559 | } |
|---|
| 560 | |
|---|
| 561 | int main(int argc, char** argv) |
|---|
| 562 | { |
|---|
| 563 | NXaccess nx_creation_code; |
|---|
| 564 | string filename; |
|---|
| 565 | string extfile_ext; |
|---|
| 566 | if(strstr(argv[0],"napi_test_cpp-hdf5") != NULL){ |
|---|
| 567 | nx_creation_code = NXACC_CREATE5; |
|---|
| 568 | filename = "napi_test_cpp.h5"; |
|---|
| 569 | extfile_ext = ".h5"; |
|---|
| 570 | }else if(strstr(argv[0],"napi_test_cpp-xml-table") != NULL){ |
|---|
| 571 | nx_creation_code = NXACC_CREATEXML | NXACC_TABLE; |
|---|
| 572 | filename = "napi_test_cpp-table.xml"; |
|---|
| 573 | extfile_ext = "-table.xml"; |
|---|
| 574 | }else if(strstr(argv[0],"napi_test_cpp-xml") != NULL){ |
|---|
| 575 | nx_creation_code = NXACC_CREATEXML; |
|---|
| 576 | filename = "napi_test_cpp.xml"; |
|---|
| 577 | extfile_ext = ".xml"; |
|---|
| 578 | } else { |
|---|
| 579 | nx_creation_code = NXACC_CREATE; |
|---|
| 580 | filename = "napi_test_cpp.hdf"; |
|---|
| 581 | extfile_ext = ".hdf"; |
|---|
| 582 | } |
|---|
| 583 | |
|---|
| 584 | int result; |
|---|
| 585 | result = writeTest(filename, nx_creation_code); |
|---|
| 586 | if (result) { |
|---|
| 587 | cout << "writeTest failed" << endl; |
|---|
| 588 | return result; |
|---|
| 589 | } |
|---|
| 590 | if ( (argc >= 2) && !strcmp(argv[1], "-q") ) |
|---|
| 591 | { |
|---|
| 592 | return 0; // |
|---|
| 593 | } |
|---|
| 594 | |
|---|
| 595 | // try reading a file |
|---|
| 596 | result = readTest(filename); |
|---|
| 597 | if (result) { |
|---|
| 598 | cout << "readTest failed" << endl; |
|---|
| 599 | return result; |
|---|
| 600 | } |
|---|
| 601 | |
|---|
| 602 | // try using the load path |
|---|
| 603 | result = testLoadPath("dmc01.hdf"); |
|---|
| 604 | if (result) { |
|---|
| 605 | cout << "testLoadPath failed" << endl; |
|---|
| 606 | return result; |
|---|
| 607 | } |
|---|
| 608 | |
|---|
| 609 | // try external linking |
|---|
| 610 | result = testExternal(extfile_ext, nx_creation_code); |
|---|
| 611 | if (result) { |
|---|
| 612 | cout << "testExternal failed" << endl; |
|---|
| 613 | return result; |
|---|
| 614 | } |
|---|
| 615 | |
|---|
| 616 | |
|---|
| 617 | // quick test of stream interface |
|---|
| 618 | std::string fname = string("stream_test") + extfile_ext; |
|---|
| 619 | result = streamTest(fname, nx_creation_code); |
|---|
| 620 | remove(fname.c_str()); |
|---|
| 621 | if (result) { |
|---|
| 622 | cout << "streamTest failed" << endl; |
|---|
| 623 | return result; |
|---|
| 624 | } |
|---|
| 625 | |
|---|
| 626 | // test of typemap generation |
|---|
| 627 | result = testTypeMap(filename); |
|---|
| 628 | if (result) { |
|---|
| 629 | cout << "testTypeMap failed" << endl; |
|---|
| 630 | return result; |
|---|
| 631 | } |
|---|
| 632 | |
|---|
| 633 | // everything went ok |
|---|
| 634 | return 0; |
|---|
| 635 | } |
|---|