@@ -31,6 +31,7 @@ import {
31
31
LayerSelection ,
32
32
BoundingBoxSelection ,
33
33
getReadableNameOfVolumeLayer ,
34
+ MagSlider ,
34
35
} from "oxalis/view/right-border-tabs/starting_job_modals" ;
35
36
import { getUserBoundingBoxesFromState } from "oxalis/model/accessors/tracing_accessor" ;
36
37
import {
@@ -73,8 +74,6 @@ type ExportLayerInfos = {
73
74
layerName : string | null ;
74
75
tracingId : string | null ;
75
76
annotationId : string | null ;
76
- lowestResolutionIndex : number ;
77
- highestResolutionIndex : number ;
78
77
} ;
79
78
80
79
enum ExportFormat {
@@ -84,26 +83,21 @@ enum ExportFormat {
84
83
85
84
const EXPECTED_DOWNSAMPLING_FILE_SIZE_FACTOR = 1.33 ;
86
85
87
- const exportKey = ( layerInfos : ExportLayerInfos , resolutionIndex : number ) =>
88
- `${ layerInfos . layerName || "" } __${ layerInfos . tracingId || "" } __${ resolutionIndex } ` ;
86
+ const exportKey = ( layerInfos : ExportLayerInfos , mag : Vector3 ) =>
87
+ `${ layerInfos . layerName || "" } __${ layerInfos . tracingId || "" } __${ mag . join ( "-" ) } ` ;
89
88
90
89
function getExportLayerInfos (
91
90
layer : APIDataLayer ,
92
91
tracing : HybridTracing | null | undefined ,
93
92
) : ExportLayerInfos {
94
93
const annotationId = tracing != null ? tracing . annotationId : null ;
95
94
96
- const highestResolutionIndex = getResolutionInfo ( layer . resolutions ) . getHighestResolutionIndex ( ) ;
97
- const lowestResolutionIndex = getResolutionInfo ( layer . resolutions ) . getClosestExistingIndex ( 0 ) ;
98
-
99
95
if ( layer . category === "color" || ! layer . tracingId ) {
100
96
return {
101
97
displayName : layer . name ,
102
98
layerName : layer . name ,
103
99
tracingId : null ,
104
100
annotationId : null ,
105
- lowestResolutionIndex,
106
- highestResolutionIndex,
107
101
} ;
108
102
}
109
103
@@ -119,8 +113,6 @@ function getExportLayerInfos(
119
113
return {
120
114
displayName : readableVolumeLayerName ,
121
115
layerName : layer . fallbackLayerInfo ?. name ?? null ,
122
- lowestResolutionIndex,
123
- highestResolutionIndex,
124
116
tracingId : volumeTracing . tracingId ,
125
117
annotationId,
126
118
} ;
@@ -169,7 +161,7 @@ function useRunningJobs(): [
169
161
(
170
162
dataset : APIDataset ,
171
163
boundingBox : BoundingBoxType ,
172
- resolutionIndex : number ,
164
+ mag : Vector3 ,
173
165
selectedLayerInfos : ExportLayerInfos ,
174
166
exportFormat : ExportFormat ,
175
167
) => Promise < void > ,
@@ -203,35 +195,29 @@ function useRunningJobs(): [
203
195
204
196
return [
205
197
runningJobs ,
206
- async ( dataset , boundingBox , resolutionIndex , selectedLayerInfos , exportFormat ) => {
198
+ async ( dataset , boundingBox , mag , selectedLayerInfos , exportFormat ) => {
207
199
const datasetResolutionInfo = getDatasetResolutionInfo ( dataset ) ;
208
200
const job = await startExportTiffJob (
209
201
dataset . name ,
210
202
dataset . owningOrganization ,
211
203
computeArrayFromBoundingBox ( boundingBox ) ,
212
204
selectedLayerInfos . layerName ,
213
- datasetResolutionInfo . getResolutionByIndexOrThrow ( resolutionIndex ) . join ( "-" ) ,
205
+ mag . join ( "-" ) ,
214
206
selectedLayerInfos . annotationId ,
215
207
selectedLayerInfos . displayName ,
216
208
exportFormat === ExportFormat . OME_TIFF ,
217
209
) ;
218
- setRunningJobs ( ( previous ) => [
219
- ...previous ,
220
- [ exportKey ( selectedLayerInfos , resolutionIndex ) , job . id ] ,
221
- ] ) ;
210
+ setRunningJobs ( ( previous ) => [ ...previous , [ exportKey ( selectedLayerInfos , mag ) , job . id ] ] ) ;
222
211
} ,
223
212
] ;
224
213
}
225
214
226
215
function estimateFileSize (
227
216
selectedLayer : APIDataLayer ,
228
- resolutionIndex : number ,
217
+ mag : Vector3 ,
229
218
boundingBox : BoundingBoxType ,
230
219
exportFormat : ExportFormat ,
231
220
) {
232
- const mag = getResolutionInfo ( selectedLayer . resolutions ) . getResolutionByIndexOrThrow (
233
- resolutionIndex ,
234
- ) ;
235
221
const shape = computeShapeFromBoundingBox ( boundingBox ) ;
236
222
const volume =
237
223
Math . ceil ( shape [ 0 ] / mag [ 0 ] ) * Math . ceil ( shape [ 1 ] / mag [ 1 ] ) * Math . ceil ( shape [ 2 ] / mag [ 2 ] ) ;
@@ -242,9 +228,8 @@ function estimateFileSize(
242
228
) ;
243
229
}
244
230
245
- function formatSelectedScale ( dataset : APIDataset , resolutionIndex : number ) {
231
+ function formatSelectedScale ( dataset : APIDataset , mag : Vector3 ) {
246
232
const scale = dataset . dataSource . scale ;
247
- const mag = getDatasetResolutionInfo ( dataset ) . getResolutionByIndexOrThrow ( resolutionIndex ) ;
248
233
formatScale ( [ scale [ 0 ] * mag [ 0 ] , scale [ 1 ] * mag [ 1 ] , scale [ 2 ] * mag [ 2 ] ] ) ;
249
234
}
250
235
@@ -343,33 +328,34 @@ function _DownloadModalView({
343
328
344
329
const selectedLayer = getLayerByName ( dataset , selectedLayerName ) ;
345
330
const selectedLayerInfos = getExportLayerInfos ( selectedLayer , tracing ) ;
331
+ const selectedLayerResolutionInfo = getResolutionInfo ( selectedLayer . resolutions ) ;
346
332
347
333
const userBoundingBoxes = [
348
334
...rawUserBoundingBoxes ,
349
335
{
350
336
id : - 1 ,
351
- name : "Full dataset " ,
337
+ name : "Full layer " ,
352
338
boundingBox : computeBoundingBoxFromBoundingBoxObject ( selectedLayer . boundingBox ) ,
353
339
color : [ 255 , 255 , 255 ] ,
354
340
isVisible : true ,
355
341
} as UserBoundingBox ,
356
342
] ;
343
+
357
344
const [ selectedBoundingBoxId , setSelectedBoundingBoxId ] = useState (
358
345
initialBoundingBoxId ?? userBoundingBoxes [ 0 ] . id ,
359
346
) ;
360
-
361
- const datasetResolutionInfo = getDatasetResolutionInfo ( dataset ) ;
362
- const { lowestResolutionIndex, highestResolutionIndex } = selectedLayerInfos ;
363
- const [ rawResolutionIndex , setResolutionIndex ] = useState < number > ( lowestResolutionIndex ) ;
364
- const resolutionIndex = clamp ( lowestResolutionIndex , rawResolutionIndex , highestResolutionIndex ) ;
347
+ const [ rawMag , setMag ] = useState < Vector3 > ( selectedLayerResolutionInfo . getLowestResolution ( ) ) ;
348
+ const mag = selectedLayerResolutionInfo . hasResolution ( rawMag )
349
+ ? rawMag
350
+ : selectedLayerResolutionInfo . getClosestExistingResolution ( rawMag ) ;
365
351
const [ exportFormat , setExportFormat ] = useState < ExportFormat > ( ExportFormat . OME_TIFF ) ;
366
352
367
353
const selectedBoundingBox = userBoundingBoxes . find (
368
354
( bbox ) => bbox . id === selectedBoundingBoxId ,
369
355
) as UserBoundingBox ;
370
356
const { isExportable, alerts : boundingBoxCompatibilityAlerts } = isBoundingBoxExportable (
371
357
selectedBoundingBox . boundingBox ,
372
- datasetResolutionInfo . getResolutionByIndexOrThrow ( resolutionIndex ) ,
358
+ mag ,
373
359
) ;
374
360
375
361
const [ runningExportJobs , triggerExportJob ] = useRunningJobs ( ) ;
@@ -390,7 +376,7 @@ function _DownloadModalView({
390
376
await triggerExportJob (
391
377
dataset ,
392
378
selectedBoundingBox . boundingBox ,
393
- resolutionIndex ,
379
+ mag ,
394
380
selectedLayerInfos ,
395
381
exportFormat ,
396
382
) ;
@@ -515,6 +501,9 @@ with wk.webknossos_context(
515
501
const hasSkeleton = tracing . skeleton != null ;
516
502
517
503
const okText = okTextForTab . get ( activeTabKey ) ;
504
+ const isCurrentlyRunningExportJob =
505
+ activeTabKey === "export" &&
506
+ runningExportJobs . some ( ( [ key ] ) => key === exportKey ( selectedLayerInfos , mag ) ) ;
518
507
519
508
return (
520
509
< Modal
@@ -526,24 +515,10 @@ with wk.webknossos_context(
526
515
< Button
527
516
key = "ok"
528
517
type = "primary"
529
- disabled = {
530
- activeTabKey === "export" &&
531
- ( ! isExportable ||
532
- runningExportJobs . some (
533
- ( [ key ] ) => key === exportKey ( selectedLayerInfos , resolutionIndex ) ,
534
- ) || // The export is already running or...
535
- isMergerModeEnabled ) // Merger mode is enabled
536
- }
518
+ disabled = { ! isExportable || isCurrentlyRunningExportJob || isMergerModeEnabled }
537
519
onClick = { handleOk }
520
+ loading = { isCurrentlyRunningExportJob }
538
521
>
539
- { activeTabKey === "export" &&
540
- runningExportJobs . some (
541
- ( [ key ] ) => key === exportKey ( selectedLayerInfos , resolutionIndex ) ,
542
- ) && (
543
- < >
544
- < SyncOutlined spin /> { " " }
545
- </ >
546
- ) }
547
522
{ okText }
548
523
</ Button >
549
524
) : null
@@ -684,7 +659,11 @@ with wk.webknossos_context(
684
659
< BoundingBoxSelection
685
660
value = { selectedBoundingBoxId }
686
661
userBoundingBoxes = { userBoundingBoxes }
687
- setSelectedBoundingBoxId = { setSelectedBoundingBoxId }
662
+ setSelectedBoundingBoxId = { ( boxId : number | null ) => {
663
+ if ( boxId != null ) {
664
+ setSelectedBoundingBoxId ( boxId ) ;
665
+ }
666
+ } }
688
667
style = { { width : "100%" } }
689
668
/>
690
669
{ boundingBoxCompatibilityAlerts }
@@ -698,25 +677,17 @@ with wk.webknossos_context(
698
677
</ Divider >
699
678
< Row >
700
679
< Col span = { 19 } >
701
- < Slider
702
- tooltip = { {
703
- formatter : ( ) =>
704
- datasetResolutionInfo
705
- . getResolutionByIndexOrThrow ( resolutionIndex )
706
- . join ( "-" ) ,
707
- } }
708
- min = { lowestResolutionIndex }
709
- max = { highestResolutionIndex }
710
- step = { 1 }
711
- value = { resolutionIndex }
712
- onChange = { ( value ) => setResolutionIndex ( value ) }
680
+ < MagSlider
681
+ resolutionInfo = { selectedLayerResolutionInfo }
682
+ value = { mag }
683
+ onChange = { setMag }
713
684
/>
714
685
</ Col >
715
686
< Col
716
687
span = { 5 }
717
688
style = { { display : "flex" , justifyContent : "flex-end" , alignItems : "center" } }
718
689
>
719
- { datasetResolutionInfo . getResolutionByIndexOrThrow ( resolutionIndex ) . join ( "-" ) }
690
+ { mag . join ( "-" ) }
720
691
</ Col >
721
692
</ Row >
722
693
< Text
@@ -728,12 +699,12 @@ with wk.webknossos_context(
728
699
Estimated file size:{ " " }
729
700
{ estimateFileSize (
730
701
selectedLayer ,
731
- resolutionIndex ,
702
+ mag ,
732
703
selectedBoundingBox . boundingBox ,
733
704
exportFormat ,
734
705
) }
735
706
< br />
736
- Resolution: { formatSelectedScale ( dataset , resolutionIndex ) }
707
+ Resolution: { formatSelectedScale ( dataset , mag ) }
737
708
</ Text >
738
709
739
710
{ downloadHint }
0 commit comments