<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def read(self, bounds=None, window=None, masked=False):
 """ Performs a boundless read against the underlying array source Parameters bounds: bounding box in w, s, e, n order, iterable, optional window: rasterio-style window, optional bounds OR window are required, specifying both or neither will raise exception masked: boolean return a masked numpy array, default: False bounds OR window are required, specifying both or neither will raise exception Returns ------- Raster object with update affine and array info """

        # Calculate the window
        if bounds and window:
            raise ValueError("Specify either bounds or window")

        if bounds:
            win = bounds_window(bounds, self.affine)
        elif window:
            win = window
        else:
            raise ValueError("Specify either bounds or window")

        c, _, _, f = window_bounds(win, self.affine)  # c ~ west, f ~ north
        a, b, _, d, e, _, _, _, _ = tuple(self.affine)
        new_affine = Affine(a, b, c, d, e, f)

        nodata = self.nodata
        if nodata is None:
            nodata = -999
            warnings.warn("Setting nodata to -999; specify nodata explicitly")

        if self.array is not None:
            # It's an ndarray already
            new_array = boundless_array(
                self.array, window=win, nodata=nodata, masked=masked)
        elif self.src:
            # It's an open rasterio dataset
            new_array = self.src.read(
                self.band, window=win, boundless=True, masked=masked)

        return Raster(new_array, new_affine, nodata)