Example #1
0
 if ('-skip_cmap' not in cmd_list) or ('-skip_vmap' not in cmd_list) or ('-skip_vmap_assemble' not in cmd_list) or ('-skip_displ' not in cmd_list) or ('-skip_grad' not in cmd_list):
     
     # Loop through all 'input_N' sections of the configuration file
     for cur_sec in conf.GetSections():
         if (cur_sec[:len('input_')]=='input_'):
             
             # Read current input section
             mi_fname = os.path.join(froot, conf.Get(cur_sec, 'mi_file'))
             if ('-silent' not in cmd_list):
                 print(' - ' + str(cur_sec) + ': working with ' + str(mi_fname) + '...')
             meta_fname = os.path.join(froot, conf.Get(cur_sec, 'meta_file'))
             out_folder = os.path.join(froot, conf.Get(cur_sec, 'out_folder'))
             img_range = conf.Get(cur_sec, 'img_range', None, int)
             crop_roi = conf.Get(cur_sec, 'crop_roi', None, int)
             
             SharedFunctions.CheckCreateFolder(out_folder)
             logging.basicConfig(filename=os.path.join(out_folder, 'DSH' + str(g_params['log_suffix']) + '.log'),\
                                 level=logging.DEBUG, format='%(asctime)s | %(levelname)s:%(message)s')
             logging.info('Now starting analysis in folder ' + str(out_folder))
             
             # Initialize image and correlation files
             mi_file = MIfile.MIfile(mi_fname, meta_fname)
             corr_maps = CorrMaps.CorrMaps(mi_file, out_folder, lag_list, kernel_specs, img_range, crop_roi)
             
             # Calculate correlation maps
             if ('-skip_cmap' not in cmd_list):
                 if ('-silent' not in cmd_list):
                     print('    - Computing correlation maps (multiprocess mode to be implemented)')
                 corr_maps.Compute(silent=True, return_maps=False)
                 
             if (('-skip_vmap' not in cmd_list) or (num_proc > 1 and '-skip_vmap_assemble' not in cmd_list) or ('-skip_displ' not in cmd_list) or ('-skip_grad' not in cmd_list)):
