class_docstr: Handle decompression of a compressed data file.
  
  Constructor
  -----------
  
  cache_size : int
      Maximum number of chunks to keep in memory while reading. Every chunk kept in cache
      may take a few dozens of MB in RAM.
  check_after_decompress : bool
      Whether to perform the automatic check after decompression.
class_docstr_tok: ["Handle","decompression","of","a","compressed","data","file",".","Constructor","--","--","--","--","--","-","cache_size",":","int","Maximum","number","of","chunks","to","keep","in","memory","while","reading",".","Every","chunk","kept","in","cache","may","take","a","few","dozens","of","MB","in","RAM",".","check_after_decompress",":","bool","Whether","to","perform","the","automatic","check","after","decompression","."]
docstr: Open a compressed data file.
  
  Parameters
  ----------
  
  cdata : str or Path
      Path to the compressed data file.
  cmeta : str or Path or dict
      Path to the compression header JSON file, or its contents as a Python dictionary.
docstr_tok: ["Open","a","compressed","data","file",".","Parameters","--","--","--","--","--","cdata",":","str","or","Path","Path","to","the","compressed","data","file",".","cmeta",":","str","or","Path","or","dict","Path","to","the","compression","header","JSON","file",",","or","its","contents","as","a","Python","dictionary","."]
code: def open(self, cdata, cmeta=None):
      """Open a compressed data file.
  
      Parameters
      ----------
  
      cdata : str or Path
          Path to the compressed data file.
      cmeta : str or Path or dict
          Path to the compression header JSON file, or its contents as a Python dictionary.
  
      """
      # Read metadata file.
      if cmeta is None:
          cmeta = Path(cdata).with_suffix(".ch")
      if not isinstance(cmeta, dict):
          with open(cmeta, "r") as f:
              cmeta = json.load(f)
      assert isinstance(cmeta, dict)
      self.cmeta = Bunch(cmeta)
      # Read some values from the metadata file.
      self.n_channels = self.cmeta.n_channels
      self.sample_rate = self.cmeta.sample_rate
      self.dtype = np.dtype(self.cmeta.dtype)
      self.chunk_offsets = self.cmeta.chunk_offsets
      self.chunk_bounds = self.cmeta.chunk_bounds
      self.chunk_order = self.cmeta.chunk_order
      self.n_samples = self.chunk_bounds[-1]
      self.n_chunks = len(self.chunk_bounds) - 1
      self.shape = (self.n_samples, self.n_channels)
      self.ndim = 2
  
      # Batches.
      self.batch_size = (
          self.config.n_threads
      )  # in each batch, there is 1 chunk per thread.
      self.n_batches = int(np.ceil(self.n_chunks / self.batch_size))
  
      # Open data.
      if isinstance(cdata, (str, Path)):
          if Path(cdata).suffix in (".bin", ".dat"):  # pragma: no cover
              # This can arise if trying to decompress an already-decompressed file.
              logger.error(
                  "File to decompress has unexpected extension %s.",
                  Path(cdata).suffix,
              )
          cdata = open(cdata, "rb")
      self.cdata = cdata
  
      self.set_cache_size()
  
imports: import argparse
  import bisect
  from functools import lru_cache
  import hashlib
  import json
  import logging
  import multiprocessing
  from multiprocessing.dummy import Pool
  import os
  import os.path
  from pathlib import Path
  import sys
  from threading import Lock
  import zlib
  from tqdm import tqdm
  import numpy
label_desc: Use image node_id 2 for calling the Reader obj's underlying member method code with example usage: obj.open(cdata, cmeta) without return types