cartodata 6.0.0
volumeutilio_d.h
Go to the documentation of this file.
1/* This software and supporting documentation are distributed by
2* Institut Federatif de Recherche 49
3* CEA/NeuroSpin, Batiment 145,
4* 91191 Gif-sur-Yvette cedex
5* France
6*
7* This software is governed by the CeCILL-B license under
8* French law and abiding by the rules of distribution of free software.
9* You can use, modify and/or redistribute the software under the
10* terms of the CeCILL-B license as circulated by CEA, CNRS
11* and INRIA at the following URL "http://www.cecill.info".
12*
13* As a counterpart to the access to the source code and rights to copy,
14* modify and redistribute granted by the license, users are provided only
15* with a limited warranty and the software's author, the holder of the
16* economic rights, and the successive licensors have only limited
17* liability.
18*
19* In this respect, the user's attention is drawn to the risks associated
20* with loading, using, modifying and/or developing or reproducing the
21* software by the user in light of its specific status of free software,
22* that may mean that it is complicated to manipulate, and that also
23* therefore means that it is reserved for developers and experienced
24* professionals having in-depth computer knowledge. Users are therefore
25* encouraged to load and test the software's suitability as regards their
26* requirements in conditions enabling the security of their systems and/or
27* data to be ensured and, more generally, to use and operate it in the
28* same conditions as regards security.
29*
30* The fact that you are presently reading this means that you have had
31* knowledge of the CeCILL-B license and that you accept its terms.
32*/
33#ifndef CARTODATA_IO_VOLUMEUTILIO_D_H
34#define CARTODATA_IO_VOLUMEUTILIO_D_H
35
36//--- cartodata --------------------------------------------------------------
37#include <cartodata/io/volumeutilio.h> // class definition
39//--- soma-io ----------------------------------------------------------------
40#include <soma-io/config/soma_config.h> // (#define soma)
41#include <soma-io/io/reader.h>
42#include <soma-io/datasourceinfo/datasourceinfoloader.h>
44//--- cartobase --------------------------------------------------------------
45#include <cartobase/object/object.h> // header, options
46#include <cartobase/object/property.h> // header, options
47//--- system -----------------------------------------------------------------
48#include <vector> // 4D vectors
49#include <set> // properties list
50//--- debug ------------------------------------------------------------------
51#include <cartobase/config/verbose.h>
52#define localMsg( message ) cartoCondMsg( 3, message, "VOLUMEUTILIO" )
53// #undef localMsg
54// #define localMsg( message ) std::cerr << (message) << std::endl;
55// localMsg must be undef at end of file
56//----------------------------------------------------------------------------
57
58namespace soma {
59
60 template <typename T> std::set<std::string>
62 {
63 std::set<std::string> properties;
64 properties.insert( "ox" );
65 properties.insert( "oy" );
66 properties.insert( "oz" );
67 properties.insert( "ot" );
68 properties.insert( "sx" );
69 properties.insert( "sy" );
70 properties.insert( "sz" );
71 properties.insert( "st" );
72 properties.insert( "bx" );
73 properties.insert( "by" );
74 properties.insert( "bz" );
75 properties.insert( "border" );
76 properties.insert( "ox1" );
77 properties.insert( "ox2" );
78 properties.insert( "ox3" );
79 properties.insert( "ox4" );
80 properties.insert( "ox5" );
81 properties.insert( "ox6" );
82 properties.insert( "ox7" );
83 properties.insert( "ox8" );
84 properties.insert( "sx1" );
85 properties.insert( "sx2" );
86 properties.insert( "sx3" );
87 properties.insert( "sx4" );
88 properties.insert( "sx5" );
89 properties.insert( "sx6" );
90 properties.insert( "sx7" );
91 properties.insert( "sx8" );
92
93 return properties;
94 }
95
96 //==========================================================================
97 // R E A D
98 //==========================================================================
99
100 template <typename T> carto::Volume<T>*
103 carto::Object options )
104 {
105 localMsg( "VolumeUtilIO<T>::read" );
106 if( obj )
107 localMsg( "with existing object" );
108 std::vector<int> position( 4, 0 );
109 std::vector<int> frame( 4, -1 );
110 std::vector<int> borders( 4, 0 );
111 try {
112 position[0] = (int) rint(options->getProperty( "ox" )->getScalar() );
113 options->removeProperty( "ox" );
114 } catch( ... ) {}
115 try {
116 position[1] = (int) rint( options->getProperty( "oy" )->getScalar() );
117 options->removeProperty( "oy" );
118 } catch( ... ) {}
119 try {
120 position[2] = (int) rint( options->getProperty( "oz" )->getScalar() );
121 options->removeProperty( "oz" );
122 } catch( ... ) {}
123 try {
124 position[3] = (int) rint( options->getProperty( "ot" )->getScalar() );
125 options->removeProperty( "ot" );
126 } catch( ... ) {}
127 try {
128 frame[0] = (int) rint( options->getProperty( "sx" )->getScalar() );
129 options->removeProperty( "sx" );
130 } catch( ... ) {}
131 try {
132 frame[1] = (int) rint( options->getProperty( "sy" )->getScalar() );
133 options->removeProperty( "sy" );
134 } catch( ... ) {}
135 try {
136 frame[2] = (int) rint( options->getProperty( "sz" )->getScalar() );
137 options->removeProperty( "sz" );
138 } catch( ... ) {}
139 try {
140 frame[3] = (int) rint( options->getProperty( "st" )->getScalar() );
141 options->removeProperty( "st" );
142 } catch( ... ) {}
143 try {
144 borders[0] = (int) rint( options->getProperty( "border" )->getScalar() );
145 borders[1] = (int) rint( options->getProperty( "border" )->getScalar() );
146 borders[2] = (int) rint( options->getProperty( "border" )->getScalar() );
147 options->removeProperty( "border" );
148 } catch( ... ) {}
149 try {
150 borders[0] = (int) rint( options->getProperty( "bx" )->getScalar() );
151 options->removeProperty( "bx" );
152 } catch( ... ) {}
153 try {
154 borders[1] = (int) rint( options->getProperty( "by" )->getScalar() );
155 options->removeProperty( "by" );
156 } catch( ... ) {}
157 try {
158 borders[2] = (int) rint( options->getProperty( "bz" )->getScalar() );
159 options->removeProperty( "bz" );
160 } catch( ... ) {}
161
162 size_t dim, value;
163 for( dim=0; dim<carto::Volume<T>::DIM_MAX; ++dim )
164 {
165 try
166 {
167 std::stringstream skey;
168 skey << "ox" << dim+1;
169 std::string key = skey.str();
170 value = (int) rint( options->getProperty( key )->getScalar() );
171 options->removeProperty( key );
172 if( position.size() <= dim )
173 position.resize( dim + 1, 0 );
174 position[ dim ] = value;
175 }
176 catch( ... ) {}
177 try
178 {
179 std::stringstream skey;
180 skey << "sx" << dim+1;
181 std::string key = skey.str();
182 value = (int) rint( options->getProperty( key )->getScalar() );
183 options->removeProperty( key );
184 if( frame.size() <= dim )
185 frame.resize( dim + 1, -1 );
186 frame[ dim ] = value;
187 }
188 catch( ... ) {}
189 }
190
191 bool partial = false;
192 for( dim=0; !partial && dim<position.size(); ++dim )
193 if( position[dim] != 0 )
194 partial = true;
195 for( dim=0; !partial && dim<frame.size(); ++dim )
196 if( frame[dim] != -1 )
197 partial = true;
198
199 if( partial )
200 return readPartial( obj, dsi, position, frame, borders, options );
201 else
202 return readFull( obj, dsi, borders, options );
203 }
204
205 template <typename T> carto::Volume<T>*
208 std::vector<int> borders,
209 carto::Object options )
210 {
211 //=== VARIABLES ==========================================================
212 //int verbose = carto::debugMessageLevel;
213 carto::Object newoptions;
216 carto::VolumeRef<T> bordersVolume;
217 std::vector<int> fullsize;
218 std::vector<int> bordersize;
219 std::vector<int> volumepos;
220
221 if( borders[0] !=0 || borders[1] !=0 || borders[2] !=0 )
222 {
223 //=== CHECK FULL VOLUME ================================================
224 localMsg( "=== READING FULL VOLUME SIZE" );
226 newoptions->copyProperties( options );
227 localMsg( "checking full volume..." );
228 *dsi = dsil.check( *dsi, options );
229 localMsg( "reading size..." );
230 if( !dsi->header()->getProperty( "volume_dimension", fullsize ) )
231 {
232 fullsize[0] = (int) rint(
233 dsi->header()->getProperty( "sizeX" )->getScalar() );
234 fullsize[1] = (int) rint(
235 dsi->header()->getProperty( "sizeY" )->getScalar() );
236 fullsize[2] = (int) rint(
237 dsi->header()->getProperty( "sizeZ" )->getScalar() );
238 fullsize[3] = (int) rint(
239 dsi->header()->getProperty( "sizeT" )->getScalar() );
240 }
241 if( fullsize.size() < 4 )
242 fullsize.resize( 4, 1 );
243 volumepos.resize( fullsize.size(), 0 );
244 volumepos[0] = borders[0];
245 volumepos[1] = borders[1];
246 volumepos[2] = borders[2];
247 localMsg( "-> size = ( "
248 + carto::toString( fullsize[0] ) + ", "
249 + carto::toString( fullsize[1] ) + ", "
250 + carto::toString( fullsize[2] ) + ", "
251 + carto::toString( fullsize[3] ) + " )"
252 );
253
254 //=== BORDERS VOLUME ===================================================
255 localMsg( "=== ALLOCATED BORDERS VOLUME" );
256 localMsg( "computing sizes..." );
257 bordersize = fullsize;
258 bordersize[0] = fullsize[0] + 2*borders[0];
259 bordersize[1] = fullsize[1] + 2*borders[1];
260 bordersize[2] = fullsize[2] + 2*borders[2];
261 localMsg( "creating allocated volume..." );
262 localMsg( "-> with size ( "
263 + carto::toString( bordersize[0] ) + ", "
264 + carto::toString( bordersize[1] ) + ", "
265 + carto::toString( bordersize[2] ) + ", "
266 + carto::toString( bordersize[3] ) + " )"
267 );
268 bordersVolume = carto::VolumeRef<T>(
269 new carto::Volume<T>( bordersize ) );
270
271 //=== READ FULL VOLUME =================================================
272 localMsg( "=== UNALLOCATED FULL VIEW" );
273 rVol = soma::Reader< carto::Volume<T> >( dsi );
275 newoptions->copyProperties( options );
276 newoptions->setProperty( "keep_allocation", true );
277 rVol.setOptions( newoptions );
278 localMsg( "creating volume view..." );
279 localMsg( "-> with pos ( "
280 + carto::toString( volumepos[0] ) + ", "
281 + carto::toString( volumepos[1] ) + ", "
282 + carto::toString( volumepos[2] ) + ", "
283 + carto::toString( volumepos[3] ) + " )"
284 );
285 localMsg( "-> with size ( "
286 + carto::toString( fullsize[0] ) + ", "
287 + carto::toString( fullsize[1] ) + ", "
288 + carto::toString( fullsize[2] ) + ", "
289 + carto::toString( fullsize[3] ) + " )"
290 );
291 if( obj )
292 *obj = carto::Volume<T>( bordersVolume, volumepos, fullsize );
293 else
294 obj = new carto::Volume<T>( bordersVolume, volumepos, fullsize );
295 localMsg( "reading unallocated volume..." );
297 rVol.read( *obj );
298
299 /* copy voxel_size to underlying volume, if any.
300 This should probably be more general, but cannot be applied to all
301 header properties (size, transformations...).
302 WARNING: Moreover here we do not guarantee to keep both voxel_size
303 unique: we point to the same vector of values for now, but it can be
304 replaced (thus, duplicated) by a setProperty().
305 We could use a addBuiltinProperty(), but then the voxel size has to be
306 stored in a fixed location somewhere.
307 */
308 try
309 {
310 carto::Object vs = obj->header().getProperty( "voxel_size" );
311 bordersVolume->header().setProperty( "voxel_size", vs );
312 }
313 catch( ... )
314 { // never mind.
315 }
316
317 }
318 else
319 {
320 //=== FULL VOLUME ======================================================
321 localMsg( "=== ALLOCATED FULL VIEW" );
322 rVol = soma::Reader< carto::Volume<T> >( dsi );
324 newoptions->copyProperties( options );
325 rVol.setOptions( newoptions );
326 localMsg( "reading volume..." );
327 obj = rVol.read();
328 }
329
330 return obj;
331 }
332
333 template <typename T> carto::Volume<T>*
336 std::vector<int> position,
337 std::vector<int> frame,
338 std::vector<int> borders,
339 carto::Object options )
340 {
341 //=== VARIABLES ==========================================================
342 localMsg( "VolumeUtilIO<T>::readPartial" );
343 std::vector<int> viewframe( frame );
344 size_t dim, ndim = std::max( position.size(), frame.size() );
345 if( viewframe.size() < ndim )
346 viewframe.resize( ndim, -1 );
347 std::vector<int> viewpos( position );
348 if( viewpos.size() < ndim )
349 viewpos.resize( ndim, 0 );
350 std::vector<int> fullsize; // full size
351 std::vector<int> borderframe( ndim, 1 ); // allocated volume size
352 std::vector<int> borderpos; // allocated volume origin
353 std::vector<int> readframe( ndim, 0 ); // read frame size
354 std::vector<int> readpos( ndim, 0 ); // read frame origin
355 carto::Object newoptions;
358 carto::VolumeRef<T> fullVolume, bordersVolume, readVolume;
359// carto::Volume<T>* viewVolume;
360
361 //=== UNALLOCATED FULL VOLUME ============================================
362 localMsg( "=== UNALLOCATED FULL VOLUME" );
363 rVol = soma::Reader<carto::Volume<T> >( dsi );
365 newoptions->setProperty( "unallocated", true );
366 newoptions->copyProperties( options );
367 rVol.setOptions( newoptions );
368 localMsg( "reading unallocated volume..." );
369 fullVolume = carto::VolumeRef<T>( rVol.read() );
370 localMsg( "reading size from volume..." );
371 fullsize = fullVolume->getSize();
372// localMsg( "-> full size ( "
373// + carto::toString( fullsize[0] ) + ", "
374// + carto::toString( fullsize[1] ) + ", "
375// + carto::toString( fullsize[2] ) + ", "
376// + carto::toString( fullsize[3] ) + " )" );
377// localMsg( "-> position ( "
378// + carto::toString( position[0] ) + ", "
379// + carto::toString( position[1] ) + ", "
380// + carto::toString( position[2] ) + ", "
381// + carto::toString( position[3] ) + " )" );
382// localMsg( "-> borders ( "
383// + carto::toString( borders[0] ) + ", "
384// + carto::toString( borders[1] ) + ", "
385// + carto::toString( borders[2] ) + ", "
386// + carto::toString( borders[3] ) + " )" );
387 for( dim=0; dim<ndim; ++dim )
388 if( viewframe[ dim ] == -1 )
389 viewframe[ dim ] = (fullsize[ dim ] - position[ dim ]);
390
391 localMsg( "===" );
392
393 // processes full image upper and lower overflows
394 std::vector<int> loverflow(3,0), uoverflow(3, 0);
395 loverflow[0] = (viewpos[0] < 0 ? -viewpos[0] : 0);
396 loverflow[1] = (viewpos[1] < 0 ? -viewpos[1] : 0);
397 loverflow[2] = (viewpos[2] < 0 ? -viewpos[2] : 0);
398
399 uoverflow[0] = (viewpos[0] + viewframe[0] - fullsize[0] > 0 ?
400 viewpos[0] + viewframe[0] - fullsize[0] : 0);
401 uoverflow[1] = (viewpos[1] + viewframe[1] - fullsize[1] > 0 ?
402 viewpos[1] + viewframe[1] - fullsize[1] : 0);
403 uoverflow[2] = (viewpos[2] + viewframe[2] - fullsize[2] > 0 ?
404 viewpos[2] + viewframe[2] - fullsize[2] : 0);
405
406 // To deal with negative view positions and view frames that ends over the
407 // full volume size, we use an overflow policy.
408 // Overflow policy : 0 => overflow is managed as unread data in the view
409 // 1 => overflow is managed as border
410 int overflow_policy = 0;
411 try
412 {
413 carto::Object overflow_pol = newoptions->getProperty(
414 "overflow_policy" );
415 overflow_policy = int( overflow_pol->getScalar() );
416 }
417 catch( ... )
418 {
419 }
420
421 if( borders[0] != 0 || borders[1] != 0 || borders[2] != 0
422 || (overflow_policy == 1 &&
423 (loverflow[0] > 0 || loverflow[1] > 0 || loverflow[2] > 0
424 || uoverflow[0] > 0 || uoverflow[1] > 0 || uoverflow[2] > 0 ) ) )
425 {
426 //=== ALLOCATED BORDERS VOLUME =========================================
427 localMsg( "=== ALLOCATED BORDERS VOLUME" );
428 localMsg( "computing borders..." );
429 // setting "bordersVolume" position / "fullVolume"
430 borderpos = viewpos;
431 borderpos[0] -= borders[0];
432 borderpos[1] -= borders[1];
433 borderpos[2] -= borders[2];
434
435 borderframe = viewframe;
436 borderframe[0] += 2*borders[0];
437 borderframe[1] += 2*borders[1];
438 borderframe[2] += 2*borders[2];
439
440 localMsg( "creating volume..." );
441 localMsg( "-> with frame size ( "
442 + carto::toString( borderframe[0] ) + ", "
443 + carto::toString( borderframe[1] ) + ", "
444 + carto::toString( borderframe[2] ) + ", "
445 + carto::toString( borderframe[3] ) + " )"
446 );
447 localMsg( "-> with frame pos ( "
448 + carto::toString( borderpos[0] ) + ", "
449 + carto::toString( borderpos[1] ) + ", "
450 + carto::toString( borderpos[2] ) + ", "
451 + carto::toString( borderpos[3] ) + " )"
452 );
453 bordersVolume = carto::VolumeRef<T>(
454 new carto::Volume<T>( fullVolume, borderpos, borderframe ) );
455
456// localMsg( "-> effective frame size ( "
457// + carto::toString( bordersVolume->getSizeX() ) + ", "
458// + carto::toString( bordersVolume->getSizeY() ) + ", "
459// + carto::toString( bordersVolume->getSizeZ() ) + ", "
460// + carto::toString( bordersVolume->getSizeT() ) + " )"
461// );
462
463 //=== UNALLOCATED READ VIEW ============================================
464 localMsg( "=== UNALLOCATED READ VIEW" );
465 localMsg( "computing read frame..." );
466 // setting "readVolume" position / "bordersVolume"
467 readpos[0] = ( borderpos[0] < 0 ? borders[0] + loverflow[0] : 0 );
468 readpos[1] = ( borderpos[1] < 0 ? borders[1] + loverflow[1] : 0 );
469 readpos[2] = ( borderpos[2] < 0 ? borders[2] + loverflow[2] : 0 );
470 readpos[3] = 0;
471 std::vector<int> borderdep( 3, 0 );
472 borderdep[0] = ( borderpos[0] + borderframe[0] - fullsize[0] > 0
473 ? borderpos[0] + borderframe[0] - fullsize[0] : 0 );
474 borderdep[1] = ( borderpos[1] + borderframe[1] - fullsize[1] > 0
475 ? borderpos[1] + borderframe[1] - fullsize[1] : 0 );
476 borderdep[2] = ( borderpos[2] + borderframe[2] - fullsize[2] > 0
477 ? borderpos[2] + borderframe[2] - fullsize[2] : 0 );
478 readframe[0] = borderframe[0] - readpos[0] - borderdep[0];
479 readframe[1] = borderframe[1] - readpos[1] - borderdep[1];
480 readframe[2] = borderframe[2] - readpos[2] - borderdep[2];
481 readframe[3] = borderframe[3];
484 newoptions->setProperty( "partial_reading", true );
485 newoptions->copyProperties( options );
486 rView.setOptions( newoptions );
487 localMsg( "creating read volume..." );
488 localMsg( "-> with frame size ( "
489 + carto::toString( readframe[0] ) + ", "
490 + carto::toString( readframe[1] ) + ", "
491 + carto::toString( readframe[2] ) + ", "
492 + carto::toString( readframe[3] ) + " )"
493 );
494 localMsg( "-> with frame pos ( "
495 + carto::toString( readpos[0] ) + ", "
496 + carto::toString( readpos[1] ) + ", "
497 + carto::toString( readpos[2] ) + ", "
498 + carto::toString( readpos[3] ) + " )"
499 );
500 readVolume = carto::VolumeRef<T>(
501 new carto::Volume<T>( bordersVolume, readpos, readframe ) );
502
503// localMsg( "-> effective read view size ( "
504// + carto::toString( readVolume->getSizeX() ) + ", "
505// + carto::toString( readVolume->getSizeY() ) + ", "
506// + carto::toString( readVolume->getSizeZ() ) + ", "
507// + carto::toString( readVolume->getSizeT() ) + " )"
508// );
509
510 localMsg( "reading frame..." );
511 rView.read( *readVolume );
512
513// localMsg( "-> effective read view size after read ( "
514// + carto::toString( readVolume->getSizeX() ) + ", "
515// + carto::toString( readVolume->getSizeY() ) + ", "
516// + carto::toString( readVolume->getSizeZ() ) + ", "
517// + carto::toString( readVolume->getSizeT() ) + " )"
518// );
519
520 //=== UNALLOCATED PROCCESSED VOLUME ====================================
521 localMsg( "=== UNALLOCATED PROCESSED VOLUME" );
522 localMsg( "computing view frame..." );
523 // setting "viewVolume" position / "bordersVolume"
524 if (overflow_policy == 1)
525 {
526 viewframe[0] -= loverflow[0] + uoverflow[0];
527 viewframe[1] -= loverflow[1] + uoverflow[1];
528 viewframe[2] -= loverflow[2] + uoverflow[2];
529
530 viewpos[0] = borders[0] + loverflow[0];
531 viewpos[1] = borders[1] + loverflow[1];
532 viewpos[2] = borders[2] + loverflow[2];
533 }
534 else
535 {
536 viewpos[0] = borders[0];
537 viewpos[1] = borders[1];
538 viewpos[2] = borders[2];
539 }
540 viewpos[3] = 0;
541
542 localMsg( "creating volume..." );
543 localMsg( "-> with frame size ( "
544 + carto::toString( viewframe[0] ) + ", "
545 + carto::toString( viewframe[1] ) + ", "
546 + carto::toString( viewframe[2] ) + ", "
547 + carto::toString( viewframe[3] ) + " )"
548 );
549 localMsg( "-> with frame pos ( "
550 + carto::toString( viewpos[0] ) + ", "
551 + carto::toString( viewpos[1] ) + ", "
552 + carto::toString( viewpos[2] ) + ", "
553 + carto::toString( viewpos[3] ) + " )"
554 );
555 if(obj)
556 {
557 bool keep_allocation = false;
558 try
559 {
560 carto::Object keep_alloc = newoptions->getProperty(
561 "keep_allocation" );
562 keep_allocation = bool( keep_alloc->getScalar() );
563 }
564 catch( ... )
565 {
566 }
567 if( !keep_allocation )
568 *obj = carto::Volume<T>( bordersVolume, viewpos, viewframe );
569 }
570 else
571 obj = new carto::Volume<T>( bordersVolume, viewpos, viewframe );
572
573 localMsg( "copying header..." );
574 obj->blockSignals( true );
575 obj->header().copyProperties( carto::Object::value( readVolume->header() ) );
576 /* copy voxel_size to underlying volume, if any.
577 This should probably be more general, but cannot be applied to all
578 header properties (size, transformations...).
579 WARNING: Moreover here we do not guarantee to keep both voxel_size
580 unique: we point to the same vector of values for now, but it can be
581 replaced (thus, duplicated) by a setProperty().
582 We could use a addBuiltinProperty(), but then the voxel size has to be
583 stored in a fixed location somewhere.
584 */
585 try
586 {
587 carto::Object vs = obj->header().getProperty( "voxel_size" );
588 bordersVolume->header().setProperty( "voxel_size", vs );
589 }
590 catch( ... )
591 { // never mind.
592 }
593 carto::PropertySet & ps = obj->header();
594 ps.setProperty( "sizeX", viewframe[0] );
595 ps.setProperty( "sizeY", viewframe[1] );
596 ps.setProperty( "sizeZ", viewframe[2] );
597 ps.setProperty( "sizeT", viewframe[3] );
598 ps.setProperty( "volume_dimension", viewframe );
599 obj->blockSignals( false );
600 }
601 else
602 {
603 //=== ALLOCATED PROCESSED VOLUME =======================================
604 localMsg( "=== ALLOCATED PROCESSED VOLUME" );
607 newoptions->setProperty( "partial_reading", true );
608 newoptions->copyProperties( options );
609 rView.setOptions( newoptions );
610 localMsg( "creating volume..." );
611 VolumeRef<T> tmp;
612 if( obj )
613 {
614 localMsg( "existing volume" );
615 bool keep_allocation = false;
616 try
617 {
618 carto::Object keep_alloc = newoptions->getProperty(
619 "keep_allocation" );
620 keep_allocation = bool( keep_alloc->getScalar() );
621 }
622 catch( ... )
623 {
624 }
625 if( keep_allocation )
626 {
627 /* read inside an existing allocated volume.
628
629 The problem here is that we need a view which is attached both
630 to a file parent (fullVolume) with a certain position, and at
631 the same time to an allocated parent volume, with another
632 position.
633
634 The trick here is to build a view in the unallocated fullVolume
635 (representing the whole file) with the size/position of the
636 patch to be read from file, and pointing to the memory block of
637 the view (obj) in memory. Then read the "file view" as for the
638 border case.
639 */
640
641 tmp.reset( new carto::Volume<T>( fullVolume, viewpos, viewframe,
642 &obj->at(0), obj->getStrides() ) );
643
644 obj = tmp.get(); // read the temp volume
645 }
646 else
647 *obj = carto::Volume<T>( fullVolume, viewpos, viewframe );
648 }
649 else
650 obj = new carto::Volume<T>( fullVolume, viewpos, viewframe );
651
652 if ( loverflow[0] > 0 || loverflow[1] > 0 || loverflow[2] > 0
653 || uoverflow[0] > 0 || uoverflow[1] > 0 || uoverflow[2] > 0 )
654 {
655 //=== UNALLOCATED READ VIEW ============================================
656 localMsg( "=== UNALLOCATED READ VIEW" );
657 localMsg( "computing read frame for overflows..." );
658 // setting "readVolume" position / "bordersVolume"
659 readpos[0] = loverflow[0];
660 readpos[1] = loverflow[1];
661 readpos[2] = loverflow[2];
662 readpos[3] = 0;
663 readframe[0] = viewframe[0] - loverflow[0] - uoverflow[0];
664 readframe[1] = viewframe[1] - loverflow[1] - uoverflow[1];
665 readframe[2] = viewframe[2] - loverflow[2] - uoverflow[2];
666 readframe[3] = viewframe[3];
667 localMsg( "creating read volume..." );
668 localMsg( "-> with frame size ( "
669 + carto::toString( readframe[0] ) + ", "
670 + carto::toString( readframe[1] ) + ", "
671 + carto::toString( readframe[2] ) + ", "
672 + carto::toString( readframe[3] ) + " )"
673 );
674 localMsg( "-> with frame pos ( "
675 + carto::toString( readpos[0] ) + ", "
676 + carto::toString( readpos[1] ) + ", "
677 + carto::toString( readpos[2] ) + ", "
678 + carto::toString( readpos[3] ) + " )"
679 );
680
681 // To avoid underlying data deletion when readVolume is deleted
682 // We need to recreate a Volume that is based on the full volume
683 tmp.reset( new carto::Volume<T>( fullVolume, viewpos, viewframe,
684 &obj->at(0), obj->getStrides() ) );
685 readVolume = carto::VolumeRef<T>(
686 new carto::Volume<T>( tmp,
687 readpos, readframe ) );
688
689 // localMsg( "-> effective read view size ( "
690 // + carto::toString( readVolume->getSizeX() ) + ", "
691 // + carto::toString( readVolume->getSizeY() ) + ", "
692 // + carto::toString( readVolume->getSizeZ() ) + ", "
693 // + carto::toString( readVolume->getSizeT() ) + " )"
694 // );
695
696 localMsg( "reading partial volume using read view ..." );
697 rView.read( *readVolume );
698 }
699 else {
700 localMsg( "reading partial volume..." );
701 rView.read( *obj );
702 }
703 }
704
705 return obj;
706 }
707
708}
709
710#undef localMsg
711#endif
virtual void copyProperties(Object source)
const PropertySet & header() const
void blockSignals(bool)
static Object value()
Object value(const Object &value)
void setProperty(const std::string &, const T &)
bool getProperty(const std::string &, T &) const
Convenient handle for a Volume - this is normally the entry point for all volumes handling.
Definition volumeref.h:60
std::vector< int > getSize() const
const PropertySet & header() const
N-D Volume main class.
Definition volumebase.h:120
const AllocatorContext & allocatorContext() const
returns volume's AllocatorContext
std::vector< long > getStrides() const
Get strides for the volume.
const T & at(long x, long y=0, long z=0, long t=0) const
DataSourceInfo check(DataSourceInfo dsi, carto::Object options=carto::none(), int passbegin=1, int passend=3)
void setAllocatorContext(const AllocatorContext &ac)
virtual bool read(T &obj, carto::Object header=carto::none(), int passbegin=1, int passend=4)
const carto::rc_ptr< DataSourceInfo > & dataSourceInfo() const
void setOptions(carto::Object options)
static std::set< std::string > listReadProperties()
list of properties triggering partial reading and/or borders
static carto::Volume< T > * readFull(carto::Volume< T > *obj, carto::rc_ptr< DataSourceInfo > dsi, std::vector< int > borders, carto::Object options)
Worker for full reading case.
static carto::Volume< T > * readPartial(carto::Volume< T > *obj, carto::rc_ptr< DataSourceInfo > dsi, std::vector< int > position, std::vector< int > frame, std::vector< int > borders, carto::Object options)
Worker for partial reading case.
static carto::Volume< T > * read(carto::Volume< T > *obj, carto::rc_ptr< DataSourceInfo > dsi, carto::Object options)
Manages all the volumes necessary and returns the final Volume.
std::string toString(const T &object)
#define localMsg(message)