예제 #1
0
	def __setattr__(self, name: str, val: Any) -> None:
		if name.startswith("!"):
			super(GlobalAttributeManager, self).__setattr__(name[1:], val)
		elif "/" in name:
			raise KeyError("Attribute name cannot contain slash (/)")
		else:
			if self.f is not None:
				if loompy.compare_loom_spec_version(self.f, "3.0.0") < 0 and "attrs" not in self.f["/"]:
					normalized = loompy.normalize_attr_values(val, False)
					self.f.attrs[name] = normalized
					self.f.flush()
					val = self.f.attrs[name]
					# Read it back in to ensure it's synced and normalized
					normalized = loompy.materialize_attr_values(val)
					self.__dict__["storage"][name] = normalized
				else:
					normalized = loompy.normalize_attr_values(val, True)
					if name in self.f["attrs"]:
						del self.f["attrs"][name]
					if not np.isscalar(normalized) and normalized.dtype == np.object_:
						self.ds._file.create_dataset("attrs/" + name, data=normalized, dtype=h5py.special_dtype(vlen=str))
					else:
						self.f["attrs"][name] = normalized
					self.f.flush()
					val = self.f["attrs"][name][()]
					# Read it back in to ensure it's synced and normalized
					normalized = loompy.materialize_attr_values(val)
					self.__dict__["storage"][name] = normalized
예제 #2
0
	def __init__(self, f: h5py.File) -> None:
		setattr(self, "!f", f)
		storage: Dict[str, str] = {}
		setattr(self, "!storage", storage)
		if "attrs" not in self.f:
			for key, val in f.attrs.items():
				materialized = loompy.materialize_attr_values(val)
				self.__dict__["storage"][key] = materialized
		else:
			for key, val in f["attrs"].items():
				materialized = loompy.materialize_attr_values(val[()])
				self.__dict__["storage"][key] = materialized
예제 #3
0
	def __setattr__(self, name: str, val: np.ndarray) -> None:
		"""
		Set the value of a named attribute

		Args:
			name (str) 			Name of the attribute
			val (np.ndarray)	Value of the attribute

		Remarks:
			Length must match the corresponding matrix dimension
			The values are automatically HMTL escaped and converted to ASCII for storage
		"""
		if name.startswith("!"):
			super(AttributeManager, self).__setattr__(name[1:], val)
		else:
			if self.ds is not None:
				values = loompy.normalize_attr_values(val)
				a = ["/row_attrs/", "/col_attrs/"][self.axis]
				if self.ds.shape[self.axis] != 0 and values.shape[0] != self.ds.shape[self.axis]:
					raise ValueError(f"Attribute must have exactly {self.ds.shape[self.axis]} values but {len(values)} were given")
				if self.ds._file[a].__contains__(name):
					del self.ds._file[a + name]
				self.ds._file[a + name] = values  # TODO: for 2D arrays, use block compression along columns/rows
				self.ds._file.flush()
				self.__dict__["storage"][name] = loompy.materialize_attr_values(self.ds._file[a][name][:])
			else:
				self.__dict__["storage"][name] = val
예제 #4
0
    def __setattr__(self, name: str, val: np.ndarray) -> None:
        """
		Set the value of a named attribute

		Args:
			name (str) 			Name of the attribute
			val (np.ndarray)	Value of the attribute

		Remarks:
			Length must match the corresponding matrix dimension
			The values are automatically HMTL escaped and converted to ASCII for storage
		"""
        if name.startswith("!"):
            super(AttributeManager, self).__setattr__(name[1:], val)
        elif "/" in name:
            raise KeyError("Attribute name cannot contain slash (/)")
        else:
            if self.ds is not None:
                values = loompy.normalize_attr_values(
                    val,
                    compare_loom_spec_version(self.ds._file, "3.0.0") >= 0)
                a = ["/row_attrs/", "/col_attrs/"][self.axis]
                if self.ds.shape[self.axis] != 0 and values.shape[
                        0] != self.ds.shape[self.axis]:
                    raise ValueError(
                        f"Attribute '{name}' must have exactly {self.ds.shape[self.axis]} values but {len(values)} were given"
                    )
                if self.ds._file[a].__contains__(name):
                    del self.ds._file[a + name]

                if isinstance(self.ds._file, h5py.File):
                    self.ds._file.create_dataset(
                        a + name,
                        data=values,
                        dtype=h5py.special_dtype(vlen=str)
                        if values.dtype == np.object_ else values.dtype,
                        maxshape=(values.shape[0], )
                        if len(values.shape) == 1 else (values.shape[0], None),
                        fletcher32=False,
                        compression="gzip",
                        shuffle=False,
                        compression_opts=2)
                else:
                    self.ds._file.create_dataset(
                        a + name,
                        data=values.astype(np.string_)
                        if values.dtype == np.object_ else values)

                self.ds._file[a + name].attrs["last_modified"] = timestamp()
                self.ds._file[a].attrs["last_modified"] = timestamp()
                self.ds._file.attrs["last_modified"] = timestamp()
                if isinstance(self.ds._file, h5py.File):
                    self.ds._file.flush()
                self.__dict__["storage"][
                    name] = loompy.materialize_attr_values(
                        self.ds._file[a][name][:])
            else:
                self.__dict__["storage"][name] = val
예제 #5
0
 def __getattr__(self, name: str) -> np.ndarray:
     try:
         return self.__dict__["storage"][name]
     except KeyError:
         if self.f is not None:
             if name in self.f.attrs:
                 val = self.f.attrs[name]
                 materialized = loompy.materialize_attr_values(val)
                 self.__dict__["storage"][name] = materialized
                 return materialized
         raise AttributeError(
             f"'{type(self)}' object has no attribute '{name}'")
예제 #6
0
 def __setattr__(self, name: str, val: Any) -> None:
     if name.startswith("!"):
         super(FileAttributeManager, self).__setattr__(name[1:], val)
     else:
         if self.f is not None:
             normalized = loompy.normalize_attr_values(val)
             self.f.attrs[name] = normalized
             self.f.flush()
             val = self.f.attrs[name]
             # Read it back in to ensure it's synced and normalized
             normalized = loompy.materialize_attr_values(val)
             self.__dict__["storage"][name] = normalized
예제 #7
0
	def __getattr__(self, name: str) -> np.ndarray:
		try:
			return self.__dict__["storage"][name]
		except KeyError:
			if self.f is not None:
				if loompy.compare_loom_spec_version(self.f, "3.0.0") < 0:
					if name in self.f.attrs:
						val = self.f.attrs[name]
					else:
						raise AttributeError(f"File has no global attribute '{name}'")
				else:
					if name in self.f["attrs"]:
						val = self.f["attrs"][name]
					else:
						raise AttributeError(f"File has no global attribute '{name}'")
				materialized = loompy.materialize_attr_values(val)
				self.__dict__["storage"][name] = materialized
				return materialized
예제 #8
0
	def __getattr__(self, name: str) -> np.ndarray:
		"""
		Return the named attribute

		Args:
			name (str) 	Name of the attribute

		Remarks:
			The values will be loaded from file, and properly HTML unescaped
		"""
		try:
			vals = self.__dict__["storage"][name]
			if vals is None:
				# Read values from the HDF5 file
				a = ["/row_attrs/", "/col_attrs/"][self.axis]
				vals = loompy.materialize_attr_values(self.ds._file[a][name][:])
				self.__dict__["storage"][name] = vals
			return vals
		except KeyError:
			raise AttributeError(f"'{type(self)}' object has no attribute '{name}'")