Index: trunk/src/series/relabel_i_j.m
===================================================================
--- trunk/src/series/relabel_i_j.m	(revision 249)
+++ trunk/src/series/relabel_i_j.m	(revision 457)
@@ -1,43 +1,208 @@
 %'relabel_i_j': relabel an image series with two indices, and correct errors from the RDvision transfer program
-%----------------------------------------------------------------------
-function GUI_input=relabel_i_j(num_i1,num_i2,num_j1,num_j2,Series)
-%requests for the visibility of input windows in the GUI series  (activated directly by the selection in the menu ACTION)
-
-GUI_input={};
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%enable waitbar
-hGUI=findobj(allchild(0),'name','series');
-hseries=guidata(hGUI);%handles of the GUI series
-WaitbarPos=get(hseries.waitbar_frame,'Position');
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% PARAMETERS (for RDvision system)
+%------------------------------------------------------------------------
+% function GUI_config=relabel_i_j(Param)
+%------------------------------------------------------------------------
+
+%%%%%%%%%%% GENERAL TO ALL SERIES ACTION FCTS %%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This function is used in four modes by the GUI series:
+%           1) config GUI: with no input argument, the function determine the suitable GUI configuration
+%           2) interactive input: the function is used to interactively introduce input parameters, and then stops
+%           3) RUN: the function itself runs, when an appropriate input  structure Param has been introduced. 
+%           4) BATCH: the function itself proceeds in BATCH mode, using an xml file 'Param' as input.
+%
+% This function is used in four modes by the GUI series:
+%           1) config GUI: with no input argument, the function determine the suitable GUI configuration
+%           2) interactive input: the function is used to interactively introduce input parameters, and then stops
+%           3) RUN: the function itself runs, when an appropriate input  structure Param has been introduced. 
+%           4) BATCH: the function itself proceeds in BATCH mode, using an xml file 'Param' as input.
+%
+%OUTPUT
+% GUI_input=list of 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
+% In the absence of input (as activated when the current Action is selected
+% in series), the function ouput GUI_input 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
+%    .OutputDir: directory for data outputs, including path
+%    .Action: .ActionName: name of the current activated function
+%             .ActionPath:   path of the current activated function
+%    .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
+%                     .TransformHandle: corresponding function handle
+%    .InputFields: sub structure describing the input fields withfields
+%              .FieldName: name 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
+%    .ProjObject: %sub structure describing a projection object (read from ancillary GUI set_object)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+function GUI_config=relabel_i_j(Param)
+
+%% set the input elements needed on the GUI series when the action is selected in the menu ActionName
+if ~exist('Param','var') % case with no input parameter 
+    GUI_config={'NbViewMax';1;...% max nbre of input file series (default='' , no limitation)
+        'AllowInputSort';'off';...% allow alphabetic sorting of the list of input files (options 'off'/'on', 'off' by default)
+        'WholeIndexRange';'on';...% prescribes the file index ranges from min to max (options 'off'/'on', 'off' by default)
+        'NbSlice';'off'; ...%nbre of slices ('off' by default)
+        'VelType';'off';...% menu for selecting the velocity type (options 'off'/'one'/'two',  'off' by default)
+        'FieldName';'off';...% menu for selecting the field (s) in the input file(options 'off'/'one'/'two', 'off' by default)
+        'FieldTransform'; 'off';...%can use a transform function
+        'ProjObject';'off';...%can use projection object(option 'off'/'on',
+        'Mask';'off';...%can use mask option   (option 'off'/'on', 'off' by default)
+        'OutputDirExt';'';...%set the output dir extension
+               ''};
+        return
+end
+
+%%%%%%%%%%%% STANDARD PART (DO NOT EDIT) %%%%%%%%%%%%
+%% select different modes,  RUN, parameter input, BATCH
+% BATCH  case: read the xml file for batch case
+GUI_config=Param;%reproduce the input parameters, no interactive input
+if ischar(Param)
+    if strcmp(Param,'input?')
+        checkrun=1;% will inly search input parameters (preparation of BATCH mode)
+    else
+        Param=xml2struct(Param);
+        checkrun=0;
+    end
+% RUN case: parameters introduced as the input structure Param
+else
+    hseries=guidata(Param.hseries);%handles of the GUI series
+    WaitbarPos=get(hseries.waitbar_frame,'Position');%position of the waitbar on the GUI series
+    checkrun=2; % indicate the RUN option is used
+end
+
+%% root input file(s) and type
+RootPath=Param.InputTable(:,1);
+RootFile=Param.InputTable(:,3);
+SubDir=Param.InputTable(:,2);
+NomType=Param.InputTable(:,4);
+FileExt=Param.InputTable(:,5);
+
+% get the set of input file names (cell array filecell), and the lists of
+% input file or frame indices i1_series,i2_series,j1_series,j2_series
+[filecell,i1_series,i2_series,j1_series,j2_series]=get_file_series(Param);
+% filecell{iview,fileindex}: cell array representing the list of file names
+%        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
+% set of frame indices used for movie or multimage input 
+% numbers of slices and file indices
+
+NbSlice=1;%default
+if isfield(Param.IndexRange,'NbSlice')&&~isempty(Param.IndexRange.NbSlice)
+    NbSlice=Param.IndexRange.NbSlice;
+end
+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
+nbfield_i=floor(nbfield/NbSlice);%total number of  indexes in a slice (adjusted to an integer number of slices) 
+nbfield=nbfield_i*NbSlice; %total number of fields after adjustement
+
+%determine the file type on each line from the first input file 
+ImageTypeOptions={'image','multimage','mmreader','video'};
+NcTypeOptions={'netcdf','civx','civdata'};
+for iview=1:nbview
+    if ~exist(filecell{iview,1}','file')
+        msgbox_uvmat('ERROR',['the first input file ' filecell{iview,1} ' does not exist'])
+        return
+    end
+    [FileType{iview},FileInfo{iview},MovieObject{iview}]=get_file_type(filecell{iview,1});
+    CheckImage{iview}=~isempty(find(strcmp(FileType{iview},ImageTypeOptions)));% =1 for images
+    CheckNc{iview}=~isempty(find(strcmp(FileType{iview},NcTypeOptions)));% =1 for netcdf files
+    if ~isempty(j1_series{iview})
+        frame_index{iview}=j1_series{iview};
+    else
+        frame_index{iview}=i1_series{iview};
+    end
+end
+
+%% calibration data and timing: read the ImaDoc files
+mode=''; %default
+timecell={};
+itime=0;
+NbSlice_calib={};
+XmlData=cell(1,nbview);%initiate the structures containing the data from the xml file (calibration and timing)
+for iview=1:nbview%Loop on views
+    SubDirBase=regexprep(SubDir{iview},'\..*','');%take the root part of SubDir, before the first dot '.'
+    filexml=[fullfile(RootPath{iview},SubDirBase) '.xml'];%new convention: xml at the level of the image folder
+    if ~exist(filexml,'file')
+        filexml=[fullfile(RootPath{iview},SubDir{iview},RootFile{iview}) '.xml']; % old convention: xml inside the image folder
+        if ~exist(filexml,'file')
+            filexml=[fullfile(RootPath{iview},SubDir{iview},RootFile{iview}) '.civ']; % very old convention: .civ file
+            if ~exist(filexml,'file')
+                filexml='';
+            end
+        end
+    end
+    if ~isempty(filexml)
+        [XmlData{iview},error]=imadoc2struct_special(filexml);
+    end
+    if isfield(XmlData{iview},'Time')
+        itime=itime+1;
+        timecell{itime}=XmlData{iview}.Time;
+    end
+    if isfield(XmlData{iview},'GeometryCalib') && isfield(XmlData{iview}.GeometryCalib,'SliceCoord')
+        NbSlice_calib{iview}=size(XmlData{iview}.GeometryCalib.SliceCoord,1);%nbre of slices for Zindex in phys transform
+        if ~isequal(NbSlice_calib{iview},NbSlice_calib{1})
+            msgbox_uvmat('WARNING','inconsistent number of Z indices for the two field series');
+        end
+    end
+end
+
+%% check coincidence in time for several input file series
+% not relevant
+
+%% coordinate transform or other user defined transform
+%not relevant
+%%%%%%%%%%%% END STANDARD PART  %%%%%%%%%%%%
+ % EDIT FROM HERE
+
+%% check the validity of  input file types
+if CheckImage{1}
+    FileExtOut='.png'; % write result as .png images for image inputs
+elseif CheckNc{1}
+    FileExtOut='.nc';% write result as .nc files for netcdf inputs
+else 
+    msgbox_uvmat('ERROR',['invalid file type input ' FileType{1}])
+    return
+end
+if nbview==2 && ~isequal(CheckImage{1},CheckImage{2})
+        msgbox_uvmat('ERROR','input must be two image series or two netcdf file series')
+    return
+end
+NomTypeOut='_1-2_1';% output file index will indicate the first and last ref index in the series
+if NbSlice~=nbfield_j
+    answer=msgbox_uvmat('INPUT_Y-N',['will not average slice by slice: for so cancel and set NbSlice= ' num2str(nbfield_j)]);
+    if ~strcmp(answer,'Yes')
+        return
+    end
+end
+
+%% Set field names and velocity types
+% not relevant here
+
+%% Initiate output fields
+% not relevant here
+
+%% interactive input of specific parameters (for RDvision system)
 display('RDvision system')
 first_label=0; %image numbers start from 0
-%errorfactor=1 %correct a factor of 2 in NbDk+1
-
-%% read imadoc
-RootPath=get(hseries.RootPath,'String');
-RootFile=get(hseries.RootFile,'String');
-if ~iscell(RootFile)
-    msgbox_uvmat('ERROR','please enter an input image series from RDVision system')%error message for xml file reading
-    return
-end
-basename=fullfile(RootPath{1},RootFile{1}); 
-[XmlData,warntext]=imadoc2struct([basename '.xml']);% read the xml file appended to the present function (containing bug corrections)
-if ~isempty(warntext)
-    msgbox_uvmat('ERROR',warntext)%error message for xml file reading
-end
-nbfield1=size(XmlData.Time,1);
-nbfield2=size(XmlData.Time,2);
-set(hseries.first_i,'String',num2str(first_label))% display the first image in the process
-set(hseries.last_i,'String',num2str(nbfield1*nbfield2-1+first_label))% display the last image in the process
-set(hseries.nb_field,'String',{num2str(nbfield1*nbfield2-1+first_label)})% display the total nbre of images
-SeriesData=get(hGUI,'UserData');
-if ~strcmp(SeriesData.NomType,'_000001')
+if ~strcmp(NomType{1},'_000001')
     msgbox_uvmat('WARNING','the input is not a file from RDvision: this function relabel_i_j has no action');%error message for directory creation
     return
 else
-    answer=msgbox_uvmat('','this function will relabel the file series from RDvision and correct the xml file');%error message for directory creation
+    answer=msgbox_uvmat('','this function will relabel the file series from RDvision from  and correct the xml file');%error message for directory creation
     if ~strcmp(answer,'Yes')
         return
@@ -45,111 +210,144 @@
 end
 
-%% stop program ther when it is selected in the menu (no run action)
-if ~exist('num_i1','var')
-    return
-end
-if nbfield2>=2
-answer=msgbox_uvmat('',[num2str(nbfield1) ' bursts containing ' num2str(nbfield2) ' images each']);%error message for directory creation
-nomtype='_i_j';
-else
-    answer=msgbox_uvmat('',['image series with ' num2str(nbfield1) ' images']);%error message for directory creation
-    nomtype='_i';
-end
-if ~strcmp(answer,'Yes')
-    return
-end
+%% read imadoc
+% RootPath=get(hseries.RootPath,'String');
+% RootFile=get(hseries.RootFile,'String');
+% if ~iscell(RootFile)
+%     msgbox_uvmat('ERROR','please enter an input image series from RDVision system')%error message for xml file reading
+%     return
+% end
+% basename=fullfile(RootPath{1},RootFile{1}); 
+% [XmlData,warntext]=imadoc2struct_special([basename '.xml']);% read the xml file appended to the present function (containing bug corrections)
+% if ~isempty(warntext)
+%     msgbox_uvmat('ERROR',warntext)%error message for xml file reading
+% end
+% nbfield1=size(XmlData.Time,1);
+% nbfield2=size(XmlData.Time,2);
+% set(hseries.first_i,'String',num2str(first_label))% display the first image in the process
+% set(hseries.last_i,'String',num2str(nbfield1*nbfield2-1+first_label))% display the last image in the process
+% set(hseries.nb_field,'String',{num2str(nbfield1*nbfield2-1+first_label)})% display the total nbre of images
+% SeriesData=get(hGUI,'UserData');
+
+
+%% stop program there when it is selected in the menu (no run action)
+% if ~exist('num_i1','var')
+%     return
+% end
+% if nbfield2>=2
+% answer=msgbox_uvmat('',[num2str(nbfield1) ' bursts containing ' num2str(nbfield2) ' images each']);%error message for directory creation
+% nomtype='_i_j';
+% else
+%     answer=msgbox_uvmat('',['image series with ' num2str(nbfield1) ' images']);%error message for directory creation
+%     nomtype='_i';
+% end
+% if ~strcmp(answer,'Yes')
+%     return
+% end
 
 %% copy and adapt the xml file
-if exist([basename '.xml'],'file')
-    try
-        copyfile([basename '.xml'],[basename '.xml~']);% backup the xml file
-    catch ME
-        msgbox_uvmat('ERROR',ME.message);
-        return
-    end
-    t=xmltree([basename '.xml']);
-    
-    %update information on the first image name in the series
-    uid_Heading=find(t,'ImaDoc/Heading');
-    if isempty(uid_Heading)
-        [t,uid_Heading]=add(t,1,'element','Heading');
-    end
-    uid_ImageName=find(t,'ImaDoc/Heading/ImageName');
-    ImageName=name_generator(basename,1,1,'.png','_i_j');
-    [pth,ImageName]=fileparts(ImageName);
-    ImageName=[ImageName '.png'];
-    if isempty(uid_ImageName)
-        [t,uid_ImageName]=add(t,uid_Heading,'element','ImageName');
-    end
-    uid_value=children(t,uid_ImageName);
-    if isempty(uid_value)
-        t=add(t,uid_ImageName,'chardata',ImageName);%indicate  name of the first image, with ;png extension
+if ~isempty(XmlData{1})
+
+%     if exist([basename '.xml'],'file')
+%         try
+%             copyfile([basename '.xml'],[basename '.xml~']);% backup the xml file
+%         catch ME
+%             msgbox_uvmat('ERROR',ME.message);
+%             return
+%         end
+%         filexml=[filebase{1} '.xml']
+        t=xmltree(filexml);
+        
+        %update information on the first image name in the series
+        uid_Heading=find(t,'ImaDoc/Heading');
+        if isempty(uid_Heading)
+            [t,uid_Heading]=add(t,1,'element','Heading');
+        end
+        uid_ImageName=find(t,'ImaDoc/Heading/ImageName');
+        j1=[];
+        if ~isempty(j1_series{1})
+            j1=j1_series{1};
+        end
+        ImageName=fullfile_uvmat(RootPath{1},SubDir{1},RootFile{1},FileExt{1},'_1_1',i1_series{1}(1),[],j);
+%         ImageName=name_generator(basename,1,1,'.png','_i_j');
+        [pth,ImageName]=fileparts(ImageName);
+        ImageName=[ImageName '.png'];
+        if isempty(uid_ImageName)
+            [t,uid_ImageName]=add(t,uid_Heading,'element','ImageName');
+        end
+        uid_value=children(t,uid_ImageName);
+        if isempty(uid_value)
+            t=add(t,uid_ImageName,'chardata',ImageName);%indicate  name of the first image, with ;png extension
+        else
+            t=set(t,uid_value(1),'value',ImageName);%indicate  name of the first image, with ;png extension
+        end
+        
+        %%%% correction RDvision %%%%
+        if isfield(XmlData,'NbDtj')
+            uid_NbDtj=find(t,'ImaDoc/Camera/BurstTiming/NbDtj');
+            uid_value=children(t,uid_NbDtj);
+            if ~isempty(uid_value)
+                t=set(t,uid_value(1),'value',num2str(XmlData.NbDtj));
+            end
+        end
+        if isfield(XmlData,'NbDtk')
+            uid_NbDtk=find(t,'ImaDoc/Camera/BurstTiming/NbDtk');
+            uid_value=children(t,uid_NbDtk);
+            if ~isempty(uid_value)
+                t=set(t,uid_value(1),'value',num2str(XmlData.NbDtk));
+            end
+        end
+        if isempty(j1_series{1}) && isfield(XmlData,'NbDti')
+            uid_Dti=find(t,'ImaDoc/Camera/BurstTiming/Dti');
+            t=add(t,uid_Dti,'chardata',num2str(XmlData.Dti));
+            uid_NbDti=find(t,'ImaDoc/Camera/BurstTiming/NbDti');
+            t=add(t,uid_NbDti,'chardata',num2str(XmlData.NbDti));
+            uid_NbDtj=find(t,'ImaDoc/Camera/BurstTiming/NbDtj');
+            uid_NbDtk=find(t,'ImaDoc/Camera/BurstTiming/NbDtk');
+            t=delete(t,uid_NbDtj);
+            t=delete(t,uid_NbDtk);
+            uid_Dtj=find(t,'ImaDoc/Camera/BurstTiming/Dtj');
+            uid_Dtk=find(t,'ImaDoc/Camera/BurstTiming/Dtk');
+            t=delete(t,uid_Dtj);
+            t=delete(t,uid_Dtk);
+        end
+            SubDirBase=regexprep(SubDir{1},'\..*','');%take the root part of SubDir, before the first dot '.'
+    filexml_new=[fullfile(RootPath{1},SubDirBase) '.xml'];
+        save(t,filexml_new)
+%     end
+end
+
+%% main loop on images
+%j1=[];%default
+nbfield2=size(XmlData{1}.Time,2);
+for ifile=1:nbfield
+    if checkrun
+        update_waitbar(hseries.waitbar_frame,WaitbarPos,ifile/nbfield)
+        stopstate=get(hseries.RUN,'BusyAction');
     else
-        t=set(t,uid_value(1),'value',ImageName);%indicate  name of the first image, with ;png extension
-    end
-    
-    %%%% correction RDvision %%%%
-    if isfield(XmlData,'NbDtj')
-        uid_NbDtj=find(t,'ImaDoc/Camera/BurstTiming/NbDtj');
-        uid_value=children(t,uid_NbDtj);
-        if ~isempty(uid_value)
-            t=set(t,uid_value(1),'value',num2str(XmlData.NbDtj));
-        end
-    end
-    if isfield(XmlData,'NbDtk')
-        uid_NbDtk=find(t,'ImaDoc/Camera/BurstTiming/NbDtk');
-        uid_value=children(t,uid_NbDtk);
-        if ~isempty(uid_value)
-            t=set(t,uid_value(1),'value',num2str(XmlData.NbDtk));
-        end
-    end
-    if strcmp(nomtype,'_i') && isfield(XmlData,'NbDti')
-        uid_Dti=find(t,'ImaDoc/Camera/BurstTiming/Dti');
-        t=add(t,uid_Dti,'chardata',num2str(XmlData.Dti));
-        uid_NbDti=find(t,'ImaDoc/Camera/BurstTiming/NbDti');
-        t=add(t,uid_NbDti,'chardata',num2str(XmlData.NbDti));
-%         uid_value=children(t,uid_NbDti);
-%         if ~isempty(uid_value)
-%             t=set(t,uid_value(1),'value',num2str(XmlData.NbDti));
-%         end
-        uid_NbDtj=find(t,'ImaDoc/Camera/BurstTiming/NbDtj');
-        uid_NbDtk=find(t,'ImaDoc/Camera/BurstTiming/NbDtk');
-        t=delete(t,uid_NbDtj);
-        t=delete(t,uid_NbDtk);
-        uid_Dtj=find(t,'ImaDoc/Camera/BurstTiming/Dtj');
-        uid_Dtk=find(t,'ImaDoc/Camera/BurstTiming/Dtk');
-        t=delete(t,uid_Dtj);
-        t=delete(t,uid_Dtk);
-    end
-    %%%
-    
-    save(t,[basename '.xml'])
-end
-
-%% main loop
-
-for ifile=1:nbfield1*nbfield2
-    update_waitbar(hseries.waitbar,WaitbarPos,ifile/(nbfield1*nbfield2))
-    filename=name_generator(basename,ifile-1,1,Series.FileExt,Series.NomType);
-    num_j=mod(ifile-1+first_label,nbfield2)+1;
-    num_i=floor((ifile-1+first_label)/nbfield2)+1;
-    filename_new=name_generator(basename,num_i,num_j,'.png',nomtype);
-    try
-        movefile(filename,filename_new);
-        [s,errormsg] = fileattrib(filename_new,'-w','a'); %set images to read only '-w' for all users ('a')
-        if ~s
-            msgbox_uvmat('ERROR',errormsg);
+        stopstate='queue';
+    end
+    if isequal(stopstate,'queue') % enable STOP command
+        filename=fullfile_uvmat(RootPath{1},SubDir{1},RootFile{1},FileExt{1},NomType{1},i1_series{1}(ifile));
+        j1=mod(ifile-1+first_label,nbfield2)+1;
+        i1=floor((ifile-1+first_label)/nbfield2)+1;
+        %         filename_new=name_generator(basename,num_i,num_j,'.png',nomtype);
+        filename_new=fullfile_uvmat(RootPath{1},SubDir{1},RootFile{1},FileExt{1},'_1_1',i1,[],j1);
+        try
+            movefile(filename,filename_new);
+            [s,errormsg] = fileattrib(filename_new,'-w','a'); %set images to read only '-w' for all users ('a')
+            if ~s
+                msgbox_uvmat('ERROR',errormsg);
+                return
+            end
+        catch ME
+            msgbox_uvmat('ERROR',ME.message);
             return
         end
-    catch ME
-        msgbox_uvmat('ERROR',ME.message);
-        return
-    end
-end
-
-
-%'imadoc2struct': reads the xml file for image documentation 
+    end
+end
+
+%'imadoc2struct_special': reads the xml file for image documentation 
 %------------------------------------------------------------------------
-% function [s,errormsg]=imadoc2struct(ImaDoc,option) 
+% function [s,errormsg]=imadoc2struct_special(ImaDoc,option) 
 %
 % OUTPUT:
@@ -165,5 +363,5 @@
 % option: ='GeometryCalib': read  the data of GeometryCalib, including source point coordinates
 
-function [s,errormsg]=imadoc2struct(ImaDoc,option) 
+function [s,errormsg]=imadoc2struct_special(ImaDoc,option) 
 
 %% default input and output
@@ -247,5 +445,5 @@
                      s.Dti=Dti;
                 else
-                     NbDtj=NbDtj/numel(Dtj);%bursts
+                    % NbDtj=NbDtj/numel(Dtj);%bursts
                     s.NbDtj=NbDtj;
                 end
