function kinetic
% exctraction automatique d'une cinetique a partir des spectres
% d'un dossier, sur raie derivee (default), positive ou negative.
% normalisation automatique / nb de scan et amplitude de modulation
% Ajustement possible des amplitudes trouvees automatiquement.
% sauvegarde de la courbe
% zoom possible sur spectres experimentaux
% exp 2D peuvent etre traitees
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% temps pour un spectre = milieu de l'acquisition %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% EE fevr 2016
% EE juin 2016: si experience 2D arretee avant la fin, spectre=0 sont
% supprimes
% EE oct2016: smooth possible
% EE june2020: denoise with SVD + compare spectra
% EE sept 2020: bug 1D corrige
%EE jan 2021 bug  time si plusieurs scan corrige
%EE june2021 pas de menu
%EE juill2021 pas de menu quand SVD
%EE sept2021 possible sur plusieurs jours, semaines, mois, annees
%sauvegarde figure en tif plutot que bmp
%EE janv 2022:  bug superposition de spectres  et time(1) non nul pour 1D
%EE janv 2022: error saving 2D fixed
%EE avr2023: pbl plage des sliders
%EE mar2024: time unit choice
%EE avr2024: loading spectra from magnettech (xml avec compression des donnees (1024 points/spectre)) + chargement données pas
%seulement dans current directory + Easyspin 6.0.0 (rescale=> rescaledata)
%EE oct2025 compatibilite avec Matlab2025





clear;close;clc;

linetype={'Derivative';'Positive';'Negative'}; 
timeunit={'[s]';'[min]';'[h]'};
denoisetype={'None';'Smooth';'SVD'};
linetypeval=[]; %init

%version easyspin
try
    easyinfo=easyspin; %seult a partir de  easyspin 6.0.0
    easyversion=str2double(easyinfo.Version(1));
catch 
    easyversion=5; %avant easyspin 6.0.0
end

%handle d'initialisation
versionyear=version('-date');
versionyear=str2double(versionyear(end-4:end)); %annee version matlab
if versionyear>=2014
        hinit=gobjects; %handle=structure
else
        hinit=NaN; %handle=double
end

if versionyear>=2025
    tickNaN=[];
else
    tickNaN=NaN;
end

hkincurve=hinit; %handle courbe cinetique
hcurrent=hinit; %handle du point rouge du point de la courbe  correspondant au spectre courant
hLF=hinit; %handle rectangle bruit bas champ
hHF=hinit; %handle rectangle bruit haut champ
hsig=hinit; %handle rectangle signal
h_linesup=hinit; %handle ligne superieure
h_lineinf=hinit; %handle ligne inferieure
hlinetype=hinit; %handle popup menu
hfiglogdiagS=hinit;% handle figure log(diag(S))
hcurrentlogdiagS=hinit;%handle du point bleu correspondant au rang courant de la SVD

tdelay=0; %init delay (s)
nbptsmooth=[]; %init nb de points du lissage 
rankSVD=[];%init rank SVD
%default_nbptsmooth_rankSVD=[NaN,20,3];%(1), pour rank SVD (2)
defaultnbptslissage=20; %nb de pts par defaut pour moyenne glissante du lissage
defaultrank4SVD=3;%init rang de la SVD

denoisingvalue=1;%init value popup denoising
maxpoints=50;%nb de points max pour smooth
maxrank=20;% rang max pour SVD
SVDstruct=[];%structure des donnees SVD (U, S, V,ydenoise{r})

data1Dloaded=[];%init
disp('The time associated to a spectrum is the time when its mid point is recorded.');

%% chargement des donnees
reload=false; %par defaut nouveau chargement

choice = questdlg('What kind of data do you want to load?','kinetic: data type','Existing kinetic','From Bruker','From Magnettech','Existing kinetic');

if isempty(choice) %si cancel
    return
else
    switch choice
        case 'Existing kinetic'
            [file2load,chemin]=uigetfile('*.mat','Select kinetic to Open');
            if isnumeric(file2load) % cancel;
                return
            else
                load(fullfile(chemin,file2load));
                reload=true;
                
                nbspec=numel(data);
                if ~isduration([data.time]) %sauvegarde avec vieille version
                    for kk=1:nbspec
                        tempt=seconds(data(kk).time);
                        data(kk).time=duration(tempt,'format','dd:hh:mm:ss'); %type duration!!!
                    end
                end
                disp([file2load,' loaded.']);
            end
            
        case 'From Bruker'
            choiceB=questdlg('What kind of Bruker data do you want to load?','kinetic: Bruker','2D','1D','2D');
            if isempty(choiceB) %si cancel
                return
            end
            switch choiceB
                case '2D'
                    [file2load,chemin]=uigetfile('*.YGF','Select Bruker 2D file to Open');
                    if isnumeric(file2load) % cancel;
                        return
                    else
                        disp(['Load ',file2load]);
                        data=load2D(fullfile(chemin,file2load));
                        nbspec=numel(data);
                        data1Dloaded=0;%2D
                    end
                case '1D'
                    [file2load_all,chemin]=uigetfile('*.DSC','Select Bruker 1D files to Open','MultiSelect','on');
                    if isnumeric(file2load_all) % cancel;
                        return
                    else
                        dir_structYGF=dir(fullfile(chemin,'*.YGF')); % structure contenant les noms de fichier.YGF (exp 2D)
                        nb2D=numel(dir_structYGF);
                        nbDSC=numel(file2load_all);
                        indDSC=1:nbDSC;
                        if nb2D>0 %suppression des DSC relatifs à 2D si selectionnes
                            ind2supr=[]; %init des indices de file2load a supprimer car YGF
                          for k2D=1:nb2D
                              nameDSC2supr=dir_structYGF(k2D).name;
                              nameDSC2supr=[nameDSC2supr(1:end-3),'DSC'];
                              nn = find(strcmp(file2load_all,nameDSC2supr));
                              if ~isempty(nn)
                                 disp(['The file ',nameDSC2supr,' is gnored because part of a 2D experiment.']); 
                                 ind2supr=[ind2supr,nn];
                              end
                          end
                          if ~isempty(ind2supr)
                            indDSC(ind2supr)=[];
                            file2load=file2load_all(indDSC);
                          else
                            file2load=file2load_all;
                          end
                        else
                          file2load=file2load_all;
                        end
                        nbspec=numel(file2load);
                        data=load1D;
                        data1Dloaded=1;%1D
                    end
            end
            
         case 'From Magnettech'
            [file2load,chemin]=uigetfile('*.xml','Select Magnettech files to Open','MultiSelect','on');
            if isnumeric(file2load) % cancel;
                return
            else
                nbspec=numel(file2load);
                data=load1Dmagnettech;
                data1Dloaded=1;%1D
            end 
    end     
end

if exist('data','var')
    %%%sauvegarde smooth avec ancienne version kinetic data.specbrut (smooth) en data.secbrut2(smooth)
    if isfield(data,'specbrut')
        for kk=1:size(data,2)
            data(kk).specbrut2=data(kk).specbrut;
        end
        data=rmfield(data,'specbrut');
        denoisingvalue=2;
        nbptsmooth=str2double(nbptsmooth);%ancienne version string sauvegardee
    end
    
if ~(isempty(data)) %no cancel;

%% figure 
hsatmain=figure(1);
scrszpix = get(0,'ScreenSize'); %taille ecran [left, bottom, width, height] en pixels
%scrszcm=scrszpix/get(0,'screenpixelsperinch')*2.54; %1inch=2.54cm  taille ecran en cm

set(hsatmain,'Units','pixels','Outerposition',[scrszpix(3)/3 0.2*scrszpix(4) 1000 scrszpix(4)*0.8],...
    'Name','Kinetic','Menubar', 'none', 'Toolbar', 'none',...%'resize','off',...
    'NumberTitle','off','CloseRequestFcn',@closekinetic,...'DoubleBuffer','on',...,...
    'color',get(0,'DefaultUicontrolBackgroundColor'));

%         %%%% pour ne garder que les outils zoomin, zoomout et main
% hToolbar = findall(hsatmain,'tag','FigureToolBar'); %handle toolbar
% halltoolbar=allchild(hToolbar);%tous les handles de la toolbar
% hzoomin=findall(halltoolbar,'TooltipString','Zoom In');
% hzoomout=findall(halltoolbar,'TooltipString','Zoom Out');
% hhand=findall(halltoolbar,'TooltipString','Pan');
% halltoolbar(halltoolbar==hzoomin)=[];%supprime 1 handle a conserver
% halltoolbar(halltoolbar==hzoomout)=[];%supprime 1 handle a conserver
% halltoolbar(halltoolbar==hhand)=[];%supprime 1 handle a conserver
% set(halltoolbar,'visible','off')

%%% graphes spectres exp %%%
hspecaxes=axes('parent',hsatmain,'Position',[0.01 0.33 0.58 0.64],...
                'Box','on');
