aimsdata 6.0.0
Neuroimaging data handling
flip.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/*
35 * Flip data.
36 */
37#ifndef AIMS_UTILITY_FLIP_H
38#define AIMS_UTILITY_FLIP_H
39
41#include <cartodata/volume/volume.h>
42#include <cartobase/containers/nditerator.h>
43
44
49template <class T>
51{
52public:
54 _flip_memory( false ) { }
55 virtual ~AimsFlip() { }
56
59 const carto::rc_ptr<carto::Volume<T> > &thing );
62 const carto::rc_ptr<carto::Volume<T> > &thing );
65 const carto::rc_ptr<carto::Volume<T> > &thing );
68 const carto::rc_ptr<carto::Volume<T> > &thing );
71 const carto::rc_ptr<carto::Volume<T> > &thing );
74 const carto::rc_ptr<carto::Volume<T> > &thing );
77 const carto::rc_ptr<carto::Volume<T> > &thing );
80 const carto::rc_ptr<carto::Volume<T> > &thing );
83 const carto::rc_ptr<carto::Volume<T> > &thing );
86 const carto::rc_ptr<carto::Volume<T> > &thing );
92 const carto::rc_ptr<carto::Volume<T> > &thing,
93 const std::string & orient );
94
95 bool useSharedView() const { return _shared_view; }
96 void setUseSharedView( bool x ) { _shared_view = x; }
97 bool updateTransforms() const { return _update_transforms; }
99 bool flipMemory() const { return _flip_memory; }
100 void setFlipMemory( bool x ) { _flip_memory = x; }
101 std::string centerRefertential() const { return _center_ref; }
102 void setCenterReferential( const std::string & x ) { _center_ref = x; }
103
104protected:
108 std::string _center_ref;
109};
110
111
112template <class T> inline
114 const carto::rc_ptr<carto::Volume<T> > &thing, const std::string & orient )
115{
117 if( _shared_view )
118 // build a view inside thing
119 res.reset( new carto::Volume<T>( thing, std::vector<int>( 4, 0 ),
120 thing->getSize() ) );
121 else
122 res.reset( new carto::Volume<T>( *thing ) );
123
124 res.copyHeaderFrom( thing->header() );
125 std::vector<float> trans_shift;
126
127 carto::Object trans;
128 if( !_update_transforms || !_center_ref.empty() )
129 {
130 try
131 {
132 trans = res->header().getProperty( "transformations" );
133 }
134 catch( ... )
135 {
136 }
137 }
138 if( !_center_ref.empty() )
139 {
140 // flip / rotate around the center of the given referential.
141 // This amounts to shift transformations by the difference of the center
142 // and the flipped center.
143 int ref_index = -1;
144 try
145 {
146 carto::Object refs = res->header().getProperty( "referentials" );
147 carto::Object rit = refs->objectIterator();
148 int i = 0;
149 for( ; rit->isValid(); rit->next(), ++i )
150 {
151 std::string rid = rit->currentValue()->getString();
152 if( rid == _center_ref )
153 {
154 ref_index = i;
155 break;
156 }
157 }
158 if( ref_index < 0 ) // not found: index number ?
159 {
160 std::stringstream s( _center_ref );
161 s >> ref_index;
162 if( ref_index == 0 && _center_ref != "0" )
163 {
164 std::cerr << "wrong referential ID\n";
165 ref_index = -1;
166 }
167 }
168
169 if( ref_index >= 0 )
170 {
171 carto::Object trans = res->header().getProperty( "transformations" );
173 = soma::AffineTransformationBase( trans->getArrayItem( ref_index ) );
174 trans_shift = tr.getInverse()->transform(
175 std::vector<float>( thing->getSize().size(), 0.f ) );
176
177 std::vector<int> dims = thing->getSize();
179 = thing->referential().toOrientation(
180 orient, soma::Transformation::vsub( dims, 1 ) );
182 = dynamic_cast<soma::AffineTransformationBase &>( *flipt );
183 // include voxel size in flip matrix
185 soma::AffineTransformationBase tvsf( flip.order() );
186 std::vector<float> vs = thing->getVoxelSize();
187 std::vector<float> fvs = flip.transformVector( vs );
188 size_t i, n;
189 for( i=0, n=fvs.size(); i<n; ++i )
190 fvs[i] = std::abs( fvs[i] );
191 for( i=0, n=std::min( size_t( flip.order() ), vs.size() ); i<n; ++i )
192 {
193 vsf.matrix()( i, i ) = 1. / vs[i];
194 tvsf.matrix()( i, i ) = fvs[i];
195 }
196 flip = tvsf * flip * vsf;
197 std::unique_ptr<soma::AffineTransformationBase> iflip = flip.inverse();
198 // transform center via inv flip
199 std::vector<float> ts2 = iflip->transform( trans_shift );
200 // the actual shift is the difference
201 trans_shift = soma::Transformation::vsub( trans_shift, ts2 );
202 }
203 }
204 catch( ... )
205 {
206 }
207 }
208
209 // flip axes
210 if( !_shared_view && _flip_memory )
211 res->flipToOrientation( orient, orient );
212 else
213 res->flipToOrientation( orient );
214 // and pretend we are back to LPI
215 res->referential().setOrientation( "LPI" );
216
217 if( trans )
218 // restore initial transforms
219 res->header().setProperty( "transformations", trans );
220 if( !trans_shift.empty() )
221 {
222 carto::Object tit = trans->objectIterator();
223
225 size_t i, n = std::min( size_t( shift.order() ), trans_shift.size() );
226 for( i=0; i<n; ++i )
227 shift.matrix()( i, shift.order() ) = trans_shift[i];
228
229 std::vector< std::vector<float> > new_trans;
230 new_trans.reserve( trans->size() );
231
232 for( ; tit->isValid(); tit->next() )
233 {
234 soma::AffineTransformationBase t( tit->currentValue() );
235 t *= shift;
236 new_trans.push_back( t.toVector() );
237 }
238 res->header().setProperty( "transformations", new_trans );
239 }
240
241 // in any case the current referential has changed.
242 if( res->header().hasProperty( "referential" ) )
243 res->header().removeProperty( "referential" );
244
245 return res;
246}
247
248
249template <class T> inline
251 const carto::rc_ptr<carto::Volume<T> > &thing )
252{
253 return this->flip( thing, "RPI" );
254}
255
256template <class T> inline
258{
259 return this->flip( thing, "LAI" );
260}
261
262
263template <class T> inline
265{
266 return this->flip( thing, "LPS" );
267}
268
269
270template <class T> inline
272{
273 return this->flip( thing, "RPS" );
274}
275
276template <class T> inline
278{
279 return this->flip( thing, "RAI" );
280}
281
282
283template <class T> inline
285{
286 return this->flip( thing, "LAS" );
287}
288
289
290template <class T> inline
292{
293 return this->flip( thing, "PLI" );
294}
295
296
297template <class T> inline
299 const carto::rc_ptr<carto::Volume<T> > &thing )
300{
301 return this->flip( thing, "IPL" );
302}
303
304
305template <class T> inline
307 const carto::rc_ptr<carto::Volume<T> > &thing )
308{
309 return this->flip( thing, "LIP" );
310}
311
312
313template <class T> inline
315 const carto::rc_ptr<carto::Volume<T> > &thing )
316{
317 return this->flip( thing, "RAS" );
318}
319
320
321#endif
void setUpdateTransforms(bool x)
Definition flip.h:98
carto::VolumeRef< T > doZZ(const carto::rc_ptr< carto::Volume< T > > &thing)
function which returns the ZZ flipped data
Definition flip.h:264
carto::VolumeRef< T > doYY(const carto::rc_ptr< carto::Volume< T > > &thing)
function which returns the YY flipped data
Definition flip.h:257
AimsFlip()
Definition flip.h:53
carto::VolumeRef< T > doXX(const carto::rc_ptr< carto::Volume< T > > &thing)
function which returns the XX flipped data
Definition flip.h:250
bool _shared_view
Definition flip.h:105
carto::VolumeRef< T > doXZ(const carto::rc_ptr< carto::Volume< T > > &thing)
function which returns the XZ flipped data
Definition flip.h:298
void setCenterReferential(const std::string &x)
Definition flip.h:102
bool _flip_memory
Definition flip.h:107
carto::VolumeRef< T > doXXYYZZ(const carto::rc_ptr< carto::Volume< T > > &thing)
function which returns the XXYYZZ flipped data
Definition flip.h:314
void setFlipMemory(bool x)
Definition flip.h:100
bool _update_transforms
Definition flip.h:106
carto::VolumeRef< T > doXY(const carto::rc_ptr< carto::Volume< T > > &thing)
function which returns the XY flipped data
Definition flip.h:291
bool updateTransforms() const
Definition flip.h:97
bool useSharedView() const
Definition flip.h:95
carto::VolumeRef< T > doXXZZ(const carto::rc_ptr< carto::Volume< T > > &thing)
function which returns the XXZZ flipped data
Definition flip.h:271
carto::VolumeRef< T > flip(const carto::rc_ptr< carto::Volume< T > > &thing, const std::string &orient)
returns the flipped data in the given orientation
Definition flip.h:113
bool flipMemory() const
Definition flip.h:99
virtual ~AimsFlip()
Definition flip.h:55
carto::VolumeRef< T > doYZ(const carto::rc_ptr< carto::Volume< T > > &thing)
function which returns the YZ flipped data
Definition flip.h:306
std::string centerRefertential() const
Definition flip.h:101
carto::VolumeRef< T > doYYZZ(const carto::rc_ptr< carto::Volume< T > > &thing)
function which returns the YYZZ flipped data
Definition flip.h:284
carto::VolumeRef< T > doXXYY(const carto::rc_ptr< carto::Volume< T > > &thing)
function which returns the XXYY flipped data
Definition flip.h:277
std::string _center_ref
Definition flip.h:108
void setUseSharedView(bool x)
Definition flip.h:96
void setProperty(const std::string &, const T &)
virtual bool removeProperty(const std::string &key)
virtual bool hasProperty(const std::string &) const
bool getProperty(const std::string &, T &) const
virtual void copyHeaderFrom(const PropertySet &other)
const PropertySet & header() const
void reset(T *p=NULL)
std::unique_ptr< Transformation > getInverse() const CARTO_OVERRIDE
std::vector< float > toVector() const
static std::vector< T > vsub(const std::vector< T > &v1, const std::vector< T > &v2)