class_docstr: Class for Siemens mosaic format data
  
  Mosaic format is a way of storing a 3D image in a 2D slice - and
  it's as simple as you'd imagine it would be - just storing the slices
  in a mosaic similar to a light-box print.
  
  We need to allow for this when getting the data and (because of an
  idiosyncrasy in the way Siemens stores the images) calculating the
  position of the first voxel.
  
  Adds attributes:
  
  * n_mosaic : int
  * mosaic_size : int
docstr: Return position of first voxel in data block
  
  Adjusts Siemens mosaic position vector for bug in mosaic format
  position.  See ``dicom_mosaic`` in doc/theory for details.
  
  Parameters
  ----------
  None
  
  Returns
  -------
  img_pos : (3,) array
     position in mm of voxel (0,0,0) in Mosaic array
docstr_tok: ["Return","position","of","first","voxel","in","data","block","Adjusts","Siemens","mosaic","position","vector","for","bug","in","mosaic","format","position",".","See","``","dicom_mosaic","``","in","doc\/theory","for","details",".","Parameters","--","--","--","--","--","None","Returns","--","--","--","-","img_pos",":","(","3",",",")","array","position","in","mm","of","voxel","(","0,0,0",")","in","Mosaic","array"]
code: def image_position(self):
      """Return position of first voxel in data block
  
      Adjusts Siemens mosaic position vector for bug in mosaic format
      position.  See ``dicom_mosaic`` in doc/theory for details.
  
      Parameters
      ----------
      None
  
      Returns
      -------
      img_pos : (3,) array
         position in mm of voxel (0,0,0) in Mosaic array
      """
      ipp = super().image_position
      # mosaic image size
      md_rows, md_cols = (self.get("Rows"), self.get("Columns"))
      iop = self.image_orient_patient
      pix_spacing = self.get("PixelSpacing")
      if any(
          x is None for x in (ipp, md_rows, md_cols, iop, pix_spacing)
      ):
          return None
      # PixelSpacing values are python Decimal in pydicom 0.9.7
      pix_spacing = np.array(list(map(float, pix_spacing)))
      # size of mosaic array before rearranging to 3D.
      md_rc = np.array([md_rows, md_cols])
      # size of slice array after reshaping to 3D
      rd_rc = md_rc / self.mosaic_size
      # apply algorithm for undoing mosaic translation error - see
      # ``dicom_mosaic`` doc
      vox_trans_fixes = (md_rc - rd_rc) / 2
      # flip IOP field to refer to rows then columns index change -
      # see dicom_orientation doc
      Q = np.fliplr(iop) * pix_spacing
      return ipp + np.dot(Q, vox_trans_fixes[:, None]).ravel()
  
imports: import operator
  import warnings
  import numpy
  from nibabel.optpkg import optional_package
  from ..onetime import auto_attr
  from ..openers import ImageOpener
  from .None import csareader
  from .dwiparams import B2q, nearest_pos_semi_def, q2bg
label_desc: Use image node_id 3 for calling the MosaicWrapper obj's underlying member method code with example usage: obj.image_position() and returns: unknown, None