Changeset 282
- Timestamp:
- Feb 19, 2011 11:54:34 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified hdf5_exchange/idl/trunk/nxexchange.pro ¶
r281 r282 30 30 ; NXEXCHANGE::CLOSE closes HDF5 file 31 31 ; NXEXCHANGE::WRITE_DATASET writes out one dataset 32 ; NXEXCHANGE::READ_DATASET reads one dataset 32 33 ; 33 34 ; 34 35 ; EXAMPLE: 35 ; ;; Create nxexchange object for writing data.h5 file36 ; nxe = obj_new('nxexchange' , version='0.3b')36 ; ;; Create nxexchange object for reading/writing data files 37 ; nxe = obj_new('nxexchange') 37 38 ; 38 39 ; ;; open an HDF5 file for writing 39 ; success = nxe->open('data.h5', 'w')40 ; nxe->open, 'data.h5', 'w' 40 41 ; 41 42 ; ;; make a 3x3 array of ints … … 43 44 ; 44 45 ; ;; write it out as primary dataset 45 ; success = nxe->write_dataset('image',['x','y'],'flourescence', idataset)46 ; nxe->write_dataset, 'image',['x','y'],'flourescence', idataset 46 47 ; 47 48 ; ;; write out a secondary dataset associated with above image 48 49 ; tdataset = fltarr(5) 49 ; success = nxe->write_dataset('temps',['C'],'', tdataset, parent='image')50 ; nxe->write_dataset, 'temps',['C'],'', tdataset, parent='image' 50 51 ; 51 52 ; ;; close the file 53 ; nxe->close 54 ; 55 ; ;; re-open the file for reading 56 ; nxe->open, 'data.h5','r' 57 ; 58 ; ;; read in a primary dataset 59 ; idataset = nxe->read_dataset('image') 60 ; 61 ; ;; read in a secondary dataset 62 ; tdataset = nxe->read_dataset('temps', parent='image') 63 ; 64 ; ;; close the file again 52 65 ; nxe->close 53 66 ; … … 104 117 ;; A simple struct to hold a primary dataset index along with 105 118 ;; associated HDF5 group ids 106 pro datasetentry__define107 COMPILE_OPT strictarr 108 struct = { datasetentry, $119 pro nxexchangedatasetentry__define 120 COMPILE_OPT strictarr 121 struct = {nxexchangedatasetentry, $ 109 122 index: 0L, $ 110 123 entry_exchange_gid: 0L, $ … … 114 127 115 128 ; ============================================================= 116 ; 129 ; INTRINSIC 117 130 ; METHODNAME: 118 131 ; NXEXCHANGE::INIT … … 129 142 ; 130 143 ; RETURNS: 131 ; A new nxexchange object.144 ; 1 - success in initializing, 0 - failure 132 145 ; 133 146 ; EXAMPLE: 134 147 ; nxe = obj_new('nxexchange', VERSION='0.3b') 148 ; ;; the above indirectly invokes this init function during 149 ; ;; object construction 135 150 ; 136 151 ; … … 138 153 139 154 COMPILE_OPT strictarr 140 CATCH, error141 if error ne 0 then begin142 print, 'NXEXCHANGE::init error: ',error,' ',!ERROR_STATE.MSG143 CATCH, /CANCEL144 return, 0145 endif146 155 147 156 if keyword_set(vers) then begin … … 181 190 ; none 182 191 ; 183 ; RETURNS:184 ; 1 - success, 0 - failure185 ;186 192 ; EXAMPLE: 187 ; nxe->open ('data.nxs', 'w')193 ; nxe->open, 'data.h5', 'w' 188 194 ; 189 195 ; 190 function nxexchange::open, filename, mode 191 192 COMPILE_OPT strictarr 193 CATCH, error 194 if error ne 0 then begin 195 print, 'NXEXCHANGE::open error: ',error,' ',!ERROR_STATE.MSG 196 CATCH, /CANCEL 197 return, 0 198 endif 196 pro nxexchange::open, filename, mode 197 198 COMPILE_OPT strictarr 199 199 200 200 if (self.fid ne 0) then begin 201 message, 'a file is already open named: ' + self.filename 201 message, 'a file is already open named: ' + self.filename, /informational 202 return 202 203 endif 203 204 … … 211 212 self.fid = H5F_CREATE(self.filename) 212 213 ;; build out some initial structure 213 success = self->build_default_structure() 214 if (~success) then begin 215 message, 'unable to build default structure' 216 endif 214 self->build_default_structure 217 215 218 216 endif else if (self.mode eq 'R') then begin … … 223 221 if (~success) then begin 224 222 self.fid = 0 225 message, 'this file does not appear to be valid' 223 message, 'this file does not appear to be valid', /informational 224 return 226 225 endif 227 226 228 227 endif else if (self.mode eq 'A') then begin 229 228 ;; self.fid = H5F_OPEN(self.filename, /WRITE) 230 message, 'the append (A) mode is not supported yet' 229 message, 'the append (A) mode is not supported yet', /informational 230 return 231 231 232 232 endif else begin 233 message, 'the mode argument must be w or r or a' 233 message, 'the mode argument must be w or r or a', /informational 234 return 234 235 endelse 235 236 236 return , 1237 return 237 238 end 238 239 … … 255 256 ; belongs to given parent dataset 256 257 ; 257 ; RETURNS:258 ; 1 - success, 0 - failure259 258 ; 260 259 ; EXAMPLE: 261 ; nxe->write_dataset('data',['ttheta','energy'],'transmission',data) 262 ; 263 ; 264 function nxexchange::write_dataset, name, axes, data_type, dataset, parent=parent 265 COMPILE_OPT strictarr 266 CATCH, error 267 if error ne 0 then begin 268 print, 'NXEXCHANGE::write_dataset error: ',error,' ',!ERROR_STATE.MSG 269 CATCH, /CANCEL 270 return, 0 260 ; nxe->write_dataset, 'data',['ttheta','energy'],'transmission', data 261 ; 262 ; 263 pro nxexchange::write_dataset, name, axes, data_type, dataset, parent=parent 264 COMPILE_OPT strictarr 265 266 if (self.fid eq 0) then begin 267 message, 'you cannot write a dataset without opening file first', /informational 268 return 271 269 endif 272 273 if (self.fid eq 0) then return, 0274 270 275 271 ;; if parent dataset name given, then we are now entering a … … 279 275 parent_exists = self.primary_dataset_set->iscontained(parent) 280 276 if (~parent_exists) then begin 281 message, 'parent dataset '+parent+' does not exist' 277 message, 'parent dataset '+parent+' does not exist', /informational 278 return 282 279 endif else begin 283 280 primary_dataset = self.primary_dataset_set->get(parent) … … 295 292 axes_n_elems = n_elements(axes) 296 293 if ((n_dims gt 0) and (n_dims ne axes_n_elems)) then begin 297 message, 'axes must have same number of elements as dimensions of dataset' 294 message, 'axes must have same number of elements as dimensions of dataset', /informational 295 return 298 296 endif 299 297 … … 308 306 ;; write primary dataset 309 307 if (~secondary) then begin 310 dataset_entry = { datasetentry}308 dataset_entry = {nxexchangedatasetentry} 311 309 dataset_entry.index = self.primary_dataset_index + 1; 312 310 … … 338 336 H5A_CLOSE, signal_aid 339 337 endif 340 existing_dataset_path = '/entry/' + name + '/data' 338 exchange_groupname = self->exchange_group_name(self.primary_dataset_index) 339 target_path = '/entry/'+exchange_groupname+'/'+name 341 340 target_aid = H5A_CREATE(dsid, 'target', self.string_dtid, self.simple_dspid) 342 H5A_WRITE, target_aid, existing_dataset_path341 H5A_WRITE, target_aid, target_path 343 342 H5A_CLOSE, target_aid 344 343 … … 385 384 endif 386 385 387 return , 1386 return 388 387 end 389 388 … … 404 403 ; 405 404 ; RETURNS: 406 ; dataset - success, null_ptr - failure405 ; dataset 407 406 ; 408 407 ; EXAMPLE: 409 ; nxe->read_dataset('data') 408 ; my_primary_dataset = nxe->read_dataset('image') 409 ; my_secondary_dataset = nxe->read_dataset('temps', parent='image') 410 410 ; 411 411 ; 412 412 function nxexchange::read_dataset, name, parent=parent 413 413 COMPILE_OPT strictarr 414 CATCH, error 415 if error ne 0 then begin 416 print, 'NXEXCHANGE::read_dataset error: ',error,' ',!ERROR_STATE.MSG 417 CATCH, /CANCEL 418 return, ptr_new() 414 415 if (self.fid eq 0) then begin 416 message, 'you cannot read a dataset without opening file first', /informational 417 return, 0 419 418 endif 420 421 if (self.fid eq 0) then return, ptr_new()422 419 423 420 ;; if parent dataset name given, then we are reading a 424 421 ;; secondary dataset 425 422 if keyword_set(parent) then begin 426 ;; have to iterate exchange groups to find secondary dataset 427 ;; n_entry_groups = H5G_GET_NMEMBERS(self.fid, 'entry') 428 429 ;; for i=0, n_entry_groups-1 do begin 430 ;; obj_name = H5G_GET_MEMBER_NAME(self.fid, 'entry', i) 431 ;; s = strpos(obj_name, 'exchange') 432 ;; if (s eq 0) then begin 433 ;; gid = H5G_OPEN(self.entry_gid, obj_name) 434 ;; dsid = H5D_OPEN(gid, parent) 435 ;; CATCH, error 436 ;; if (error ne 0) 437 438 439 ;; endif 440 ;; oid = H5G_OPEN(self.entry_gid, obj_name) 441 ;; type_string = H5I_GET_TYPE(oid) 442 ;; if (type_string eq 'GROUP') then begin 443 ;; see if group has @NX_class=NXsubentry 444 ;; H5A_OPEN_NAME(oid 445 446 ;; endif 447 ;; endfor 448 449 ;; try this a different way... 450 ;; validate that parent group exists 451 ;; parent_gid = H5G_OPEN(self.entry_gid,parent) 452 ;; link_dest_path = H5G_GET_LINKVAL(parent_gid,'data') 453 ;; slice off end to get group path 454 ;; end_pos = strpos(link_dest_path, parent, /REVERSE_SEARCH) 455 ;; exchange_path = strpos(link_dest_path, 0, end_pos) 456 457 ;; print, '**** exchange_path: ' + exchange_path 423 ;; install temporary exception handler (yuck) 424 CATCH, error 425 if (error ne 0) then begin 426 message, 'given parent dataset ' + parent + ' does not exist in file', /informational 427 return, 0 428 endif 429 ;; attempt to find /entry/'parent' NXdata group 430 parent_gid = H5G_OPEN(self.entry_gid,parent) 431 CATCH, /CANCEL ;; cancel temporary exception handler 458 432 459 ;; open dataset 460 dsid = H5D_OPEN(parent_gid, name) 433 ;; open NXdata dataset 434 dsid = H5D_OPEN(parent_gid, 'data') 435 ;; get @target attribute 436 target_aid = H5A_OPEN_NAME(dsid,'target') 437 target_path = H5A_READ(target_aid) 438 H5A_CLOSE, target_aid 439 ;; close out the linked dataset 440 H5D_CLOSE, dsid 441 ;; close out NXdata group 442 H5G_CLOSE, parent_gid 443 444 ;; slice off end of target path to get group path 445 end_pos = strpos(target_path, parent, /REVERSE_SEARCH) 446 exchange_path = strmid(target_path, 0, end_pos) 447 448 ;; open exchange group 449 parent_gid = H5G_OPEN(self.fid, exchange_path) 450 ;; finally! - read the dataset we are looking for 451 dsid = H5D_OPEN(parent_gid, name); 461 452 dataset = H5D_READ(dsid) 462 453 … … 470 461 H5D_CLOSE, dsid 471 462 472 ;; clean up gid s463 ;; clean up gid 473 464 H5G_CLOSE, parent_gid 474 465 … … 479 470 ; Internal METHOD - builds initial /entry 480 471 ; 481 function nxexchange::build_default_structure 482 COMPILE_OPT strictarr 483 CATCH, error 484 if error ne 0 then begin 485 print, 'NXEXCHANGE::build_default_structure error: ',error,' ',!ERROR_STATE.MSG 486 CATCH, /CANCEL 487 return, 0 488 endif 489 490 if (self.fid eq 0) then begin 491 return, 0 492 endif 472 pro nxexchange::build_default_structure 473 COMPILE_OPT strictarr 493 474 494 475 ;; create /entry group with @NX_class=NXentry … … 498 479 H5A_CLOSE, nxclass_aid 499 480 500 return , 1481 return 501 482 end 502 483 503 484 ; ============================================================= 504 485 ; Internal METHOD - reads in initial file structure and validates 486 ; returns 1 - valid, 0 - invalid 505 487 ; 506 488 function nxexchange::read_default_structure 507 489 COMPILE_OPT strictarr 508 CATCH, error509 if error ne 0 then begin510 print, 'NXEXCHANGE::read_default_structure error: ',error,' ',!ERROR_STATE.MSG511 CATCH, /CANCEL512 return, 0513 endif514 490 515 491 ;; read /entry group and verify it has @NX_class=NXentry … … 529 505 ; index=2 produces /entry/exchange2 530 506 ; 531 ; returns open gid for new group , or 0 if error507 ; returns open gid for new group 532 508 ; 533 509 function nxexchange::build_exchange_group, index 534 510 COMPILE_OPT strictarr 535 CATCH, error 536 if error ne 0 then begin 537 print, 'NXEXCHANGE::build_exchange_group error: ',error,' ',!ERROR_STATE.MSG 538 CATCH, /CANCEL 511 512 if (index lt 1) then begin 513 message, 'index must be 1 or greater', /informational 539 514 return, 0 540 515 endif 541 516 542 if (index lt 1) then begin 543 print, 'NXEXCHANGE::build_exchange_group error: index must be 1 or greater' 544 return, 0 545 endif 546 547 if (index eq 1) then begin 548 groupname = 'exchange' 549 endif else begin 550 groupname = 'exchange'+STRTRIM(STRING(index),1) 551 endelse 552 553 ;; create /entry/exchange(n) group with @NX_class=NXsubentry 517 groupname = self->exchange_group_name(index) 518 519 ;; create /entry/exchange(n) group with @NX_class=NXsubentry 554 520 entry_exchange_gid = H5G_CREATE(self.entry_gid, groupname) 555 521 nxclass_aid = H5A_CREATE(entry_exchange_gid, 'NX_class', self.string_dtid, self.simple_dspid) … … 568 534 end 569 535 536 function nxexchange::exchange_group_name, index 537 COMPILE_OPT strictarr 538 if (index eq 1) then begin 539 groupname = 'exchange' 540 endif else begin 541 groupname = 'exchange'+STRTRIM(STRING(index),1) 542 endelse 543 return, groupname 544 end 545 570 546 ; ============================================================= 571 547 ; Internal METHOD - builds a single nxdata group with given name 572 ; returns open gid for new group , or 0 if error548 ; returns open gid for new group 573 549 ; 574 550 function nxexchange::build_nxdata_group, name 575 551 COMPILE_OPT strictarr 576 CATCH, error577 if error ne 0 then begin578 print, 'NXEXCHANGE::build_nxdata_group error: ',error,' ',!ERROR_STATE.MSG579 CATCH, /CANCEL580 return, 0581 endif582 552 583 553 ;; create /entry/'name' with @NX_class=NXdata … … 611 581 pro nxexchange::close 612 582 COMPILE_OPT strictarr 613 CATCH, error614 if error ne 0 then begin615 print, 'NXEXCHANGE::close error: ',error,' ',!ERROR_STATE.MSG616 CATCH, /CANCEL617 endif618 583 619 584 if (self.fid ne 0) then begin 620 585 ;; close out various subgroup gids we have been holding onto 621 586 keys = self.primary_dataset_set->keys() 622 for idx = 0L, N_ELEMENTS(keys)-1 do begin 587 if (keys eq '') then begin 588 numkeys = 0 589 endif else begin 590 numkeys = n_elements(keys) 591 endelse 592 for idx = 0, numkeys-1 do begin 623 593 key = keys[idx] 624 594 dataset_entry = self.primary_dataset_set->get(key) … … 644 614 645 615 ; ============================================================= 646 ; 616 ; INTRINSIC 647 617 ; METHODNAME: 648 618 ; NXEXCHANGE::CLEANUP … … 660 630 ; EXAMPLE: 661 631 ; OBJ_DESTROY, nxe 632 ; ;; the above winds up calling this cleanup procedure 662 633 ; 663 634 ; 664 635 pro nxexchange::cleanup 665 636 COMPILE_OPT strictarr 666 CATCH, error667 if error ne 0 then begin668 print, 'NXEXCHANGE::cleanup error: ',error,' ',!ERROR_STATE.MSG669 CATCH, /CANCEL670 endif671 637 672 638 ;; close out useful types and space definitions … … 680 646 ; ============================================================= 681 647 ; METHODNAME: NXEXCHANGE__DEFINE 682 ; internal method: defines nxexchange internal data structures648 ; defines nxexchange class data structure 683 649 ; 684 650 pro nxexchange__define
Note: See TracChangeset
for help on using the changeset viewer.