Skip to content

Commit a27e67f

Browse files
authored
Merge pull request FABLE-3DXRD#487 from jonwright/master
Allow to use VDS for assembling sparse pixels (faster, uses less space, but you can't copy sparsefile around)
2 parents f1766f5 + 6f75fc6 commit a27e67f

File tree

1 file changed

+81
-28
lines changed

1 file changed

+81
-28
lines changed

ImageD11/sinograms/assemble_label.py

Lines changed: 81 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,36 @@ def getsparse(dsobj, num):
6868
return row, col, intensity, nnz
6969

7070

71+
def make_sparse_vds(dsobj, nums, grp,
72+
names = ('row','col','intensity','nnz')):
73+
"""
74+
dsobj = DataSet object
75+
nums = indices of the sparsefiles in dset.sparsefiles
76+
names = data to be linked
77+
78+
create vds links in grp pointing at names in nums
79+
"""
80+
for name in names:
81+
total_size = 0
82+
sources = []
83+
for num in nums:
84+
hname = dsobj.sparsefiles[num]
85+
hfullname = os.path.join( dsobj.analysispath, hname )
86+
with h5py.File(hfullname, "r" ) as hin:
87+
source_array = hin[dsobj.limapath][name]
88+
total_size += len(source_array)
89+
sources.append( h5py.VirtualSource( hname,
90+
dsobj.limapath + '/' + name,
91+
shape = source_array.shape ) )
92+
dt = source_array.dtype
93+
layout = h5py.VirtualLayout( shape=(total_size,), dtype = dt )
94+
start = 0
95+
for source in sources:
96+
layout[ start : start + source.shape[0] ] = source
97+
start += source.shape[0]
98+
grp.create_virtual_dataset(name, layout)
99+
100+
71101
@numba.njit(boundscheck=True)
72102
def filterpixels(cutimage, row, col, intensity, nnz):
73103
"""
@@ -102,7 +132,12 @@ def filterpixels(cutimage, row, col, intensity, nnz):
102132

103133

104134
def harvest_masterfile(
105-
dset, outname, scanmotors=SCANMOTORS, headermotors=HEADERMOTORS, cutimage=None
135+
dset,
136+
outname,
137+
scanmotors=SCANMOTORS,
138+
headermotors=HEADERMOTORS,
139+
cutimage=None,
140+
use_vds=True,
106141
):
107142
"""
108143
dset = ImageD11.sinograms.dataset.DataSet object
@@ -171,40 +206,57 @@ def harvest_masterfile(
171206
print("Loading pixels:", end=" ")
172207
for scan in done:
173208
g = hout.require_group(scan)
174-
for name in "row", "col":
175-
if name not in g:
176-
g.create_dataset(name, shape=(0,), dtype=np.uint16, **opts)
177-
if "intensity" not in g:
178-
g.create_dataset(
179-
"intensity", shape=(0,), dtype=g.attrs["itype"], **opts
180-
)
181209
nfrm = g.attrs["nframes"]
182-
g.require_dataset("nnz", shape=(nfrm,), dtype=np.uint32)
183210
nstart = nread = npx = pstart = 0
184-
while nread < nfrm:
185-
row, col, intensity, nnz = getsparse(dset, idx)
186-
if cutimage is not None:
187-
row, col, intensity, nnz = filterpixels(
188-
cutimage, row, col, intensity, nnz
211+
if use_vds:
212+
assert cutimage is None
213+
# dset.frames_per_file
214+
# dset.frames_per_scan
215+
nums = [idx,]
216+
nread = dset.frames_per_file[idx]
217+
while nread < nfrm:
218+
idx += 1
219+
nums.append( idx )
220+
nread += dset.frames_per_file[idx]
221+
try:
222+
make_sparse_vds(dset, nums, g)
223+
except Exception as e:
224+
print("Error",nums,list(g), scan,e)
225+
raise
226+
idx += 1
227+
else:
228+
g.require_dataset("nnz", shape=(nfrm,), dtype=np.uint32)
229+
for name in "row", "col":
230+
if name not in g:
231+
g.create_dataset(name, shape=(0,), dtype=np.uint16, **opts)
232+
if "intensity" not in g:
233+
g.create_dataset(
234+
"intensity", shape=(0,), dtype=g.attrs["itype"], **opts
189235
)
190-
idx += 1 # loop over sparse files in this scan
191-
nread = nstart + len(nnz) # number of frames in this limafile
192-
g["nnz"][nstart:nread] = nnz
193-
nstart = nread
194-
pread = pstart + len(row) # number of pixels in this limafile
195-
g["row"].resize((pread,))
196-
g["row"][pstart:pread] = row
197-
g["col"].resize((pread,))
198-
g["col"][pstart:pread] = col
199-
g["intensity"].resize((pread,))
200-
g["intensity"][pstart:pread] = intensity
201-
pstart = pread
236+
while nread < nfrm:
237+
row, col, intensity, nnz = getsparse(dset, idx)
238+
if cutimage is not None:
239+
row, col, intensity, nnz = filterpixels(
240+
cutimage, row, col, intensity, nnz
241+
)
242+
idx += 1 # loop over sparse files in this scan
243+
nread = nstart + len(nnz) # number of frames in this limafile
244+
g["nnz"][nstart:nread] = nnz
245+
nstart = nread
246+
pread = pstart + len(row) # number of pixels in this limafile
247+
g["row"].resize((pread,))
248+
g["row"][pstart:pread] = row
249+
g["col"].resize((pread,))
250+
g["col"][pstart:pread] = col
251+
g["intensity"].resize((pread,))
252+
g["intensity"][pstart:pread] = intensity
253+
pstart = pread
202254
print(scan, end=", ")
203255
print()
204256
return outname
205257

206258

207-
def main(dsname, outname=None, cutimage=None):
259+
def main(dsname, outname=None, cutimage=None, use_vds=False):
208260
"""
209261
dsname = Dataset describing the masterfile + segmentation etc
210262
outname = sparse pixels file to write. Defaults to dset.sparsefile
@@ -216,8 +268,9 @@ def main(dsname, outname=None, cutimage=None):
216268
if outname is None:
217269
outname = dset.sparsefile
218270
if cutimage is not None:
271+
assert (not use_vds)
219272
cutimage = fabio.open(cutimage).data
220-
harvest_masterfile(dset, outname, cutimage=cutimage)
273+
harvest_masterfile(dset, outname, cutimage=cutimage, use_vds=use_vds)
221274

222275

223276
if __name__ == "__main__":

0 commit comments

Comments
 (0)