aimsdata  5.1.2
Neuroimaging data handling
reader_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 
34 #ifndef AIMS_IO_READER_D_H
35 #define AIMS_IO_READER_D_H
36 
37 #include <aims/io/reader.h>
38 #include <aims/io/fileFormat.h>
39 #include <aims/def/settings.h>
40 #include <aims/io/finder.h>
44 #include <set>
45 #include <soma-io/io/reader.h>
47 
48 #define localMsg( message ) cartoCondMsg( 4, message, "AIMS::READER" )
49 
50 #define AIMS_INSTANTIATE_READER( T ) \
51  namespace aims { \
52  template class aims::Reader< T >; \
53  } \
54  namespace soma { \
55  template class soma::FormatDictionary< T >; \
56  template class soma::Reader< T >; \
57  }
58 #define AIMS_INSTANTIATE_AIMS_READER( T ) \
59  namespace aims { \
60  template class aims::Reader< T >; \
61  }
62 
63 
64 namespace aims
65 {
66 
67  template<class T> Reader<T>::Reader()
68  : _mode( carto::AllocatorStrategy::Memory )
69  {
70  }
71 
72  template<class T> Reader<T>::Reader( const std::string& filename )
73  : _filename( filename ), _mode( carto::AllocatorStrategy::Memory )
74  {
75  }
76 
77 
78  template<class T>
79  void Reader<T>::setMode( carto::AllocatorStrategy::MappingMode mode )
80  {
81  _mode = mode;
82  // compatibility with new AllocatorContext
83  switch( mode )
84  {
85  case carto::AllocatorStrategy::Memory:
87  case carto::AllocatorStrategy::CopyMap:
88  _alloccontext.setAccessMode( carto::AllocatorStrategy::InternalModif );
89  break;
90  case carto::AllocatorStrategy::ReadOnlyMap:
91  _alloccontext.setAccessMode( carto::AllocatorStrategy::ReadOnly );
92  break;
93  case carto::AllocatorStrategy::ReadWriteMap:
94  _alloccontext.setAccessMode( carto::AllocatorStrategy::ReadWrite );
95  break;
96  case carto::AllocatorStrategy::Unallocated:
97  _alloccontext.setAccessMode( carto::AllocatorStrategy::NotOwner );
98  break;
99  default:
100  _alloccontext.setAccessMode( carto::AllocatorStrategy::InternalModif );
101  break;
102  }
103  }
104 
105  template <typename T>
106  void Reader<T>::setAllocatorContext( const carto::AllocatorContext & ac )
107  {
108  _alloccontext = ac;
109  }
110 
111  template <typename T>
112  const carto::AllocatorContext & Reader<T>::allocatorContext() const
113  {
114  return _alloccontext;
115  }
116 
117  template<class T>
118  void Reader<T>::setFileName( const std::string &fileName )
119  {
120  _filename = fileName;
121  }
122 
123  template<class T>
125  {
126  _options = options;
127  }
128 
129  template<class T>
131  {
132  return _options;
133  }
134 
135  template<class T>
137  {
138  return _options;
139  }
140 
141  template<class T>
142  bool Reader<T>::read( T & obj, int border, const std::string* format,
143  int frame )
144  {
145 #ifdef AIMS_DEBUG_IO
146  localMsg("void Reader<" + carto::DataTypeCode<T>::name() + ">::read( obj )");
147 #endif
148 
150 
151  // Copy aims settings to read options
152  read_options->copyProperties(
154  Settings::settings().getValue() ) );
155 
156  // take care of old-style options
157  if( !_options.get() )
159  if( frame >= 0 )
160  {
161  _options->setProperty( "frame", frame );
162  // (for graphs)
163  _options->setProperty( "subobjectsfilter", frame );
164  }
165  if( border > 0 )
166  _options->setProperty( "border", border );
167 
168  std::string _format;
169  if( !format )
170  {
171  try
172  {
173  carto::Object oformat = _options->getProperty( "format" );
174  _format = oformat->getString();
175  format = &_format;
176  }
177  catch( ... )
178  {
179  }
180  }
181  else
182  _options->setProperty( "format", *format );
183 
184  // update read options using reader object options
185  read_options->copyProperties(_options);
186 
187  // try first soma-io reader (since 2013)
188  // try first 3 passes
189  try
190  {
191  // building uri
192  std::string uri = _filename;
193  if( border != 0 || frame != -1 )
194  uri += "?";
195  if( border != 0 )
196  uri += ( "border=" + carto::toString( border ) );
197  if( border != 0 && frame != -1 )
198  uri += "&";
199  if ( frame != -1 )
200  uri += ( "ot=" + carto::toString( frame ) + "&st=1" );
201 
202  soma::Reader<T> reader( uri );
203  // set conversion option to invoque Carto2AimsHeaderTranslator
204  carto::Object options = read_options;
205  if( options.isNull() )
207  options->setProperty( "convert_to_aims", true );
208  reader.setOptions( options );
209  reader.setAllocatorContext( allocatorContext() );
210  const carto::Object & n = carto::none();
211 #ifdef AIMS_DEBUG_IO
212  localMsg("0. Try soma::Reader ...") ;
213 #endif
214  return reader.read( obj, n, 1, 3 );
215  }
216 #ifdef AIMS_DEBUG_IO
217  catch( std::exception & e )
218  {
219  localMsg("0. soma::Reader failed: " + carto::toString(e.what()));
220  }
221 #else
222  catch( ... ) {}
223 #endif
224 
225  // if it failed, continue with aims reader.
226 
227  std::set<std::string> tried;
228  std::set<FileFormat<T> *> triedf;
229  FileFormat<T> *reader;
230  std::set<std::string>::iterator notyet = tried.end();
231  typename std::set<FileFormat<T> *>::iterator notyetf = triedf.end();
232  int excp = 0;
233  int exct = -1;
234  std::string excm;
235 
236  // parse/split query-string part or URI
237  std::string filename = carto::FileUtil::uriFilename( _filename );
238  carto::Object uri_opt = carto::FileUtil::uriOptions( _filename );
239  if( uri_opt )
240  {
241  if( read_options.isNull() )
242  read_options = carto::Object::value( carto::Dictionary() );
243  read_options->copyProperties( uri_opt );
244  }
245 
246  if( format ) // priority to format hint
247  {
248  reader = FileFormatDictionary<T>::fileFormat( *format );
249  if( reader )
250  {
251  try
252  {
253 #ifdef AIMS_DEBUG_IO
254  localMsg("1. try reader " + *format);
255 #endif
256  if( reader->read( filename, obj, _alloccontext, read_options ) )
257  {
258 #ifdef AIMS_DEBUG_IO
259  localMsg("1. " + *format + " OK");
260 #endif
262  if( h )
264  return true;
265  }
266  }
267  catch( std::exception & e )
268  {
269 #ifdef AIMS_DEBUG_IO
270  localMsg("1. failed: " + carto::toString(e.what()));
271 #endif
272  carto::io_error::keepExceptionPriority( e, excp, exct, excm,
273  5 );
274  }
275  tried.insert( *format );
276  triedf.insert( reader );
277  }
278  }
279 
280  std::string bname = carto::FileUtil::basename( filename );
281  std::string::size_type pos = bname.find( '.' );
282  std::string::size_type dlen = filename.length() - bname.length();
283  std::string ext;
284 
285  if( pos != std::string::npos )
286  ext = filename.substr( dlen+pos+1, filename.length() - pos - 1 );
287 
288  const std::map<std::string, std::list<std::string> > & extensions
290 
291  std::map<std::string, std::list<std::string> >::const_iterator iext
292  = extensions.find( ext ),
293  eext = extensions.end();
294  std::list<std::string>::const_iterator ie, ee;
295 
296  while( iext == eext && (pos=bname.find( '.', pos+1 ))!=std::string::npos )
297  {
298  ext = filename.substr( dlen+pos+1, filename.length() - pos - 1 );
299  iext = extensions.find( ext );
300  }
301 
302  // try every matching format until one works
303  if( iext != eext )
304  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
305  if( tried.find( *ie ) == notyet )
306  {
307  reader = FileFormatDictionary<T>::fileFormat( *ie );
308  if( reader && triedf.find( reader ) == notyetf )
309  {
310  try
311  {
312 #ifdef AIMS_DEBUG_IO
313  localMsg("2. try reader " + *ie);
314 #endif
315  if( reader->read( filename, obj, _alloccontext, read_options ) )
316  {
317 #ifdef AIMS_DEBUG_IO
318  localMsg("2. " + *ie + " OK");
319 #endif
321  if( h )
323  return true;
324  }
325  }
326  catch( std::exception & e )
327  {
328 #ifdef AIMS_DEBUG_IO
329  localMsg("2. failed: " + carto::toString(e.what()));
330 #endif
332  excm );
333  }
334 #ifdef AIMS_DEBUG_IO
335  localMsg("2. unsuccessfully tried " + *ie);
336 #endif
337  tried.insert( *ie );
338  triedf.insert( reader );
339  }
340  }
341 
342  if( !ext.empty() )
343  {
344  // not found or none works: try readers with no extension
345  iext = extensions.find( "" );
346 
347  if( iext != eext )
348  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
349  if( tried.find( *ie ) == notyet )
350  {
351  reader = FileFormatDictionary<T>::fileFormat( *ie );
352  if( reader && triedf.find( reader ) == notyetf )
353  {
354  try
355  {
356 #ifdef AIMS_DEBUG_IO
357  localMsg("3. try reader " + *ie);
358 #endif
359  if( reader->read( filename, obj, _alloccontext, read_options ) )
360  {
361 #ifdef AIMS_DEBUG_IO
362  localMsg("3. " + *ie + " OK");
363 #endif
365  if( h )
367  return true;
368  }
369  }
370  catch( std::exception & e )
371  {
372 #ifdef AIMS_DEBUG_IO
373  localMsg("3. failed: " + carto::toString(e.what()));
374 #endif
376  excm );
377  }
378  tried.insert( *ie );
379  triedf.insert( reader );
380  }
381  }
382  }
383 
384  // still not found ? well, try EVERY format this time...
385  for( iext=extensions.begin(); iext!=eext; ++iext )
386  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
387  if( tried.find( *ie ) == notyet )
388  {
389  reader = FileFormatDictionary<T>::fileFormat( *ie );
390  if( reader && triedf.find( reader ) == notyetf )
391  {
392  try
393  {
394 #ifdef AIMS_DEBUG_IO
395  localMsg("4. try reader " + *ie);
396 #endif
397  if( reader->read( filename, obj, _alloccontext, read_options ) )
398  {
399 #ifdef AIMS_DEBUG_IO
400  localMsg("4. " + *ie + " OK");
401 #endif
403  if( h )
405  return true;
406  }
407  }
408  catch( std::exception & e )
409  {
410 #ifdef AIMS_DEBUG_IO
411  localMsg("4. failed: " + carto::toString(e.what()));
412 #endif
414  excm );
415  }
416  tried.insert( *ie );
417  triedf.insert( reader );
418  }
419  }
420 
421  // try first soma-io reader (since 2013)
422  // try pass 4
423  try
424  {
425  // building uri
426  std::string uri = filename;
427  if( border != 0 || frame != -1 )
428  uri += "?";
429  if( border != 0 )
430  uri += ( "border=" + carto::toString( border ) );
431  if( border != 0 && frame != -1 )
432  uri += "&";
433  if ( frame != -1 )
434  uri += ( "ot=" + carto::toString( frame ) + "&st=1" );
435 
436  soma::Reader<T> reader( uri );
437  reader.setOptions( read_options );
438  const carto::Object & n = carto::none();
439  return reader.read( obj, n, 4, 4 );
440  } catch( ... ) {}
441  // if it failed, it's hopeless.
442 
443  // still not succeeded, it's hopeless...
444  carto::io_error::launchExcept( exct, excm,
445  filename + " : no matching format" );
446  return( false );
447  }
448 
449 
450  template<class T>
451  T* Reader<T>::read( int border, const std::string* format, int frame )
452  {
453 #ifdef AIMS_DEBUG_IO
454  localMsg(carto::DataTypeCode<T>::name() + "* Reader<"
455  + carto::DataTypeCode<T>::name() + ">::read()");
456 #endif
457 
459 
460  // Copy aims settings to read options
461  read_options->copyProperties(
463  Settings::settings().getValue() ) );
464 
465  // take care of old-style options
466  if( !_options.get() )
468  if( frame >= 0 )
469  {
470  _options->setProperty( "frame", frame );
471  // (for graphs)
472  _options->setProperty( "subobjectsfilter", frame );
473  }
474  if( border > 0 )
475  _options->setProperty( "border", border );
476 
477  std::string _format;
478  if( !format )
479  {
480  try
481  {
482  carto::Object oformat = _options->getProperty( "format" );
483  _format = oformat->getString();
484  format = &_format;
485  }
486  catch( ... )
487  {
488  }
489  }
490  else
491  _options->setProperty( "format", *format );
492 
493  // update read options using reader object options
494  read_options->copyProperties(_options);
495 
496  // try first soma-io reader (since 2013)
497  // try first 3 passes
498  try
499  {
500  // building uri
501  std::string uri = _filename;
502  if( border != 0 || frame != -1 )
503  uri += "?";
504  if( border != 0 )
505  uri += ( "border=" + carto::toString( border ) );
506  if( border != 0 && frame != -1 )
507  uri += "&";
508  if ( frame != -1 )
509  uri += ( "ot=" + carto::toString( frame ) + "&st=1" );
510 
511 #ifdef AIMS_DEBUG_IO
512  localMsg("building soma::Reader using uri: " + uri);
513 #endif
514  soma::Reader<T> reader( uri );
515  // set conversion option to invoque Carto2AimsHeaderTranslator
516  carto::Object options = read_options;
517  if( options.isNull() )
519  options->setProperty( "convert_to_aims", true );
520  reader.setOptions( options );
521  reader.setAllocatorContext( allocatorContext() );
522 #ifdef AIMS_DEBUG_IO
523  localMsg("0. Try soma::Reader ...");
524 #endif
525  return reader.read( carto::none(), 1, 3 );
526  }
527 #ifdef AIMS_DEBUG_IO
528  catch( std::exception & e )
529  {
530  localMsg("0. soma::Reader failed: " + carto::toString(e.what()));
531  }
532 #else
533  catch( ... ) {}
534 #endif
535 
536  // if it failed, continue with aims reader.
537 
538  std::set<std::string> tried;
539  std::set<FileFormat<T> *> triedf;
540  FileFormat<T> *reader;
541  std::set<std::string>::iterator notyet = tried.end();
542  typename std::set<FileFormat<T> *>::iterator notyetf = triedf.end();
543  T *obj;
544  int excp = 0;
545  int exct = -1;
546  std::string excm;
547 
548  // parse/split query-string part or URI
549  std::string filename = carto::FileUtil::uriFilename( _filename );
550  carto::Object uri_opt = carto::FileUtil::uriOptions( _filename );
551  if( uri_opt )
552  {
553  if( read_options.isNull() )
554  read_options = carto::Object::value( carto::Dictionary() );
555  read_options->copyProperties( uri_opt );
556  }
557 
558  if( format ) // priority to format hint
559  {
560  reader = FileFormatDictionary<T>::fileFormat( *format );
561  if( reader )
562  {
563  try
564  {
565 #ifdef AIMS_DEBUG_IO
566  localMsg("1. try reader " + *format);
567 #endif
568  obj = reader->read( filename, _alloccontext, read_options );
569  if( obj )
570  {
571 #ifdef AIMS_DEBUG_IO
572  localMsg("1. " + *format + " OK");
573 #endif
575  if( h )
577  return( obj );
578  }
579  }
580  catch( std::exception & e )
581  {
582 #ifdef AIMS_DEBUG_IO
583  localMsg("1. failed: " + carto::toString(e.what()));
584 #endif
585  carto::io_error::keepExceptionPriority( e, excp, exct, excm,
586  5 );
587  }
588  tried.insert( *format );
589  triedf.insert( reader );
590  }
591  }
592 
593  std::string ext = carto::FileUtil::extension( filename );
594 
595  const std::map<std::string, std::list<std::string> > & extensions
597 
598  std::map<std::string, std::list<std::string> >::const_iterator iext
599  = extensions.find( ext ),
600  eext = extensions.end();
601  std::list<std::string>::const_iterator ie, ee;
602 
603  // try every matching format until one works
604  if( iext != eext )
605  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
606  if( tried.find( *ie ) == notyet )
607  {
608  reader = FileFormatDictionary<T>::fileFormat( *ie );
609  if( reader && triedf.find( reader ) == notyetf )
610  {
611  try
612  {
613 #ifdef AIMS_DEBUG_IO
614  localMsg("2. try reader " + *ie);
615 #endif
616  obj = reader->read( filename, _alloccontext, read_options );
617  if( obj )
618  {
619 #ifdef AIMS_DEBUG_IO
620  localMsg("2. " + *ie + " OK");
621 #endif
623  if( h )
625  return( obj );
626  }
627  }
628  catch( std::exception & e )
629  {
630 #ifdef AIMS_DEBUG_IO
631  localMsg("2. failed: " + carto::toString(e.what()));
632 #endif
634  excm );
635  }
636 #ifdef AIMS_DEBUG_IO
637  localMsg("2. unsuccessfully tried " + *ie);
638 #endif
639  tried.insert( *ie );
640  triedf.insert( reader );
641  }
642  }
643 
644  if( !ext.empty() )
645  {
646  // not found or none works: try readers with no extension
647  iext = extensions.find( "" );
648 
649  if( iext != eext )
650  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
651  if( tried.find( *ie ) == notyet )
652  {
653  reader = FileFormatDictionary<T>::fileFormat( *ie );
654  if( reader && triedf.find( reader ) == notyetf )
655  {
656  try
657  {
658 #ifdef AIMS_DEBUG_IO
659  localMsg("3. try reader " + *ie);
660 #endif
661  obj = reader->read( filename, _alloccontext, read_options );
662  if( obj )
663  {
664 #ifdef AIMS_DEBUG_IO
665  localMsg("3. " + *ie + " OK");
666 #endif
668  if( h )
670  return( obj );
671  }
672  }
673  catch( std::exception & e )
674  {
675 #ifdef AIMS_DEBUG_IO
676  localMsg("3. failed: " + carto::toString(e.what()));
677 #endif
679  excm );
680  }
681  tried.insert( *ie );
682  triedf.insert( reader );
683  }
684  }
685  }
686 
687  // still not found ? well, try EVERY format this time...
688  for( iext=extensions.begin(); iext!=eext; ++iext )
689  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
690  if( tried.find( *ie ) == notyet )
691  {
692  reader = FileFormatDictionary<T>::fileFormat( *ie );
693  if( reader && triedf.find( reader ) == notyetf )
694  {
695  try
696  {
697 #ifdef AIMS_DEBUG_IO
698  localMsg("4. try reader " + *ie);
699 #endif
700  obj = reader->read( filename, _alloccontext, read_options );
701  if( obj )
702  {
703 #ifdef AIMS_DEBUG_IO
704  localMsg("4. " + *ie + " OK");
705 #endif
707  if( h )
709  return( obj );
710  }
711  }
712  catch( std::exception & e )
713  {
714 #ifdef AIMS_DEBUG_IO
715  localMsg("4. failed: " + carto::toString(e.what()));
716 #endif
718  excm );
719  }
720  tried.insert( *ie );
721  triedf.insert( reader );
722  }
723  }
724 
725  // try first soma-io reader (since 2013)
726  // try pass 4
727  try
728  {
729  // building uri
730  std::string uri = filename;
731  if( border != 0 || frame != -1 )
732  uri += "?";
733  if( border != 0 )
734  uri += ( "border=" + carto::toString( border ) );
735  if( border != 0 && frame != -1 )
736  uri += "&";
737  if ( frame != -1 )
738  uri += ( "ot=" + carto::toString( frame ) + "&st=1" );
739 
740  soma::Reader<T> reader( uri );
741  reader.setOptions( read_options );
742  return reader.read( carto::none(), 4, 4 );
743  } catch( ... ) {}
744  // if it failed, it's hopeless
745 
746  // still not succeeded, it's hopeless...
747  carto::io_error::launchExcept( exct, excm,
748  filename + " : no matching format" );
749  return( 0 );
750  }
751 
752 }
753 
754 
755 #undef localMsg
756 
757 #endif
const carto::AllocatorStrategy::MappingMode MAP
Definition: allocator.h:46
static FileFormat< T > * fileFormat(const std::string &format)
Definition: fileFormat_d.h:199
static const std::map< std::string, std::list< std::string > > & extensions()
Definition: fileFormat_d.h:105
Low-level object IO format: each specific format has such a reader / writer.
Definition: fileFormat.h:62
virtual bool read(const std::string &filename, T &obj, const carto::AllocatorContext &context, carto::Object options)=0
static void postProcessHeader(carto::Object hdr)
carto::Object options() const
Definition: reader_d.h:130
void setAllocatorContext(const carto::AllocatorContext &ac)
allocator control (not used by every format yet)
Definition: reader_d.h:106
virtual bool read(T &obj, int border=0, const std::string *format=0, int frame=-1)
Finds the correct format and reads the object. if format is specified, this format is tried first,...
Definition: reader_d.h:142
const carto::AllocatorContext & allocatorContext() const
Definition: reader_d.h:112
void setFileName(const std::string &fileName)
set input file name
Definition: reader_d.h:118
void setOptions(carto::Object options)
Definition: reader_d.h:124
void setMode(carto::AllocatorStrategy::MappingMode mode)
set input file mode - soon obsolete
Definition: reader_d.h:79
static Settings & settings()
static std::string basename(const std::string &)
static std::string extension(const std::string &)
static std::string uriFilename(const std::string &filein)
static Object uriOptions(const std::string &filein)
Object reference(Object &value)
static Object value()
bool isNull() const
static void keepExceptionPriority(std::exception &e, int &prio, int &type, std::string &message, int raiseprio=0)
static void launchExcept(int code, const std::string &msg, const std::string &defmsg="")
void setAllocatorContext(const AllocatorContext &ac)
virtual bool read(T &obj, carto::Object header=carto::none(), int passbegin=1, int passend=4)
void setOptions(carto::Object options)
The class for EcatSino data write operation.
Definition: borderfiller.h:13
std::string toString(const T &object)
carto::Object getObjectHeader(Headered &h)
std::map< std::string, Object > Dictionary
Object none()
#define localMsg(message)
Definition: reader_d.h:48