Page History
...
There's currently no function that uses these coordinates for plotting. The pixel coordinate map is mostly useful if you want to find the location of individual spots, e.g. Bragg peaks, in your data. You can then get the x-coordinate from the x_coordinates array using the same indices that you use to get the data value. I.e. you find a peak of interest in quad#2, section#4, row 33, column 102, you'll find the x and y-coordinate from x_coordinates2,4,33,102 and y_coordinates2,4,33,102.
The coordinates
The coordinates of the optical measurements are defined by X, Y, Z, where (0,0,0) is at the nominal beam spot, and X points along the long side of section 1, Y points towards section 3 and Z points downstream. The unit of the measurements are micrometers, but the computed pixel coordinates here have been converted to pixel units (based on the average effective pixel size). Each quad coordinate system is rotated by 90 degrees w.r.t. the next one.
The method (python code)
Here's almost cut'n'paste from the latest XtcExplorer/src/cspad.py. Feel free to use it, and let me know if you have suggestions for improvements.
Code Block | ||||
---|---|---|---|---|
| ||||
import numpy as np import scipy.ndimage.interpolation as interpol x_coordinates = np.zeros((4,8,185,388), dtype="float") y_coordinates = np.zeros((4,8,185,388), dtype="float") z_coordinates = np.zeros((4,8,185,388), dtype="float") def get_asics(bigsection): """Utility function @param bigsection a 185 x 391 section for plotting (has a 3-pixel gap between asics) @return asics the 185 x 388 section array which has the 3-pixel gap removed """ asic0 = bigsection[:,0:194] asic1 = bigsection[:,(391-194):] asics = np.concatenate( (asic0,asic1), axis=1 ) return asics # section pixel array / grid rr,cc = np.mgrid[0:185:185j, 0:391:391j] # now compute the "fractional pixels" rrfrac = rr / 185.0 ccfrac = cc / 391.0 # remove the 3-pixel gap rrfrac = get_asics(rrfrac) ccfrac = get_asics(ccfrac) sec_coords = np.array([rrfrac,ccfrac]) # load data from metrology file (ignore first column) metrology = np.loadtxt("XtcExplorer/calib/CSPad/cspad_2011-08-10-Metrology.txt")[:,1:] metrology = metrology.reshape(4,8,4,3) # also, we need to resort the 2x1 sections, they are # listed in the file in the order 1,0,3,2,4,5,7,6 metrology = metrology[:,(1,0,3,2,4,5,7,6),:,:] # I want the points in a different order: # (firstrow,firstcol), (firstrow,lastcol), (lastrow,firstcol), (lastrow,lastcol) sec_coord_order = [(1,2,0,3),(1,2,0,3),(2,3,1,0),(2,3,1,0),(3,0,2,1),(3,0,2,1),(2,3,1,0),(2,3,1,0)] # collect all pixel widths for averaging dLong = np.zeros((4,8,2), dtype="float64") # pixel size from long side of section dShort = np.zeros((4,8,2), dtype="float64") # pixel size from short side of section # Start looping over quads and sections: for quad in range(4): for sec in range(8): # corner values input_x = metrology[quad,sec,sec_coord_order[sec],0].reshape(2,2) input_y = metrology[quad,sec,sec_coord_order[sec],1].reshape(2,2) input_z = metrology[quad,sec,sec_coord_order[sec],2].reshape(2,2) # interpolate coordinates over to the pixel map x_coordinates[quad,sec] = interpol.map_coordinates(input_x, sec_coords) y_coordinates[quad,sec] = interpol.map_coordinates(input_y, sec_coords) z_coordinates[quad,sec] = interpol.map_coordinates(input_z, sec_coords) # ! in micrometers! Need to convert to pixel units dL = np.array([ abs(input_x[0,1]-input_x[0,0])/391, abs(input_x[1,1]-input_x[1,0])/391, abs(input_y[0,0]-input_y[0,1])/391, abs(input_y[1,0]-input_y[1,1])/391 ]) dLong[quad,sec] = dL[dL>100] # filter out the nonsense ones dS = np.array([ abs(input_y[0,0]-input_y[1,0])/185, abs(input_y[0,1]-input_y[1,1])/185, abs(input_x[0,0]-input_x[1,0])/185, abs(input_x[0,1]-input_x[1,1])/185 ]) dShort[quad,sec] = dS[dS>100] # filter out the nonsense ones dTotal = np.concatenate( (dLong.ravel(), dShort.ravel() )) print "Pixel-size:" print " long side average: %.2f +- %.2f "%( dLong.mean(), dLong.std()) print " short side average: %.2f +- %.2f "%( dShort.mean(), dShort.std()) print " all sides average: %.2f +- %.2f "%( dTotal.mean(), dTotal.std()) # use the total to convert it all to pixel units x_coordinates = x_coordinates / dTotal.mean() y_coordinates = y_coordinates / dTotal.mean() z_coordinates = z_coordinates / dTotal.mean() print "Done making coordinate map of the CSPAD detector." |
...