-
Notifications
You must be signed in to change notification settings - Fork 29
In Data Loading, Clip to Layer BoundingBox #8551
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
7081ed1
b3aac2c
fbbefca
4431584
b021251
5cb88f9
4a58957
ab97fb2
cac3521
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -106,16 +106,51 @@ class BinaryDataService(val dataBaseDir: Path, | |
conversionFunc(inputArray)) | ||
else Full(inputArray) | ||
|
||
/* | ||
* Everything outside of the layer bounding box is set to black (zero) so data outside of the specified | ||
* bounding box is not exposed to the user | ||
*/ | ||
private def clipToLayerBoundingBox(request: DataServiceDataRequest)(inputArray: Array[Byte]): Box[Array[Byte]] = { | ||
val bytesPerElement = request.dataLayer.bytesPerElement | ||
val requestBboxInMag = request.cuboid.toBoundingBoxInMag | ||
val layerBboxInMag = request.dataLayer.boundingBox / request.mag // Note that this div is implemented to round to the bigger bbox so we don’t lose voxels inside. | ||
val intersectionOpt = requestBboxInMag.intersection(layerBboxInMag).map(_.move(-requestBboxInMag.topLeft)) | ||
val outputArray = Array.fill[Byte](inputArray.length)(0) | ||
intersectionOpt.foreach { intersection => | ||
for { | ||
z <- intersection.topLeft.z until intersection.bottomRight.z | ||
y <- intersection.topLeft.y until intersection.bottomRight.y | ||
// We can bulk copy a row of voxels and do not need to iterate in the x dimension | ||
} { | ||
val offset = | ||
(intersection.topLeft.x + | ||
y * requestBboxInMag.width + | ||
z * requestBboxInMag.width * requestBboxInMag.height) * bytesPerElement | ||
System.arraycopy(inputArray, | ||
offset, | ||
outputArray, | ||
offset, | ||
(intersection.bottomRight.x - intersection.topLeft.x) * bytesPerElement) | ||
Comment on lines
+131
to
+135
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO this is the most likely cause for the nullpointer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. some out of bounds maybe. Maybe even due to my comment above regarding them dimensions not being converted to the respective mag There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the record, the |
||
} | ||
} | ||
Full(outputArray) | ||
} | ||
|
||
private def convertAccordingToRequest(request: DataServiceDataRequest, inputArray: Array[Byte]): Fox[Array[Byte]] = | ||
for { | ||
clippedData <- convertIfNecessary( | ||
!request.cuboid.toMag1BoundingBox.isFullyContainedIn(request.dataLayer.boundingBox), | ||
inputArray, | ||
clipToLayerBoundingBox(request), | ||
request) | ||
mappedDataFox <- agglomerateServiceOpt.map { agglomerateService => | ||
convertIfNecessary( | ||
request.settings.appliedAgglomerate.isDefined && request.dataLayer.category == Category.segmentation && request.cuboid.mag.maxDim <= MaxMagForAgglomerateMapping, | ||
inputArray, | ||
clippedData, | ||
agglomerateService.applyAgglomerate(request), | ||
request | ||
) | ||
}.fillEmpty(Fox.successful(inputArray)) ?~> "Failed to apply agglomerate mapping" | ||
}.fillEmpty(Fox.successful(clippedData)) ?~> "Failed to apply agglomerate mapping" | ||
mappedData <- mappedDataFox | ||
resultData <- convertIfNecessary(request.settings.halfByte, mappedData, convertToHalfByte, request) | ||
} yield resultData | ||
|
@@ -164,7 +199,6 @@ class BinaryDataService(val dataBaseDir: Path, | |
private def cutOutCuboid(request: DataServiceDataRequest, rs: List[(BucketPosition, Array[Byte])]): Array[Byte] = { | ||
val bytesPerElement = request.dataLayer.bytesPerElement | ||
val cuboid = request.cuboid | ||
val subsamplingStrides = Vec3Int.ones | ||
|
||
val resultShape = Vec3Int(cuboid.width, cuboid.height, cuboid.depth) | ||
val result = new Array[Byte](cuboid.volume * bytesPerElement) | ||
|
@@ -190,9 +224,9 @@ class BinaryDataService(val dataBaseDir: Path, | |
y % bucketLength * bucketLength + | ||
z % bucketLength * bucketLength * bucketLength) * bytesPerElement | ||
|
||
val rx = (xMin - cuboid.topLeft.voxelXInMag) / subsamplingStrides.x | ||
val ry = (y - cuboid.topLeft.voxelYInMag) / subsamplingStrides.y | ||
val rz = (z - cuboid.topLeft.voxelZInMag) / subsamplingStrides.z | ||
val rx = xMin - cuboid.topLeft.voxelXInMag | ||
val ry = y - cuboid.topLeft.voxelYInMag | ||
val rz = z - cuboid.topLeft.voxelZInMag | ||
|
||
val resultOffset = (rx + ry * resultShape.x + rz * resultShape.x * resultShape.y) * bytesPerElement | ||
System.arraycopy(data, dataOffset, result, resultOffset, (xMax - xMin) * bytesPerElement) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't
width, height, depth
also be in mag?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they already are, they are just not named as explicitly