def pipeline(self, data): if self.nimage.get('pipeline')[0] == 'STOCHASTIC': ####! swap x and z for volume coming from Slicer - do not forget to apply the inverse before to send them back data = data.swapaxes(2, 0) data = data.astype('float') #### shpD = data.shape shpV0 = numpy.zeros((4), 'uint16') shpV0[0] = shpD[0] shpV0[1] = shpD[1] shpV0[2] = shpD[2] shpV0[3] = shpD[3] logger.info("pipeline data shape : %s:%s:%s:%s" % (shpD[0], shpD[1], shpD[2], shpD[3])) logger.info("pipeline data type : %s" % data.dtype) orgS = self.nimage.get('origin') org = [float(orgS[0]), float(orgS[1]), float(orgS[2])] org0 = numpy.zeros((3), 'float') org0[0] = org[0] org0[1] = org[1] org0[2] = org[2] logger.info("origin : %s:%s:%s" % (org[0], org[1], org[2])) spaS = self.nimage.get('spacing') spa = [float(spaS[0]), float(spaS[1]), float(spaS[2])] spa0 = numpy.zeros((3), 'float') spa0[0] = spa[0] spa0[1] = spa[1] spa0[2] = spa[2] logger.info("spacing : %s:%s:%s" % (spa[0], spa[1], spa[2])) G = self.nimage.get('grads') b = self.nimage.get('bval') i2r = self.nimage.get('ijk2ras') i2rd = self.nimage.get('ijk2rasd') mu = self.nimage.get('mu') dims = self.nimage.get('dimensions') s = slicerd.slicerd() scene = s.ls() dscene = {} indS = [] for i in range(len(scene)): if scene[i].isdigit(): indS.append(i) for j in range(len(indS)): if j < len(indS) - 1: tmpD2 = '' tmpD = scene[indS[j] + 2:indS[j + 1]] for k in range(len(tmpD)): if k < len(tmpD) - 1: tmpD2 += tmpD[k] + ' ' else: tmpD2 += tmpD[k] dscene[tmpD2] = j else: tmpD2 = '' tmpD = scene[indS[j] + 2:] for k in range(len(tmpD)): if k < len(tmpD) - 1: tmpD2 += tmpD[k] + ' ' else: tmpD2 += tmpD[k] dscene[tmpD2] = j logger.info("scene : %s" % dscene) # currently there is a bug in the GUI of slicer python - do not load if three times the same volume isInRoiA = False if self.params.hasKey('roiA'): if dscene.has_key(self.params.get('roiA')[0]): self.roiA = s.get(int(dscene[self.params.get('roiA')[0]])) roiAR = numpy.fromstring(self.roiA.getImage(), 'uint16') if roiAR.shape[0] == shpD[2] * shpD[1] * shpD[0]: roiAR = roiAR.reshape( shpD[2], shpD[1], shpD[0] ) # because come from Slicer - will not send them back so swap them one for all roiAR = roiAR.swapaxes(2, 0) roiAR[roiAR > 0] = 1 self.roiA.setImage(roiAR) isInRoiA = True logger.info( "RoiA : %s:%s:%s" % (roiAR.shape[0], roiAR.shape[1], roiAR.shape[2])) else: logger.info( "RoiA has not the same dimension as the DWI : %s" % roiAR.shape[0]) isInRoiB = False if self.params.hasKey('roiB'): if dscene.has_key(self.params.get('roiB')[0]): if self.params.get('roiB')[0] != self.params.get( 'roiA')[0]: self.roiB = s.get( int(dscene[self.params.get('roiB')[0]])) roiBR = numpy.fromstring(self.roiB.getImage(), 'uint16') if roiBR.shape[0] == shpD[2] * shpD[1] * shpD[0]: roiBR = roiBR.reshape(shpD[2], shpD[1], shpD[0]) roiBR = roiBR.swapaxes(2, 0) roiBR[roiBR > 0] = 1 self.roiB.setImage(roiBR) isInRoiB = True logger.info("RoiB : %s:%s:%s" % (roiBR.shape[0], roiBR.shape[1], roiBR.shape[2])) else: logger.info( "RoiB has not the same dimension as the DWI : %s" % roiBR.shape[0]) isInWM = False if self.params.hasKey('wm'): if dscene.has_key(self.params.get('wm')[0]): self.wm = s.get(int(dscene[self.params.get('wm')[0]])) wmR = numpy.fromstring(self.wm.getImage(), 'uint16') if wmR.shape[0] == shpD[2] * shpD[1] * shpD[0]: wmR = wmR.reshape(shpD[2], shpD[1], shpD[0]) wmR = wmR.swapaxes(2, 0) self.wm.setImage(wmR) isInWM = True logger.info("WM : %s:%s:%s" % (wmR.shape[0], wmR.shape[1], wmR.shape[2])) else: logger.info( "WM has not the same dimension as the DWI : %s" % wmR.shape[0]) isInTensor = False if self.params.hasKey('tensor'): if dscene.has_key(self.params.get('tensor')[0]): self.ten = s.get(int(dscene[self.params.get('tensor')[0]])) tenR = numpy.fromstring(self.ten.getImage(), 'float32') if tenR.shape[0] == shpD[2] * shpD[1] * shpD[0] * 7: tenR = tenR.reshape(shpD[2], shpD[1], shpD[0], 7) tenR = tenR.swapaxes(2, 0) self.ten.setImage(tenR) isInTensor = True logger.info("Tensor : %s:%s" % (tenR.shape[0], tenR.shape[1])) else: logger.info( "Tensor has not the same dimension as the DWI : %s" % tenR.shape[0]) logger.info("Input volumes loaded!") # values per default smoothEnabled = False wmEnabled = True infWMThres = 300 supWMThres = 900 tensEnabled = True bLine = 0 stEnabled = True totalTracts = 500 maxLength = 200 stepSize = 0.5 stopEnabled = True fa = 0.0 cmEnabled = False probMode = 0 # got from client # special handling for bools if self.params.hasKey('smoothEnabled'): smoothEnabled = bool(int(self.params.get('smoothEnabled')[0])) if self.params.hasKey('wmEnabled'): wmEnabled = bool(int(self.params.get('wmEnabled')[0])) if self.params.hasKey('tensEnabled'): tensEnabled = bool(int(self.params.get('tensEnabled')[0])) if self.params.hasKey('stEnabled'): stEnabled = bool(int(self.params.get('stEnabled')[0])) if self.params.hasKey('cmEnabled'): cmEnabled = bool(int(self.params.get('cmEnabled')[0])) if self.params.hasKey('spaceEnabled'): spaceEnabled = bool(int(self.params.get('spaceEnabled')[0])) if self.params.hasKey('stopEnabled'): stopEnabled = bool(int(self.params.get('stopEnabled')[0])) if self.params.hasKey('faEnabled'): faEnabled = bool(int(self.params.get('faEnabled')[0])) if self.params.hasKey('traceEnabled'): traceEnabled = bool(int(self.params.get('traceEnabled')[0])) if self.params.hasKey('modeEnabled'): modeEnabled = bool(int(self.params.get('modeEnabled')[0])) if self.params.hasKey('sphericalEnabled'): sphericalEnabled = bool( int(self.params.get('sphericalEnabled')[0])) # can handle normally FWHM = numpy.ones((3), 'float') if self.params.hasKey('stdDev'): FWHM[0] = float(self.params.get('stdDev')[0]) FWHM[1] = float(self.params.get('stdDev')[1]) FWHM[2] = float(self.params.get('stdDev')[2]) logger.debug("FWHM: %s:%s:%s" % (FWHM[0], FWHM[1], FWHM[2])) if self.params.hasKey('infWMThres'): infWMThres = int(self.params.get('infWMThres')[0]) logger.debug("infWMThres: %s" % infWMThres) if self.params.hasKey('supWMThres'): supWMThres = int(self.params.get('supWMThres')[0]) logger.debug("supWMThres: %s" % supWMThres) if self.params.hasKey('bLine'): bLine = int(self.params.get('bLine')[0]) logger.debug("bLine: %s" % bLine) if self.params.hasKey('isIJK'): isIJK = bool(int(self.params.get('isIJK')[0])) logger.debug("isIJK: %s" % isIJK) if self.params.hasKey('tensMode'): tensMode = self.params.get('tensMode')[0] logger.debug("tensMode: %s" % tensMode) if self.params.hasKey('totalTracts'): totalTracts = int(self.params.get('totalTracts')[0]) logger.debug("totalTracts: %s" % totalTracts) if self.params.hasKey('maxLength'): maxLength = int(self.params.get('maxLength')[0]) logger.debug("maxLength: %s" % maxLength) if self.params.hasKey('stepSize'): stepSize = float(self.params.get('stepSize')[0]) logger.debug("stepSize: %s" % stepSize) if self.params.hasKey('fa'): fa = float(self.params.get('fa')[0]) logger.debug("fa: %s" % fa) if self.params.hasKey('probMode'): probMode = self.params.get('probMode')[0] logger.debug("probMode: %s" % probMode) if self.params.hasKey('lengthEnabled'): lengthEnabled = self.params.get('lengthEnabled')[0] logger.debug("lengthEnabled: %s" % lengthEnabled) if self.params.hasKey('lengthClass'): lengthClass = self.params.get('lengthClass')[0] logger.debug("lengthClass: %s" % lengthClass) if self.params.hasKey('tractOffset'): tractOffset = int(self.params.get('tractOffset')[0]) logger.debug("tractOffset: %s" % tractOffset) if self.params.hasKey('vicinity'): vicinity = int(self.params.get('vicinity')[0]) logger.debug("vicinity: %s" % vicinity) if self.params.hasKey('threshold'): threshold = float(self.params.get('threshold')[0]) logger.debug("threshold: %s" % threshold) ngrads = shpD[3] logger.info("Number of gradients : %s" % str(ngrads)) G = G.reshape((ngrads, 3)) b = b.reshape((ngrads, 1)) i2r = i2r.reshape((4, 4)) i2rd = i2rd.reshape((4, 4)) mu = mu.reshape((4, 4)) r2i = numpy.linalg.inv(i2r) r2id = numpy.linalg.inv(i2rd) # compute trafo fir IJK & RAS # gradients in RAS G1 = numpy.dot(G, mu[:3, :3].T) # gradients in IJK mu2 = numpy.dot(r2id[:3, :3], mu[:3, :3]) G2 = numpy.dot(G, mu2[:3, :3].T) # switch to compute either in IJK or RAS if isIJK: G0 = G2 else: G0 = G1 vts = vects.vectors logger.info("Tensor flag : %s" % str(tensEnabled)) if smoothEnabled: for k in range(shpD[3]): timeSM0 = time.time() data[..., k] = sm.smooth( data[..., k], FWHM, numpy.array([spa[0], spa[1], spa[2]], 'float')) logger.info("Smoothing DWI volume %i in %s sec" % (k, str(time.time() - timeSM0))) if wmEnabled: wm = tens.EvaluateWM0(data, bLine, infWMThres, supWMThres) if isInRoiA: # correcting brain mask with roi A logger.info("Correcting mask based on roiA") tmpA = self.roiA.getImage() wm[tmpA > 0] = 1 if isInRoiB: # correcting brain mask with roi A & B logger.info("Correcting mask based on roiB") tmpB = self.roiB.getImage() wm[tmpB > 0] = 1 else: # avoid singularities in data minVData = 10 wm = tens.EvaluateWM0(data, bLine, minVData, data[..., bLine].max()) if isInWM: logger.info("Using external mask") wm = self.wm.getImage() if tensEnabled: logger.info("Compute tensor") timeS1 = time.time() if not isInTensor: EV, lV, xVTensor, xYTensor = tens.EvaluateTensorX1( data, G0.T, b.T, wm) else: EV, lV, xVTensor, xYTensor = tens.EvaluateTensorK1( self.ten.getImage(), shpD, wm) logger.info("Compute tensor in %s sec" % str(time.time() - timeS1)) if faEnabled: faMap = tensC.CalculateFA0(lV) if traceEnabled: trMap = tensC.CalculateTrace0(lV) if modeEnabled: moMap = tensC.CalculateMode0(lV) if cmEnabled: logger.info("Track fibers") if not stopEnabled: fa = 0.0 if isInRoiA: # ROI A logger.info("Search ROI A") roiP = cmpV.march0InVolume(self.roiA.getImage()) shpR = roiP.shape logger.info("ROI A dimension : %s:%s" % (str(shpR[0]), str(shpR[1]))) blocksize = totalTracts IJKstartpoints = numpy.tile(roiP, (blocksize, 1)) logger.info("IJK start points shape : %s" % str(IJKstartpoints.shape)) timeS2 = time.time() logger.info("Data type : %s" % data.dtype) if tensEnabled: paths00, paths01, paths02, paths03, paths04 = track.TrackFiberZ40(s, wm, shpD, b.T, G0.T, vts.T, IJKstartpoints.T,\ r2i, i2r, r2id, i2rd, spa, lV, EV, xVTensor, stepSize, maxLength, fa, spaceEnabled, isIJK) else: paths00, paths01, paths02, paths03, paths04 = track.TrackFiberX40(s, data.flatten(), wm, shpD, b.T, G0.T, vts.T, IJKstartpoints.T,\ r2i, i2r, r2id, i2rd, spa, stepSize, maxLength, fa, spaceEnabled, isIJK) logger.info("Track fibers in %s sec" % str(time.time() - timeS2)) logger.info("Connect tract") if probMode == 'binary': cm = track.ConnectFibersX0(paths01, paths04, shpD, lengthEnabled, lengthClass) elif probMode == 'cumulative': cm = track.ConnectFibersX1(paths01, paths04, shpD, lengthEnabled, lengthClass) else: cm = track.ConnectFibersX2(paths01, paths04, shpD, lengthEnabled, lengthClass) if isInRoiB: # ROI B logger.info("Search ROI B") roiP2 = cmpV.march0InVolume(self.roiB.getImage()) shpR2 = roiP2.shape logger.info("ROI B dimension : %s:%s" % (str(shpR2[0]), str(shpR2[1]))) blocksize = totalTracts IJKstartpoints2 = numpy.tile(roiP2, (blocksize, 1)) logger.info("IJK start points shape : %s" % str(IJKstartpoints2.shape)) timeS3 = time.time() logger.info("Data type : %s" % data.dtype) if tensEnabled: paths10, paths11, paths12, paths13, paths14 = track.TrackFiberZ40(s, wm, shpD, b.T, G0.T, vts.T, IJKstartpoints2.T,\ r2i, i2r, r2id, i2rd, spa, lV, EV, xVTensor, stepSize, maxLength, fa, spaceEnabled, isIJK) else: paths10, paths11, paths12, paths13, paths14 = track.TrackFiberX40(s, data.flatten(), wm, shpD, b.T, G0.T, vts.T, IJKstartpoints2.T,\ r2i, i2r, r2id, i2rd, spa, stepSize, maxLength, fa, spaceEnabled, isIJK) logger.info("Track fibers in %s sec" % str(time.time() - timeS3)) logger.info("Connect tract") if probMode == 'binary': cm2 = track.ConnectFibersX0(paths11, paths14, shpD, lengthEnabled, lengthClass) elif probMode == 'cumulative': cm2 = track.ConnectFibersX1(paths11, paths14, shpD, lengthEnabled, lengthClass) else: cm2 = track.ConnectFibersX2(paths11, paths14, shpD, lengthEnabled, lengthClass) if isInRoiA and isInRoiB: cm3 = track.FilterFibers0(paths00, paths01, paths02, paths03, paths04, self.roiA.getImage(), self.roiB.getImage(),\ shpD, threshold, tractOffset, vicinity, sphericalEnabled) cm4 = track.FilterFibers0(paths10, paths11, paths12, paths13, paths14, self.roiB.getImage(), self.roiA.getImage(),\ shpD, threshold, tractOffset, vicinity, sphericalEnabled) else: logger.info("No tractography to execute!") dateT = str(int(round(time.time()))) isDir = os.access('outputs', os.F_OK) if not isDir: os.mkdir('outputs') tmpF = './outputs/' i2r.tofile(tmpF + 'trafo_' + dateT + '.ijk') if smoothEnabled: ga = data[..., bLine] ga = ga.swapaxes(2, 0) tmp = 'smooth_' + dateT if not (ga == 0).all(): ga.tofile(tmpF + tmp + '.data') createParams(ga, tmpF + tmp) s.putS(ga, dims, org, i2r, tmp) #if wmEnabled: wm = wm.swapaxes(2, 0) tmp = 'brain_' + dateT if not (wm == 0).all(): wm.tofile(tmpF + tmp + '.data') createParams(wm, tmpF + tmp) s.putS(wm, dims, org, i2r, tmp) if tensEnabled: if isIJK: xVTensor = xVTensor.swapaxes(2, 0) xVTensor = xVTensor.astype( 'float32') # slicerd do not support double type yet xYTensor = xYTensor.swapaxes(2, 0) xYTensor = xYTensor.astype( 'float32') # slicerd do not support double type yet tmp = 'tensor_' + dateT if (not (xYTensor == 0).all()) and (not (xVTensor == 0).all()): xYTensor.tofile(tmpF + tmp + '.data') createParams(xYTensor, tmpF + tmp, True) s.putD(xVTensor, dims, org, i2r, mu, tmp) if faEnabled: faMap = faMap.swapaxes(2, 0) tmp = 'fa_' + dateT if not (faMap == 0).all(): faMap.tofile(tmpF + tmp + '.data') createParams(faMap, tmpF + tmp) s.putS(faMap, dims, org, i2r, tmp) if traceEnabled: trMap = trMap.swapaxes(2, 0) tmp = 'trace_' + dateT if not (trMap == 0).all(): trMap.tofile(tmpF + tmp + '.data') createParams(trMap, tmpF + tmp) s.putS(trMap, dims, org, i2r, tmp) if modeEnabled: moMap = moMap.swapaxes(2, 0) tmp = 'mode_' + dateT if not (moMap == 0).all(): moMap.tofile(tmpF + tmp + '.data') createParams(moMap, tmpF + tmp) s.putS(moMap, dims, org, i2r, tmp) if cmEnabled: if isInRoiA: cm = cm.swapaxes(2, 0) tmp = 'cmA_' + dateT if not (cm == 0).all(): cm.tofile(tmpF + tmp + '.data') createParams(cm, tmpF + tmp) #s.putS(cm, dims, org, i2r, tmp) tmp = 'cmFA_' + dateT cmf = cm / float(cm.max()) cmf.astype('float32') if not (cmf == 0).all(): cmf.tofile(tmpF + tmp + '.data') createParams(cmf, tmpF + tmp) s.putS(cmf, dims, org, i2r, tmp) if isInRoiB: cm2 = cm2.swapaxes(2, 0) tmp = 'cmB_' + dateT if not (cm2 == 0).all(): cm2.tofile(tmpF + tmp + '.data') createParams(cm2, tmpF + tmp) #s.putS(cm2, dims, org, i2r, tmp) tmp = 'cmFB_' + dateT cm2f = cm2 / float(cm2.max()) cm2f.astype('float32') if not (cm2f == 0).all(): cm2f.tofile(tmpF + tmp + '.data') createParams(cm2f, tmpF + tmp) s.putS(cm2f, dims, org, i2r, tmp) if isInRoiA and isInRoiB: cm1a2 = cm[...] * cm2[...] / 2.0 cm1a2 = cm1a2.astype('uint32') if not (cm1a2 == 0).all(): tmp = 'cmAandB_' + dateT cm1a2.tofile(tmpF + tmp + '.data') createParams(cm1a2, tmpF + tmp) #s.putS(cm1a2, dims, org, i2r, tmp) tmp = 'cmFAandB_' + dateT cm1a2f = cm1a2 / float(cm1a2.max()) cm1a2f.astype('float32') cm1a2f.tofile(tmpF + tmp + '.data') createParams(cm1a2f, tmpF + tmp) s.putS(cm1a2f, dims, org, i2r, tmp) cm1o2 = (cm[...] + cm2[...]) / 2.0 cm1o2 = cm1o2.astype('uint32') if not (cm1o2 == 0).all(): tmp = 'cmAorB_' + dateT cm1o2.tofile(tmpF + tmp + '.data') createParams(cm1o2, tmpF + tmp) #s.putS(cm1o2, dims, org, i2r, tmp) tmp = 'cmFAorB_' + dateT cm1o2f = cm1o2 / float(cm1o2.max()) cm1o2f.astype('float32') cm1o2f.tofile(tmpF + tmp + '.data') createParams(cm1o2f, tmpF + tmp) s.putS(cm1o2f, dims, org, i2r, tmp) if not (cm3 == 0).all(): tmp = 'cmA2B_' + dateT cm3 = cm3.swapaxes(2, 0) cm3.tofile(tmpF + tmp + '.data') createParams(cm3, tmpF + tmp) #s.putS(cm3, dims, org, i2r, tmp) tmp = 'cmFA2B_' + dateT cm3f = cm3 / float(cm3.max()) cm3f.astype('float32') cm3f.tofile(tmpF + tmp + '.data') createParams(cm3f, tmpF + tmp) s.putS(cm3f, dims, org, i2r, tmp) if not (cm4 == 0).all(): tmp = 'cmB2A_' + dateT cm4 = cm4.swapaxes(2, 0) cm4.tofile(tmpF + tmp + '.data') createParams(cm4, tmpF + tmp) #s.putS(cm4, dims, org, i2r, tmp) tmp = 'cmFB2A_' + dateT cm4f = cm4 / float(cm4.max()) cm4f.astype('float32') cm4f.tofile(tmpF + tmp + '.data') createParams(cm4f, tmpF + tmp) s.putS(cm4f, dims, org, i2r, tmp) logger.debug("pipeline data shape end : %s:%s:%s:%s" % (shpD[0], shpD[1], shpD[2], shpD[3])) return data
def pipeline(params, nimage, roiA, roiB, wm): if params.get('pipeline')=='STOCHASTIC': #print "Pipeline : STOCHASTIC" ppserversL=("localhost",) #ppserversL=("*",) data = nimage.getImage() ####! swap x and z for volume coming from Slicer - do not forget tp apply the inverse before to send them back data = data.swapaxes(2,0) print 'pipeline data type : %s' % str(data.dtype) #### shpD = data.shape print 'pipeline data shape : %s' % str(shpD) orgS = nimage.get('origin') org = [float(orgS[0]), float(orgS[1]), float(orgS[2])] print 'Origin : %s:%s:%s' % (str(org[0]), str(org[1]), str(org[2])) spaS = nimage.get('spacing') spa = [float(spaS[0]), float(spaS[1]), float(spaS[2])] print 'Spacing : %s:%s:%s' % (str(spa[0]), str(spa[1]), str(spa[2])) G = nimage.get('grads') b = nimage.get('bval') i2r = nimage.get('ijk2ras') i2rd = nimage.get('ijk2rasd') mu = nimage.get('mu') dims = nimage.get('dimensions') #print 'DWI : ', params.get('dwi') isInRoiA = False if params.hasKey('roiA'): roiAR = numpy.fromstring(roiA.getImage(), 'uint16') roiAR = roiAR.reshape(shpD[2], shpD[1], shpD[0]) # because come from Slicer - will not send them back so swap them one for all roiAR = roiAR.swapaxes(2,0) roiAR[roiAR>0]=1 roiA.setImage(roiAR) isInRoiA = True #print "RoiA : %s" % str(roiAR.shape) isDir = os.access('paths0', os.F_OK) if not isDir: os.mkdir('paths0') isInRoiB = False if params.hasKey('roiB'): if params.get('roiB') != params.get('roiA'): roiBR = numpy.fromstring(roiB.getImage(), 'uint16') roiBR = roiBR.reshape(shpD[2], shpD[1], shpD[0]) roiBR = roiBR.swapaxes(2,0) roiBR[roiBR>0]=1 roiB.setImage(roiBR) isInRoiB = True #print "RoiB : %s" % str(roiBR.shape) isDir = os.access('paths1', os.F_OK) if not isDir: os.mkdir('paths1') isInWM = False if params.hasKey('wm'): wmR = numpy.fromstring(wm.getImage(), 'uint16') wmR = wmR.reshape(shpD[2], shpD[1], shpD[0]) wmR = wmR.swapaxes(2,0) wm.setImage(wmR) isInWM = True #print "WM : %s" % str(wmR.shape) isInTensor = False print "Input volumes loaded!" # values per default smoothEnabled = False wmEnabled = True infWMThres = 300 supWMThres = 900 tensEnabled =True bLine = 0 stEnabled = True totalTracts = 500 maxLength = 200 stepSize = 0.5 stopEnabled = True fa = 0.0 cmEnabled = False probMode = 0 # got from client # special handling for bools if params.hasKey('smoothEnabled'): smoothEnabled = bool(int(params.get('smoothEnabled'))) if params.hasKey('wmEnabled'): wmEnabled = bool(int(params.get('wmEnabled'))) if params.hasKey('tensEnabled'): tensEnabled = bool(int(params.get('tensEnabled'))) if params.hasKey('stEnabled'): stEnabled = bool(int(params.get('stEnabled'))) if params.hasKey('cmEnabled'): cmEnabled = bool(int(params.get('cmEnabled'))) if params.hasKey('spaceEnabled'): spaceEnabled = bool(int(params.get('spaceEnabled'))) if params.hasKey('stopEnabled'): stopEnabled = bool(int(params.get('stopEnabled'))) if params.hasKey('faEnabled'): faEnabled = bool(int(params.get('faEnabled'))) if params.hasKey('traceEnabled'): traceEnabled = bool(int(params.get('traceEnabled'))) if params.hasKey('modeEnabled'): modeEnabled = bool(int(params.get('modeEnabled'))) # can handle normally FWHM = numpy.ones((3), 'float') if params.hasKey('stdDev'): FWHM[0] = float(params.get('stdDev')[0]) FWHM[1] = float(params.get('stdDev')[1]) FWHM[2] = float(params.get('stdDev')[2]) print "FWHM: %s:%s:%s" % (str(FWHM[0]), str(FWHM[1]), str(FWHM[2])) if params.hasKey('infWMThres'): infWMThres = int(params.get('infWMThres')) print "infWMThres: %s" % str(infWMThres) if params.hasKey('supWMThres'): supWMThres = int(params.get('supWMThres')) print "supWMThres: %s" % str(supWMThres) if params.hasKey('bLine'): bLine = int(params.get('bLine')) print "bLine: %s" % str(bLine) if params.hasKey('tensMode'): tensMode = params.get('tensMode') print "tensMode: %s" % str(tensMode) if params.hasKey('totalTracts'): totalTracts = int(params.get('totalTracts')) print "totalTracts: %s" % str(totalTracts) if params.hasKey('maxLength'): maxLength = int(params.get('maxLength')) print "maxLength: %s" % str(maxLength) if params.hasKey('stepSize'): stepSize = float(params.get('stepSize')) print "stepSize: %s" % str(stepSize) if params.hasKey('fa'): fa = float(params.get('fa')) print "fa: %s" % str(fa) if params.hasKey('probMode'): probMode = params.get('probMode') print "probMode: %s" % str(probMode) if params.hasKey('lengthEnabled'): lengthEnabled = params.get('lengthEnabled') print "lengthEnabled: %s" % str(lengthEnabled) if params.hasKey('lengthClass'): lengthClass = params.get('lengthClass') print "lengthClass: %s" % str(lengthClass) ngrads = shpD[3] #b.shape[0] print "Number of gradients : %s" % str(ngrads) G = G.reshape(ngrads,3) b = b.reshape(ngrads,1) i2r = i2r.reshape(4,4) i2rd = i2rd.reshape(4,4) mu = mu.reshape(4,4) r2i = numpy.linalg.inv(i2r) r2id = numpy.linalg.inv(i2rd) mu2 = numpy.dot(r2id[:3, :3], mu[:3, :3]) G2 = numpy.dot(G, mu2[:3, :3].T) vts = vects.vectors print "Tensor flag : %s" % str(tensEnabled) cm = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') cm2 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') cm3 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') cm4 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') if smoothEnabled: for k in range(shpD[3]): timeSM0 = time.time() data[...,k] = sm.smooth(data[...,k], FWHM, numpy.array([ spa[0], spa[1], spa[2] ],'float')) print "Smoothing DWI volume %i in %s sec" % (k, str(time.time()-timeSM0)) if wmEnabled: wm = tensPP.EvaluateWM0(data, bLine, infWMThres, supWMThres) if isInRoiA: # correcting brain mask with roi A print "Correcting mask based on roiA" tmpA = roiA.getImage() wm[tmpA>0]=1 if isInRoiB: # correcting brain mask with roi A & B print "Correcting mask based on roiB" tmpB = roiB.getImage() wm[tmpB>0]=1 else: # avoid singularities in data minVData = 10 wm = tensPP.EvaluateWM0(data, bLine, minVData, data[..., bLine].max()) wmEnabled = True # fix if isInWM or wmEnabled: isDir = os.access('masks', os.F_OK) if not isDir: os.mkdir('masks') tmpF = './masks/' numpy.save(tmpF + 'wm.npy', wm) indx = numpy.transpose(wm.nonzero()) print 'Total Number of voxels : ', shpD[0]*shpD[1]*shpD[2]*ngrads print 'Masked voxels : ', indx.shape[0]*ngrads print 'Index shape : ', indx.shape dataf = data.flatten() cId = numpy.zeros((indx.shape[0]), 'uint32') mdata = numpy.zeros((indx.shape[0], ngrads), data.dtype) for i in range(indx.shape[0]): cId[i] = indx[i][0]*shpD[1]*shpD[2]*shpD[3] + indx[i][1]*shpD[2]*shpD[3] + indx[i][2]*shpD[3] mdata[i,:]= dataf[cId[i]:cId[i]+ngrads] numpy.save(tmpF + 'index.npy', cId) numpy.save(tmpF + 'mdata.npy', mdata) if cmEnabled: print "Compute tensor" timeS1 = time.time() roiFilterOnly = False monoP = False # multiprocessing support dataBlocks = [] wmBlocks = [] nCpu = 2 # could be set to the number of available cores nParts = 1 if shpD[2]>0 and nCpu>0 : job_server = pp.Server(ppservers=ppserversL) ncpusL = job_server.get_ncpus() print "Number of cores on local machine : %s" % str(ncpusL) print "Number of active computing nodes : %s" % str(nCpu) if shpD[2] >= nCpu: nParts = nCpu else: nParts = shpD[2] for i in range(nParts): datax = data[:, :, i*shpD[2]/nParts:(i+1)*shpD[2]/nParts, :] print "data block %i dimension : %s" % (i, str(datax.shape)) dataBlocks.append(datax) if isInWM or wmEnabled: wmx = wm[:, :, i*shpD[2]/nParts:(i+1)*shpD[2]/nParts] wmBlocks.append(wmx) else: monoP = True if not monoP: jobs = [] job_server.set_ncpus(ncpus = ncpusL) for i in range(nParts): jobs.append(job_server.submit(tensPP.EvaluateTensorX1, (dataBlocks[i], G2.T, b.T, wmBlocks[i],),(tensPP.ComputeAFunctional, tensPP.ComputeTensorFunctional,), ("numpy","time",) )) tBlocks = [] for i in range(nParts): tBlocks.append(jobs[i]()) lV = numpy.zeros((shpD[0], shpD[1], shpD[2], 3) , 'float') EV = numpy.zeros((shpD[0], shpD[1], shpD[2], 3, 3), 'float' ) xVTensor = numpy.zeros((shpD[0], shpD[1], shpD[2], 7), 'float') xYTensor = numpy.zeros((shpD[0], shpD[1], shpD[2], 9), 'float') xTensor0 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'float') for i in range(nParts): EV[:, :, i*shpD[2]/nParts:(i+1)*shpD[2]/nParts, ...]= tBlocks[i][0] lV[:, :, i*shpD[2]/nParts:(i+1)*shpD[2]/nParts, :]= tBlocks[i][1] xVTensor[:, :, i*shpD[2]/nParts:(i+1)*shpD[2]/nParts, ...]= tBlocks[i][2] xYTensor[:, :, i*shpD[2]/nParts:(i+1)*shpD[2]/nParts, ...]= tBlocks[i][3] xTensor0[...]= xVTensor[..., 0] lVType = lV.dtype EVType = EV.dtype xVTensorType = xVTensor.dtype wmType = wm.dtype # computation of alpha, beta, logmu0 and principal eigenvector tdata = numpy.zeros((indx.shape[0], 6), 'float') for i in range(indx.shape[0]): cId[i] = indx[i][0]*shpD[1]*shpD[2]*shpD[3] + indx[i][1]*shpD[2]*shpD[3] + indx[i][2]*shpD[3] l = lV[indx[i][0], indx[i][1], indx[i][2], :] index = numpy.argsort(abs(l))[::-1] l =l[index,:] # Set point estimates in the Constrained model E = EV[indx[i][0], indx[i][1], indx[i][2], ...] alpha = (l[1]+l[2])/2 beta = l[0] - alpha logmu0 = xTensor0[indx[i][0], indx[i][1], indx[i][2]] e = E[:, index[0]] tdata[i,0]= alpha tdata[i,1]= beta tdata[i,2]= logmu0 tdata[i,3:]= e numpy.save(tmpF + 'tdata.npy', tdata) isDir = os.access('tensors', os.F_OK) if not isDir: os.mkdir('tensors') tmpF = './tensors/' numpy.save(tmpF + 'eigenv.npy', EV) numpy.save(tmpF + 'lambda.npy', lV) numpy.save(tmpF + 'tensor.npy', xVTensor) numpy.save(tmpF + 'tensor0.npy', xTensor0) numpy.save(tmpF + 'vectors.npy', vts.T) dateT = str(int(round(time.time()))) isDir = os.access('outputs', os.F_OK) if not isDir: os.mkdir('outputs') tmpF = './outputs/' i2r.tofile(tmpF + 'trafo_' + dateT + '.ijk') if smoothEnabled: ga = data[..., bLine] ga = ga.swapaxes(2,0) tmp= 'smooth_' + dateT ga.tofile(tmpF + tmp + '.data') createParams(ga, tmpF + tmp) if wmEnabled: wm = wm.swapaxes(2,0) tmp= 'brain_' + dateT wm.tofile(tmpF + tmp + '.data') createParams(wm, tmpF + tmp) if cmEnabled: xVTensor = xVTensor.swapaxes(2,0) xVTensor = xVTensor.astype('float32') # slicerd do not support double type yet xYTensor = xYTensor.swapaxes(2,0) xYTensor = xYTensor.astype('float32') # slicerd do not support double type yet tmp= 'tensor_' + dateT xYTensor.tofile(tmpF + tmp + '.data') createParams(xYTensor, tmpF + tmp, True) if faEnabled: faMap = tensPP.CalculateFA0(lV) faMap = faMap.swapaxes(2,0) tmp= 'fa_' + dateT faMap.tofile(tmpF + tmp + '.data') createParams(faMap, tmpF + tmp) if traceEnabled: trMap = tensPP.CalculateTrace0(lV) trMap = trMap.swapaxes(2,0) tmp= 'trace_' + dateT trMap.tofile(tmpF + tmp + '.data') createParams(trMap, tmpF + tmp) if modeEnabled: moMap = tensPP.CalculateMode0(lV) moMap = moMap.swapaxes(2,0) tmp= 'mode_' + dateT moMap.tofile(tmpF + tmp + '.data') createParams(moMap, tmpF + tmp) del tBlocks del dataBlocks del wmBlocks del lV del EV del xVTensor del xYTensor else: pass print "Compute tensor in %s sec" % str(time.time()-timeS1) print "Track fibers" if not stopEnabled: fa = 0.0 if isInRoiA: # ROI A print "Search ROI A" roiP = cmpV.march0InVolume(roiA.getImage()) shpR = roiP.shape print "ROI A dimension : %s" % str(shpR) blocksize = totalTracts IJKstartpoints = [] monoP = False nParts = 1 if shpR[0]>0 and nCpu>0 : if shpR[0] >= nCpu: nParts = nCpu else: nParts = shpR[0] for i in range(nParts): roiPx = roiP[i*shpR[0]/nParts:(i+1)*shpR[0]/nParts, :] print "ROI A %i dimension : %s" % (i, str(roiPx.shape)) IJKstartpoints.append(numpy.tile(roiPx,( blocksize, 1))) else: IJKstartpoints.append(numpy.tile(roiP,( blocksize, 1))) monoP = True timeS2 = time.time() # multiprocessing print "Data type : %s" % str(data.dtype) if not monoP: jobs = [] for i in range(nParts): jobs.append(job_server.submit(trackPP.TrackFiberYFM40, (i, 0, params.get('location'), nimage.get('fullname'), nimage.get('type'), shpD, b.T, G2.T, IJKstartpoints[i].T, r2i, i2r, r2id, i2rd, spa,\ 'vectors.npy', vects.vectors.dtype, vects.vectors.T.shape, 'lambda.npy', lVType, 'eigenv.npy', EVType, 'tensor0.npy', xVTensorType, 'wm.npy' ,\ wmType, stepSize, maxLength, fa, spaceEnabled,),(), ("numpy","time",) )) res = jobs[0]() for i in range(nParts-1): res = jobs[i+1]() print "Track fibers in %s sec" % str(time.time()-timeS2) if not roiFilterOnly: print "Connect tract" jobs = [] cm = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') for j in range(nParts): print "Number of paths : %s" % str(IJKstartpoints[j].shape[0]) pathsIJKId = './paths0/' + 'unit_' + str(j) + '_IJK.npy' pathsLENId = './paths0/' + 'unit_' + str(j) + '_LEN.npy' if probMode=='binary': jobs.append(job_server.submit(trackPP.ConnectFibersPZM0, ( params.get('location'), pathsIJKId, pathsLENId, shpD, lengthEnabled),\ (trackPP.ComputeConnectFibersFunctionalP0, trackPP.ComputeConnectFibersFunctionalP1, trackPP.ComputeConnectFibersFunctionalP2,),\ ("numpy","time",) )) elif probMode=='cumulative': jobs.append(job_server.submit(trackPP.ConnectFibersPZM1, ( params.get('location'), pathsIJKId, pathsLENId, shpD, lengthEnabled),\ (trackPP.ComputeConnectFibersFunctionalP0, trackPP.ComputeConnectFibersFunctionalP1, trackPP.ComputeConnectFibersFunctionalP2,),\ ("numpy","time",) )) else: jobs.append(job_server.submit(trackPP.ConnectFibersPZM2, ( params.get('location'), pathsIJKId, pathsLENId, shpD, lengthEnabled),\ (trackPP.ComputeConnectFibersFunctionalP0, trackPP.ComputeConnectFibersFunctionalP1, trackPP.ComputeConnectFibersFunctionalP2,),\ ("numpy","time",) )) cm = jobs[0]() for j in range(nParts-1): cm += jobs[j+1]() else: pass if isInRoiB: # ROI B print "Search ROI B" roiP2 = cmpV.march0InVolume(roiB.getImage()) shpR2 = roiP2.shape print "ROI B dimension : %s" % str(shpR2) blocksize = totalTracts IJKstartpoints2 = [] monoP = False nParts2 = 1 if shpR2[0]>0 and nCpu>0 : if shpR2[0] >= nCpu: nParts2 = nCpu else: nParts2 = shpR2[0] for i in range(nParts2): roiPx = roiP2[i*shpR2[0]/nParts2:(i+1)*shpR2[0]/nParts2, :] print "ROI B %i dimension : %s" % (i, str(roiPx.shape)) IJKstartpoints2.append(numpy.tile(roiPx,( blocksize, 1))) else: IJKstartpoints2.append(numpy.tile(roiP2,( blocksize, 1))) monoP = True timeS3 = time.time() # multiprocessing print "Data type : %s" % str(data.dtype) if not monoP: jobs = [] for i in range(nParts2): jobs.append(job_server.submit(trackPP.TrackFiberYFM40, (i, 1, params.get('location'), nimage.get('fullname'), nimage.get('type'), shpD, b.T, G2.T, IJKstartpoints2[i].T, r2i, i2r, r2id, i2rd, spa,\ 'vectors.npy', vects.vectors.dtype, vects.vectors.T.shape, 'lambda.npy', lVType, 'eigenv.npy', EVType, 'tensor0.npy', xVTensorType, 'wm.npy' ,\ wmType, stepSize, maxLength, fa, spaceEnabled,),(), ("numpy","time",) )) res = jobs[0]() for i in range(nParts2-1): res = jobs[i+1]() print "Track fibers in %s sec" % str(time.time()-timeS3) if not roiFilterOnly: print "Connect tract" jobs = [] cm2 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') for j in range(nParts2): print "Number of paths : %s" % str(IJKstartpoints2[j].shape[0]) pathsIJKId = './paths1/' + 'unit_' + str(j) + '_IJK.npy' pathsLENId = './paths1/' + 'unit_' + str(j) + '_LEN.npy' if probMode=='binary': jobs.append(job_server.submit(trackPP.ConnectFibersPZM0, ( params.get('location'), pathsIJKId, pathsLENId, shpD, lengthEnabled),\ (trackPP.ComputeConnectFibersFunctionalP0, trackPP.ComputeConnectFibersFunctionalP1, trackPP.ComputeConnectFibersFunctionalP2,),\ ("numpy","time",) )) elif probMode=='cumulative': jobs.append(job_server.submit(trackPP.ConnectFibersPZM1, ( params.get('location'), pathsIJKId, pathsLENId, shpD, lengthEnabled),\ (trackPP.ComputeConnectFibersFunctionalP0, trackPP.ComputeConnectFibersFunctionalP1, trackPP.ComputeConnectFibersFunctionalP2,),\ ("numpy","time",) )) else: jobs.append(job_server.submit(trackPP.ConnectFibersPZM2, ( params.get('location'), pathsIJKId, pathsLENId, shpD, lengthEnabled),\ (trackPP.ComputeConnectFibersFunctionalP0, trackPP.ComputeConnectFibersFunctionalP1, trackPP.ComputeConnectFibersFunctionalP2,),\ ("numpy","time",) )) cm2 = jobs[0]() for j in range(nParts2-1): cm2 += jobs[j+1]() else: pass if isInRoiA and isInRoiB: if not monoP: vicinity= 1 threshold = 0.1 minLength = 4 print "Try out connecting" jobs = [] cm3 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') counter1 = 0 counter2 = 0 counterA1 = 0 counterB1 = 0 counterA2 = 0 counterB2 = 0 Pr = 0.0 Fa = 0.0 Wa = 0.0 for i in range(nParts): print "Number of paths : %s" % str(IJKstartpoints[i].shape[0]) #pathsRASId = './paths0/' + 'unit_' + str(i) + '_RAS.npy' pathsIJKId = './paths0/' + 'unit_' + str(i) + '_IJK.npy' #pathsANISId = './paths0/' + 'unit_' + str(i) + '_ANIS.npy' pathsLOGPId = './paths0/' + 'unit_' + str(i) + '_LOGP.npy' pathsLENId = './paths0/' + 'unit_' + str(i) + '_LEN.npy' jobs.append(job_server.submit(trackPP.FilterFibersZM0, (params.get('location'), pathsIJKId, pathsLOGPId, pathsLENId, roiA.getImage(), roiB.getImage(), shpD,\ counter1, counter2, counterA1, counterB1, counterA2, counterB2, Pr, threshold, vicinity), (), ("numpy","time",) )) cm3 = jobs[0]() for i in range(nParts-1): cm3 += jobs[i+1]() print "Filtering of fibers done from region A to region B" if counter1>0: print "Number of curves connecting : %s" % str(counter1) print "Mean probability : %s" % str(Pr/float(counter1)) jobs = [] cm4 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') counter1 = 0 counter2 = 0 counterA1 = 0 counterB1 = 0 counterA2 = 0 counterB2 = 0 Pr = 0.0 Fa = 0.0 Wa = 0.0 for i in range(nParts2): print "Number of paths : ", str(IJKstartpoints2[i].shape[0]) #pathsRASId = './paths1/' + 'unit_' + str(i) + '_RAS.npy' pathsIJKId = './paths1/' + 'unit_' + str(i) + '_IJK.npy' #pathsANISId = './paths1/' + 'unit_' + str(i) + '_ANIS.npy' pathsLOGPId = './paths1/' + 'unit_' + str(i) + '_LOGP.npy' pathsLENId = './paths1/' + 'unit_' + str(i) + '_LEN.npy' jobs.append(job_server.submit(trackPP.FilterFibersZM0, (params.get('location'), pathsIJKId, pathsLOGPId, pathsLENId, roiB.getImage(), roiA.getImage(), shpD,\ counter1, counter2, counterA1, counterB1, counterA2, counterB2, Pr, threshold, vicinity), (), ("numpy","time",) )) cm4 = jobs[0]() for i in range(nParts2-1): cm4 += jobs[i+1]() print "Filtering of fibers done from region B to region A" if counter1>0: print "Number of curves connecting : %s" % str(counter1) print "Mean probability : %s" % str(Pr/float(counter1)) else: pass else: print "No tractography to execute!" if cmEnabled: if isInRoiA and not roiFilterOnly: if not (cm == 0).all(): cm = cm.swapaxes(2,0) tmp= 'cmA_' + dateT cm.tofile(tmpF + tmp + '.data') createParams(cm, tmpF + tmp) if isInRoiB and not roiFilterOnly: if not (cm2 == 0).all(): cm2 = cm2.swapaxes(2,0) tmp= 'cmB_' + dateT cm2.tofile(tmpF + tmp + '.data') createParams(cm2, tmpF + tmp) if isInRoiA and isInRoiB and not roiFilterOnly: cm1a2 = cm[...]*cm2[...]/2.0 cm1a2 = cm1a2.astype('uint32') if not (cm1a2 == 0).all(): tmp= 'cmAandB_' + dateT cm1a2.tofile(tmpF + tmp + '.data') createParams(cm1a2, tmpF + tmp) tmp= 'cmFAandB_' + dateT cm1a2f = cm1a2/float(cm1a2.max()) cm1a2f.astype('float32') cm1a2f.tofile(tmpF + tmp + '.data') createParams(cm1a2f, tmpF + tmp) cm1o2 = (cm[...]+cm2[...])/2.0 cm1o2 = cm1o2.astype('uint32') if not (cm1o2 == 0).all(): tmp= 'cmAorB_' + dateT cm1o2.tofile(tmpF + tmp + '.data') createParams(cm1o2, tmpF + tmp) tmp= 'cmFAorB_' + dateT cm1o2f = cm1o2/float(cm1o2.max()) cm1o2f.astype('float32') cm1o2f.tofile(tmpF + tmp + '.data') createParams(cm1o2f, tmpF + tmp) if isInRoiA and isInRoiB: if not (cm3 == 0).all(): tmp= 'cmA2B_' + dateT cm3 = cm3.swapaxes(2,0) cm3.tofile(tmpF + tmp + '.data') createParams(cm3, tmpF + tmp) tmp= 'cmFA2B_' + dateT cm3f = cm3/float(cm3.max()) cm3f.astype('float32') cm3f.tofile(tmpF + tmp + '.data') createParams(cm3f, tmpF + tmp) if not (cm4 == 0).all(): tmp= 'cmB2A_' + dateT cm4 = cm4.swapaxes(2,0) cm4.tofile(tmpF + tmp + '.data') createParams(cm4, tmpF + tmp) tmp= 'cmFB2A_' + dateT cm4f = cm4/float(cm4.max()) cm4f.astype('float32') cm4f.tofile(tmpF + tmp + '.data') createParams(cm4f, tmpF + tmp) print "pipeline STOCHASTIC, data shape end : %s" % str(shpD)
def pipeline(host, port, params, nimage, roiA, roiB, wm): if params.get('pipeline')=='STOCHASTIC': #print "Pipeline : STOCHASTIC" ppserversL=("localhost",) #ppserversL=("*",) data = nimage.getImage() ####! swap x and z for volume coming from Slicer - do not forget tp apply the inverse before to send them back data = data.swapaxes(2,0) print 'pipeline data type : %s' % str(data.dtype) #### shpD = data.shape print 'pipeline data shape : %s' % str(shpD) orgS = nimage.get('origin') org = [float(orgS[0]), float(orgS[1]), float(orgS[2])] print 'Origin : %s:%s:%s' % (str(org[0]), str(org[1]), str(org[2])) spaS = nimage.get('spacing') spa = [float(spaS[0]), float(spaS[1]), float(spaS[2])] print 'Spacing : %s:%s:%s' % (str(spa[0]), str(spa[1]), str(spa[2])) G = nimage.get('grads') b = nimage.get('bval') i2r = nimage.get('ijk2ras') i2rd = nimage.get('ijk2rasd') mu = nimage.get('mu') dims = nimage.get('dimensions') s = slicerd.slicerd(host, int(port)) #print 'DWI : ', params.get('dwi') isInRoiA = False if params.hasKey('roiA'): roiAR = numpy.fromstring(roiA.getImage(), 'uint16') roiAR = roiAR.reshape(shpD[2], shpD[1], shpD[0]) # because come from Slicer - will not send them back so swap them one for all roiAR = roiAR.swapaxes(2,0) roiAR[roiAR>0]=1 roiA.setImage(roiAR) isInRoiA = True #print "RoiA : %s" % str(roiAR.shape) isDir = os.access('paths0', os.F_OK) if not isDir: os.mkdir('paths0') isInRoiB = False if params.hasKey('roiB'): if params.get('roiB') != params.get('roiA'): roiBR = numpy.fromstring(roiB.getImage(), 'uint16') roiBR = roiBR.reshape(shpD[2], shpD[1], shpD[0]) roiBR = roiBR.swapaxes(2,0) roiBR[roiBR>0]=1 roiB.setImage(roiBR) isInRoiB = True #print "RoiB : %s" % str(roiBR.shape) isDir = os.access('paths1', os.F_OK) if not isDir: os.mkdir('paths1') isInWM = False if params.hasKey('wm'): wmR = numpy.fromstring(wm.getImage(), 'uint16') wmR = wmR.reshape(shpD[2], shpD[1], shpD[0]) wmR = wmR.swapaxes(2,0) wm.setImage(wmR) isInWM = True #print "WM : %s" % str(wmR.shape) isInTensor = False print "Input volumes loaded!" # values per default smoothEnabled = False wmEnabled = True infWMThres = 300 supWMThres = 900 tensEnabled =True bLine = 0 stEnabled = True totalTracts = 500 maxLength = 200 stepSize = 0.5 stopEnabled = True fa = 0.0 cmEnabled = False probMode = 0 # got from client # special handling for bools if params.hasKey('smoothEnabled'): smoothEnabled = bool(int(params.get('smoothEnabled'))) if params.hasKey('wmEnabled'): wmEnabled = bool(int(params.get('wmEnabled'))) if params.hasKey('tensEnabled'): tensEnabled = bool(int(params.get('tensEnabled'))) if params.hasKey('stEnabled'): stEnabled = bool(int(params.get('stEnabled'))) if params.hasKey('cmEnabled'): cmEnabled = bool(int(params.get('cmEnabled'))) if params.hasKey('spaceEnabled'): spaceEnabled = bool(int(params.get('spaceEnabled'))) if params.hasKey('stopEnabled'): stopEnabled = bool(int(params.get('stopEnabled'))) if params.hasKey('faEnabled'): faEnabled = bool(int(params.get('faEnabled'))) if params.hasKey('traceEnabled'): traceEnabled = bool(int(params.get('traceEnabled'))) if params.hasKey('modeEnabled'): modeEnabled = bool(int(params.get('modeEnabled'))) # can handle normally FWHM = numpy.ones((3), 'float') if params.hasKey('stdDev'): FWHM[0] = float(params.get('stdDev')[0]) FWHM[1] = float(params.get('stdDev')[1]) FWHM[2] = float(params.get('stdDev')[2]) print "FWHM: %s:%s:%s" % (str(FWHM[0]), str(FWHM[1]), str(FWHM[2])) if params.hasKey('infWMThres'): infWMThres = int(params.get('infWMThres')) print "infWMThres: %s" % str(infWMThres) if params.hasKey('supWMThres'): supWMThres = int(params.get('supWMThres')) print "supWMThres: %s" % str(supWMThres) if params.hasKey('bLine'): bLine = int(params.get('bLine')) print "bLine: %s" % str(bLine) if params.hasKey('tensMode'): tensMode = params.get('tensMode') print "tensMode: %s" % str(tensMode) if params.hasKey('totalTracts'): totalTracts = int(params.get('totalTracts')) print "totalTracts: %s" % str(totalTracts) if params.hasKey('maxLength'): maxLength = int(params.get('maxLength')) print "maxLength: %s" % str(maxLength) if params.hasKey('stepSize'): stepSize = float(params.get('stepSize')) print "stepSize: %s" % str(stepSize) if params.hasKey('fa'): fa = float(params.get('fa')) print "fa: %s" % str(fa) if params.hasKey('probMode'): probMode = params.get('probMode') print "probMode: %s" % str(probMode) if params.hasKey('lengthEnabled'): lengthEnabled = params.get('lengthEnabled') print "lengthEnabled: %s" % str(lengthEnabled) if params.hasKey('lengthClass'): lengthClass = params.get('lengthClass') print "lengthClass: %s" % str(lengthClass) ngrads = shpD[3] #b.shape[0] print "Number of gradients : %s" % str(ngrads) G = G.reshape(ngrads,3) b = b.reshape(ngrads,1) i2r = i2r.reshape(4,4) i2rd = i2rd.reshape(4,4) mu = mu.reshape(4,4) r2i = numpy.linalg.inv(i2r) r2id = numpy.linalg.inv(i2rd) mu2 = numpy.dot(r2id[:3, :3], mu[:3, :3]) G2 = numpy.dot(G, mu2[:3, :3].T) vts = vects.vectors print "Tensor flag : %s" % str(tensEnabled) cm = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') cm2 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') cm3 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') cm4 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') if smoothEnabled: for k in range(shpD[3]): timeSM0 = time.time() data[...,k] = sm.smooth(data[...,k], FWHM, numpy.array([ spa[0], spa[1], spa[2] ],'float')) print "Smoothing DWI volume %i in %s sec" % (k, str(time.time()-timeSM0)) if wmEnabled: wm = tensPP.EvaluateWM0(data, bLine, infWMThres, supWMThres) if isInRoiA: # correcting brain mask with roi A print "Correcting mask based on roiA" tmpA = roiA.getImage() wm[tmpA>0]=1 if isInRoiB: # correcting brain mask with roi A & B print "Correcting mask based on roiB" tmpB = roiB.getImage() wm[tmpB>0]=1 else: # avoid singularities in data minVData = 10 wm = tensPP.EvaluateWM0(data, bLine, minVData, data[..., bLine].max()) wmEnabled = True # fix if isInWM or wmEnabled: isDir = os.access('masks', os.F_OK) if not isDir: os.mkdir('masks') tmpF = './masks/' numpy.save(tmpF + 'wm.npy', wm) indx = numpy.transpose(wm.nonzero()) print 'Total Number of voxels : ', shpD[0]*shpD[1]*shpD[2]*ngrads print 'Masked voxels : ', indx.shape[0]*ngrads print 'Index shape : ', indx.shape dataf = data.flatten() cId = numpy.zeros((indx.shape[0]), 'uint32') mdata = numpy.zeros((indx.shape[0], ngrads), data.dtype) for i in range(indx.shape[0]): cId[i] = indx[i][0]*shpD[1]*shpD[2]*shpD[3] + indx[i][1]*shpD[2]*shpD[3] + indx[i][2]*shpD[3] mdata[i,:]= dataf[cId[i]:cId[i]+ngrads] numpy.save(tmpF + 'index.npy', cId) numpy.save(tmpF + 'mdata.npy', mdata) if cmEnabled: print "Compute tensor" timeS1 = time.time() monoP = False # multiprocessing support dataBlocks = [] wmBlocks = [] nCpu = 2 # could be set to the number of available cores nParts = 1 if shpD[2]>0 and nCpu>0 : job_server = pp.Server(ppservers=ppserversL) ncpusL = job_server.get_ncpus() #if ncpusL == 0 : ncpusL = 1 print "Number of cores on local machine : %s" % str(ncpusL) print "Number of active computing nodes : %s" % str(nCpu) if shpD[2] >= nCpu: nParts = nCpu else: nParts = shpD[2] for i in range(nParts): datax = data[:, :, i*shpD[2]/nParts:(i+1)*shpD[2]/nParts, :] print "data block %i dimension : %s" % (i, str(datax.shape)) dataBlocks.append(datax) if isInWM or wmEnabled: wmx = wm[:, :, i*shpD[2]/nParts:(i+1)*shpD[2]/nParts] wmBlocks.append(wmx) else: monoP = True if not monoP: jobs = [] job_server.set_ncpus(ncpus = ncpusL) for i in range(nParts): jobs.append(job_server.submit(tensPP.EvaluateTensorX1, (dataBlocks[i], G2.T, b.T, wmBlocks[i],),(tensPP.ComputeAFunctional, tensPP.ComputeTensorFunctional,), ("numpy","time",) )) tBlocks = [] for i in range(nParts): tBlocks.append(jobs[i]()) lV = numpy.zeros((shpD[0], shpD[1], shpD[2], 3) , 'float') EV = numpy.zeros((shpD[0], shpD[1], shpD[2], 3, 3), 'float' ) xVTensor = numpy.zeros((shpD[0], shpD[1], shpD[2], 7), 'float') xYTensor = numpy.zeros((shpD[0], shpD[1], shpD[2], 9), 'float') xTensor0 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'float') for i in range(nParts): EV[:, :, i*shpD[2]/nParts:(i+1)*shpD[2]/nParts, ...]= tBlocks[i][0] lV[:, :, i*shpD[2]/nParts:(i+1)*shpD[2]/nParts, :]= tBlocks[i][1] xVTensor[:, :, i*shpD[2]/nParts:(i+1)*shpD[2]/nParts, ...]= tBlocks[i][2] xYTensor[:, :, i*shpD[2]/nParts:(i+1)*shpD[2]/nParts, ...]= tBlocks[i][3] xTensor0[...]= xVTensor[..., 0] lVType = lV.dtype EVType = EV.dtype xVTensorType = xVTensor.dtype wmType = wm.dtype # computation of alpha, beta, logmu0 and principal eigenvector tdata = numpy.zeros((indx.shape[0], 6), 'float') for i in range(indx.shape[0]): cId[i] = indx[i][0]*shpD[1]*shpD[2]*shpD[3] + indx[i][1]*shpD[2]*shpD[3] + indx[i][2]*shpD[3] l = lV[indx[i][0], indx[i][1], indx[i][2], :] index = numpy.argsort(abs(l))[::-1] l =l[index,:] # Set point estimates in the Constrained model E = EV[indx[i][0], indx[i][1], indx[i][2], ...] alpha = (l[1]+l[2])/2 beta = l[0] - alpha logmu0 = xTensor0[indx[i][0], indx[i][1], indx[i][2]] e = E[:, index[0]] tdata[i,0]= alpha tdata[i,1]= beta tdata[i,2]= logmu0 tdata[i,3:]= e numpy.save(tmpF + 'tdata.npy', tdata) isDir = os.access('tensors', os.F_OK) if not isDir: os.mkdir('tensors') tmpF = './tensors/' numpy.save(tmpF + 'eigenv.npy', EV) numpy.save(tmpF + 'lambda.npy', lV) numpy.save(tmpF + 'tensor.npy', xVTensor) numpy.save(tmpF + 'tensor0.npy', xTensor0) numpy.save(tmpF + 'vectors.npy', vts.T) else: pass print "Compute tensor in %s sec" % str(time.time()-timeS1) if faEnabled: faMap = tensC.CalculateFA0(lV) if traceEnabled: trMap = tensC.CalculateTrace0(lV) if modeEnabled: moMap = tensC.CalculateMode0(lV) print "Track fibers" if not stopEnabled: fa = 0.0 if isInRoiA: # ROI A print "Search ROI A" roiP = cmpV.march0InVolume(roiA.getImage()) shpR = roiP.shape print "ROI A dimension : %s" % str(shpR) blocksize = totalTracts IJKstartpoints = [] monoP = False nParts = 1 if shpR[0]>0 and nCpu>0 : if shpR[0] >= nCpu: nParts = nCpu else: nParts = shpR[0] for i in range(nParts): roiPx = roiP[i*shpR[0]/nParts:(i+1)*shpR[0]/nParts, :] print "ROI A %i dimension : %s" % (i, str(roiPx.shape)) IJKstartpoints.append(numpy.tile(roiPx,( blocksize, 1))) else: IJKstartpoints.append(numpy.tile(roiP,( blocksize, 1))) monoP = True timeS2 = time.time() # multiprocessing print "Data type : %s" % str(data.dtype) if not monoP: jobs = [] for i in range(nParts): jobs.append(job_server.submit(trackPP.TrackFiberYFM40, (i, 0, params.get('location'), nimage.get('fullname'), nimage.get('type'), shpD, b.T, G2.T, IJKstartpoints[i].T, r2i, i2r, r2id, i2rd, spa,\ 'vectors.npy', vects.vectors.dtype, vects.vectors.T.shape, 'lambda.npy', lVType, 'eigenv.npy', EVType, 'tensor0.npy', xVTensorType, 'wm.npy' ,\ wmType, stepSize, maxLength, fa, spaceEnabled,),(), ("numpy","time",) )) res = jobs[0]() for i in range(nParts-1): res = jobs[i+1]() print "Track fibers in %s sec" % str(time.time()-timeS2) print "Connect tract" jobs = [] cm = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') for j in range(nParts): print "Number of paths : %s" % str(IJKstartpoints[j].shape[0]) pathsIJKId = './paths0/' + 'unit_' + str(j) + '_IJK.npy' pathsLENId = './paths0/' + 'unit_' + str(j) + '_LEN.npy' if probMode=='binary': jobs.append(job_server.submit(trackPP.ConnectFibersPZM0, ( params.get('location'), pathsIJKId, pathsLENId, shpD, lengthEnabled),\ (trackPP.ComputeConnectFibersFunctionalP0, trackPP.ComputeConnectFibersFunctionalP1, trackPP.ComputeConnectFibersFunctionalP2,),\ ("numpy","time",) )) elif probMode=='cumulative': jobs.append(job_server.submit(trackPP.ConnectFibersPZM1, ( params.get('location'), pathsIJKId, pathsLENId, shpD, lengthEnabled),\ (trackPP.ComputeConnectFibersFunctionalP0, trackPP.ComputeConnectFibersFunctionalP1, trackPP.ComputeConnectFibersFunctionalP2,),\ ("numpy","time",) )) else: jobs.append(job_server.submit(trackPP.ConnectFibersPZM2, ( params.get('location'), pathsIJKId, pathsLENId, shpD, lengthEnabled),\ (trackPP.ComputeConnectFibersFunctionalP0, trackPP.ComputeConnectFibersFunctionalP1, trackPP.ComputeConnectFibersFunctionalP2,),\ ("numpy","time",) )) cm = jobs[0]() for j in range(nParts-1): cm += jobs[j+1]() else: pass if isInRoiB: # ROI B print "Search ROI B" roiP2 = cmpV.march0InVolume(roiB.getImage()) shpR2 = roiP2.shape print "ROI B dimension : %s" % str(shpR2) blocksize = totalTracts IJKstartpoints2 = [] monoP = False nParts2 = 1 if shpR2[0]>0 and nCpu>0 : if shpR2[0] >= nCpu: nParts2 = nCpu else: nParts2 = shpR2[0] for i in range(nParts2): roiPx = roiP2[i*shpR2[0]/nParts2:(i+1)*shpR2[0]/nParts2, :] print "ROI B %i dimension : %s" % (i, str(roiPx.shape)) IJKstartpoints2.append(numpy.tile(roiPx,( blocksize, 1))) else: IJKstartpoints2.append(numpy.tile(roiP2,( blocksize, 1))) monoP = True timeS3 = time.time() # multiprocessing print "Data type : %s" % str(data.dtype) if not monoP: jobs = [] for i in range(nParts2): #if isInWM or wmEnabled: jobs.append(job_server.submit(trackPP.TrackFiberYFM40, (i, 1, params.get('location'), nimage.get('fullname'), nimage.get('type'), shpD, b.T, G2.T, IJKstartpoints2[i].T, r2i, i2r, r2id, i2rd, spa,\ 'vectors.npy', vects.vectors.dtype, vects.vectors.T.shape, 'lambda.npy', lVType, 'eigenv.npy', EVType, 'tensor0.npy', xVTensorType, 'wm.npy' ,\ wmType, stepSize, maxLength, fa, spaceEnabled,),(), ("numpy","time",) )) res = jobs[0]() for i in range(nParts2-1): res = jobs[i+1]() print "Track fibers in %s sec" % str(time.time()-timeS3) print "Connect tract" jobs = [] cm2 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') for j in range(nParts2): print "Number of paths : %s" % str(IJKstartpoints2[j].shape[0]) pathsIJKId = './paths1/' + 'unit_' + str(j) + '_IJK.npy' pathsLENId = './paths1/' + 'unit_' + str(j) + '_LEN.npy' if probMode=='binary': jobs.append(job_server.submit(trackPP.ConnectFibersPZM0, ( params.get('location'), pathsIJKId, pathsLENId, shpD, lengthEnabled),\ (trackPP.ComputeConnectFibersFunctionalP0, trackPP.ComputeConnectFibersFunctionalP1, trackPP.ComputeConnectFibersFunctionalP2,),\ ("numpy","time",) )) elif probMode=='cumulative': jobs.append(job_server.submit(trackPP.ConnectFibersPZM1, ( params.get('location'), pathsIJKId, pathsLENId, shpD, lengthEnabled),\ (trackPP.ComputeConnectFibersFunctionalP0, trackPP.ComputeConnectFibersFunctionalP1, trackPP.ComputeConnectFibersFunctionalP2,),\ ("numpy","time",) )) else: jobs.append(job_server.submit(trackPP.ConnectFibersPZM2, ( params.get('location'), pathsIJKId, pathsLENId, shpD, lengthEnabled),\ (trackPP.ComputeConnectFibersFunctionalP0, trackPP.ComputeConnectFibersFunctionalP1, trackPP.ComputeConnectFibersFunctionalP2,),\ ("numpy","time",) )) cm2 = jobs[0]() for j in range(nParts2-1): cm2 += jobs[j+1]() else: pass if isInRoiA and isInRoiB: if not monoP: vicinity= 1 threshold = 0.1 minLength = 4 print "Try out connecting" jobs = [] cm3 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') counter1 = 0 counter2 = 0 counterA1 = 0 counterB1 = 0 counterA2 = 0 counterB2 = 0 Pr = 0.0 Fa = 0.0 Wa = 0.0 for i in range(nParts): print "Number of paths : %s" % str(IJKstartpoints[i].shape[0]) #pathsRASId = './paths0/' + 'unit_' + str(i) + '_RAS.npy' pathsIJKId = './paths0/' + 'unit_' + str(i) + '_IJK.npy' #pathsANISId = './paths0/' + 'unit_' + str(i) + '_ANIS.npy' pathsLOGPId = './paths0/' + 'unit_' + str(i) + '_LOGP.npy' pathsLENId = './paths0/' + 'unit_' + str(i) + '_LEN.npy' jobs.append(job_server.submit(trackPP.FilterFibersZM0, (params.get('location'), pathsIJKId, pathsLOGPId, pathsLENId, roiA.getImage(), roiB.getImage(), shpD,\ counter1, counter2, counterA1, counterB1, counterA2, counterB2, Pr, threshold, vicinity, minLength), (), ("numpy","time",) )) cm3 = jobs[0]() for i in range(nParts-1): cm3 += jobs[i+1]() print "Filtering of fibers done from region A to region B" if counter1>0: print "Number of curves connecting : %s" % str(counter1) print "Mean probability : %s" % str(Pr/float(counter1)) #print "Mean FA : %s" % str(Fa/float(counter1)) #print "Mean WA : %s" % str(Wa/float(counter1)) jobs = [] cm4 = numpy.zeros((shpD[0], shpD[1], shpD[2]), 'uint32') counter1 = 0 counter2 = 0 counterA1 = 0 counterB1 = 0 counterA2 = 0 counterB2 = 0 Pr = 0.0 Fa = 0.0 Wa = 0.0 for i in range(nParts2): print "Number of paths : ", str(IJKstartpoints2[i].shape[0]) #pathsRASId = './paths1/' + 'unit_' + str(i) + '_RAS.npy' pathsIJKId = './paths1/' + 'unit_' + str(i) + '_IJK.npy' #pathsANISId = './paths1/' + 'unit_' + str(i) + '_ANIS.npy' pathsLOGPId = './paths1/' + 'unit_' + str(i) + '_LOGP.npy' pathsLENId = './paths1/' + 'unit_' + str(i) + '_LEN.npy' jobs.append(job_server.submit(trackPP.FilterFibersZM0, (params.get('location'), pathsIJKId, pathsLOGPId, pathsLENId, roiB.getImage(), roiA.getImage(), shpD,\ counter1, counter2, counterA1, counterB1, counterA2, counterB2, Pr, threshold, vicinity, minLength), (), ("numpy","time",) )) cm4 = jobs[0]() for i in range(nParts2-1): cm4 += jobs[i+1]() print "Filtering of fibers done from region B to region A" if counter1>0: print "Number of curves connecting : %s" % str(counter1) print "Mean probability : %s" % str(Pr/float(counter1)) else: pass else: print "No tractography to execute!" dateT = str(int(round(time.time()))) isDir = os.access('outputs', os.F_OK) if not isDir: os.mkdir('outputs') tmpF = './outputs/' i2r.tofile(tmpF + 'trafo_' + dateT + '.ijk') if smoothEnabled: ga = data[..., bLine] ga = ga.swapaxes(2,0) tmp= 'smooth_' + dateT ga.tofile(tmpF + tmp + '.data') createParams(ga, tmpF + tmp) s.putS(ga, dims, org, i2r, tmp) if wmEnabled: wm = wm.swapaxes(2,0) tmp= 'brain_' + dateT wm.tofile(tmpF + tmp + '.data') createParams(wm, tmpF + tmp) s.putS(wm, dims, org, i2r, tmp) if cmEnabled: xVTensor = xVTensor.swapaxes(2,0) xVTensor = xVTensor.astype('float32') # slicerd do not support double type yet xYTensor = xYTensor.swapaxes(2,0) xYTensor = xYTensor.astype('float32') # slicerd do not support double type yet tmp= 'tensor_' + dateT xYTensor.tofile(tmpF + tmp + '.data') createParams(xYTensor, tmpF + tmp, True) s.putD(xVTensor, dims, org, i2r, mu, tmp) if faEnabled: faMap = faMap.swapaxes(2,0) tmp= 'fa_' + dateT faMap.tofile(tmpF + tmp + '.data') createParams(faMap, tmpF + tmp) s.putS(faMap, dims, org, i2r, tmp) if traceEnabled: trMap = trMap.swapaxes(2,0) tmp= 'trace_' + dateT trMap.tofile(tmpF + tmp + '.data') createParams(trMap, tmpF + tmp) s.putS(trMap, dims, org, i2r, tmp) if modeEnabled: moMap = moMap.swapaxes(2,0) tmp= 'mode_' + dateT moMap.tofile(tmpF + tmp + '.data') createParams(moMap, tmpF + tmp) s.putS(moMap, dims, org, i2r, tmp) if isInRoiA: if not (cm == 0).all(): cm = cm.swapaxes(2,0) tmp= 'cmA_' + dateT cm.tofile(tmpF + tmp + '.data') createParams(cm, tmpF + tmp) #s.putS(cm, dims, org, i2r, tmp) tmp= 'cmFA_' + dateT cmf = cm/float(cm.max()) cmf.astype('float32') cmf.tofile(tmpF + tmp + '.data') createParams(cmf, tmpF + tmp) s.putS(cmf, dims, org, i2r, tmp) if isInRoiB: if not (cm2 == 0).all(): cm2 = cm2.swapaxes(2,0) tmp= 'cmB_' + dateT cm2.tofile(tmpF + tmp + '.data') createParams(cm2, tmpF + tmp) #s.putS(cm2, dims, org, i2r, tmp) tmp= 'cmFB_' + dateT cm2f = cm2/float(cm2.max()) cm2f.astype('float32') cm2f.tofile(tmpF + tmp + '.data') createParams(cm2f, tmpF + tmp) s.putS(cm2f, dims, org, i2r, tmp) if isInRoiA and isInRoiB: cm1a2 = cm[...]*cm2[...]/2.0 cm1a2 = cm1a2.astype('uint32') if not (cm1a2 == 0).all(): tmp= 'cmAandB_' + dateT cm1a2.tofile(tmpF + tmp + '.data') createParams(cm1a2, tmpF + tmp) #s.putS(cm1a2, dims, org, i2r, tmp) tmp= 'cmFAandB_' + dateT cm1a2f = cm1a2/float(cm1a2.max()) cm1a2f.astype('float32') cm1a2f.tofile(tmpF + tmp + '.data') createParams(cm1a2f, tmpF + tmp) s.putS(cm1a2f, dims, org, i2r, tmp) cm1o2 = (cm[...]+cm2[...])/2.0 cm1o2 = cm1o2.astype('uint32') if not (cm1o2 == 0).all(): tmp= 'cmAorB_' + dateT cm1o2.tofile(tmpF + tmp + '.data') createParams(cm1o2, tmpF + tmp) #s.putS(cm1o2, dims, org, i2r, tmp) tmp= 'cmFAorB_' + dateT cm1o2f = cm1o2/float(cm1o2.max()) cm1o2f.astype('float32') cm1o2f.tofile(tmpF + tmp + '.data') createParams(cm1o2f, tmpF + tmp) s.putS(cm1o2f, dims, org, i2r, tmp) if not (cm3 == 0).all(): tmp= 'cmA2B_' + dateT cm3 = cm3.swapaxes(2,0) cm3.tofile(tmpF + tmp + '.data') createParams(cm3, tmpF + tmp) #s.putS(cm3, dims, org, i2r, tmp) tmp= 'cmFA2B_' + dateT cm3f = cm3/float(cm3.max()) cm3f.astype('float32') cm3f.tofile(tmpF + tmp + '.data') createParams(cm3f, tmpF + tmp) s.putS(cm3f, dims, org, i2r, tmp) if not (cm4 == 0).all(): tmp= 'cmB2A_' + dateT cm4 = cm4.swapaxes(2,0) cm4.tofile(tmpF + tmp + '.data') createParams(cm4, tmpF + tmp) #s.putS(cm4, dims, org, i2r, tmp) tmp= 'cmFB2A_' + dateT cm4f = cm4/float(cm4.max()) cm4f.astype('float32') cm4f.tofile(tmpF + tmp + '.data') createParams(cm4f, tmpF + tmp) s.putS(cm4f, dims, org, i2r, tmp) print "pipeline STOCHASTIC, data shape end : %s" % str(shpD)
def pipeline(self, data): if self.nimage.get('pipeline')[0]=='STOCHASTIC': ####! swap x and z for volume coming from Slicer - do not forget to apply the inverse before to send them back data = data.swapaxes(2,0) data = data.astype('float') #### shpD = data.shape shpV0 = numpy.zeros((4), 'uint16') shpV0[0]= shpD[0] shpV0[1]= shpD[1] shpV0[2]= shpD[2] shpV0[3]= shpD[3] logger.info("pipeline data shape : %s:%s:%s:%s" % (shpD[0], shpD[1], shpD[2], shpD[3])) logger.info("pipeline data type : %s" % data.dtype) orgS = self.nimage.get('origin') org = [float(orgS[0]), float(orgS[1]), float(orgS[2])] org0 = numpy.zeros((3), 'float') org0[0]=org[0] org0[1]=org[1] org0[2]=org[2] logger.info("origin : %s:%s:%s" % (org[0], org[1], org[2])) spaS = self.nimage.get('spacing') spa = [float(spaS[0]), float(spaS[1]), float(spaS[2])] spa0 = numpy.zeros((3), 'float') spa0[0]=spa[0] spa0[1]=spa[1] spa0[2]=spa[2] logger.info("spacing : %s:%s:%s" % (spa[0], spa[1], spa[2])) G = self.nimage.get('grads') b = self.nimage.get('bval') i2r = self.nimage.get('ijk2ras') i2rd = self.nimage.get('ijk2rasd') mu = self.nimage.get('mu') dims = self.nimage.get('dimensions') s = slicerd.slicerd() scene = s.ls() dscene = {} indS = [] for i in range(len(scene)): if scene[i].isdigit(): indS.append(i) for j in range(len(indS)): if j<len(indS)-1: tmpD2 = '' tmpD = scene[indS[j]+2:indS[j+1]] for k in range(len(tmpD)): if k <len(tmpD)-1: tmpD2 += tmpD[k] + ' ' else: tmpD2 += tmpD[k] dscene[tmpD2]= j else: tmpD2 = '' tmpD = scene[indS[j]+2:] for k in range(len(tmpD)): if k <len(tmpD)-1: tmpD2 += tmpD[k] + ' ' else: tmpD2 += tmpD[k] dscene[tmpD2]= j logger.info("scene : %s" % dscene) # currently there is a bug in the GUI of slicer python - do not load if three times the same volume isInRoiA = False if self.params.hasKey('roiA'): if dscene.has_key(self.params.get('roiA')[0]): self.roiA = s.get(int(dscene[self.params.get('roiA')[0]])) roiAR = numpy.fromstring(self.roiA.getImage(), 'uint16') if roiAR.shape[0] == shpD[2]*shpD[1]*shpD[0]: roiAR = roiAR.reshape(shpD[2], shpD[1], shpD[0]) # because come from Slicer - will not send them back so swap them one for all roiAR = roiAR.swapaxes(2,0) roiAR[roiAR>0]=1 self.roiA.setImage(roiAR) isInRoiA = True logger.info("RoiA : %s:%s:%s" % (roiAR.shape[0], roiAR.shape[1], roiAR.shape[2])) else: logger.info("RoiA has not the same dimension as the DWI : %s" % roiAR.shape[0]) isInRoiB = False if self.params.hasKey('roiB'): if dscene.has_key(self.params.get('roiB')[0]): if self.params.get('roiB')[0] != self.params.get('roiA')[0]: self.roiB = s.get(int(dscene[self.params.get('roiB')[0]])) roiBR = numpy.fromstring(self.roiB.getImage(), 'uint16') if roiBR.shape[0] == shpD[2]*shpD[1]*shpD[0]: roiBR = roiBR.reshape(shpD[2], shpD[1], shpD[0]) roiBR = roiBR.swapaxes(2,0) roiBR[roiBR>0]=1 self.roiB.setImage(roiBR) isInRoiB = True logger.info("RoiB : %s:%s:%s" % (roiBR.shape[0], roiBR.shape[1], roiBR.shape[2])) else: logger.info("RoiB has not the same dimension as the DWI : %s" % roiBR.shape[0]) isInWM = False if self.params.hasKey('wm'): if dscene.has_key(self.params.get('wm')[0]): self.wm = s.get(int(dscene[self.params.get('wm')[0]])) wmR = numpy.fromstring(self.wm.getImage(), 'uint16') if wmR.shape[0] == shpD[2]*shpD[1]*shpD[0]: wmR = wmR.reshape(shpD[2], shpD[1], shpD[0]) wmR = wmR.swapaxes(2,0) self.wm.setImage(wmR) isInWM = True logger.info("WM : %s:%s:%s" % (wmR.shape[0], wmR.shape[1], wmR.shape[2])) else: logger.info("WM has not the same dimension as the DWI : %s" % wmR.shape[0]) isInTensor = False if self.params.hasKey('tensor'): if dscene.has_key(self.params.get('tensor')[0]): self.ten = s.get(int(dscene[self.params.get('tensor')[0]])) tenR = numpy.fromstring(self.ten.getImage(), 'float32') if tenR.shape[0] == shpD[2]*shpD[1]*shpD[0]*7: tenR = tenR.reshape(shpD[2], shpD[1], shpD[0], 7) tenR = tenR.swapaxes(2,0) self.ten.setImage(tenR) isInTensor = True logger.info("Tensor : %s:%s" % (tenR.shape[0], tenR.shape[1])) else: logger.info("Tensor has not the same dimension as the DWI : %s" % tenR.shape[0]) logger.info("Input volumes loaded!") # values per default smoothEnabled = False wmEnabled = True infWMThres = 300 supWMThres = 900 tensEnabled =True bLine = 0 stEnabled = True totalTracts = 500 maxLength = 200 stepSize = 0.5 stopEnabled = True fa = 0.0 cmEnabled = False probMode = 0 # got from client # special handling for bools if self.params.hasKey('smoothEnabled'): smoothEnabled = bool(int(self.params.get('smoothEnabled')[0])) if self.params.hasKey('wmEnabled'): wmEnabled = bool(int(self.params.get('wmEnabled')[0])) if self.params.hasKey('tensEnabled'): tensEnabled = bool(int(self.params.get('tensEnabled')[0])) if self.params.hasKey('stEnabled'): stEnabled = bool(int(self.params.get('stEnabled')[0])) if self.params.hasKey('cmEnabled'): cmEnabled = bool(int(self.params.get('cmEnabled')[0])) if self.params.hasKey('spaceEnabled'): spaceEnabled = bool(int(self.params.get('spaceEnabled')[0])) if self.params.hasKey('stopEnabled'): stopEnabled = bool(int(self.params.get('stopEnabled')[0])) if self.params.hasKey('faEnabled'): faEnabled = bool(int(self.params.get('faEnabled')[0])) if self.params.hasKey('traceEnabled'): traceEnabled = bool(int(self.params.get('traceEnabled')[0])) if self.params.hasKey('modeEnabled'): modeEnabled = bool(int(self.params.get('modeEnabled')[0])) if self.params.hasKey('sphericalEnabled'): sphericalEnabled = bool(int(self.params.get('sphericalEnabled')[0])) # can handle normally FWHM = numpy.ones((3), 'float') if self.params.hasKey('stdDev'): FWHM[0] = float(self.params.get('stdDev')[0]) FWHM[1] = float(self.params.get('stdDev')[1]) FWHM[2] = float(self.params.get('stdDev')[2]) logger.debug("FWHM: %s:%s:%s" % (FWHM[0], FWHM[1], FWHM[2]) ) if self.params.hasKey('infWMThres'): infWMThres = int(self.params.get('infWMThres')[0]) logger.debug("infWMThres: %s" % infWMThres) if self.params.hasKey('supWMThres'): supWMThres = int(self.params.get('supWMThres')[0]) logger.debug("supWMThres: %s" % supWMThres) if self.params.hasKey('bLine'): bLine = int(self.params.get('bLine')[0]) logger.debug("bLine: %s" % bLine) if self.params.hasKey('isIJK'): isIJK = bool(int(self.params.get('isIJK')[0])) logger.debug("isIJK: %s" % isIJK) if self.params.hasKey('tensMode'): tensMode = self.params.get('tensMode')[0] logger.debug("tensMode: %s" % tensMode) if self.params.hasKey('totalTracts'): totalTracts = int(self.params.get('totalTracts')[0]) logger.debug("totalTracts: %s" % totalTracts) if self.params.hasKey('maxLength'): maxLength = int(self.params.get('maxLength')[0]) logger.debug("maxLength: %s" % maxLength) if self.params.hasKey('stepSize'): stepSize = float(self.params.get('stepSize')[0]) logger.debug("stepSize: %s" % stepSize) if self.params.hasKey('fa'): fa = float(self.params.get('fa')[0]) logger.debug("fa: %s" % fa) if self.params.hasKey('probMode'): probMode = self.params.get('probMode')[0] logger.debug("probMode: %s" % probMode) if self.params.hasKey('lengthEnabled'): lengthEnabled = self.params.get('lengthEnabled')[0] logger.debug("lengthEnabled: %s" % lengthEnabled) if self.params.hasKey('lengthClass'): lengthClass = self.params.get('lengthClass')[0] logger.debug("lengthClass: %s" % lengthClass) if self.params.hasKey('tractOffset'): tractOffset = int(self.params.get('tractOffset')[0]) logger.debug("tractOffset: %s" % tractOffset) if self.params.hasKey('vicinity'): vicinity = int(self.params.get('vicinity')[0]) logger.debug("vicinity: %s" % vicinity) if self.params.hasKey('threshold'): threshold = float(self.params.get('threshold')[0]) logger.debug("threshold: %s" % threshold) ngrads = shpD[3] logger.info("Number of gradients : %s" % str(ngrads) ) G = G.reshape((ngrads,3)) b = b.reshape((ngrads,1)) i2r = i2r.reshape((4,4)) i2rd = i2rd.reshape((4,4)) mu = mu.reshape((4,4)) r2i = numpy.linalg.inv(i2r) r2id = numpy.linalg.inv(i2rd) # compute trafo fir IJK & RAS # gradients in RAS G1 = numpy.dot(G, mu[:3, :3].T) # gradients in IJK mu2 = numpy.dot(r2id[:3, :3], mu[:3, :3]) G2 = numpy.dot(G, mu2[:3, :3].T) # switch to compute either in IJK or RAS if isIJK: G0 = G2 else: G0 = G1 vts = vects.vectors logger.info("Tensor flag : %s" % str(tensEnabled)) if smoothEnabled: for k in range(shpD[3]): timeSM0 = time.time() data[...,k] = sm.smooth(data[...,k], FWHM, numpy.array([ spa[0], spa[1], spa[2] ],'float')) logger.info("Smoothing DWI volume %i in %s sec" % (k, str(time.time()-timeSM0))) if wmEnabled: wm = tens.EvaluateWM0(data, bLine, infWMThres, supWMThres) if isInRoiA: # correcting brain mask with roi A logger.info("Correcting mask based on roiA") tmpA = self.roiA.getImage() wm[tmpA>0]=1 if isInRoiB: # correcting brain mask with roi A & B logger.info("Correcting mask based on roiB") tmpB = self.roiB.getImage() wm[tmpB>0]=1 else: # avoid singularities in data minVData = 10 wm = tens.EvaluateWM0(data, bLine, minVData, data[..., bLine].max()) if isInWM: logger.info("Using external mask") wm = self.wm.getImage() if tensEnabled: logger.info("Compute tensor") timeS1 = time.time() if not isInTensor: EV, lV, xVTensor, xYTensor = tens.EvaluateTensorX1(data, G0.T, b.T, wm) else: EV, lV, xVTensor, xYTensor = tens.EvaluateTensorK1(self.ten.getImage(), shpD, wm) logger.info("Compute tensor in %s sec" % str(time.time()-timeS1)) if faEnabled: faMap = tensC.CalculateFA0(lV) if traceEnabled: trMap = tensC.CalculateTrace0(lV) if modeEnabled: moMap = tensC.CalculateMode0(lV) if cmEnabled: logger.info("Track fibers") if not stopEnabled: fa = 0.0 if isInRoiA: # ROI A logger.info("Search ROI A") roiP = cmpV.march0InVolume(self.roiA.getImage()) shpR = roiP.shape logger.info("ROI A dimension : %s:%s" % (str(shpR[0]), str(shpR[1]))) blocksize = totalTracts IJKstartpoints= numpy.tile(roiP,( blocksize, 1)) logger.info("IJK start points shape : %s" % str(IJKstartpoints.shape)) timeS2 = time.time() logger.info("Data type : %s" % data.dtype) if tensEnabled: paths00, paths01, paths02, paths03, paths04 = track.TrackFiberZ40(s, wm, shpD, b.T, G0.T, vts.T, IJKstartpoints.T,\ r2i, i2r, r2id, i2rd, spa, lV, EV, xVTensor, stepSize, maxLength, fa, spaceEnabled, isIJK) else: paths00, paths01, paths02, paths03, paths04 = track.TrackFiberX40(s, data.flatten(), wm, shpD, b.T, G0.T, vts.T, IJKstartpoints.T,\ r2i, i2r, r2id, i2rd, spa, stepSize, maxLength, fa, spaceEnabled, isIJK) logger.info("Track fibers in %s sec" % str(time.time()-timeS2)) logger.info("Connect tract") if probMode=='binary': cm = track.ConnectFibersX0(paths01, paths04, shpD, lengthEnabled, lengthClass) elif probMode=='cumulative': cm = track.ConnectFibersX1(paths01, paths04, shpD, lengthEnabled, lengthClass) else: cm = track.ConnectFibersX2(paths01, paths04, shpD, lengthEnabled, lengthClass) if isInRoiB: # ROI B logger.info("Search ROI B") roiP2 = cmpV.march0InVolume(self.roiB.getImage()) shpR2 = roiP2.shape logger.info("ROI B dimension : %s:%s" % (str(shpR2[0]), str(shpR2[1]))) blocksize = totalTracts IJKstartpoints2 = numpy.tile(roiP2,( blocksize, 1)) logger.info("IJK start points shape : %s" % str(IJKstartpoints2.shape)) timeS3 = time.time() logger.info("Data type : %s" % data.dtype) if tensEnabled: paths10, paths11, paths12, paths13, paths14 = track.TrackFiberZ40(s, wm, shpD, b.T, G0.T, vts.T, IJKstartpoints2.T,\ r2i, i2r, r2id, i2rd, spa, lV, EV, xVTensor, stepSize, maxLength, fa, spaceEnabled, isIJK) else: paths10, paths11, paths12, paths13, paths14 = track.TrackFiberX40(s, data.flatten(), wm, shpD, b.T, G0.T, vts.T, IJKstartpoints2.T,\ r2i, i2r, r2id, i2rd, spa, stepSize, maxLength, fa, spaceEnabled, isIJK) logger.info("Track fibers in %s sec" % str(time.time()-timeS3)) logger.info("Connect tract") if probMode=='binary': cm2 = track.ConnectFibersX0(paths11, paths14, shpD, lengthEnabled, lengthClass) elif probMode=='cumulative': cm2 = track.ConnectFibersX1(paths11, paths14, shpD, lengthEnabled, lengthClass) else: cm2 = track.ConnectFibersX2(paths11, paths14, shpD, lengthEnabled, lengthClass) if isInRoiA and isInRoiB: cm3 = track.FilterFibers0(paths00, paths01, paths02, paths03, paths04, self.roiA.getImage(), self.roiB.getImage(),\ shpD, threshold, tractOffset, vicinity, sphericalEnabled) cm4 = track.FilterFibers0(paths10, paths11, paths12, paths13, paths14, self.roiB.getImage(), self.roiA.getImage(),\ shpD, threshold, tractOffset, vicinity, sphericalEnabled) else: logger.info("No tractography to execute!") dateT = str(int(round(time.time()))) isDir = os.access('outputs', os.F_OK) if not isDir: os.mkdir('outputs') tmpF = './outputs/' i2r.tofile(tmpF + 'trafo_' + dateT + '.ijk') if smoothEnabled: ga = data[..., bLine] ga = ga.swapaxes(2,0) tmp= 'smooth_' + dateT if not (ga == 0).all(): ga.tofile(tmpF + tmp + '.data') createParams(ga, tmpF + tmp) s.putS(ga, dims, org, i2r, tmp) #if wmEnabled: wm = wm.swapaxes(2,0) tmp= 'brain_' + dateT if not (wm == 0).all(): wm.tofile(tmpF + tmp + '.data') createParams(wm, tmpF + tmp) s.putS(wm, dims, org, i2r, tmp) if tensEnabled: if isIJK: xVTensor = xVTensor.swapaxes(2,0) xVTensor = xVTensor.astype('float32') # slicerd do not support double type yet xYTensor = xYTensor.swapaxes(2,0) xYTensor = xYTensor.astype('float32') # slicerd do not support double type yet tmp= 'tensor_' + dateT if (not (xYTensor == 0).all()) and (not (xVTensor == 0).all()): xYTensor.tofile(tmpF + tmp + '.data') createParams(xYTensor, tmpF + tmp, True) s.putD(xVTensor, dims, org, i2r, mu, tmp) if faEnabled: faMap = faMap.swapaxes(2,0) tmp= 'fa_' + dateT if not (faMap == 0).all(): faMap.tofile(tmpF + tmp + '.data') createParams(faMap, tmpF + tmp) s.putS(faMap, dims, org, i2r, tmp) if traceEnabled: trMap = trMap.swapaxes(2,0) tmp= 'trace_' + dateT if not (trMap == 0).all(): trMap.tofile(tmpF + tmp + '.data') createParams(trMap, tmpF + tmp) s.putS(trMap, dims, org, i2r, tmp) if modeEnabled: moMap = moMap.swapaxes(2,0) tmp= 'mode_' + dateT if not (moMap == 0).all(): moMap.tofile(tmpF + tmp + '.data') createParams(moMap, tmpF + tmp) s.putS(moMap, dims, org, i2r, tmp) if cmEnabled: if isInRoiA: cm = cm.swapaxes(2,0) tmp= 'cmA_' + dateT if not (cm == 0).all(): cm.tofile(tmpF + tmp + '.data') createParams(cm, tmpF + tmp) #s.putS(cm, dims, org, i2r, tmp) tmp= 'cmFA_' + dateT cmf = cm/float(cm.max()) cmf.astype('float32') if not (cmf == 0).all(): cmf.tofile(tmpF + tmp + '.data') createParams(cmf, tmpF + tmp) s.putS(cmf, dims, org, i2r, tmp) if isInRoiB: cm2 = cm2.swapaxes(2,0) tmp= 'cmB_' + dateT if not (cm2 == 0).all(): cm2.tofile(tmpF + tmp + '.data') createParams(cm2, tmpF + tmp) #s.putS(cm2, dims, org, i2r, tmp) tmp= 'cmFB_' + dateT cm2f = cm2/float(cm2.max()) cm2f.astype('float32') if not (cm2f == 0).all(): cm2f.tofile(tmpF + tmp + '.data') createParams(cm2f, tmpF + tmp) s.putS(cm2f, dims, org, i2r, tmp) if isInRoiA and isInRoiB: cm1a2 = cm[...]*cm2[...]/2.0 cm1a2 = cm1a2.astype('uint32') if not (cm1a2 == 0).all(): tmp= 'cmAandB_' + dateT cm1a2.tofile(tmpF + tmp + '.data') createParams(cm1a2, tmpF + tmp) #s.putS(cm1a2, dims, org, i2r, tmp) tmp= 'cmFAandB_' + dateT cm1a2f = cm1a2/float(cm1a2.max()) cm1a2f.astype('float32') cm1a2f.tofile(tmpF + tmp + '.data') createParams(cm1a2f, tmpF + tmp) s.putS(cm1a2f, dims, org, i2r, tmp) cm1o2 = (cm[...]+cm2[...])/2.0 cm1o2 = cm1o2.astype('uint32') if not (cm1o2 == 0).all(): tmp= 'cmAorB_' + dateT cm1o2.tofile(tmpF + tmp + '.data') createParams(cm1o2, tmpF + tmp) #s.putS(cm1o2, dims, org, i2r, tmp) tmp= 'cmFAorB_' + dateT cm1o2f = cm1o2/float(cm1o2.max()) cm1o2f.astype('float32') cm1o2f.tofile(tmpF + tmp + '.data') createParams(cm1o2f, tmpF + tmp) s.putS(cm1o2f, dims, org, i2r, tmp) if not (cm3 == 0).all(): tmp= 'cmA2B_' + dateT cm3 = cm3.swapaxes(2,0) cm3.tofile(tmpF + tmp + '.data') createParams(cm3, tmpF + tmp) #s.putS(cm3, dims, org, i2r, tmp) tmp= 'cmFA2B_' + dateT cm3f = cm3/float(cm3.max()) cm3f.astype('float32') cm3f.tofile(tmpF + tmp + '.data') createParams(cm3f, tmpF + tmp) s.putS(cm3f, dims, org, i2r, tmp) if not (cm4 == 0).all(): tmp= 'cmB2A_' + dateT cm4 = cm4.swapaxes(2,0) cm4.tofile(tmpF + tmp + '.data') createParams(cm4, tmpF + tmp) #s.putS(cm4, dims, org, i2r, tmp) tmp= 'cmFB2A_' + dateT cm4f = cm4/float(cm4.max()) cm4f.astype('float32') cm4f.tofile(tmpF + tmp + '.data') createParams(cm4f, tmpF + tmp) s.putS(cm4f, dims, org, i2r, tmp) logger.debug("pipeline data shape end : %s:%s:%s:%s" % (shpD[0], shpD[1], shpD[2], shpD[3])) return data