hslidsup=uicontrol('Style','slider','Units','Normalized','pos',[0.595 0.84 0.02 0.13],'BackgroundColor',[0.9 0.9 0.9],...
    'parent',hsatmain,'String',num2str(0),'Callback', @slidsup,'TooltipString','Adjust up line for amplitude extraction','SliderStep',[0.1/40 1/40]);%'fontunits','pixels','fontsize',ftsz,...
   % 'Min',-20,'Max',+20);%,'Value',0,);
   
hslidinf=uicontrol('Style','slider','Units','Normalized','pos',[0.595 0.33 0.02 0.13],'BackgroundColor',[0.9 0.9 0.9],...
    'parent',hsatmain,'String',num2str(0),'Callback', @slidinf,'TooltipString','Adjust bottom line for amplitude extraction','SliderStep',[0.1/40 1/40]);



%%% graphes courbe de saturation => cinetique %%%
hsataxes=axes('parent',hsatmain,'Position',[0.64 0.5 0.35 0.47],...
                'Ytick',tickNaN,'Box','on');%,'Xtick',tickNaN);


htimeunit=uicontrol(...
        'Parent',hsatmain,...
        'FontUnits','pixels',...
        'FontSize',13,...
        'BackgroundColor','w',...
        'Units','normalized',...
        'Position',[0.84 0.32 0.07 0.15],...[0.835 0.315 0.05 0.15]
        'String',timeunit,...
        'Value',1,...
        'Callback',@dispsat,...
        'Style','popupmenu');%,... %
   
%%% liste des spectres experimentaux
hlist=uicontrol('Style','listbox','Units','Normalized','pos',[0.64 0.01 0.35 0.38],...
    'parent',hsatmain,'max',2,'min',0,'Callback',{@dispexp,'new'},'fontunits','pixels',...'fontsize',ftsz,...
    'backgroundcolor','w','string',{data(:).name},'value',1,'fontsize',13);

if ~isempty(data1Dloaded) %nouvelles dnnees
    if data1Dloaded
        out=regexp(chemin,filesep,'split');%pour separer les disques et dossiers du chemin et n'afficher que le dernier
        str2disp=['Directory of 1D data = ',out{end-1}];
    else
        str2disp=['2D data = ',file2load];
    end
else %anciennes donnees rechargees
    %out=regexp(chemin,filesep,'split');
    str2disp=['Previously saved data = ',file2load];
end

%out=regexp(chemin,filesep,'split');%pour separer les disques et dossiers du chemin et n'afficher que le dernier
hpath=uicontrol('Style','text','Units','Normalized','pos',[0.64 0.40 0.35 0.02],...
    'parent',hsatmain,'String',str2disp,'HorizontalAlignment','center','tooltipstring',chemin);


        
%%% panel noise
noisestrLF=sprintf('If min=max, noise at low field is not\nconsidered for amplitude extraction.');
noisestrHF=sprintf('If min=max, noise at high field is not\nconsidered for amplitude extraction.');
hpanelnoise = uipanel('Parent',hsatmain,'FontWeight','bold','Title','Noise',...
        'Position',[0.02 0.13 0.35 0.15],'Units','Normalized',...
        'FontUnits','pixels','FontSize',16,'FontWeight','bold');
    %low field
uicontrol('Style','text','Units','Normalized','pos',[0.05 0.7 0.33 0.2],...'BackgroundColor','w',....
    'parent',hpanelnoise,'String','Low Field: from','HorizontalAlignment','center','fontsize',11);
hB1min=uicontrol('Parent',hpanelnoise,...
        'Units','normalized',...
        'FontUnits','pixels',...
        'BackgroundColor','w',...
        'Callback',@dispnoiserange,...
        'FontSize',13,'foregroundcolor','b',...
        'Position',[0.39 0.69 0.15 0.21],...
        'Style','edit',...
    'TooltipString',noisestrLF);
uicontrol('Style','text','Units','Normalized','pos',[0.54 0.7 0.15 0.2],...'BackgroundColor','w',....
    'parent',hpanelnoise,'String','mT to','HorizontalAlignment','center','fontsize',11);    
hB1max=uicontrol('Parent',hpanelnoise,...
        'Units','normalized',...
        'FontUnits','pixels',...
        'BackgroundColor','w',...
        'Callback',@dispnoiserange,...
        'FontSize',13,'foregroundcolor','b',...
        'Position',[0.69 0.69 0.15 0.21],...
        'Style','edit',...
        'TooltipString',noisestrLF);
uicontrol('Style','text','Units','Normalized','pos',[0.84 0.7 0.1 0.2],...'BackgroundColor','w',....
    'parent',hpanelnoise,'String','mT','HorizontalAlignment','center','fontsize',11);    

    %high field
uicontrol('Style','text','Units','Normalized','pos',[0.05 0.25 0.33 0.2],...'BackgroundColor','w',....
    'parent',hpanelnoise,'String','High Field: from','HorizontalAlignment','center','fontsize',11);
hB2min=uicontrol('Parent',hpanelnoise,...
        'Units','normalized',...
        'FontUnits','pixels',...
        'BackgroundColor','w',...
        'Callback',@dispnoiserange,...
        'FontSize',13,'foregroundcolor','b',...
        'Position',[0.39 0.24 0.15 0.21],...
        'Style','edit',...
    'TooltipString',noisestrHF);
uicontrol('Style','text','Units','Normalized','pos',[0.54 0.25 0.15 0.2],...'BackgroundColor','w',....
    'parent',hpanelnoise,'String','mT to','HorizontalAlignment','center','fontsize',11);    
hB2max=uicontrol('Parent',hpanelnoise,...
        'Units','normalized',...
        'FontUnits','pixels',...
        'BackgroundColor','w',...
        'Callback',@dispnoiserange,...
        'FontSize',13,'foregroundcolor','b',...
        'Position',[0.69 0.24 0.15 0.21],...
        'Style','edit',...
        'TooltipString',noisestrHF);
uicontrol('Style','text','Units','Normalized','pos',[0.84 0.25 0.1 0.2],...'BackgroundColor','w',....
    'parent',hpanelnoise,'String','mT','HorizontalAlignment','center','fontsize',11);  


%%% panel signal
hpanelsignal = uipanel('Parent',hsatmain,'FontWeight','bold','Title','Signal',...
        'Position',[0.38 0.13 0.25 0.15],'Units','Normalized',...
        'FontUnits','pixels','FontSize',16,'FontWeight','bold');

uicontrol('Style','text','Units','Normalized','pos',[0.1 0.7 0.2 0.2],...'BackgroundColor','w',....
    'parent',hpanelsignal,'String','From','HorizontalAlignment','center','fontsize',11);
hBsmin=uicontrol('Parent',hpanelsignal,...
        'Units','normalized',...
        'FontUnits','pixels',...
        'BackgroundColor','w',...
        'Callback',@dispnoiserange,...
        'FontSize',13,'foregroundcolor',[0 0.7 0],...
        'Position',[0.34 0.69 0.15 0.21],...
        'Style','edit');
uicontrol('Style','text','Units','Normalized','pos',[0.49 0.7 0.2 0.2],...'BackgroundColor','w',....
    'parent',hpanelsignal,'String','mT to','HorizontalAlignment','center','fontsize',11);    
hBsmax=uicontrol('Parent',hpanelsignal,...
        'Units','normalized',...
        'FontUnits','pixels',...
        'BackgroundColor','w',...
        'Callback',@dispnoiserange,...
        'FontSize',13,'foregroundcolor',[0 0.7 0],...
        'Position',[0.69 0.69 0.15 0.21],...
        'Style','edit');
uicontrol('Style','text','Units','Normalized','pos',[0.84 0.7 0.1 0.2],...'BackgroundColor','w',....
    'parent',hpanelsignal,'String','mT','HorizontalAlignment','center','fontsize',11);    


hlinetype=uicontrol(...
        'Parent',hpanelsignal,...
        'FontUnits','pixels',...
        'FontSize',12,...
        'BackgroundColor','w',...
        'Units','normalized',...
        'Callback',@setlinetype,...
        'Position',[0.2 0.2 0.35 0.3],...[0.2 0.25 0.35 0.15],...
        'String',linetype,...
        'Style','popupmenu');%,...
        %'Value',1);

uicontrol('Style','text','Units','Normalized','pos',[0.55 0.2 0.15 0.3],...'BackgroundColor','w',....
    'parent',hpanelsignal,'String','line','HorizontalAlignment','center','fontsize',11); 


heditdelay=uicontrol('Parent',hsatmain,...
        'Units','normalized',...
        'FontUnits','pixels',...
        'BackgroundColor','w',...
        'Callback',@considerdelay,...
        'FontSize',13,...
        'Position',[0.34 0.08 0.06 0.03],...
        'Style','edit',...
        'String',num2str(tdelay),...
    'TooltipString','Delay between experiment and first record (s)');

uicontrol('Style','text','Units','Normalized','pos',[0.29 0.08 0.05 0.03],...'BackgroundColor','w',....
    'parent',hsatmain,'String','delay=','HorizontalAlignment','left','fontsize',11,...
    'TooltipString','Delay between experiment and start of first record');    
uicontrol('Style','text','Units','Normalized','pos',[0.4 0.08 0.02 0.03],...'BackgroundColor','w',....
    'parent',hsatmain,'String','s','HorizontalAlignment','center','fontsize',11,...
    'TooltipString','Delay between experiment and start of first record (s)'); 

