You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/base/core/acquisition.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,6 +27,10 @@ For example, in the `"Brain Computer Interface"` project name, good acquisition
27
27
28
28
You should use the `Code.parameters` field to store your stimulus properties for each [StimulusEpoch](#stimulusepoch). We have pre-existing parameter schemas for a subset of stimuli defined [here](components/stimulus.md) or you can define your own schema.
29
29
30
+
## Manipulations
31
+
32
+
Procedures that occur during an acquisition (between the start_time and end_time) should be recorded in the `Acquisition.manipulations` using a [Manipulation](#manipulation).
Copy file name to clipboardExpand all lines: docs/source/acquisition.md
+19-1Lines changed: 19 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,6 +27,10 @@ For example, in the `"Brain Computer Interface"` project name, good acquisition
27
27
28
28
You should use the `Code.parameters` field to store your stimulus properties for each [StimulusEpoch](#stimulusepoch). We have pre-existing parameter schemas for a subset of stimuli defined [here](components/stimulus.md) or you can define your own schema.
29
29
30
+
## Manipulations
31
+
32
+
Procedures that occur during an acquisition (between the start_time and end_time) should be recorded in the `Acquisition.manipulations` using a [Manipulation](#manipulation).
33
+
30
34
## FAQs
31
35
32
36
### When should a DataStream be split in two
@@ -88,6 +92,7 @@ while the StimulusEpoch represents all stimuli being presented.
88
92
|`maintenance`| List[[Maintenance](components/measurements.md#maintenance)]| Maintenance (List of maintenance on instrument prior to acquisition.) |
89
93
|`data_streams`| List[[DataStream](acquisition.md#datastream)]| Data streams (A data stream is a collection of devices that are acquiring data simultaneously. Each acquisition can include multiple streams. Streams should be split when configurations are changed.) |
90
94
|`stimulus_epochs`| List[[StimulusEpoch](acquisition.md#stimulusepoch)]| Stimulus (A stimulus epoch captures all stimuli being presented during an acquisition. Epochs should be split when the purpose of the stimulus changes.) |
95
+
|`manipulations`| List[[Manipulation](acquisition.md#manipulation)]| Manipulations (Procedures performed during the acquisition.) |
|`anaesthesia`| Optional[[Anaesthetic](components/surgery_procedures.md#anaesthetic)]| Anaesthesia (Anaesthesia present during entire acquisition, use Manipulation for partial anaesthesia)|
106
111
|`mouse_platform_name`|`str`| Mouse platform |
107
112
|`reward_consumed_total`|`Optional[decimal.Decimal]`| Total reward consumed (mL) |
108
113
|`reward_consumed_unit`| Optional[[VolumeUnit](aind_data_schema_models/units.md#volumeunit)]| Reward consumed unit |
@@ -125,6 +130,19 @@ same time.
125
130
|`connections`| List[[Connection](components/connections.md#connection)]| Connections (Connections are links between devices that are specific to this acquisition (i.e. not already defined in the Instrument)) |
126
131
127
132
133
+
### Manipulation
134
+
135
+
Description of procedures performed during an acquisition.
136
+
137
+
| Field | Type | Title (Description) |
138
+
|-------|------|-------------|
139
+
|`start_time`|`datetime (timezone-aware)`| Manipulation start time (Must be between the acquisition start and end times) |
140
+
|`end_time`|`datetime (timezone-aware)`| Manipulation end time (Must be between the acquisition start and end times) |
141
+
|`procedures`| Optional[List[[Injection](components/injection_procedures.md#injection) or [BrainInjection](components/surgery_procedures.md#braininjection)]]| Procedures (Procedures performed during the manipulation) |
Copy file name to clipboardExpand all lines: docs/source/coordinate_systems.md
+52-32Lines changed: 52 additions & 32 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -44,6 +44,18 @@ An [Origin](aind_data_schema_models/coordinates.md#origin) is a point in space,
44
44
45
45
Each [Axis](components/coordinates.md#axis) is a combination of an [AxisName](aind_data_schema_models/coordinates.md#axisname) and [Direction](aind_data_schema_models/coordinates.md#direction).
46
46
47
+
### Units
48
+
49
+
Each [CoordinateSystem](components/coordinates.md#coordinatesystem) defines its origin, axis direction, and units. All of this information is inherited by the [Translation](components/coordinates.md#translation), [Rotation](components/coordinates.md#rotation), and [Scale](components/coordinates.md#scale) transforms that are applied. The only exception is for rotations, where we ask you to specify for each rotation the units (degrees or radians).
50
+
51
+
#### 3D vs 4D and Depth
52
+
53
+
Because skull shapes vary across animals the most useful coordinates to re-create insertions across animals are often the AP/ML position of the entry coordinate and then the "depth", i.e. the insertion distance of the tip of the inserted device from the brain (or dura) surface, whether a probe, fiber, needle, whatever. To support these kinds of insertions we include a depth axis option.
54
+
55
+
In most cases users should report the coordinates of the *entry coordinate* at the brain/dura surface using the first three (AP, ML, SI) values and then the depth *from the brain/dura surface* in the fourth depth coordinate. Recording all three coordinates disambiguates between the two ways that a probe can be "dropped" to the brain surface (either along the SI axis or down the probe depth axis). You can also use a 3-dimensional coordinate system (AP, ML, Depth) but we don't recommend it, since you need to either report in a protocol or in the notes how you dropped from the AP/ML plane down to the brain surface.
56
+
57
+
Note that in general, the process by which you perform an insertion should be recorded in a protocol, especially if there are specific details a user would need to know about how to interpret coordinates.
58
+
47
59
### CoordinateSystemLibrary
48
60
49
61
We know that allowing complete flexibility with coordinate systems will be a source of confusion. With that in mind, we encourage everybody to use the `CoordinateSystemLibrary` class, which comes with a pre-defined set of standard coordinate systems. For example, you can import the `BREGMA_ARI` coordinate system and then re-use it as follows:
You can always define your own coordinate system. If you find yourself re-using a coordinate system that isn't available in the library across multiple projects, please request an update to the library by opening an [issue](https://github.com/AllenNeuralDynamics/aind-data-schema/issues).
61
73
74
+
## Measured Coordinates
75
+
76
+
During a [Surgery](components/subject_procedures.md#surgery) requiring stereotaxic coordinates the surgeon will typically reference the stereotax or insertion device to a known coordinate, almost always Bregma. It's useful at this time to also measure the relative position of other known landmarks, like Lambda. The `Surgery.measured_coordinates` field is intended to store this data, for example for a surgery in the BREGMA_ARI coordinate system and where Lambda is measured 4.1 mm posterior to Bregma you would include:
Some notes: the position is *negative* because in BREGMA_ARI the AP axis points positive in the anterior direction, the other two axes are zero because this skull has apparently already been leveled, and finally no units are included in the translation itself because they are implied by the coordinate system, see [units](#units) above.
85
+
86
+
## Rotations
87
+
88
+
Rotations are applied using the [scipy Euler angle conventions](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.transform.Rotation.from_euler.html#scipy.spatial.transform.Rotation.from_euler), in "xyz" order. Positive angles rotate counter-clockwise.
89
+
90
+
It can be complicated to translate your rotations into the default conventions in situations where you aren't in control of the coordinate system definition. In that situation, it is preferable to construct an affine rotation matrix directly and pass it using the [Affine](components/coordinates.md#affine) object.
91
+
62
92
## Device transforms
63
93
64
94
To understand the position and orientation of a **device** in an instrument requires knowing three things: (1) the coordinate system for the instrument, (2) the coordinate system for the device, and (3) the coordinate system transform i.e. how a point in one coordinate system is translated, rotated, and scaled to the other. For example, a [CameraAssembly](components/devices.md#cameraassembly) is a positioned device: it has three special fields `relative_position`, `coordinate_system`, and `transform`. The relative position is required for all positioned devices while the transform and coordinate system are only required when a device's exact position will have an impact on the interpretation/analysis of data.
65
95
96
+
### Relative Position
97
+
98
+
For devices where the exact position is not important or is unknown, simply tell us where the device is *roughly* relative to the origin. By combining several [AnatomicalRelative](aind_data_schema_models/coordinates.md#anatomicalrelative) directions in a list, for example `[AnatomicalRelative.ANTERIOR, AnatomicalRelative.SUPERIOR]`, etc, you can describe the position.
99
+
100
+
### Exact Position
101
+
66
102
The transform we require for devices is the device to instrument transform. I.e. given the origin of the device (0, 0, 0) and the three axis directions, what will be the position of the origin and what direction will the three axes point in the instrument's coordinate system.
67
103
68
-
Here is an example of an affine rotation matrix and a translation applied to a [Monitor](components/devices.md#monitor) device being positioned in the standard `BREGMA_ARI` coordinate system, see above for the definition. Note that the affine matrix and translation could be composed together, we're keeping them separate here for interpretability.
The easiest way to construct the exact position is to start by drawing two pictures of your device. First, draw your device in the instrument coordinate system at the origin. Define a "neutral" position: for example, a monitor at neutral might be facing posterior as if the mouse is looking at it. Select an origin coordinate for the device, a logical point for a monitor is the center of the screen. Then, define this device coordinate system by adding axis direction information matching the picture you drew so that the X, Y, and Z axes are matched between your instrument coordinate system and the device. Assuming that our instrument coordinate system is BREGMA_ARI, i.e. +X = +Anterior, +Y = +Right, and +Z = +Inferior, then our monitor should be defined as:
107
+
108
+
```{code} python
109
+
CoordinateSystem(
110
+
name="MONITOR_BRU",
111
+
origin=Origin.FRONT_CENTER,
112
+
axis_unit=SizeUnit.MM,
113
+
axes=[
114
+
Axis(name=AxisName.X, direction=Direction.FB),
115
+
Axis(name=AxisName.Y, direction=Direction.LR),
116
+
Axis(name=AxisName.Z, direction=Direction.DU),
101
117
],
102
118
)
103
119
```
120
+
121
+
The device is now defined in the instrument coordinate system, but at a physically impossible location overlapping the mouse. Now draw a second picture, which is the actual location of your monitor relative to the mouse. In our case, lets assume that this monitor is facing the mouse's right eye, at a 45 degree angle to the axis of the mouse's body (i.e. the eye to monitor vector is perpendicular to the monitor surface.), and at a viewing distance of 100 mm.
122
+
123
+
Now we calculate the transforms needed to correctly position the device in the acquisition coordinate system. First we translate the monitor to the correct position by applying `Translation(translation=70.7, 70.7, 0)`. Then, we rotate *clockwise* around the Z axis by applying `Rotation(angles=[0, 0, -45], angles_unit=AngleUnit.DEG)`.
To ensure that your metadata is valid you need to construct the full [Metadata](metadata.md#metadata) object. *Validition* does not guarantee in any way that your metadata is *complete*. Many fields are marked as `Optional[]` because not all situations require them, but they may be expected for your use case. If you have a piece of metadata accessible, it should be reported!
4
+
5
+
## Instrument and Acquisition
6
+
7
+
If you are validating your `Instrument` and `Acquisition` on your rig, you may not have access to the other metadata files like the procedures. To allow for partial validation of these files we include an `InstrumentAcquisitionCompatibility` class. Construct it as follows:
8
+
9
+
```{python}
10
+
from aind_data_schema.utils.compatibility_check import InstrumentAcquisitionCompatibility
11
+
12
+
# Construct your Instrument and Acquisition objects
The `raise_for_missing_devices` will raise a `ValidationError` if `Acquisition.active_devices` can't be found in the instrument. Note that if your situation includes implanted devices in the procedures, then errors will be raised because the procedures are not available. In that case, you should construct the a full `Metadata` object for validation.
0 commit comments