arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

nrro.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------
00002 //
00003 //   Joe Kniss
00004 //     9-17-02
00005 //                   ________    ____   ___ 
00006 //                  |        \  /    | /  /
00007 //                  +---+     \/     |/  /
00008 //                  +--+|  |\    /|     < 
00009 //                  |  ||  | \  / |  |\  \ 
00010 //                  |      |  \/  |  | \  \ 
00011 //                   \_____|      |__|  \__\
00012 //                       Copyright  2002 
00013 //                      Joe Michael Kniss
00014 //                   <<< jmk@cs.utah.edu >>>
00015 //               "All Your Base are Belong to Us"
00016 //-------------------------------------------------------------------------
00017 
00018 //nrro.cpp
00019 // Q:Why is this sooooo harry?
00020 // A:Gordon "jeek" Kindlman (Kindlemmon), he coded TEEM & NRRD in "ANSI C"
00021 //   This means, that I kind of need to follow his progamatic way of thinking,
00022 //   The nice thing is no crazy templating and dynamic casting, I added some
00023 //   semantics "image, volume, etc..."  to this class with out subclassing, 
00024 //   keeping in the spirit of having an object that could be any type and also
00025 //   and "kind" of data.  This class is probably incomplete, lots of functionality
00026 //   in TEEM, I try to keep up :)
00027 
00028 //nrro, a nrrd object wrapper.
00029 
00030 #include "nrro.h"
00031 #include "nrroProbe.h"
00032 #include <iostream>
00033 #include <air.h>
00034 
00035 using namespace std;
00036 using namespace gutz;
00037 
00038 /////////////////////////////////////////////////////////////////////////
00039 /////////////////////////////////////////////////////////////////////////
00040 //Nrro
00041 /////////////////////////////////////////////////////////////////////////
00042 /////////////////////////////////////////////////////////////////////////
00043 
00044 /////////////////////////////////////////////////////////////////////////
00045 // Construction / Destruction
00046 /////////////////////////////////////////////////////////////////////////
00047 
00048 Nrro::Nrro()
00049 {
00050    initMembers();
00051    NrroDbg("Nrro(), empty nrrd object");
00052    _nrrd = nrrdNew();
00053    for(int i=0; i<MAX_NRRO_ARRAY_DIM; ++i)
00054    {
00055       _strides[i] = 0;
00056    }
00057    update();
00058    if(_nrrd)
00059       _valid = true;
00060 }
00061 
00062 //copy constructor
00063 Nrro::Nrro(const Nrro &n)
00064 {
00065    initMembers();
00066    copy(n);
00067    update();
00068    if(_nrrd)
00069       _valid = true;
00070 }
00071 
00072 //ah this looks usefull
00073 Nrro::Nrro(const char *nrrdFileName, bool proxy)
00074 {
00075    initMembers();
00076    if(readNrrd(nrrdFileName, proxy))
00077    {
00078       _valid = false; 
00079       return;
00080    }
00081    else
00082    {
00083       update();
00084    }
00085    if(_nrrd)
00086       _valid = true;
00087 }
00088 
00089 Nrro::Nrro(Nrrd* n)
00090 {
00091    initMembers();
00092    setNrrd(n);
00093    update();
00094    if(_nrrd)
00095       _valid = true;
00096 }
00097 
00098 Nrro::Nrro(int typeEnum, int sx)
00099 {
00100    initMembers();
00101    _nrrd = nrrdNew();
00102    nrrdAlloc(_nrrd, typeEnum, 1, sx);
00103    for(int i=0; i<dim(); ++i)
00104      {
00105        _pads[i].x = 0;
00106        _pads[i].y = dim(i);
00107      }
00108    update();
00109    if(_nrrd)
00110      _valid = true;
00111 }
00112 
00113 Nrro::Nrro(int typeEnum, int sx, int sy)
00114 {
00115    initMembers();
00116    _nrrd = nrrdNew();
00117    nrrdAlloc(_nrrd, typeEnum, 2, sx, sy);
00118    for(int i=0; i<dim(); ++i)
00119      {
00120        _pads[i].x = 0;
00121        _pads[i].y = dim(i);
00122      }
00123    update();
00124    if(_nrrd)
00125      _valid = true;
00126 }
00127 
00128 Nrro::Nrro(int typeEnum, int sx, int sy, int sz)
00129 {
00130    initMembers();
00131    _nrrd = nrrdNew();
00132    nrrdAlloc(_nrrd, typeEnum, 3, sx, sy, sz);
00133    for(int i=0; i<dim(); ++i)
00134      {
00135        _pads[i].x = 0;
00136        _pads[i].y = dim(i);
00137      }
00138    update();
00139    if(_nrrd)
00140      _valid = true;
00141 }
00142 
00143 Nrro::Nrro(int typeEnum, int sx, int sy, int sz, int sw)
00144 {
00145    initMembers();
00146    _nrrd = nrrdNew();
00147    nrrdAlloc(_nrrd, typeEnum, 4, sx, sy, sz, sw);
00148    for(int i=0; i<dim(); ++i)
00149      {
00150        _pads[i].x = 0;
00151        _pads[i].y = dim(i);
00152      }
00153    update();
00154    if(_nrrd)
00155      _valid = true;
00156 }
00157 
00158 Nrro::Nrro(int typeEnum, int s1, int s2, int s3, int s4, int s5)
00159 {
00160    initMembers();
00161    _nrrd = nrrdNew();
00162    nrrdAlloc(_nrrd, typeEnum, 5, s1, s2, s3, s4, s5);
00163    for(int i=0; i<dim(); ++i)
00164      {
00165        _pads[i].x = 0;
00166        _pads[i].y = dim(i);
00167      }
00168    update();
00169    if(_nrrd)
00170      _valid = true;
00171 }
00172 
00173 Nrro::Nrro(int typeEnum, int dim, int sz[])
00174 {
00175    initMembers();
00176    _nrrd = nrrdNew();
00177    nrrdAlloc_nva(_nrrd, typeEnum, dim, sz);
00178    for(int i=0; i<this->dim(); ++i)
00179      {
00180        _pads[i].x = 0;
00181        _pads[i].y = this->dim(i);
00182      }
00183    update();
00184    if(_nrrd)
00185      _valid = true;
00186 }
00187 
00188 //destruct
00189 Nrro::~Nrro()
00190 {
00191    erase();
00192 }
00193 
00194 //assignment operator
00195 void Nrro::operator=(const Nrro &n)
00196 {
00197    copy(n);
00198    setModified(true);
00199    update();
00200 }
00201 
00202 void Nrro::initMembers()
00203 {  
00204    _nrrd = 0;
00205    _valid = false;
00206    _modified = true;
00207    _kind = KIND_NOT_SET;
00208    _pos = vec3f_zero;
00209    _pads = arrayo1v2ui(MAX_NRRO_ARRAY_DIM, vec2ui(0,0));
00210 }
00211 
00212 
00213 /////////////////////////////////////////////////////////////////////////
00214 // Update
00215 /////////////////////////////////////////////////////////////////////////
00216 //this is where we update cached values.
00217 void Nrro::update()
00218 {
00219    if(!_modified) return;
00220    if(!_nrrd) 
00221    {
00222       _valid = false;
00223       return;
00224    }
00225    
00226    setStrides();   
00227    /// update size
00228    _size = dim(0);
00229    for(int i=1; i<int(dim()); ++i)
00230    {
00231       _size *= dim(i);
00232    }
00233    /// min max depends on size!!
00234    updateMinMax();
00235    writeExtended();
00236 
00237    setModified(false);
00238 }
00239 
00240 /////////////////////////////////////////////////////////////////////////
00241 // axis Size Real
00242 /////////////////////////////////////////////////////////////////////////
00243 float Nrro::axisSizeNPad(int a) const
00244 {
00245    return float(_nrrd->axis[a].spacing * float(dimNPad(a)-1));
00246 }
00247 
00248 /////////////////////////////////////////////////////////////////////////
00249 // size, total number of elementes in nrro
00250 /////////////////////////////////////////////////////////////////////////
00251 int Nrro::size() const
00252 {
00253    return _size;
00254 }
00255 
00256 
00257 /////////////////////////////////////////////////////////////////////////
00258 // get Size()
00259 /////////////////////////////////////////////////////////////////////////
00260 gutz::vec3f Nrro::getSizeV3() const
00261 {
00262    //// sigh, we have to handle symantics here
00263    /// 2D image, or 3D time series image
00264    if( ( (dim() == 2)&&(IMAGE & _kind) ) 
00265       || ( (dim() == 3)&&(IMAGE & _kind)&&(TIME_SERIES & _kind) ))
00266    {
00267       return vec3f(axisSizeNPad(0), axisSizeNPad(1), 0.0f);
00268    }
00269    /// regular n-channel image, or 4D time series image
00270    else if(((dim() == 3) && (IMAGE & _kind)) 
00271       || ((dim()==4)&&(IMAGE & _kind)&&(TIME_SERIES & _kind)))
00272    {
00273       return vec3f(axisSizeNPad(1),axisSizeNPad(2),0.0f);
00274    }
00275    /// 3D volume or 4D time series volume
00276    if(((dim() == 3) && (VOLUME & _kind)) 
00277       || ((dim()==4)&&(VOLUME & _kind)&&(TIME_SERIES & _kind)))
00278    {
00279       return vec3f(axisSizeNPad(0),axisSizeNPad(1),axisSizeNPad(2));
00280    }
00281    /// 4D volume or 5D time series volume
00282    else if(((dim() == 4) && (VOLUME & _kind)) 
00283       || ((dim()==5)&&(VOLUME & _kind)&&(TIME_SERIES & _kind)))
00284    {
00285       return vec3f(axisSizeNPad(1),axisSizeNPad(2),axisSizeNPad(3));
00286    }
00287    else
00288    {
00289       NrroDbg("getSize(), size only valid for 3D & 4D(3+fields) volumes");
00290       return vec3f_zero;
00291    }
00292 }
00293 
00294 /////////////////////////////////////////////////////////////////////////
00295 // deep copy
00296 /////////////////////////////////////////////////////////////////////////
00297 void Nrro::copy(const Nrro &n)
00298 {
00299    erase();
00300 
00301    if(n._valid && n._nrrd)
00302    {
00303       if( nrrdCopy( _nrrd, (n._nrrd) ) )
00304       {
00305          char *nerr = biffGetDone(NRRD);
00306          cerr << "nrroDat: nrrd copy failed : " << nerr << endl; 
00307          _valid = false;
00308       }
00309       for(int i=0; i<MAX_NRRO_ARRAY_DIM; ++i)
00310       {
00311          _strides[i] = n._strides[i];
00312       }
00313       _pos = n._pos;
00314       _valid = true;
00315       _pads = n._pads;
00316       _kind = n._kind;
00317    }
00318 }
00319 
00320 /////////////////////////////////////////////////////////////////////////
00321 // erase
00322 /////////////////////////////////////////////////////////////////////////
00323 void Nrro::erase()
00324 {
00325    if(_nrrd)
00326    {
00327       nrrdNuke(_nrrd);
00328       _valid = false;
00329       for(int i=0; i<MAX_NRRO_ARRAY_DIM; ++i)
00330       {
00331          _strides[i] = 0;
00332       }
00333    }
00334    _nrrd = nrrdNew();
00335 }
00336 
00337 /////////////////////////////////////////////////////////////////////////
00338 // set strides
00339 /////////////////////////////////////////////////////////////////////////
00340 void Nrro::setStrides()
00341 {
00342    // set up strides for accessors
00343    if(_nrrd->dim < MAX_NRRO_ARRAY_DIM)
00344    {
00345       for(int i=0; i<_nrrd->dim; ++i)
00346       {
00347          _strides[i] = 1; /// all start with 1
00348       }
00349       for(int i=0; i<_nrrd->dim; ++i)
00350       {
00351          for(int j=i+1; j<_nrrd->dim; ++j)
00352          {
00353             _strides[j] *= _nrrd->axis[i].size; /// multiply by the one under you
00354          }
00355       }
00356       /// zero out all others
00357       for(int i=_nrrd->dim; i< MAX_NRRO_ARRAY_DIM; ++i)
00358       {
00359          _strides[i] = 0;
00360       }
00361    } 
00362    else
00363    {
00364       NrroDbg(" WARNING : nrrd dimension greater than max allowd for () accessor ");
00365    }
00366 }
00367 
00368 /////////////////////////////////////////////////////////////////////////
00369 // setNrrd
00370 /////////////////////////////////////////////////////////////////////////
00371 void  Nrro::setNrrd(Nrrd *n)
00372 {
00373    if(_nrrd)
00374       nrrdNuke(_nrrd);
00375    _nrrd = n;
00376 
00377    if(_nrrd)
00378       _valid = true;
00379    else
00380       return;
00381 
00382    setStrides();
00383 
00384    /// TODO: read out pos, tc, and pads from comments
00385    _pos = vec3f_zero;
00386    /// set the padds
00387    for(unsigned int i=0; i<MAX_NRRO_ARRAY_DIM; ++i)
00388    {
00389       _pads[i].x = 0;
00390       _pads[i].y = g_max(int(dim(i)) - 1, 0);
00391    }
00392 }
00393 
00394 /////////////////////////////////////////////////////////////////////////
00395 // printInfo
00396 /////////////////////////////////////////////////////////////////////////
00397 void Nrro::printInfo() const
00398 {
00399    if(!isValid())
00400    {
00401       cerr << " Nrro::printInfo(), invalid Nrro" << endl;
00402    }
00403 
00404    cerr << " Nrro::printInfo() " << endl;
00405    printType();
00406    printKind();
00407    cerr << "  Name: " << _name << endl;
00408    cerr << "  Dimension  : " << dim() << endl;
00409    cerr << "  Position   : " << _pos << endl;
00410    cerr << "  Axis Names : ";
00411    for(int i=0; i<dim(); ++i)
00412       if(axisName(i))
00413          cerr << axisName(i) << " ";
00414    cerr << endl;
00415 
00416    cerr << "  Axis Units : ";
00417    for(int i=0; i<dim(); ++i)
00418       if(axisUnit(i))
00419          cerr << axisUnit(i) << " ";
00420    cerr << endl;
00421 
00422    cerr << "  Axis Dims  : ";
00423    for(int i=0; i<dim(); ++i)
00424       cerr << dim(i) << ", ";
00425    cerr << endl;
00426 
00427    cerr << "  Spacings   : ";
00428    for(int i=0; i<dim(); ++i)
00429       cerr << axisSpacing(i) << ", ";
00430    cerr << endl;
00431 
00432    cerr << "  Axis Sizes : ";
00433    for(int i=0; i<dim(); ++i)
00434       cerr << axisSize(i) << ", ";
00435    cerr << endl;
00436 
00437    cerr << "  Unpadded Sizes : ";
00438    for(int i=0; i<dim(); ++i)
00439       cerr << axisSizeNPad(i) << ", ";
00440    cerr << endl;
00441 
00442    cerr << "  Valid Data Ranges : " << endl << "   ";
00443    for(int i=0; i<dim(); ++i)
00444       cerr << "(" << _pads[i].x << ", " << _pads[i].y << "), ";
00445    cerr << endl;
00446 }
00447 
00448 /////////////////////////////////////////////////////////////////////////
00449 // printType
00450 /////////////////////////////////////////////////////////////////////////
00451 void Nrro::printType() const
00452 {
00453    cerr << "  Nrro::TYPE = ";
00454    switch(_nrrd->type)
00455    {
00456    case UNKNOWN:
00457       cerr << "Unknown type" << endl;
00458       break;
00459    case CHAR:
00460       cerr << "char" << endl;
00461       break;
00462    case UCHAR:
00463       cerr << "unsigned char" << endl;
00464       break;
00465    case SHORT:
00466       cerr << "short" << endl;
00467       break;
00468    case USHORT:
00469       cerr << "unsigned short" << endl;
00470       break;
00471    case INT:
00472       cerr << "int" << endl;
00473       break;
00474    case UINT:
00475       cerr << "unsigned int" << endl;
00476       break;
00477    case FLOAT:
00478       cerr << "float" << endl;
00479       break;
00480    case DOUBLE:
00481       cerr << "double" << endl;
00482       break;
00483    case BLOCK:
00484       cerr << "block" << endl;
00485       break;
00486    case TYPE_LAST:
00487       cerr << "last type????" << endl;
00488    default:
00489       cerr << "typeEnum invalid" << endl;
00490    }
00491    return;
00492 }
00493 

Send questions, comments, and bug reports to:
jmk