def test_blockav2d(self): out = xu.blockAverage2D(self.seq2d, self.n2d[0], self.n2d[1]) self.assertAlmostEqual( out[0, 0], numpy.average(self.seq2d[0:self.n2d[0], 0:self.n2d[1]])) self.assertEqual( out.shape, (numpy.ceil(self.seq2d.shape[0] / float(self.n2d[0])), numpy.ceil(self.seq2d.shape[1] / float(self.n2d[1]))))
def getimage(fname, hotpixelmap, roi=None): cbf = xu.io.CBFFile(fname) ccdr = removehotpixel(cbf.data, hotpixelmap) ccd = xu.blockAverage2D(ccdr, 1, 1, roi=roi) if ccd.max() / ccd.mean() < 1e2: print('no clear maximum in %s?' % fname) ccd[ccd < 2 * ccd.mean()] = 0 # make center of mass position easier return ccd
def rawmap(specfile, scannr, experiment, angdelta=None, U=identity(3), norm=True): """ read ccd frames and and convert them in reciprocal space angular coordinates are taken from the spec file. A single or multiple scan-numbers can be given. """ [mu, eta, phi, nu, delta, ty, tz, ccdn] = xu.io.getspec_scan( specfile, scannr, 'mu', 'eta', 'phi', 'nu', 'del', 'mpxy', 'mpxz', 'mpx4inr') idx = 0 nav = experiment._A2QConversion._area_nav roi = experiment._A2QConversion._area_roi if not isinstance(scannr, collections.Iterable): scannr = [scannr, ] for snr in scannr: specscan = getattr(specfile, 'scan%d' % snr) ccdfiletmp = getmpx4_filetmp(specscan) en = getmono_energy(specscan) experiment.energy = en for j in range(len(specscan.data)): i = ccdn[idx] # read ccd image from EDF file e = xu.io.EDFFile(ccdfiletmp % i) ccd = deadpixelkill(e.data) # normalize ccd-data (optional) # create data for normalization if norm: d = {'CCD': ccd, 'exp1': specscan.data['exp1'][idx], 'Seconds': specscan.data['Seconds'][idx]} ccd = xid01_normalizer(d) CCD = xu.blockAverage2D(ccd, nav[0], nav[1], roi=roi) if idx == 0: intensity = zeros((len(ccdn), ) + CCD.shape) intensity[idx, :, :] = CCD idx += 1 # transform scan angles to reciprocal space coordinates for all detector # pixels if angdelta is None: qx, qy, qz = experiment.Ang2Q.area(mu, eta, phi, nu, delta, ty, tz, UB=U) else: qx, qy, qz = experiment.Ang2Q.area(mu, eta, phi, nu, delta, ty, tz, delta=angdelta, UB=U) return qx, qy, qz, intensity
def load_file(start_img, current_img, mydetector, region=None): # global index # for testing, to simulate ongoing measurement if region is None: if mydetector == 0: region = [0, 2164, 0, 1030] elif mydetector == 1: region = [0, 516, 0, 516] frame_nb = current_img - start_img rawdata = np.zeros( (frame_nb, region[1] - region[0], region[3] - region[2])) for idx in range(frame_nb): i = start_img + idx e = fabio.open(ccdfiletmp % i) ccdraw = e.data ccd = xu.blockAverage2D(ccdraw, nav[0], nav[1], roi=region) rawdata[idx, :, :] = ccd return rawdata
frame_id = mpx4inr edf_file_template = "/data/id01/inhouse/data/IHR/ihhc3586/id01/detector/" \ + "2021_01_21_151602_platinum/data_mpx4_{id:0>5d}.edf.gz" roi = [0, 516, 0, 516] nav = [1, 1] frames_nb = len(frame_id) frames = np.empty((frames_nb, roi[1], roi[3])) x_com = np.empty((frames_nb)) y_com = np.empty((frames_nb)) for i, id in enumerate(frame_id): edf_data = xu.io.EDFFile(edf_file_template.format(id=int(id))).data ccdraw = xu.blockAverage2D(edf_data, nav[0], nav[1], roi=roi) frames[i] = scipy.signal.medfilt2d(ccdraw, [3, 3]) x_com[i], y_com[i] = center_of_mass(ccdraw) detector_figure = plt.figure(figsize=(5, 5)) ax1 = detector_figure.add_subplot() ax1.imshow(np.log10(frames.sum(axis=0))) com_figure, ax = plt.subplots(1, 2, figsize=(8, 3)) ax[0].plot(delta, x_com) ax[0].set_xlabel("delta") ax[0].set_ylabel("COM in x") ax[1].plot(nu, y_com) ax[1].set_xlabel("nu")
def rawmap(self,scans, angdelta=[0,0,0,0,0], adframes=None, mask = None): """ read ad frames and and convert them in reciprocal space angular coordinates are taken from the spec file or read from the edf file header when no scan number is given (scannr=None) """ if mask is None: mask_was_none = True #mask = [True] * len(self.getImageToBeUsed()[scans[0]]) else: mask_was_none = False #sd = spec.SpecDataFile(self.specFile) intensity = np.array([]) # fourc goniometer in fourc coordinates # convention for coordinate system: # x: upwards; # y: along the incident beam; # z: "outboard" (makes coordinate system right-handed). # QConversion will set up the goniometer geometry. # So the first argument describes the sample rotations, the second the # detector rotations and the third the primary beam direction. qconv = xu.experiment.QConversion(self.getSampleCircleDirections(), \ self.getDetectorCircleDirections(), \ self.getPrimaryBeamDirection()) # define experimental class for angle conversion # # ipdir: inplane reference direction (ipdir points into the primary beam # direction at zero angles) # ndir: surface normal of your sample (ndir points in a direction # perpendicular to the primary beam and the innermost detector # rotation axis) en = self.getIncidentEnergy() hxrd = xu.HXRD(self.getInplaneReferenceDirection(), \ self.getSampleSurfaceNormalDirection(), \ en=en[self.getAvailableScans()[0]], \ qconv=qconv) # initialize area detector properties if (self.getDetectorPixelWidth() != None ) and \ (self.getDistanceToDetector() != None): hxrd.Ang2Q.init_area(self.getDetectorPixelDirection1(), \ self.getDetectorPixelDirection2(), \ cch1=self.getDetectorCenterChannel()[0], \ cch2=self.getDetectorCenterChannel()[1], \ Nch1=self.getDetectorDimensions()[0], \ Nch2=self.getDetectorDimensions()[1], \ pwidth1=self.getDetectorPixelWidth()[0], \ pwidth2=self.getDetectorPixelWidth()[1], \ distance=self.getDistanceToDetector(), \ Nav=self.getNumPixelsToAverage(), \ roi=self.getDetectorROI()) else: hxrd.Ang2Q.init_area(self.getDetectorPixelDirection1(), \ self.getDetectorPixelDirection2(), \ cch1=self.getDetectorCenterChannel()[0], \ cch2=self.getDetectorCenterChannel()[1], \ Nch1=self.getDetectorDimensions()[0], \ Nch2=self.getDetectorDimensions()[1], \ chpdeg1=self.getDetectorChannelsPerDegree()[0], \ chpdeg2=self.getDetectorChannelsPerDegree()[1], \ Nav=self.getNumPixelsToAverage(), roi=self.getDetectorROI()) angleNames = self.getAngles() scanAngle = {} for i in range(len(angleNames)): scanAngle[i] = np.array([]) offset = 0 imageToBeUsed = self.getImageToBeUsed() monitorName = self.getMonitorName() monitorScaleFactor = self.getMonitorScaleFactor() filterName = self.getFilterName() filterScaleFactor = self.getFilterScaleFactor() for scannr in scans: if self.haltMap: raise ProcessCanceledException("Process Canceled") scan = self.sd.scans[str(scannr)] angles = self.getGeoAngles(scan, angleNames) scanAngle1 = {} scanAngle2 = {} for i in range(len(angleNames)): scanAngle1[i] = angles[:,i] scanAngle2[i] = [] if monitorName != None: monitor_data = scan.data.get(monitorName) if monitor_data is None: raise IOError("Did not find Monitor source '" + \ monitorName + \ "' in the Spec file. Make sure " + \ "monitorName is correct in the " + \ "instrument Config file") if filterName != None: filter_data = scan.data.get(filterName) if filter_data is None: raise IOError("Did not find filter source '" + \ filterName + \ "' in the Spec file. Make sure " + \ "filterName is correct in the " + \ "instrument Config file") # read in the image data arrayInitializedForScan = False foundIndex = 0 if mask_was_none: mask = [True] * len(self.getImageToBeUsed()[scannr]) for ind in range(len(scan.data[list(scan.data.keys())[0]])): if imageToBeUsed[scannr][ind] and mask[ind]: # read tif image im = Image.open(self.imageFileTmp % (scannr, scannr, ind)) img = np.array(im.getdata()).reshape(im.size[1],im.size[0]).T img = self.hotpixelkill(img) ff_data = self.getFlatFieldData() if not (ff_data is None): img = img * ff_data # reduce data siz img2 = xu.blockAverage2D(img, self.getNumPixelsToAverage()[0], \ self.getNumPixelsToAverage()[1], \ roi=self.getDetectorROI()) # apply intensity corrections if monitorName != None: img2 = img2 / monitor_data[ind] * monitorScaleFactor if filterName != None: img2 = img2 / filter_data[ind] * filterScaleFactor # initialize data array if not arrayInitializedForScan: imagesToProcess = [imageToBeUsed[scannr][i] and mask[i] for i in range(len(imageToBeUsed[scannr]))] if not intensity.shape[0]: intensity = np.zeros((np.count_nonzero(imagesToProcess),) + img2.shape) arrayInitializedForScan = True else: offset = intensity.shape[0] intensity = np.concatenate( (intensity, (np.zeros((np.count_nonzero(imagesToProcess),) + img2.shape))), axis=0) arrayInitializedForScan = True # add data to intensity array intensity[foundIndex+offset,:,:] = img2 for i in range(len(angleNames)): # logger.debug("appending angles to angle2 " + # str(scanAngle1[i][ind])) scanAngle2[i].append(scanAngle1[i][ind]) foundIndex += 1 if len(scanAngle2[0]) > 0: for i in range(len(angleNames)): scanAngle[i] = \ np.concatenate((scanAngle[i], np.array(scanAngle2[i])), \ axis=0) # transform scan angles to reciprocal space coordinates for all detector pixels angleList = [] for i in range(len(angleNames)): angleList.append(scanAngle[i]) if self.ubMatrix[scans[0]] is None: qx, qy, qz = hxrd.Ang2Q.area(*angleList, \ roi=self.getDetectorROI(), Nav=self.getNumPixelsToAverage()) else: qx, qy, qz = hxrd.Ang2Q.area(*angleList, \ roi=self.getDetectorROI(), Nav=self.getNumPixelsToAverage(), \ UB = self.ubMatrix[scans[0]]) # apply selected transform qxTrans, qyTrans, qzTrans = \ self.transform.do3DTransform(qx, qy, qz) return qxTrans, qyTrans, qzTrans, intensity
def gridmap(specfile, scan_nb, mydetector, region=None, myflatfield=None, myhotpixels=None, reload=0, previous_data=None, previous_mask=None, mysetup='ID01', myrocking_angle="outofplane", follow_bragg=0, myenergy=None, myoffsets=(0, 0, 0, 0, 0)): """ Load the data, check for saturated pixels, interpolate on an orthogonal grid :param specfile: :param scan_nb: :param mydetector: "Eiger4M" or "Eiger2M" or "Maxipix" :param region: roi on the detector :param myflatfield: 2D array, flatfield correction for the detector :param myhotpixels: 2D array, detector hotpixels to be masked :param reload: 1 when you reload the data :param previous_data: when you reload the data :param previous_mask: when you reload the data :param mysetup: 'ID01' or 'SIXS' or 'CRISTAL', different data loading method :param myrocking_angle: name of the motor which is tilted during the rocking curve :param follow_bragg: for energy_scan, set to 1 if the detector is scanned to follow the Bragg peak (delta @ ID01) :param myenergy: energy in eV of the experiment, in case it is not in the spec file :param myoffsets: sample and detector offsets for xrayutilities :return: """ global sixs_beta, nb_pixel_x, nb_pixel_y if region is None: if mydetector == "Eiger2M": region = [0, nb_pixel_y, 0, nb_pixel_x] elif mydetector == "Maxipix": region = [0, nb_pixel_y, 0, nb_pixel_x] elif mydetector == "Eiger4M": region = [0, nb_pixel_y, 0, nb_pixel_x] else: region = [0, nb_pixel_y, 0, nb_pixel_x] if mysetup == 'ID01': motor_names = specfile[str(scan_nb) + '.1'].motor_names # positioners motor_positions = specfile[str(scan_nb) + '.1'].motor_positions # positioners labels = specfile[str(scan_nb) + '.1'].labels # motor scanned labels_data = specfile[str(scan_nb) + '.1'].data # motor scanned chi = 0 delta = motor_positions[motor_names.index('del')] nu = motor_positions[motor_names.index('nu')] if myrocking_angle == "outofplane": eta = labels_data[labels.index('eta'), :] phi = motor_positions[motor_names.index('phi')] myenergy = motor_positions[motor_names.index('nrj')] # in kev elif myrocking_angle == "inplane": phi = labels_data[labels.index('phi'), :] eta = motor_positions[motor_names.index('eta')] myenergy = motor_positions[motor_names.index('nrj')] # in kev elif myrocking_angle == "energy": myenergy = labels_data[labels.index('energy'), :] # in kev if follow_bragg == 1: delta = labels_data[labels.index('del'), :] # TODO: understand why Qx is positive phi = motor_positions[motor_names.index('phi')] eta = motor_positions[motor_names.index('eta')] else: print("Error in rocking angle definition") sys.exit() myenergy = myenergy * 1000.0 # switch to eV if isinstance(myenergy, float) and myenergy < 0: print("Energy not correctly defined in spec file, default to 9keV") myenergy = 9000.0 elif mysetup == 'SIXS': mydataset = nxsReady.DataSet(datadir + ccdfiletmp % scan_nb, ccdfiletmp % scan_nb, scan="SBS") img = mydataset.mfilm[1:, :, :] # first frame is duplicated delta = mydataset.delta[1:].mean() # not scanned gamma = mydataset.gamma[1:].mean() # not scanned mu = mydataset.mu[1:] elif mysetup == 'CRISTAL': omega = specfile['a']['scan_data']['actuator_1_1'][:] / 1e6 delta = specfile['a/CRISTAL/I06-C-C07__EX__DIF-DELTA__#1/raw_value'][:] nu = specfile['a/CRISTAL/I06-C-C07__EX__DIF-GAMMA__#1/raw_value'][:] maxpix_img = specfile['a']['scan_data']['data_04'][:] elif mysetup == 'P10': # TODO: find motors in specfile mu = [] for index in range(25): # header specfile.readline() for index, myline in enumerate(specfile, 0): myline = myline.strip() mycolumns = myline.split() if mycolumns[0] == '!': break mu.append(mycolumns[0]) mu = np.asarray(mu, dtype=float) nb_img = len(mu) specfile.close() if reload == 0: if mydetector == "Eiger2M": counter = 'ei2minr' mymask = np.zeros((nb_pixel_y, nb_pixel_x)) elif mydetector == "Maxipix": counter = 'mpx4inr' # counter = 'roi7' mymask = np.zeros((nb_pixel_y, nb_pixel_x)) elif mydetector == "Eiger4M": mymask = np.zeros((nb_pixel_y, nb_pixel_x)) else: counter = 'mpx4inr' mymask = np.zeros((nb_pixel_y, nb_pixel_x)) if myflatfield is None: myflatfield = np.ones(mymask.shape) if myhotpixels is None: myhotpixels = np.zeros(mymask.shape) if mysetup == 'ID01': ccdn = labels_data[labels.index(counter), :] rawdata = np.zeros((len(ccdn), region[1] - region[0], region[3] - region[2])) for index in range(len(ccdn)): i = int(ccdn[index]) e = fabio.open(ccdfiletmp % i) ccdraw = e.data ccdraw, mymask = remove_hotpixels(ccdraw, myhotpixels, mymask) if mydetector == "Eiger2M": ccdraw, mymask = mask_eiger(ccdraw, mymask) elif mydetector == "Maxipix": ccdraw, mymask = mask_maxipix(ccdraw, mymask) ccdraw = myflatfield * ccdraw ccd = xu.blockAverage2D(ccdraw, nav[0], nav[1], roi=region) rawdata[int(i - ccdn[0]), :, :] = ccd elif mysetup == 'SIXS': nb_img = img.shape[0] rawdata = np.zeros((nb_img, region[1] - region[0], region[3] - region[2])) for index in range(nb_img): ccdraw = img[index, :, :] # first image is duplicated ccdraw, mymask = remove_hotpixels(ccdraw, myhotpixels, mymask) if mydetector == "Eiger2M": ccdraw, mymask = mask_eiger(ccdraw, mymask) elif mydetector == "Maxipix": ccdraw, mymask = mask_maxipix(ccdraw, mymask) ccdraw = myflatfield * ccdraw ccd = xu.blockAverage2D(ccdraw, nav[0], nav[1], roi=region) rawdata[index, :, :] = ccd elif mysetup == 'CRISTAL': nb_img = omega.shape[0] rawdata = np.zeros((nb_img, region[1] - region[0], region[3] - region[2])) for index in range(nb_img): ccdraw = maxpix_img[index, :, :] ccdraw, mymask = remove_hotpixels(ccdraw, myhotpixels, mymask) ccdraw, mymask = mask_maxipix(ccdraw, mymask) ccdraw = myflatfield * ccdraw ccd = xu.blockAverage2D(ccdraw, nav[0], nav[1], roi=region) rawdata[index, :, :] = ccd elif mysetup == 'P10': rawdata = np.zeros((nb_img, region[1] - region[0], region[3] - region[2])) for index in range(nb_img): h5file = h5py.File(ccdfiletmp % (index + 1), 'r') try: ccdraw = h5file['entry']['data']['data'][:].sum(axis=0) except OSError: print('hdf5plugin is not installed') sys.exit() ccdraw, mymask = remove_hotpixels(ccdraw, myhotpixels, mymask) ccdraw, mymask = mask_eiger4m(ccdraw, mymask) ccdraw = myflatfield * ccdraw ccd = xu.blockAverage2D(ccdraw, nav[0], nav[1], roi=region) rawdata[index, :, :] = ccd mymask = mymask[region[0]:region[1], region[2]:region[3]] rawdata, mymask = check_pixels(rawdata, mymask, var_threshold=5, debugging=0) # additional check for hotpixels numz, numy, numx = rawdata.shape rawmask3d = np.repeat(mymask[np.newaxis, :, :], numz, axis=0) rawmask3d[np.isnan(rawdata)] = 1 rawdata[np.isnan(rawdata)] = 0 else: rawmask3d = previous_mask rawdata = previous_data numz, numy, numx = rawdata.shape # transform scan angles to reciprocal space coordinates for all detector pixels if mysetup == 'ID01': myqx, myqy, myqz = hxrd.Ang2Q.area(eta, chi, phi, nu, delta, en=myenergy, delta=myoffsets) mygridder = xu.Gridder3D(numz, numy, numx) # convert mask to rectangular grid in reciprocal space mygridder(myqx, myqz, myqy, rawmask3d) mymask3d = np.copy(mygridder.data) # convert data to rectangular grid in reciprocal space mygridder(myqx, myqz, myqy, rawdata) return mygridder.xaxis, mygridder.yaxis, mygridder.zaxis, rawdata, mygridder.data, rawmask3d, mymask3d elif mysetup == 'SIXS': if myenergy is None: print('Defaulting energy to 8.5keV') myenergy = 8500 myqx, myqy, myqz = hxrd.Ang2Q.area(sixs_beta, mu, sixs_beta, gamma, delta, en=myenergy, delta=myoffsets) mygridder = xu.Gridder3D(numz, numy, numx) # convert mask to rectangular grid in reciprocal space mygridder(myqx, myqz, myqy, rawmask3d) mymask3d = np.copy(mygridder.data) # convert data to rectangular grid in reciprocal space mygridder(myqx, myqz, myqy, rawdata) return mygridder.xaxis, mygridder.yaxis, mygridder.zaxis, rawdata, mygridder.data, rawmask3d, mymask3d elif mysetup == 'CRISTAL': # TODO: implement this for CRISTAL print('Gridder not yet implemented for CRISTAL setup') return 0, 0, 0, rawdata, 0, rawmask3d, 0 elif mysetup == 'P10': # TODO: implement this for P10 print('Gridder not yet implemented for P10 setup') return 0, 0, 0, rawdata, 0, rawmask3d, 0 else: print('Wrong setup') sys.exit()
def rawmap(self, scans, angledelta=[0, 0, 0, 0], adframes=None, mask=None): logger.debug(METHOD_ENTER_STR) if mask is None: mask_was_none = True else: mask_was_none = False intensity = np.array([]) qconv = xu.experiment.QConversion(self.sampleCircleDirections, \ self.detectorCircleDirections, \ self.primaryBeamDirection) en = self.incidentEnergy hxrd = xu.HXRD(self.sampleInplaneReferenceDirection, \ self.sampleSurfaceNormalDirection, \ en=en[self.availableScans[0]], \ qconv=qconv) # initialize area detector properties if (self.detectorPixelWidth != None ) and \ (self.distanceToDetector != None): hxrd.Ang2Q.init_area(self.detectorPixelDirection1, \ self.detectorPixelDirection2, \ cch1=self.detectorCenterChannel[0], \ cch2=self.detectorCenterChannel[1], \ Nch1=self.detectorDimensions[0], \ Nch2=self.detectorDimensions[1], \ pwidth1=self.detectorPixelWidth[0], \ pwidth2=self.detectorPixelWidth[1], \ distance=self.distanceToDetector, \ Nav=self.numPixelsToAverage, \ roi=self.detectorROI) else: hxrd.Ang2Q.init_area(self.detectorPixelDirection1, \ self.detectorPixelDirection2, \ cch1=self.detectorCenterChannel[0], \ cch2=self.detectorCenterChannel[1], \ Nch1=self.detectorDimensions[0], \ Nch2=self.getDetectorDimensions[1], \ chpdeg1=self.detectorChannelsPerDegree[0], \ chpdeg2=self.detectorChannelsPerDegree[1], \ Nav=self.numPixelsToAverage, roi=self.detectorROI) angleNames = self.getAngles() scanAngle = {} for i in range(len(angleNames)): scanAngle[i] = np.array([]) offset = 0 imageToBeUsed = self.imageToBeUsed for scannr in scans: if self.haltMap: raise ProcessCanceledException("ProcessCanceled") angles = self.getGeoAngles(scannr) scanAngle1 = {} scanAngle2 = {} for i in range(len(angleNames)): scanAngle1[i] = angles[:, i] scanAngle2[i] = [] arrayInitializedForScan = False foundIndex = 0 logger.debug("imageDirName %s" % self.imageDirName) logger.debug(("fileParams[%d]" % scannr) + str(self.fileParams[scannr])) imageFilePrefix = os.path.join( self.imageDirName, self.fileParams[scannr][IMAGE_PREFIX] + "_" + self.fileParams[scannr][IMAGE_NUMBER] + "." + self.fileParams[scannr][FILE_EXT]) imageNameTemplate = str(imageFilePrefix) + '.frame%d.cor' if mask_was_none: mask = [True] * len(self.imageToBeUsed[scannr]) for ind in range(len(angles[:, 0])): if imageToBeUsed[scannr][ind] and mask[ind]: imageName = imageNameTemplate % (ind + 1) logger.debug("processing image file " + imageName) image = np.empty((self.detectorDimensions[0], self.detectorDimensions[1]), np.float32) with open(imageName) as f: image.data[:] = f.read() img2 = xu.blockAverage2D(image, self.getNumPixelsToAverage()[0], self.getNumPixelsToAverage()[1], roi=self.getDetectorROI()) if not arrayInitializedForScan: imagesToProcess = [imageToBeUsed[scannr][i] and mask[i] \ for i in range(len(imageToBeUsed[scannr]))] if not intensity.shape[0]: # For first scan intensity = np.zeros( \ (np.count_nonzero(imagesToProcess),) + \ img2.shape) arrayInitializedForScan = True else: # Need to expand for addditional scans offset = intensity.shape[0] intenstity = np.concatenate( \ (intensity, \ (np.zeros((np.count_nonzero(imagesToProcess),) + img2.shape))), \ axis=0) arrayInitializedForScan = True intensity[foundIndex + offset, :, :] = img2 for i in range(len(angleNames)): logger.debug("appending angles to angle2 " + str(scanAngle1[i][ind])) scanAngle2[i].append(scanAngle1[i][ind]) foundIndex += 1 if len(scanAngle2[0]) > 0: for i in range(len(angleNames)): scanAngle[i] = \ np.concatenate((scanAngle[i], \ np.array(scanAngle2[i])), \ axis=0) angleList = [] for i in range(len(angleNames)): angleList.append(scanAngle[i]) logger.debug("Before hxrd.Ang2Q.area %s" % str(angleList)) if self.ubMatrix[scans[0]] is None: qx, qy, qz = hxrd.Ang2Q.area(*angleList, \ roi=self.detectorROI, Nav=self.numPixelsToAverage) else: qx, qy, qz = hxrd.Ang2Q.area(*angleList, \ roi=self.detectorROI, Nav=self.numPixelsToAverage, \ UB = self.ubMatrix[scans[0]]) logger.debug("After hxrd.Ang2Q.area") # apply selected transform qxTrans, qyTrans, qzTrans = \ self.transform.do3DTransform(qx, qy, qz) logger.debug(METHOD_EXIT_STR) return qxTrans, qyTrans, qzTrans, intensity
counter = 'ei2minr' elif detector == 1: counter = 'mpx4inr' else: print('Wrong detector type') sys.exit() ccdn = labels_data[labels.index(counter), :] metadata = dict(title=movie_title) writer = FFMpegWriter(fps=5, metadata=metadata) fontsize = 10 sum_img = np.zeros((roi[1]-roi[0], roi[3]-roi[2])) fig = plt.figure(figsize=(6, 5)) with writer.saving(fig, homedir+"S"+str(scan)+"_movie.mp4", dpi=100): for index in range(len(ccdn)): i = int(ccdn[index]) e = fabio.open(ccdfiletmp % i) ccdraw = e.data ccdraw = flatfield * ccdraw ccd = xu.blockAverage2D(ccdraw, nav[0], nav[1], roi=roi) sum_img = sum_img + ccd ccd = ccd + 0.0001 plt.clf() plt.title("Img %3d" % i, fontsize=fontsize) plt.imshow(np.log10(ccd), vmin=0, vmax=4, cmap=my_cmap) writer.grab_frame() sum_img = sum_img+0.0001 plt.imshow(np.log10(sum_img), vmin=0, cmap=my_cmap) plt.title('Sum of all images') plt.show()
def rawmap(h5file, scannr, ccdfiletmp, roi=default_roi, angdelta=[0, 0, 0, 0, 0], en=default_en, cch=default_cch, chpdeg=default_chpdeg, nav=default_nav, ccdframes=None): """ read ccd frames and and convert them in reciprocal space angular coordinates are taken from the spec file or read from the edf file header when no scan number is given (scannr=None) """ if scannr: # read image numbers from spec scan, get angles from spec [mu, eta, phi, nu, delta, ccdn], sdata = xu.io.geth5_scan( h5file, scannr, 'Mu', 'Eta', 'Phi', 'Nu', 'Delta', 'ccdn') ccdn = sdata['ccd_n'] else: # get image number from input ccdn = ccdframes # 3S+2D goniometer (simplified ID01 goniometer, sample mu,eta,phi detector # nu,del qconv = xu.experiment.QConversion(['z+', 'y-', 'z-'], ['z+', 'y-'], [1, 0, 0]) # convention for coordinate system: x downstream; z upwards; y to the # "outside" (righthanded) # QConversion will set up the goniometer geometry. So the first argument # describes the sample rotations, the second the detector rotations and the # third the primary beam direction. # For this consider the following coordinate system (at least this is what # i use at ID01, feel free to use your conventions): # x: downstream (direction of primary beam) # y: out of the ring # z: upwards # these three axis form a right handed coordinate system. # The outer most sample rotation (so the one mounted on the floor) is one # which turns righthanded (+) around the z-direction -> z+ (at the moment # this rotation is called 'mu' in the spec-session) # The second sample rotation ('eta') is lefthanded (-) around y -> y- # define experimental class for angle conversion hxrd = xu.HXRD([1, 0, 0], [0, 0, 1], en=en, qconv=qconv) # initialize area detector properties hxrd.Ang2Q.init_area('z-', 'y+', cch1=cch[0], cch2=cch[1], Nch1=516, Nch2=516, chpdeg1=chpdeg[0], chpdeg2=chpdeg[1], Nav=nav, roi=roi) if ccdframes: mu = [] eta = [] phi = [] delta = [] nu = [] for idx in range(len(ccdn)): i = ccdn[idx] # read ccd image from EDF file e = xu.io.EDFFile(ccdfiletmp % i) ccdraw = e.data ccd = hotpixelkill(ccdraw) # normalize ccd-data (optional) # create data for normalization # d = {'CCD': ccd, 'Opt2': sdata['Opt2'][idx], # 'Filter': sdata['Filter'][idx], # 'Seconds': sdata['Seconds'][idx]} # ccd = xid01_normalizer(d) # here a darkfield correction would be done # reduce data size CCD = xu.blockAverage2D(ccd, nav[0], nav[1], roi=roi) if i == ccdn[0]: intensity = numpy.zeros((len(ccdn), ) + CCD.shape) intensity[idx, :, :] = CCD # if angles not read from spec file read them from the edf file header if ccdframes: # the following lines work for older EDF files only # mu.append(float(e.header['ESRF_ID01_PSIC_NANO_MU'])) # eta.append(float(e.header['ESRF_ID01_PSIC_NANO_ETA'])) # phi.append(float(e.header['ESRF_ID01_PSIC_NANO_PHI'])) # nu.append(float(e.header['ESRF_ID01_PSIC_NANO_NU'])) # delta.append(float(e.header['ESRF_ID01_PSIC_NANO_DELTA'])) # for new EDF files (recorded in year >~2013) use mu.append(e.motors['mu']) eta.append(e.motors['eta']) phi.append(e.motors['phi']) nu.append(e.motors['nu']) delta.append(e.motors['del']) # transform scan angles to reciprocal space coordinates for all detector # pixels qx, qy, qz = hxrd.Ang2Q.area(mu, eta, phi, nu, delta, delta=angdelta) return qx, qy, qz, intensity
def rawmap(h5file, scannr, ccdfiletmp, roi=default_roi, angdelta=[0, 0, 0, 0, 0], en=default_en, cch=default_cch, chpdeg=default_chpdeg, nav=default_nav, ccdframes=None): """ read ccd frames and and convert them in reciprocal space angular coordinates are taken from the spec file or read from the edf file header when no scan number is given (scannr=None) """ if scannr: # read image numbers from spec scan, get angles from spec [mu, eta, phi, nu, delta, ccdn], sdata = xu.io.geth5_scan(h5file, scannr, 'Mu', 'Eta', 'Phi', 'Nu', 'Delta', 'ccdn') ccdn = sdata['ccd_n'] else: # get image number from input ccdn = ccdframes # 3S+2D goniometer (simplified ID01 goniometer, sample mu,eta,phi detector # nu,del qconv = xu.experiment.QConversion(['z+', 'y-', 'z-'], ['z+', 'y-'], [1, 0, 0]) # convention for coordinate system: x downstream; z upwards; y to the # "outside" (righthanded) # QConversion will set up the goniometer geometry. So the first argument # describes the sample rotations, the second the detector rotations and the # third the primary beam direction. # For this consider the following coordinate system (at least this is what # i use at ID01, feel free to use your conventions): # x: downstream (direction of primary beam) # y: out of the ring # z: upwards # these three axis form a right handed coordinate system. # The outer most sample rotation (so the one mounted on the floor) is one # which turns righthanded (+) around the z-direction -> z+ (at the moment # this rotation is called 'mu' in the spec-session) # The second sample rotation ('eta') is lefthanded (-) around y -> y- # define experimental class for angle conversion hxrd = xu.HXRD([1, 0, 0], [0, 0, 1], en=en, qconv=qconv) # initialize area detector properties hxrd.Ang2Q.init_area('z-', 'y+', cch1=cch[0], cch2=cch[1], Nch1=516, Nch2=516, chpdeg1=chpdeg[0], chpdeg2=chpdeg[1], Nav=nav, roi=roi) if ccdframes: mu = [] eta = [] phi = [] delta = [] nu = [] for idx in range(len(ccdn)): i = ccdn[idx] # read ccd image from EDF file e = xu.io.EDFFile(ccdfiletmp % i) ccdraw = e.data ccd = hotpixelkill(ccdraw) # normalize ccd-data (optional) # create data for normalization # d = {'CCD': ccd, 'Opt2': sdata['Opt2'][idx], # 'Filter': sdata['Filter'][idx], # 'Seconds': sdata['Seconds'][idx]} # ccd = xid01_normalizer(d) # here a darkfield correction would be done # reduce data size CCD = xu.blockAverage2D(ccd, nav[0], nav[1], roi=roi) if i == ccdn[0]: intensity = numpy.zeros((len(ccdn), ) + CCD.shape) intensity[idx, :, :] = CCD # if angles not read from spec file read them from the edf file header if ccdframes: # the following lines work for older EDF files only # mu.append(float(e.header['ESRF_ID01_PSIC_NANO_MU'])) # eta.append(float(e.header['ESRF_ID01_PSIC_NANO_ETA'])) # phi.append(float(e.header['ESRF_ID01_PSIC_NANO_PHI'])) # nu.append(float(e.header['ESRF_ID01_PSIC_NANO_NU'])) # delta.append(float(e.header['ESRF_ID01_PSIC_NANO_DELTA'])) # for new EDF files (recorded in year >~2013) use mu.append(e.motors['mu']) eta.append(e.motors['eta']) phi.append(e.motors['phi']) nu.append(e.motors['nu']) delta.append(e.motors['del']) # transform scan angles to reciprocal space coordinates for all detector # pixels qx, qy, qz = hxrd.Ang2Q.area(mu, eta, phi, nu, delta, delta=angdelta) return qx, qy, qz, intensity
def gridmap(specfile, scan_nb, mydetector, region=None, myflatfield=None, myhotpixels=""): global offset, offset_chi, offset_eta, offset_phi, filtered_data, datadir if region is None: if mydetector == "Eiger2M": region = [0, 2164, 0, 1030] elif mydetector == "Maxipix": region = [0, 516, 0, 516] if mydetector == "Eiger2M": counter = 'ei2minr' mymask = np.zeros((2164, 1030)) elif mydetector == "Maxipix": counter = 'mpx4inr' mymask = np.zeros((516, 516)) else: sys.exit("Incorrect value for 'mydetector' parameter") if myhotpixels != "": print("Loading hotpixels array") hotpix_array = np.load(myhotpixels) npz_key = hotpix_array.keys() hotpix_array = hotpix_array[npz_key[0]] if len(hotpix_array.shape) == 3: # 3D array hotpix_array = hotpix_array.sum(axis=0) hotpix_array[hotpix_array != 0] = -1 if myflatfield is None: myflatfield = np.ones(mymask.shape) motor_names = specfile[str(scan_nb) + '.1'].motor_names # positioners motor_positions = specfile[str(scan_nb) + '.1'].motor_positions # positioners labels = specfile[str(scan_nb) + '.1'].labels # motor scanned labels_data = specfile[str(scan_nb) + '.1'].data # motor scanned chi = offset_chi phi = offset_phi delta = motor_positions[motor_names.index('del')] nu = motor_positions[motor_names.index('nu')] eta = labels_data[labels.index('eta'), :] + offset_eta ccdn = labels_data[labels.index(counter), :] if filtered_data == 0: rawdata = np.zeros( (len(ccdn), region[1] - region[0], region[3] - region[2])) for index in range(len(ccdn)): i = int(ccdn[index]) e = fabio.open(ccdfiletmp % i) ccdraw = e.data if myhotpixels != "": ccdraw, mymask = remove_hotpixels(ccdraw, hotpix_array, mymask) if mydetector == "Eiger2M": ccdraw, mymask = mask_eiger(ccdraw, mymask) elif mydetector == "Maxipix": ccdraw, mymask = mask_maxipix(ccdraw, mymask) ccdraw = myflatfield * ccdraw ccd = xu.blockAverage2D(ccdraw, nav[0], nav[1], roi=region) rawdata[int(i - ccdn[0]), :, :] = ccd else: print('Loading filtered data') myfile_path = filedialog.askopenfilename(initialdir=specdir, title="Select 3D data", filetypes=[("NPZ", "*.npz")]) rawdata = np.load(myfile_path)['data'] rawdata = rawdata[region[0]:region[1], region[2]:region[3]] mymask = mymask[region[0]:region[1], region[2]:region[3]] numz, numy, numx = rawdata.shape if numz != len(ccdn): print('Filtered data has not the same shape as raw data') sys.exit() rawmask3d = np.zeros((numz, region[1] - region[0], region[3] - region[2])) for index in range(numz): rawmask3d[index, :, :] = mymask # transform scan angles to reciprocal space coordinates for all detector pixels myqx, myqy, myqz = hxrd.Ang2Q.area(eta, chi, phi, nu, delta, delta=(0, 0, 0, offset, 0)) mygridder = xu.Gridder3D(numz, numy, numx) # convert mask to rectangular grid in reciprocal space mygridder(myqx, myqz, myqy, rawmask3d) mymask3d = np.copy(mygridder.data) # convert data to rectangular grid in reciprocal space mygridder(myqx, myqz, myqy, rawdata) return mygridder.xaxis, mygridder.yaxis, mygridder.zaxis, rawdata, mygridder.data, rawmask3d, mymask3d