Exemplo n.º 1
0
    def test_orientation_FF_reduced(quat):
        """
        input parameters are [
        plane_data, instrument, imgser_dict,
        tth_tol, eta_tol, ome_tol, npdiv, threshold
        ]
        """
        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']

        phi = 2*np.arccos(quat[0])
        n = xfcapi.unitRowVector(quat[1:])
        grain_params = np.hstack([
            phi*n, cnst.zeros_3, cnst.identity_6x1,
        ])

        compl, scrap = instrument.pull_spots(
            plane_data, grain_params, imgser_dict,
            tth_tol=tth_tol, eta_tol=eta_tol, ome_tol=ome_tol,
            npdiv=npdiv, threshold=threshold,
            eta_ranges=None, ome_period=(-np.pi, np.pi),
            check_only=True)

        return sum(compl)/float(len(compl))
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
def fit_grain_FF_reduced(grain_id):
    """
    Perform non-linear least-square fit for the specified grain.

    Parameters
    ----------
    grain_id : int
        The grain id.

    Returns
    -------
    grain_id : int
        The grain id.
    completeness : float
        The ratio of predicted to measured (observed) Bragg reflections.
    chisq: float
        Figure of merit describing the sum of squared residuals for each Bragg
        reflection in the form (x, y, omega) normalized by the total number of
        degrees of freedom.
    grain_params : array_like
        The optimized grain parameters
        [<orientation [3]>, <centroid [3]> <inverse stretch [6]>].

    Notes
    -----
    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']
    prefix = paramMP['spots_filename']
    spots_filename = None if prefix is None else prefix % grain_id

    grain = grains_table[grain_id]
    grain_params = grain[3:15]

    for tols in zip(tth_tol, eta_tol, ome_tol):
        complvec, results = instrument.pull_spots(plane_data,
                                                  grain_params,
                                                  imgser_dict,
                                                  tth_tol=tols[0],
                                                  eta_tol=tols[1],
                                                  ome_tol=tols[2],
                                                  npdiv=npdiv,
                                                  threshold=threshold,
                                                  eta_ranges=eta_ranges,
                                                  ome_period=ome_period,
                                                  dirname=analysis_dirname,
                                                  filename=spots_filename,
                                                  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]
            '''
            grab panel results:
                peak_id
                hkl_id
                hkl
                sum_int
                max_int,
                pred_angs,
                meas_angs,
                meas_xy
            '''
            presults = results[det_key]
            nrefl = len(presults)

            # make data arrays
            refl_ids = np.empty(nrefl)
            max_int = np.empty(nrefl)
            for i, spot_data in enumerate(presults):
                refl_ids[i] = spot_data[0]
                max_int[i] = spot_data[4]

            valid_refl_ids = refl_ids >= 0

            # find unsaturated spots on this panel
            unsat_spots = np.ones(len(valid_refl_ids), dtype=bool)
            if panel.saturation_level is not None:
                unsat_spots[valid_refl_ids] = \
                    max_int[valid_refl_ids] < 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(refl_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
            # FIXME: want to avoid looping again here
            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
            return grain_id, completeness, np.inf, grain_params
        else:
            grain_params = 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[gFlag_ref],
                                    grain_params,
                                    gFlag_ref,
                                    instrument,
                                    culled_results,
                                    plane_data.latVecOps['B'],
                                    plane_data.wavelength,
                                    ome_period,
                                    simOnly=False,
                                    return_value_flag=2)
            pass  # end conditional on fit
        pass  # end tolerance looping

    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[gFlag_ref],
                                           grain_params,
                                           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]

            if not presults:
                culled_results_r[det_key] = []
                continue

            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 > 12:
            grain_params = fitGrain(grain_params, instrument, culled_results_r,
                                    plane_data.latVecOps['B'],
                                    plane_data.wavelength)
            # get chisq
            # TODO: do this while evaluating fit???
            chisq = objFuncFitGrain(grain_params[gFlag_ref],
                                    grain_params,
                                    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