class_docstr: Class for the Diffusion Kurtosis Model
      
docstr: Diffusion Kurtosis Tensor Model [1]
  
  Parameters
  ----------
  gtab : GradientTable instance
      The gradient table for the data set.
  fit_method : str or callable, optional
      str be one of the following:
          'OLS' or 'ULLS' for ordinary least squares.
          'WLS', 'WLLS' or 'UWLLS' for weighted ordinary least squares.
              See dki.ls_fit_dki.
          'CLS' for LMI constrained ordinary least squares [2].
          'CWLS' for LMI constrained weighted least squares [2].
              See dki.cls_fit_dki.
      callable has to have the signature:
          fit_method(design_matrix, data, *args, **kwargs).
      Default: "WLS"
  args, kwargs :
      arguments and key-word arguments passed to the fit_method.
  
  References
  ----------
  .. [1] Tabesh, A., Jensen, J.H., Ardekani, B.A., Helpern, J.A., 2011.
         Estimation of tensors and tensor-derived measures in diffusional
         kurtosis imaging. Magn Reson Med. 65(3), 823-836
  .. [2] Dela Haije et al. "Enforcing necessary non-negativity constraints
         for common diffusion MRI models using sum of squares
         programming". NeuroImage 209, 2020, 116405.
docstr_tok: ["Diffusion","Kurtosis","Tensor","Model","[","1","]","Parameters","--","--","--","--","--","gtab",":","GradientTable","instance","The","gradient","table","for","the","data","set",".","fit_method",":","str","or","callable",",","optional","str","be","one","of","the","following",":","'OLS","'","or","'ULLS","'","for","ordinary","least","squares",".","'WLS","'",",","'WLLS","'","or","'UWLLS","'","for","weighted","ordinary","least","squares",".","See","dki.ls_fit_dki",".","'CLS","'","for","LMI","constrained","ordinary","least","squares","[","2","]",".","'CWLS","'","for","LMI","constrained","weighted","least","squares","[","2","]",".","See","dki.cls_fit_dki",".","callable","has","to","have","the","signature",":","fit_method","(","design_matrix",",","data",",","*","args",",","*","*","kwargs",")",".","Default",":","``","WLS","''","args",",","kwargs",":","arguments","and","key-word","arguments","passed","to","the","fit_method",".","References","--","--","--","--","--","..","[","1","]","Tabesh",",","A.",",","Jensen",",","J.H.",",","Ardekani",",","B.A.",",","Helpern",",","J.A.",",","2011",".","Estimation","of","tensors","and","tensor-derived","measures","in","diffusional","kurtosis","imaging",".","Magn","Reson","Med",".","65","(","3",")",",","823-836","..","[","2","]","Dela","Haije","et","al",".","``","Enforcing","necessary","non-negativity","constraints","for","common","diffusion","MRI","models","using","sum","of","squares","programming","''",".","NeuroImage","209",",","2020",",","116405","."]
code: def __init__(self, gtab, fit_method="WLS", *args, **kwargs):
      """Diffusion Kurtosis Tensor Model [1]
  
      Parameters
      ----------
      gtab : GradientTable instance
          The gradient table for the data set.
      fit_method : str or callable, optional
          str be one of the following:
              'OLS' or 'ULLS' for ordinary least squares.
              'WLS', 'WLLS' or 'UWLLS' for weighted ordinary least squares.
                  See dki.ls_fit_dki.
              'CLS' for LMI constrained ordinary least squares [2].
              'CWLS' for LMI constrained weighted least squares [2].
                  See dki.cls_fit_dki.
          callable has to have the signature:
              fit_method(design_matrix, data, *args, **kwargs).
          Default: "WLS"
      args, kwargs :
          arguments and key-word arguments passed to the fit_method.
  
      References
      ----------
      .. [1] Tabesh, A., Jensen, J.H., Ardekani, B.A., Helpern, J.A., 2011.
             Estimation of tensors and tensor-derived measures in diffusional
             kurtosis imaging. Magn Reson Med. 65(3), 823-836
      .. [2] Dela Haije et al. "Enforcing necessary non-negativity constraints
             for common diffusion MRI models using sum of squares
             programming". NeuroImage 209, 2020, 116405.
  
      """
      ReconstModel.__init__(self, gtab)
  
      # Check if at least three b-values are given
      enough_b = check_multi_b(self.gtab, 3, non_zero=False)
      if not enough_b:
          msg = "DKI requires at least 3 b-values (which can include b=0)."
          raise ValueError(msg)
  
      self.common_fit_method = not callable(fit_method)
      if self.common_fit_method:
          try:
              self.fit_method = common_fit_methods[fit_method]
          except KeyError:
              msg = (
                  '"'
                  + str(fit_method)
                  + '" is not a known fit method. The'
              )
              msg += " fit method should either be a function or one of the"
              msg += " common fit methods."
              raise ValueError(msg)
  
      self.args = args
      self.kwargs = kwargs
  
      self.min_signal = self.kwargs.pop("min_signal", None)
      if self.min_signal is None:
          self.min_signal = MIN_POSITIVE_SIGNAL
      elif self.min_signal <= 0:
          msg = (
              "The `min_signal` key-word argument needs to be strictly"
          )
          msg += " positive."
          raise ValueError(msg)
  
      self.design_matrix = design_matrix(self.gtab)
      self.inverse_design_matrix = np.linalg.pinv(self.design_matrix)
  
      tol = 1e-6
      self.min_diffusivity = tol / -self.design_matrix.min()
  
      self.convexity_constraint = fit_method in {"CLS", "CWLS"}
      if self.convexity_constraint:
          self.cvxpy_solver = self.kwargs.pop("cvxpy_solver", None)
          self.convexity_level = self.kwargs.pop(
              "convexity_level", "full"
          )
          msg = "convexity_level must be a positive, even number, or 'full'."
          if isinstance(self.convexity_level, str):
              if self.convexity_level == "full":
                  self.sdp_constraints = load_sdp_constraints("dki")
              else:
                  raise ValueError(msg)
          elif self.convexity_level < 0 or self.convexity_level % 2:
              raise ValueError(msg)
          else:
              if self.convexity_level > 4:
                  msg = "Maximum convexity_level supported is 4."
                  warnings.warn(msg)
                  self.convexity_level = 4
              self.sdp_constraints = load_sdp_constraints(
                  "dki", self.convexity_level
              )
          self.sdp = PositiveDefiniteLeastSquares(
              22, A=self.sdp_constraints
          )
  
      self.weights = fit_method in {"WLS", "WLLS", "UWLLS", "CWLS"}
      self.is_multi_method = fit_method in [
          "WLS",
          "OLS",
          "UWLLS",
          "ULLS",
          "WLLS",
          "OLLS",
          "CLS",
          "CWLS",
      ]
  
imports: import numpy
  import warnings
  import scipy.optimize
  import dipy.core.sphere
  from dipy.reconst.multi_voxel import multi_voxel_fit
  from dipy.reconst.dti import TensorFit, mean_diffusivity, from_lower_triangular, lower_triangular, decompose_tensor, MIN_POSITIVE_SIGNAL, nlls_fit_tensor, restore_fit_tensor
  from dipy.reconst.utils import dki_design_matrix
  from dipy.reconst.recspeed import local_maxima
  from dipy.reconst.base import ReconstModel
  from dipy.core.ndindex import ndindex
  from dipy.core.geometry import sphere2cart, cart2sphere, perpendicular_directions
  from dipy.core.optimize import PositiveDefiniteLeastSquares
  from dipy.data import get_sphere, get_fnames, load_sdp_constraints
  from dipy.reconst.vec_val_sum import vec_val_vect
  from dipy.core.gradients import check_multi_b
label_desc: Use image node_id 1 to create a new DiffusionKurtosisModel object from inherited base classes: ReconstModel with example: obj = DiffusionKurtosisModel(gtab, fit_method)