Пример #1
0
    def create_fancy_profile_plot(self,
                                  data,
                                  N,
                                  z,
                                  name='test',
                                  unit='rad',
                                  chip='',
                                  distance=0):
        ''' Full beam profile plot with analysis
        '''
        left, width = 0.1, 0.65
        bottom, height = 0.13, 0.65
        bottom_h = left_h = left + width + 0.07
        cbarHeight = 0.02

        rect_color = [left, bottom, width, height]
        rect_histx = [left, bottom_h + 0.02, width, 0.15]
        rect_histy = [left_h, bottom, 0.15, height]

        # get limits from raw data fields
        peak_x, peak_y, xmin, xmax, ymin, ymax = self.get_beam_parameters(
            data, z, N)
        extent = np.round((xmin, xmax, ymin, ymax), decimals=1)
        histBin = np.linspace(xmin, xmax, N)

        fig = plt.figure(figsize=(9, 9))
        axColor = fig.add_axes(rect_color)

        sumx = z[int((N - 1) / 2)]  # p.sum(z, 0)
        sumxn = sumx / np.amax(sumx)
        sumy = z.T[int((N - 1) / 2)]  # np.sum(z, 1)
        sumyn = sumy / np.amax(sumy)

        # plot image and contour
        peak_intensity = np.amax(z)
        im = plt.imshow(np.flip(z, 0),
                        cmap='viridis',
                        extent=extent,
                        interpolation="bicubic")
        cset = plt.contour(z / peak_intensity,
                           linewidths=.8,
                           cmap='cividis_r',
                           extent=extent)
        axColor.clabel(cset, inline=True, fmt="%1.1f", fontsize=8)
        axColor.set(xlabel='x position [mm]',
                    ylabel='y position [mm]',
                    title='Beam profile (' + name + ')')
        axColor.title.set_position([0.5, 1.01])

        # draw a circle at the peak value
        center_x = 0
        center_y = 0
        radius = (ymax - ymin) / (N - 1) / 2
        peak_xx = (xmax - xmin) / N * (peak_x + 0.5) + xmin
        peak_yy = (ymax - ymin) / N * (peak_y + 0.5) + ymin

        circle = Circle((peak_xx, peak_yy), radius, color='red', fill=False)
        if unit == 'rad':
            label = 'peak: %s Mrad/h \nat x=%.1f mm y=%.1f mm'
        if unit == 'A':
            label = 'peak: %s nA \nat x=%.1f mm y=%.1f mm'
        legend_helper = axColor.plot([],
                                     marker='o',
                                     markerfacecolor='none',
                                     markersize=10,
                                     linestyle='',
                                     color=circle.get_edgecolor())
        axColor.legend(
            legend_helper,
            [label % (np.round(peak_intensity, 2), peak_xx, peak_yy)])
        axColor.add_artist(circle)

        # draw a cross hair, indicating the laser position
        plt.axhline(y=center_y,
                    linewidth=0.5,
                    linestyle='dashed',
                    color='#d62728')
        plt.axvline(x=center_x,
                    linewidth=0.5,
                    linestyle='dashed',
                    color='#d62728')

        # plot cuts
        major_ticks = np.arange(0, 1.1, 0.5)
        minor_ticks = np.arange(0, 1.1, 0.25)

        axHistx = fig.add_axes(rect_histx,
                               xlim=(xmin, xmax),
                               ylim=(-0.05, 1.05))
        axHistx.plot(histBin, sumxn)
        axHistx.set(ylabel='rel. instensity in x')
        axHistx.title.set_position([0.4, 1.05])
        axHistx.set_yticks(major_ticks)
        axHistx.set_yticks(minor_ticks, minor=True)
        axHistx.grid(which='minor', alpha=0.2)
        axHistx.grid(which='major', alpha=0.5)

        thrshld_list = [0.5, 0.2]
        peaks, _ = find_peaks(sumxn, prominence=1, threshold=0.01)
        for thrshld in thrshld_list:
            try:
                results_half = peak_widths(sumxn, peaks, rel_height=thrshld)
                leng = len(results_half[0])
                if leng > 1:
                    ret = (results_half[i][-1]
                           for i in range(len(results_half)))
                    results_half = list(ret)
                axHistx.plot(histBin[peaks], sumxn[peaks], "x", color="C1")
                fwhm_line = float(results_half[1:][0]), self._conv_to_mm(
                    float(results_half[1:][1]), ymin, ymax,
                    N), self._conv_to_mm(float(results_half[1:][2]), ymin,
                                         ymax, N)
                axHistx.hlines(*fwhm_line, color="C2")
            except Exception as e:
                print(e)

        axHisty = fig.add_axes(rect_histy,
                               ylim=(ymin, ymax),
                               xlim=(-0.05, 1.05))
        axHisty.plot(sumyn, histBin)
        axHisty.set(xlabel='rel. instensity in y')
        axHisty.title.set_position([0.4, 1.015])
        axHisty.set_xticks(major_ticks)
        axHisty.set_xticks(minor_ticks, minor=True)
        axHisty.grid(which='minor', alpha=0.2)
        axHisty.grid(which='major', alpha=0.5)

        beam_diameter = {}
        peaks, _ = find_peaks(sumyn, distance=10)
        for thrshld in thrshld_list:
            try:
                results_half = peak_widths(sumyn, peaks, rel_height=thrshld)
                leng = len(results_half[0])
                if leng > 1:
                    ret = (results_half[i][-1]
                           for i in range(len(results_half)))
                    results_half = list(ret)
                axHisty.plot(sumyn[peaks], histBin[peaks], "x", color="C1")
                fwhm_line = float(results_half[1:][0]), self._conv_to_mm(
                    float(results_half[1:][1]), ymin, ymax,
                    N), self._conv_to_mm(float(results_half[1:][2]), ymin,
                                         ymax, N)
                axHisty.vlines(*fwhm_line, color="C2")
                beam_diameter.update(
                    {1 - thrshld: (fwhm_line[2] - fwhm_line[1])})
            except Exception as e:
                print(e)

        axCbar = fig.add_axes([left, 0.05, width, cbarHeight])
        if unit == 'A':
            label = '$\Delta$ diode current [nA]'
        if unit == 'rad':
            label = 'dose rate in Si$O_2$ [Mrad/h]'
        plt.colorbar(im, cax=axCbar, label=label, orientation='horizontal')
        # cbar.set_ticks(np.arange(np.floor(np.amin(z)), np.ceil(np.amax(z)) + 0.1, 0.1))

        # draw the chip outline
        # TODO: Implement chip rotation
        if chip in self._chip_outlines:
            sty = {
                'xy': (self._chip_outlines[chip]['pos_x'] -
                       self._chip_outlines[chip]['size_x'] / 2,
                       self._chip_outlines[chip]['pos_y'] -
                       self._chip_outlines[chip]['size_y'] / 2),
                'width':
                self._chip_outlines[chip]['size_x'],
                'height':
                self._chip_outlines[chip]['size_y'],
                'color':
                'red'
            }

            axColor.add_artist(
                Rectangle(sty['xy'],
                          sty['width'],
                          sty['height'],
                          color=sty['color'],
                          fill=False))
            axHistx.add_artist(
                Rectangle(sty['xy'],
                          sty['width'],
                          sty['height'],
                          color=sty['color'],
                          fill=True,
                          alpha=0.2))
            axHisty.add_artist(
                Rectangle(sty['xy'],
                          sty['width'],
                          sty['height'],
                          color=sty['color'],
                          fill=True,
                          alpha=0.2))

        # Summary
        textstr = '\n'.join(
            (r'distance=%.1f cm' % distance,
             r'peak=%.2f Mrad/h' % peak_intensity,
             r'' + '\n'.join("d@{:.0f}%: {:.1f}mm".format(100 * k, v)
                             for k, v in beam_diameter.items()),
             r'DUT={}'.format(chip)))
        props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
        fig.text(0.78,
                 0.92,
                 textstr,
                 fontsize=13,
                 ha="left",
                 va="center",
                 bbox=props)

        # save the plot
        plt.savefig(name + '.pdf', dpi=200)
        plt.savefig(name + '.png', dpi=200)
        plt.close('all')

        return peak_intensity, beam_diameter