h2all=uicontrol('Style','pushbutton','String','Send to all spectra','Units','Normalized','HorizontalAlignment','center',...
    'pos',[0.02 0.05 0.1 0.05],'parent',hsatmain,'Callback', {@sent,'all'},...%[0.02 0.09 0.1 0.04]
    'fontunits','pixels','fontsize',11,'TooltipString','Send noise and signal ranges to all spectra');
% uicontrol('Style','pushbutton','String','Send to prev. spectra','Units','Normalized','HorizontalAlignment','center',...
%     'pos',[0.02 0.044 0.1 0.04],'parent',hsatmain,'Callback', {@sent,'prev'},...
%     'fontunits','pixels','fontsize',11,'TooltipString','Send noise and signal ranges to all previous spectra');
% uicontrol('Style','pushbutton','String','Send to next spectra','Units','Normalized','HorizontalAlignment','center',...
%     'pos',[0.02 0.002 0.1 0.04],'parent',hsatmain,'Callback', {@sent,'next'},...
%     'fontunits','pixels','fontsize',11,'TooltipString','Send noise and signal ranges to all next spectra');

hsavekin=uicontrol('Style','pushbutton','String','Save Kinetic','Units','Normalized','HorizontalAlignment','center',...
    'pos',[0.15 0.05 0.1 0.05],'parent',hsatmain,'Callback', @savesat,...
    'fontunits','pixels','fontsize',11);




% hchk_smooth=uicontrol('Style','checkbox','String','Smooth  (','Units','Normalized','HorizontalAlignment','center',...
%     'pos',[0.3 0.01 0.07 0.03],'parent',hsatmain,'Callback', @lissage,'value',val2disp,...
%     'fontunits','pixels','fontsize',11,'TooltipString','Treatment on smoothed data');
% hnbpts_smooth=uicontrol('Style','edit','String',num2str(nb2disp),'Units','Normalized','HorizontalAlignment','center',...
%     'pos',[0.37 0.01 0.03 0.03],'parent',hsatmain,'Callback', @nbpts_lissage,'enable','inactive',...
%     'fontunits','pixels','fontsize',11,'BackgroundColor','w','TooltipString','Points number for moving average');
% uicontrol('Style','text','Units','Normalized','pos',[0.4 0.013 0.04 0.02],...'BackgroundColor','w',....
%     'parent',hsatmain,'String','points)','HorizontalAlignment','center','fontunits','pixels','fontsize',11,...
%     'TooltipString','Points number for moving average');    

%%%%% denoising
tooltip_str_denoise={'';'Points number for moving average';'Rank for singular values'};
str_info_denoise={'';'Points:';'Rank:'};

hdenoisetype=uicontrol('Parent',hsatmain,...
        'FontUnits','pixels',...
        'FontSize',13,...
        'BackgroundColor','w',...
        'Units','normalized',...
        'Callback',@denoisedatalaunch,...
        'Position',[0.365 0.025 0.07 0.035],...[0.365 0.055 0.08 0.03]
        'String',denoisetype,...
        'Style','popupmenu',...
        'Value',denoisingvalue);
uicontrol('Style','text','Units','Normalized','pos',[0.29 0.025 0.07 0.03],...'BackgroundColor','w',....
    'parent',hsatmain,'String','denoising:','HorizontalAlignment','left','fontsize',11);  

hinfodenoising=uicontrol('Style','text','Units','Normalized','pos',[0.46 0.025 0.05 0.03],...'BackgroundColor','w',....
    'parent',hsatmain,'HorizontalAlignment','right','String','points:','fontsize',11,'visible','off');%,...'String','points:',
    %'TooltipString','Points number for moving average'); 
    
hnbpts_smoothrank=uicontrol('Style','edit','Units','Normalized','HorizontalAlignment','center',...
     'pos',[0.51 0.025 0.03 0.03],'parent',hsatmain,'visible','on','Callback', @editnum,...
     'fontsize',11,'BackgroundColor','w');%,'TooltipString','Points number for moving average'); 

% hsliddenoise=uicontrol('Style','slider','Units','Normalized','pos',[0.54 0.025 0.018 0.03],'BackgroundColor',[0.9 0.9 0.9],...
%     'parent',hsatmain,'Callback', @slidnum,...'String',num2str(0,'%3.2f'),'fontsize',ftsz,...
%     'Min',1,'Max',50,'Value',1,'SliderStep',[1/49 1/49],'visible','off');%
hrankmoins=uicontrol('Style','pushbutton','Units','Normalized','pos',[0.54 0.020 0.02 0.02],...'BackgroundColor',[0.9 0.9 0.9],...
    'parent',hsatmain,'String','-','Callback',{@changerank,-1},'visible','on');
hrankplus=uicontrol('Style','pushbutton','Units','Normalized','pos',[0.54 0.04 0.02 0.02],...'BackgroundColor',[0.9 0.9 0.9],...
    'parent',hsatmain,'String','+','Callback',{@changerank,+1},'visible','on');

 setdenoisingcontrol;

%%% + et -
uicontrol('Style', 'pushbutton', 'String', 'Down','Units','Normalized','Position', [0.59 0.01 0.05 0.05],...
    'parent',hsatmain,'Callback',{@plus_or_minus_fctn,'+'},'tooltipstring','Change spectrum');
%     uicontrol(plusbutton);%set(plusbutton,'selected','off'); %focus par défaut sur bouton +
uicontrol('Style', 'pushbutton', 'String', 'Up','Units','Normalized','Position', [0.59 0.06 0.05 0.05],...
    'parent',hsatmain,'Callback', {@plus_or_minus_fctn,'-'},'tooltipstring','Change spectrum');

%%%%%%%%%%%%%%% init %%%%%%%%%%%%%%%%
% if data(1).amp==0
%     alpha1initnum=max(data(1).spec)-min(data(1).spec);
% else
%     alpha1initnum=data(1).amp;
% end
% alpha1=log10(alpha1initnum/data(1).sqrtpuissance); %init facteur de propportionalite pour diag sur sat curve
% alpha2=0;
%     set(hslidinf,'value',alpha2);
kolor= [0 0 1; %1  pour comparer les spectres
        0.3 0.8 0; %2
        1 0.6 0; %3
        0 0.8 1; %4
        0.6 0 0; %5
        0.75 0.75 0; %6
        1 0 0; %7
        0 1 0.5; %8
        0.7 0 1; %9
        0.4 0.4 0.4;%10
        0.8 0.8 0.8];%11
num_definedkolor=size(kolor,1); %nb de couleurs definies
dispexp(hlist,[],'new')
if isempty(linetypeval)
    linetypeval=1;
    disp('The signal type is unknown. The default one is indicated (Derivative) and could be wrong.');
end
set(hlinetype,'value',linetypeval);
end
end
%%
function data1D=load1D()
    %if nbspec>1
        for k=1:nbspec
            data1D(k).name=file2load{k};%dir_structDSC(k,1).name;%nom du fichier
            [B,spec,par]=eprload(fullfile(chemin,data1D(k).name));
            if iscell(B)
               error(['Kinetic is not able to deal with 1D Data present in ',chemin,'. Please, check 1D data compatibility.']);
            end
            data1D(k).B=B/10;%B en mT
            MA=par.B0MA;%amplitude de modulation (T)
            nbsc=par.AVGS;%nb de scan
            data1D(k).spec=spec/MA/nbsc;%normalisation du signal par nb de scan et amplitude de modulation
            acqtime(k)=str2double(par.SweepTime(1:end-2))*nbsc; %s temps d'acquisition du spectre
         
            data1D(k).tempsh=datestr(datenum(par.TIME)-datenum(datestr(acqtime(k)/2/86400,'HH:MM:SS')),'HH:MM:SS');% heure d'enregistrement (hh:mm:ss): heure - 1/2 acquisition
            data1D(k).date=par.DATE;% date d'enregistrement (MM/DD/YY)
            data1D(k).timenum=datetime([data1D(k).date,' ',data1D(k).tempsh],'InputFormat','MM/dd/yy HH:mm:ss'); %date et heure associee au spectre version matlab
            
            data1D(k).B1min=floor(data1D(k).B(1))+1;%plage de champ pour tenir compte du bruit (bas champ)
            data1D(k).B1max=floor(data1D(k).B(1))+1;            


            [data1D(k).imin1,data1D(k).imax1]=getindex(data1D(k).B,[data1D(k).B1min data1D(k).B1max]); %indice pour plage bas champ 

            data1D(k).B2min=floor(data1D(k).B(end));%plage de champ pour tenir compte du bruit (haut champ)
            data1D(k).B2max=floor(data1D(k).B(end));
            [data1D(k).imin2,data1D(k).imax2]=getindex(data1D(k).B,[data1D(k).B2min data1D(k).B2max]); %indice pour plage haut champ 

            data1D(k).Bsmin=floor(data1D(k).B(1)+(data1D(k).B(end)-data1D(k).B(1))/4);%plage de champ du signal
            data1D(k).Bsmax=floor(data1D(k).B(1)+3*(data1D(k).B(end)-data1D(k).B(1))/4);
            [data1D(k).imins,data1D(k).imaxs]=getindex(data1D(k).B,[data1D(k).Bsmin data1D(k).Bsmax]); %indice pour plage du signal 

            data1D(k).ysup=posline(data1D(k),'sup'); %ordonnee ligne superieure
            data1D(k).yinf=posline(data1D(k),'inf'); %ordonnee ligne inferieure
            data1D(k).amp=data1D(k).ysup-data1D(k).yinf;
            
            clear B spec par MA nbsc 
        end
        [~,order]=sort([data1D(:).timenum]); %ordonner selon temps croissants
        data1D=data1D(order);
        
        for k=1:nbspec
            data1D(k).time=duration(data1D(k).timenum-data1D(1).timenum,'format','dd:hh:mm:ss')+seconds(acqtime(1)/2); %type duration!!!
        end
