cartodata  4.5.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>
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 // localMsg must be undef at end of file
54 //----------------------------------------------------------------------------
55 
56 namespace soma {
57 
58  template <typename T> std::set<std::string>
60  {
61  std::set<std::string> properties;
62  properties.insert( "ox" );
63  properties.insert( "oy" );
64  properties.insert( "oz" );
65  properties.insert( "ot" );
66  properties.insert( "sx" );
67  properties.insert( "sy" );
68  properties.insert( "sz" );
69  properties.insert( "st" );
70  properties.insert( "bx" );
71  properties.insert( "by" );
72  properties.insert( "bz" );
73  properties.insert( "border" );
74  return properties;
75  }
76 
77  //==========================================================================
78  // R E A D
79  //==========================================================================
80 
81  template <typename T> carto::Volume<T>*
84  carto::Object options )
85  {
86  std::vector<int> position( 4, 0 );
87  std::vector<int> frame( 4, 0 );
88  std::vector<int> borders( 4, 0 );
89  try {
90  position[0] = (int) rint(
91  options->getProperty( "ox" )->getScalar() );
92  options->removeProperty( "ox" );
93  } catch( ... ) {}
94  try {
95  position[1] = (int) rint(
96  options->getProperty( "oy" )->getScalar() );
97  options->removeProperty( "oy" );
98  } catch( ... ) {}
99  try {
100  position[2] = (int) rint(
101  options->getProperty( "oz" )->getScalar() );
102  options->removeProperty( "oz" );
103  } catch( ... ) {}
104  try {
105  position[3] = (int) rint(
106  options->getProperty( "ot" )->getScalar() );
107  options->removeProperty( "ot" );
108  } catch( ... ) {}
109  try {
110  frame[0] = (int) rint(
111  options->getProperty( "sx" )->getScalar() );
112  options->removeProperty( "sx" );
113  } catch( ... ) {}
114  try {
115  frame[1] = (int) rint(
116  options->getProperty( "sy" )->getScalar() );
117  options->removeProperty( "sy" );
118  } catch( ... ) {}
119  try {
120  frame[2] = (int) rint(
121  options->getProperty( "sz" )->getScalar() );
122  options->removeProperty( "sz" );
123  } catch( ... ) {}
124  try {
125  frame[3] = (int) rint(
126  options->getProperty( "st" )->getScalar() );
127  options->removeProperty( "st" );
128  } catch( ... ) {}
129  try {
130  borders[0] = (int) rint( options->getProperty( "border" )->getScalar() );
131  borders[1] = (int) rint( options->getProperty( "border" )->getScalar() );
132  borders[2] = (int) rint( options->getProperty( "border" )->getScalar() );
133  options->removeProperty( "border" );
134  } catch( ... ) {}
135  try {
136  borders[0] = (int) rint( options->getProperty( "bx" )->getScalar() );
137  options->removeProperty( "bx" );
138  } catch( ... ) {}
139  try {
140  borders[1] = (int) rint( options->getProperty( "by" )->getScalar() );
141  options->removeProperty( "by" );
142  } catch( ... ) {}
143  try {
144  borders[2] = (int) rint( options->getProperty( "bz" )->getScalar() );
145  options->removeProperty( "bz" );
146  } catch( ... ) {}
147 
148  bool partial = !( frame[0] == 0 && frame[1] == 0 &&
149  frame[2] == 0 && frame[3] == 0 &&
150  position[0] == 0 && position[1] == 0 &&
151  position[2] == 0 && position[3] == 0);
152  if( partial )
153  return readPartial( obj, dsi, position, frame, borders, options );
154  else
155  return readFull( obj, dsi, borders, options );
156  }
157 
158  template <typename T> carto::Volume<T>*
161  std::vector<int> borders,
162  carto::Object options )
163  {
164  //=== VARIABLES ==========================================================
166  carto::Object newoptions;
169  carto::VolumeRef<T> bordersVolume;
170 // carto::Volume<T>* fullVolume;
171  typename carto::Volume<T>::Position4Di fullsize;
172  typename carto::Volume<T>::Position4Di bordersize;
173  typename carto::Volume<T>::Position4Di volumepos( borders[0],
174  borders[1],
175  borders[2], 0 );
176 
177  if( borders[0] !=0 || borders[1] !=0 || borders[2] !=0 )
178  {
179  //=== CHECK FULL VOLUME ================================================
180  localMsg( "=== READING FULL VOLUME SIZE" );
181  newoptions = carto::Object::value( carto::PropertySet() );
182  newoptions->copyProperties( options );
183  localMsg( "checking full volume..." );
184  *dsi = dsil.check( *dsi, options );
185  localMsg( "reading size..." );
186  fullsize[0] = (int) rint(
187  dsi->header()->getProperty( "sizeX" )->getScalar() );
188  fullsize[1] = (int) rint(
189  dsi->header()->getProperty( "sizeY" )->getScalar() );
190  fullsize[2] = (int) rint(
191  dsi->header()->getProperty( "sizeZ" )->getScalar() );
192  fullsize[3] = (int) rint(
193  dsi->header()->getProperty( "sizeT" )->getScalar() );
194  localMsg( "-> size = ( "
195  + carto::toString( fullsize[0] ) + ", "
196  + carto::toString( fullsize[1] ) + ", "
197  + carto::toString( fullsize[2] ) + ", "
198  + carto::toString( fullsize[3] ) + " )"
199  );
200 
201  //=== BORDERS VOLUME ===================================================
202  localMsg( "=== ALLOCATED BORDERS VOLUME" );
203  localMsg( "computing sizes..." );
204  bordersize[0] = fullsize[0] + 2*borders[0];
205  bordersize[1] = fullsize[1] + 2*borders[1];
206  bordersize[2] = fullsize[2] + 2*borders[2];
207  bordersize[3] = fullsize[3];
208  localMsg( "creating allocated volume..." );
209  localMsg( "-> with size ( "
210  + carto::toString( bordersize[0] ) + ", "
211  + carto::toString( bordersize[1] ) + ", "
212  + carto::toString( bordersize[2] ) + ", "
213  + carto::toString( bordersize[3] ) + " )"
214  );
215  bordersVolume = carto::VolumeRef<T>(
216  new carto::Volume<T>( bordersize[0], bordersize[1],
217  bordersize[2], bordersize[3] ) );
218 
219  //=== READ FULL VOLUME =================================================
220  localMsg( "=== UNALLOCATED FULL VIEW" );
221  rVol = soma::Reader< carto::Volume<T> >( dsi );
222  newoptions = carto::Object::value( carto::PropertySet() );
223  newoptions->copyProperties( options );
224  newoptions->setProperty( "keep_allocation", true );
225  rVol.setOptions( newoptions );
226  localMsg( "creating volume view..." );
227  localMsg( "-> with pos ( "
228  + carto::toString( volumepos[0] ) + ", "
229  + carto::toString( volumepos[1] ) + ", "
230  + carto::toString( volumepos[2] ) + ", "
231  + carto::toString( volumepos[3] ) + " )"
232  );
233  localMsg( "-> with size ( "
234  + carto::toString( fullsize[0] ) + ", "
235  + carto::toString( fullsize[1] ) + ", "
236  + carto::toString( fullsize[2] ) + ", "
237  + carto::toString( fullsize[3] ) + " )"
238  );
239  if( obj )
240  *obj = carto::Volume<T>( bordersVolume, volumepos, fullsize );
241  else
242  obj = new carto::Volume<T>( bordersVolume, volumepos, fullsize );
243  localMsg( "reading unallocated volume..." );
244  rVol.setAllocatorContext( obj->allocatorContext() );
245  rVol.read( *obj );
246 
247  /* copy voxel_size to underlying volume, if any.
248  This should probably be more general, but cannot be applied to all
249  header properties (size, transformations...).
250  WARNING: Moreover here we do not guarantee to keep both voxel_size
251  unique: we point to the same vector of values for now, but it can be
252  replaced (thus, duplicated) by a setProperty().
253  We could use a addBuiltinProperty(), but then the voxel size has to be
254  stored in a fixed location somewhere.
255  */
256  try
257  {
258  carto::Object vs = obj->header().getProperty( "voxel_size" );
259  bordersVolume->header().setProperty( "voxel_size", vs );
260  }
261  catch( ... )
262  { // never mind.
263  }
264 
265  }
266  else
267  {
268  //=== FULL VOLUME ======================================================
269  localMsg( "=== ALLOCATED FULL VIEW" );
270  rVol = soma::Reader< carto::Volume<T> >( dsi );
271  newoptions = carto::Object::value( carto::PropertySet() );
272  newoptions->copyProperties( options );
273  rVol.setOptions( newoptions );
274  localMsg( "reading volume..." );
275  obj = rVol.read();
276  }
277 
278  return obj;
279  }
280 
281  template <typename T> carto::Volume<T>*
284  std::vector<int> position,
285  std::vector<int> frame,
286  std::vector<int> borders,
287  carto::Object options )
288  {
289  //=== VARIABLES ==========================================================
292  viewframe( frame[0], frame[1], frame[2], frame[3] );
294  viewpos( position[0], position[1], position[2], position[3] );
295  typename carto::Volume<T>::Position4Di fullsize; // full size
296  typename carto::Volume<T>::Position4Di borderframe; // allocated volume size
297  typename carto::Volume<T>::Position4Di borderpos; // allocated volume size
298  typename carto::Volume<T>::Position4Di readframe; // read frame size
299  typename carto::Volume<T>::Position4Di readpos; // read frame origin
300  carto::Object newoptions;
303  carto::VolumeRef<T> fullVolume, bordersVolume, readVolume;
304 // carto::Volume<T>* viewVolume;
305 
306  //=== UNALLOCATED FULL VOLUME ============================================
307  localMsg( "=== UNALLOCATED FULL VOLUME" );
308  rVol = soma::Reader<carto::Volume<T> >( dsi );
309  newoptions = carto::Object::value( carto::PropertySet() );
310  newoptions->setProperty( "unallocated", true );
311  newoptions->copyProperties( options );
312  rVol.setOptions( newoptions );
313  localMsg( "reading unallocated volume..." );
314  fullVolume = carto::VolumeRef<T>( rVol.read() );
315  localMsg( "reading size from volume..." );
316  fullsize[ 0 ] = fullVolume->getSizeX();
317  fullsize[ 1 ] = fullVolume->getSizeY();
318  fullsize[ 2 ] = fullVolume->getSizeZ();
319  fullsize[ 3 ] = fullVolume->getSizeT();
320  if( viewframe[ 0 ] == 0 )
321  viewframe[ 0 ] = (fullsize[ 0 ] - position[ 0 ]);
322  if( viewframe[ 1 ] == 0 )
323  viewframe[ 1 ] = (fullsize[ 1 ] - position[ 1 ]);
324  if( viewframe[ 2 ] == 0 )
325  viewframe[ 2 ] = (fullsize[ 2 ] - position[ 2 ]);
326  if( viewframe[ 3 ] == 0 )
327  viewframe[ 3 ] = (fullsize[ 3 ] - position[ 3 ]);
328  localMsg( "===" );
329 
330  if( borders[0] != 0 || borders[1] != 0 || borders[2] != 0 )
331  {
332  //=== ALLOCATED BORDERS VOLUME =========================================
333  localMsg( "=== ALLOCATED BORDERS VOLUME" );
334  localMsg( "computing borders..." );
335  // setting "bordersVolume" position / "fullVolume"
336  borderpos = viewpos;
337  borderpos[0] -= borders[0];
338  borderpos[1] -= borders[1];
339  borderpos[2] -= borders[2];
340  borderframe = viewframe;
341  borderframe[0] += 2*borders[0];
342  borderframe[1] += 2*borders[1];
343  borderframe[2] += 2*borders[2];
344  localMsg( "creating volume..." );
345  localMsg( "-> with frame size ( "
346  + carto::toString( borderframe[0] ) + ", "
347  + carto::toString( borderframe[1] ) + ", "
348  + carto::toString( borderframe[2] ) + ", "
349  + carto::toString( borderframe[3] ) + " )"
350  );
351  localMsg( "-> with frame pos ( "
352  + carto::toString( borderpos[0] ) + ", "
353  + carto::toString( borderpos[1] ) + ", "
354  + carto::toString( borderpos[2] ) + ", "
355  + carto::toString( borderpos[3] ) + " )"
356  );
357  bordersVolume = carto::VolumeRef<T>(
358  new carto::Volume<T>( fullVolume, borderpos, borderframe ) );
359 
360  //=== UNALLOCATED READ VIEW ============================================
361  localMsg( "=== UNALLOCATED READ VIEW" );
362  localMsg( "computing read frame..." );
363  // setting "readVolume" position / "bordersVolume"
364  readpos[0] = ( borderpos[0] < 0 ? borders[0] : 0 );
365  readpos[1] = ( borderpos[1] < 0 ? borders[1] : 0 );
366  readpos[2] = ( borderpos[2] < 0 ? borders[2] : 0 );
367  readpos[3] = 0;
368  std::vector<int> borderdep( 3, 0 );
369  borderdep[0] = ( borderpos[0] + borderframe[0] - fullsize[0] > 0
370  ? borderpos[0] + borderframe[0] - fullsize[0] : 0 );
371  borderdep[1] = ( borderpos[1] + borderframe[1] - fullsize[1] > 0
372  ? borderpos[1] + borderframe[1] - fullsize[1] : 0 );
373  borderdep[2] = ( borderpos[2] + borderframe[2] - fullsize[2] > 0
374  ? borderpos[2] + borderframe[2] - fullsize[2] : 0 );
375  readframe[0] = borderframe[0] - readpos[0] - borderdep[0];
376  readframe[1] = borderframe[1] - readpos[1] - borderdep[1];
377  readframe[2] = borderframe[2] - readpos[2] - borderdep[2];
378  readframe[3] = borderframe[3];
379  rView = soma::Reader<carto::Volume<T> >( rVol.dataSourceInfo() );
380  newoptions = carto::Object::value( carto::PropertySet() );
381  newoptions->setProperty( "partial_reading", true );
382  newoptions->copyProperties( options );
383  rView.setOptions( newoptions );
384  localMsg( "creating volume..." );
385  localMsg( "-> with frame size ( "
386  + carto::toString( readframe[0] ) + ", "
387  + carto::toString( readframe[1] ) + ", "
388  + carto::toString( readframe[2] ) + ", "
389  + carto::toString( readframe[3] ) + " )"
390  );
391  localMsg( "-> with frame pos ( "
392  + carto::toString( readpos[0] ) + ", "
393  + carto::toString( readpos[1] ) + ", "
394  + carto::toString( readpos[2] ) + ", "
395  + carto::toString( readpos[3] ) + " )"
396  );
397  readVolume = carto::VolumeRef<T>(
398  new carto::Volume<T>( bordersVolume, readpos, readframe ) );
399  localMsg( "reading frame..." );
400  rView.read( *readVolume );
401 
402  //=== UNALLOCATED PROCCESSED VOLUME ====================================
403  localMsg( "=== UNALLOCATED PROCCESSED VOLUME" );
404  localMsg( "computing view frame..." );
405  // setting "viewVolume" position / "bordersVolume"
406  viewpos[0] = borders[0];
407  viewpos[1] = borders[1];
408  viewpos[2] = borders[2];
409  viewpos[3] = 0;
410  localMsg( "creating volume..." );
411  localMsg( "-> with frame size ( "
412  + carto::toString( viewframe[0] ) + ", "
413  + carto::toString( viewframe[1] ) + ", "
414  + carto::toString( viewframe[2] ) + ", "
415  + carto::toString( viewframe[3] ) + " )"
416  );
417  localMsg( "-> with frame pos ( "
418  + carto::toString( viewpos[0] ) + ", "
419  + carto::toString( viewpos[1] ) + ", "
420  + carto::toString( viewpos[2] ) + ", "
421  + carto::toString( viewpos[3] ) + " )"
422  );
423  if( obj)
424  *obj = carto::Volume<T>( bordersVolume, viewpos, viewframe );
425  else
426  obj = new carto::Volume<T>( bordersVolume, viewpos, viewframe );
427  localMsg( "copying header..." );
428  obj->blockSignals( true );
429  obj->header().copyProperties( carto::Object::value( readVolume->header() ) );
430  /* copy voxel_size to underlying volume, if any.
431  This should probably be more general, but cannot be applied to all
432  header properties (size, transformations...).
433  WARNING: Moreover here we do not guarantee to keep both voxel_size
434  unique: we point to the same vector of values for now, but it can be
435  replaced (thus, duplicated) by a setProperty().
436  We could use a addBuiltinProperty(), but then the voxel size has to be
437  stored in a fixed location somewhere.
438  */
439  try
440  {
441  carto::Object vs = obj->header().getProperty( "voxel_size" );
442  bordersVolume->header().setProperty( "voxel_size", vs );
443  }
444  catch( ... )
445  { // never mind.
446  }
447  carto::PropertySet & ps = obj->header();
448  ps.setProperty( "sizeX", viewframe[0] );
449  ps.setProperty( "sizeY", viewframe[1] );
450  ps.setProperty( "sizeZ", viewframe[2] );
451  ps.setProperty( "sizeT", viewframe[3] );
452  obj->blockSignals( false );
453  }
454  else
455  {
456  //=== ALLOCATED PROCESSED VOLUME =======================================
457  localMsg( "=== ALLOCATED PROCESSED VOLUME" );
458  rView = soma::Reader<carto::Volume<T> >( rVol.dataSourceInfo() );
459  newoptions = carto::Object::value( carto::PropertySet() );
460  newoptions->setProperty( "partial_reading", true );
461  newoptions->copyProperties( options );
462  rView.setOptions( newoptions );
463  localMsg( "creating volume..." );
464  if( obj )
465  *obj = carto::Volume<T>( fullVolume, viewpos, viewframe );
466  else
467  obj = new carto::Volume<T>( fullVolume, viewpos, viewframe );
468  localMsg( "reading partial volume..." );
469  rView.read( *obj );
470  }
471 
472  return obj;
473  }
474 
475 }
476 
477 #undef localMsg
478 #endif
const carto::rc_ptr< DataSourceInfo > & dataSourceInfo() const
4D Volume main class
virtual bool getProperty(const std::string &key, Object &value) const =0
const AllocatorContext & allocatorContext() const
returns volume's AllocatorContext
Definition: volumebase_d.h:439
Convenient handle for a Volume - this is normally the entry point for all volumes handling...
int verbose
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.
const PropertySet & header() const
void setProperty(const std::string &, const T &)
const carto::Object & header() const
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.
int debugMessageLevel
void setAllocatorContext(const AllocatorContext &ac)
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.
#define localMsg(message)
DataSourceInfo check(DataSourceInfo dsi, carto::Object options=carto::none(), int passbegin=1, int passend=3)
void setOptions(carto::Object options)
#define soma
static Object value()
static std::set< std::string > listReadProperties()
list of properties triggering partial reading and/or borders
virtual bool read(T &obj, carto::Object header=carto::none(), int passbegin=1, int passend=4)
void blockSignals(bool)
const PropertySet & header() const
std::string toString(const T &object)
virtual bool removeProperty(const std::string &)=0
virtual void copyProperties(Object source)