cartodata  5.1.2
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>
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 ------------------------------------------------------------------
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 
58 namespace 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" );
225  newoptions = carto::Object::value( carto::PropertySet() );
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 );
274  newoptions = carto::Object::value( carto::PropertySet() );
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..." );
296  rVol.setAllocatorContext( obj->allocatorContext() );
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 );
323  newoptions = carto::Object::value( carto::PropertySet() );
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 );
364  newoptions = carto::Object::value( carto::PropertySet() );
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];
482  rView = soma::Reader<carto::Volume<T> >( rVol.dataSourceInfo() );
483  newoptions = carto::Object::value( carto::PropertySet() );
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" );
605  rView = soma::Reader<carto::Volume<T> >( rVol.dataSourceInfo() );
606  newoptions = carto::Object::value( carto::PropertySet() );
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)
void blockSignals(bool)
const PropertySet & header() const
static 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:119
const AllocatorContext & allocatorContext() const
returns volume's AllocatorContext
Definition: volumebase_d.h:521
std::vector< size_t > getStrides() const
Get strides for the volume.
Definition: volumebase_d.h:726
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)
const carto::rc_ptr< DataSourceInfo > & dataSourceInfo() const
virtual bool read(T &obj, carto::Object header=carto::none(), int passbegin=1, int passend=4)
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)
T max(const Volume< T > &vol)
Returns the maximum value of the volume.
Definition: volumeutil.h:1153
#define localMsg(message)