Incomplete
For volumetric data sets lacking an explicit segmentation. Examples:
Rendered with VVDViewer, a high-performance system for direct volume rendering of fluorescence microscopy volumes.
The "volumes"
section of the JSON file associates volume files with names to be used in the "animation"
section.
The "source"
indicates where to find the volume files. It can be an absolute path, or a local path, but note that a local path must start with ./
. For example, the following specifies a volume file in the Davis-etal-2020/JRC_SS04438-20151118_31_F1
subdirectory (folder) of the directory containing the generated VVDViewer project (.vrp) file:
"volumes": {
"source": "./Davis-etal-2020",
"JRC_SS04438-20151118_31_F1": "JRC_SS04438-20151118_31_F1/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j"
}
Currently only H5J format volume files are supported.
By default, the first channel ("Channel_0") is used for all volumes. This default channel can be changed with the command-line argument --channel
(-ch
). The channel for an individual volume can be specified with an array, as in the following example, which specifies the fourth channel ("Channel_3"):
"volumes": {
"source": "./Davis-etal-2020",
"JRC_SS04438-20151118_31_F1-ch3": ["JRC_SS04438-20151118_31_F1/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j", 3]
}
Note that channels are "zero-based", so the first channel is 0.
If local copies of the volume files are not yet available, the companion fetchVvd
program can fetch them from a cloud data source, like https://s3.amazonaws.com/janelia-flylight-imagery
where the Janelia FlyLight Split-GAL4 driver collection and Janelia FlyLight Generation 1 MCFO collection are stored. The fetched volume files are stored in a directory neuVidVolumes
located as a sibling of the input JSON file.
To use fetchVvd
, download it from the releases page.
The input to fetchVvd
is a JSON file with a "volumes"
section of a particular format, as in the following example:
"volumes": {
"source": "https://s3.amazonaws.com/janelia-flylight-imagery",
"R10A06": {"line": "R10A06"},
"R10A12": {"line": "R10A12"},
"R10A12_ref": [{"line": "R10A12"}, 3]
}
The "source"
is the URL of the cloud data source. The other items specify a pattern to use when searching for the volume in the cloud data source. The most basic pattern has the line name. More advanced patterns can include the region or sex:
"volumes": {
"source": "https://s3.amazonaws.com/janelia-flylight-imagery",
"R10A06": {"line": "R10A06", "region": "vnc"},
"R10A12": {"line": "R10A12", "region": "(central|brain)", "sex": "male"}
}
The "(central|brain)"
pattern element matches either central
or brain
in the volume file name on the cloud data source.
By default fetchVvd
rewrites the input JSON file with a new "volumes"
section that refers to the local copies of the volume files. Use the --output
(-o
) command-line option to specify a different file for the output (leaving the input file unmodified).
To be used in the "animation"
section of the JSON file.
General command syntax (quotes are necessary):
[ "commandName", { "argumentKey1" : argumentValue1, ..., "argumentKeyN" : argumentValueN }]
Required arguments:
by
: a time, in seconds.
Note that only the advanceTime
and flash
commands advance the current time, to make subsequent comamnds start later.
Required arguments:
at
: a point, [x, y, z], -1 <= x, y, z <= 1, with -1 being one edge of the volume's bounding box and 1 being the other edge.
Optional arguments:
duration
(default: 1)
Required arguments:
startingAlpha
endingAlpha
volume
: don't forget the"volumes."
prefix.
Optional arguments:
duration
(default: 1)
Required arguments:
volume
: don't forget the"volumes."
prefix.
Optional arguments:
ramp
: The time, in seconds, to go from alpha 0 to 1 at the start, and also the time to go from alpha 1 to 0 at the end.duration
: The overall number of seconds for the ramp up, hold, and ramp down.advanceTime
: Equivalent to anadvanceTime
command added after the start of theflash
command.
Note that only the flash
and advanceTime
commands advance the current time, to make subsequent comamnds start later.
When optional arguments are unspecified, the are given the values of the previous flash
command, making it simpler to specifiy a series of similarly-timed flash
operations affecting different volumes.
Optional arguments:
endingRelativeAngle
(default: 360)axis
(default:"-y"
): Can be"x"
,"-x"
,"y"
,"-y"
,"z"
,"-z"
, or a vector like[1, 0, 1]
.duration
(default: 1)
Currently, there is no support for multiple orbitCamera
commands overlap in time.
Required arguments:
to
: Matches the "Zoom" slider at the right of VVDViewer's "Render View: 1" panel, with 100 being the default and 200 being more zoomed in.
Optional arguments:
duration
(default: 1)
A zoomCamera
command may overlap in time with an orbitCamera
command, making the camera move in a spiral.
The first example references volumes to be downloaded with fetchVvd
:
{
"volumes": {
"source": "https://s3.amazonaws.com/janelia-flylight-imagery",
"Ref": [{"line": "R10A06", "region": "vnc"}, 3],
"R10A06": {"line": "R10A06", "region": "vnc"},
"R10A12": {"line": "R10A12", "region": "vnc"},
"R10B01": {"line": "R10B01", "region": "vnc"},
"R10B02": {"line": "R10B02", "region": "vnc"}
},
"animation": [
["zoomCamera", {"to": 100, "duration": 0}],
["fade", {"volume": "volumes.Ref", "startingAlpha": 0, "endingAlpha": 1, "duration": 1}],
["advanceTime", {"by": 1}],
["advanceTime", {"by": 1}],
["fade", {"volume": "volumes.Ref", "startingAlpha": 1, "endingAlpha": 0, "duration": 1}],
["fade", {"volume": "volumes.R10A06", "startingAlpha": 0, "endingAlpha": 1, "duration": 1}],
["advanceTime", {"by": 1}],
["fade", {"volume": "volumes.R10A12", "startingAlpha": 0, "endingAlpha": 1, "duration": 1}],
["advanceTime", {"by": 1}],
["fade", {"volume": "volumes.R10B01", "startingAlpha": 0, "endingAlpha": 1, "duration": 1}],
["advanceTime", {"by": 1}],
["fade", {"volume": "volumes.R10B02", "startingAlpha": 0, "endingAlpha": 1, "duration": 1}],
["advanceTime", {"by": 1}],
["orbitCamera", {"axis": "z", "endingRelativeAngle": -90, "duration": 2}],
["advanceTime", {"by": 2}],
["zoomCamera", {"to": 200, "duration": 4}],
["orbitCamera", {"axis": "y", "duration": 4}],
["advanceTime", {"by": 4}],
["advanceTime", {"by": 1}]
]
}
The next two examples use the names of some volumes from the "Optic lobe TAPIN-Seq 2020" release of the
Janelia FlyLight Split-GAL4 driver collection. Citation: Fred P. Davis et al., "A genetic, genomic, and computational resource for exploring neural circuit function," eLife, 2020; https://doi.org/10.7554/eLife.50901. These volumes must be downloaded to a directory Davis-etal-2020
that is a sibling of the JSON file.
When building a basic JSON file from a directory (folder) of volumes, animateVvd
creates a sequence of flash
commands that show each volume in turn, with a little overlap. With the default values of duration
= 4, advanceTime
= 1, at most 4 volumes will be visible at once, as illustrated by this timing diagram for volumes A
through F
:
Time 0: A
1: A, B
2: A, B, C
3: A, B, C, D
4: B. C, D. E
5: C. D. E. F
...
The general formula relating the total duration of the video to volume count and the duration
and advanceTime
arguments is:
totalDuration = volumeCount * duration - (volumeCount - 1) * (duration - advanceTime)
For the default values duration
= 4 and advanceTime
= 1, the formula reduces to:
totalDuration = volumeCount + 3
Here is a summary of how the total duration relates to several argument values:
duration |
advanceTime |
totalDuration |
---|---|---|
3 | 1 | volumeCount + 2 |
4 | 1 | volumeCount + 3 |
2.5 | 0.5 | volumeCount / 2 + 2 |
3.5 | 0.5 | volumeCount / 2 + 3 |
4 | 2 | 2 * volumeCount + 2 |
These formulas are useful for making camera motion fit into the pattern of appearing volumes. In the following example, the camera rocks back and forth for one cycle, with three segments of lengths t, 2 * t and t. This motion fits best if the total duration is divisible by 4, hence the example uses a volume count of 13 (and hence a total duration of 13 + 3 = 16).
This example starts with a zoomCamera
of duration
= 0, which sets the initial zoom to be greater than the default. It then has a zoomCamera
whose duration
covers the total duration of the video, providing a gradual zooming in simultaneous with the other camera motion.
{
"volumes": {
"source": "./Davis-etal-2020",
"JRC_SS04438-20151118_31_F1": "JRC_SS04438-20151118_31_F1/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"JRC_SS23757-20160621_31_C5": "JRC_SS23757-20160621_31_C5/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"SS00116-20150123_43_G5": "SS00116-20150123_43_G5/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"SS00308-20130612_33_A5": "SS00308-20130612_33_A5/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"SS00355-20130604_33_E1": "SS00355-20130604_33_E1/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"SS00657-20130618_31_I5": "SS00657-20130618_31_I5/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"SS00657-20140425_32_A5": "SS00657-20140425_32_A5/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_ColorMIP_HR.h5j",
"SS02204-IVS-myr-FLAG_Syt-HA_3_0055-A01-20141112_31_C2": "SS02204-IVS-myr-FLAG_Syt-HA_3_0055-A01-20141112_31_C2/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"SS02268-IVS-myr-FLAG_Syt-HA_3_0055-A01-20141121_31_E2": "SS02268-IVS-myr-FLAG_Syt-HA_3_0055-A01-20141121_31_E2/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"SS02302-IVS-myr-FLAG_Syt-HA_3_0055-A01-20141104_31_E5": "SS02302-IVS-myr-FLAG_Syt-HA_3_0055-A01-20141104_31_E5/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"SS02437-20141201_32_F3": "SS02437-20141201_32_F3/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"SS02575-20150204_31_F1": "SS02575-20150204_31_F1/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"SS02594-20150211_31_C1": "SS02594-20150211_31_C1/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j"
},
"animation": [
["zoomCamera", {"to": 150, "duration": 0}],
["zoomCamera", {"to": 175, "duration": 16}],
["orbitCamera", {"endingRelativeAngle": 25, "duration": 4}],
["flash", {"volume": "volumes.JRC_SS04438-20151118_31_F1", "ramp": 0.5, "duration": 4, "advanceTime": 1}],
["flash", {"volume": "volumes.JRC_SS23757-20160621_31_C5"}],
["flash", {"volume": "volumes.SS00116-20150123_43_G5"}],
["flash", {"volume": "volumes.SS00308-20130612_33_A5"}],
["orbitCamera", {"endingRelativeAngle": -50, "duration": 8}],
["flash", {"volume": "volumes.SS00355-20130604_33_E1"}],
["flash", {"volume": "volumes.SS00657-20130618_31_I5"}],
["flash", {"volume": "volumes.SS00657-20140425_32_A5"}],
["flash", {"volume": "volumes.SS02204-IVS-myr-FLAG_Syt-HA_3_0055-A01-20141112_31_C2"}],
["flash", {"volume": "volumes.SS02268-IVS-myr-FLAG_Syt-HA_3_0055-A01-20141121_31_E2"}],
["flash", {"volume": "volumes.SS02302-IVS-myr-FLAG_Syt-HA_3_0055-A01-20141104_31_E5"}],
["flash", {"volume": "volumes.SS02437-20141201_32_F3"}],
["flash", {"volume": "volumes.SS02575-20150204_31_F1"}],
["orbitCamera", {"endingRelativeAngle": 25, "duration": 4}],
["flash", {"volume": "volumes.SS02594-20150211_31_C1"}]
]
}
The next example shows fewer volumes but has more camera motion. After a bit of orbiting around the center of the volumes, the camera pans over to be centered on the middle of the right half of the volumes. Then it zooms in and orbits back, with the orbit using the new camera center.
Note the use of the advanceTime
commands to control when each operation starts. Note also that the visibility of only two volumes is ever explicitly mentioned, in the fade
command that makes those two become invisible. All other volumes stay visible for the entire video by default.
{
"volumes": {
"source": "./Davis-etal-2020",
"SS00355-20130604_33_E1": "SS00355-20130604_33_E1/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"SS00657-20130618_31_I5": "SS00657-20130618_31_I5/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j",
"SS00657-20140425_32_A5": "SS00657-20140425_32_A5/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_ColorMIP_HR.h5j",
"SS02204-IVS-myr-FLAG_Syt-HA_3_0055-A01-20141112_31_C2": "SS02204-IVS-myr-FLAG_Syt-HA_3_0055-A01-20141112_31_C2/JRC2018_Unisex_20x_HR (CMTK)-REG_UNISEX_20x_HR.h5j"
},
"animation": [
["zoomCamera", {"to": 150, "duration": 0}],
["orbitCamera", {"endingRelativeAngle": 30, "duration": 2}],
["advanceTime", {"by": 2}],
["centerCamera", {"at": [0.5, 0.25, 0], "duration": 2}],
["advanceTime", {"by": 2}],
["zoomCamera", {"to": 300, "duration": 2}],
["fade", {"volume": "volumes.SS00355-20130604_33_E1", "duration": 2}],
["fade", {"volume": "volumes.SS00657-20130618_31_I5", "duration": 2}],
["advanceTime", {"by": 2}],
["orbitCamera", {"endingRelativeAngle": -30, "duration": 2}]
]
}
After loading the project (.vrp) file, avoid doing anything in the VVDViewer user interface other than switching to the "Record/Export" panel's "Advanced" tab and pressing the "Save..." button. Other operations might change the project in a way that would affect the video rendering.