def fit_grains(self, grain_id, grain_params): """ Executes lsq fits of grains based on spot files REFLECTION TABLE Cols as follows: 0-6: ID PID H K L sum(int) max(int) 6-9: pred tth pred eta pred ome 9-12: meas tth meas eta meas ome 12-15: meas X meas Y meas ome """ ome_start = self._p['omega_start'] ome_step = self._p['omega_step'] ome_stop = self._p['omega_stop'] refl_table = np.loadtxt(self._p['spots_stem'] % grain_id) valid_refl_ids = refl_table[:, 0] >= 0 unsat_spots = refl_table[:, 6] < self._p['saturation_level'] pred_ome = refl_table[:, 9] if angularDifference(ome_start, ome_stop, units='degrees') > 0: # if here, incomplete have omega range and # clip the refelctions very close to the edges to avoid # problems with the least squares... if np.sign(ome_step) < 0: idx_ome = np.logical_and( pred_ome < np.radians(ome_start + 2*ome_step), pred_ome > np.radians(ome_stop - 2*ome_step) ) else: idx_ome = np.logical_and( pred_ome > np.radians(ome_start + 2*ome_step), pred_ome < np.radians(ome_stop - 2*ome_step) ) idx = np.logical_and( valid_refl_ids, np.logical_and(unsat_spots, idx_ome) ) else: idx = np.logical_and(valid_refl_ids, unsat_spots) hkls = refl_table[idx, 2:5].T # must be column vectors self._p['hkls'] = hkls xyo_det = refl_table[idx, -3:] # these are the cartesian centroids + ome xyo_det[:, 2] = mapAngle(xyo_det[:, 2], self._p['omega_period']) self._p['xyo_det'] = xyo_det if sum(idx) <= 12: return grain_params, 0 grain_params = fitGrain( xyo_det, hkls, self._p['bMat'], self._p['wlen'], self._p['detector_params'], grain_params[:3], grain_params[3:6], grain_params[6:], beamVec=bVec_ref, etaVec=eta_ref, distortion=self._p['distortion'], gFlag=gFlag, gScl=gScl, omePeriod=self._p['omega_period'] ) completeness = sum(valid_refl_ids)/float(len(valid_refl_ids)) return grain_params, completeness
def fit_grains(self, grain_id, grain_params): ome_start = self._p['omega_start'] ome_step = self._p['omega_step'] ome_stop = self._p['omega_stop'] refl_table = np.loadtxt(self._p['spots_stem'] % grain_id) valid_refl_ids = refl_table[:, 0] >= 0 unsat_spots = refl_table[:, 5] < self._p['saturation_level'] pred_ome = refl_table[:, 8] if angularDifference(ome_start, ome_stop, units='degrees') > 0: # if here, incomplete have omega range and # clip the refelctions very close to the edges to avoid # problems with the least squares... if np.sign(ome_step) < 0: idx_ome = np.logical_and( pred_ome < np.radians(ome_start + 2 * ome_step), pred_ome > np.radians(ome_stop - 2 * ome_step)) else: idx_ome = np.logical_and( pred_ome > np.radians(ome_start + 2 * ome_step), pred_ome < np.radians(ome_stop - 2 * ome_step)) idx = np.logical_and(unsat_spots, np.logical_and(valid_refl_ids, idx_ome)) else: idx = np.logical_and(valid_refl_ids, unsat_spots) hkls = refl_table[idx, 1:4].T # must be column vectors self._p['hkls'] = hkls xyo_det = refl_table[idx, -3:] # these are the cartesian centroids + ome xyo_det[:, 2] = mapAngle(xyo_det[:, 2], self._p['omega_period']) self._p['xyo_det'] = xyo_det if sum(idx) <= 12: return grain_params, 0 grain_params = fitGrain(xyo_det, hkls, self._p['bMat'], self._p['wlen'], self._p['detector_params'], grain_params[:3], grain_params[3:6], grain_params[6:], beamVec=bVec_ref, etaVec=eta_ref, distortion=self._p['distortion'], gFlag=gFlag, gScl=gScl, omePeriod=self._p['omega_period']) completeness = sum(idx) / float(len(idx)) return grain_params, completeness
def fit_grains(self, grain_id, grain_params): ome_start = self._p['omega_start'] ome_step = self._p['omega_step'] ome_stop = self._p['omega_stop'] refl_table = np.loadtxt(self._p['spots_stem'] % grain_id) valid_refl_ids = refl_table[:, 0] >= 0 unsat_spots = refl_table[:, 5] < self._p['saturation_level'] pred_ome = refl_table[:, 8] if angularDifference(ome_start, ome_stop, units='degrees') > 0: # if here, incomplete have omega range and # clip the refelctions very close to the edges to avoid # problems with the least squares... if np.sign(ome_step) < 0: idx_ome = np.logical_and( pred_ome < np.radians(ome_start + 2*ome_step), pred_ome > np.radians(ome_stop - 2*ome_step) ) else: idx_ome = np.logical_and( pred_ome > np.radians(ome_start + 2*ome_step), pred_ome < np.radians(ome_stop - 2*ome_step) ) idx = np.logical_and( unsat_spots, np.logical_and(valid_refl_ids, idx_ome) ) else: idx = np.logical_and(valid_refl_ids, unsat_spots) hkls = refl_table[idx, 1:4].T # must be column vectors self._p['hkls'] = hkls xyo_det = refl_table[idx, -3:] # these are the cartesian centroids + ome xyo_det[:, 2] = mapAngle(xyo_det[:, 2], self._p['omega_period']) self._p['xyo_det'] = xyo_det if sum(idx) <= 12: return grain_params, 0 grain_params = fitGrain( xyo_det, hkls, self._p['bMat'], self._p['wlen'], self._p['detector_params'], grain_params[:3], grain_params[3:6], grain_params[6:], beamVec=bVec_ref, etaVec=eta_ref, distortion=self._p['distortion'], gFlag=gFlag, gScl=gScl, omePeriod=self._p['omega_period'] ) completeness = sum(idx)/float(len(idx)) return grain_params, completeness
def fit_grains(self, grain_id, grain_params): ome_start = self._p['omega_start'] ome_step = self._p['omega_step'] ome_stop = self._p['omega_stop'] gtable = np.loadtxt(self._p['spots_stem'] % grain_id) valid_refl_ids = gtable[:, 0] >= 0 pred_ome = gtable[:, 6] if np.sign(ome_step) < 0: idx_ome = np.logical_and( pred_ome < np.radians(ome_start + 2*ome_step), pred_ome > np.radians(ome_stop - 2*ome_step) ) else: idx_ome = np.logical_and( pred_ome > np.radians(ome_start + 2*ome_step), pred_ome < np.radians(ome_stop - 2*ome_step) ) idx = np.logical_and(valid_refl_ids, idx_ome) hkls = gtable[idx, 1:4].T # must be column vectors self._p['hkls'] = hkls xyo_det = gtable[idx, -3:] # these are the cartesian centroids + ome xyo_det[:, 2] = mapAngle(xyo_det[:, 2], self._p['omega_period']) self._p['xyo_det'] = xyo_det if sum(idx) <= 12: return grain_params, 0 grain_params = fitGrain( xyo_det, hkls, self._p['bMat'], self._p['wlen'], self._p['detector_params'], grain_params[:3], grain_params[3:6], grain_params[6:], beamVec=bVec_ref, etaVec=eta_ref, distortion=self._p['distortion'], gFlag=gFlag, gScl=gScl, omePeriod=self._p['omega_period'] ) completeness = sum(idx)/float(len(idx)) return grain_params, completeness
def fit_grains(self, grain_id, grain_params, refit_tol=None): """ Executes lsq fits of grains based on spot files REFLECTION TABLE Cols as follows: 0:7 ID PID H K L sum(int) max(int) 7:10 pred tth pred eta pred ome 10:13 meas tth meas eta meas ome 13:17 pred X pred Y meas X meas Y """ # !!! load resuts form spots spots_fname_dict = {} for det_key in self._instr.detectors.iterkeys(): spots_fname_dict[det_key] = os.path.join( self._p['analysis_directory'], os.path.join( det_key, self._p['spots_stem'] % grain_id ) ) self._culled_results = dict.fromkeys(spots_fname_dict) num_refl_tot = 0 num_refl_valid = 0 for det_key in self._culled_results: panel = self._instr.detectors[det_key] presults = np.loadtxt(spots_fname_dict[det_key]) valid_refl_ids = presults[:, 0] >= 0 spot_ids = presults[:, 1] # find unsaturated spots on this panel if panel.saturation_level is None: unsat_spots = np.ones(len(valid_refl_ids)) else: unsat_spots = presults[:, 6] < panel.saturation_level idx = np.logical_and(valid_refl_ids, unsat_spots) # if an overlap table has been written, load it and use it overlaps = np.zeros_like(idx, dtype=bool) try: ot = np.load( os.path.join( self._p['analysis_directory'], 'overlap_table.npz' ) ) for key in ot.keys(): for this_table in ot[key]: these_overlaps = np.where( this_table[:, 0] == grain_id)[0] if len(these_overlaps) > 0: mark_these = np.array( this_table[these_overlaps, 1], dtype=int ) otidx = [ np.where(spot_ids == mt)[0] for mt in mark_these ] overlaps[otidx] = True idx = np.logical_and(idx, ~overlaps) # logger.info("found overlap table for '%s'", det_key) except(IOError, IndexError): # logger.info("no overlap table found for '%s'", det_key) pass # attach to proper dict entry self._culled_results[det_key] = presults[idx, :] num_refl_tot += len(valid_refl_ids) num_refl_valid += sum(valid_refl_ids) pass # now we have culled data # CAVEAT: completeness from pullspots only; incl saturated and overlaps # <JVB 2015-12-15> completeness = num_refl_valid / float(num_refl_tot) # ======= DO LEASTSQ FIT ======= if num_refl_valid <= min_nrefl: # exit if not enough refls to fit grain_params_fit = grain_params return grain_id, completeness, np.inf, grain_params_fit else: grain_params_fit = fitGrain( grain_params, self._instr, self._culled_results, self._p['bmat'], self._p['wlen'] ) # get chisq # TODO: do this while evaluating fit??? chisq = objFuncFitGrain( grain_params_fit[gFlag_ref], grain_params_fit, gFlag_ref, self._instr, self._culled_results, self._p['bmat'], self._p['wlen'], self._p['omega_period'], simOnly=False, return_value_flag=2) if self._p['refit_tol'] is not None: # first get calculated x, y, ome from previous solution # NOTE: this result is a dict xyo_det_fit_dict = objFuncFitGrain( grain_params_fit[gFlag_ref], grain_params_fit, gFlag_ref, self._instr, self._culled_results, self._p['bmat'], self._p['wlen'], self._p['omega_period'], simOnly=True, return_value_flag=2) # make dict to contain new culled results culled_results_r = dict.fromkeys(self._culled_results) num_refl_valid = 0 for det_key in culled_results_r: presults = self._culled_results[det_key] ims = self._imgsd[det_key] # !!! must be OmegaImageSeries ome_step = sum(np.r_[-1, 1]*ims.metadata['omega'][0, :]) # measured vals for pull spots xyo_det = presults[:, [15, 16, 12]] # previous solutions calc vals xyo_det_fit = xyo_det_fit_dict[det_key] xpix_tol = self._p['refit_tol'][0]*panel.pixel_size_col ypix_tol = self._p['refit_tol'][0]*panel.pixel_size_row fome_tol = self._p['refit_tol'][1]*ome_step # define difference vectors for spot fits x_diff = abs(xyo_det[:, 0] - xyo_det_fit['calc_xy'][:, 0]) y_diff = abs(xyo_det[:, 1] - xyo_det_fit['calc_xy'][:, 1]) ome_diff = np.degrees( xfcapi.angularDifference(xyo_det[:, 2], xyo_det_fit['calc_omes']) ) # filter out reflections with centroids more than # a pixel and delta omega away from predicted value idx_new = np.logical_and( x_diff <= xpix_tol, np.logical_and(y_diff <= ypix_tol, ome_diff <= fome_tol) ) # attach to proper dict entry culled_results_r[det_key] = presults[idx_new, :] num_refl_valid += sum(idx_new) pass # only execute fit if left with enough reflections if num_refl_valid > min_nrefl: grain_params_fit = fitGrain( grain_params_fit, self._instr, culled_results_r, self._p['bmat'], self._p['wlen'], ) # get chisq # TODO: do this while evaluating fit??? chisq = objFuncFitGrain( grain_params_fit[gFlag_ref], grain_params_fit, gFlag_ref, self._instr, culled_results_r, self._p['bmat'], self._p['wlen'], self._p['omega_period'], simOnly=False, return_value_flag=2) pass # close check on number of valid refls pass # close refit conditional return grain_id, completeness, chisq, grain_params_fit
def fit_grain_FF_reduced(grain_id): """ input parameters are [ plane_data, instrument, imgser_dict, tth_tol, eta_tol, ome_tol, npdiv, threshold ] """ grains_table = paramMP['grains_table'] plane_data = paramMP['plane_data'] instrument = paramMP['instrument'] imgser_dict = paramMP['imgser_dict'] tth_tol = paramMP['tth_tol'] eta_tol = paramMP['eta_tol'] ome_tol = paramMP['ome_tol'] npdiv = paramMP['npdiv'] refit = paramMP['refit'] threshold = paramMP['threshold'] eta_ranges = paramMP['eta_ranges'] ome_period = paramMP['ome_period'] analysis_dirname = paramMP['analysis_dirname'] spots_filename = paramMP['spots_filename'] grain = grains_table[grain_id] grain_params = grain[3:15] complvec, results = instrument.pull_spots(plane_data, grain_params, imgser_dict, tth_tol=tth_tol[tol_loop_idx], eta_tol=eta_tol[tol_loop_idx], ome_tol=ome_tol[tol_loop_idx], npdiv=npdiv, threshold=threshold, eta_ranges=eta_ranges, ome_period=ome_period, dirname=analysis_dirname, filename=spots_filename % grain_id, save_spot_list=False, quiet=True, check_only=False, interp='nearest') # ======= DETERMINE VALID REFLECTIONS ======= culled_results = dict.fromkeys(results) num_refl_tot = 0 num_refl_valid = 0 for det_key in culled_results: panel = instrument.detectors[det_key] presults = results[det_key] valid_refl_ids = np.array([x[0] for x in presults]) >= 0 spot_ids = np.array([x[0] for x in presults]) # find unsaturated spots on this panel if panel.saturation_level is None: unsat_spots = np.ones(len(valid_refl_ids)) else: unsat_spots = \ np.array([x[4] for x in presults]) < panel.saturation_level idx = np.logical_and(valid_refl_ids, unsat_spots) # if an overlap table has been written, load it and use it overlaps = np.zeros_like(idx, dtype=bool) try: ot = np.load( os.path.join(analysis_dirname, os.path.join(det_key, 'overlap_table.npz'))) for key in ot.keys(): for this_table in ot[key]: these_overlaps = np.where(this_table[:, 0] == grain_id)[0] if len(these_overlaps) > 0: mark_these = np.array(this_table[these_overlaps, 1], dtype=int) otidx = [ np.where(spot_ids == mt)[0] for mt in mark_these ] overlaps[otidx] = True idx = np.logical_and(idx, ~overlaps) # print("found overlap table for '%s'" % det_key) except (IOError, IndexError): # print("no overlap table found for '%s'" % det_key) pass # attach to proper dict entry culled_results[det_key] = [presults[i] for i in np.where(idx)[0]] num_refl_tot += len(valid_refl_ids) num_refl_valid += sum(valid_refl_ids) pass # now we have culled data # CAVEAT: completeness from pullspots only; incl saturated and overlaps # <JVB 2015-12-15> completeness = num_refl_valid / float(num_refl_tot) # ======= DO LEASTSQ FIT ======= if num_refl_valid <= 12: # not enough reflections to fit... exit grain_params_fit = grain_params return grain_id, completeness, np.inf, grain_params_fit else: grain_params_fit = fitGrain(grain_params, instrument, culled_results, plane_data.latVecOps['B'], plane_data.wavelength) # get chisq # TODO: do this while evaluating fit??? chisq = objFuncFitGrain(grain_params_fit[gFlag_ref], grain_params_fit, gFlag_ref, instrument, culled_results, plane_data.latVecOps['B'], plane_data.wavelength, ome_period, simOnly=False, return_value_flag=2) if refit is not None: # first get calculated x, y, ome from previous solution # NOTE: this result is a dict xyo_det_fit_dict = objFuncFitGrain(grain_params_fit[gFlag_ref], grain_params_fit, gFlag_ref, instrument, culled_results, plane_data.latVecOps['B'], plane_data.wavelength, ome_period, simOnly=True, return_value_flag=2) # make dict to contain new culled results culled_results_r = dict.fromkeys(culled_results) num_refl_valid = 0 for det_key in culled_results_r: presults = culled_results[det_key] ims = imgser_dict[det_key] ome_step = sum(np.r_[-1, 1] * ims.metadata['omega'][0, :]) xyo_det = np.atleast_2d( np.vstack([np.r_[x[7], x[6][-1]] for x in presults])) xyo_det_fit = xyo_det_fit_dict[det_key] xpix_tol = refit[0] * panel.pixel_size_col ypix_tol = refit[0] * panel.pixel_size_row fome_tol = refit[1] * ome_step # define difference vectors for spot fits x_diff = abs(xyo_det[:, 0] - xyo_det_fit['calc_xy'][:, 0]) y_diff = abs(xyo_det[:, 1] - xyo_det_fit['calc_xy'][:, 1]) ome_diff = np.degrees( xfcapi.angularDifference(xyo_det[:, 2], xyo_det_fit['calc_omes'])) # filter out reflections with centroids more than # a pixel and delta omega away from predicted value idx_new = np.logical_and( x_diff <= xpix_tol, np.logical_and(y_diff <= ypix_tol, ome_diff <= fome_tol)) # attach to proper dict entry culled_results_r[det_key] = [ presults[i] for i in np.where(idx_new)[0] ] num_refl_valid += sum(idx_new) pass # only execute fit if left with enough reflections if num_refl_valid > 24: grain_params_fit = fitGrain(grain_params_fit, instrument, culled_results_r, plane_data.latVecOps['B'], plane_data.wavelength) # get chisq # TODO: do this while evaluating fit??? chisq = objFuncFitGrain(grain_params_fit[gFlag_ref], grain_params_fit, gFlag_ref, instrument, culled_results_r, plane_data.latVecOps['B'], plane_data.wavelength, ome_period, simOnly=False, return_value_flag=2) pass pass # close refit conditional return grain_id, completeness, chisq, grain_params_fit
def fit_grain_FF_reduced(grain_id): """ input parameters are [ plane_data, instrument, imgser_dict, tth_tol, eta_tol, ome_tol, npdiv, threshold ] """ grains_table = paramMP['grains_table'] plane_data = paramMP['plane_data'] instrument = paramMP['instrument'] imgser_dict = paramMP['imgser_dict'] tth_tol = paramMP['tth_tol'] eta_tol = paramMP['eta_tol'] ome_tol = paramMP['ome_tol'] npdiv = paramMP['npdiv'] threshold = paramMP['threshold'] eta_ranges = paramMP['eta_ranges'] ome_period = paramMP['ome_period'] analysis_dirname = paramMP['analysis_dirname'] spots_filename = paramMP['spots_filename'] grain = grains_table[grain_id] grain_params = grain[3:15] complvec, results = instrument.pull_spots( plane_data, grain_params, imgser_dict, tth_tol=tth_tol[0], eta_tol=eta_tol[0], ome_tol=ome_tol[0], npdiv=npdiv, threshold=threshold, eta_ranges=eta_ranges, ome_period=ome_period, dirname=analysis_dirname, filename=spots_filename % grain_id, save_spot_list=False, quiet=True, lrank=1, check_only=False) # ======= DETERMINE VALID REFLECTIONS ======= # CAVEAT: in the event of different stauration levels, can't mark saturated # spots in aggregated results <JVB 2017-03-26> culled_results = dict.fromkeys(results) num_refl_tot = 0 num_refl_valid = 0 for det_key in culled_results: presults = results[det_key] valid_refl_ids = np.array([x[0] for x in presults]) >= 0 # FIXME: spot saturations will have to be handled differently unsat_spots = np.ones(len(valid_refl_ids)) idx = np.logical_and(valid_refl_ids, unsat_spots) # TODO: wire in reflection overlap tables """ # if an overlap table has been written, load it and use it overlaps = np.zeros(len(refl_table), dtype=bool) try: ot = np.load(self._p['overlap_table']) for key in ot.keys(): for this_table in ot[key]: these_overlaps = np.where( this_table[:, 0] == grain_id)[0] if len(these_overlaps) > 0: mark_these = np.array( this_table[these_overlaps, 1], dtype=int ) overlaps[mark_these] = True idx = np.logical_and(idx, ~overlaps) except IOError, IndexError: #print "no overlap table found" pass """ # attach to proper dict entry culled_results[det_key] = [presults[i] for i in np.where(idx)[0]] num_refl_tot += len(valid_refl_ids) num_refl_valid += sum(valid_refl_ids) pass # CAVEAT: completeness from pullspots only; incl saturated and overlaps # <JVB 2015-12-15> completeness = num_refl_valid / float(num_refl_tot) # ======= DO LEASTSQ FIT ======= if num_refl_valid <= 12: # not enough reflections to fit... exit grain_params_fit = grain_params return grain_id, completeness, np.inf, grain_params_fit else: grain_params_fit = fitGrain( grain_params, instrument, culled_results, plane_data.latVecOps['B'], plane_data.wavelength ) # get chisq # TODO: do this while evaluating fit??? chisq = objFuncFitGrain( grain_params, grain_params, gFlag_ref, instrument, culled_results, plane_data.latVecOps['B'], plane_data.wavelength, ome_period, simOnly=False, return_value_flag=2) return grain_id, completeness, chisq, grain_params_fit
class FitGrainsWorker(object): def __init__(self, jobs, results, reader, pkwargs, **kwargs): self._jobs = jobs self._results = results self._reader = reader # a dict containing the rest of the parameters self._p = pkwargs # lets make a couple shortcuts: self._p['bMat'] = np.ascontiguousarray( self._p['plane_data'].latVecOps['B'] ) # is it still necessary to re-cast? self._p['wlen'] = self._p['plane_data'].wavelength self._pbar = kwargs.get('progressbar', None) def pull_spots(self, grain_id, grain_params, iteration): # need to calc panel dims on the fly xdim = self._p['pixel_pitch'][1] * self._p['ncols'] ydim = self._p['pixel_pitch'][0] * self._p['nrows'] panel_dims = [(-0.5 * xdim, -0.5 * ydim), (0.5 * xdim, 0.5 * ydim)] return pullSpots( self._p['plane_data'], self._p['detector_params'], grain_params, self._reader, distortion=self._p['distortion'], eta_range=self._p['eta_range'], ome_period=self._p['omega_period'], eta_tol=self._p['eta_tol'][iteration], ome_tol=self._p['omega_tol'][iteration], tth_tol=self._p['tth_tol'][iteration], pixel_pitch=self._p['pixel_pitch'], panel_dims=panel_dims, panel_buff=self._p['panel_buffer'], npdiv=self._p['npdiv'], threshold=self._p['threshold'], doClipping=False, filename=self._p['spots_stem'] % grain_id, ) def fit_grains(self, grain_id, grain_params, refit_tol=None): """ Executes lsq fits of grains based on spot files REFLECTION TABLE Cols as follows: 0-6: ID PID H K L sum(int) max(int) 6-9: pred tth pred eta pred ome 9-12: meas tth meas eta meas ome 12-15: meas X meas Y meas ome """ ome_start = self._p['omega_start'] ome_step = self._p['omega_step'] ome_stop = self._p['omega_stop'] refl_table = np.loadtxt(self._p['spots_stem'] % grain_id) valid_refl_ids = refl_table[:, 0] >= 0 unsat_spots = refl_table[:, 6] < self._p['saturation_level'] pred_ome = refl_table[:, 9] if angularDifference(ome_start, ome_stop, units='degrees') > 0: # if here, incomplete have omega range and # clip the refelctions very close to the edges to avoid # problems with the least squares... if np.sign(ome_step) < 0: idx_ome = np.logical_and( pred_ome < np.radians(ome_start + 2 * ome_step), pred_ome > np.radians(ome_stop - 2 * ome_step)) else: idx_ome = np.logical_and( pred_ome > np.radians(ome_start + 2 * ome_step), pred_ome < np.radians(ome_stop - 2 * ome_step)) idx = np.logical_and(valid_refl_ids, np.logical_and(unsat_spots, idx_ome)) else: idx = np.logical_and(valid_refl_ids, unsat_spots) pass # end if edge case # if an overlap table has been written, load it and use it overlaps = np.zeros(len(refl_table), dtype=bool) try: ot = np.load(self._p['overlap_table']) for key in ot.keys(): for this_table in ot[key]: these_overlaps = np.where(this_table[:, 0] == grain_id)[0] if len(these_overlaps) > 0: mark_these = np.array(this_table[these_overlaps, 1], dtype=int) overlaps[mark_these] = True idx = np.logical_and(idx, ~overlaps) except IOError, IndexError: #print "no overlap table found" pass # completeness from pullspots only; incl saturated and overlaps completeness = sum(valid_refl_ids) / float(len(valid_refl_ids)) # extract data from grain table hkls = refl_table[idx, 2:5].T # must be column vectors xyo_det = refl_table[idx, -3:] # these are the cartesian centroids + ome # set in parameter attribute self._p['hkls'] = hkls self._p['xyo_det'] = xyo_det if sum(idx) <= 12: # not enough reflections to fit... exit completeness = 0. else: grain_params = fitGrain(xyo_det, hkls, self._p['bMat'], self._p['wlen'], self._p['detector_params'], grain_params[:3], grain_params[3:6], grain_params[6:], beamVec=bVec_ref, etaVec=eta_ref, distortion=self._p['distortion'], gFlag=gFlag, gScl=gScl, omePeriod=self._p['omega_period']) if refit_tol is not None: xpix_tol = refit_tol[0] * self._p['pixel_pitch'][1] ypix_tol = refit_tol[0] * self._p['pixel_pitch'][0] fome_tol = refit_tol[1] * self._p['omega_step'] xyo_det_fit = objFuncFitGrain(grain_params[gFlag], grain_params, gFlag, self._p['detector_params'], xyo_det, hkls, self._p['bMat'], self._p['wlen'], bVec_ref, eta_ref, self._p['distortion'][0], self._p['distortion'][1], self._p['omega_period'], simOnly=True) # define difference vectors for spot fits x_diff = abs(xyo_det[:, 0] - xyo_det_fit[:, 0]) y_diff = abs(xyo_det[:, 1] - xyo_det_fit[:, 1]) ome_diff = np.degrees( angularDifference(xyo_det[:, 2], xyo_det_fit[:, 2])) # filter out reflections with centroids more than # a pixel and delta omega away from predicted value idx_1 = np.logical_and( x_diff <= xpix_tol, np.logical_and(y_diff <= ypix_tol, ome_diff <= fome_tol)) idx_new = np.zeros_like(idx, dtype=bool) idx_new[np.where(idx == 1)[0][idx_1]] = True if sum(idx_new) > 12 and (sum(idx_new) > 0.5 * sum(idx)): # have enough reflections left # ** the check that we have more than half of what # we started with is a hueristic hkls = refl_table[idx_new, 2:5].T xyo_det = refl_table[idx_new, -3:] # set in parameter attribute self._p['hkls'] = hkls self._p['xyo_det'] = xyo_det # do fit grain_params = fitGrain(xyo_det, hkls, self._p['bMat'], self._p['wlen'], self._p['detector_params'], grain_params[:3], grain_params[3:6], grain_params[6:], beamVec=bVec_ref, etaVec=eta_ref, distortion=self._p['distortion'], gFlag=gFlag, gScl=gScl, omePeriod=self._p['omega_period']) pass # end check on num of refit refls pass # end refit loop pass # end on num of refls return grain_params, completeness
def fit_grains(self, grain_id, grain_params, refit_tol=None): """ Executes lsq fits of grains based on spot files REFLECTION TABLE Cols as follows: 0-6: ID PID H K L sum(int) max(int) 6-9: pred tth pred eta pred ome 9-12: meas tth meas eta meas ome 12-15: meas X meas Y meas ome """ ome_start = self._p['omega_start'] ome_step = self._p['omega_step'] ome_stop = self._p['omega_stop'] refl_table = np.loadtxt(self._p['spots_stem'] % grain_id) valid_refl_ids = refl_table[:, 0] >= 0 unsat_spots = refl_table[:, 6] < self._p['saturation_level'] pred_ome = refl_table[:, 9] if angularDifference(ome_start, ome_stop, units='degrees') > 0: # if here, incomplete have omega range and # clip the refelctions very close to the edges to avoid # problems with the least squares... if np.sign(ome_step) < 0: idx_ome = np.logical_and( pred_ome < np.radians(ome_start + 2*ome_step), pred_ome > np.radians(ome_stop - 2*ome_step) ) else: idx_ome = np.logical_and( pred_ome > np.radians(ome_start + 2*ome_step), pred_ome < np.radians(ome_stop - 2*ome_step) ) idx = np.logical_and( valid_refl_ids, np.logical_and(unsat_spots, idx_ome) ) else: idx = np.logical_and(valid_refl_ids, unsat_spots) pass # end if edge case # completeness from pullspots only; incl saturated completeness = sum(valid_refl_ids)/float(len(valid_refl_ids)) # extract data from grain table hkls = refl_table[idx, 2:5].T # must be column vectors xyo_det = refl_table[idx, -3:] # these are the cartesian centroids + ome # set in parameter attribute self._p['hkls'] = hkls self._p['xyo_det'] = xyo_det if sum(idx) <= 12: # not enough reflections to fit... exit completeness = 0. else: grain_params = fitGrain( xyo_det, hkls, self._p['bMat'], self._p['wlen'], self._p['detector_params'], grain_params[:3], grain_params[3:6], grain_params[6:], beamVec=bVec_ref, etaVec=eta_ref, distortion=self._p['distortion'], gFlag=gFlag, gScl=gScl, omePeriod=self._p['omega_period'] ) if refit_tol is not None: xpix_tol = refit_tol[0]*self._p['pixel_pitch'][1] ypix_tol = refit_tol[0]*self._p['pixel_pitch'][0] fome_tol = refit_tol[1]*self._p['omega_step'] xyo_det_fit = objFuncFitGrain( grain_params[gFlag], grain_params, gFlag, self._p['detector_params'], xyo_det, hkls, self._p['bMat'], self._p['wlen'], bVec_ref, eta_ref, self._p['distortion'][0], self._p['distortion'][1], self._p['omega_period'], simOnly=True ) # define difference vectors for spot fits x_diff = abs(xyo_det[:, 0] - xyo_det_fit[:, 0]) y_diff = abs(xyo_det[:, 1] - xyo_det_fit[:, 1]) ome_diff = np.degrees( angularDifference(xyo_det[:, 2], xyo_det_fit[:, 2]) ) # filter out reflections with centroids more than # a pixel and delta omega away from predicted value idx_1 = np.logical_and( x_diff <= xpix_tol, np.logical_and(y_diff <= ypix_tol, ome_diff <= fome_tol) ) idx_new = np.zeros_like(idx, dtype=bool) idx_new[np.where(idx == 1)[0][idx_1]] = True if sum(idx_new) > 12 and (sum(idx_new) > 0.5*sum(idx)): # have enough reflections left # ** the check that we have more than half of what # we started with is a hueristic hkls = refl_table[idx_new, 2:5].T xyo_det = refl_table[idx_new, -3:] # set in parameter attribute self._p['hkls'] = hkls self._p['xyo_det'] = xyo_det # do fit grain_params = fitGrain( xyo_det, hkls, self._p['bMat'], self._p['wlen'], self._p['detector_params'], grain_params[:3], grain_params[3:6], grain_params[6:], beamVec=bVec_ref, etaVec=eta_ref, distortion=self._p['distortion'], gFlag=gFlag, gScl=gScl, omePeriod=self._p['omega_period'] ) pass # end check on num of refit refls pass # end refit loop pass # end on num of refls return grain_params, completeness
def fit_grains(self, grain_id, grain_params, refit_tol=None): """ Executes lsq fits of grains based on spot files REFLECTION TABLE Cols as follows: 0:7 ID PID H K L sum(int) max(int) 7:10 pred tth pred eta pred ome 10:13 meas tth meas eta meas ome 13:17 pred X pred Y meas X meas Y """ # !!! load resuts form spots spots_fname_dict = {} for det_key in self._instr.detectors.iterkeys(): spots_fname_dict[det_key] = os.path.join( self._p['analysis_directory'], os.path.join(det_key, self._p['spots_stem'] % grain_id)) self._culled_results = dict.fromkeys(spots_fname_dict) num_refl_tot = 0 num_refl_valid = 0 for det_key in self._culled_results: panel = self._instr.detectors[det_key] presults = np.loadtxt(spots_fname_dict[det_key]) valid_refl_ids = presults[:, 0] >= 0 spot_ids = presults[:, 1] # find unsaturated spots on this panel if panel.saturation_level is None: unsat_spots = np.ones(len(valid_refl_ids)) else: unsat_spots = presults[:, 6] < panel.saturation_level idx = np.logical_and(valid_refl_ids, unsat_spots) # if an overlap table has been written, load it and use it overlaps = np.zeros_like(idx, dtype=bool) try: ot = np.load( os.path.join(self._p['analysis_directory'], 'overlap_table.npz')) for key in ot.keys(): for this_table in ot[key]: these_overlaps = np.where(this_table[:, 0] == grain_id)[0] if len(these_overlaps) > 0: mark_these = np.array(this_table[these_overlaps, 1], dtype=int) otidx = [ np.where(spot_ids == mt)[0] for mt in mark_these ] overlaps[otidx] = True idx = np.logical_and(idx, ~overlaps) # logger.info("found overlap table for '%s'", det_key) except (IOError, IndexError): # logger.info("no overlap table found for '%s'", det_key) pass # attach to proper dict entry self._culled_results[det_key] = presults[idx, :] num_refl_tot += len(valid_refl_ids) num_refl_valid += sum(valid_refl_ids) pass # now we have culled data # CAVEAT: completeness from pullspots only; incl saturated and overlaps # <JVB 2015-12-15> completeness = num_refl_valid / float(num_refl_tot) # ======= DO LEASTSQ FIT ======= if num_refl_valid <= min_nrefl: # exit if not enough refls to fit grain_params_fit = grain_params return grain_id, completeness, np.inf, grain_params_fit else: grain_params_fit = fitGrain(grain_params, self._instr, self._culled_results, self._p['bmat'], self._p['wlen']) # get chisq # TODO: do this while evaluating fit??? chisq = objFuncFitGrain(grain_params_fit[gFlag_ref], grain_params_fit, gFlag_ref, self._instr, self._culled_results, self._p['bmat'], self._p['wlen'], self._p['omega_period'], simOnly=False, return_value_flag=2) if self._p['refit_tol'] is not None: # first get calculated x, y, ome from previous solution # NOTE: this result is a dict xyo_det_fit_dict = objFuncFitGrain(grain_params_fit[gFlag_ref], grain_params_fit, gFlag_ref, self._instr, self._culled_results, self._p['bmat'], self._p['wlen'], self._p['omega_period'], simOnly=True, return_value_flag=2) # make dict to contain new culled results culled_results_r = dict.fromkeys(self._culled_results) num_refl_valid = 0 for det_key in culled_results_r: presults = self._culled_results[det_key] ims = self._imgsd[det_key] # !!! must be OmegaImageSeries ome_step = sum(np.r_[-1, 1] * ims.metadata['omega'][0, :]) # measured vals for pull spots xyo_det = presults[:, [15, 16, 12]] # previous solutions calc vals xyo_det_fit = xyo_det_fit_dict[det_key] xpix_tol = self._p['refit_tol'][0] * panel.pixel_size_col ypix_tol = self._p['refit_tol'][0] * panel.pixel_size_row fome_tol = self._p['refit_tol'][1] * ome_step # define difference vectors for spot fits x_diff = abs(xyo_det[:, 0] - xyo_det_fit['calc_xy'][:, 0]) y_diff = abs(xyo_det[:, 1] - xyo_det_fit['calc_xy'][:, 1]) ome_diff = np.degrees( xfcapi.angularDifference(xyo_det[:, 2], xyo_det_fit['calc_omes'])) # filter out reflections with centroids more than # a pixel and delta omega away from predicted value idx_new = np.logical_and( x_diff <= xpix_tol, np.logical_and(y_diff <= ypix_tol, ome_diff <= fome_tol)) # attach to proper dict entry culled_results_r[det_key] = presults[idx_new, :] num_refl_valid += sum(idx_new) pass # only execute fit if left with enough reflections if num_refl_valid > min_nrefl: grain_params_fit = fitGrain( grain_params_fit, self._instr, culled_results_r, self._p['bmat'], self._p['wlen'], ) # get chisq # TODO: do this while evaluating fit??? chisq = objFuncFitGrain(grain_params_fit[gFlag_ref], grain_params_fit, gFlag_ref, self._instr, culled_results_r, self._p['bmat'], self._p['wlen'], self._p['omega_period'], simOnly=False, return_value_flag=2) pass # close check on number of valid refls pass # close refit conditional return grain_id, completeness, chisq, grain_params_fit
pred_ome > d2r*(ome_stop - 2*ome_delta)) else: idx_ome = np.logical_and(pred_ome > d2r*(ome_start + 2*ome_delta), pred_ome < d2r*(ome_stop - 2*ome_delta)) # idx = np.logical_and(idx0, idx_ome) hkls = gtable[idx, 1:4].T # must be column vectors xyo_det = gtable[idx, -3:] # these are the cartesian centroids + ome xyo_det[:, 2] = xf.mapAngle(xyo_det[:, 2], ome_period) print "completeness: %f%%" %(100. * sum(idx)/float(len(idx))) if sum(idx) > 12: g_initial = grain_params g_refined = fitting.fitGrain(xyo_det, hkls, bMat, wlen, detector_params, g_initial[:3], g_initial[3:6], g_initial[6:], beamVec=bVec_ref, etaVec=eta_ref, distortion=(dFunc, dParams), gFlag=gFlag, gScl=gScl, omePeriod=ome_period) if i == 0: fid = open(filename %grainID, 'w') sd = xrdutil.pullSpots(pd, detector_params, g_refined, reader, distortion=(dFunc, dParams), eta_range=etaRange, ome_period=ome_period, tth_tol=tth_tol_r, eta_tol=eta_tol_r, ome_tol=ome_tol_r, panel_buff=[10, 10], npdiv=2, threshold=threshold, use_closest=True, doClipping=False, filename=fid) fid.close() pass