aimsdata 6.0.0
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>
41#include <cartobase/type/string_conversion.h>
42#include <cartobase/exception/ioexcept.h>
43#include <cartobase/stream/fileutil.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
64namespace 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:
86 case carto::AllocatorStrategy::MAP:
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 }
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 {
121 }
122
123 template<class T>
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 );
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 );
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 {
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 {
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 {
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...
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
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 );
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 );
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 {
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 {
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 {
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...
748 filename + " : no matching format" );
749 return( 0 );
750 }
751
752}
753
754
755#undef localMsg
756
757#endif
static FileFormat< T > * fileFormat(const std::string &format)
static const std::map< std::string, std::list< std::string > > & extensions()
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
carto::Object _options
Definition reader.h:113
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
carto::AllocatorStrategy::MappingMode _mode
Definition reader.h:111
carto::AllocatorContext _alloccontext
Definition reader.h:112
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
const std::string & fileName() const
get input file name
Definition reader.h:102
static Settings & settings()
std::string name()
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.
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