% 
%     else
%                 error('No data...');
% 
%     end

end

function data1D=load1Dmagnettech()

        for k=1:nbspec
            msg=fprintf(['loading and compressing data... (',num2str(k/nbspec*100,'%2.f'),'%%)']);pause(0.0001)
            data1D(k).name=file2load{k};%dir_structDSC(k,1).name;%nom du fichier
            [B,spec,par]=eprload(fullfile(chemin,data1D(k).name));
            if iscell(B)
               error(['Kinetic is not able to deal with 1D Data present in ',chemin,'. Please, check 1D data compatibility.']);
            end
            %%%%%% xml (>22000pts avec param standard d'enregistrement)=> interpolation à 1024 points
            if strcmp(data1D(k).name([end-3:end]),'.xml')
                
                B_=linspace(B(1),B(end),1024);
                spec_=interp1(B,spec,B_,'spline');
                clear B spec
                B=B_;
                spec=spec_;
            end


            data1D(k).B=B;%/10;%B en mT  deja en mT avec magnettech
            MA=par.Modulation;%amplitude de modulation (T)
            nbsc=par.Accumulations;%nb de scan  (normalisation faite par logiciel spectro)
            data1D(k).spec=spec/MA;%/nbsc;%normalisation du signal par  amplitude de modulation
            
   
            acqtime(k)=par.SweepTime*nbsc; %s temps d'acquisition du spectre

            timestamp=par.Timestamp; %forme:'2024-04-03T18:12:58.5654129+02:00'  debut du scan
            data1D(k).date=timestamp(1:10);% date d'enregistrement (YY-MM-DD)
            timeinit=[timestamp(12:17),num2str(round(str2double(timestamp(18:25))))];% heure d'enregistrement (HH:MM:SS)
            data1D(k).tempsh=datestr(datetime(timeinit,'inputformat','HH:mm:ss')+seconds(acqtime(k)/2),'HH:MM:SS');
            data1D(k).timenum=datetime([data1D(k).date,' ',data1D(k).tempsh],'InputFormat','yy-MM-dd HH:mm:ss'); %date et heure associee au spectre version matlab

            
            data1D(k).B1min=floor(data1D(k).B(1))+1;%plage de champ pour tenir compte du bruit (bas champ)
            data1D(k).B1max=floor(data1D(k).B(1))+1;    
            [data1D(k).imin1,data1D(k).imax1]=getindex(data1D(k).B,[data1D(k).B1min data1D(k).B1max]); %indice pour plage bas champ 

            data1D(k).B2min=floor(data1D(k).B(end));%plage de champ pour tenir compte du bruit (haut champ)
            data1D(k).B2max=floor(data1D(k).B(end));
            [data1D(k).imin2,data1D(k).imax2]=getindex(data1D(k).B,[data1D(k).B2min data1D(k).B2max]); %indice pour plage haut champ 

            data1D(k).Bsmin=floor(data1D(k).B(1)+(data1D(k).B(end)-data1D(k).B(1))/4);%plage de champ du signal
            data1D(k).Bsmax=floor(data1D(k).B(1)+3*(data1D(k).B(end)-data1D(k).B(1))/4);
            [data1D(k).imins,data1D(k).imaxs]=getindex(data1D(k).B,[data1D(k).Bsmin data1D(k).Bsmax]); %indice pour plage du signal 

            data1D(k).ysup=posline(data1D(k),'sup'); %ordonnee ligne superieure
            data1D(k).yinf=posline(data1D(k),'inf'); %ordonnee ligne inferieure
            data1D(k).amp=data1D(k).ysup-data1D(k).yinf;
            
            clear B spec par MA nbsc 
            fprintf(repmat('\b', 1,msg)); %supprime la ligne 'loading...'
        end
        
        [~,order]=sort([data1D(:).timenum]); %ordonner selon temps croissants
        data1D=data1D(order);
        

        for k=1:nbspec
           
            data1D(k).time=duration(data1D(k).timenum-data1D(1).timenum,'format','dd:hh:mm:ss')+seconds(acqtime(1)/2); %type duration!!!
        
        end

end





function data2D=load2D(file)
    [x,spec,par]=eprload([file(1:end-3),'DSC']); %chargement de l'experience 2D
    nbspc=size(spec,2); %nb de spectres a considerer
    starttime=x{1,2}; %s temps de debut d'acquisition de chaque spectre
    nbsc=par.AVGS;%nb de scan
    while nbsc==0 || isnan(nbsc)  %si manip arretee avant la fin AVGS=0
       nbsc=str2double(inputdlg(sprintf('Enter the scan number per spectrum:\n(Stop before finishing?)'),'',1,{'1'}));
    end
    acqtime=str2double(par.SweepTime(1:end-2))*nbsc; %s temps d'acquisition d'un spectre
    delai=starttime(2)-starttime(1)-acqtime; %s delai entre 2 acquisitions
    MA=par.B0MA;%amplitude de modulation (T)
    
    n=1;
    for k=1:nbspc
        if ~isequal(spec(:,k),zeros(size(spec,1),1)) %si  exp 2D arretee avant la fin
            ind2keep(n)=k;
            n=n+1;
        end
    end
    
    for k=ind2keep
        data2D(k).name=['spectre ',num2str(k)];
        data2D(k).B=x{1,1}/10; %mT champ magnetique experimental en gauss
        data2D(k).spec=spec(:,k)/MA;%/nbsc;%normalisation du signal par nb de scan et amplitude de modulation
        timetemp=seconds(starttime(k)+acqtime/2);
        data2D(k).time=duration(timetemp,'format','dd:hh:mm:ss'); %type duration!!!
        
        data2D(k).tempsh=datestr(datenum(par.TIME)-datenum(datestr(((2*nbspc+1-2*k)/2*acqtime+(nbspc-k)*delai)/86400,'HH:MM:SS')),'HH:MM:SS');% heure d'enregistrement (hh:mm:ss)
        
        data2D(k).B1min=floor(data2D(k).B(1))+1;%plage de champ pour tenir compte du bruit (bas champ)
        data2D(k).B1max=floor(data2D(k).B(1))+1;            
        [data2D(k).imin1,data2D(k).imax1]=getindex(data2D(k).B,[data2D(k).B1min data2D(k).B1max]); %indice pour plage bas champ 
        
        data2D(k).B2min=floor(data2D(k).B(end));%plage de champ pour tenir compte du bruit (haut champ)
        data2D(k).B2max=floor(data2D(k).B(end));
        [data2D(k).imin2,data2D(k).imax2]=getindex(data2D(k).B,[data2D(k).B2min data2D(k).B2max]); %indice pour plage haut champ 

        data2D(k).Bsmin=floor(data2D(k).B(1)+(data2D(k).B(end)-data2D(k).B(1))/4);%plage de champ du signal
        data2D(k).Bsmax=floor(data2D(k).B(1)+3*(data2D(k).B(end)-data2D(k).B(1))/4);
        [data2D(k).imins,data2D(k).imaxs]=getindex(data2D(k).B,[data2D(k).Bsmin data2D(k).Bsmax]); %indice pour plage du signal 

        data2D(k).ysup=posline(data2D(k),'sup'); %ordonnee ligne superieure
        data2D(k).yinf=posline(data2D(k),'inf'); %ordonnee ligne inferieure
        data2D(k).amp=data2D(k).ysup-data2D(k).yinf;
    end
    [~,order]=sort([data2D(:).time]); %ordonner selon temps croissants
    data2D=data2D(order);
    
end

function dispexp(hobject,~,status) %affichage spectre  
    rang=get(hobject,'value'); %numero du spectre dans la liste
    
    if strcmp(status,'new') 
        h2del=get(hspecaxes,'children');
        delete(h2del);

        if numel(rang)==1 %1! spectre selectionne)  
            set([get(hpanelnoise,'children');get(hpanelsignal,'children');heditdelay;h2all;hsavekin;...
                hdenoisetype;hnbpts_smoothrank;hrankmoins;hrankplus],'enable','on');
            
            if isfield(data(rang),'specbrut2') %lissage actif
               hspecbrut=plot(hspecaxes,data(rang).B,data(rang).specbrut2,'color',[0.8 0.8 0.8],'linewidth',2);
               hold(hspecaxes,'on');
               hspec=plot(hspecaxes,data(rang).B,data(rang).spec,'k','linewidth',2);
               rangey=1.1*[min(data(rang).specbrut2) max(data(rang).specbrut2)];
               
            elseif isfield(data(rang),'specbrut3') %SVD actif
               hspecbrut=plot(hspecaxes,data(rang).B,data(rang).specbrut3,'color',[0.8 0.8 0.8],'linewidth',2);
               hold(hspecaxes,'on');
               hspec=plot(hspecaxes,data(rang).B,data(rang).spec,'k','linewidth',2);
               rangey=1.1*[min(data(rang).specbrut3) max(data(rang).specbrut3)];
               if ~ishandle(hfiglogdiagS)
                   plotlogdiagS
                   figure(hfiglogdiagS);
                   hcurrentlogdiagS=plot(rankSVD,log(SVDstruct.S(rankSVD,rankSVD)),'ob','markerfacecolor',[51 153 255]/255);
                   figure(hsatmain);
               end
            else
               hspec=plot(hspecaxes,data(rang).B,data(rang).spec,'k','linewidth',2);
               rangey=1.1*[min(data(rang).spec) max(data(rang).spec)]; 
            end

            set(hspecaxes,'xlim',[data(rang).B(1) data(rang).B(end)],'Ytick',tickNaN,'ylim',rangey);
            xlabel(hspecaxes,'Magnetic Field [mT]');


            set(hB1min,'string',num2str(data(rang).B1min));
            set(hB1max,'string',num2str(data(rang).B1max));
            set(hB2min,'string',num2str(data(rang).B2min));
            set(hB2max,'string',num2str(data(rang).B2max));
            set(hBsmin,'string',num2str(data(rang).Bsmin));
            set(hBsmax,'string',num2str(data(rang).Bsmax));
