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