def harmonizeData(self):

        from reconstSignal import reconst, approx
        from preprocess import dti_harm, preprocessing, common_processing

        # check the templatePath
        if not exists(self.templatePath):
            raise NotADirectoryError(f'{self.templatePath} does not exist')
        else:
            if not listdir(self.templatePath):
                raise ValueError(f'{self.templatePath} is empty')

        
        # fit spherical harmonics on reference site
        if self.debug and self.ref_csv:
            check_csv(self.ref_unproc_csv, self.force)
            refImgs, refMasks= read_caselist(self.ref_unproc_csv)

            # reference data is not manipulated in multi-shell-dMRIharmonization i.e. bvalMapped, resampled, nor denoised
            # this block may be uncommented in a future design
            # res= []
            # pool = multiprocessing.Pool(self.N_proc)
            # for imgPath, maskPath in zip(refImgs, refMasks):
            #     res.append(pool.apply_async(func=preprocessing, args=(imgPath, maskPath)))
            #
            # attributes = [r.get() for r in res]
            #
            # pool.close()
            # pool.join()
            #
            # for i in range(len(refImgs)):
            #     refImgs[i] = attributes[i][0]
            #     refMasks[i] = attributes[i][1]

            pool = multiprocessing.Pool(self.N_proc)
            for imgPath, maskPath in zip(refImgs, refMasks):
                pool.apply_async(func= approx, args=(imgPath,maskPath,))

            pool.close()
            pool.join()



        # go through each file listed in csv, check their existence, create dti and harm directories
        check_csv(self.target_csv, self.force)
        targetImgs, targetMasks= common_processing(self.tar_unproc_csv)

        # reconstSignal steps ------------------------------------------------------------------------------------------

        # read target image list
        moving= pjoin(self.templatePath, f'Mean_{self.target}_FA_b{self.bshell_b}.nii.gz')

        if not self.target_csv.endswith('.modified'):
            self.target_csv += '.modified'


        self.harm_csv= self.target_csv+'.harmonized'
        fh= open(self.harm_csv, 'w')
        pool = multiprocessing.Pool(self.N_proc)
        res= []
        for imgPath, maskPath in zip(targetImgs, targetMasks):
            res.append(pool.apply_async(func= reconst, args= (imgPath, maskPath, moving, self.templatePath,)))

        for r in res:
            harmImg, harmMask= r.get()
            fh.write(harmImg + ',' + harmMask + '\n')


        pool.close()
        pool.join()

       
        # loop for debugging
        # res= []
        # for imgPath, maskPath in zip(imgs, masks):
        #     res.append(reconst(imgPath, maskPath, moving, self.templatePath))
        #
        # for r in res:
        #     harmImg, harmMask= r
        #     fh.write(harmImg + ',' + harmMask + '\n')


        fh.close()

        
        if self.debug:
            harmImgs, harmMasks= read_caselist(self.harm_csv)
            pool = multiprocessing.Pool(self.N_proc)
            for imgPath,maskPath in zip(harmImgs,harmMasks):
                pool.apply_async(func= dti_harm, args= (imgPath,maskPath,))
            pool.close()
            pool.join()


        print('\n\nHarmonization completed\n\n')
    def createTemplate(self):

        from buildTemplate import difference_calc, antsMult, warp_bands, \
            dti_stat, rish_stat, template_masking, createAntsCaselist
        from preprocess import common_processing

        # check directory existence
        check_dir(self.templatePath, self.force)

        # go through each file listed in csv, check their existence, create dti and harm directories
        check_csv(self.ref_csv, self.force)
        check_csv(self.target_csv, self.force)

        # createTemplate steps -----------------------------------------------------------------------------------------

        # read image lists
        refImgs, refMasks = common_processing(self.ref_csv)
        if not self.ref_csv.endswith('.modified'):
            self.ref_csv += '.modified'
        # debug: use the following line to omit processing again
        # refImgs, refMasks = read_caselist(self.ref_csv)

        targetImgs, targetMasks = common_processing(self.target_csv)
        if not self.target_csv.endswith('.modified'):
            self.target_csv += '.modified'
        # debug: use the following line to omit processing again
        # targetImgs, targetMasks = read_caselist(self.target_csv)

        imgs = refImgs + targetImgs
        masks = refMasks + targetMasks

        # create caselist for antsMult
        antsMultCaselist = pjoin(self.templatePath, 'antsMultCaselist.txt')
        createAntsCaselist(imgs, antsMultCaselist)

        # run ANTS multivariate template construction

        # ATTN: antsMultivariateTemplateConstruction2.sh requires '/' at the end of templatePath
        if not self.templatePath.endswith('/'):
            self.templatePath += '/'

        # check if bmax template was created earlier
        bmaxTemplateFile = pjoin(self.templatePath, 'bmaxTemplateCompletion')
        template0 = pjoin(self.templatePath, 'template0.nii.gz')
        if not isfile(bmaxTemplateFile):
            # ATTN: antsMultivariateTemplateConstruction2.sh requires absolute path for caselist
            antsMult(abspath(antsMultCaselist), self.templatePath)
        else:
            warnings.warn(
                f'Using {template0} which was created before with bmax shell')

        # load templateHdr
        templateHdr = load(template0).header

        # warp mask, dti, and rish bands
        pool = multiprocessing.Pool(self.N_proc)
        for imgPath, maskPath in zip(imgs, masks):
            pool.apply_async(func=warp_bands,
                             args=(
                                 imgPath,
                                 maskPath,
                                 self.templatePath,
                             ))

        pool.close()
        pool.join()

        # loop for debugging
        # for imgPath, maskPath in zip(imgs, masks):
        #     warp_bands(imgPath, maskPath, self.templatePath)

        print(
            'calculating dti statistics i.e. mean, std calculation for reference site'
        )
        refMaskPath = dti_stat(self.reference, refImgs, refMasks,
                               self.templatePath, templateHdr)
        print(
            'calculating dti statistics i.e. mean, std calculation for target site'
        )
        targetMaskPath = dti_stat(self.target, targetImgs, targetMasks,
                                  self.templatePath, templateHdr)

        print('masking dti statistics of reference site')
        _ = template_masking(refMaskPath, targetMaskPath, self.templatePath,
                             self.reference)
        print('masking dti statistics of target site')
        templateMask = template_masking(refMaskPath, targetMaskPath,
                                        self.templatePath, self.target)

        print(
            'calculating rish_statistics i.e. mean, std calculation of reference site'
        )
        rish_stat(self.reference, refImgs, self.templatePath, templateHdr)
        print(
            'calculating rish_statistics i.e. mean, std calculation of target site'
        )
        rish_stat(self.target, targetImgs, self.templatePath, templateHdr)

        print('calculating templates map for diffusionMeasures')
        difference_calc(self.reference, self.target, refImgs, targetImgs,
                        self.templatePath, templateHdr, templateMask,
                        self.diffusionMeasures)

        print('calculating templates for rishFeatures')
        difference_calc(self.reference, self.target, refImgs, targetImgs,
                        self.templatePath, templateHdr, templateMask,
                        [f'L{i}' for i in range(0, self.N_shm + 1, 2)])

        print('\n\nTemplate creation completed \n\n')

        # write a flag in templatePath that can be used to see if bmax template was created earlier
        if not isfile(bmaxTemplateFile):
            with open(pjoin(bmaxTemplateFile), 'w'):
                pass
    def harmonizeData(self):

        from reconstSignal import reconst, approx
        from preprocess import dti_harm, common_processing, preprocessing

        # check the templatePath
        if not exists(self.templatePath):
            raise NotADirectoryError(f'{self.templatePath} does not exist')
        else:
            if not listdir(self.templatePath):
                raise ValueError(f'{self.templatePath} is empty')



        # fit spherical harmonics on reference site
        if self.debug and self.ref_csv:
            check_csv(self.ref_unproc_csv, self.force)
            refImgs, refMasks= read_imgs_masks(self.ref_unproc_csv)
            res= []
            pool = multiprocessing.Pool(self.N_proc)
            for imgPath, maskPath in zip(refImgs, refMasks):
                res.append(pool.apply_async(func=preprocessing, args=(imgPath, maskPath)))

            attributes = [r.get() for r in res]

            pool.close()
            pool.join()

            for i in range(len(refImgs)):
                refImgs[i] = attributes[i][0]
                refMasks[i] = attributes[i][1]

            pool = multiprocessing.Pool(self.N_proc)
            for imgPath, maskPath in zip(refImgs, refMasks):
                pool.apply_async(func= approx, args=(imgPath,maskPath,))

            pool.close()
            pool.join()



        # go through each file listed in csv, check their existence, create dti and harm directories
        check_csv(self.target_csv, self.force)
        targetImgs, targetMasks= common_processing(self.tar_unproc_csv)


        # reconstSignal steps ------------------------------------------------------------------------------------------

        moving= pjoin(self.templatePath, f'Mean_{self.target}_FA.nii.gz')


        if not self.target_csv.endswith('.modified'):
            self.target_csv += '.modified'


        self.harm_csv= self.target_csv+'.harmonized'
        fh= open(self.harm_csv, 'w')
        pool = multiprocessing.Pool(self.N_proc)
        res= []
        for imgPath, maskPath in zip(targetImgs, targetMasks):
            res.append(pool.apply_async(func= reconst, args= (imgPath, maskPath, moving, self.templatePath,)))

        for r in res:
            harmImg, harmMask= r.get()
            fh.write(harmImg + ',' + harmMask + '\n')


        pool.close()
        pool.join()

        fh.close()
        
        
        if self.debug:
            harmImgs, harmMasks= read_imgs_masks(self.harm_csv)
            pool = multiprocessing.Pool(self.N_proc)
            for imgPath,maskPath in zip(harmImgs,harmMasks):
                pool.apply_async(func= dti_harm, args= (imgPath,maskPath,))
            pool.close()
            pool.join()
            
        print('\n\nHarmonization completed\n\n')