%             if ~isfield(data(rang),'linetypeval') || isempty(data(rang).linetypeval)
%           
%                 data(rang).linetypeval=linetypeval;
%             end  
%             set(hlinetype,'value',data(rang).linetypeval);
            
            %rectangles pour bruit et signal
            hLF=disprect('B1',rang); %noise low field
            hHF=disprect('B2',rang); %noise high field
            hsig=disprect('Bs',rang); %signal

            %lines pour extraction amplitude
            [imins,imaxs]=getindex(data(rang).B,[data(rang).Bsmin data(rang).Bsmax]);
            h_linesup=line([data(rang).B(imins) data(rang).B(imaxs)],data(rang).ysup*[1 1],'color','m','parent',hspecaxes);
            h_lineinf=line([data(rang).B(imins) data(rang).B(imaxs)],data(rang).yinf*[1 1],'color','m','parent',hspecaxes);

            %init sliders
    maxrange=max(data(rang).spec(imins:imaxs));
    minrange=min(data(rang).spec(imins:imaxs));
    set(hslidsup,'value',data(rang).ysup,'max',maxrange+0.4*sign(maxrange)*maxrange,'min',minrange);
    set(hslidinf,'value',data(rang).yinf,'max',maxrange,'min',minrange-0.4*sign(minrange)*minrange);
            time2disp=char(data(rang).time+seconds(tdelay));

            nb22points=numel(strfind(time2disp,':'));
            if nb22points==2 % hh:mm:ss
            title(hspecaxes,[time2disp,' (hh:mm:ss) / Amplitude = ',num2str(data(rang).amp,'%3.2e')]);
            elseif nb22points==3% dd:hh:mm:ss
               title(hspecaxes,[time2disp,' (dd:hh:mm:ss) / Amplitude = ',num2str(data(rang).amp,'%3.2e')]);
            end
            dispsat() %affichage courbe de saturation => cinetique
            
        else %plusieurs spectres selectiones
            if isfield(data(rang),'specbrut2') || isfield(data(rang),'specbrut3') %lissage ou SVD actif
                str2disp='Amplitude normalization (denoised data)';
            else
               str2disp='Amplitude normalization';
            end
            y=data(rang(1)).spec; %1er spectre  = reference
            maxy(1)=max(y);
            miny(1)=min(y);
             plot(hspecaxes,data(rang(1)).B,y,'color',kolor(1,:));%,'linewidth',2);
             hold(hspecaxes,'on');
            for k=2:numel(rang)
                if easyversion>=6 %easyspin 6.0.0 et ulterieur
                    ytemp=rescaledata(data(rang(k)).spec,y,'lsq');
                else
                   ytemp=rescale(data(rang(k)).spec,y,'lsq0');
                end
               if k>num_definedkolor
                   k2plot=1+mod(k,size(kolor,1));
               else
                   k2plot=k;
               end
               plot(hspecaxes,data(rang(k)).B,ytemp,'color',kolor(k2plot,:));%,'linewidth',2);
               maxy(k)=max(ytemp);
               miny(k)=min(ytemp);
               clear ytemp;
            end
            title(hspecaxes,str2disp);
            rangey=1.1*[min(miny) max(maxy)]; 
            set(hspecaxes,'xlim',[data(rang(1)).B(1) data(rang(1)).B(end)],'Ytick',tickNaN,'ylim',rangey);
            xlabel(hspecaxes,'Magnetic Field [mT]');
            set([get(hpanelnoise,'children');get(hpanelsignal,'children');heditdelay;h2all;hsavekin;...
                hdenoisetype;hnbpts_smoothrank;hrankmoins;hrankplus],'enable','off');
            if ishandle(hcurrent)
                delete(hcurrent)
            end
            hcurrent=plot(seconds([data(rang).time])+tdelay,[data(rang).amp],'ob','MarkerFaceColor','m','parent',hsataxes);
            
        end
        
    else %status=old
        delete([h_linesup,h_lineinf]); %hLF,hHF,hsig

        %lines pour extraction amplitude
        [imins,imaxs]=getindex(data(rang).B,[data(rang).Bsmin data(rang).Bsmax]);
        h_linesup=line([data(rang).B(imins) data(rang).B(imaxs)],data(rang).ysup*[1 1],'color','m','parent',hspecaxes);
        h_lineinf=line([data(rang).B(imins) data(rang).B(imaxs)],data(rang).yinf*[1 1],'color','m','parent',hspecaxes);
        dispsat() %affichage courbe de saturation => cinetique
    end

    
end

function dispsat(~,~) %affichage courbe de saturation => cinetique
    if ishandle(hkincurve)
        delete(hkincurve)
    end
    if ishandle(hcurrent)
        delete(hcurrent)
    end
%     if ishandle(hdiag)
%         delete(hdiag)
%     end
%     if isduration([data.time])
%         hkincurve=plot([data(:).time]+tdelay,[data(:).amp],'ob','parent',hsataxes);hold on
%         
%         xlabel(hsataxes,'Time [s]');
%          % point du spectre courant en rouge
%         rang=get(hlist,'value');
%         hcurrent=plot(data(rang).time+tdelay,data(rang).amp,'ob','MarkerFaceColor','m','parent',hsataxes);
%     else

        timeunitnum=get(htimeunit,'value'); %1:s / 2:min / 3:h
        rang=get(hlist,'value'); % point du spectre courant en rouge
        if timeunitnum==1
            time2plot=seconds([data(:).time])+tdelay;
            timecurrent=seconds(data(rang).time)+tdelay;
        end
        if timeunitnum==2
            time2plot=minutes([data(:).time])+tdelay/60;
            timecurrent=minutes(data(rang).time)+tdelay/60;
        end
        if timeunitnum==3
            time2plot=hours([data(:).time])+tdelay/3600;
            timecurrent=hours(data(rang).time)+tdelay/3600;
        end

        %hkincurve=plot(seconds([data(:).time])+tdelay,[data(:).amp],'ob','parent',hsataxes);hold on
        hkincurve=plot(time2plot,[data(:).amp],'ob','parent',hsataxes);hold on
        xlabel(hsataxes,'Time');
         
        
        hcurrent=plot(timecurrent,data(rang).amp,'ob','MarkerFaceColor','m','parent',hsataxes);
        
%     end
    set(hkincurve,'ButtonDownFcn',@MouseleftclicksatCllbck);
    ylabel(hsataxes,'EPR amplitude [a.u.]');
    title(hsataxes,'Kinetic');  
end

function [imin,imax]=getindex(B,rangeB) %recherche des indices de la plage de champ à considérer 
    i=1;

    while B(i)<rangeB(1)
        i=i+1;
    end
    imin=i;
    while B(i)<rangeB(2)
        i=i+1;
    end
    imax=i;
end

