Index: /trunk/src/series/ima_threshold.m
===================================================================
--- /trunk/src/series/ima_threshold.m	(revision 921)
+++ /trunk/src/series/ima_threshold.m	(revision 921)
@@ -0,0 +1,233 @@
+% function ParamOut=particle_tracking(Param)
+%
+% Method: 
+   
+% Organization of image indices:
+    
+%INPUT:
+% num_i1: matrix of image indices i
+% num_j1: matrix of image indices j, must be the same size as num_i1
+% num_i2 and num_j2: not used for a function acting on images
+% Series: matlab structure containing parameters, as defined by the interface UVMAT/series
+%       Series.RootPath{1}: path to the image series
+%       Series.RootFile{1}: root file name
+%       Series.FileExt{1}: image file extension 
+%       Series.NomType{1}: nomenclature type for file in
+%
+% Method: 
+%       Series.NbSlice: %number of slices defined on the interface
+% global A rangx0 rangy0 minA maxA; % make current image A accessible in workspace
+% global hfig1 hfig2 scalar
+% global Abackg nbpart lum diam
+%%%%%%%%%%%%%%ï¿œ
+%
+%%%%%%%%%%% GENERAL TO ALL SERIES ACTION FCTS %%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%OUTPUT
+% ParamOut: sets options in the GUI series.fig needed for the function
+%
+%INPUT:
+% In run mode, the input parameters are given as a Matlab structure Param copied from the GUI series.
+% In batch mode, Param is the name of the corresponding xml file containing the same information
+% when Param.Action.RUN=0 (as activated when the current Action is selected
+% in series), the function ouput paramOut set the activation of the needed GUI elements
+%
+% Param contains the elements:(use the menu bar command 'export/GUI config' in series to 
+% see the current structure Param)
+%    .InputTable: cell of input file names, (several lines for multiple input)
+%                      each line decomposed as {RootPath,SubDir,Rootfile,NomType,Extension}
+%    .OutputSubDir: name of the subdirectory for data outputs
+%    .OutputDirExt: directory extension for data outputs
+%    .Action: .ActionName: name of the current activated function
+%             .ActionPath:   path of the current activated function
+%             .ActionExt: fct extension ('.m', Matlab fct, '.sh', compiled   Matlab fct
+%             .RUN =0 for GUI input, =1 for function activation
+%             .RunMode='local','background', 'cluster': type of function  use
+%             
+%    .IndexRange: set the file or frame indices on which the action must be performed
+%    .FieldTransform: .TransformName: name of the selected transform function
+%                     .TransformPath:   path  of the selected transform function
+%    .InputFields: sub structure describing the input fields withfields
+%              .FieldName: name(s) of the field
+%              .VelType: velocity type
+%              .FieldName_1: name of the second field in case of two input series
+%              .VelType_1: velocity type of the second field in case of two input series
+%              .Coord_y: name of y coordinate variable
+%              .Coord_x: name of x coordinate variable
+%    .ProjObject: %sub structure describing a projection object (read from ancillary GUI set_object)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%=======================================================================
+% Copyright 2008-2015, LEGI UMR 5519 / CNRS UJF G-INP, Grenoble, France
+%   http://www.legi.grenoble-inp.fr
+%   Joel.Sommeria - Joel.Sommeria (A) legi.cnrs.fr
+%
+%     This file is part of the toolbox UVMAT.
+%
+%     UVMAT is free software; you can redistribute it and/or modify
+%     it under the terms of the GNU General Public License as published
+%     by the Free Software Foundation; either version 2 of the license,
+%     or (at your option) any later version.
+%
+%     UVMAT is distributed in the hope that it will be useful,
+%     but WITHOUT ANY WARRANTY; without even the implied warranty of
+%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%     GNU General Public License (see LICENSE.txt) for more details.
+%=======================================================================
+
+function ParamOut=particle_tracking(Param)
+
+%% set the input elements needed on the GUI series when the action is selected in the menu ActionName
+if isstruct(Param) && isequal(Param.Action.RUN,0)
+    % general settings of the GUI:
+    ParamOut.AllowInputSort='off';% allow alphabetic sorting of the list of input file SubDir (options 'off'/'on', 'off' by default)
+    ParamOut.WholeIndexRange='off';% prescribes the file index ranges from min to max (options 'off'/'on', 'off' by default)
+    ParamOut.NbSlice='off'; %nbre of slices ('off' by default)
+    ParamOut.VelType='off';% menu for selecting the velocity type (options 'off'/'one'/'two',  'off' by default)
+    ParamOut.FieldName='off';% menu for selecting the field (s) in the input file(options 'off'/'one'/'two', 'off' by default)
+    ParamOut.FieldTransform = 'off';%can use a transform function
+    ParamOut.ProjObject='off';%can use projection object(option 'off'/'on',
+    ParamOut.Mask='off';%can use mask option   (option 'off'/'on', 'off' by default)
+    ParamOut.OutputDirExt='.patch';%set the output dir extension
+    ParamOut.OutputFileMode='NbSlice';% '=NbInput': 1 output file per input file index, '=NbInput_i': 1 file per input file index i, '=NbSlice': 1 file per slice
+    filecell=get_file_series(Param);%check existence of the first input file
+    if ~exist(filecell{1,1},'file')
+        msgbox_uvmat('WARNING','the first input file does not exist') 
+    end
+    % parameters specific to the function 
+    prompt = {'threshold value'};
+    dlg_title = 'get threshold';
+    num_lines= 1;
+    def     = { '0'};
+    answer = inputdlg(prompt,dlg_title,num_lines,def);
+    if isempty(answer)
+        return
+    end
+    ParamOut.ActionInput.LumThreshold=str2double(answer{1});
+    
+    return
+end
+
+%%%%%%%%%%%%  STANDARD RUN PART  %%%%%%%%%%%%
+ParamOut=[];
+%% read input parameters from an xml file if input is a file name (batch mode)
+checkrun=1;
+if ischar(Param)
+    Param=xml2struct(Param);% read Param as input file (batch case)
+    checkrun=0;
+end
+hseries=findobj(allchild(0),'Tag','series');
+RUNHandle=findobj(hseries,'Tag','RUN');%handle of RUN button in GUI series
+WaitbarHandle=findobj(hseries,'Tag','Waitbar');%handle of waitbar in GUI series
+
+%% define the directory for result file
+OutputDir=[Param.OutputSubDir Param.OutputDirExt];
+
+%% root input file(s) name, type and index series
+RootPath=Param.InputTable{1,1};
+RootFile=Param.InputTable{1,3};
+SubDir=Param.InputTable{1,2};
+NomType=Param.InputTable{1,4};
+FileExt=Param.InputTable{1,5};
+[filecell,i1_series,i2_series,j1_series,j2_series]=get_file_series(Param);
+%%%%%%%%%%%%
+% The cell array filecell is the list of input file names, while
+% filecell{iview,fileindex}:
+%        iview: line in the table corresponding to a given file series
+%        fileindex: file index within  the file series, 
+% i1_series(iview,ref_j,ref_i)... are the corresponding arrays of indices i1,i2,j1,j2, depending on the input line iview and the two reference indices ref_i,ref_j 
+% i1_series(iview,fileindex) expresses the same indices as a 1D array in file indices
+%%%%%%%%%%%%
+nbview=numel(i1_series);%number of input file series (lines in InputTable)
+nbfield_j=size(i1_series{1},1); %nb of fields for the j index (bursts or volume slices)
+nbfield_i=size(i1_series{1},2); %nb of fields for the i index
+nbfield=nbfield_j*nbfield_i; %total number of fields
+
+%% frame index for movie or multimage file input  
+if ~isempty(j1_series{1})
+    frame_index=j1_series{1};
+else
+    frame_index=i1_series{1};
+end
+
+%% check the input file type  
+[FileInfo,VideoObject]=get_file_info(filecell{1,1});
+FileType=FileInfo.FileType;
+ImageTypeOptions={'image','multimage','mmreader','video'};
+if isempty(find(strcmp(FileType,ImageTypeOptions)))
+    disp('input file not images')
+    return
+end
+
+%% calibration data and timing: read the ImaDoc files
+[XmlData,NbSlice_calib,time,errormsg]=read_multimadoc(RootPath,SubDir,RootFile,FileExt,i1_series,i2_series,j1_series,j2_series);
+
+%%%%%%%%%%%%   SPECIFIC PART (to edit) %%%%%%%%%%%%
+%filter for particle center of mass(luminosity)
+
+Threshold=Param.ActionInput.LumThreshold;% luminosity threshold for particle detection, < 0 for black particles, >0 for white particles
+
+%%  fixed mask to avoid tube image
+Amask=imread('/fsnet/project/coriolis/2015/15MINI_MEDDY/0_REF_FILES/mask_patch.png');
+
+%% initiate output statistics data
+Data.ListVarName={'Time','z','Area',  'MajorAxisLength' , 'MinorAxisLength'};
+Data.VarDimName={'Time','z',{'Time','z'},{'Time','z'},{'Time','z'}};
+Data.Time = 1:nbfield_i; %default
+Data.z=1:nbfield_j;
+Data.Area=zeros(nbfield_i,nbfield_j);
+Data.MajorAxisLength=zeros(nbfield_i,nbfield_j);
+Data.MinorAxisLength=zeros(nbfield_i,nbfield_j);
+
+%%%%%% MAIN LOOP ON FRAMES %%%%%%
+for ifile=1:nbfield
+    if checkrun
+        update_waitbar(WaitbarHandle,ifile/nbfield)
+        if ~isempty(RUNHandle) &&ishandle(RUNHandle) && ~strcmp(get(RUNHandle,'BusyAction'),'queue')
+            disp('program stopped by user')
+            return
+        end
+    end
+    i1=i1_series{1}(ifile);
+    j1=1;
+    if ~isempty(j1_series)&&~isequal(j1_series,{[]})
+        j1=j1_series{1}(ifile);
+    end
+    filename=fullfile_uvmat(RootPath,SubDir,RootFile,FileExt,NomType,i1,[],j1);
+    A=read_image(filename,FileType,VideoObject,frame_index(ifile));% read the current frame
+    
+    A=(A>Threshold) & Amask>100;%transform to binary image format
+    try
+        STATS = regionprops(A, 'FilledArea','MinorAxisLength','MajorAxisLength','PixelIdxList');
+        Area=zeros(size(STATS));
+        for iobj=1:numel(STATS)
+            Area(iobj)=STATS(iobj).FilledArea;
+        end
+        [Data.Area(i1,j1), main_obj]=max(Area);
+        Data.MajorAxisLength(i1,j1)=STATS(main_obj).MajorAxisLength;
+        Data.MinorAxisLength(i1,j1)=STATS(main_obj).MinorAxisLength;
+        for iobj=1:numel(STATS)
+            if iobj~=main_obj
+                A(STATS(iobj).PixelIdxList)=0;
+            end
+        end
+
+    catch ME
+        disp('image toolbox not available, program stopped')
+%         return
+    end
+            filename_out=fullfile_uvmat(RootPath,OutputDir,RootFile,'.png',NomType,i1,[],j1);
+        imwrite(255*A,filename_out,'BitDepth',8)
+        disp([filename_out ' written'])
+end
+    
+%% record time series of stat
+[filename_nc,idetect]=name_generator(RootPath,OutputDir,RootFile,'.nc','_i1-i2',1,nbfield_i)
+errormsg=struct2nc(filename_nc,Data);
+
+if isempty(errormsg)
+    [filename_nc ' written']
+else
+    disp(errormsg)
+end
+
Index: /trunk/src/transform_field/ima_patch_detection.m
===================================================================
--- /trunk/src/transform_field/ima_patch_detection.m	(revision 921)
+++ /trunk/src/transform_field/ima_patch_detection.m	(revision 921)
@@ -0,0 +1,191 @@
+% 'ima_edge_detection': find edges 
+
+%------------------------------------------------------------------------
+%%%%  Use the general syntax for transform fields with a single input and parameters %%%%
+% OUTPUT: 
+% DataOut:   output field structure 
+%
+%INPUT:
+% DataIn:  input field structure
+% Param: matlab structure whose field Param.TransformInput contains the filter parameters
+%-----------------------------------
+
+%=======================================================================
+% Copyright 2008-2015, LEGI UMR 5519 / CNRS UJF G-INP, Grenoble, France
+%   http://www.legi.grenoble-inp.fr
+%   Joel.Sommeria - Joel.Sommeria (A) legi.cnrs.fr
+%
+%     This file is part of the toolbox UVMAT.
+%
+%     UVMAT is free software; you can redistribute it and/or modify
+%     it under the terms of the GNU General Public License as published
+%     by the Free Software Foundation; either version 2 of the license,
+%     or (at your option) any later version.
+%
+%     UVMAT is distributed in the hope that it will be useful,
+%     but WITHOUT ANY WARRANTY; without even the implied warranty of
+%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%     GNU General Public License (see LICENSE.txt) for more details.
+%=======================================================================
+
+function DataOut=ima_patch_detection(DataIn,Param)
+
+%% request input parameters
+if isfield(DataIn,'Action') && isfield(DataIn.Action,'RUN') && isequal(DataIn.Action.RUN,0)
+    prompt = {'npx';'npy';'threshold'};
+    dlg_title = 'get the filter size in x and y';
+    num_lines= 3;
+    def     = { '50';'50';'0.3'};
+    if isfield(Param,'TransformInput')&&isfield(Param.TransformInput,'FilterBoxSize_x')&&...
+            isfield(Param.TransformInput,'FilterBoxSize_y')&&isfield(Param.TransformInput,'LumThreshold')
+        def={num2str(Param.TransformInput.FilterBoxSize_x);num2str(Param.TransformInput.FilterBoxSize_y);num2str(Param.TransformInput.LumThreshold)};
+    end
+    
+    
+    
+    %% create the GUI set_threshold
+    set(0,'Units','points')
+    ScreenSize=get(0,'ScreenSize');% get the size of the screen, to put the fig on the upper right
+    Width=350;% fig width in points (1/72 inch)
+    Height=min(0.8*ScreenSize(4),300);
+    Left=ScreenSize(3)- Width-40; %right edge close to the right, with margin=40
+    Bottom=ScreenSize(4)-Height-40; %put fig at top right
+    hfig=findobj(allchild(0),'Tag','set_threshold');
+    if isempty(hfig)
+        hfig=figure('name','set_threshold','tag','set_threshold','MenuBar','none','NumberTitle','off','Units',...
+            'pixels','Position',[Left,Bottom,Width,Height],'DeleteFcn',@closefcn)%);
+    else
+        figure(hfig)
+    end
+    BackgroundColor=get(hfig,'Color');
+    hh=0.14; % box height (relative)
+    ii=0.01; % gap between uicontrols
+    
+    ww=(1-5*ii)/4; % box width (relative)
+    % first raw of the GUI
+    %Amask=imread('/fsnet/project/coriolis/2015/15MINI_MEDDY/0_REF_FILES/mask_patch.png');
+    uicontrol('Style','text','Units','normalized', 'Position', [ii 0.95-2*ii-0.75*hh ww hh/2],'BackgroundColor',BackgroundColor,...
+        'String','Threshold','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','right');%title
+    % uicontrol('Style','edit','Units','normalized', 'Position', [2*ii+ww 0.95-2*ii-hh ww hh],'tag','num_Z_1','BackgroundColor',[1 1 1],...
+    %     'String',num2str(SliceCoord(1,3)),'FontUnits','points','FontSize',12,'FontWeight','bold','TooltipString','''num_Z_1'': z position of first slice');%edit box
+    hThreshold=uicontrol('Style','edit','Units','normalized', 'Position', [3*ii+2*ww 0.95-2*ii-hh ww hh],'tag','Threshold','BackgroundColor',[1 1 1],...
+        'FontUnits','points','FontSize',12,'FontWeight','bold');%edit box
+    uicontrol('Style','slider','Units','normalized', 'Position', [0.1 0.1 0.8 0.1],'tag','SetThreshold','BackgroundColor',[1 1 1],...
+        'FontUnits','points','FontSize',12,'FontWeight','bold','Callback',@(hObject,eventdata)SetThreshold_Callback(hObject,eventdata));%edit box
+  %  uiwait(hfig);
+    %
+    %
+    %     DataOut.TransformInput.FilterBoxSize_x=str2num(answer{1}); %size of the filtering window
+    %     DataOut.TransformInput.FilterBoxSize_y=str2num(answer{2}); %size of the filtering window
+    DataOut.TransformInput.LumThreshold=str2num(get(hThreshold,'String')) %size of the filtering window
+    
+ 
+    
+    return
+end
+
+DataOut=DataIn; %default
+%Amask=imread('/fsnet/project/coriolis/2015/15MINI_MEDDY/0_REF_FILES/mask_patch.png');
+plot_mask(DataIn.A,Param.TransformInput.LumThreshold)
+% Athreshold=Param.TransformInput.LumThreshold;
+% %
+% %     DataOut.A=zeros(size(DataIn.A,1),size(DataIn.A,2),3);
+% DataOut.A=(DataIn.A>Athreshold);%transform to the initial image format
+% %     DataOut.A(:,:,1)=DataIn.A;%transform to the initial image format, red
+% STATS = regionprops(DataOut.A, 'FilledArea','MinorAxisLength','MajorAxisLength','PixelIdxList');
+% Area=zeros(size(STATS));
+% for iobj=1:numel(STATS)
+%     Area(iobj)=STATS(iobj).FilledArea;
+% end
+% [Area, main_obj]=max(Area);
+% MajorAxisLength=STATS(main_obj).MajorAxisLength
+% MinorAxisLength=STATS(main_obj).MinorAxisLength
+% for iobj=1:numel(STATS)
+%     if iobj~=main_obj
+%         DataOut.A(STATS(iobj).PixelIdxList)=0;
+%     end
+% end
+% 
+% DataOut.A=Amax*DataOut.A;
+
+
+%------------------------------------------------------------------------
+% function called by selecting CheckRefraction in the GUI set_slices
+function SetThreshold_Callback(hObject,eventdata)
+%------------------------------------------------------------------------
+hfig=get(hObject,'parent');
+hThreshold=findobj(hfig,'Tag','Threshold');
+Threshold=get(hObject,'Value');
+
+huvmat=findobj(allchild(0),'Tag','uvmat');
+hhuvmat=guidata(huvmat);
+UvData=get(huvmat,'UserData');
+Amax=max(max(UvData.Field.A));
+Amin=min(min(UvData.Field.A));
+Threshold=Amin+(Amax-Amin)*Threshold;
+set(hThreshold,'String',num2str(Threshold))
+
+plot_mask(UvData.Field.A,Threshold)
+
+UvData.XmlData{1}.TransformInput.LumThreshold=Threshold;
+set(huvmat,'UserData',UvData)
+
+
+
+
+
+
+% h_refraction(1)=findobj(hset_slice,'String','surface');
+% h_refraction(2)=findobj(hset_slice,'Tag','num_H');
+% h_refraction(3)=findobj(hset_slice,'String','index');
+% h_refraction(4)=findobj(hset_slice,'Tag','num_RefractionIndex');
+% if isequal(get(hObject,'Value'),1)
+%     set(h_refraction,'Visible','on')
+% else
+%     set(h_refraction,'Visible','off')
+% end
+
+function plot_mask(A,Threshold)
+    
+A=(A>Threshold) ;%& Amask>100;%transform to binary image format
+try
+    STATS = regionprops(A, 'FilledArea','MinorAxisLength','MajorAxisLength','PixelIdxList');
+    Area=zeros(size(STATS));
+    for iobj=1:numel(STATS)
+        Area(iobj)=STATS(iobj).FilledArea;
+    end
+    [Area, main_obj]=max(Area);
+    MajorAxisLength=STATS(main_obj).MajorAxisLength;
+    MinorAxisLength=STATS(main_obj).MinorAxisLength;
+    for iobj=1:numel(STATS)
+        if iobj~=main_obj
+            A(STATS(iobj).PixelIdxList)=0;
+        end
+    end
+catch ME
+    disp('image toolbox not available, skipped')
+end
+[npy,npx]=size(A);
+A=cat(3,A,zeros(npy,npx,2));% make a color image
+
+huvmat=findobj(allchild(0),'Tag','uvmat');
+hhuvmat=guidata(huvmat);
+hmask=findobj(hhuvmat.PlotAxes,'Tag','MaskFig')
+if isempty(hmask)
+    axes(hhuvmat.PlotAxes)
+    hold on
+    imagesc([0.5 npx],[npy-0.5 0.5],A,'AlphaData',0.2,'Tag','MaskFig')
+else
+    set(hmask,'CData',A)
+    set(hmask,'AlphaData',0.2)
+end
+
+
+function closefcn(hObject,eventdata)
+
+huvmat=findobj(allchild(0),'Tag','uvmat');
+hhuvmat=guidata(huvmat);
+hmask=findobj(hhuvmat.PlotAxes,'Tag','MaskFig')
+if ~isempty(hmask)
+   delete(hmask)
+end