Example #2
0
    def Compute(self, silent=True, return_maps=False):
        """Computes correlation maps
        
        Parameters
        ----------
        silent : bool. If set to False, procedure will print to output every time steps it goes through. 
                otherwise, it will run silently
        return_maps : bool. If set to True, procedure will return the array with correlation maps.
                Warning: no memory check is done when this happens, so be aware of memory consumption
                
        Returns
        -------
        res_4D : list of correlation maps (np.float32), if return_maps==True
        """

        if not silent:
            start_time = time.time()
            print('Computing correlation maps:')
        sf.CheckCreateFolder(self.outFolder)
        self.ExportConfiguration()

        if not silent:
            print(
                '  STEP 1: Loading images and computing average intensity...')
        # This will contain image data, eventually zero-padded
        Intensity = np.empty(self.inputShape)
        # This will contain kernel-averaged intensity data
        AvgIntensity = np.empty(
            [self.inputShape[0], self.outputShape[1], self.outputShape[2]])
        # This will contain autocorrelation data ("d0")
        AutoCorr = np.empty(self.outputShape)
        # 2D Kernel to convolve to spatially average images
        ker2D = self.Kernel.ToMatrix()
        # This is to properly normalize correlations at the edges
        ConvNorm = signal.convolve2d(np.ones_like(Intensity[0]),
                                     ker2D,
                                     mode=self.Kernel.convolveMode,
                                     **self.Kernel.convolve_kwargs)
        # Now load all images we need
        self.MIinput.OpenForReading()
        for utidx in range(len(self.UniqueIdx)):
            Intensity[utidx] = self.MIinput.GetImage(
                img_idx=self.UniqueIdx[utidx], cropROI=self.cropROI)
            AvgIntensity[utidx] = signal.convolve2d(
                Intensity[utidx],
                ker2D,
                mode=self.Kernel.convolveMode,
                **self.Kernel.convolve_kwargs)
            if (self.Kernel.convolveMode == 'same'):
                AvgIntensity[utidx] = np.true_divide(AvgIntensity[utidx],
                                                     ConvNorm)
        self.MIinput.Close()

        if not silent:
            print('  STEP 2: Computing contrast...')
        for tidx in range(self.outputShape[0]):
            AutoCorr[tidx] = signal.convolve2d(np.square(Intensity[self.imgIdx[tidx,0,0]]),\
                                               ker2D, mode=self.Kernel.convolveMode, **self.Kernel.convolve_kwargs)
            if (self.Kernel.Padding):
                AutoCorr[tidx] = np.true_divide(AutoCorr[tidx], ConvNorm)
            AutoCorr[tidx] = np.subtract(
                np.true_divide(AutoCorr[tidx], np.square(AvgIntensity[tidx])),
                1)
        MI.MIfile(os.path.join(self.outFolder, 'CorrMap_d0.dat'),
                  self.outMetaData).WriteData(AutoCorr)

        if not silent:
            print('  STEP 3: Computing correlations...')
        if return_maps:
            res_4D = [np.asarray(AutoCorr, dtype=np.float32)]
        for lidx in range(self.numLags):
            if not silent:
                print('     ...lag ' + str(self.lagList[lidx]))
            CorrMap = np.empty_like(AutoCorr)
            for tidx in range(self.imgNumber - self.lagList[lidx]):
                CorrMap[tidx] = signal.convolve2d(np.multiply(Intensity[self.imgIdx[tidx,lidx,0]], Intensity[self.imgIdx[tidx,lidx,1]]),\
                                                  ker2D, mode=self.Kernel.convolveMode, **self.Kernel.convolve_kwargs)
                if (self.Kernel.Padding):
                    CorrMap[tidx] = np.true_divide(CorrMap[tidx], ConvNorm)
                CorrMap[tidx] = np.true_divide(np.subtract(np.true_divide(CorrMap[tidx],\
                                                                           np.multiply(AvgIntensity[self.imgIdx[tidx,lidx,0]],\
                                                                                       AvgIntensity[self.imgIdx[tidx,lidx,1]])),\
                                                            1),\
                                                AutoCorr[tidx])
                # NOTE: in principle a better normalization for CorrMap is with
                #       0.5 * (AutoCorr[t] + AutoCorr[t+tau])
            MI.MIfile(
                os.path.join(
                    self.outFolder,
                    'CorrMap_d' + str(self.lagList[lidx]).zfill(4) + '.dat'),
                self.outMetaData).WriteData(CorrMap)
            if return_maps:
                res_4D.append(np.asarray(CorrMap, dtype=np.float32))

        if not silent:
            print(
                'Procedure completed in {0:.1f} seconds!'.format(time.time() -
                                                                 start_time))

        if return_maps:
            return res_4D
        else:
            return None
Example #3
0
    def __init__(self,
                 MIin,
                 outFolder,
                 centerPos,
                 ROIs=None,
                 maskRaw=None,
                 BkgCorr=None,
                 expTimes=[1],
                 dlsLags=None,
                 imgTimes=None,
                 timeAvg_T=None):
        """
        Initialize SALS

        Parameters
        ----------
        MIin : input MIfile or MIstack. It can be empty (i.e. initialized with metadata only)
        outFolder : output folder path. If the directory doesn't exist, it will be created
        centerPos : [float, float]. Position of transmitted beam [posX, posY], in pixels.
                    The center of top left pixel is [0,0], 
                    posX increases leftwards, posY increases downwards
        ROIs :      None, or raw mask with ROI numbers, or couple [rSlices, aSlices].
                    if raw mask:integer mask with ROI indexes for every pixel, 0-based.
                                Each pixel can only belong to one ROI.
                                Pixels belonging to no ROI are labeled with -1
                                Number of ROI is given by np.max(mask)
                    None would correspond to [None, None]
                    rSlices :   2D float array of shape (N, 2), or 1D float array of length N+1, or None. 
                                If 2D: i-th element will be (rmin_i, rmax_i), where rmin_i and rmax_i 
                                        delimit i-th annulus (values in pixels)
                                If 1D: i-th annulus will be delimited by i-th and (i+1)-th element of the list
                                If None: one single annulus will be generated, comprising the whole image
                    aSlices :   angular slices, same structure as for rSlices. 
                                Here, angles are measured clockwise (y points downwards) starting from the positive x axis
        maskRaw :   2D binary array with same shape as MIin.ImageShape()
                    True values (nonzero) denote pixels that will be included in the analysis,
                    False values (zeroes) will be excluded
                    If None, all pixels will be included.
                    Disregarded if ROIs is already a raw mask
        BkgCorr :   Eventually, data for background correction: [DarkBkg, OptBkg, PDdata], where:
                    DarkBkg :    None, float array or MIfile with dark measurement from the camera. 
                                If None, dark subtraction will be skipped
                                If MIfile, all images from MIfile will be averaged and the raw result will be stored
                    OptBkg :     None, float array or MIfile with empty cell measurement. Sale as MIdark
                    PDdata :    2D float array of shape (Nimgs+2, 2), where Nimgs is the number of images.
                                i-th item is (PD0, PD1), where PD0 is the reading of the incident light, 
                                and PD1 is the reading of the transmitted light.
                                Only useful if DarkBkg or OptBkg is not None
        imgTimes :  None or float array of length Nimgs. i-th element will be the time of the image
                    if None, i-th time will be computed using the FPS from the MIfile Metadata
        expTimes :  list of floats
        """

        self.MIinput = MIin
        self.outFolder = outFolder
        sf.CheckCreateFolder(self.outFolder)
        self.centerPos = centerPos
        self._genROIs(ROIs, maskRaw=maskRaw)
        self._loadBkg(BkgCorr)
        self._loadTimes(imgTimes)
        # check that expTimes is sorted:
        assert np.all(np.diff(expTimes) >= 0
                      ), 'Exposure times ' + str(expTimes) + ' must be sorted!'
        self.expTimes = expTimes
        # ensure that lags are sorted and include 0
        if dlsLags is not None:
            dlsLags = np.unique(dlsLags)
            if dlsLags[0] > 0:
                dlsLags = np.append([0], dlsLags)
        self.dlsLags = dlsLags
        self.timeAvg_T = timeAvg_T
        self._initConstants()
