def __init__(self, model, target_image=None, levels_image=None, tau=None):
        """
        Target gray matter segmentation constructor

        :param model: Model used to compute the segmentation, type: Model

        :param target_image: Target image to segment gray matter on, type: Image

        :param tau: Weighting parameter associated with the geodesic distances in the model dictionary, type: float
        """
        self.model = model

        # Get the target image
        if len(target_image.data.shape) == 3:
            self.target = [Slice(slice_id=i_slice, im=target_slice) for i_slice, target_slice in enumerate(target_image.data)]
        elif len(target_image.data.shape) == 2:
            self.target = [Slice(slice_id=0, im=target_image.data)]

        # if levels_image is not None:
        if isinstance(levels_image, Image):
            nz_coord = levels_image.getNonZeroCoordinates()
            for i_level_slice, level_slice in enumerate(levels_image.data):
                nz_val = []
                for coord in nz_coord:
                    if coord.x == i_level_slice:
                        nz_val.append(level_slice[coord.y, coord.z])
                try:
                    self.target[i_level_slice].set(level=int(round(sum(nz_val)/len(nz_val))))
                except ZeroDivisionError:
                            sct.printv('No level label for slice ' + str(i_level_slice) + ' of target')
                            self.target[i_level_slice].set(level=0)
        elif isinstance(levels_image, str):
            self.target[0].set(level=get_key_from_val(self.model.dictionary.level_label, levels_image))

        # self.majority_vote_segmentation()

        # self.target_M = self.target_pairwise_registration()
        self.target_pairwise_registration()

        # coord_projected_target is a list of all the coord of the target's projected slices
        sct.printv('\nProjecting the target image in the reduced common space ...', model.param.verbose, 'normal')
        # self.coord_projected_target = model.pca.project(self.target_M) if self.target_M is not None else None
        self.coord_projected_target = model.pca.project([target_slice.im_M for target_slice in self.target])

        self.epsilon = round(1.0/self.model.dictionary.J, 4)/2
        print 'epsilon : ', self.epsilon

        if tau is None:
            self.tau = self.compute_tau()
        else:
            self.tau = tau

        if levels_image is not None:
            self.beta = self.compute_beta(self.coord_projected_target, target_levels=np.asarray([target_slice.level for target_slice in self.target]), tau=self.tau)
        else:
            self.beta = self.compute_beta(self.coord_projected_target, tau=self.tau)

        sct.printv('\nSelecting the dictionary slices most similar to the target ...', model.param.verbose, 'normal')

        self.selected_k_slices = self.select_k_slices(self.beta)

        slice_levels = np.asarray([self.model.dictionary.level_label[dic_slice.level] for dic_slice in self.model.dictionary.slices])
        fic_selected_slices = open('selected_slices.txt', 'w')
        fic_selected_slices.write(str(slice_levels[self.selected_k_slices.reshape(self.model.dictionary.J,)]))
        fic_selected_slices.close()

        sct.printv('\nComputing the result gray matter segmentation ...', model.param.verbose, 'normal')
        # self.target_GM_seg_M = self.label_fusion(self.selected_k_slices)
        self.label_fusion(self.selected_k_slices)

        sct.printv('\nRegistering the result gray matter segmentation back into the target original space...',
                   model.param.verbose, 'normal')
        self.target_pairwise_registration(inverse=True)

    # ------------------------------------------------------------------------------------------------------------------
dataset/ETHPy150Open neuropoly/spinalcordtoolbox/dev/sct_segment_gray_matter_asman/sct_asman_old.py/TargetSegmentationPairwise.__init__/original