function dispnoiserange(~,~) %callback des edit des plages de champ pour bruit et signal
    if ishandle(hLF)
        delete(hLF)
    end
    if ishandle(hHF)
        delete(hHF)
    end
    if ishandle(hsig)
        delete(hsig)
    end
    if ishandle(h_linesup)
        delete(h_linesup)
    end
    if ishandle(h_lineinf)
        delete(h_lineinf)
    end
    rang=get(hlist,'value');
    data(rang).B1min=str2double(get(hB1min,'string'));%plage de champ pour tenir compte du bruit (bas champ)
    data(rang).B1max=str2double(get(hB1max,'string'));
    [data(rang).imin1,data(rang).imax1]=getindex(data(rang).B,[data(rang).B1min data(rang).B1max]); %indice pour plage bas champ 

    data(rang).B2min=str2double(get(hB2min,'string'));%plage de champ pour tenir compte du bruit (haut champ)
    data(rang).B2max=str2double(get(hB2max,'string'));
    [data(rang).imin2,data(rang).imax2]=getindex(data(rang).B,[data(rang).B2min data(rang).B2max]); %indice pour plage haut champ 
   
    data(rang).Bsmin=str2double(get(hBsmin,'string'));%plage de champ du signal
    data(rang).Bsmax=str2double(get(hBsmax,'string'));
   [data(rang).imins,data(rang).imaxs]=getindex(data(rang).B,[data(rang).Bsmin data(rang).Bsmax]); %indice pour plage du signal 

     %rectangles pour bruit et signal
    hLF=disprect('B1',rang); %noise low field
    hHF=disprect('B2',rang); %noise high field
    hsig=disprect('Bs',rang); %signal

    
    %maj
    data(rang).ysup=posline(data(rang),'sup'); %ordonnee ligne superieure
    data(rang).yinf=posline(data(rang),'inf'); %ordonnee ligne inferieure
    data(rang).amp=data(rang).ysup-data(rang).yinf;
        
    %lines pour extraction amplitude
    [imins,imaxs]=getindex(data(rang).B,[data(rang).Bsmin data(rang).Bsmax]);
    h_linesup=line([data(rang).B(imins) data(rang).B(imaxs)],data(rang).ysup*[1 1],'color','m','parent',hspecaxes);
    h_lineinf=line([data(rang).B(imins) data(rang).B(imaxs)],data(rang).yinf*[1 1],'color','m','parent',hspecaxes);
    % maj sliders
    set(hslidsup,'value',data(rang).ysup);
    set(hslidinf,'value',data(rang).yinf);
    
    
    dispsat() %affichage courbe de saturation => cinetique
end


function setdenoisingcontrol()
    if denoisingvalue==1 %none
           set([hinfodenoising,hnbpts_smoothrank,hrankmoins,hrankplus],'visible','off');
    else
        switch denoisingvalue
        case 2 %smooth
            if isempty(nbptsmooth)
                num2disp=defaultnbptslissage;
                nbptsmooth=num2disp;
            else
                num2disp=nbptsmooth;
            end
            %set(hsliddenoise,'Max',maxpoints,'SliderStep',1/(maxpoints-1)*[1 1]);
        case 3 %SVD
            if isempty(rankSVD)
                num2disp=defaultrank4SVD;
                rankSVD=num2disp;
            else
                num2disp=rankSVD;
            end
            %set(hsliddenoise,'Max',maxrank,'SliderStep',1/(maxrank-1)*[1 1]);
        end
        set(hinfodenoising,'visible','on','tooltipstring',tooltip_str_denoise{denoisingvalue},'string',str_info_denoise{denoisingvalue});
        set(hnbpts_smoothrank,'visible','on','tooltipstring',tooltip_str_denoise{denoisingvalue},'string',num2str(num2disp));  
        set([hrankmoins hrankplus],'visible','on');
    end
end

% function slidnum(hobject,~) %slider pour incrementer nb de point lissage/rank SVD
%         if denoisingvalue==2 %
%             nbptsmooth=get(hobject,'value');
%             tempstr=num2str(nbptsmooth);
%         elseif denoisingvalue==3 %SVD
%             rankSVD=get(hobject,'value');
%             tempstr=num2str(rankSVD);
%         end
%         set(hnbpts_smoothrank,'string',tempstr);
%         denoisedata;
% end

function changerank(~,~,inc_or_dec) % inc_or_dec=+1 ou -1
        if denoisingvalue==2 %
            nbptsmoothprev=str2double(get(hnbpts_smoothrank,'string'));
            nbptsmoothnext=nbptsmoothprev+inc_or_dec;
            if nbptsmoothnext>=1 && nbptsmoothnext<=50
                nbptsmooth=nbptsmoothnext;
            else
                nbptsmooth=nbptsmoothprev;
            end
            tempstr=num2str(nbptsmooth);

        elseif denoisingvalue==3 %SVD
            rankSVDprev=str2double(get(hnbpts_smoothrank,'string'));
            rankSVDnext=rankSVDprev+inc_or_dec;
            if rankSVDnext>=1 && rankSVDnext<=50
                rankSVD=rankSVDnext;
            else
                rankSVD=rankSVDprev;
            end
            tempstr=num2str(rankSVD);
        end
        set(hnbpts_smoothrank,'string',tempstr);
        denoisedata;





    % set(hstoredeltaB,'enable','on');
    % deltaB=str2double(get(hdeltaBval,'string'))+inc_or_dec*0.01;
    % set(hdeltaBval,'string',num2str(deltaB,'%3.2f'));
    % set(hfitindicator,'visible','off'); 
    % if ishandle(hpoint) %point + ligne verticale + info
    %     xp=get(hpoint,'xdata')+deltaB+Bexpinit(1)-Bexp(1); %abscisse du point + increment de decalage
    %     yp=get(hpoint,'ydata'); %ordonnee du point
    %     set(hpoint,'xdata',xp);
    %     set(hvert,'xdata',[xp xp]);
    %     str2disp=[num2str(xp,'%3.2f'),'mT, ',num2str(yp,'%3.3f'),', g=',num2str(planck*expfreq*1e9/bmagn/xp*1e3,'%5.4f')];
    %     set(hcursorinfo,'string',str2disp);
    % end
    %     plotspecexp(deltaB);
end


function editnum(hobject,~)
       if denoisingvalue==2 %
            nbptsmooth=str2double(get(hobject,'string'));
            tempnum=nbptsmooth;
        elseif denoisingvalue==3 %SVD
            rankSVD=str2double(get(hobject,'string'));
            tempnum=rankSVD;
        end
        %set(hsliddenoise,'value',tempnum);
        denoisedata;

end

function h=disprect(fieldB,rang) %affichage des rectangles pour visu des plages
    [imin,imax]=getindex(data(rang).B,[data(rang).([fieldB,'min']) data(rang).([fieldB,'max'])]);
    if imin==imax
        amp=max(data(rang).spec)-min(data(rang).spec);
        pos=[data(rang).([fieldB,'min']) -amp/10 0.01 amp/5];
    else
        amp=max(data(rang).spec(imin:imax))-min(data(rang).spec(imin:imax));
        pos=[data(rang).([fieldB,'min']) min(data(rang).spec(imin:imax))...
             data(rang).([fieldB,'max'])-data(rang).([fieldB,'min'])...
             amp];
    end
    switch fieldB
        case 'B1'
            color='b';
        case 'B2'
            color='b';
        case 'Bs'
            color=[0 0.7 0];
            graphe_lim=get(hspecaxes,'Ylim');
            pos([2 4])= [0.95*graphe_lim(1) 0.95*(graphe_lim(2)-graphe_lim(1))];
        
    end
    
    h=rectangle('parent',hspecaxes,'position',pos,'Edgecolor',color);
end

function y=posline(datatemp,arg) %ordonnee de  line arg='sup' ou 'inf'
        amp_bruit1=NaN; %amplitude bruit bas champ
        std1=NaN; %deviation standard bruit bas champ
        amp_bruit2=NaN; %amplitude bruit haut champ
        std2=NaN; %deviation standard bruit haut champ
        if datatemp.B1min~=datatemp.B1max %noise a bas champ
            maxbruit1=max(datatemp.spec(datatemp.imin1:datatemp.imax1));
            minbruit1=min(datatemp.spec(datatemp.imin1:datatemp.imax1));
            amp_bruit1=maxbruit1-minbruit1;
            std1=std(datatemp.spec(datatemp.imin1:datatemp.imax1));
        end
        if datatemp.B2min~=datatemp.B2max %noise a haut champ
            maxbruit2=max(datatemp.spec(datatemp.imin2:datatemp.imax2));
            minbruit2=min(datatemp.spec(datatemp.imin2:datatemp.imax2));
            amp_bruit2=maxbruit2-minbruit2;
            std2=std(datatemp.spec(datatemp.imin2:datatemp.imax2));
        end
        if ishandle(hlinetype)
            linetypeval=get(hlinetype,'value');
        else 
            linetypeval=1; %par defaut derivative line
        end
        switch arg
            case 'sup' %ordonnee superieur
                if linetypeval==3 %raie negative
                    y=0;
                else
                    maxspec=max(datatemp.spec(datatemp.imins:datatemp.imaxs));
                    % amplitude moyenne bruit
                    amp_bruit_all=[amp_bruit1 amp_bruit2];
                    amp_bruit_all(isnan(amp_bruit_all))=[]; %supprime les NaN
                    amp_bruit=mean(amp_bruit_all); %NaN si isempty(amp_bruit)
                    if isnan(amp_bruit) 
                        amp_bruit=0;
                    end
                    % deviation standard moyenne bruit
                    std_bruit_all=[std1 std2];
                    std_bruit_all(isnan(std_bruit_all))=[]; %supprime les NaN
                    std_bruit=mean(std_bruit_all); %NaN si isempty(std_bruit)
                    if isnan(std_bruit)
                        std_bruit=0;
                    end
                     y=maxspec-mean([amp_bruit/2 std_bruit]);
                end
                
            case 'inf' %ordonnee inferieur
                if linetypeval==2 %raie positive
                    y=0;
                else
                    minspec=min(datatemp.spec(datatemp.imins:datatemp.imaxs));
                    % amplitude moyenne bruit
                    amp_bruit_all=[amp_bruit1 amp_bruit2];
                    amp_bruit_all(isnan(amp_bruit_all))=[]; %supprime les NaN
                    amp_bruit=mean(amp_bruit_all); %NaN si isempty(amp_bruit)
                    if isnan(amp_bruit) 
                        amp_bruit=0;
                    end
                    % deviation standard moyenne bruit
                    std_bruit_all=[std1 std2];
                    std_bruit_all(isnan(std_bruit_all))=[]; %supprime les NaN
                    std_bruit=mean(std_bruit_all); %NaN si isempty(std_bruit)
                    if isnan(std_bruit)
                        std_bruit=0;
                    end
                     y=minspec+mean([amp_bruit/2 std_bruit]);
               
                end
                
        end
                
