|
1 | | -import copy |
2 | 1 | import logging |
3 | 2 | import math |
4 | 3 | import operator |
@@ -310,6 +309,29 @@ def add_mag( |
310 | 309 |
|
311 | 310 | return self._mags[mag] |
312 | 311 |
|
| 312 | + def add_mag_for_existing_files( |
| 313 | + self, |
| 314 | + mag: Union[int, str, list, tuple, np.ndarray, Mag], |
| 315 | + ) -> MagView: |
| 316 | + """ |
| 317 | + Creates a new mag based on already existing files. |
| 318 | +
|
| 319 | + Raises an IndexError if the specified `mag` does not exists. |
| 320 | + """ |
| 321 | + mag = Mag(mag) |
| 322 | + assert ( |
| 323 | + mag not in self.mags |
| 324 | + ), f"Cannot add mag {mag} as it already exists for layer {self}" |
| 325 | + self._setup_mag(mag) |
| 326 | + mag_view = self._mags[mag] |
| 327 | + cube_length = mag_view.header.file_len * mag_view.header.block_len |
| 328 | + self._properties.wkw_resolutions.append( |
| 329 | + MagViewProperties(resolution=mag, cube_length=cube_length) |
| 330 | + ) |
| 331 | + self.dataset._export_as_json() |
| 332 | + |
| 333 | + return mag_view |
| 334 | + |
313 | 335 | def get_or_add_mag( |
314 | 336 | self, |
315 | 337 | mag: Union[int, str, list, tuple, np.ndarray, Mag], |
@@ -372,71 +394,93 @@ def delete_mag(self, mag: Union[int, str, list, tuple, np.ndarray, Mag]) -> None |
372 | 394 | rmtree(full_path) |
373 | 395 |
|
374 | 396 | def _add_foreign_mag( |
375 | | - self, foreign_mag_path: Path, symlink: bool, make_relative: bool |
| 397 | + self, |
| 398 | + foreign_mag_view_or_path: Union[os.PathLike, str, MagView], |
| 399 | + symlink: bool, |
| 400 | + make_relative: bool, |
| 401 | + extend_layer_bounding_box: bool = True, |
376 | 402 | ) -> MagView: |
377 | | - mag_name = foreign_mag_path.name |
378 | | - mag = Mag(mag_name) |
379 | | - operation = "symlink" if symlink else "copy" |
380 | | - if mag in self.mags.keys(): |
381 | | - raise IndexError( |
382 | | - f"Cannot {operation} {foreign_mag_path}. This dataset already has a mag called {mag_name}." |
| 403 | + """ |
| 404 | + The foreign mag is (shallow) copied and the existing mag is added to the datasource-properties.json. |
| 405 | + If extend_layer_bounding_box is true, the self.bounding_box will be extended |
| 406 | + by the bounding box of the layer the foreign mag belongs to. |
| 407 | + """ |
| 408 | + |
| 409 | + if isinstance(foreign_mag_view_or_path, MagView): |
| 410 | + foreign_mag_view = foreign_mag_view_or_path |
| 411 | + else: |
| 412 | + # local import to prevent circular dependency |
| 413 | + from .dataset import Dataset |
| 414 | + |
| 415 | + foreign_mag_view_path = Path(foreign_mag_view_or_path) |
| 416 | + foreign_mag_view = ( |
| 417 | + Dataset(foreign_mag_view_path.parent.parent) |
| 418 | + .get_layer(foreign_mag_view_path.parent.name) |
| 419 | + .get_mag(foreign_mag_view_path.name) |
383 | 420 | ) |
384 | 421 |
|
| 422 | + self._assert_mag_does_not_exist_yet(foreign_mag_view.mag) |
| 423 | + |
385 | 424 | foreign_normalized_mag_path = ( |
386 | | - Path(os.path.relpath(foreign_mag_path, self.dataset.path)) |
| 425 | + Path(os.path.relpath(foreign_mag_view.path, self.path)) |
387 | 426 | if make_relative |
388 | | - else foreign_mag_path |
| 427 | + else Path(os.path.abspath(foreign_mag_view.path)) |
389 | 428 | ) |
390 | 429 |
|
391 | 430 | if symlink: |
392 | 431 | os.symlink( |
393 | 432 | foreign_normalized_mag_path, |
394 | | - join(self.dataset.path, self.name, mag_name), |
| 433 | + join(self.dataset.path, self.name, str(foreign_mag_view.mag)), |
395 | 434 | ) |
396 | 435 | else: |
397 | 436 | shutil.copytree( |
398 | 437 | foreign_normalized_mag_path, |
399 | | - join(self.dataset.path, self.name, mag_name), |
| 438 | + join(self.dataset.path, self.name, str(foreign_mag_view.mag)), |
400 | 439 | ) |
401 | 440 |
|
402 | | - # copy the properties of the layer into the properties of this dataset |
403 | | - from .dataset import Dataset # local import to prevent circular dependency |
404 | | - |
405 | | - original_layer = Dataset(foreign_mag_path.parent.parent).get_layer( |
406 | | - foreign_mag_path.parent.name |
407 | | - ) |
408 | | - original_mag = original_layer.get_mag(foreign_mag_path.name) |
409 | | - mag_properties = copy.deepcopy(original_mag._properties) |
410 | | - |
411 | | - self.bounding_box = self.bounding_box.extended_by(original_layer.bounding_box) |
412 | | - self._properties.wkw_resolutions += [mag_properties] |
413 | | - self._setup_mag(mag) |
| 441 | + self.add_mag_for_existing_files(foreign_mag_view.mag) |
| 442 | + if extend_layer_bounding_box: |
| 443 | + self.bounding_box = self.bounding_box.extended_by( |
| 444 | + foreign_mag_view.layer.bounding_box |
| 445 | + ) |
414 | 446 | self.dataset._export_as_json() |
415 | | - return self.mags[mag] |
| 447 | + |
| 448 | + return self._mags[foreign_mag_view.mag] |
416 | 449 |
|
417 | 450 | def add_symlink_mag( |
418 | | - self, foreign_mag_path: Union[str, Path], make_relative: bool = False |
| 451 | + self, |
| 452 | + foreign_mag_view_or_path: Union[os.PathLike, str, MagView], |
| 453 | + make_relative: bool = False, |
| 454 | + extend_layer_bounding_box: bool = True, |
419 | 455 | ) -> MagView: |
420 | 456 | """ |
421 | | - Creates a symlink to the data at `foreign_mag_path` which belongs to another dataset. |
| 457 | + Creates a symlink to the data at `foreign_mag_view_or_path` which belongs to another dataset. |
422 | 458 | The relevant information from the `datasource-properties.json` of the other dataset is copied to this dataset. |
423 | 459 | Note: If the other dataset modifies its bounding box afterwards, the change does not affect this properties |
424 | 460 | (or vice versa). |
425 | 461 | If make_relative is True, the symlink is made relative to the current dataset path. |
426 | 462 | """ |
427 | | - foreign_mag_path = Path(os.path.abspath(foreign_mag_path)) |
428 | 463 | return self._add_foreign_mag( |
429 | | - foreign_mag_path, symlink=True, make_relative=make_relative |
| 464 | + foreign_mag_view_or_path, |
| 465 | + symlink=True, |
| 466 | + make_relative=make_relative, |
| 467 | + extend_layer_bounding_box=extend_layer_bounding_box, |
430 | 468 | ) |
431 | 469 |
|
432 | | - def add_copy_mag(self, foreign_mag_path: Union[str, Path]) -> MagView: |
| 470 | + def add_copy_mag( |
| 471 | + self, |
| 472 | + foreign_mag_view_or_path: Union[os.PathLike, str, MagView], |
| 473 | + extend_layer_bounding_box: bool = True, |
| 474 | + ) -> MagView: |
433 | 475 | """ |
434 | | - Copies the data at `foreign_mag_path` which belongs to another dataset to the current dataset. |
| 476 | + Copies the data at `foreign_mag_view_or_path` which belongs to another dataset to the current dataset. |
435 | 477 | Additionally, the relevant information from the `datasource-properties.json` of the other dataset are copied too. |
436 | 478 | """ |
437 | | - foreign_mag_path = Path(os.path.abspath(foreign_mag_path)) |
438 | 479 | return self._add_foreign_mag( |
439 | | - foreign_mag_path, symlink=False, make_relative=False |
| 480 | + foreign_mag_view_or_path, |
| 481 | + symlink=False, |
| 482 | + make_relative=False, |
| 483 | + extend_layer_bounding_box=extend_layer_bounding_box, |
440 | 484 | ) |
441 | 485 |
|
442 | 486 | def _create_dir_for_mag( |
|
0 commit comments