def calc_median_profile(self, roll_offset=0): """Calculate the median profile of the Line Pair region. Parameters ---------- roll_offset : int, float The offset to apply to the start of the profile, in radians. E.g. if set to pi/2, profile extraction will begin at 12 o clock (90 degrees). Returns ------- median profile : core.profile.Profile A 1D Profile of the Line Pair regions. """ # extract the profile for each ROI (5 adjacent profiles) for roi in self.ROIs.values(): roi.get_profile(self.image.array, size=2*np.pi*1000, start=np.pi+roll_offset) # average profiles together prof = np.zeros(len(roi.y_values)) for idx, roi in enumerate(self.ROIs.values()): prof += roi.y_values prof /= len(self.ROIs) new_prof = Profile(prof) new_prof.filter(0.001) # new_prof.ground() return new_prof
def _construct_pickets(self, tolerance, action_tolerance): """Construct the Picket instances.""" if self.orientation == orientations['UD']: leaf_prof = np.median(self._analysis_array, 0) else: leaf_prof = np.median(self._analysis_array, 1) leaf_prof = Profile(leaf_prof) _, peak_idxs = leaf_prof.find_peaks(min_peak_distance=0.01, min_peak_height=0.5) for peak in range(len(peak_idxs)): self.pickets.append(Picket(self.image, tolerance, self.orientation, action_tolerance))
def _threshold(self): """Threshold the image by subtracting the minimum value. Allows for more accurate image orientation determination. """ col_prof = np.median(self.image.array, 0) col_prof = Profile(col_prof) row_prof = np.median(self.image.array, 1) row_prof = Profile(row_prof) _, r_peak_idx = row_prof.find_peaks(min_peak_distance=0.01, exclude_lt_edge=0.05, exclude_rt_edge=0.05) _, c_peak_idx = col_prof.find_peaks(min_peak_distance=0.01, exclude_lt_edge=0.05, exclude_rt_edge=0.05) min_val = self.image.array[r_peak_idx[0]:r_peak_idx[-1], c_peak_idx[0]:c_peak_idx[-1]].min() self._analysis_array = self.image.array.copy() self._analysis_array[self._analysis_array < min_val] = min_val self._analysis_array -= min_val
def _calc_mlc_positions(self, leaf_centers): """Calculate the positions of all the MLC pairs.""" diff = np.diff(leaf_centers) sample_width = np.round(np.median(diff*2/5)/2).astype(int) for mlc_num, mlc_peak_loc in enumerate(np.round(leaf_centers).astype(int)): mlc_rows = np.arange(mlc_peak_loc-sample_width, mlc_peak_loc+sample_width+1) if self.orientation == orientations['UD']: pix_vals = np.median(self._analysis_array[mlc_rows, :], axis=0) else: pix_vals = np.median(self._analysis_array[:, mlc_rows], axis=1) prof = Profile(pix_vals) prof.find_FWXM_peaks(fwxm=80, min_peak_distance=0.01, min_peak_height=0.5, interpolate=True) for idx, peak in enumerate(prof.peaks): if self.orientation == orientations['UD']: meas = MLC_Meas((peak.idx, mlc_rows[0]), (peak.idx, mlc_rows[-1])) else: meas = MLC_Meas((mlc_rows[0], peak.idx), (mlc_rows[-1], peak.idx)) self.pickets[idx].mlc_meas.append(meas)
def _find_leaf_centers(self, hdmlc): """Return the leaf centers perpendicular to the leaf motion.""" # generate some settings sm_lf_wdth = 5 * self.image.dpmm bg_lf_wdth = sm_lf_wdth * 2 if hdmlc: sm_lf_wdth /= 2 bg_lf_wdth /= 2 self._sm_lf_meas_wdth = slmw = int(round(sm_lf_wdth*3/4)) self._bg_lf_meas_wdth = blmw = int(round(bg_lf_wdth*3/4)) bl_ex = int(bg_lf_wdth/4) sm_ex = int(sm_lf_wdth/4) # generate leaf profile if self.orientation == orientations['UD']: leaf_prof = np.mean(self._analysis_array, 1) center = self.image.center.y else: leaf_prof = np.mean(self._analysis_array, 0) center = self.image.center.x leaf_prof = Profile(leaf_prof) # ground profile to reasonable level _, peak_idxs = leaf_prof.find_peaks(min_peak_distance=self._sm_lf_meas_wdth, exclude_lt_edge=sm_ex, exclude_rt_edge=sm_ex) min_val = leaf_prof.y_values[peak_idxs[0]:peak_idxs[-1]].min() leaf_prof.y_values[leaf_prof.y_values < min_val] = min_val # remove unevenness in signal leaf_prof.y_values = signal.detrend(leaf_prof.y_values, bp=[int(len(leaf_prof.y_values)/3), int(len(leaf_prof.y_values)*2/3)]) _, peak_idxs = leaf_prof.find_peaks(min_peak_distance=self._sm_lf_meas_wdth, exclude_lt_edge=sm_ex, exclude_rt_edge=sm_ex) leaf_range = (peak_idxs[-1] - peak_idxs[0]) / self.image.dpmm # mm sm_lf_range = 220 # mm # find leaf peaks if leaf_range > sm_lf_range: lt_biglittle_lf_bndry = int(round(center - 100 * self.image.dpmm)) rt_biglittle_lf_bndry = int(round(center + 100 * self.image.dpmm)) pp = leaf_prof.subdivide([lt_biglittle_lf_bndry, rt_biglittle_lf_bndry], slmw) if len(pp) != 3: raise ValueError("3 Profiles weren't found but should have been") # Left Big MLC region _, peak_idxs = pp[0].find_peaks(min_peak_distance=blmw, exclude_lt_edge=bl_ex) peak_diff = np.diff(peak_idxs).mean() lt_v_idx = np.array(peak_idxs[:-1]) + peak_diff/2 # Middle, small MLC region _, peak_idxs = pp[1].find_peaks(min_peak_distance=slmw) peak_diff = np.diff(peak_idxs).mean() mid_v_idx = np.array(peak_idxs[:-1]) + peak_diff / 2 # Right Big MLC region _, peak_idxs = pp[2].find_peaks(min_peak_distance=blmw, exclude_rt_edge=bl_ex) peak_diff = np.diff(peak_idxs).mean() rt_v_idx = np.array(peak_idxs[:-1]) + peak_diff / 2 leaf_center_idxs = np.concatenate((lt_v_idx, mid_v_idx, rt_v_idx)) else: _, peak_idxs = leaf_prof.find_peaks(min_peak_distance=slmw, exclude_lt_edge=sm_ex, exclude_rt_edge=sm_ex) _, peak_idxs = leaf_prof.find_FWXM_peaks(min_peak_distance=slmw, interpolate=True) peak_diff = np.diff(peak_idxs).mean() leaf_center_idxs = np.array(peak_idxs[:-1]) + peak_diff / 2 return leaf_center_idxs