diff --git a/docs/concepts/ale/ale-driver-architecture.md b/docs/concepts/ale/ale-driver-architecture.md new file mode 100644 index 0000000000000000000000000000000000000000..cb1fcd797e32178ace23b78fe52eb5d99acf2138 --- /dev/null +++ b/docs/concepts/ale/ale-driver-architecture.md @@ -0,0 +1,150 @@ +# ALE Driver Architecture + +## Drivers + +There are many similarities between image-gathering spacecraft. +For example, their output will generally include an image and a timestamp. +Though not always attached, orientation data can often be found given that timestamp. +Data should be able to be processed into a standard format. + +But, each spacecraft also has it's particularities. +One may gather image data in more bands than another. The distortion of their lenses may differ. +They may gather the same type of data, but store it in slightly different formats. +To get data into a standard format, the unique properties of each spacecraft must be accounted for. + +This is what ALE drivers are for. If ALE has a driver for a spacecraft, +it can return an ISD (Image Support Data) for images from that spacecraft. +(ALE may also need supplementary data along with the image, like labels or NAIF SPICE Kernels) + +An ALE driver is a Python Class. It uses Mixins to inherit shared functionality, +and Methods to define per-spacecraft functionality. + + +## Mixins + +Mixins allow code from different classes to be reused and mixed together in one class (or ALE driver, in our case). +Mixins can be thought of like multiple inheritance, though one mixin is not usually the single parent/super of another class. +They can also be thought of similar to an *include* at the top of the class. + +A class that uses a mixin is not typically a specialized version of that mixin. +Rather, the mixin is one component among many in the class that is using it. + +??? example "Python Mixins Example" + + `class_c` may use methods from `mixin_A` and `mixin_B`, as well as its own methods. Methods which overwrite others print `!` here. + ```python + class mixin_A(): + def method_1(self): + print("mixin_A - method_1") + + def method_3(self): + print("mixin_A - method_3 !") + # super().method_3() # would print " mixin_B - method_3" if called from class_C + + class mixin_B(): + def method_2(self): + print("mixin_B - method_2") + + def method_3(self): + print("mixin_B - method_3") + + def method_5(self): + print("mixin_B - method_5") + + class class_C(mixin_A, mixin_B): + def method_4(self): + print("class_C - method_4") + + def method_5(self): + print("class_C - method_5 !") + # super().method_5() # would print " mixin_B - method_5" + + driver = class_C() + driver.method_1() + driver.method_2() + driver.method_3() + driver.method_4() + driver.method_5() + ``` + + This example will print: + ``` + mixin_A - method1 + mixin_B - method2 + mixin_A - method3 ! + class_C - method4 + class_C - method5 ! + ``` + + ## Method Resolution Order + In the case of two methods with the same name, + the method from the first leftmost mixin will be used before methods from later mixins, + and the methods in the class overwrite methods from mixins. + `super()` can be used to access methods from parent classes or further-right mixins. + +Mixins let ALE drivers mix and match common spacecraft/image data features. + +*For example*: There are mixins that correspond to different camera types. +Whatever the other mixins and methods in a driver, +any methods that correspond to a certain type of camera +can be included simply by adding a mixin like `Framer`. + +Generally, every ALE driver has five mixins in this order: +Camera Type, Label Type, Aux Data Type, Distortion Type, and last a base driver class. +More info can be found on ALE Driver mixins in +[Creating ALE Drivers - Class Signature](../../how-to-guides/ale-developer-guides/creating-ale-drivers.md/#class-signature). + + +## ale.driver.load() + +The `load()` function in ALE is for creating an ISD from a label. + +- `load()` returns a dictionary. +- `loads()` is a wrapper for `load()` that returns a string. +- `isd_generate.py` is a command-line script that uses `load()` and writes a .json file. + +`load()` runs through every class containing `_driver` in the name, +until one works and successfully creates an ISD (or until all fail). +It initially checks for an `instrument_id` and fails the driver if that does not succeed. + +Because of the sequential trial-and-error loading method, in some cases +a different driver may succeed before the desired driver is reached. + + +## Overwriting Base Behavior + +The base ALE Driver/mixin behavior will sometimes need to be overwritten in favor of a more specific behavior for your driver. + +!!! note "Use ISIS for Reference!" + + ISIS is your guide for creating drivers in ALE. + + Labels from cubes generated with an ALE driver should match closely with labels from an ISIS cube. + A mismatch between the ALE and ISIS labels (aside from cases of insignificant digits) + is an indication the ALE driver needs to be changed. The mismatched field may give an + indication of what method needs implementation or changing. + + A look at related camera classes in ISIS may help show how to implement the ALE Driver. + + +Methods in the driver itself will take precedence over methods in the mixin classes. +Every driver will need some of its own methods, some drivers more than others. +See [Creating ALE Drivers - Creating Methods to Customize the Driver](../../how-to-guides/ale-developer-guides/creating-ale-drivers.md/#creating-methods-to-customize-the-driver). +Any time a spacecraft records data in a different way than others, it will need a method in its driver. + +### Mixin Order + +Occasionally, though the target behavior for a driver is already implemented in ALE, +the Method Resolution Order may mean it gets overwritten. +Methods from mixins on the left overwrite (and are children of) +methods with the same name from mixins on the right. + +Changing the order of of the mixins in the class signature +can bring to the surface a different version of a method needed +by the driver. **But be careful!** Changing the mixin order can +also obscure other methods the driver needs. + +### Editing Mixin Classes + +Adding or changing a method in a mixin class will propagate that method to any drivers that use the mixin. +Take caution when editing a mixin class, as changes can affect many drivers. \ No newline at end of file diff --git a/docs/how-to-guides/ale-developer-guides/creating-ale-drivers.md b/docs/how-to-guides/ale-developer-guides/creating-ale-drivers.md index 9ae8911fe76247d46c91071810a95c97eb1c2e02..79186da695088d4a504fde2f0dc18b12eac66046 100644 --- a/docs/how-to-guides/ale-developer-guides/creating-ale-drivers.md +++ b/docs/how-to-guides/ale-developer-guides/creating-ale-drivers.md @@ -119,9 +119,10 @@ ALE drivers largely follow the same structure, but individual methods differ amo ## Preparing Test Data 1. Create a data directory within `ale/tests/pytests/data/` based on your .cub name -1. Slice the Kernels with ALE's kernel slicing notebook (ale/notebooks/KernelSlice.py) +1. Slice the Kernels with ALE's kernel slicing notebook (`ale/notebooks/KernelSlice.py`) - This will require some customization based on your instrument, specifically to PVL structure - Requires the separate installation of [ckslicer](https://naif.jpl.nasa.gov/naif/utilities.html) (select your operating system -> CKSlicer). + - If using the `KernelSlice` notebook is unsuccessful, you may have to manually slice the kernels with NAIF utilities (ckslicer, toxfr, spkmerge) and the appropriate arguments. 1. Copy transfer kernels into the test data directory that you created above - See [Test Data](#test-data) for what data you will need to copy. 1. Generate an isd using ALE's `isd_generate` utility and copy it into `ale/tests/pytests/data/isds/` diff --git a/mkdocs.yml b/mkdocs.yml index c39f2b5cc599b526bac13209f9afc7ca06e7f85e..60485bb2b3025e9d1fb2c07b7a091013cc54eb3e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -76,6 +76,8 @@ nav: - Concepts: - Home: concepts/index.md - Glossary: concepts/glossary.md + - ALE: + - Ale Driver Architecture: concepts/ale/ale-driver-architecture.md - Camera Geometry and Projections: - Camera Geometry: concepts/camera-geometry-and-projections/camera-geometry.md - Learning About Map Projections: concepts/camera-geometry-and-projections/learning-about-map-projections.md