def test_speeds(): # This very superficial test checks that calculate_speeds is able to # execute (no syntax errors) n = 101 IM = np.random.randn(n, n) calculate_speeds(IM)
r2 = rows//2 # half-height image size c2 = cols//2 # half-width image size print ('image size {:d}x{:d}'.format(rows,cols)) # Hansen & Law inverse Abel transform print('Performing Hansen and Law inverse Abel transform:') AIM = iabel_hansenlaw(IM) #,dr=1, use_quadrants=(True,True,True,True), #vertical_symmetry=False, horizontal_symmetry=False, #verbose=True) # PES - photoelectron speed distribution ------------- print('Calculating speed distribution:') speed, r, theta = calculate_speeds(AIM) #origin=None, Jacobian=False, dr=None, dt=None) # normalize to max intensity peak speed /= speed[200:].max() #exclude nose close to center # PAD - photoelectron angular distribution ------------ print('Calculating angular distribution:') # radial ranges (of spectral features) to follow intensity vs angle # view the speed distribution to determine radial ranges r_range=[(93,111),(145,162),(255,280),(330,350),(350,370),(370,390), (390,410),(410,430)] # map to intensity vs theta for each radial range theta, intensities = calculate_angular_distributions(AIM, radial_ranges=r_range)
r2 = rows // 2 # half-height image size c2 = cols // 2 # half-width image size print('image size {:d}x{:d}'.format(rows, cols)) # Hansen & Law inverse Abel transform print('Performing Hansen and Law inverse Abel transform:') AIM = iabel_hansenlaw(IM) #,dr=1, use_quadrants=(True,True,True,True), #vertical_symmetry=False, horizontal_symmetry=False, #verbose=True) # PES - photoelectron speed distribution ------------- print('Calculating speed distribution:') speed, r, theta = calculate_speeds(AIM) #origin=None, Jacobian=False, dr=None, dt=None) # normalize to max intensity peak speed /= speed[200:].max() #exclude nose close to center # PAD - photoelectron angular distribution ------------ print('Calculating angular distribution:') # radial ranges (of spectral features) to follow intensity vs angle # view the speed distribution to determine radial ranges r_range = [(93, 111), (145, 162), (255, 280), (330, 350), (350, 370), (370, 390), (390, 410), (410, 430)] # map to intensity vs theta for each radial range theta, intensities = calculate_angular_distributions(AIM, radial_ranges=r_range)
def test_speeds_non_integer_center(): # ensures that the rest speeds function can work with a non-integer center n = 101 IM = np.random.randn(n, n) calculate_speeds(IM, origin=(50.5, 50.5))
def iabel_hansenlaw (data,quad=(True,True,True,True),calc_speeds=True,verbose=True): """ Helper function for Hansen Law inverse Abel transform. (1) split image into quadrants (optional) exploit symmetry and co-add selected quadrants together (2) inverse Abel transform of quadrant (iabel_hansenlaw_transform) (3) reassemble image for co-add all inverted quadrants are identical (4) (optionally) calculate the radial integration of the image (calc_speeds) Parameters: ---------- - data: a NxN numpy array - quad: boolean tuple, (Q0,Q1,Q2,Q3) image is inverted one quadrant at a time +--------+--------+ | Q1 * | * Q0 | | * | * | | * | * | +--------+--------+ | * | * | | * | * | | Q2 * | * Q3 | +--------+--------+ NB may exploit image symmetry, all quadrants are equivalent, co-add (1) quad.any() = False (FALSE,FALSE,FALSE,FALSE) => inverse Abel transform for each quadrant inverse image AQ1 | AQ0 AQi == inverse Abel transform --------- of quadrant Q0 AQ2 | AQ3 (2) quad.any() = True exploits image symmetry to improve signal sum True quadrants Q = Q0 + Q1 + Q2 + Q3 (True,True,True,True) or Q = Q0 + Q1 + Q2 (True,True,True,False) etc inverse image AQ | AQ all quadrants are equivalent ------- AQ | AQ - calc_speeds: boolean, evaluate speed profile - verbose: boolean, more output, timings etc. """ verboseprint = print if verbose else lambda *a, **k: None if data.ndim == 1 or np.shape(data)[0] <= 2: raise ValueError('Data must be 2-dimensional. To transform a single row, use iabel_hansenlaw_transform().') (N,M) = np.shape(data) verboseprint ("HL: Calculating inverse Abel transform:", " image size {:d}x{:d}".format(N,M)) t0=time() # split image into quadrants Q = get_image_quadrants(data, reorient=True) (N2,M2) = Q[0].shape # quadrant size AQ = [] # empty reconstructed image # combine selected quadrants into one or loop through if none if np.any(quad): verboseprint ("HL: Co-adding quadrants") Qcombined = Q[0]*quad[0]+Q[1]*quad[1]+Q[2]*quad[2]+Q[3]*quad[3] Q = (Qcombined,) # one combined quadrant else: verboseprint ("HL: Individual quadrants") verboseprint ("HL: Calculating inverse Abel transform ... ") # HL inverse Abel transform for quadrant 0 AQ.append(iabel_hansenlaw_transform(Q[0])) if np.any(quad): for q in (1,2,3): AQ.append(AQ[0]) # if symmetry is applied, all quadrants the same else: # otherwise, take the inverse Abel transform of the remaining quadrants individually for q in (1,2,3): AQ.append(iabel_hansenlaw_transform(Q[q])) # reform image recon = put_image_quadrants(AQ,odd_size=N%2) verboseprint ("{:.2f} seconds".format(time()-t0)) if calc_speeds: verboseprint('Generating speed distribution ...') t1 = time() image_centre = (N2,N2) if N2%2 else (N2-0.5,N2-0.5) speeds = calculate_speeds(recon,origin=image_centre) verboseprint('{:.2f} seconds'.format(time() - t1)) return recon, speeds else: return recon