def _orient(self, proc): old = getattr(proc.signature['input_spm_orientation'], 'lastInput', None) if self.input is None or old is None \ or old.fullPath() != self.input.fullPath() \ or proc.isDefault('input_spm_orientation'): hide = 1 res = 'Not applicable' if self.input is not None: if self.input.format in list( map(getFormat, ('SPM image', 'Series of SPM image'))): hide = 0 atts = aimsGlobals.aimsVolumeAttributes(self.input) tr = atts.get('storage_to_memory') if tr is not None and tr[0] < 0: res = 'Neurological' else: res = 'Radiological' if hide: proc.signature['input_spm_orientation'].setChoices( 'Not applicable') else: proc.signature['input_spm_orientation'].setChoices( 'Neurological', 'Radiological') else: res = self.input_spm_orientation proc.signature['input_spm_orientation'].lastInput = self.input return res
def execution(self, context): # context.write( 'encoder:', self.encoder ) attrs = aimsGlobals.aimsVolumeAttributes(self.images[0], forceFormat=1) width = attrs['volume_dimension'][0] mod16 = width % 16 if mod16: raise RuntimeError(_t_('Image width must be a multiple of 16. Actual ' 'width is %d, closest good values are %d and ' '%d.') % (width, width - mod16, width + 16 - mod16)) return size = str( attrs[ 'volume_dimension' ][ 0 ] ) + 'x' \ + str(attrs['volume_dimension'][1]) dir = context.temporary('Directory') yuvImage = os.path.join(dir.fullPath(), 'yuvImage.yuv') yuvImages = os.path.join(dir.fullPath(), 'yuvImages.yuv') for image in self.images: context.system('convert', image.fullPath(), yuvImage, outputLevel=-1) # for n in six.moves.xrange( self.frameRepetition ): context.system('cat "' + yuvImage + '" >> "' + yuvImages + '"', outputLevel=-1) cmd = ['recmpeg', '-P', self.encoding, '--coding', self.coding, '--quality', self.quality, '--fps', self.framesPerSecond, '--picture', size] + self.additional_encoder_options \ + [self.animation.fullPath(), yuvImages] context.system(*cmd)
def _orient(self, proc): old = getattr(proc.signature['input_spm_orientation'], 'lastInput', None) if self.input is None \ or old is None \ or old.fullPath() != self.input.fullPath() \ or proc.isDefault('input_spm_orientation'): hide = 1 res = 'Not applicable' if self.input is not None: if self.input.format in list( map(getFormat, ('SPM image', 'Series of SPM image'))): hide = 0 inputAtts = aimsGlobals.aimsVolumeAttributes(self.input) radio = isRadio(inputAtts) if radio is not None and radio != 0: res = 'Radiological' else: res = 'Neurological' if hide: proc.signature['input_spm_orientation'].setChoices( 'Not applicable') else: proc.signature['input_spm_orientation'].setChoices( 'Neurological', 'Radiological') else: # print 'using old value:', old, self.input_spm_orientation res = None proc.signature['input_spm_orientation'].lastInput = self.input return res
def execution(self, context): convert = 0 command = ['AimsFileConvert', '-i', '', '-o', ''] if self.ascii: convert = 1 command += ['-a'] if self.voxelType is not None: convert = 1 command += ['-t', self.voxelType] voldim = aimsGlobals.aimsVolumeAttributes( self.read).get('volume_dimension') time_length = voldim[3] name_serie = self.write.get('name_serie') if name_serie: if len(name_serie) != time_length: raise ValueError( _t_('<em>write</em> parameter must have <em>%d</em> files') % (time_length, )) else: nb_digit = len(str(time_length)) if nb_digit < 4: # nb_digit for the serie zeros are added at the beginning of the number that doesn't have enough digits nb_digit = 4 for n in range(time_length): n = str(n) while len(n) < nb_digit: n = "0" + n name_serie.append(n) # name_serie = [str(x) for x in range(time_length)] self.write._setLocal('name_serie', name_serie) command = [ 'AimsSubVolume', '--singleminf', '-i', self.read, '-o'] + \ self.write.firstFullPathsOfEachSeries() + \ [ '-t' ] + list(range( len( name_serie ))) + \ ['-T'] + list(range(len(name_serie))) if context.system(*command): raise Exception(_t_('Error while splitting <em>%s</em>') % (self.read.fullPath(), )) if convert: for f in self.write.firstFullPathsOfEachSeries(): command[2] = f command[4] = f if context.system(*command): raise Exception(_t_('Error while converting <em>%s</em> to <em>%s</em>') % (command[2], command[4])) if self.removeSource: for f in self.read.fullPaths(): shelltools.rm(f)
def execution(self, context): filetype = self.read.type if filetype is getDiskItemType( 'SPM99 normalization matrix' ) \ or self.read.fullName()[-5:] == '_sn3d': spm2 = 0 else: spm2 = 1 AtoT = aims.readSpmNormalization(self.read.fullPath(), self.source_volume.fullPath()) srcref = None h = AtoT.header() if 'source_referential' in h: srcref = h['source_referential'] tm = registration.getTransformationManager() if self.target != 'normalized_volume in AIMS orientation': aims.write(AtoT, self.write.fullPath()) if self.target == 'MNI template': destref = tm.referential(registration.talairachMNIReferentialId) else: destref = None else: # normalized_volume in AIMS orientation nim = self.normalized_volume if not nim or not nim.isReadable(): raise RuntimeError( _t_('normalized_volume shoud be specified when using this target mode' )) context.write('use normalized image:', nim.fullPath(), '\n') hasnorm = 1 attrs = shfjGlobals.aimsVolumeAttributes(nim) t1 = aims.Motion(attrs['transformations'][-1]) AIMS = t1.inverse() * AtoT AIMS.header().update(AtoT.header()) destref = tm.referential(nim) aims.write(AIMS, self.write.fullPath()) if srcref or destref: tm.setNewTransformationInfo(self.write, srcref, destref) if self.removeSource: for f in self.read.fullPaths(): os.unlink(f)
def execution(self, context): # Read header information atts = aimsGlobals.aimsVolumeAttributes(self.volume_input) ref = atts['referentials'] trf = atts['transformations'] if ("Scanner-based anatomical coordinates" in ref): trm_to_scannerBased = trf[ ref.index("Scanner-based anatomical coordinates")] # Create a referential for Scanner-based tm = registration.getTransformationManager() dest = tm.referential(self.new_referential) context.write('dest:', dest) if dest is None: dest = tm.createNewReferentialFor( self.new_referential, referentialType='Scanner Based Referential') # Create a new referential if needed for the volume # src = tm.referential( self.volume_input ) # print "Attributes" # print self.volume_input.hierarchyAttributes() # if src is None: # print "create src" # src = tm.createNewReferentialFor(self.volume_input) # print "apres" # print src src = tm.referential(self.referential_volume_input) context.write('src:', src) # print "Attributes" # print self.volume_input.hierarchyAttributes() if src is None: src = tm.createNewReferentialFor(self.volume_input, referentialType='Referential of Raw T1 MRI', output_diskitem=self.referential_volume_input) dest.setMinf('direct_referential', 1, saveMinf=True) # Store information into the trm file mot = aims.Motion(trm_to_scannerBased) aims.write(mot, self.T1_TO_Scanner_Based.fullPath()) # set and update database tm.setNewTransformationInfo( self.T1_TO_Scanner_Based, source_referential=src, destination_referential=dest)
def execution(self, context): # context.write( 'encoder:', self.encoder ) attrs = aimsGlobals.aimsVolumeAttributes(self.images[0], forceFormat=1) width = attrs['volume_dimension'][0] tmpdi = context.temporary('File') tmp = tmpdi.fullPath() tfile = open(tmp, 'w') im = [x.fullPath() for x in self.images] tfile.write('\n'.join(im)) tfile.write('\n') tfile.close() f = open(tmp) context.log('transcode input files', html=f.read()) f.close() # os.system( 'cat ' + tmp ) height = attrs['volume_dimension'][1] cmd = ['transcode', '-x', 'imlist,null', '-y', self.encoding + ',null', '-i', tmp, '-g', str(width) + 'x' + str(height), '-H', 0, '-o', self.animation.fullPath(), '-f', self.framesPerSecond] \ + self.additional_encoder_options context.system(*cmd)
def execution(self, context): if len(self.images) == 0: raise RuntimeError('No image selected') context.write(self.images[0]) attrs = aimsGlobals.aimsVolumeAttributes(self.images[0], forceFormat=1) context.write(attrs) width = attrs['volume_dimension'][0] im = [x.fullPath() for x in self.images] passlog = context.temporary('log file') cmd = ['mencoder', 'mf://' + ','.join(im), '-o', self.animation.fullPath(), '-mf', 'fps=' + str(self.framesPerSecond), '-ovc', 'lavc', '-passlogfile', passlog, '-lavcopts', 'vbitrate=' + str(self.quality * 10) + ':vcodec=' + self.encoding + ':vpass=1'] + self.additional_encoder_options # print cmd context.system(*cmd) if self.passes > 1: cmd[-1] = cmd[-1][:-1] + '2' # print cmd context.system(*cmd)
def execution(self, context): if len(self.images) == 0: raise RuntimeError('No image selected') if 'ffmpeg' in mpegConfig.encoders: encoder = 'ffmpeg' else: encoder = 'avconv' attrs = aimsGlobals.aimsVolumeAttributes(self.images[0], forceFormat=1) # context.write( attrs ) dims = attrs['volume_dimension'] vs = attrs['voxel_size'] width = float(dims[0] * vs[0]) height = float(dims[1] * vs[1]) aspect = width / height # bps = self.quality*10 qscale = int((100 - self.quality) * 0.3 + 1) # determine filanemes pattern numre = re.compile('(.*[^0-9])([0-9]+)$') m = numre.match(os.path.basename(self.images[0].fullName())) pat = '' ext = self.images[0].fullPath()[len(self.images[0].fullName()):] if m: sp = m.span(2) dirn = os.path.dirname(self.images[0].fullName()) pat = os.path.join(dirn, m.group(1) + '%' + str(sp[1] - sp[0]) + 'd' + ext) # context.write( 'pattern: ', pat ) for x in self.images[1:]: m2 = numre.match(os.path.basename(x.fullName())) if not m2 or m2.group(1) != m.group(1) or m2.span(2) != sp \ or os.path.basename(self.images[0].fullPath())[sp[1]:] \ != ext: pat = '' msg = _t_('ffmpeg/avconv can ony handle a series of homogen, ' 'numbered image filenames. Image %s breaks the ' 'rule') % x.fullPath() break if pat: # check if the pattern only includes theimages we want imnames = [os.path.basename(x.fullPath()) for x in self.images] # context.write( imnames ) d = os.listdir(dirn) n = len(ext) for x in d: if x.endswith(ext) and x not in imnames: m2 = numre.match(os.path.basename(x[:-n])) if m2 and m2.group(1) == m.group(1) and m2.span(2) == sp: pat = '' msg = _t_('ffmpeg/avconv can ony handle a series of ' 'homogen, numbered image filenames. There are ' 'additional files in the images directory that ' 'would interfere with the pattern: %s prevents ' 'it from working') % x break if pat: im = [pat] else: context.write( _t_('Images have to be copied for the following reason:') + '\n', msg) tmpdir = context.temporary('Directory') td = tmpdir.fullPath() inum = 0 snum = int(math.ceil(math.log10(len(self.images) + 1))) for x in self.images: if not x.fullPath().endswith(ext): raise RuntimeError( _t_('all images must have the same format:' ' %s has not the expected extension %s') % x % ext) ofile = os.path.join(td, ('img%0' + str(snum) + 'd' + ext) % inum) if platform == 'windows': shutil.copyfile(x.fullPath(), ofile) else: # cheaper solution on unix os.symlink(x.fullPath(), ofile) inum += 1 context.write('copy done') im = [os.path.join(td, 'img%' + str(snum) + 'd' + ext)] # im = [x.fullPath() for x in self.images] passlog = context.temporary('log file') cmd = [encoder] for x in im: cmd += ['-i', x] cmd += [ '-r', str(self.framesPerSecond), # '-hq', # this options seems to have disapeared # '-b', str( bps ), '-qscale', str(qscale), '-aspect', str(aspect), '-vcodec', self.encoding ] if self.encoding == 'msmpeg4': # force to be readable by MS Media player # see http://ffmpeg.sourceforge.net/compat.php cmd += ['-vtag', 'MP43'] cmd += ['-pass', '1', '-passlogfile', passlog] + self.additional_encoder_options \ + [self.animation.fullPath()] context.write(cmd) if os.path.exists(self.animation.fullPath()): # ffmpeg doesn't overwrite existing files os.unlink(self.animation.fullPath()) context.system(*cmd) if self.passes > 1: cmd[-4] = '2' # print cmd context.system(*cmd)
def execution(self, context): if self.input.format is not self.output.format: # Convert input to appropriate output format inp = self.input if inp.type is None \ or inp.type == ReadDiskItem('Any Type', inp.format).type: # if the input type is not recognized (data not in database), # assume it is the same type as the output inp = (self.output.type, inp.format) if self.converter == 'Any converter': converter = context.getConverter(inp, self.output) else: converter = getProcess(self.converter) if converter is None: raise RuntimeError(_t_('Cannot convert input data')) input = self.input if self.input.format in list( map(getFormat, ('SPM image', 'Series of SPM image'))): atts = aimsGlobals.aimsVolumeAttributes(self.input) tr = atts.get('storage_to_memory') radio = None if tr: radio = (tr[0] > 0) iradio = 0 if self.input_spm_orientation == 'Radiological': iradio = 1 context.write('input_spm_orientation:', self.input_spm_orientation) if radio is None or radio != iradio: context.write('changing SPM orientation') input = context.temporary(self.input.format) inputFiles = self.input.fullPaths() outputFiles = input.fullPaths() if len(inputFiles) != len(outputFiles): raise RuntimeError( _t_('input and output do not have the same number of files' )) for i in six.moves.xrange(len(inputFiles)): if neuroConfig.platform != 'windows': os.symlink(inputFiles[i], outputFiles[i]) else: shelltools.cp(inputFiles[i], outputFiles[i]) if os.path.exists(input.fullPath() + '.minf'): os.unlink(input.fullPath() + '.minf') if os.path.exists(self.input.fullPath() + '.minf'): shelltools.cp(self.input.fullPath() + '.minf', input.fullPath() + '.minf') input.readAndUpdateMinf() if iradio != 1: iradio = -1 if tr is None: tr = [1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1] tr[7] = atts['volume_dimension'][1] - 1 tr[11] = atts['volume_dimension'][2] - 1 tr[0] = iradio if tr[0] < 0: tr[3] = atts['volume_dimension'][0] - 1 else: tr[3] = 0 input.setMinf('storage_to_memory', tr) context.runProcess(converter, input, self.output) else: # Copy input files to output files inputFiles = self.input.fullPaths() outputFiles = self.output.fullPaths() if len(inputFiles) != len(outputFiles): raise RuntimeError( _t_('input and output do not have the same number of files')) for i in six.moves.xrange(len(inputFiles)): context.write('cp', inputFiles[i], outputFiles[i]) shelltools.cp(inputFiles[i], outputFiles[i]) if self.input.format in list( map(getFormat, ('SPM image', 'Series of SPM image'))): atts = aimsGlobals.aimsVolumeAttributes(self.input) radio = atts.get('spm_radio_convention') if self.input_spm_orientation == 'Neurological': radio = 0 elif self.input_spm_orientation == 'Radiological': radio = 1 self.output.readAndUpdateMinf() self.output.setMinf('spm_radio_convention', radio)
def execution(self, context): # to fetch all parameters of the input image (type, transfo, dimension, voxel size, ...) inputAtts = aimsGlobals.aimsVolumeAttributes(self.input) dtype = inputAtts.get('data_type') input1 = self.input if input1.format is not self.output.format or dtype != 'S16': # Convert input to appropriate output format converter = context.getConverter(input1, self.output) if converter is None: raise RuntimeError(_t_('Cannot convert input data')) if self.input.format in list( map(getFormat, ('SPM image', 'Series of SPM image'))): radio = isRadio(inputAtts) iradio = 0 if self.input_spm_orientation == 'Radiological': iradio = 1 if radio is None or radio != iradio: input1 = context.temporary(input1.format, 'Raw FLAIR MRI') if neuroConfig.platform != 'windows': os.symlink(self.input.fullName() + '.img', input1.fullName() + '.img') os.symlink(self.input.fullName() + '.hdr', input1.fullName() + '.hdr') else: shelltools.cp(self.input.fullName() + '.img', input1.fullName() + '.img') shelltools.cp(self.input.fullName() + '.hdr', input1.fullName() + '.hdr') if os.path.exists(self.input.fullName() + '.img.minf'): ominf = input1.fullName() + '.img.minf' shelltools.cp(self.input.fullName() + '.img.minf', ominf) s = os.stat(ominf) os.chmod(ominf, s.st_mode | stat.S_IWUSR | stat.S_IWGRP) input1.readAndUpdateMinf() input1.setMinf('spm_radio_convention', iradio) input = input1 if dtype in ('FLOAT', 'DOUBLE'): # in float/double images, NaN values may have been introduced # (typically by SPM after a normalization) input2 = context.temporary('NIFTI-1 image', 'Raw T1 MRI') context.system('AimsRemoveNaN', '-i', input1, '-o', input2) input1 = input2 input = input2 if converter._id != 'AimsConverter' or dtype == 'S16': if dtype == 'S16': input = self.output else: input = context.temporary('NIFTI-1 image', 'Raw T1 MRI') context.runProcess(converter, input1, input) if dtype != 'S16': # here we must convert to S16 data type cmd = [ 'AimsFileConvert', '-i', input.fullPath(), '-o', self.output.fullPath(), '-t', 'S16' ] if dtype not in ('U8', 'S8', 'U16'): # apply rescaling if input type is wider than S16 to avoid losing any precision cmd += ['-r', '--omin', 0, '--omax', 4095] context.system(*cmd) else: # Copy input files to output files inputFiles = self.input.fullPaths() outputFiles = self.output.fullPaths() if len(inputFiles) != len(outputFiles): raise RuntimeError( _t_('input and output do not have the same number of files')) inputMinf = self.input.minfFileName() if os.path.isfile(inputMinf): # if there is a .minf file with the input file, copy it. ominf = self.output.fullPath() + '.minf' shelltools.cp(inputMinf, ominf) s = os.stat(ominf) os.chmod(ominf, s.st_mode | stat.S_IWUSR | stat.S_IWGRP) for i in range(len(inputFiles)): # copy input file in the brainvisa database context.write('cp', inputFiles[i], outputFiles[i]) shelltools.cp(inputFiles[i], outputFiles[i]) outputAtts = aimsGlobals.aimsVolumeAttributes(self.output) for x, y in outputAtts.items(): if x != "dicom": # force completing .minf, without dicom information self.output.setMinf(x, y) self.output.saveMinf() self.output.readAndUpdateMinf() if self.input.format in list( map(getFormat, ('SPM image', 'Series of SPM image'))): radio = isRadio(inputAtts) if self.input_spm_orientation == 'Neurological': radio = 0 elif self.input_spm_orientation == 'Radiological': radio = 1 # force completing spm_radio_convention in the .minf file self.output.setMinf('spm_radio_convention', radio) self.output.saveMinf() # the referential can be written in the file header (nifti) if self.output.minf().get('referential', None): self.output.removeMinf('referential') # save referential tm = registration.getTransformationManager() ref = tm.createNewReferentialFor(self.output, name='Raw FLAIR MRI')
def execution(self, context): # IMAGE REF : reference_image = self.reference_image atts = aimsGlobals.aimsVolumeAttributes(reference_image) dims = atts.get('volume_dimension', [1, 1, 1, 1]) if len(dims) > 3 and dims[3] > 1: reference_image = context.temporary('GIS Image') context.warning('Reference image is a 4D Volume ==> Conversion to 3D') context.system( 'AimsSumFrame', '-i', self.reference_image, '-o', reference_image) dtype = atts.get('data_type') if dtype and dtype in ('FLOAT', 'DOUBLE'): pdt = atts.get('possible_data_types') if not pdt or 'S16' not in pdt: # convert to int type with rescaling rim = context.temporary('GIS Image') context.warning( 'Reference image is a floating point data Volume ==> Conversion to int16') context.system('AimsFileConvert', '-i', reference_image, '-o', rim, '-t', 'S16', '-r', '--omin', 0, '--omax', 4095) reference_image = rim # IMAGE TEST : source_image = self.source_image atts = aimsGlobals.aimsVolumeAttributes(source_image) dims = atts.get('volume_dimension', [1, 1, 1, 1]) if len(dims) > 3 and dims[3] > 1: source_image = context.temporary('GIS Image') context.warning('Test image is a 4D Volume ==> Conversion to 3D') context.system( 'AimsSumFrame', '-i', self.source_image, '-o', source_image) dtype = atts.get('data_type') if dtype and dtype in ('FLOAT', 'DOUBLE'): pdt = atts.get('possible_data_types') if not pdt or 'S16' not in pdt: # convert to int type with rescaling sim = context.temporary('GIS Image') context.warning( 'Test image is a floating point data Volume ==> Conversion to int16') context.system('AimsFileConvert', '-i', source_image, '-o', sim, '-t', 'S16', '-r', '--omin', 0, '--omax', 4095) source_image = sim command = ['AimsMIRegister', '-r', reference_image, '-t', source_image, '--dir', self.source_to_reference, '--inv', self.reference_to_source, '--refstartpyr', self.reference_reduction_factor, '--seuilref', self.reference_threshold, '--seuiltest', self.source_threshold, '--error', self.error_epsilon, '--graylevel', self.gray_level, '--index', self.index_optimized ] if self.init_with_gravity_center: command += ['--gcinit', 'yes'] else: command += ['--gcinit', 'no'] if self.initial_translation_x is not None: command += ['--Tx', self.initial_translation_x] if self.initial_translation_y is not None: command += ['--Ty', self.initial_translation_y] if self.initial_translation_z is not None: command += ['--Tz', self.initial_translation_z] if self.initial_rotation_x is not None: command += ['--Rx', self.initial_rotation_x] if self.initial_rotation_y is not None: command += ['--Ry', self.initial_rotation_y] if self.initial_rotation_z is not None: command += ['--Rz', self.initial_rotation_z] if self.step_translation_x is not None: command += ['--dTx', self.step_translation_x] if self.step_translation_y is not None: command += ['--dTy', self.step_translation_y] if self.step_translation_z is not None: command += ['--dTz', self.step_translation_z] if self.step_rotation_x is not None: command += ['--dRx', self.step_rotation_x] if self.step_rotation_y is not None: command += ['--dRy', self.step_rotation_y] if self.step_rotation_z is not None: command += ['--dRz', self.step_rotation_z] context.system(*command) if self.resampled_image is not None: context.runProcess('ApplyTransformation', image=self.source_image, transformation=self.source_to_reference, interpolation=self.resampled_interpolation, resampled_grid_geometry=self.source_image, resampled=self.resampled_image)
def execution( self, context ): if loadmat is None: return self.matlabExecution( context ) # scipy / numpy / pyaims execution aim = self.source_volume amat = self.read bim = self.registered_volume if self.registered_volume is not None: bmatname = self.registered_volume.fullName() + '.mat' bmat = self.central_to_registered if bmat is None: context.write( 'No destination transformation - ' \ 'taking its origin translation' ) # bim = None else: bmat = None context.write( 'No destination volume - going only to central ref' ) aattrs = aimsGlobals.aimsVolumeAttributes( aim ) # context.write( 'aatrs: ', aattrs ) if bim: battrs = aimsGlobals.aimsVolumeAttributes( bim ) # context.write( 'battrs: ', battrs ) dim1 = aattrs[ 'volume_dimension' ][:3] vox1 = aattrs[ 'voxel_size' ][:3] t1 = aims.Motion( aattrs[ 'transformations' ][0] ) s2m = aims.Motion( aattrs[ 'storage_to_memory' ] ) mvox1 = aims.Motion() mvox1.rotation().setValue( vox1[0], 0, 0 ) mvox1.rotation().setValue( vox1[1], 1, 1 ) mvox1.rotation().setValue( vox1[2], 2, 2 ) tn = t1 * s2m * mvox1 origin1 = tn.inverse().transform( aims.Point3df( 0, 0, 0 ) ) origin1 += aims.Point3df( 1, 1, 1 ) # add 1 to matlab coords if bim: dim2 = battrs[ 'volume_dimension' ][:3] vox2 = battrs[ 'voxel_size' ][:3] t2 = aims.Motion( battrs[ 'transformations' ][0] ) s2m2 = aims.Motion( battrs[ 'storage_to_memory' ] ) mvox2 = aims.Motion() mvox2.rotation().setValue( vox2[0], 0, 0 ) mvox2.rotation().setValue( vox2[1], 1, 1 ) mvox2.rotation().setValue( vox2[2], 2, 2 ) tn = t2 * s2m2 * mvox2 origin2 = tn.inverse().transform( aims.Point3df( 0, 0, 0 ) ) origin2 += aims.Point3df( 1, 1, 1 ) # add 1 to matlab coords else: dim2 = [ 0, 0, 0 ] vox2 = [ 1, 1, 1 ] origin2 = [ 0, 0, 0 ] # context.write( 'dim1:', str( dim1 ) ) # context.write( 'vox1:', str( vox1 ) ) # context.write( 'origin1:', str( origin1 ) ) # context.write( 'dim2', str( dim2 ) ) # context.write( 'vox2:', str( vox2 ) ) # context.write( 'origin2:', str( origin2 ) ) # create matlab script DIM1 = numpy.transpose( numpy.mat( dim1 ) ) VOX1 = numpy.transpose( numpy.mat( vox1 ) ) ORIGIN1 = numpy.transpose( numpy.mat( origin1 ) ) DIM2 = numpy.transpose( numpy.mat( dim2 ) ) VOX2 = numpy.transpose( numpy.mat( vox2 ) ) ORIGIN2 = numpy.transpose( numpy.mat( origin2 ) ) trans1 = self.write.fullPath() if os.path.exists( amat.fullPath() ): a = loadmat( amat.fullPath() ) aM = numpy.mat( a[ 'M' ] ).astype( numpy.double ) aM = aM * numpy.mat( numpy.diag( [ 1./vox1[0], 1./vox1[1], 1./vox1[2], 1. ] ) ) else: aM = numpy.mat( numpy.diag( [ 1., 1., 1., 1., ] ) ) aM[ 0:3, 3 ] = - numpy.multiply( ORIGIN1, VOX1 ) ainv = numpy.linalg.inv( aM ) o1 = ainv[:, 3 ] # Y and Z axis are flipped o1[ 1:3 ] = -o1[ 1:3 ] + numpy.multiply( ( DIM1[1:3] - 1 ), VOX1[1:3] ) if bmat: if os.path.exists( bmat.fullPath() ): b = loadmat( bmat.fullPath() ); bM = numpy.mat( b[ 'M' ] ).astype( numpy.double ) bM = bM * numpy.mat( numpy.diag( [ 1./vox2[0], 1./vox2[1], 1./vox2[2], 1. ] ) ) else: bM = numpy.mat( numpy.diag( [ 1., 1., 1., 1. ] ) ) bM[ 0:3, 3 ] = - numpy.multiply( ORIGIN2, VOX2 ) else: bM = numpy.mat( numpy.diag( [ 1., 1., 1., 1. ] ) ) bM[ 0:3, 3 ] = - numpy.multiply( ORIGIN2, VOX2 ) binv = numpy.linalg.inv( bM ) o2 = binv[:, 3 ] # Y and Z axis are flipped o2[ 1:3 ] = -o2[ 1:3, 0 ] + numpy.multiply( ( DIM2[1:3] - 1 ), VOX2[1:3] ) # flip Y and Z axis to go to Aims/Anatomist world aflip = numpy.mat( numpy.diag( [ 1., -1., -1., 1. ] ) ) aflip[ 1:3, 3 ] = numpy.multiply( ( DIM1[1:3] - 1 ), VOX1[1:3] ) aM = aM * aflip # verify origin still transforms to 0 # aM * o1 bflip = numpy.mat( numpy.diag( [ 1., -1., -1., 1. ] ) ) bflip[ 1:3, 3 ] = numpy.multiply( ( DIM2[1:3] - 1 ), VOX2[1:3] ) bM = bM * bflip # verify origin still transforms to 0 # bM * o2 M = numpy.linalg.inv(bM) * aM # M * o1 - o2 T = numpy.array( numpy.transpose( M[ 0:3, 3 ] ) )[ 0,: ] context.write( 'writing ', trans1 ) fid = open( trans1, 'w' ) Mt = numpy.array( numpy.transpose( M[0:3, 0:3] ) ) print('%f %f %f' % tuple( T ), file=fid) print('%f %f %f' % tuple( Mt[ 0,: ] ), file=fid) print('%f %f %f' % tuple( Mt[ 1,: ] ), file=fid) print('%f %f %f' % tuple( Mt[ 2,: ] ), file=fid) fid.close()
def matlabExecution( self, context ): aim = self.source_volume amat = self.read bim = self.registered_volume if self.registered_volume is not None: bmatname = self.registered_volume.fullName() + '.mat' bmat = self.central_to_registered if bmat is None: context.write( 'No destination transformation - ' \ 'taking its origin translation' ) # bim = None else: bmat = None context.write( 'No destination volume - going only to central ref' ) aattrs = aimsGlobals.aimsVolumeAttributes( aim ) # context.write( 'aatrs: ', aattrs ) if bim: battrs = aimsGlobals.aimsVolumeAttributes( bim ) # context.write( 'battrs: ', battrs ) dim1 = aattrs[ 'volume_dimension' ][:3] vox1 = aattrs[ 'voxel_size' ][:3] origin1 = aattrs.get( 'spm_origin' ) if not origin1: origin1 = ( 0, 0, 0 ) if bim: dim2 = battrs[ 'volume_dimension' ][:3] vox2 = battrs[ 'voxel_size' ][:3] origin2 = battrs.get( 'spm_origin' ) if not origin2: origin2 = ( 0, 0, 0 ) else: dim2 = [ 0, 0, 0 ] vox2 = [ 1, 1, 1 ] origin2 = [ 0, 0, 0 ] # context.write( 'dim1:', str( dim1 ) ) # context.write( 'vox1:', str( vox1 ) ) # context.write( 'origin1:', str( origin1 ) ) # context.write( 'dim2', str( dim2 ) ) # context.write( 'vox2:', str( vox2 ) ) # context.write( 'origin2:', str( origin2 ) ) # create matlab script matlabcom = "amat = '" if amat: matlabcom += amat.fullPath() matlabcom += "';\n" if bmat: matlabcom += "bmat = '" + bmat.fullPath() + "';\n" matlabcom += "DIM1 = " + listToVectorString( dim1 ) + ";\n" matlabcom += "VOX1 = " + listToVectorString( vox1 ) + ";\n" matlabcom += "ORIGIN1 = " + listToVectorString( origin1 ) + ";\n" matlabcom += "DIM2 = " + listToVectorString( dim2 ) + ";\n" matlabcom += "VOX2 = " + listToVectorString( vox2 ) + ";\n" matlabcom += "ORIGIN2 = " + listToVectorString( origin2 ) + ";\n" matlabcom += "trans1 = '" + self.write.fullPath() + "';\n" matlabcom += '''if( exist( amat ) ) a = load( amat ); a.M = a.M * diag( [ 1/VOX1(1) 1/VOX1(2) 1/VOX1(3) 1 ] ); disp( [ amat ' read' ] ); else a.M = diag( [ 1 1 1 1 ] ); % diag( [ VOX1(1) VOX1(2) VOX1(3) 1 ] ); a.M( 1:3, 4 ) = - ( ORIGIN1 .* VOX1 )'; end ainv = inv( a.M ); o1 = ainv( :, 4 ); % Y and Z axis are flipped o1( 2:3 ) = -o1( 2:3 ) + ( ( DIM1(2:3) - 1 ) .* VOX1(2:3) )'; ''' if bmat: matlabcom += '''if( exist( bmat ) ) b = load( bmat ); b.M = b.M * diag( [ 1/VOX2(1) 1/VOX2(2) 1/VOX2(3) 1 ] ); disp( [ bmat ' read' ] ); else b.M = diag( [ 1 1 1 1 ] ); % diag( [ VOX2(1) VOX2(2) VOX2(3) 1 ] ); b.M( 1:3, 4 ) = - ( ORIGIN2 .* VOX2 )'; end ''' else: matlabcom += '''b.M = diag( [ 1 1 1 1 ] ); % diag( [ VOX2(1) VOX2(2) VOX2(3) 1 ] ); b.M( 1:3, 4 ) = - ( ORIGIN2 .* VOX2 )'; ''' matlabcom += '''binv = inv( b.M ); o2 = binv( :, 4 ); % Y and Z axis are flipped o2( 2:3 ) = -o2( 2:3, 1 ) + ( ( DIM2(2:3) - 1 ) .* VOX2(2:3) )'; % flip Y and Z axis to go to Aims/Anatomist world aflip = diag( [ 1 -1 -1 1 ] ); aflip( 2:3, 4 ) = ( ( DIM1(2:3) - 1 ) .* VOX1(2:3) )'; a.M = a.M * aflip; % verify origin still transforms to 0 %a.M * o1 bflip = diag( [ 1 -1 -1 1 ] ); bflip( 2:3, 4 ) = ( ( DIM2(2:3) - 1 ) .* VOX2(2:3) )'; b.M = b.M * bflip; % verify origin still transforms to 0 %b.M * o2 M = inv(b.M) * a.M; disp( 'Result matrix :' ); M %M * o1 - o2 T = M( 1:3, 4 )'; disp( [ 'writing ' trans1 ] ); fid = fopen( trans1, 'w' ); if( fid == -1 ) disp( [ 'could not write ' trans1 ] ); exit 1 end fprintf( fid, '%f %f %f\\n', T ); fprintf( fid, '%f %f %f\\n', M(1:3,1:3)' ); fclose( fid ); %disp( [ 'writing ' trans2 ] ); %fid = fopen( trans2, 'w' ); %if( fid == -1 ) % disp( [ 'could not write ' trans2 ] ); % exit 1 %end %M = inv( M ); %T = M( 1:3, 4 )'; %fprintf( fid, '%f %f %f\\n', T ); %fprintf( fid, '%f %f %f\\n', M(1:3,1:3)' ); %fclose( fid ); ''' ml = matlab.matlab() ml.eval( matlabcom ) if self.removeSource: for f in self.read.fullPaths(): os.unlink( f )