end

function slidsup(hObject,~)
    rang=get(hlist,'value');
    data(rang).ysup=get(hObject,'value');
    data(rang).amp=abs(data(rang).ysup-data(rang).yinf);
    dispexp(hlist,[],'old')
end

function slidinf(hObject,~)
    rang=get(hlist,'value');
    data(rang).yinf=get(hObject,'value');
    data(rang).amp=abs(data(rang).ysup-data(rang).yinf);
    dispexp(hlist,[],'old')
end

% function slidalpha(~,~)
%     alpha2=get(hslidalpha,'value');
%     dispsat()
% end

function sent(~,~,type)
    rang=get(hlist,'value');
    if strcmp(type,'all')
        first=1;last=nbspec;
    elseif strcmp(type,'prev')
        first=1;last=rang;
    else %'next'
        first=rang;last=nbspec;
    end
    
    for n=first:last
        data(n).B1min=data(rang).B1min;%plage de champ pour tenir compte du bruit (bas champ)
        data(n).B1max=data(rang).B1max;
        data(n).imin1=data(rang).imin1;
        data(n).imax1=data(rang).imax1; %indice pour plage bas champ 

        data(n).B2min=data(rang).B2min;%plage de champ pour tenir compte du bruit (haut champ)
        data(n).B2max=data(rang).B2max;
        data(n).imin2=data(rang).imin2;
        data(n).imax2=data(rang).imax2; %indice pour plage haut champ 

        data(n).Bsmin=data(rang).Bsmin;%plage de champ du signal
        data(n).Bsmax=data(rang).Bsmax;
        data(n).imins=data(rang).imins;
        data(n).imaxs=data(rang).imaxs; %indice pour plage du signal 

        data(n).ysup=posline(data(n),'sup'); %ordonnee ligne superieure
        data(n).yinf=posline(data(n),'inf'); %ordonnee ligne inferieure
        data(n).amp=data(n).ysup-data(n).yinf;
        %data(n).linetypeval=data(rang).linetypeval;
    end
    
    %dispsat()
    dispexp(hlist,[],'old')
end

function denoisedatalaunch(hobject,~)
    denoisingvalue=get(hobject,'value'); %denoisetype={'None';'Smooth';'SVD'};
    
    if denoisingvalue==3 %SVD
           uiwait(msgbox({'You are about to denoise with Single Value Decomposition.';...
               'Using SVD with nested signals result in wrong signals.';...
               'If signal shape depends on the rank, SVD should not be used.'},...
         'Kinetic_SVD_WARNING','Warn','modal'));
        if isempty(SVDstruct) %SVD a calculer
                [SVDstruct.U,SVDstruct.S,SVDstruct.V]=svd([data.spec],0);
                if size(SVDstruct.S,1)<maxrank
                    maxrank=size(SVDstruct.S,1);
                end
                for r=1:maxrank
                    Ur=SVDstruct.U(:,1:r);            % réduit la taille de U aux r premières colonnes
                    Sr=SVDstruct.S(1:r,1:r);         % réduit la taille de S a une matrice carrée de taille r
                    Vr=SVDstruct.V(:,1:r);            % réduit la taille de V aux r premières colonnes
                    SVDstruct.ydenoise{r}=Ur*Sr*Vr';       % calcule la matrice débruitée
                    clear Ur Sr Vr;
                end
        end
        
        if ~ishandle(hfiglogdiagS)
              plotlogdiagS
        end

                    
    elseif ishandle(hfiglogdiagS)
        close(hfiglogdiagS)
    end
    setdenoisingcontrol;
    denoisedata;
end

function denoisedata()
    switch denoisingvalue
        case 1 %none
            for n=1:nbspec
               if isfield(data,'specbrut2')
                 data(n).spec=data(n).specbrut2;
               elseif isfield(data,'specbrut3')
                   data(n).spec=data(n).specbrut3;
               end
                data(n).ysup=posline(data(n),'sup'); %ordonnee ligne superieure
                data(n).yinf=posline(data(n),'inf'); %ordonnee ligne inferieure
                data(n).amp=data(n).ysup-data(n).yinf;
            end

            if isfield(data,'specbrut2')
                 data=rmfield(data,'specbrut2');
            elseif isfield(data,'specbrut3')
                 data=rmfield(data,'specbrut3');
            end
           
            dispexp(hlist,[],'new')
            
        case 2 %smooth
            if isfield(data,'specbrut3') 
                for n=1:nbspec
                    data(n).spec=data(n).specbrut3;
                    data(n).ysup=posline(data(n),'sup'); %ordonnee ligne superieure
                    data(n).yinf=posline(data(n),'inf'); %ordonnee ligne inferieure
                    data(n).amp=data(n).ysup-data(n).yinf;
                end
                data=rmfield(data,'specbrut3');
            end
            if isfield(data,'specbrut2') %lissage precedent?
                previouslissage=1;
            else
                previouslissage=0;
            end
            for n=1:nbspec
                if ~previouslissage %pas de lissage precedent
                    data(n).specbrut2=data(n).spec;
                end
                data(n).spec=datasmooth(data(n).specbrut2,floor(nbptsmooth),'savgol',2);
                data(n).ysup=posline(data(n),'sup'); %ordonnee ligne superieure
                data(n).yinf=posline(data(n),'inf'); %ordonnee ligne inferieure
                data(n).amp=data(n).ysup-data(n).yinf;
            end
            %set(hnbpts_smooth,'enable','on')
            dispexp(hlist,[],'new')
        
        case 3 %SVD
            if isfield(data,'specbrut2') 
                for n=1:nbspec
                    data(n).spec=data(n).specbrut2;
                    data(n).ysup=posline(data(n),'sup'); %ordonnee ligne superieure
                    data(n).yinf=posline(data(n),'inf'); %ordonnee ligne inferieure
                    data(n).amp=data(n).ysup-data(n).yinf;
                end
                data=rmfield(data,'specbrut2');
            end
            if isfield(data,'specbrut3') %SVD precedente?
                previousSVD=1;
            else
                previousSVD=0;
            end
            for n=1:nbspec
                if ~previousSVD %pas de lissage precedent
                    data(n).specbrut3=data(n).spec;
                end
                
                data(n).spec=SVDstruct.ydenoise{1,rankSVD}(:,n);
                data(n).ysup=posline(data(n),'sup'); %ordonnee ligne superieure
                data(n).yinf=posline(data(n),'inf'); %ordonnee ligne inferieure
                data(n).amp=data(n).ysup-data(n).yinf;
            end
            %set(hnbpts_smooth,'enable','on')
            dispexp(hlist,[],'new')
            if ~ishandle(hfiglogdiagS)
              plotlogdiagS
            end
            if ishandle(hcurrentlogdiagS) 
                delete(hcurrentlogdiagS);
            end
            figure(hfiglogdiagS);
            hcurrentlogdiagS=plot(rankSVD,log(SVDstruct.S(rankSVD,rankSVD)),'ob','markerfacecolor',[51 153 255]/255);
            figure(hsatmain);
    end
    
    
end

