aimsdata 6.0.0
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 for (i = 0; i < tmesh; ++i)
332 {
333 AimsSurface<D, T> & surf = vol[i];
334 std::vector<Point3df> & vert = surf.vertex();
335 std::vector<AimsVector<uint, D> > & poly = surf.polygon();
336 typename std::vector<AimsVector<uint, D> >::iterator ip;
337 unsigned nvertex = vert.size();
338 for (ip = poly.begin(); ip != poly.end(); ++ip)
339 {
340 AimsVector<uint, D> & pol = *ip;
341 for (int j = 0; j < D; ++j)
342 if (pol[j] >= nvertex)
343 {
344 if (!broken)
345 {
346 broken = true;
347 std::cerr << "Broken mesh: polygon pointing to a "
348 << "vertex out of range" << std::endl;
349 // std::cout << pol[j] << " / " << nvertex << std::endl;
350 }
351 poly.erase(ip);
352 --ip;
353 break;
354 }
355 }
356
357 if (surf.normal().size() != vert.size())
358 surf.updateNormals();
359 }
360
361 vol.setHeader(hdr);
362 gifti_free_image(gim);
363
364 // std::cout << "gifti mesh read OK\n";
365 return true;
366 }
367
368 template<int D, typename T>
369 bool GiftiMeshFormat<D, T>::write(const std::string & filename,
370 const AimsTimeSurface<D, T> & thing, carto::Object )
371 {
372 // std::cout << "gifti mesh write\n";
373 setlocale( LC_NUMERIC, "C" );
374 try
375 {
376 const PythonHeader & thdr = thing.header();
377 GiftiHeader hdr(filename);
378 hdr.copy(thdr);
379
380 if (hdr.hasProperty("nb_t_pos"))
381 hdr.removeProperty("nb_t_pos");
382 gifti_image *gim = hdr.giftiImageBase();
383 std::string fname = hdr.name();
384
385 int hdrmeshda = 0, hdrnormda = 0, hdrpolyda = 0, hdrtexda = 0;
386
387 bool normal = false;
388 int encoding = 2;
389
390 carto::Object da_info;
391 try
392 {
393 da_info = thdr.getProperty("GIFTI_dataarrays_info");
394
395 carto::Object it = da_info->objectIterator();
396 for (; it->isValid(); it->next())
397 {
398 carto::Object el = it->currentValue();
399 if (el->getProperty("encoding", encoding))
400 break;
401 }
402
403 }
404 catch (...)
405 {
406 //std::cout << "error GIFTI_dataarrays_info\n";
407 }
408
409 if (!options().isNull())
410 {
411 hdr.setOptions(options());
412 try
413 {
414 carto::Object n = options()->getProperty("normal");
415 normal = (bool) n->getScalar();
416 carto::Object a = options()->getProperty("encoding");
417 if ((int) a->getScalar() != 0)
418 {
419 encoding = (int) a->getScalar();
420 }
421
422 }
423 catch( ... )
424 {
425 }
426 }
427
428 int nda = 0, t = 0;
429 typename AimsTimeSurface<D, T>::const_iterator is, es=thing.end();
430
431 for( is=thing.begin(); is!=es; ++is, ++t )
432 {
433 const AimsSurface<D, T> & surf = is->second;
434 // write vertices
435 {
436 const std::vector<Point3df> & vert = surf.vertex();
437 nda = gim->numDA;
438 gifti_add_empty_darray( gim, 1 );
439 giiDataArray * da = gim->darray[nda];
440 gifti_set_DA_defaults( da );
441 da->intent = NIFTI_INTENT_POINTSET;
442 da->datatype = NIFTI_TYPE_FLOAT32;
443 da->num_dim = 2;
444 da->dims[0] = vert.size();
445 da->dims[1] = 3;
446 da->dims[2] = 0;
447 da->dims[3] = 0;
448 da->dims[4] = 0;
449 da->dims[5] = 0;
450 da->nvals = vert.size() * 3;
451 da->nbyper = 4;
452
453 da->encoding = encoding;
454 //GIFTI_ENCODING_ASCII 1 /* human readable ASCII data */
455 //GIFTI_ENCODING_B64BIN 2 /* base64 encoded binary data */
456 //GIFTI_ENCODING_B64GZ 3 /* base64 compressed binary */
457
458 gifti_alloc_DA_data( gim, &nda, 1 );
459 unsigned i, n = vert.size();
460
461 float *buf = reinterpret_cast<float *>( da->data );
462 for( i=0; i<n; ++i )
463 {
464 buf[i*3] = vert[i][0];
465 buf[i*3+1] = vert[i][1];
466 buf[i*3+2] = vert[i][2];
467 }
468
469 if( t != is->first )
470 {
471 // store timestep
472 std::ostringstream ts;
473 ts << is->first;
474 gifti_add_to_meta( &da->meta, "Timestep", ts.str().c_str(), 1 );
475 }
476
477 //TO DO : write that BV is in left hand referential
478 // gifti_add_empty_CS (da);
479 //
480 // giiCoordSystem * csnew = da->coordsys[da->numCS-1];
481 // int r, c;
482 //
483 // csnew->dataspace = gifti_strdup("Brainvisa Referential");
484 // csnew->xformspace = gifti_strdup("indirect reference");
485 //
486 // for( r = 0; r < 4; r++ )
487 // for( c = 0; c < 4; c++ )
488 // csnew->xform[r][c] = 0;
489 //
490 // csnew->xform[0][0] = -1;
491 // csnew->xform[1][1] = 1;
492 // csnew->xform[2][2] = 1;
493 // csnew->xform[3][3] = 1;
494
495 // metadata
496 carto::Object dainf
497 = GiftiHeader::giftiFindHdrDA( hdrmeshda, da_info,
498 "NIFTI_INTENT_POINTSET" );
499 if( !dainf.isNone() )
500 {
501 ++hdrmeshda;
502 GiftiHeader::giftiCopyMetaToGii( dainf, da );
503 }
504 }
505
506 // write normals
507 if (normal)
508 {
509 const std::vector<Point3df> & norm = surf.normal();
510 if( !norm.empty() )
511 {
512 nda = gim->numDA;
513 gifti_add_empty_darray( gim, 1 );
514 giiDataArray * da = gim->darray[nda];
515 gifti_set_DA_defaults( da );
516 da->intent = NIFTI_INTENT_VECTOR;
517 da->datatype = NIFTI_TYPE_FLOAT32;
518 da->num_dim = 2;
519 da->dims[0] = norm.size();
520 da->dims[1] = 3;
521 da->dims[2] = 0;
522 da->dims[3] = 0;
523 da->dims[4] = 0;
524 da->dims[5] = 0;
525 da->nvals = norm.size() * 3;
526 da->nbyper = 4;
527
528 da->encoding = encoding;
529
530 gifti_alloc_DA_data( gim, &nda, 1 );
531 unsigned i, n = norm.size();
532 float *buf = reinterpret_cast<float *>( da->data );
533 for( i=0; i<n; ++i )
534 {
535 buf[i*3] = norm[i][0];
536 buf[i*3+1] = norm[i][1];
537 buf[i*3+2] = norm[i][2];
538 }
539
540 if( t != is->first )
541 {
542 // store timestep
543 std::ostringstream ts;
544 ts << is->first;
545 gifti_add_to_meta( &da->meta, "Timestep", ts.str().c_str(), 1 );
546 }
547
548 // metadata
549 carto::Object dainf
550 = GiftiHeader::giftiFindHdrDA( hdrnormda, da_info,
551 "NIFTI_INTENT_VECTOR" );
552 if( !dainf.isNone() )
553 {
554 ++hdrnormda;
555 GiftiHeader::giftiCopyMetaToGii( dainf, da );
556 }
557 }
558 }
559
560 // write polygons
561 {
562 const std::vector<AimsVector<unsigned, D> > & poly
563 = surf.polygon();
564 nda = gim->numDA;
565 gifti_add_empty_darray( gim, 1 );
566 giiDataArray * da = gim->darray[nda];
567 gifti_set_DA_defaults( da );
568 da->intent = NIFTI_INTENT_TRIANGLE;
569 da->datatype = NIFTI_TYPE_INT32;
570 da->num_dim = 2;
571 da->dims[0] = poly.size();
572 da->dims[1] = D;
573 da->dims[2] = 0;
574 da->dims[3] = 0;
575 da->dims[4] = 0;
576 da->dims[5] = 0;
577 da->nvals = poly.size() * D;
578 da->nbyper = 4;
579
580 da->encoding = encoding;
581
582 gifti_alloc_DA_data( gim, &nda, 1 );
583 unsigned i, j, n = poly.size();
584 int *buf = reinterpret_cast<int *>( da->data );
585 for( i=0; i<n; ++i )
586 for( j=0; j<D; ++j )
587 buf[i*D+j] = poly[i][j];
588
589 if( t != is->first )
590 {
591 // store timestep
592 std::ostringstream ts;
593 ts << is->first;
594 gifti_add_to_meta( &da->meta, "Timestep", ts.str().c_str(), 1 );
595 }
596
597 // metadata
598 carto::Object dainf
599 = GiftiHeader::giftiFindHdrDA( hdrpolyda, da_info,
600 "NIFTI_INTENT_TRIANGLE" );
601 if( !dainf.isNone() )
602 {
603 ++hdrpolyda;
604 GiftiHeader::giftiCopyMetaToGii( dainf, da );
605 }
606 }
607 // write texture
608 const std::vector<T> & tex = surf.texture();
609 hdr.giftiAddTexture( gim, tex );
610
611 // metadata
612 carto::Object dainf
613 = GiftiHeader::giftiFindHdrDA( hdrtexda, da_info, "" );
614 if( !dainf.isNone() )
615 {
616 ++hdrtexda;
617 GiftiHeader::giftiCopyMetaToGii( dainf,
618 gim->darray[gim->numDA-1] );
619 }
620 }
621
622 // add external textures
623 hdr.giftiAddExternalTextures( gim, hdrtexda, da_info );
624
625 // labels table
626 hdr.giftiAddLabelTable( gim );
627
628 // global referential
629 if( thdr.hasProperty( "transformations" )
630 && thdr.hasProperty( "referentials" ) )
631 {
632 // set it on the first mesh, and in any other which does not have
633 // coordinates systems information
634 nda = gim->numDA;
635 bool first = true;
636 for( t=0; t<nda; ++t )
637 {
638 giiDataArray *da = gim->darray[t];
639 if( da->intent == NIFTI_INTENT_POINTSET
640 && ( first || da->numCS == 0 ) )
641 {
642 first = false;
643 hdr.giftiSetTransformations( carto::Object::reference( thdr ),
644 da );
645 }
646 }
647 }
648
650 gifti_write_image( gim, fname.c_str(), 1 );
652
653 gifti_free_image( gim );
654 // .minf header
655 if( hdr.hasProperty( "GIFTI_metadata") )
656 hdr.removeProperty( "GIFTI_metadata" );
657 if( hdr.hasProperty( "GIFTI_version" ) )
658 hdr.removeProperty( "GIFTI_version" );
659 if( hdr.hasProperty( "GIFTI_dataarrays_info" ) )
660 hdr.removeProperty( "GIFTI_dataarrays_info" );
661 if( hdr.hasProperty( "file_type" ) )
662 hdr.removeProperty( "file_type" );
663 hdr.writeMinf( fname + ".minf" );
664 return true;
665 }
666 catch( std::exception & e )
667 {
668 return false;
669 }
670
671 return true;
672 }
673
674} // namespace aims
675
676#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
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)