class_docstr: Convenience class to encapsulate TCK file format.
  
  Notes
  -----
  MRtrix (so its file format: TCK) considers streamlines coordinates
  to be in world space (RAS+ and mm space). MRtrix refers to that space
  as the "real" or "scanner" space [#]_.
  
  Moreover, when streamlines are mapped back to voxel space [#]_, a
  streamline point located at an integer coordinate (i,j,k) is considered
  to be at the center of the corresponding voxel. This is in contrast with
  TRK's internal convention where it would have referred to a corner.
  
  NiBabel's streamlines internal representation follows the same
  convention as MRtrix.
  
  .. [#] http://www.nitrc.org/pipermail/mrtrix-discussion/2014-January/000859.html
  .. [#] http://nipy.org/nibabel/coordinate_systems.html#voxel-coordinates-are-in-voxel-space
class_docstr_tok: ["Convenience","class","to","encapsulate","TCK","file","format",".","Notes","--","--","-","MRtrix","(","so","its","file","format",":","TCK",")","considers","streamlines","coordinates","to","be","in","world","space","(","RAS+","and","mm","space",")",".","MRtrix","refers","to","that","space","as","the","``","real","''","or","``","scanner","''","space","[","#","]","_",".","Moreover",",","when","streamlines","are","mapped","back","to","voxel","space","[","#","]","_",",","a","streamline","point","located","at","an","integer","coordinate","(","i",",","j",",","k",")","is","considered","to","be","at","the","center","of","the","corresponding","voxel",".","This","is","in","contrast","with","TRK","'s","internal","convention","where","it","would","have","referred","to","a","corner",".","NiBabel","'s","streamlines","internal","representation","follows","the","same","convention","as","MRtrix",".","..","[","#","]","http",":","\/\/www.nitrc.org\/pipermail\/mrtrix-discussion\/2014-January\/000859.html","..","[","#","]","http",":","\/\/nipy.org\/nibabel\/coordinate_systems.html","#","voxel-coordinates-are-in-voxel-space"]
docstr: Reads a TCK header from a file.
  
  Parameters
  ----------
  fileobj : string or file-like object
      If string, a filename; otherwise an open file-like object in
      binary mode pointing to TCK file (and ready to read from the
      beginning of the TCK header). Note that calling this function
      does not change the file position.
  
  Returns
  -------
  header : dict
      Metadata associated with this tractogram file.
docstr_tok: ["Reads","a","TCK","header","from","a","file",".","Parameters","--","--","--","--","--","fileobj",":","string","or","file-like","object","If","string",",","a","filename",";","otherwise","an","open","file-like","object","in","binary","mode","pointing","to","TCK","file","(","and","ready","to","read","from","the","beginning","of","the","TCK","header",")",".","Note","that","calling","this","function","does","not","change","the","file","position",".","Returns","--","--","--","-","header",":","dict","Metadata","associated","with","this","tractogram","file","."]
code: def _read_header(cls, fileobj):
      """Reads a TCK header from a file.
  
      Parameters
      ----------
      fileobj : string or file-like object
          If string, a filename; otherwise an open file-like object in
          binary mode pointing to TCK file (and ready to read from the
          beginning of the TCK header). Note that calling this function
          does not change the file position.
  
      Returns
      -------
      header : dict
          Metadata associated with this tractogram file.
      """
  
      # Build header dictionary from the buffer
      hdr = {}
      offset_data = 0
  
      with Opener(fileobj) as f:
          # Record start position
          start_position = f.tell()
  
          # Make sure we are at the beginning of the file
          f.seek(0, os.SEEK_SET)
  
          # Read magic number
          magic_number = f.read(len(cls.MAGIC_NUMBER))
  
          if magic_number != cls.MAGIC_NUMBER:
              raise HeaderError(f"Invalid magic number: {magic_number}")
  
          hdr[Field.MAGIC_NUMBER] = magic_number
  
          f.seek(1, os.SEEK_CUR)  # Skip \n
  
          found_end = False
          key = None
          tmp_hdr = {}
  
          # Read all key-value pairs contained in the header, stop at EOF
          for n_line, line in enumerate(f, 1):
              line = line.decode("utf-8").strip()
  
              if not line:  # Skip empty lines
                  continue
  
              if line == "END":  # End of the header
                  found_end = True
                  break
  
              # Set new key if available, otherwise append to last known key
              with suppress(ValueError):
                  key, line = line.split(":", 1)
                  key = key.strip()
  
              # Apparent continuation line before any keys are found
              if key is None:
                  raise HeaderError(
                      f"Invalid header (line {n_line}): {line}"
                  )
  
              tmp_hdr.setdefault(key, []).append(line.strip())
  
          if not found_end:
              raise HeaderError("Missing END in the header.")
  
          hdr.update(
              {key: "\n".join(val) for key, val in tmp_hdr.items()}
          )
  
          offset_data = f.tell()
  
          # Set the file position where it was, in case it was previously open
          if start_position is not None:
              f.seek(start_position, os.SEEK_SET)
  
      # Check integrity of TCK header.
      if "datatype" not in hdr:
          msg = "Missing 'datatype' attribute in TCK header. Assuming it is Float32LE."
          warnings.warn(msg, HeaderWarning)
          hdr["datatype"] = "Float32LE"
  
      if not hdr["datatype"].startswith("Float32"):
          msg = (
              f"TCK only supports float32 dtype but 'datatype: {hdr['datatype']}' "
              "was specified in the header."
          )
          raise HeaderError(msg)
  
      if "file" not in hdr:
          msg = "Missing 'file' attribute in TCK header. Will try to guess it."
          warnings.warn(msg, HeaderWarning)
          hdr["file"] = f". {offset_data}"
  
      if hdr["file"].split()[0] != ".":
          msg = (
              "TCK only supports single-file - in other words the filename part must be "
              f"specified as '.' but '{hdr['file'].split()[0]}' was specified."
          )
          raise HeaderError("Missing 'file' attribute in TCK header.")
  
      # Set endianness and _dtype attributes in the header.
      hdr[Field.ENDIANNESS] = (
          ">" if hdr["datatype"].endswith("BE") else "<"
      )
  
      hdr["_dtype"] = np.dtype(hdr[Field.ENDIANNESS] + "f4")
  
      # Keep the file position where the data begin.
      hdr["_offset_data"] = int(hdr["file"].split()[1])
  
      return hdr
  
imports: import os
  import warnings
  from contextlib import suppress
  import numpy
  from nibabel.openers import Opener
  from .array_sequence import ArraySequence
  from .header import Field
  from .tractogram import LazyTractogram, Tractogram, TractogramItem
  from .tractogram_file import DataError, DataWarning, HeaderError, HeaderWarning, TractogramFile
  from .utils import peek_next
label_desc: Use image node_id 8 for calling the TckFile obj's underlying member method code with example usage: obj._read_header(cls, fileobj) and returns: hdr