aimsdata 6.0.16
Neuroimaging data handling
giftimeshformat_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_GIFTIMESHFORMAT_D_H
35#define AIMS_IO_GIFTIMESHFORMAT_D_H
36
37#include <aims/io/giftiformat.h>
38#include <aims/io/giftiheader.h>
39#include <aims/io/giftiutil.h>
40#include <aims/io/process.h>
41#include <aims/io/finder.h>
42#include <aims/io/writer.h>
43#include <aims/io/reader.h>
44#include <cartobase/thread/mutex.h>
45#include <aims/io/gifti.h>
46#include <locale.h>
47
48namespace aims
49{
50
51 namespace
52 {
53 template<int D, typename T>
54 void giftiReadTexture(AimsTimeSurface<D, T> & vol, int texnum,
55 giiDataArray *da, GiftiHeader & hdr)
56 {
57 int vnum = da->dims[0];
58 int j;
59 std::vector<T> & tex = vol[texnum].texture();
60 tex.clear();
61 tex.reserve(vnum);
62 for (j = 0; j < vnum; ++j)
63 {
64 tex.push_back(convertedNiftiValue<T> (da->data, j, da->datatype));
65 }
66 }
67
68 class GiftiReadExternalTexture: public Process
69 {
70 public:
71 GiftiReadExternalTexture( carto::Object textures, giiDataArray* da,
72 int nt, int nts) :
73 Process(), textures(textures), da(da), nt(nt), nts(nts)
74 {
75 }
76
77 carto::Object textures;
78 giiDataArray *da;
79 int nt;
80 int nts;
81 };
82
83 template<typename T>
84 bool giftiReadExternalTexture(Process & p, const std::string &, Finder &)
85 {
86 GiftiReadExternalTexture & gp
87 = static_cast<GiftiReadExternalTexture &> (p);
88 giiDataArray *da = gp.da;
89 int j, vnum = da->dims[0], nt = gp.nt;
90 carto::Object textures = gp.textures;
91 carto::Object o;
92 if ((int) textures->size() > nt)
93 o = textures->getArrayItem(nt);
94 else
95 {
96 o = carto::Object::value(TimeTexture<T> ());
97 textures->insertArrayItem(-1, o);
98 }
99 TimeTexture<T> & ttex
100 = o->carto::GenericObject::value<TimeTexture<T> >();
101 ttex[ttex.size()]; // force inserting a new timepoint
102 std::vector<T> & tex = ttex[ttex.size() - 1].data();
103 tex.reserve(vnum);
104 for (j = 0; j < vnum; ++j)
105 {
106 tex.push_back(convertedNiftiValue<T> (da->data, j, da->datatype));
107 }
108
109 return true;
110 }
111
112 template<int D>
113 void giftiReadTexture(AimsTimeSurface<D, Void> & /*vol*/, int /*texnum*/,
114 giiDataArray *da, GiftiHeader & hdr, int nts)
115 {
116 carto::Object textures;
117 try
118 {
119 textures = hdr.getProperty("textures");
120 }
121 catch (...)
122 {
124 }
125 // get data type
126 int ndim = da->num_dim;
127 int nt = 1;
128 std::string dtype = giftiTextureDataType(da->datatype, ndim, da->dims,
129 da->intent, nt);
130 // std::cout << "reading texture of: " << dtype << std::endl;
131
132 GiftiReadExternalTexture p(textures, da, nt, nts);
133 p.registerProcessType("Texture", "FLOAT",
134 &giftiReadExternalTexture<float> );
135 p.registerProcessType("Texture", "POINT2DF",
136 &giftiReadExternalTexture<Point2df> );
137 p.registerProcessType("Texture", "S16",
138 &giftiReadExternalTexture<int16_t> );
139 p.registerProcessType("Texture", "S32",
140 &giftiReadExternalTexture<int32_t> );
141 p.registerProcessType("Texture", "U32",
142 &giftiReadExternalTexture<uint32_t> );
143 p.registerProcessType("Texture", "VECTOR_OF_2_S16",
144 &giftiReadExternalTexture<Point2d> );
145 // TODO: etc for other types...
146 Finder f;
147 f.setObjectType("Texture");
148 f.setDataType(dtype);
149 if (p.execute(f, ""))
150 {
151 hdr.setProperty("textures", textures);
152 }
153 }
154
155 } // unknown namespace
156
157 template<int D, typename T>
158 bool GiftiMeshFormat<D, T>::read(const std::string & filename, AimsTimeSurface<
159 D, T> & vol, const carto::AllocatorContext & /*context*/,
161 {
162 setlocale( LC_NUMERIC, "C" );
163 GiftiHeader hdr(filename);
164
166
167 if (!hdr.read())
169
171 gifti_image *gim = gifti_read_image(hdr.name().c_str(), 1);
173
174 if (!gim)
175 {
176 throw carto::format_error("could not re-read GIFTI file", hdr.name());
177 }
178
179 int nda = gim->numDA, i;
180 int tmesh = -1, ttex = -1, tnorm = -1, tpoly = -1, nts = 0;
181 for (i = 0; i < nda; ++i)
182 {
183 giiDataArray *da = gim->darray[i];
184 if( !da )
185 {
186 gifti_free_image(gim);
187 throw carto::parse_error( "no data arrays", "", hdr.name(), 0 );
188 }
189 switch (da->intent)
190 {
191 case NIFTI_INTENT_POINTSET:
192 {
193 ++tmesh;
194 char *ts = gifti_get_meta_value(&da->meta, "Timestep");
195 if (ts)
196 sscanf(ts, "%d", &tmesh);
197 int vnum = da->dims[0];
198 int j;
199
200#ifdef AIMS_DEBUG_IO
201 if (da->ind_ord == GIFTI_IND_ORD_UNDEF)
202 std::cout << "GIFTI_IND_ORD_UNDEF" << std::endl;
203
204 if (da->ind_ord == GIFTI_IND_ORD_ROW_MAJOR)
205 std::cout << "GIFTI_IND_ORD_ROW_MAJOR" << std::endl;
206
207 if (da->ind_ord == GIFTI_IND_ORD_COL_MAJOR)
208 std::cout << "GIFTI_IND_ORD_COL_MAJOR " << vnum << std::endl;
209#endif
210
211 std::vector<Point3df> & vert = vol[tmesh].vertex();
212 vert.clear();
213 vert.reserve(vnum);
214
215 if (da->ind_ord == GIFTI_IND_ORD_ROW_MAJOR || da->ind_ord == GIFTI_IND_ORD_UNDEF)
216 for (j = 0; j < vnum; ++j)
217 vert.push_back(Point3df(
218 convertedNiftiValue<float> (da->data, j* 3, da->datatype),
219 convertedNiftiValue<float> (da->data, j * 3 + 1, da->datatype),
220 convertedNiftiValue<float> (da->data, j * 3 + 2,da->datatype)));
221
222 if (da->ind_ord == GIFTI_IND_ORD_COL_MAJOR)
223 for (j = 0; j < vnum; ++j)
224 vert.push_back(Point3df(
225 convertedNiftiValue<float> (da->data, j , da->datatype),
226 convertedNiftiValue<float> (da->data, j + vnum, da->datatype),
227 convertedNiftiValue<float> (da->data, j + 2*vnum, da->datatype)));
228}
229 break;
230 case NIFTI_INTENT_VECTOR:
231 {
232 ++tnorm;
233 char *ts = gifti_get_meta_value(&da->meta, "Timestep");
234 if (ts)
235 sscanf(ts, "%d", &tnorm);
236 else if (tnorm < tmesh)
237 tnorm = tmesh;
238 int vnum = da->dims[0];
239 int j;
240 std::vector<Point3df> & norm = vol[tnorm].normal();
241 norm.clear();
242 norm.reserve(vnum);
243
244 if (da->ind_ord == GIFTI_IND_ORD_ROW_MAJOR || da->ind_ord == GIFTI_IND_ORD_UNDEF)
245 for (j = 0; j < vnum; ++j)
246 norm.push_back(Point3df(
247 convertedNiftiValue<float> (da->data, j * 3, da->datatype),
248 convertedNiftiValue<float> (da->data, j * 3 + 1, da->datatype),
249 convertedNiftiValue<float> (da->data, j * 3 + 2, da->datatype)));
250
251 if (da->ind_ord == GIFTI_IND_ORD_COL_MAJOR)
252 for (j = 0; j < vnum; ++j)
253 norm.push_back(Point3df(
254 convertedNiftiValue<float> (da->data, j , da->datatype),
255 convertedNiftiValue<float> (da->data, j + vnum, da->datatype),
256 convertedNiftiValue<float> (da->data, j + 2*vnum, da->datatype)));
257
258 break;
259 }
260 case NIFTI_INTENT_TRIANGLE:
261 {
262 ++tpoly;
263 char *ts = gifti_get_meta_value(&da->meta, "Timestep");
264 if (ts)
265 sscanf(ts, "%d", &tpoly);
266 else if (tpoly < tmesh)
267 tpoly = tmesh;
268 int vnum = da->dims[0];
269 int j, k;
270 std::vector<AimsVector<unsigned, D> > & poly = vol[tpoly].polygon();
271 poly.clear();
272 poly.reserve(vnum);
273 if( !da->data )
274 {
275 gifti_free_image( gim );
276 throw carto::parse_error( "no data array", "", hdr.name(), 0 );
277 }
278
279 if (da->ind_ord == GIFTI_IND_ORD_ROW_MAJOR || da->ind_ord == GIFTI_IND_ORD_UNDEF)
280 for (j = 0; j < vnum; ++j)
281 {
282 poly.push_back(AimsVector<unsigned, D> ());
283 AimsVector<unsigned, D> &p = poly[j];
284 for (k = 0; k < D; ++k)
285 p[k] = convertedNiftiValue<unsigned> (da->data, j * D + k,
286 da->datatype);
287 }
288
289 if (da->ind_ord == GIFTI_IND_ORD_COL_MAJOR)
290 for (j = 0; j < vnum; ++j)
291 {
292 poly.push_back(AimsVector<unsigned, D> ());
293 AimsVector<unsigned, D> &p = poly[j];
294 for (k = 0; k < D; ++k)
295 p[k] = convertedNiftiValue<unsigned> (da->data, j + k*vnum, da->datatype);
296 }
297 break;
298 }
299 case NIFTI_INTENT_TIME_SERIES:
300 if (nts == 0)
301 ++ttex;
302 giftiReadTexture(vol, ttex, da, hdr, nts);
303 ++nts;
304 break;
305 default:
306 {
307 // texture
308 ++ttex;
309 nts = 0;
310 giftiReadTexture(vol, ttex, da, hdr, 0);
311 }
312 }
313 }
314
315 ++tmesh;
316 ++tnorm;
317 ++tpoly;
318 ++ttex;
319 if (tmesh > tpoly)
320 tmesh = tpoly;
321 /* if( vol.size() > (unsigned) tmesh )
322 {
323 std::cout << "warning: some incomplete meshes; truncating "
324 << vol.size() << " instead of " << tmesh << "elements" << std::endl;
325 while( vol.size() > (unsigned) tmesh )
326 static_cast<std::map<int,AimsSurface<D,T> > &>(vol).erase(
327 (int) vol.size() - 1 );
328 }*/
329 // verify polygons are all in the vertices range
330 bool broken = false;
331 typename AimsTimeSurface<D, T>::iterator im, em = vol.end();
332 for( im=vol.begin(); im!=em; ++im )
333 {
334 i = im->first;
335 AimsSurface<D, T> & surf = im->second;
336 std::vector<Point3df> & vert = surf.vertex();
337 std::vector<AimsVector<uint, D> > & poly = surf.polygon();
338 typename std::vector<AimsVector<uint, D> >::iterator ip;
339 unsigned nvertex = vert.size();
340 for (ip = poly.begin(); ip != poly.end(); ++ip)
341 {
342 AimsVector<uint, D> & pol = *ip;
343 for (int j = 0; j < D; ++j)
344 if (pol[j] >= nvertex)
345 {
346 if (!broken)
347 {
348 broken = true;
349 std::cerr << "Broken mesh: polygon pointing to a "
350 << "vertex out of range" << std::endl;
351 // std::cout << pol[j] << " / " << nvertex << std::endl;
352 }
353 poly.erase(ip);
354 --ip;
355 break;
356 }
357 }
358
359 if (surf.normal().size() != vert.size())
360 surf.updateNormals();
361 }
362
363 vol.setHeader(hdr);
364 gifti_free_image(gim);
365
366 // std::cout << "gifti mesh read OK\n";
367 return true;
368 }
369
370 template<int D, typename T>
371 bool GiftiMeshFormat<D, T>::write(const std::string & filename,
372 const AimsTimeSurface<D, T> & thing, carto::Object )
373 {
374 // std::cout << "gifti mesh write\n";
375 setlocale( LC_NUMERIC, "C" );
376 try
377 {
378 const PythonHeader & thdr = thing.header();
379 GiftiHeader hdr(filename);
380 hdr.copy(thdr);
381
382 if (hdr.hasProperty("nb_t_pos"))
383 hdr.removeProperty("nb_t_pos");
384 gifti_image *gim = hdr.giftiImageBase();
385 std::string fname = hdr.name();
386
387 int hdrmeshda = 0, hdrnormda = 0, hdrpolyda = 0, hdrtexda = 0;
388
389 bool normal = false;
390 int encoding = 2;
391
392 carto::Object da_info;
393 try
394 {
395 da_info = thdr.getProperty("GIFTI_dataarrays_info");
396
397 carto::Object it = da_info->objectIterator();
398 for (; it->isValid(); it->next())
399 {
400 carto::Object el = it->currentValue();
401 if (el->getProperty("encoding", encoding))
402 break;
403 }
404
405 }
406 catch (...)
407 {
408 //std::cout << "error GIFTI_dataarrays_info\n";
409 }
410
411 if (!options().isNull())
412 {
413 hdr.setOptions(options());
414 try
415 {
416 carto::Object n = options()->getProperty("normal");
417 normal = (bool) n->getScalar();
418 carto::Object a = options()->getProperty("encoding");
419 if ((int) a->getScalar() != 0)
420 {
421 encoding = (int) a->getScalar();
422 }
423
424 }
425 catch( ... )
426 {
427 }
428 }
429
430 int nda = 0, t = 0;
431 typename AimsTimeSurface<D, T>::const_iterator is, es=thing.end();
432
433 for( is=thing.begin(); is!=es; ++is, ++t )
434 {
435 const AimsSurface<D, T> & surf = is->second;
436 // write vertices
437 {
438 const std::vector<Point3df> & vert = surf.vertex();
439 nda = gim->numDA;
440 gifti_add_empty_darray( gim, 1 );
441 giiDataArray * da = gim->darray[nda];
442 gifti_set_DA_defaults( da );
443 da->intent = NIFTI_INTENT_POINTSET;
444 da->datatype = NIFTI_TYPE_FLOAT32;
445 da->num_dim = 2;
446 da->dims[0] = vert.size();
447 da->dims[1] = 3;
448 da->dims[2] = 0;
449 da->dims[3] = 0;
450 da->dims[4] = 0;
451 da->dims[5] = 0;
452 da->nvals = vert.size() * 3;
453 da->nbyper = 4;
454
455 da->encoding = encoding;
456 //GIFTI_ENCODING_ASCII 1 /* human readable ASCII data */
457 //GIFTI_ENCODING_B64BIN 2 /* base64 encoded binary data */
458 //GIFTI_ENCODING_B64GZ 3 /* base64 compressed binary */
459
460 gifti_alloc_DA_data( gim, &nda, 1 );
461 unsigned i, n = vert.size();
462
463 float *buf = reinterpret_cast<float *>( da->data );
464 for( i=0; i<n; ++i )
465 {
466 buf[i*3] = vert[i][0];
467 buf[i*3+1] = vert[i][1];
468 buf[i*3+2] = vert[i][2];
469 }
470
471 if( t != is->first )
472 {
473 // store timestep
474 std::ostringstream ts;
475 ts << is->first;
476 gifti_add_to_meta( &da->meta, "Timestep", ts.str().c_str(), 1 );
477 }
478
479 //TO DO : write that BV is in left hand referential
480 // gifti_add_empty_CS (da);
481 //
482 // giiCoordSystem * csnew = da->coordsys[da->numCS-1];
483 // int r, c;
484 //
485 // csnew->dataspace = gifti_strdup("Brainvisa Referential");
486 // csnew->xformspace = gifti_strdup("indirect reference");
487 //
488 // for( r = 0; r < 4; r++ )
489 // for( c = 0; c < 4; c++ )
490 // csnew->xform[r][c] = 0;
491 //
492 // csnew->xform[0][0] = -1;
493 // csnew->xform[1][1] = 1;
494 // csnew->xform[2][2] = 1;
495 // csnew->xform[3][3] = 1;
496
497 // transormations
498 hdr.giftiSetTransformations( carto::Object::reference( thdr ), da );
499
500 // metadata
501 carto::Object dainf
502 = GiftiHeader::giftiFindHdrDA( hdrmeshda, da_info,
503 "NIFTI_INTENT_POINTSET" );
504 if( !dainf.isNone() )
505 {
506 ++hdrmeshda;
507 GiftiHeader::giftiCopyMetaToGii( dainf, da );
508 }
509 }
510
511 // write normals
512 if (normal)
513 {
514 const std::vector<Point3df> & norm = surf.normal();
515 if( !norm.empty() )
516 {
517 nda = gim->numDA;
518 gifti_add_empty_darray( gim, 1 );
519 giiDataArray * da = gim->darray[nda];
520 gifti_set_DA_defaults( da );
521 da->intent = NIFTI_INTENT_VECTOR;
522 da->datatype = NIFTI_TYPE_FLOAT32;
523 da->num_dim = 2;
524 da->dims[0] = norm.size();
525 da->dims[1] = 3;
526 da->dims[2] = 0;
527 da->dims[3] = 0;
528 da->dims[4] = 0;
529 da->dims[5] = 0;
530 da->nvals = norm.size() * 3;
531 da->nbyper = 4;
532
533 da->encoding = encoding;
534
535 gifti_alloc_DA_data( gim, &nda, 1 );
536 unsigned i, n = norm.size();
537 float *buf = reinterpret_cast<float *>( da->data );
538 for( i=0; i<n; ++i )
539 {
540 buf[i*3] = norm[i][0];
541 buf[i*3+1] = norm[i][1];
542 buf[i*3+2] = norm[i][2];
543 }
544
545 if( t != is->first )
546 {
547 // store timestep
548 std::ostringstream ts;
549 ts << is->first;
550 gifti_add_to_meta( &da->meta, "Timestep", ts.str().c_str(), 1 );
551 }
552
553 // metadata
554 carto::Object dainf
555 = GiftiHeader::giftiFindHdrDA( hdrnormda, da_info,
556 "NIFTI_INTENT_VECTOR" );
557 if( !dainf.isNone() )
558 {
559 ++hdrnormda;
560 GiftiHeader::giftiCopyMetaToGii( dainf, da );
561 }
562 }
563 }
564
565 // write polygons
566 {
567 const std::vector<AimsVector<unsigned, D> > & poly
568 = surf.polygon();
569 nda = gim->numDA;
570 gifti_add_empty_darray( gim, 1 );
571 giiDataArray * da = gim->darray[nda];
572 gifti_set_DA_defaults( da );
573 da->intent = NIFTI_INTENT_TRIANGLE;
574 da->datatype = NIFTI_TYPE_INT32;
575 da->num_dim = 2;
576 da->dims[0] = poly.size();
577 da->dims[1] = D;
578 da->dims[2] = 0;
579 da->dims[3] = 0;
580 da->dims[4] = 0;
581 da->dims[5] = 0;
582 da->nvals = poly.size() * D;
583 da->nbyper = 4;
584
585 da->encoding = encoding;
586
587 gifti_alloc_DA_data( gim, &nda, 1 );
588 unsigned i, j, n = poly.size();
589 int *buf = reinterpret_cast<int *>( da->data );
590 for( i=0; i<n; ++i )
591 for( j=0; j<D; ++j )
592 buf[i*D+j] = poly[i][j];
593
594 if( t != is->first )
595 {
596 // store timestep
597 std::ostringstream ts;
598 ts << is->first;
599 gifti_add_to_meta( &da->meta, "Timestep", ts.str().c_str(), 1 );
600 }
601
602 // metadata
603 carto::Object dainf
604 = GiftiHeader::giftiFindHdrDA( hdrpolyda, da_info,
605 "NIFTI_INTENT_TRIANGLE" );
606 if( !dainf.isNone() )
607 {
608 ++hdrpolyda;
609 GiftiHeader::giftiCopyMetaToGii( dainf, da );
610 }
611 }
612 // write texture
613 const std::vector<T> & tex = surf.texture();
614 hdr.giftiAddTexture( gim, tex );
615
616 // metadata
617 carto::Object dainf
618 = GiftiHeader::giftiFindHdrDA( hdrtexda, da_info, "" );
619 if( !dainf.isNone() )
620 {
621 ++hdrtexda;
622 GiftiHeader::giftiCopyMetaToGii( dainf,
623 gim->darray[gim->numDA-1] );
624 }
625 }
626
627 // add external textures
628 hdr.giftiAddExternalTextures( gim, hdrtexda, da_info );
629
630 // labels table
631 hdr.giftiAddLabelTable( gim );
632
633 // global referential
634 if( thdr.hasProperty( "transformations" )
635 && thdr.hasProperty( "referentials" ) )
636 {
637 // set it on the first mesh, and in any other which does not have
638 // coordinates systems information
639 nda = gim->numDA;
640 bool first = true;
641 for( t=0; t<nda; ++t )
642 {
643 giiDataArray *da = gim->darray[t];
644 if( da->intent == NIFTI_INTENT_POINTSET
645 && ( first || da->numCS == 0 ) )
646 {
647 first = false;
648 hdr.giftiSetTransformations( carto::Object::reference( thdr ),
649 da );
650 }
651 }
652 }
653
655 gifti_write_image( gim, fname.c_str(), 1 );
657
658 gifti_free_image( gim );
659 // .minf header
660 if( hdr.hasProperty( "GIFTI_metadata") )
661 hdr.removeProperty( "GIFTI_metadata" );
662 if( hdr.hasProperty( "GIFTI_version" ) )
663 hdr.removeProperty( "GIFTI_version" );
664 if( hdr.hasProperty( "GIFTI_dataarrays_info" ) )
665 hdr.removeProperty( "GIFTI_dataarrays_info" );
666 if( hdr.hasProperty( "file_type" ) )
667 hdr.removeProperty( "file_type" );
668 hdr.writeMinf( fname + ".minf" );
669 return true;
670 }
671 catch( std::exception & e )
672 {
673 return false;
674 }
675
676 return true;
677 }
678
679} // namespace aims
680
681#endif
The template class to manage a mesh.
Definition surface.h:69
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals.
Definition surface.h:98
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons.
Definition surface.h:108
void updateNormals()
Update/Compute the normals.
Definition surface.h:188
const std::vector< T > & texture() const
Get a const reference to the vector of textures.
Definition surface.h:103
const std::vector< Point3df > & vertex() const
Get a const reference to the vector of vertices.
Definition surface.h:93
The template class to manage a mesh with time if needed.
Definition surface.h:317
void setHeader(const aims::PythonHeader &hdr)
Set the header.
Definition surface.h:336
const aims::PythonHeader & header() const
Get the header.
Definition surface.h:332
std::map< int, AimsSurface< D, T > >::const_iterator const_iterator
Definition surface.h:321
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals of the 0 surface.
Definition surface.h:354
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons of the 0 surface.
Definition surface.h:366
const std::vector< T > & texture() const
Get a const reference to the vector of textures of the 0 surface.
Definition surface.h:360
std::map< int, AimsSurface< D, T > >::iterator iterator
Definition surface.h:319
const std::vector< Point3df > & vertex() const
Get a const reference to the vector of verteces of the surface of index 0.
Definition surface.h:348
Generic finder / checker for all data objects and file formats This will replace the old AimsFinder.
Definition finder.h:118
void setObjectType(const std::string &obj)
Definition finder.h:142
GIFTI Header class.
Definition giftiheader.h:56
static carto::Mutex & giftiMutex()
void setOptions(carto::Object opt)
Definition giftiheader.h:67
const std::string & name() const
virtual bool read(const std::string &filename, AimsTimeSurface< D, T > &vol, const carto::AllocatorContext &context, carto::Object options)
virtual bool write(const std::string &filename, const AimsTimeSurface< D, T > &vol, carto::Object options=carto::none())
void setOptions(carto::Object opt)
Definition giftiformat.h:57
const carto::Object options() const
Definition giftiformat.h:56
Link mechanism between the Finder and a process operating on arbitrary data types.
Definition process.h:200
Attributed python-like header, stores all needed information about an object, currently used for volu...
Definition pheader.h:52
virtual void copy(const PythonHeader &, bool keepUuid=false)
virtual bool writeMinf(const std::string &filename)
write meta-info header, non-const version (may change some attributes)
Object reference(Object &value)
static Object value()
bool isNone() const
virtual bool getProperty(const std::string &, Object &) const
virtual bool removeProperty(const std::string &)
virtual bool hasProperty(const std::string &) const
static void launchErrnoExcept(const std::string &filename="")
The class for EcatSino data write operation.
std::string giftiTextureDataType(int dtype, int &ndim, int *dims, int intent, int &ntime)
U convertedNiftiValue(void *data, int index, int dtype)
Definition giftiutil.h:122
std::vector< Object > ObjectVector
AimsVector< float, 3 > Point3df
float norm(const AimsVector< T, D > &v1)