diff --git a/bmad/hdf5/hdf5_read_beam.f90 b/bmad/hdf5/hdf5_read_beam.f90 index 10425945ca..5dadde194f 100644 --- a/bmad/hdf5/hdf5_read_beam.f90 +++ b/bmad/hdf5/hdf5_read_beam.f90 @@ -164,9 +164,10 @@ subroutine hdf5_read_bunch (root_id, bunch_obj_name, bunch, error, pmd_head, ele real(rp), allocatable :: pos_x_off(:), pos_y_off(:), pos_z_off(:) integer(hid_t), value :: root_id -integer(hid_t) g_id, g2_id, a_id +integer(hid_t) g_id, g1_id, g2_id, g3_id, a_id integer(hsize_t) idx -integer n, stat, h5_stat, ia, ip, species, h5_err, n_links +integer(size_t) g_size +integer n, stat, h5_stat, ia, ip, species, h5_err, storage_type, n_links, max_corder integer, allocatable :: charge_state(:) character(*) bunch_obj_name @@ -175,14 +176,41 @@ subroutine hdf5_read_bunch (root_id, bunch_obj_name, bunch, error, pmd_head, ele logical error, momentum_warning_printed +! Get number of particles and init. +! Old style: Beam info tree is in g1_id directory. +! New style: Beam info tree is in subdirectory ! General note: There is no way to check names for misspellings since any name may just be an extension standard. g_id = hdf5_open_group(root_id, bunch_obj_name, error, .true.); if (error) return -g2_id = hdf5_open_group(g_id, pmd_head%particlesPath, error, .true.); if (error) return +g1_id = hdf5_open_group(g_id, pmd_head%particlesPath, error, .true.); if (error) return +g2_id = g1_id ! Assume old style + +call hdf5_read_attribute_int(g1_id, 'numParticles', n, error, .false.) + +if (error) then ! Is new style. + call H5Gget_info_f (g1_id, storage_type, n_links, max_corder, h5_err) + do idx = 0, n_links-1 + call H5Lget_name_by_idx_f (g1_id, '.', H5_INDEX_NAME_F, H5_ITER_INC_F, idx, c_name, h5_err, g_size) + call to_f_str(c_name, name) + call H5Oget_info_by_name_f(g1_id, name, infobuf, h5_stat) + if (infobuf%type /= H5O_TYPE_GROUP_F) cycle ! Ignore non-group elements. + g3_id = hdf5_open_group(g1_id, name, error, .false.) + call hdf5_read_attribute_int(g3_id, 'numParticles', n, error, .false.) + if (error) then + call H5Gclose_f(g3_id, h5_err) + cycle + endif + g2_id = g3_id + exit + enddo -! Get number of particles and init. + if (g2_id == g1_id) then ! Not found + call hdf5_read_attribute_int(g2_id, 'numParticles', n, error, .true.) ! Generate error message + return + endif +endif -call hdf5_read_attribute_int(g2_id, 'numParticles', n, error, .true.); if (error) return +! allocate (dt(n), charge_state(n), tot_mom(n), mom_x_off(n), mom_y_off(n), mom_z_off(n)) allocate (pos_x_off(n), pos_y_off(n), pos_z_off(n)) @@ -323,7 +351,8 @@ subroutine hdf5_read_bunch (root_id, bunch_obj_name, bunch, error, pmd_head, ele ! g_id = g2_id when pmd_head%particlesPath = "./". In this case both refer to the same group. if (g2_id /= root_id) call H5Gclose_f(g2_id, h5_err) -if (g_id /= g2_id) call H5Gclose_f(g_id, h5_err) +if (g_id /= g2_id) call H5Gclose_f(g_id, h5_err) +if (g1_id /= g2_id) call H5Gclose_f(g1_id, h5_err) if (error) then call out_io (s_error$, r_name, 'ERROR READING BEAM DATA FROM: ' // file_name, 'ABORTING READ...') diff --git a/bmad/hdf5/hdf5_write_beam.f90 b/bmad/hdf5/hdf5_write_beam.f90 index 0050fc66fd..368f5857dc 100644 --- a/bmad/hdf5/hdf5_write_beam.f90 +++ b/bmad/hdf5/hdf5_write_beam.f90 @@ -33,13 +33,13 @@ subroutine hdf5_write_beam (file_name, bunches, append, error, lat, alive_only) real(rp) f real(rp), allocatable :: rvec(:), p0c(:) -integer(HID_T) f_id, g_id, z_id, z2_id, r_id, b_id, b2_id +integer(HID_T) f_id, g_id, z_id, z2_id, r_id, b_id, b1_id, b2_id integer i, n, ib, ix, h5_err, h_err, ib2 integer, allocatable :: ivec(:) character(*) file_name character(20) date_time, root_path, bunch_path, particle_path, fmt -character(100) this_path +character(100) this_bunch_path character(*), parameter :: r_name = 'hdf5_write_beam' logical, optional :: alive_only @@ -108,12 +108,13 @@ subroutine hdf5_write_beam (file_name, bunches, append, error, lat, alive_only) do ix = index(bunch_path, '%T') ib2 = ib2 + 1 - write (this_path, '(a, i5.5, 2a)') bunch_path(1:ix-1), ib2, trim(bunch_path(ix+2:)) - if (.not. hdf5_exists(r_id, this_path, err, .true.)) exit + write (this_bunch_path, '(a, i5.5, 2a)') bunch_path(1:ix-1), ib2, trim(bunch_path(ix+2:)) + if (.not. hdf5_exists(r_id, this_bunch_path, err, .true.)) exit enddo - call H5Gcreate_f(r_id, trim(this_path), b_id, h5_err) - call H5Gcreate_f(b_id, particle_path, b2_id, h5_err) + call H5Gcreate_f(r_id, trim(this_bunch_path), b_id, h5_err) + call H5Gcreate_f(b_id, particle_path, b1_id, h5_err) + call H5Gcreate_f(b1_id, trim(openpmd_species_name(p(1)%species)), b2_id, h5_err) call hdf5_write_attribute_string(b2_id, 'speciesType', openpmd_species_name(p(1)%species), err) call hdf5_write_attribute_real(b2_id, 'totalCharge', bunch%charge_tot, err) diff --git a/tao/version/tao_version_mod.f90 b/tao/version/tao_version_mod.f90 index d1949df921..bb2c60b3d4 100644 --- a/tao/version/tao_version_mod.f90 +++ b/tao/version/tao_version_mod.f90 @@ -6,5 +6,5 @@ !- module tao_version_mod -character(*), parameter :: tao_version_date = "2024/05/10 15:23:35" +character(*), parameter :: tao_version_date = "2024/05/18 12:55:41" end module