Example #4
0
    def Compute(self):

        sf.CheckCreateFolder(self.outFolder)

        logging.info(
            'NonAffMaps.Compute() started! Result will be saved in folder ' +
            str(self.outFolder))

        # Search for correlation map MIfiles, skip autocorrelation maps

        fw_mistack = self.cmaps_fw.GetCorrMaps(openMIfiles=True)
        bk_mistack = self.cmaps_bk.GetCorrMaps(openMIfiles=True)
        common_lags = list(
            set(fw_mistack.IdxList).intersection(bk_mistack.IdxList))
        if self.lag_range is None:
            if 0 in common_lags: common_lags.remove(0)
        else:
            if self.lag_range[1] < 0:
                self.lag_range[1] = np.max(common_lags) + 1
            common_lags = [
                lag for lag in common_lags
                if (lag != 0 and lag >= self.lag_range[0]
                    and lag <= self.lag_range[1])
            ]

        self.lagList = common_lags

        # Export configuration
        self.ExportConfiguration()

        if self.trans_bk_matrix is not None:
            tr_matrix = np.reshape(np.asarray(self.trans_bk_matrix), (2, 2))
            logging.debug(
                'Backscattered correlation maps will be transformed using matrix '
                + str(tr_matrix) + ' and offset ' + str(self.trans_bk_offset))

        # For each couple of correlation maps (with equal lagtime)
        for lidx in range(len(self.lagList)):

            logging.info('Now working on lagtime ' + str(lidx) + '/' +
                         str(len(self.lagList)) + ' (d' +
                         str(self.lagList[lidx]) + ')')

            fw_lidx = fw_mistack.IdxList.index(self.lagList[lidx])
            bk_lidx = bk_mistack.IdxList.index(self.lagList[lidx])

            # eventually compute normalization factors
            if self.norm_range is not None:
                fw_norm_factor = np.mean(fw_mistack.MIfiles[fw_lidx].Read(
                    zRange=self.norm_range[:2],
                    cropROI=self.norm_range[2:],
                    closeAfter=False))
                if self.trans_bk_matrix is None and self.trans_bk_offset is None:
                    bk_norm_factor = np.mean(bk_mistack.MIfiles[bk_lidx].Read(
                        zRange=self.norm_range[:2],
                        cropROI=self.norm_range[2:],
                        closeAfter=False))
                else:
                    bk_norm_data = bk_mistack.MIfiles[bk_lidx].Read(
                        zRange=self.norm_range[:2],
                        cropROI=None,
                        closeAfter=False)
                    if len(bk_norm_data.shape) > 2:
                        bk_norm_data = np.mean(bk_norm_data, axis=0)
                    logging.debug('shape before transformation: ' +
                                  str(bk_norm_data.shape))
                    bk_norm_data = sp.ndimage.affine_transform(bk_norm_data, tr_matrix, offset=self.trans_bk_offset,\
                                                      output_shape=bk_norm_data.shape, order=1, mode='constant', cval=1.0)
                    norm_cropROI = MI.ValidateROI(self.norm_range[2:],
                                                  bk_norm_data.shape,
                                                  replaceNone=True)
                    logging.debug('shape after transformation: ' +
                                  str(bk_norm_data.shape) +
                                  ' will be cropped with ROI ' +
                                  str(norm_cropROI))
                    bk_norm_factor = np.mean(bk_norm_data[norm_cropROI[1]:norm_cropROI[1]+norm_cropROI[3],\
                                                          norm_cropROI[0]:norm_cropROI[0]+norm_cropROI[2]])
                    bk_norm_data = None
            else:
                fw_norm_factor, bk_norm_factor = 1, 1

            logging.info('Normalization factors: ' + str(fw_norm_factor) +
                         ' (front) and ' + str(bk_norm_factor) + ' (back)')

            # load, normalize and eventually smooth correlation maps.
            fw_data = np.true_divide(
                fw_mistack.MIfiles[fw_lidx].Read(zRange=self.t_range,
                                                 cropROI=self.cropROI,
                                                 closeAfter=True),
                fw_norm_factor)
            bk_data = np.true_divide(
                bk_mistack.MIfiles[bk_lidx].Read(zRange=self.t_range,
                                                 cropROI=self.cropROI,
                                                 closeAfter=True),
                bk_norm_factor)

            if self.smooth_kernel_specs is not None:
                Kernel3D = self.LoadKernel(self.smooth_kernel_specs)
                logging.debug('Smoothing with kernel with shape ' +
                              str(Kernel3D.shape))
                fw_data = signal.convolve(fw_data, Kernel3D, mode='same')
                bk_data = signal.convolve(bk_data, Kernel3D, mode='same')

            # transform backscattered images
            if self.trans_bk_matrix is not None:
                tr_matrix3D = np.asarray(
                    [[1, 0, 0], [0, tr_matrix[0, 0], tr_matrix[0, 1]],
                     [0, tr_matrix[1, 0], tr_matrix[1, 1]]])
                tr_offset3D = np.asarray(
                    [0, self.trans_bk_offset[0], self.trans_bk_offset[1]])
                bk_data = sp.ndimage.affine_transform(bk_data, tr_matrix3D, offset=tr_offset3D,\
                                                      output_shape=fw_data.shape, order=1, mode='constant', cval=1.0)

            # sigma2 = ln(forward-scattering corr / backscattering corr) * 6 / (qz_bk^2 - qz_fw^2)
            sigma2 = np.log(np.true_divide(
                fw_data, bk_data)) * 6.0 / (self.qz_bk**2 - self.qz_fw**2)

            # For the first lagtime, generate and export metadata
            if (lidx == 0):
                out_meta = fw_mistack.MIfiles[fw_lidx].GetMetadata().copy()
                out_meta['hdr_len'] = 0
                out_meta['gap_bytes'] = 0
                out_meta['shape'] = list(sigma2.shape)
                if ('fps' in out_meta):
                    val_tRange = fw_mistack.MIfiles[fw_lidx].Validate_zRange(
                        self.t_range)
                    out_meta['fps'] = float(
                        out_meta['fps']) * 1.0 / val_tRange[2]
                exp_config = cf.Config()
                exp_config.Import(out_meta, section_name='MIfile')
                metadata_fname = os.path.join(self.outFolder,
                                              'NAffMap_metadata.ini')
                exp_config.Export(metadata_fname)
                logging.info('Metadata exported to file ' +
                             str(metadata_fname))

            # export data
            cur_fname = 'NaffMap_d' + str(self.lagList[lidx]).zfill(4) + '.dat'
            MI.MIfile(os.path.join(self.outFolder, cur_fname),
                      metadata_fname).WriteData(sigma2)

            logging.info('Result saved to file ' + str(cur_fname))

            fw_mistack.MIfiles[fw_lidx].Close()
            bk_mistack.MIfiles[bk_lidx].Close()