diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 7d28bc2..ba1146c 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -20,7 +20,7 @@ Added
 *****
 - ``raster.Image()``: expanded test_arr to test AttributeError #31
 - ``raster.Image()``: optional dimorder for arr and according test #31
-- dn2toa tests and testfiles #17
+- `dn2toa` tests and testfiles #17
 - ``data.source()``: accept WKT string as AOI #26
 - ``data.source()``: check if an AOI string is a file or a WKT string #26
 
@@ -31,6 +31,7 @@ Fixed
 Changed
 *******
 - ``raster.Image()``: changed ``dn2toa(platform, metadata, wavelengths)`` to ``dn2toa(platform, mtl_file, wavelengths)`` #17
+- ``raster.Image()``: auto-update of in-memory `dataset` #35
 
 
 [0.3.0]  (2020-05-26)
diff --git a/docs/conf.py b/docs/conf.py
index a33e834..367a590 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -29,6 +29,7 @@ version = str(subprocess.check_output(["git", "describe", "--always"]).strip())
 # -- General configuration ---------------------------------------------------
 
 master_doc = 'index'
+autoclass_content = 'both'
 
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
diff --git a/ukis_pysat/raster.py b/ukis_pysat/raster.py
index 398e040..fa4d337 100644
--- a/ukis_pysat/raster.py
+++ b/ukis_pysat/raster.py
@@ -29,6 +29,12 @@ logger = logging.getLogger(__name__)
 
 class Image:
     def __init__(self, path=None, dataset=None, arr=None, dimorder="first"):
+        """
+        :param path: str, path to raster (default: None)
+        :param dataset: rasterio.io.DatasetReader (default: None)
+        :param arr: np.ndarray (default: None)
+        :param dimorder: order of channels or bands 'first' or 'last' (default: 'first)
+        """
         if path:
             if isinstance(path, str):
                 self.dataset = rasterio.open(path)
@@ -50,6 +56,7 @@ class Image:
 
     @property
     def arr(self):
+        """array property"""
         if self.dimorder == "first":
             return self.__arr
         elif self.dimorder == "last":
@@ -67,12 +74,13 @@ class Image:
         return windows.bounds(valid_data_window, windows.transform(valid_data_window, self.transform))
 
     def mask_image(self, bbox, crop=True, pad=False, **kwargs):
-        """
-        TODO https://github.com/mapbox/rasterio/issues/995
+        """Mask the area outside of the input shapes with no data.
+
         :param bbox: bounding box of type tuple or Shapely Polygon
         :param crop: bool, see rasterio.mask. Optional, (default: True)
         :param pad: pads image, should only be used when bbox.bounds extent img.bounds, optional (default: False)
         """
+        # TODO https://github.com/mapbox/rasterio/issues/995
         if pad:
             self.dataset = self._pad_to_bbox(bbox, **kwargs).open()
 
@@ -83,6 +91,9 @@ class Image:
         else:
             raise TypeError(f"bbox must be of type tuple or Shapely Polygon")
 
+        # update for further processing
+        self.dataset = self.__update_dataset().open()
+
     def _pad_to_bbox(self, bbox, mode="constant", constant_values=0):
         """Buffers array with biggest difference to bbox and adjusts affine transform matrix. Can be used to fill
         array with nodata values before masking in case bbox only partially overlaps dataset bounds.
@@ -90,7 +101,7 @@ class Image:
         :param bbox: bounding box of type tuple or Shapely Polygon
         :param mode: str, how to pad, see rasterio.pad. Optional (default: 'constant')
         :param constant_values: nodata value, padding should be filled with, optional (default: 0)
-        :return: open, buffered dataset in memory
+        :return: closed, buffered dataset in memory
         """
         if isinstance(bbox, polygon.Polygon):
             bbox = bbox.bounds
@@ -117,6 +128,13 @@ class Image:
 
         self.__arr = destination
 
+        return self.__update_dataset()
+
+    def __update_dataset(self):
+        """Update dataset without writing to file after it theoretically changed.
+
+        :return: closed dataset in memory
+        """
         mem_profile = self.dataset.meta
         mem_profile.update(
             {"height": self.__arr.shape[-2], "width": self.__arr.shape[-1], "transform": self.transform,}
@@ -171,6 +189,7 @@ class Image:
         self.__arr = destination
         self.transform = transform
         self.crs = dst_crs
+        self.dataset = self.__update_dataset().open()
 
     def dn2toa(self, platform, mtl_file=None, wavelengths=None):
         """This method converts digital numbers to top of atmosphere reflectance, like described here:

Image dataset update
When we do a transformation on the `Image` object, the underlying rasterio `dataset` should be updated accordingly. This does not happen at the moment and may be confusing and lead to problems when chaining several transformations. For example:

