def make_indices(self): arshape = self.dims[0]/2+1, self.dims[1] nv = (arshape[0]-1)*2 nh = arshape[0] print("NV,NH",nv,nh) self.ftimshape = (nv, nh) self.ftimlen = nv*nh n1 = (self.dims[0]/2+1)*self.dims[1] xv = numpy.arange(0, self.dims[0]/2+1, 1, dtype=numpy.float32 ) # dimensions? cth = numpy.cos( self.theta ) # 1D sth = numpy.sin( self.theta ) # 1D ia = numpy.round(numpy.outer( cth, xv )).astype(numpy.int) ja = numpy.round(numpy.outer( sth, xv )).astype(numpy.int) on = numpy.array([1.0],numpy.float32) jm = numpy.where(ja < 0, -on, on) numpy.multiply( ia, jm, ia ) # if j<0: i=-i numpy.multiply( ja, jm, ja ) # if j<0: j=-j # if j<0: f=f.conj() ia = numpy.where( ia < 0, nv+ia, ia) inds = (ia*nh + ja).ravel() self.conjer = jm self.inds = inds nim = numpy.zeros( ( nv* nh), numpy.float32 ) wons = numpy.ones( (len(inds)), dtype=numpy.float32 ) # This is now more dense - bincount? closest.put_incr( nim , inds, wons ) nim = nim.astype(numpy.int) self.nim_div = nim + (nim==0)
def test_put(self): data = np.zeros(10,np.float32) ind = np.arange(10).astype(np.intp) vals = np.ones(10,np.float32) closest.put_incr( data, ind, vals ) assert (data == vals).all() closest.put_incr( data, ind, vals ) assert (data == 2*vals).all()
def test_as_flat(self): data = np.zeros( (10, 10), np.float32 ) ind = np.ones( 10 , np.intp)*50 vals = np.ones( 10 , np.float32) closest.put_incr( np.ravel(data) , ind, vals ) assert ( np.ravel(data)[50] == 10 ) assert ( np.ravel(data)[49] == 0 ) assert ( np.ravel(data)[51] == 0 )
def test_put_twice(self): data = np.zeros(10,np.float32) ind = np.ones(10,np.intp) vals = np.ones(10,np.float32) closest.put_incr( data, ind, vals ) assert (data == np.array( [0, 10] + [0]*8 , np.float)).all() closest.put_incr( data, ind, vals ) assert (data == np.array( [0, 20] + [0]*8 , np.float)).all()
def process_sinogram( self, sinogram, do_interpolation=False): """ sinogram is from the data dimensions [npixels, nangles] do_interp - tries to fill in some of the missing data in fourier space returns the radon transform """ assert sinogram.shape == self.dims ar = numpy.fft.rfft(sinogram, axis=0) faprojr = (ar.T.real.astype(numpy.float32)) faprojc = (ar.T.imag.astype(numpy.float32)) numpy.multiply( faprojc, self.conjer, faprojc) fimr = numpy.zeros( self.ftimlen , numpy.float32 ) fimc = numpy.zeros( self.ftimlen , numpy.float32 ) closest.put_incr( fimr, self.inds, faprojr.ravel()) closest.put_incr( fimc, self.inds, faprojc.ravel()) fim = fimr + fimc*1j fim = numpy.divide( fimr + fimc*1j, self.nim_div) fim.shape = self.ftimshape return fim
def gv_to_grid_new(self, gv): """ Put gvectors into our grid gv - ImageD11.indexing gvectors """ # Compute hkl indices in the fft unit cell logging.info("Gridding data") self.gv = gv hrkrlr = self.cell_size * gv hkl = numpy.floor(hrkrlr + 0.5).astype(numpy.int) # Filter to have the peaks in asym unit # ... do we need to do this? What about wrapping? hmx = numpy.where( hkl.max(axis=1) < self.np/2 - 2., 1, 0 ) hmn = numpy.where( hkl.min(axis=1) > -self.np/2 + 2., 1, 0 ) my_g = numpy.compress( hmx & hmn, gv, axis=0 ) # Compute hkl indices in the fft unit cell using filtered peaks hrkrlr = self.cell_size * my_g # Integer part of hkl (eg 1.0 from 1.9) hkl = numpy.floor(hrkrlr).astype(numpy.int) # Fractional part of indices ( eg 0.9 from 1.9) remain = hrkrlr - hkl grid = self.grid import time start = time.time() # Loop over corners with respect to floor corner ng = grid.shape[0]*grid.shape[1]*grid.shape[2] flatgrid = grid.reshape( ng ) for cor in [ (0,0,0), #1 (1,0,0), #2 (0,1,0), #3 (0,0,1), #4 (1,1,0), #5 (1,0,1), #6 (0,1,1), #7 (1,1,1) ]: #8 # The corner thkl = hkl + cor fac = 1 - numpy.absolute(remain - cor) vol = numpy.absolute(fac[:,0]*fac[:,1]*fac[:,2]).astype(numpy.float32) thkl = numpy.where(thkl < 0, self.np + thkl, thkl) ind = thkl[:,0]*grid.shape[1]*grid.shape[2] + \ thkl[:,1]*grid.shape[1] + \ thkl[:,2] closest.put_incr( flatgrid , ind.astype(numpy.intp), vol ) # print thkl,vol # vals = numpy.take(grid.flat, ind) # print "vals",vals # vals = vals + vol # print "vol",vol # print "ind",ind # FIXME # This is wrong - if ind repeats several times we # only take the last value # numpy.put(grid, ind, vals) # print numpy.argmax(numpy.argmax(numpy.argmax(grid))) # print grid[0:3,-13:-9,-4:] logging.warn("Grid filling loop takes "+str(time.time()-start)+" /s")
def add_image(self, om, data): """ RSV = bounds of reciprocal space vol NR = dims of RSV k = scattering vector for image at om == 0 data = 2D image (dims == k.dims) SIG = signal MON = monitor """ dat = numpy.ravel(data).astype(numpy.float32) assert len(dat) == len(self.k[0]), "dimensioning issue" # hkl = ubi.( gtok. k ) gvm = transform.compute_g_from_k( numpy.eye(3), # this transform module sucks om * float(self.pars.get('omegasign')), wedge=float(self.pars.get('wedge')), chi=float(self.pars.get('chi'))) tmat = numpy.dot(self.uspace, gvm) hkls = numpy.dot(tmat, self.k) # Find a way to test if we are doing the transform OK # Bounds checks # for i in range(3): # assert hkls[i].min() > self.bounds[i][0], \ # "%d %s %s"%(i, str(hkls[i].min()),str( self.bounds[i][0])) # assert hkls[i].max() < self.bounds[i][1], \ # "%d %s %s"%(i, str(hkls[i].max()),str( self.bounds[i][1])) NR = self.rsv.NR # hkls[0] is the slowest index. integer steps of NR[1]*NR[2] ind = numpy.floor(hkls[0] + 0.5 - self.bounds[0][0]).astype(numpy.intp) numpy.multiply(ind, NR[1] * NR[2], ind) assert ind.dtype == numpy.intp # hkls[1] is faster. Steps by NR[2] only numpy.add( ind, NR[2] * numpy.floor(hkls[1] + 0.5 - self.bounds[1][0]).astype(numpy.int32), ind) numpy.add( ind, numpy.floor(hkls[2] + 0.5 - self.bounds[2][0]).astype(numpy.int32), ind) # # # if self.maxpix is not None: msk = numpy.where(dat > self.maxpix, 0, 1).astype(numpy.uint8) else: msk = None if self.mask is not None: # This excludes saturated pixels if msk is None: msk = self.mask else: numpy.multiply(msk, numpy.ravel(self.mask), msk) # cases: # maxpix only == msk # mask only == msk # maxpix and mask == msk # neither if msk is not None: numpy.multiply(dat, msk, dat) closest.put_incr(self.rsv.SIG, ind, dat) closest.put_incr(self.rsv.MON, ind, self.lorfac * msk) else: closest.put_incr(self.rsv.SIG, ind, dat) closest.put_incr(self.rsv.MON, ind, self.lorfac) return
def main(): """ A CLI user interface """ import sys, time, os, logging start = time.time() root = logging.getLogger('') root.setLevel(logging.WARNING) try: from optparse import OptionParser parser = OptionParser() parser = get_options(parser) options, args = parser.parse_args() except SystemExit: raise except: parser.print_help() print("\nProblem with your options:") raise if options.mask is not None: fit2dmask = (1 - openimage(options.mask).data).ravel() else: fit2dmask = 1.0 first_image = True imagefiles = ImageD11_file_series.get_series_from_options(options, args) tthvals = numpy.load(options.lookup + "_tth.npy") try: for fim in imagefiles: dataim = fim.data print(fim.filename) if first_image: # allocate volume, compute k etc first_image = False dxim = openimage(options.lookup + "_dx.edf").data dyim = openimage(options.lookup + "_dy.edf").data outsum = numpy.ravel(numpy.zeros(dataim.shape, numpy.float32)) outnp = numpy.ravel(numpy.zeros(dataim.shape, numpy.float32)) e = edfimage() # C code from rsv_mapper (not intended to be obfuscated) o = blobcorrector.perfect() idealx, idealy = o.make_pixel_lut(dataim.shape) destx, desty = idealx + dxim, idealy + dyim assert destx.min() >= 0 assert destx.max() < dataim.shape[1] assert desty.min() >= 0 assert desty.max() < dataim.shape[1] imageshape = dataim.shape indices = numpy.ravel(destx).astype(numpy.intp) numpy.multiply(indices, dataim.shape[1], indices) numpy.add(indices, numpy.ravel(desty).astype(numpy.intp), indices) assert indices.min() >= 0 assert indices.max() < dataim.shape[0] * dataim.shape[1] on = numpy.ones(len(outnp), numpy.float32) if fit2dmask is not None: on = on * fit2dmask # Number of pixels and mask are constant closest.put_incr(outnp, indices, on) mask = outnp < 0.1 scalar = (1.0 - mask) / (outnp + mask) flatshape = outsum.shape # arsorted = mask.copy() outmask = mask.copy() outmask = outmask * 1e6 outmask.shape = imageshape arsorted.shape = imageshape arsorted.sort(axis=1) minds = numpy.array([l.searchsorted(0.5) for l in arsorted]) # ENDIF firstimage start = time.time() numpy.multiply(outsum, 0, outsum) outsum.shape = flatshape dm = (dataim.ravel() * fit2dmask).astype(numpy.float32) closest.put_incr(outsum, indices, dm) # outsum = outsum.reshape( dataim.shape ) # outnp = outnp.reshape( dataim.shape ).astype(numpy.int32) # Normalise numpy.multiply(outsum, scalar, outsum) print(dataim.max(), dataim.min(), end=' ') print(scalar.max(), scalar.min(), outsum.min(), outsum.max()) outsum.shape = imageshape # saving edf e.data = outsum e.write("r_" + fim.filename, force_type=numpy.float32) print(time.time() - start) except: raise
def update_wtd( recon, proj, angle, msk, dbg=True ): """ recon is the current reconstruction proj is a projection at angle (degrees) the middle pixel of proj matches the middle pixel of recon TODO: angle + offset as more general geometric term """ assert len(recon.shape) == 2 assert len(proj.shape) == 1 rads = angle * np.pi / 180.0 cth = np.cos( rads ).astype(np.float32) sth = np.sin( rads ).astype(np.float32) # For each pixel in recon, compute the array index in proj nx = recon.shape[0] ny = recon.shape[1] x , y = np.mgrid[ -nx/2:nx/2, -ny/2:ny/2 ] # pos is a 2D array of positions in reconstruction pos = np.zeros( x.shape, np.float32).ravel() np.add( x.ravel()*cth, y.ravel()*sth, pos) # Lower & upper pixel: idx_lo = np.floor(pos).astype(np.int) idx_hi = idx_lo+1 # idx will go from -xxx to xxx mn = idx_lo.min() mx = idx_hi.max()+1 # Weights: wt_lo = np.subtract( idx_hi, pos, np.zeros( pos.shape, np.float32) ) wt_hi = np.subtract( pos, idx_lo, np.zeros( pos.shape, np.float32) ) wt_lo = np.where(msk.ravel(), wt_lo, 0) wt_hi = np.where(msk.ravel(), wt_hi, 0) # wtc = wt_lo + wt_hi calc_proj = np.zeros( (mx-mn), np.float32 ) r = recon.ravel() np.subtract( idx_lo, mn, idx_lo) # Move these to offsets in calc_proj np.subtract( idx_hi, mn, idx_hi) closest.put_incr( calc_proj, idx_lo, r*wt_lo ) closest.put_incr( calc_proj, idx_hi, r*wt_hi ) error = np.zeros( calc_proj.shape, np.float32 ) start = (len(calc_proj)- len(proj))/2 error[ start:start+len(proj) ] = proj error = error - calc_proj npcalc_proj = np.zeros( (mx-mn), np.float32 ) closest.put_incr( npcalc_proj, idx_hi, wt_hi ) closest.put_incr( npcalc_proj, idx_lo, wt_lo ) npcalc_proj = np.where(npcalc_proj >0 ,npcalc_proj, 1) update = np.zeros( r.shape, np.float32) update = wt_hi*np.take( error/npcalc_proj, idx_hi ) update += wt_lo*np.take( error/npcalc_proj, idx_lo ) # Now make calc_proj align with the supplied proj. # Convention will be to make the central pixel of our image # match the central pixel of proj. Logically this is the central # pixel of calc_proj too... # Now take this error off of recon according to the weights #tot = np.zeros( (mx-mn), np.float32 ) #closest.put_incr( tot, idx_hi, wt_hi) #closest.put_incr( tot, idx_lo, wt_lo) #pl.imshow(np.reshape(update,recon.shape)) #pl.colorbar() #pl.show() update = update update.shape = recon.shape print(update.sum(),error.sum(), end=' ') if dbg: pl.figure() pl.imshow( np.reshape(update, recon.shape) ) pl.colorbar() # pl.show() return update