def _loadAnalyzeFile(filename, name, imgObj, task): with f: filename = Future.get(filename) name = name or self.mgr.getUniqueObjName( splitPathExt(filename)[1]) img = imgObj or nibabel.load(filename) dat = dat = np.asanyarray(img.dataobj) hdr = dict(img.get_header()) hdr['filename'] = filename pixdim = hdr['pixdim'] interval = float(pixdim[4]) if interval == 0.0 and len( img.shape) == 4 and img.shape[-1] > 1: interval = 1.0 spacing = vec3(pixdim[1], pixdim[2], pixdim[3]) dat = eidolon.transposeRowsColsNP( dat) # transpose from row-column to column-row obj = self.createObjectFromArray(name, dat, interval, 0, vec3(), rotator(), spacing, task=task) obj.source = hdr f.setObject(obj)
def _loadNiftiFile(filename, name, imgObj, task): with f: filename = Future.get(filename) name = name or self.mgr.getUniqueObjName( splitPathExt(filename)[1]) img = imgObj or nibabel.load(filename) hdr = dict(img.header) hdr['filename'] = filename pixdim = hdr['pixdim'] xyzt_units = hdr['xyzt_units'] x = float(hdr['qoffset_x']) y = float(hdr['qoffset_y']) z = float(hdr['qoffset_z']) b = float(hdr['quatern_b']) c = float(hdr['quatern_c']) d = float(hdr['quatern_d']) toffset = float(hdr['toffset']) interval = float(pixdim[4]) if interval == 0.0 and len( img.shape) == 4 and img.shape[-1] > 1: interval = 1.0 qfac = float(pixdim[0]) or 1.0 spacing = vec3(pixdim[1], pixdim[2], qfac * pixdim[3]) if int(hdr['qform_code']) > 0: position = vec3(-x, -y, z) rot = rotator( -c, b, math.sqrt(max(0, 1.0 - (b * b + c * c + d * d))), -d) * rotator(vec3.Z(), halfpi) else: affine = img.get_affine() position = vec3(-affine[0, 3], -affine[1, 3], affine[2, 3]) rmat = np.asarray([ affine[0, :3] / -spacing.x(), affine[1, :3] / -spacing.y(), affine[2, :3] / spacing.z() ]) rot = rotator(*rmat.flatten().tolist()) * rotator( vec3.Z(), halfpi) xyzunit = xyzt_units & 0x07 # isolate space units with a bitmask of 7 tunit = xyzt_units & 0x38 # isolate time units with a bitmask of 56 if tunit == 0: # if no tunit provided, try to guess if interval < 1.0: tunit = unit_codes['sec'] elif interval > 1000.0: tunit = unit_codes['usec'] # convert to millimeters if xyzunit == unit_codes['meter']: position *= 1000.0 spacing *= 1000.0 elif xyzunit == unit_codes['micron']: position /= 1000.0 spacing /= 1000.0 # convert to milliseconds if tunit == unit_codes['sec']: toffset *= 1000.0 interval *= 1000.0 elif tunit == unit_codes['usec']: toffset /= 1000.0 interval /= 1000.0 dobj = img.dataobj datshape = tuple( d or 1 for d in dobj.shape ) # dimensions are sometimes given as 0 for some reason? # reading file data directly is expected to be faster than using nibabel, specifically by using memmap if filename.endswith('.gz'): dat = img.get_data() #dat=np.asanyarray(dobj) # same as the above # with gzip.open(filename) as o: # TODO: not sure if this is any faster than the above # o.seek(dobj.offset) # seek beyond the header # dat=np.frombuffer(o.read(),dobj.dtype).reshape(datshape,order=dobj.order) else: # mmap the image data below the header in the file dat = np.memmap(dobj.file_like, dobj.dtype, 'r', dobj.offset, datshape, dobj.order) dat = eidolon.transposeRowsColsNP( dat) # transpose from row-column to column-row obj = self.createObjectFromArray(name, dat, interval, toffset, position, rot, spacing, task=task) obj.source = hdr # apply slope since this isn't done automatically when using memmap/gzip if not filename.endswith('.gz'): eidolon.applySlopeIntercept(obj, *img.header.get_slope_inter()) f.setObject(obj)
def _loadFile(filename, name, position=None, rot=None, toffset=None, interval=None, task=None): with f: filename = Future.get(filename) name = name or self.mgr.getUniqueObjName( splitPathExt(filename)[1]) recfile = os.path.splitext(filename)[0] if os.path.exists(recfile + '.rec'): recfile = recfile + '.rec' elif os.path.exists(recfile + '.REC'): recfile = recfile + '.REC' else: raise IOError("Cannot find rec file '%s.rec'" % recfile) geninfo, imginfo = parseParFile(filename) # read par file rec = np.fromfile(recfile, np.uint8) # read rec file # numorients=geninfo[genInfoFields.maxgrad[2]][0] # numslices=geninfo[genInfoFields.maxloc[2]][0] # numsteps=geninfo[genInfoFields.maxphase[2]][0] # slicenum=imgInfoFields.slicenum[-1] # trigger=imgInfoFields.trigger[-1] # numslices=len(set(i[slicenum] for i in imginfo)) # # count the number of times the slice number decreases one slice to the next, this indicates how many times the slice index loops back # numorients=1+sum(1 if imginfo[i][slicenum]>imginfo[i+1][slicenum] else 0 for i in range(len(imginfo)-1)) # # count the number of times the trigger time decreases one slice to the next, this indicates when the images transition between volumes # numvols=1+sum(1 if imginfo[i][trigger]>imginfo[i+1][trigger] else 0 for i in range(len(imginfo)-1))/(numorients*numslices) # if len(imginfo)!=(numvols*numorients*numslices*numsteps): # raise IOError,'Mismatch between stated orient, slice, and step numbers and number of images (%r != %r*%r*%r*%r)'%(len(imginfo),numorients,numslices,numsteps,numvols) # orientsize=len(imginfo)/numorients datasize = 0 objs = [] rpos = 0 typemap = { } # maps type ID to dict mapping dynamic ID to SharedImage lists for imgi in imginfo: # sum up the sizes of each image to compare against the actual size of the rec file w, h = imgi[imgInfoFields.reconres[-1]] pixelsize = imgi[imgInfoFields.imgpix[ -1]] / 8 # convert from bits to bytes datasize += w * h * pixelsize if rec.shape[0] != datasize: raise IOError( 'Rec file incorrect size, should be %i but is %i' % (datasize, rec.shape[0])) for imgi in imginfo: dynamic = imgi[imgInfoFields.dynnum[-1]] itype = imgi[imgInfoFields.imgtypemr[-1]] dims = imgi[imgInfoFields.reconres[-1]] trigger = imgi[imgInfoFields.trigger[-1]] orientation = imgi[imgInfoFields.sliceori[-1]] spacing = imgi[imgInfoFields.pixspace[-1]] offcenter = imgi[imgInfoFields.imgoff[-1]] angulation = imgi[imgInfoFields.imgang[-1]] pixelsize = imgi[imgInfoFields.imgpix[-1]] reslope = imgi[imgInfoFields.rescalesl[-1]] intercept = imgi[imgInfoFields.rescalein[-1]] if itype not in typemap: typemap[itype] = dict() if dynamic not in typemap[itype]: typemap[itype][dynamic] = [] images = typemap[itype][dynamic] dtype = np.dtype('uint' + str(pixelsize)) pos, rot = getTransformFromInfo(offcenter, angulation, orientation, vec3(*spacing), vec3(*dims)) imgsize = dims[0] * dims[1] * dtype.itemsize arr = rec[rpos:rpos + imgsize].view(dtype).reshape(dims) rpos += imgsize if scalemethod in ('dv', 'DV'): arr = (arr.astype(float) * reslope) + intercept # DV scaling method simg = SharedImage(recfile, pos, rot, dims, spacing, trigger) simg.allocateImg('%s_t%i_d%i_img%i' % (name, itype, dynamic, len(images))) #simg.setArrayImg(arr) simg.setMinMaxValues(arr.min(), arr.max()) np.asarray(simg.img)[:, :] = arr images.append(simg) for itype in typemap: for dynamic, images in typemap[itype].items(): vname = '%s_t%i_d%i' % (name, itype, dynamic) source = { 'geninfo': geninfo, 'imginfo': imginfo, 'filename': filename, 'scalemethod': scalemethod, 'loadorder': len(objs) } obj = ImageSceneObject(vname, source, images, self) objs.append(obj) # for numo in range(numorients): # orientimgs=imginfo[numo*orientsize:(numo+1)*orientsize] # # for numv in range(numvols): # volsimgs=[img for i,img in enumerate(orientimgs) if i%numvols==numv] # images=[] # for imgi in volsimgs: # vname='%s_o%i_v%i'%(name,numo,numv) # dims=imgi[imgInfoFields.reconres[-1]] # trigger=imgi[imgInfoFields.trigger[-1]] # orientation=imgi[imgInfoFields.sliceori[-1]] # spacing=imgi[imgInfoFields.pixspace[-1]] # offcenter=imgi[imgInfoFields.imgoff[-1]] # angulation=imgi[imgInfoFields.imgang[-1]] # pixelsize=imgi[imgInfoFields.imgpix[-1]] # # reslope=imgi[imgInfoFields.rescalesl[-1]] # intercept=imgi[imgInfoFields.rescalein[-1]] # # dtype=np.dtype('uint'+str(pixelsize)) # # pos,rot=self._getTransformFromInfo(offcenter,angulation,orientation,vec3(*spacing),vec3(*dims)) # # imgsize=dims[0]*dims[1]*dtype.itemsize # arr=rec[rpos:rpos+imgsize].view(dtype).reshape(dims) # rpos+=imgsize # # if scalemethod in ('dv','DV'): # arr=(arr.astype(float)*reslope)+intercept # DV scaling method # # simg=SharedImage(recfile,pos,rot,dims,spacing,trigger) # simg.allocateImg('%s_img%i'%(vname,len(images))) # simg.setArrayImg(arr) # images.append(simg) # # obj=ImageSceneObject(vname,{'geninfo':geninfo,'imginfo':imginfo,'filename':filename},images,self) # objs.append(obj) assert rpos == rec.shape[0], '%i != %i' % (rpos, rec.shape[0]) f.setObject(objs)