Example #1
0
    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)
Example #4
0
   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