```python
img = Image(path="dummy.tif")
img.mask_img().warp()
```
This would create an incorrect output, because `mask_img()` updates `transform` and `arr`, but not the entire `dataset`. `Dataset` is however used by `warp()`. At the moment `warp()` would be applied on the original `dataset` and not on the transformed one from `mask_img()`.
diff --git a/tests/test_raster.py b/tests/test_raster.py
index 0fbe9e1..ca6b7fb 100644
--- a/tests/test_raster.py
+++ b/tests/test_raster.py
@@ -85,13 +85,17 @@ class DataTest(unittest.TestCase):
         img.mask_image(box(11.9027457562112939, 51.4664152338322580, 11.9477435281016131, 51.5009522690838750,))
         self.assertEqual(
             img.dataset.bounds,
-            BoundingBox(left=11.896863892, bottom=51.446545369, right=11.9578595, top=51.515176657,),
+            BoundingBox(
+                left=11.902702941366716, bottom=51.46639813686387, right=11.947798368783504, top=51.50098327545026,
+            ),
         )
 
         img.mask_image((11.9027457562112939, 51.4664152338322580, 11.9477435281016131, 51.5009522690838750,))
         self.assertEqual(
             img.dataset.bounds,
-            BoundingBox(left=11.896863892, bottom=51.446545369, right=11.9578595, top=51.515176657,),
+            BoundingBox(
+                left=11.902702941366716, bottom=51.46639813686387, right=11.947798368783504, top=51.50098327545026,
+            ),
         )
 
         img.mask_image(
@@ -100,7 +104,7 @@ class DataTest(unittest.TestCase):
         self.assertEqual(
             img.dataset.bounds,
             BoundingBox(
-                left=11.897762207287187, bottom=51.4614574027801, right=11.952739102863033, top=51.50592400953403,
+                left=11.891923157920472, bottom=51.46639813686387, right=11.947798368783504, top=51.50098327545026
             ),
         )
 

pip install -e .[complete]
parse_log_pytest
requirements.txt
pytest
3.7
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
affine==2.4.0
appdirs==1.4.4
attrs==24.2.0
certifi @ file:///croot/certifi_1671487769961/work/certifi
chardet==3.0.4
click==7.1.2
click-plugins==1.1.1
cligj==0.7.2
dask==2.14.0
decopatch==1.4.10
exceptiongroup==1.2.2
Fiona==1.8.22
geographiclib==2.0
geojson==3.2.0
geomet==1.1.0
geopy==2.4.1
html2text==2020.1.16
idna==2.10
importlib-metadata==6.7.0
iniconfig==2.0.0
landsatxplore==0.6
makefun==1.15.6
munch==4.0.0
numpy==1.18.5
packaging==24.0
pandas==1.0.5
Pillow==7.1.2
pluggy==1.2.0
pyfields==1.1.5
pylandsat==0.4
pyparsing==3.1.4
pyproj==2.6.1.post1
pytest==7.4.4
python-dateutil==2.8.2
pytz==2025.2
rasterio==1.1.8
requests==2.23.0
rio-mucho==1.0.0
rio-toa==0.3.0
sentinelsat==0.14
Shapely==1.7.1
six==1.17.0
snuggs==1.4.7
tomli==2.0.1
toolz==0.12.1
tqdm==4.67.1
typing_extensions==4.7.1
-e git+https://github.com/dlr-eoc/ukis-pysat.git@5e8ae0f5aa92c083b20147b8ac794fa3ae97f321#egg=ukis_pysat
urllib3==1.25.11
utm==0.5.0
valid8==5.1.2
zipp==3.15.0

name: ukis-pysat
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - affine==2.4.0
      - appdirs==1.4.4
      - attrs==24.2.0
      - chardet==3.0.4
      - click==7.1.2
      - click-plugins==1.1.1
      - cligj==0.7.2
      - dask==2.14.0
      - decopatch==1.4.10
      - exceptiongroup==1.2.2
      - fiona==1.8.22
      - geographiclib==2.0
      - geojson==3.2.0
      - geomet==1.1.0
      - geopy==2.4.1
      - html2text==2020.1.16
      - idna==2.10
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - landsatxplore==0.6
      - makefun==1.15.6
      - munch==4.0.0
      - numpy==1.18.5
      - packaging==24.0
      - pandas==1.0.5
      - pillow==7.1.2
      - pluggy==1.2.0
      - pyfields==1.1.5
      - pylandsat==0.4
      - pyparsing==3.1.4
      - pyproj==2.6.1.post1
      - pytest==7.4.4
      - python-dateutil==2.8.2
      - pytz==2025.2
      - rasterio==1.1.8
      - requests==2.23.0
      - rio-mucho==1.0.0
      - rio-toa==0.3.0
      - sentinelsat==0.14
      - shapely==1.7.1
      - six==1.17.0
      - snuggs==1.4.7
      - tomli==2.0.1
      - toolz==0.12.1
      - tqdm==4.67.1
      - typing-extensions==4.7.1
      - urllib3==1.25.11
      - utm==0.5.0
      - valid8==5.1.2
      - zipp==3.15.0
prefix: /opt/conda/envs/ukis-pysat

tests/test_raster.py::DataTest::test_mask_image
tests/test_raster.py::DataTest::test__lookup_bands tests/test_raster.py::DataTest::test_arr tests/test_raster.py::DataTest::test_dn2toa tests/test_raster.py::DataTest::test_get_dask_array tests/test_raster.py::DataTest::test_get_subset tests/test_raster.py::DataTest::test_get_tiles tests/test_raster.py::DataTest::test_get_valid_data_bbox tests/test_raster.py::DataTest::test_init tests/test_raster.py::DataTest::test_warp tests/test_raster.py::DataTest::test_write_to_file
docs/conf.py CHANGELOG.rst ukis_pysat/raster.py
docs/conf.py CHANGELOG.rst ukis_pysat/raster.py