# -*- coding: utf-8 -*- # This software and supporting documentation are distributed by # Institut Federatif de Recherche 49 # CEA/NeuroSpin, Batiment 145, # 91191 Gif-sur-Yvette cedex # France # # This software is governed by the CeCILL license version 2 under # French law and abiding by the rules of distribution of free software. # You can use, modify and/or redistribute the software under the # terms of the CeCILL license version 2 as circulated by CEA, CNRS # and INRIA at the following URL "http://www.cecill.info". # # As a counterpart to the access to the source code and rights to copy, # modify and redistribute granted by the license, users are provided only # with a limited warranty and the software's author, the holder of the # economic rights, and the successive licensors have only limited # liability. # # In this respect, the user's attention is drawn to the risks associated # with loading, using, modifying and/or developing or reproducing the # software by the user in light of its specific status of free software, # that may mean that it is complicated to manipulate, and that also # therefore means that it is reserved for developers and experienced # professionals having in-depth computer knowledge. Users are therefore # encouraged to load and test the software's suitability as regards their # requirements in conditions enabling the security of their systems and/or # data to be ensured and, more generally, to use and operate it in the # same conditions as regards security. # # The fact that you are presently reading this means that you have had # knowledge of the CeCILL license version 2 and that you accept its terms. from brainvisa.processes import * from brainvisa.processing.qtgui.backwardCompatibleQt import * from brainvisa.processing.qtgui.neuroProcessesGUI import * from brainvisa import anatomist name = 'Diffusoids' userLevel = 2 def validation(): anatomist.validation() signature=Signature( 't2_diffusion', ReadDiskItem( 'T2 Diffusion MR', 'Aims readable volume formats' ), 'dw_diffusion', ReadDiskItem( 'DW Diffusion MR', 'Aims readable volume formats' ), 'symetry', Boolean(), 'sphere', ReadDiskItem( 'Directions mesh', [ 'TRI mesh', 'MESH Mesh' ] ), 'orientation', String(), ); def initialization( self ): self.orientation = '+x+y+z' self.linkParameters( 'sphere', 't2_diffusion' ) self.linkParameters( 'dw_diffusion', 't2_diffusion' ) self.setOptional( 'sphere' ) class DiffusoidsPanel( QWidget ): def __init__( self, values, context, parent ): self.values = values self.context = context QWidget.__init__( self, parent ) layout=QHBoxLayout(self) layout.setMargin( 10 ) layout.setSpacing( 5 ) btn = QPushButton( _t_('show T2'), self ) layout.addWidget(btn) QObject.connect( btn, SIGNAL( 'clicked()' ), self.showT2 ) btn = QPushButton( _t_('update diffusoids'), self ) layout.addWidget(btn) QObject.connect( btn, SIGNAL( 'clicked()' ), self.updateDiffusoids ) self.roi = None self.diffusoids = None def showT2( self ): if self.roi is None: # Build sphere triangulation a = anatomist.Anatomist() # Load T2 image t2 = a.loadObject( self.values.t2_diffusion.fullPath() ) # Create drawing graph, bucket and node graphItem = self.context.temporary( 'Graph and data' ) file = os.path.basename( graphItem.fullPath() ) if file[-4:] == '.arg': file = file[:-4] graph = a.createGraph( t2, name = file ) ( node, bucket ) = graph.createNode( name = "roi", with_bucket = True, duplicate = False ) # Create drawing view window = a.createWindow( 'Axial' ) window.addObjects( [ graph, t2 ] ) a.execute( 'Select', objects=(node,) ) window.setControl( control = "PaintControl" ) # Save important values self.roi = ( t2, graphItem, graph, node, bucket, window ) def updateDiffusoids( self ): if self.roi is None: self.context.warning( 'Select ROI first' ) return t2, graphItem, graph, node, bucket, window = self.roi print '!a = anatomist.Anatomist()!' a = anatomist.Anatomist() if self.diffusoids is None: print '!self.diffusoids is None!' # This is the fist call of updateDiffusoid diffusoidsItem = defaultContext().temporary( 'MESH mesh' ) textureItem = defaultContext().temporary( 'Texture' ) winInfo = None print '!windowdiffusoid = a.createWindow( \'3D\' )!' windowdiffusoid = a.createWindow( '3D' ) print 'windowdiffusoid.addObjects( ( t2, ) )' windowdiffusoid.addObjects( ( t2, ) ) else: print '!self.diffusoids!', self.diffusoids ( t2, sphereItem, diffusoidsItem, diffusoids, textureItem, texture, fusion, windowdiffusoid ) = self.diffusoids winInfo = window.objectInfo() window.removeObject( fusion ) fusion.deleteObject() a.deleteObject( [ diffusoids, texture ] ) # a.execute( 'CloseWindow', windows=windowNum ) # Build sphere print '!build sphere!' sphereItem = self.values.sphere if sphereItem is None: # Normalize directions directions = self.values.dw_diffusion.get( 'diffusion_gradient_orientations' ) if directions is None: raise Exception( _t_('Missing directions') ) norms = map( lambda x: pow( float(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]), 0.5 ), directions ) directions = map( lambda v, n: (v[0]/n,v[1]/n,v[2]/n), directions, norms ) # Mesh sphere sphereItem = self.context.temporary( 'MESH Mesh' ) points = self.context.temporary( 'File' ) file = open( points.fullPath(), 'w' ) if self.values.symetry: print >> file, 2 * len( directions ) else: print >> file, len( directions ) for d in directions: print >> file, d[0], d[1], d[2] if self.values.symetry: for d in directions: print >> file, -d[0], -d[1], -d[2] file.close() self.context.system( 'AimsConvexHull', '-i', points.fullPath(), '-o', sphereItem.fullPath() ) graphItem.clear() graph.save( graphItem.fullPath() ) command = [ 'comistDiffusionToMesh', '--verbose', '-t2', self.values.t2_diffusion.fullPath(), '-dw', self.values.dw_diffusion.fullPath(), '-s', sphereItem.fullPath(), '-roi', graphItem.fullPath(), '-o', diffusoidsItem.fullPath(), '--texture', textureItem.fullPath(), '--orientation', self.values.orientation ] if self.values.symetry: command.append( '--symetry' ) apply( self.context.system, command ) diffusoids = a.loadObject( diffusoidsItem.fullPath() ) texture = a.loadObject( textureItem.fullPath() ) fusion = diffusoids.fusionObjects( texture, method = None ) windowdiffusoid.addObject( fusion ) if winInfo is not None: # a.execute( 'WindowConfig', windows=windowNum, # geometry = winInfo[ 'geometry' ] ) window.camera( zoom = winInfo[ 'zoom' ], observer_position = winInfo[ 'observer_position' ], view_quaternion = winInfo[ 'view_quaternion' ], slice_quaternion = winInfo[ 'slice_quaternion' ] ) self.diffusoids = ( sphereItem, diffusoidsItem, diffusoids, textureItem, texture, fusion, windowdiffusoid ) def inlineGUI( self, values, context, parent ): return DiffusoidsPanel( values, context, parent ) def execution( self, context ): pass