function plotlogdiagS 
        % spectre i nul <=> log(diag(S)(i,i)<0
        %SVDstruct
        logdiagS=log(diag(SVDstruct.S));
        logdiagS2plot=logdiagS(logdiagS>0);
        dimS=numel(logdiagS2plot);
        if dimS<maxrank
           maxrank=dimS; 
        end
        hfiglogdiagS=figure();
        set(hfiglogdiagS,'Name','kinetic_SVD','NumberTitle','off','Units','pixels',...
            'Outerposition',[scrszpix(3)/4 0.1*scrszpix(4) 410 360],'Menubar', 'none', 'Toolbar', 'figure')
        plot(logdiagS2plot,'ob');hold on  % trace le graphique log(Si,i)=f(i)
        title('log(Si,i)=f(i) (>0)');   % affiche le titre du graphe
        xlabel('rank')
%         %%%% pour ne garder que les outils zoomin, zoomout et main
%         hToolbar2 = findall(hfiglogdiagS,'tag','FigureToolBar'); %handle toolbar
%         halltoolbar2=allchild(hToolbar2);%tous les handles de la toolbar
%         hzoomin2=findall(halltoolbar2,'TooltipString','Zoom In');
%         hzoomout2=findall(halltoolbar2,'TooltipString','Zoom Out');
%         hhand2=findall(halltoolbar2,'TooltipString','Pan');
%         halltoolbar2(halltoolbar2==hzoomin2)=[];%supprime 1 handle a conserver
%         halltoolbar2(halltoolbar2==hzoomout2)=[];%supprime 1 handle a conserver
%         halltoolbar2(halltoolbar2==hhand2)=[];%supprime 1 handle a conserver
%         set(halltoolbar2,'visible','off')

end
% function lissage(hobject,~)
%     chkstatus=get(hobject,'value');
%     
%     if chkstatus %case cochee
%         if isfield(data,'specbrut') %lissage precedent?
%             previouslissage=1;
%         else
%             previouslissage=0;
%         end
%         for n=1:nbspec
%             if ~previouslissage %pas de lissage precedent
%                 data(n).specbrut=data(n).spec;
%             end
%             nbptsmooth=get(hnbpts_smooth,'string');
%             data(n).spec=datasmooth(data(n).specbrut,str2double(nbptsmooth),'savgol',2);
%             data(n).ysup=posline(data(n),'sup'); %ordonnee ligne superieure
%             data(n).yinf=posline(data(n),'inf'); %ordonnee ligne inferieure
%             data(n).amp=data(n).ysup-data(n).yinf;
%         end
%         set(hnbpts_smooth,'enable','on')
%         dispexp(hlist,[],'new')
%     else %case decochee
%         for n=1:nbspec
%             data(n).spec=data(n).specbrut;
%             data(n).ysup=posline(data(n),'sup'); %ordonnee ligne superieure
%             data(n).yinf=posline(data(n),'inf'); %ordonnee ligne inferieure
%             data(n).amp=data(n).ysup-data(n).yinf;
%         end
%         nbptsmooth=[];
%         data=rmfield(data,'specbrut');
%         set(hnbpts_smooth,'enable','inactive')
%         dispexp(hlist,[],'new')
%     end
% 
% end

% function nbpts_lissage (hobject,~) %nb de point pour moyenne glissante
%     nbptslissage=str2double(get(hobject,'string'));
%     if isnumeric(nbptslissage)
%         set(hobject,'string',num2str(floor(nbptslissage)));
%     else
%         set(hobject,'string',num2str(defaultnbptslissage));
%     end
%     lissage(hchk_smooth);
% end

function savesat(~,~)
    %%% sauvegarde fichier txt
    [fnametxt,path2save]=uiputfile(fullfile(chemin,'*.txt'));
    if ~(isnumeric(fnametxt)) %no cancel
        fid=fopen(fullfile(path2save,fnametxt),'w');
        if isfield(data,'timenum') %from 1D
            fprintf(fid,'%22s\t','Rec. time');
        end
        fprintf(fid,'%12s\t','time');
        fprintf(fid,'%12s\t','time');
        fprintf(fid,'%12s\t','Amplitude');
        fprintf(fid,'%12s\n','File name');
        if isfield(data,'timenum') %from 1D
            fprintf(fid,'%22s\t','[ date  hh:mm:ss]');
        end
        time2disp=char(data(end).time+seconds(tdelay));
        nb22points=numel(strfind(time2disp,':'));
        if nb22points==2 % hh:mm:ss
            fprintf(fid,'%12s\t','[hh:mm:ss]');
        else
            fprintf(fid,'%12s\t','[dd:hh:mm:ss]');
        end
        
        fprintf(fid,'%12s\t','[s]');
        fprintf(fid,'%12s\t','[ ]');
        fprintf(fid,'%12s\n','[ ]');
        for i=1:nbspec
            taillename(i)=numel(data(i).name);
        end
        maxname=max(taillename);
        for i=1:nbspec
            if isfield(data,'timenum') %from 1D
                fprintf(fid,'%22s\t',char(data(i).timenum));%tempsh)); %heure d'enregistrement
            end
            fprintf(fid,'%12s\t',char(data(i).time+seconds(tdelay))); %t+t0
            fprintf(fid,'%12.0f\t',seconds(data(i).time)+tdelay); %t+t0 en s
            fprintf(fid,'%12.5e\t',data(i).amp);
            fprintf(fid,['%',num2str(maxname),'s\n'],data(i).name);
        end
        fclose(fid);

        % save plot
        figure2save=figure();%max(findobj('type','figure'))+1); %pour ne pas superposer des figures 
        set(figure2save,'Units','pixels','Name','Kinetic','NumberTitle','on','visible','on',...
                'Position',[300 300 400 400],'Menubar', 'figure','Toolbar', 'figure');
        hnew=copyobj(hsataxes,figure2save);%graphe(=axes)+legend copier dans nouvelle figure
        set(hnew,'units','normalized','position',[0.15 0.12 0.8 0.8])%,...
        title(hnew,['Kinetic: ',fnametxt(1:end-4)],'interpreter','none');

        timeunitnum=get(htimeunit,'value'); %1:s / 2:min / 3:h
        if timeunitnum==1
            xlabel('Time [s]');
        end
        if timeunitnum==2
           xlabel('Time [min]');
        end
        if timeunitnum==3
          xlabel('Time [h]');
        end

        set(findobj(hnew,'MarkerFaceColor','m'),'MarkerFaceColor','none');
        set(figure2save,'visible','on');
        saveas(figure2save,fullfile(path2save,[fnametxt(1:end-3),'tif']));
        saveas(figure2save,fullfile(path2save,[fnametxt(1:end-3),'fig']));
        delete(figure2save);

        %save data
%         if get(hchk_smooth,'value') %lissage
%             save(fullfile(path2save,[fnametxt(1:end-3),'mat']),'data','tdelay','nbptsmooth');
%         else
         

         save(fullfile(path2save,[fnametxt(1:end-3),'mat']),'data','tdelay','denoisingvalue','linetypeval');
          if denoisingvalue==2
              save(fullfile(path2save,[fnametxt(1:end-3),'mat']),'nbptsmooth','-append');
          end
          if denoisingvalue==3
              save(fullfile(path2save,[fnametxt(1:end-3),'mat']),'SVDstruct','rankSVD','-append');
          end
            
%         end
    end
end

function considerdelay(hObject,~)
     t0=str2double(get(hObject,'string'));  
     if ~isnan(t0)
         tdelay=t0;
     else
         set(hObject,'string',num2str(tdelay))
     end   
     dispexp(hlist,[],'old')
end

function setlinetype(~,~)
      for n=1:nbspec
          data(n).ysup=posline(data(n),'sup'); %ordonnee ligne superieure
          data(n).yinf=posline(data(n),'inf'); %ordonnee ligne inferieure
          data(n).amp=data(n).ysup-data(n).yinf;
      end
      dispexp(hlist,[],'old')
      linetypeval=get(hlinetype,'value');
      

end


function plus_or_minus_fctn(~,~,strsign) %strsign='+' ou '-'
    rang=get(hlist,'value');
   switch strsign
       case '+'
           if rang~=nbspec
               rang=rang+1;
           end         
           
       case '-'
           if rang~=1
               rang=rang-1;
           end   
   end
   set(hlist,'value',rang);
   dispexp(hlist,[],'new')    

end
function closekinetic(~,~)
    delete(hsatmain);
    if ishandle(hfiglogdiagS)
        delete(hfiglogdiagS);
    end
end 

function MouseleftclicksatCllbck(~,~)
    delete(hcurrent)
    p = get(hsataxes,'CurrentPoint');
    p = p(1,1:2);
    
    timeunitnum=get(htimeunit,'value'); %1:s / 2:min / 3:h
    if timeunitnum==1
        time2search=abs((seconds([data.time])+tdelay-p(1))./(seconds([data.time])+tdelay));
    end
    if timeunitnum==2
       time2search=abs((minutes([data.time])+tdelay/60-p(1))./(minutes([data.time])+tdelay/60));
    end
    if timeunitnum==3
       time2search=abs((hours([data.time])+tdelay/3600-p(1))./(hours([data.time])+tdelay/3600));
    end
    
    
    minsearch=[time2search;abs(([data.amp]-p(2))./[data.amp])];
    [~,rang]=min(sum(minsearch,1));%min(abs([data.time]+tdelay-p(1)));%recherche du rang avec valeur de temps la plus proche
   
    if timeunitnum==1
        tcurrent=seconds(data(rang).time)+tdelay;
    end
    if timeunitnum==2
        tcurrent=minutes(data(rang).time)+tdelay/60;
    end
    if timeunitnum==3
        tcurrent=hours(data(rang).time)+tdelay/3600;
    end
    
    
    hcurrent=plot(tcurrent,data(rang).amp,'ob','MarkerFaceColor','m','parent',hsataxes);
    set(hlist,'value',rang);
    dispexp(hlist,[],'new');
    
    %
end

end