function [] = settings2txt(settings, obs, input, rec_pco, rec_pcv, tStart)

% Function to write the processing settings from raPPPid (VieVS PPP) into a 
% settings.txt-file to be able to check them easily. Function is called 
% after the epoch-wise processing is finished 
%  
% INPUT:  
%   settings    struct, processing settings from GUI
%   obs         struct, information about observations
%   input       struct, contains input data
%   rec_pco     string, missing receiver PCO corrections in ANTEX
%   rec_pcv     string, missing receiver PCV corrections in ANTEX
%   tStart      uint64, start time of processing from Matlab tic
% OUTPUT:
%   settings.txt is written to results folder
% 
% Revision:
%   2024/12/16, MFWG: improved the printing of the version
%
% This function belongs to raPPPid, Copyright (c) 2023, M.F. Glaner
% *************************************************************************


% get the name of the file
fileID = fopen([settings.PROC.output_dir,'/', 'settings_summary.txt'], 'w');

% check if decoupled clock model was used during processing
bool_DCM = strcmp(settings.IONO.model, 'Estimate, decoupled clock');


%% File - Set input file

fprintf(fileID,'%s\n','Input Data:');

fprintf(fileID,'  %s%s\n','Obs-File: ', settings.INPUT.file_obs);
if ~settings.KINE.satellite.bool
    fprintf(fileID,'  %s%.3f%s%.3f%s%.3f\n','Approx Pos [m]: ',settings.INPUT.pos_approx(1),' | ',settings.INPUT.pos_approx(2),' | ',settings.INPUT.pos_approx(3));
end
fprintf(fileID,'  %s%s\n','Coordinate System: ', obs.coordsyst);
if settings.INPUT.bool_realtime
    fprintf(fileID,'  %s\n', ['Real-Time processing from ' settings.INPUT.realtime_start_GUI ' to ' settings.INPUT.realtime_ende_GUI]);
end
if settings.KINE.bool_kinematic
    fprintf(fileID,'  %s\n', 'Kinematic processing');
end
fprintf(fileID,'\n');



%% Selected Signals
switch settings.PROC.method
    case 'Code Only'
        fprintf(fileID,'%s\n\n','Processing Method: Code Only');
    case 'Code + Doppler'
        fprintf(fileID,'%s\n\n','Processing Method: Code + Doppler');
    case 'Code + Phase'
        fprintf(fileID,'%s\n\n','Processing Method: Phase + Code');
    case 'Code (Doppler Smoothing)'
        fprintf(fileID,'%s\n\n','Processing Method: Code (Doppler Smoothing)');
    otherwise
        fprintf(fileID,'%s\n\n','Processing Method: Error');
end
if settings.INPUT.use_GPS
    fprintf(fileID,'%s\n','Selected GPS Signals:');
    fprintf(fileID,'  Code:     %s, %s, %s\n', obs.GPS.C1,obs.GPS.C2,obs.GPS.C3);
    fprintf(fileID,'  Phase:    %s, %s, %s\n', obs.GPS.L1,obs.GPS.L2,obs.GPS.L3);
    fprintf(fileID,'  Strength: %s, %s, %s\n', obs.GPS.S1,obs.GPS.S2,obs.GPS.S3);
    fprintf(fileID,'  Doppler:  %s, %s, %s\n', obs.GPS.D1,obs.GPS.D2,obs.GPS.D3);
end
if settings.INPUT.use_GLO
    fprintf(fileID,'%s\n','Selected Glonass Signals:');
    fprintf(fileID,'  Code:     %s, %s, %s\n', obs.GLO.C1,obs.GLO.C2,obs.GLO.C3);
    fprintf(fileID,'  Phase:    %s, %s, %s\n', obs.GLO.L1,obs.GLO.L2,obs.GLO.L3);
    fprintf(fileID,'  Strength: %s, %s, %s\n', obs.GLO.S1,obs.GLO.S2,obs.GLO.S3);
    fprintf(fileID,'  Doppler:  %s, %s, %s\n', obs.GLO.D1,obs.GLO.D2,obs.GLO.D3);
end
if settings.INPUT.use_GAL
    fprintf(fileID,'%s\n','Selected Galileo Signals:');    
    fprintf(fileID,'  Code:     %s, %s, %s\n', obs.GAL.C1,obs.GAL.C2,obs.GAL.C3);
    fprintf(fileID,'  Phase:    %s, %s, %s\n', obs.GAL.L1,obs.GAL.L2,obs.GAL.L3);
    fprintf(fileID,'  Strength: %s, %s, %s\n', obs.GAL.S1,obs.GAL.S2,obs.GAL.S3);
    fprintf(fileID,'  Doppler:  %s, %s, %s\n', obs.GAL.D1,obs.GAL.D2,obs.GAL.D3);
end
if settings.INPUT.use_BDS
    fprintf(fileID,'%s\n','Selected BeiDou Signals:');    
    fprintf(fileID,'  Code:     %s, %s, %s\n', obs.BDS.C1,obs.BDS.C2,obs.BDS.C3);
    fprintf(fileID,'  Phase:    %s, %s, %s\n', obs.BDS.L1,obs.BDS.L2,obs.BDS.L3);
    fprintf(fileID,'  Strength: %s, %s, %s\n', obs.BDS.S1,obs.BDS.S2,obs.BDS.S3);
    fprintf(fileID,'  Doppler:  %s, %s, %s\n', obs.BDS.D1,obs.BDS.D2,obs.BDS.D3);
end
if settings.INPUT.use_QZSS
    fprintf(fileID,'%s\n','Selected QZSS Signals:');    
    fprintf(fileID,'  Code:     %s, %s, %s\n', obs.QZSS.C1,obs.QZSS.C2,obs.QZSS.C3);
    fprintf(fileID,'  Phase:    %s, %s, %s\n', obs.QZSS.L1,obs.QZSS.L2,obs.QZSS.L3);
    fprintf(fileID,'  Strength: %s, %s, %s\n', obs.QZSS.S1,obs.QZSS.S2,obs.QZSS.S3);
    fprintf(fileID,'  Doppler:  %s, %s, %s\n', obs.QZSS.D1,obs.QZSS.D2,obs.QZSS.D3);
end


%% Models - Orbit/Clock data

fprintf(fileID,'%s\n\n','Orbit/Clock Data:');
if settings.ORBCLK.bool_precise
    
    fprintf(fileID,'  %s\n','Precise products:');
    fprintf(fileID,'    %s%s%s\n',settings.ORBCLK.prec_prod,':   ',settings.ORBCLK.file_sp3);
    fprintf(fileID,'    %s%s%s\n',settings.ORBCLK.prec_prod,':   ',settings.ORBCLK.file_clk);
    if settings.ORBCLK.bool_obx
        fprintf(fileID,'    %s%s%s\n',settings.ORBCLK.prec_prod,':   ',settings.ORBCLK.file_obx);
    else
        fprintf(fileID,'    %s\n','No ORBEX File');
    end    
    
else
    
    fprintf(fileID,'  %s\n','Broadcast products + Correction stream');
    if settings.ORBCLK.bool_nav_multi
        fprintf(fileID,'    %s%s%s%s\n','Multi-GNSS Navigation file: ',settings.ORBCLK.multi_nav,':   ',settings.ORBCLK.file_nav_multi);
    end
    if settings.ORBCLK.bool_nav_single
        fprintf(fileID,'    %s%s\n','GPS Navigation file: ',settings.ORBCLK.file_nav_GPS);
        fprintf(fileID,'    %s%s\n','GLONASS Navigation file: ',settings.ORBCLK.file_nav_GLO);
        fprintf(fileID,'    %s%s\n','Galileo Navigation file: ',settings.ORBCLK.file_nav_GAL);
    end
    
    if ~strcmpi(settings.ORBCLK.CorrectionStream,'off')
        fprintf(fileID,'    %s%s%s%s\n','Correction stream file: ',settings.ORBCLK.CorrectionStream,':   ',settings.ORBCLK.file_corr2brdc);
        fprintf(fileID,'    %s%s\n','Correction stream reference point: ', char(settings.ORBCLK.CorrectionStream_APC * 'APC' + settings.ORBCLK.CorrectionStream_COM * 'COM'));
        fprintf(fileID,'    %s%.0f%s%.0f%s%.0f%s\n','Corrections age limit [s]: ', settings.ORBCLK.CorrectionStream_age(1), ', ', settings.ORBCLK.CorrectionStream_age(2), ', ', settings.ORBCLK.CorrectionStream_age(3), ' (orbit, clock, biases)');
    else
        fprintf(fileID,'    %s\n','No correction stream file');
    end
    
end
fprintf(fileID,'\n');



%% Models - Biases

fprintf(fileID,'%s\n','Biases:');

switch settings.BIASES.code
    case 'CODE DCBs (P1P2, P1C1, P2C2)'
        fprintf(fileID,'    %s\n', settings.BIASES.code);
        fprintf(fileID,'%s%s\n','    P1P2: ', settings.BIASES.code_file{1});
        fprintf(fileID,'%s%s\n','    P1C1: ', settings.BIASES.code_file{2});
    case 'Correction Stream'
        fprintf(fileID,'%s\n','    Code biases from correction stream are applied');
    case 'manually'
        if settings.BIASES.code_manually_Sinex_bool
            fprintf(fileID,'    %s%s\n','manually, Sinex-Bias-File: ', settings.BIASES.code_file);
        elseif settings.BIASES.code_manually_DCBs_bool
            fprintf(fileID,'    %s\n', 'CODE DCBs manually');
            fprintf(fileID,'    %s%s\n','P1P2: ', settings.BIASES.code_file{1});
            fprintf(fileID,'    %s%s\n','P1C1: ', settings.BIASES.code_file{2});
            fprintf(fileID,'    %s%s\n','P2C2: ', settings.BIASES.code_file{3});
        end
    case 'off'
        fprintf(fileID,'    %s\n','no');
    case 'Broadcasted TGD'
        fprintf(fileID,'    %s\n','Broadcasted Time Group Delay');
    otherwise 
        fprintf(fileID,'    %s%s%s\n', settings.BIASES.code, ': ', settings.BIASES.code_file);
end
% Estimation of receiver DCBs
if settings.BIASES.estimate_rec_dcbs
    fprintf(fileID,'    %s\n','Receiver Bias Estimation is enabled');
end

% Phase Biases
if ~strcmp(settings.BIASES.phase, 'off')
    fprintf(fileID,'%s\n','Phase Biases:');
    switch settings.BIASES.phase
        case 'TUW (not implemented)'
            fprintf(fileID,'%s%s\n','  TUW-WL-File: ', settings.BIASES.phase_file{1});
            fprintf(fileID,'%s%s\n','  TUW-NL-File: ', settings.BIASES.phase_file{2});
        case {'WHU phase/clock biases', 'SGG FCBs'}
            fprintf(fileID,'  %s: %s\n',settings.BIASES.phase, settings.BIASES.phase_file);
        case {'NRCAN (not implemented)', 'manually (not implemented)'}
            fprintf(fileID,'  %s\n', settings.BIASES.phase);
        case 'Correction Stream'
            fprintf(fileID,'  %s\n','Phase biases from correction stream are applied');
        case 'off'
            fprintf(fileID,'  %s\n','no');
    end
end

fprintf(fileID,'\n');



%% Models - Troposphere

fprintf(fileID,'%s\n', 'Troposphere:');
fprintf(fileID,'  %s%s %s\n','zhd: ', settings.TROPO.zhd, detectGridSiteWise(settings.TROPO.zhd, input, settings.TROPO.vmf_version));
if strcmpi(settings.TROPO.zhd,'p (in situ) + Saastamoinen')
    fprintf(fileID,'    %s%7.2f%s\n','p: ', settings.TROPO.p,' hPa');
elseif strcmpi(settings.TROPO.zhd,'Tropo file') && strcmpi(settings.TROPO.tropo_file,'manually')
    fprintf(fileID,'    %s: %s\n', 'manually', settings.TROPO.tropo_filepath);
end
fprintf(fileID,'  %s%s %s\n','zwd: ', settings.TROPO.zwd, detectGridSiteWise(settings.TROPO.zwd, input, settings.TROPO.vmf_version));
if strcmpi(settings.TROPO.zwd,'e (in situ) + Askne')
    fprintf(fileID,'    %s%5.2f%s\n','q: ', settings.TROPO.q,' %');
    fprintf(fileID,'    %s%6.2f%s\n','T: ', settings.TROPO.T,' °C');
elseif strcmpi(settings.TROPO.zwd,'Tropo file') && strcmpi(settings.TROPO.tropo_file,'manually')
    fprintf(fileID,'    %s: %s\n', 'manually', settings.TROPO.tropo_filepath);    
end
fprintf(fileID,'  %s%s %s\n','mfh: ', settings.TROPO.mfh, detectGridSiteWise(settings.TROPO.mfh, input, settings.TROPO.vmf_version));
fprintf(fileID,'  %s%s %s\n','mfw: ', settings.TROPO.mfw, detectGridSiteWise(settings.TROPO.mfw, input, settings.TROPO.vmf_version));
fprintf(fileID,'  %s%s %s\n','Gn_h & Ge_h: ', settings.TROPO.Gh, detectGridSiteWise(settings.TROPO.Gh, input, settings.TROPO.vmf_version));
fprintf(fileID,'  %s%s %s\n','Gn_w & Ge_w: ', settings.TROPO.Gw, detectGridSiteWise(settings.TROPO.Gw, input, settings.TROPO.vmf_version));
if settings.TROPO.estimate_ZWD
    if settings.TROPO.est_ZWD_from == 0
        fprintf(fileID,'  %s\n','ZWD is estimated');
    else
        fprintf(fileID,'  %s%5.2f\n','ZWD is estimated from minute ', settings.TROPO.est_ZWD_from);
    end
else
    fprintf(fileID,'  %s\n','ZWD is not estimated');
end
fprintf(fileID,'\n');



%% Models - Ionosphere

fprintf(fileID,'%s\n','Ionosphere:');
fprintf(fileID,'  %s%s\n','Model: ',settings.IONO.model);
if strcmpi(settings.IONO.model,'Estimate with ... as constraint')   ||   strcmpi(settings.IONO.model,'Correct with ...')
    fprintf(fileID,'    %s%s\n','Ionosphere source: ',settings.IONO.source);
    if strcmp(settings.IONO.source,'IONEX File')
        if strcmp(settings.IONO.model_ionex, 'Source:')
            fprintf(fileID,'    %s%s%s%s%s\n',settings.IONO.model_ionex,' ', settings.IONO.file_source, ', ',settings.IONO.file_ionex);
        else
            fprintf(fileID,'    %s%s%s\n',settings.IONO.model_ionex,' ',settings.IONO.file_ionex);
        end
		fprintf(fileID,'    %s%s\n','TEC-Interpolation: ',settings.IONO.interpol);
    end
end
fprintf(fileID,'\n');



%% Models - Other corrections

fprintf(fileID,'%s\n','Other Corrections:');
if ~isempty(settings.OTHER.file_antex)
    switch settings.OTHER.antex
        case 'Manual choice:'
            fprintf(fileID,'  %s%s\n','Manual Antex file: ', settings.OTHER.file_antex);
        otherwise 
            fprintf(fileID,'  %s%s\n','Antex file: ', settings.OTHER.file_antex);
    end
    if settings.OTHER.antex_rec_manual
        fprintf(fileID,'  %s\n','Own corrections from MyAntex.atx');
    end
    if ~isempty(rec_pco)        % print missing PCO corrrections
        fprintf(fileID,'    %s%s\n','Missing PCOs: ', rec_pco);
    end
    if ~isempty(rec_pcv)        % print missing PCV corrrections
        fprintf(fileID,'    %s%s\n','Missing PCVs: ', rec_pcv);
    end
end
if settings.OTHER.bool_rec_arp || settings.OTHER.bool_rec_pco || settings.OTHER.bool_sat_pco || ... % all other corrections
        settings.OTHER.bool_solid_tides || settings.OTHER.bool_wind_up || settings.OTHER.bool_eclipse          
    fprintf(fileID,'  %s\n','Activated Corrections: ');
    if settings.OTHER.bool_rec_arp && ~settings.KINE.bool_kinematic
        fprintf(fileID,'    %s\n','o Antenna Reference Point');
    end
    if settings.OTHER.bool_rec_pco
        fprintf(fileID,'    %s\n','o Receiver Phase Center Offset');
    end
    if settings.OTHER.bool_rec_pcv
        fprintf(fileID,'    %s\n','o Receiver Phase Center Variations');
    end
    if settings.OTHER.bool_sat_pco
        fprintf(fileID,'    %s\n','o Satellite Phase Center Offset');
    end
    if settings.OTHER.bool_sat_pcv
        fprintf(fileID,'    %s\n','o Satellite Phase Center Variations');
    end
    if settings.OTHER.bool_wind_up
        fprintf(fileID,'    %s\n','o Phase Wind-Up Correction');
    end
    if settings.OTHER.bool_eclipse && ~settings.ORBCLK.bool_obx
        fprintf(fileID,'    %s\n','o Eclipse condition is on');
    end
    if settings.OTHER.shapiro
        fprintf(fileID,'    %s\n','o Shapiro Effect Correction');
    end
    if settings.OTHER.bool_GDV
        fprintf(fileID,'    %s\n','o Group Delay Variation Correction');
    end
    if settings.OTHER.bool_solid_tides
        fprintf(fileID,'    %s\n','o Solid Tides Correction');
    end
    if settings.OTHER.ocean_loading
        if ~isempty(input.OTHER.OcLoad)
            fprintf(fileID,'    %s\n','o Ocean Loading');
        else
            fprintf(fileID,'    %s\n','o Ocean Loading (not applied, lacking coefficients)');
        end
    end
    if settings.OTHER.polar_tides
        if ~isempty(input.ORBCLK.ERP)
            fprintf(fileID,'    %s\n','o Polar Tides');
        else
            fprintf(fileID,'    %s\n','o Polar Tides (not applied, lacking *.erp-file)');
        end
    end
   
else
    fprintf(fileID,'  %s\n','No Other Corrections');
end
if settings.OTHER.CS.l1c1 || settings.OTHER.CS.DF || settings.OTHER.CS.Doppler
    fprintf(fileID,'  %s\n','Cycle-Slip-Detection:');
    if settings.OTHER.CS.l1c1
        fprintf(fileID,'    %s%.2f%s%.2f%s%d%s\n','L1-C1: threshold = ',settings.OTHER.CS.l1c1_threshold,' [m], window-size = ',settings.OTHER.CS.l1c1_window,' [epochs]' );
    end
    if settings.OTHER.CS.DF
        fprintf(fileID,'    %s%.2f%s\n','dL1-dL2: threshold = ',settings.OTHER.CS.DF_threshold,' [m]');
    end
    if settings.OTHER.CS.Doppler
        fprintf(fileID,'    %s%.2f%s\n','Doppler-Shift: threshold = ',settings.OTHER.CS.D_threshold,' [cy]');
    end
    if settings.OTHER.CS.TimeDifference
        fprintf(fileID,'    %s%.2f%s%.2f%s%d\n','Time difference: threshold = ',settings.OTHER.CS.TD_threshold,' [m], degree = ',settings.OTHER.CS.TD_degree );
    end    
    if settings.OTHER.CS.HMW
        fprintf(fileID,'    %s%.2f%s%.2f%s%d\n','HMW LC: threshold = ',settings.OTHER.CS.HMW_threshold,' [cy], factor = ',settings.OTHER.CS.HMW_factor );
    end    
    if settings.PROC.LLI
        fprintf(fileID,'    %s\n','LLI from RINEX is used');
    end
else
    fprintf(fileID,'  %s\n','No Cycle-Slip-Detection');
end
if settings.OTHER.mp_detection
    fprintf(fileID,'  %s\n','Multipath Detection is on:');
    fprintf(fileID,'    %s%.2f%s%.2f%s%d%s%d\n','Code difference: threshold = ',settings.OTHER.mp_thresh,' [m], degree = ',settings.OTHER.mp_degree,', cooldown = ', settings.OTHER.mp_cooldown);
end

fprintf(fileID,'\n');



%% Models - Kinematic

if settings.KINE.bool_kinematic || settings.KINE.satellite.bool

    fprintf(fileID,'%s\n','Kinematic:');
    if settings.KINE.bool_offset
        fprintf(fileID,'  %s%.4f, %.4f, %.4f\n', 'Offsets are applied [m]: ', settings.KINE.offset(1), settings.KINE.offset(2), settings.KINE.offset(3));
    else
        fprintf(fileID,'  %s\n', 'No offsets applied');
    end
	fprintf(fileID,'    %s%s\n', 'Orientation mode: ', settings.KINE.orient_mode);

    if settings.KINE.satellite.bool
        fprintf(fileID,'  %s\n', 'Satellite, dynamic model is applied');
        fprintf(fileID,'    %s%s\n', 'Identifier: ', settings.KINE.satellite.ID);
        fprintf(fileID,'    %s%.2f\n', 'Mass [kg]: ',  settings.KINE.satellite.mass);
        fprintf(fileID,'    %s%.2f\n', 'Area [m^2]: ', settings.KINE.satellite.area);
        fprintf(fileID,'    %s%.2f\n', 'Drag coefficient []: ', settings.KINE.satellite.drag);
        fprintf(fileID,'    %s%.2f\n', 'Solar coefficient []: ', settings.KINE.satellite.solar);
    else
        fprintf(fileID,'  %s\n', 'No satellite');
    end

    fprintf(fileID,'\n');
end




%% Estimation - Adjustment and Weighting

fprintf(fileID,'%s\n','Adjustment:');
% Observation weighting scheme
fprintf(fileID,'  %s','Weighting Scheme for Observations: ');
if settings.ADJ.weight_mplc
    fprintf(fileID,'%s\n','Multipath-LC');
elseif settings.ADJ.weight_elev
    if ischar(settings.ADJ.elev_weight_fun)
        fprintf(fileID,'%s%s\n','Elevation: ', settings.ADJ.elev_weight_fun);
    else
        fprintf(fileID,'%s%s\n','Elevation, function: ', strrep(func2str(settings.ADJ.elev_weight_fun), '@(e)', ''));
    end
elseif settings.ADJ.weight_sign_str
    if ischar(settings.ADJ.snr_weight_fun)
        fprintf(fileID,'%s%s\n','C/N0: ', settings.ADJ.snr_weight_fun);
    else
        fprintf(fileID,'%s%s\n','C/N0, function: ', strrep(func2str(settings.ADJ.snr_weight_fun), '@(snr)', ''));
    end
elseif settings.ADJ.weight_bore
    fprintf(fileID,'%s\n','Boresight angle');
elseif settings.ADJ.weight_none
    fprintf(fileID,'%s\n','None');
end
fprintf(fileID,'  %s %4.2f %s %4.2f %s %4.2f %s %4.2f%s %4.2f\n','GNSS weights (GRECJ):', ...
    settings.ADJ.fac_GPS, ':', settings.ADJ.fac_GLO, ':', settings.ADJ.fac_GAL, ':', settings.ADJ.fac_BDS, ':', settings.ADJ.fac_QZSS);
% Standard deviations of code and phase observations
fprintf(fileID,'  %s\n','Standard deviation of observations:');
if contains(settings.PROC.method, '+ Doppler')
    fprintf(fileID, '%s%6.3f\n%s%6.3f\n%s%6.3f\n', '    code  [m]    = ',sqrt(settings.ADJ.var_code),'    phase [m]    = ',sqrt(settings.ADJ.var_phase), '    Doppler [Hz] = ',sqrt(settings.ADJ.var_doppler));
else
    fprintf(fileID, '%s%6.3f\n%s%6.3f\n', '    code  [m]    = ',sqrt(settings.ADJ.var_code),'    phase [m]    = ',sqrt(settings.ADJ.var_phase));
end
if settings.ADJ.bool_std_frqs       % Frequency-specific standard devations
    fprintf(fileID, '  %s\n', 'Code, additional frequency-specific standard-deviations:');
    if settings.INPUT.use_GPS
        fprintf(fileID, '%s%6.3f, %6.3f, %6.3f\n', '    GPS: ', settings.ADJ.var_code_frq_GUI{1,1}, settings.ADJ.var_code_frq_GUI{1,2}, settings.ADJ.var_code_frq_GUI{1,3});
    end
    if settings.INPUT.use_GLO
        fprintf(fileID, '%s%6.3f, %6.3f, %6.3f\n', '    GLO: ', settings.ADJ.var_code_frq_GUI{2,1}, settings.ADJ.var_code_frq_GUI{2,2}, settings.ADJ.var_code_frq_GUI{2,3});
    end
    if settings.INPUT.use_GAL
        fprintf(fileID, '%s%6.3f, %6.3f, %6.3f\n', '    GAL: ', settings.ADJ.var_code_frq_GUI{3,1}, settings.ADJ.var_code_frq_GUI{3,2}, settings.ADJ.var_code_frq_GUI{3,3});
    end
    if settings.INPUT.use_BDS
        fprintf(fileID, '%s%6.3f, %6.3f, %6.3f\n', '    BDS: ', settings.ADJ.var_code_frq_GUI{4,1}, settings.ADJ.var_code_frq_GUI{4,2}, settings.ADJ.var_code_frq_GUI{4,3});
    end
    if settings.INPUT.use_QZSS
        fprintf(fileID, '%s%6.3f, %6.3f, %6.3f\n', '    QZSS:', settings.ADJ.var_code_frq_GUI{5,1}, settings.ADJ.var_code_frq_GUI{5,2}, settings.ADJ.var_code_frq_GUI{5,3});
    end
    fprintf(fileID, '  %s\n', 'Phase, additional frequency-specific standard-deviations:');
    if settings.INPUT.use_GPS
        fprintf(fileID, '%s%6.3f, %6.3f, %6.3f\n', '    GPS: ', settings.ADJ.var_phase_frq_GUI{1,1}, settings.ADJ.var_phase_frq_GUI{1,2}, settings.ADJ.var_phase_frq_GUI{1,3});
    end
    if settings.INPUT.use_GLO
        fprintf(fileID, '%s%6.3f, %6.3f, %6.3f\n', '    GLO: ', settings.ADJ.var_phase_frq_GUI{2,1}, settings.ADJ.var_phase_frq_GUI{2,2}, settings.ADJ.var_phase_frq_GUI{2,3});
    end
    if settings.INPUT.use_GAL
        fprintf(fileID, '%s%6.3f, %6.3f, %6.3f\n', '    GAL: ', settings.ADJ.var_phase_frq_GUI{3,1}, settings.ADJ.var_phase_frq_GUI{3,2}, settings.ADJ.var_phase_frq_GUI{3,3});
    end
    if settings.INPUT.use_BDS
        fprintf(fileID, '%s%6.3f, %6.3f, %6.3f\n', '    BDS: ', settings.ADJ.var_phase_frq_GUI{4,1}, settings.ADJ.var_phase_frq_GUI{4,2}, settings.ADJ.var_phase_frq_GUI{4,3});
    end
    if settings.INPUT.use_QZSS
        fprintf(fileID, '%s%6.3f, %6.3f, %6.3f\n', '    QZSS:', settings.ADJ.var_phase_frq_GUI{5,1}, settings.ADJ.var_phase_frq_GUI{5,2}, settings.ADJ.var_phase_frq_GUI{5,3});
    end    

else
    fprintf(fileID, '  %s\n', 'No frequency-specifics');
end
% Standard deviation of ionospheric pseudo-observations
if strcmpi(settings.IONO.model,'Estimate with ... as constraint')
    fprintf(fileID, '%s%6.3f\n', '    ionosphere  = ',sqrt(settings.ADJ.var_iono));
    fprintf(fileID,'      Constraint until minute: %.2f\n', settings.IONO.constraint_until);
    fprintf(fileID,'      Decrease stdev [m] to: %.2f\n', sqrt(settings.IONO.var_iono_decr));
end
% Filter and filter settings
fprintf(fileID,'  %s\n',settings.ADJ.filter.type);
if ~strcmp(settings.ADJ.filter.type,'No Filter')
    fprintf(fileID,'    %s%s\n', 'Filter direction: ', settings.ADJ.filter.direction);
    fprintf(fileID,'    %s\n', 'Filter-Settings (initial standard deviation [m] | system noise standard deviation [m/sqrt(h)] | dynamic model):');
    fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Coordinates:        ',sqrt(settings.ADJ.filter.var_coord),    ' | ',sqrt(settings.ADJ.filter.Q_coord),     ' | ',settings.ADJ.filter.dynmodel_coord);
    if settings.KINE.satellite.bool || settings.KINE.bool_kinematic
        fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Velocity:           ',sqrt(settings.ADJ.filter.var_velocity), ' | ',sqrt(settings.ADJ.filter.Q_velocity),  ' | ', settings.ADJ.filter.dynmodel_velocity);
    end
    if settings.TROPO.estimate_ZWD
        fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Zenith Wet Delay:   ',sqrt(settings.ADJ.filter.var_zwd),      ' | ',sqrt(settings.ADJ.filter.Q_zwd),       ' | ', settings.ADJ.filter.dynmodel_zwd);
    end
    if settings.INPUT.use_GPS
        fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Receiver Clock GPS: ',sqrt(settings.ADJ.filter.var_rclk_gps),' | ',sqrt(settings.ADJ.filter.Q_rclk_gps),  ' | ',settings.ADJ.filter.dynmodel_rclk_gps);
    end
    if settings.INPUT.use_GLO
        fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Receiver Clock GLO: ',sqrt(settings.ADJ.filter.var_rclk_glo), ' | ',sqrt(settings.ADJ.filter.Q_rclk_glo),  ' | ',settings.ADJ.filter.dynmodel_rclk_glo);
    end
    if settings.INPUT.use_GAL
        fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Receiver Clock GAL: ',sqrt(settings.ADJ.filter.var_rclk_gal), ' | ',sqrt(settings.ADJ.filter.Q_rclk_gal),  ' | ',settings.ADJ.filter.dynmodel_rclk_gal);
    end
    if settings.INPUT.use_BDS
        fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Receiver Clock BDS: ',sqrt(settings.ADJ.filter.var_rclk_bds), ' | ',sqrt(settings.ADJ.filter.Q_rclk_bds),  ' | ',settings.ADJ.filter.dynmodel_rclk_bds);
    end
    if settings.INPUT.use_QZSS
        fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Receiver Clock QZSS:',sqrt(settings.ADJ.filter.var_rclk_qzss), ' | ',sqrt(settings.ADJ.filter.Q_rclk_qzss),  ' | ',settings.ADJ.filter.dynmodel_rclk_qzss);
    end    
    if settings.BIASES.estimate_rec_dcbs
        if ~bool_DCM
            fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Receiver DCBs:      ',sqrt(settings.ADJ.filter.var_DCB),      ' | ',sqrt(settings.ADJ.filter.Q_DCB),       ' | ', settings.ADJ.filter.dynmodel_DCB);
        else
            fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Receiver Biases:    ',sqrt(settings.ADJ.filter.var_DCB),      ' | ',sqrt(settings.ADJ.filter.Q_DCB),       ' | ', settings.ADJ.filter.dynmodel_DCB);
        end
    end
    if contains(settings.PROC.method, '+ Doppler')
        fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Rec Clock Drift:    ',sqrt(settings.ADJ.filter.var_rclk_drift),' | ',sqrt(settings.ADJ.filter.Q_rclk_drift),' | ', settings.ADJ.filter.dynmodel_rclk_drift);
    end    
    if contains(settings.PROC.method, '+ Phase')
        fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Float Ambiguities:  ',sqrt(settings.ADJ.filter.var_amb),      ' | ',sqrt(settings.ADJ.filter.Q_amb),       ' | ', settings.ADJ.filter.dynmodel_amb);
    end
    if contains(settings.IONO.model, 'Estimate')
        fprintf(fileID,'    %s%11.3f%s%11.3f%s%d\n','Ionospheric Delay:  ',sqrt(settings.ADJ.filter.var_iono),     ' | ',sqrt(settings.ADJ.filter.Q_iono),      ' | ', settings.ADJ.filter.dynmodel_iono);
    end
end
fprintf(fileID,'  %s%d','Number of estimated parameters: ', ~bool_DCM*DEF.NO_PARAM_ZD + bool_DCM*DEF.NO_PARAM_DCM);
fprintf(fileID,'\n');



%% Estimation - Ambiguity Fixing

fprintf(fileID,'\n%s\n','Ambiguity Fixing: ');
if settings.AMBFIX.bool_AMBFIX
    if ~bool_DCM
        fprintf(fileID,'  %s%.0f%s%.0f%s\n','Fixing-Start [s]: WL = ',settings.AMBFIX.start_WL_sec,', NL = ',settings.AMBFIX.start_NL_sec);
    else
        fprintf(fileID,'  %s%.0f\n', 'Fixing-Start [s] = ', settings.AMBFIX.start_WL_sec);
    end
    if ~bool_DCM
        fprintf(fileID,'  %s%.2f%s%.2f%s%.0f%s\n','HMW fixing: threshold = ', settings.AMBFIX.HMW_thresh, ' [cy], releasing threshold = ', settings.AMBFIX.HMW_release, ' [cy], window = ', settings.AMBFIX.HMW_window, ' [s]');
    end
    fprintf(fileID,'  %s%d\n','Fixing cutoff [°]: ', settings.AMBFIX.cutoff);
    fprintf(fileID,'  %s%s\n','Choice of Reference Satellite: ', settings.AMBFIX.refSatChoice);
    if strcmp(settings.AMBFIX.refSatChoice, 'manual choice (list):')
        fprintf(fileID,'    %s%d\n','GPS: ', settings.AMBFIX.refSatGPS);
		fprintf(fileID,'    %s%d\n','GLONASS: ', settings.AMBFIX.refSatGLO);
        fprintf(fileID,'    %s%d\n','Galileo: ', settings.AMBFIX.refSatGAL);
		fprintf(fileID,'    %s%d\n','BeiDou: ', settings.AMBFIX.refSatBDS);
		fprintf(fileID,'    %s%d\n','QZSS: ', settings.AMBFIX.refSatQZS);
    end
    if isempty(settings.AMBFIX.exclude_sats_fixing)
        fprintf(fileID,'  %s\n','No satellites excluded from fixing.');
    else
        fprintf(fileID,'  %s%s\n','Excluded satellites from fixing: ', num2str(settings.AMBFIX.exclude_sats_fixing'));
    end
    fprintf(fileID,'  %s%s\n','Detection of Wrong Fixes: ', settings.AMBFIX.wrongFixes);
else
    fprintf(fileID,'  %s\n','Off');
end
fprintf(fileID,'\n');


%% Run - Processing Options

fprintf(fileID,'%s\n','Processing Options:');

fprintf(fileID,'  %s%s\n','Processing name: ', settings.PROC.name);
fprintf(fileID,'  %s%s\n','Output: ', settings.PROC.output_dir);
if settings.PROC.timeSpan_format_epochs
    fprintf(fileID,'  %s%d%s%d\n','Epochs: ',settings.PROC.timeFrame(1),' - ',settings.PROC.timeFrame(2));
elseif settings.PROC.timeSpan_format_time
    fprintf(fileID,'  %s%s - %s\n','Time: ',settings.PROC.timeFrameFrom,settings.PROC.timeFrameTo);
elseif settings.PROC.timeSpan_format_SOD
    fprintf(fileID,'  %s%d%s%d\n','Seconds of Day: ',settings.PROC.timeFrame(1),' - ',settings.PROC.timeFrame(2));
elseif settings.PROC.timeSpan_format_HOD
    fprintf(fileID,'  %s%d%s%d\n','Hours of Day ',settings.PROC.timeFrame(1),' - ',settings.PROC.timeFrame(2));
end
if settings.PROC.reset_float || settings.PROC.reset_fixed
    if settings.PROC.reset_bool_min
        fprintf(fileID,'  %s%d%s\n','Reset solution after ', settings.PROC.reset_after, ' minutes');
    elseif settings.PROC.reset_bool_epoch
        fprintf(fileID,'  %s%d%s\n','Reset solution after ', settings.PROC.reset_after, ' epochs');
    end
end
if settings.INPUT.use_GPS
    fprintf(fileID,'  %s%s%s%s%s%s\n','GPS-Frequencies: ',settings.INPUT.gps_freq{1},', ',settings.INPUT.gps_freq{2},', ',settings.INPUT.gps_freq{3});
    fprintf(fileID,'  GPS-Ranking: %s\n', settings.INPUT.gps_ranking);
end
if settings.INPUT.use_GLO
    fprintf(fileID,'  %s%s%s%s%s%s\n','Glonass-Frequencies: ',settings.INPUT.glo_freq{1},', ',settings.INPUT.glo_freq{2},', ',settings.INPUT.glo_freq{3});
    fprintf(fileID,'  Glonass-Ranking: %s\n', settings.INPUT.glo_ranking);
end
if settings.INPUT.use_GAL
    fprintf(fileID,'  %s%s%s%s%s%s\n','Galileo-Frequencies: ',settings.INPUT.gal_freq{1},', ',settings.INPUT.gal_freq{2},', ',settings.INPUT.gal_freq{3});
    fprintf(fileID,'  %s%s\n','Galileo-Ranking: ', settings.INPUT.gal_ranking);
end
if settings.INPUT.use_BDS
    fprintf(fileID,'  %s%s%s%s%s%s\n','BeiDou-Frequencies: ',settings.INPUT.bds_freq{1},', ',settings.INPUT.bds_freq{2},', ',settings.INPUT.bds_freq{3});
    fprintf(fileID,'  %s%s\n','BeiDou-Ranking: ', settings.INPUT.bds_ranking);
end
if settings.INPUT.use_QZSS
    fprintf(fileID,'  %s%s%s%s%s%s\n','QZSS-Frequencies: ',settings.INPUT.qzss_freq{1},', ',settings.INPUT.qzss_freq{2},', ',settings.INPUT.qzss_freq{3});
    fprintf(fileID,'  %s%s\n','BeiDou-Ranking: ', settings.INPUT.qzss_ranking);
end

% adjust phase to code
if settings.PROC.AdjustPhase2Code
    fprintf(fileID,'  %s\n','Adjust phase to code is ON');
else
    fprintf(fileID,'  %s\n','Adjust phase to code is OFF');
end



% print excluded satellites from processing
fprintf(fileID,'  Excluded Satellites:\n');
excl_matrix_sats = settings.PROC.exclude;
n = size(excl_matrix_sats,1);
bool = false;
for i = 1:n
    prn =   excl_matrix_sats{i,1};
    start = excl_matrix_sats{i,2};
    ende =  excl_matrix_sats{i,3};
    if isempty(prn)
        continue
    end
    if isempty(start)
        start = 0;
    end
    if isempty(ende)
        ende = Inf;
    end
    if ischar(prn)
        fprintf(fileID, '    %s%s','PRN ',  prn);
    else
        fprintf(fileID, '    %s%s','PRN ',  sprintf('%03d', prn));
    end
    fprintf(fileID, '%s%s',', from ', sprintf('%6d', start));
    fprintf(fileID, '%s%s',' to ', sprintf('%6d', ende));
    fprintf(fileID,'\n');
    bool = true;
end
if ~bool
    fprintf(fileID, '    None\n');
end

% print from processing excluded epochs 
fprintf(fileID,'  Excluded Epochs:\n');
excl_matrix_eps = settings.PROC.exclude_epochs;
n = size(excl_matrix_eps,1);
bool = false;
for i = 1:n
    start =  excl_matrix_eps{i,1};
    ende  =  excl_matrix_eps{i,2};
    reset =  excl_matrix_eps{i,3};
    if isempty(start)
        continue
    end
    if isempty(ende)
        ende = Inf;
    end
    fprintf(fileID, '    %s%s','From ', sprintf('%6d', start));
    fprintf(fileID, '%s%s',' to ', sprintf('%6d', ende));
    if reset
        fprintf(fileID,', with reset\n');
    else
        fprintf(fileID,', no reset\n');
    end
    bool = true;
end
if ~bool
    fprintf(fileID, '    None\n');
end

fprintf(fileID,'  Satellite Exclusion Criteria:\n');
fprintf(fileID,'    %s%d%s\n', 'Elevation Cutoff: ',settings.PROC.elev_mask,' [°]');
fprintf(fileID,'    %s%s%s\n', 'C/N0 Cutoff: ', num2str(settings.PROC.SNR_mask),' [db-Hz]');
fprintf(fileID,'    %s%d\n', 'Signal Strength Threshold: ',settings.PROC.ss_thresh);

if settings.PROC.check_omc
    fprintf(fileID,'    %s\n', 'Check of observed minus (omc) computed is ON.');
    fprintf(fileID,'      %s%06.3f\n', 'Threshold Code  [m]: ', settings.PROC.omc_code_thresh);
    fprintf(fileID,'      %s%06.3f\n', 'Threshold Phase [m]: ', settings.PROC.omc_phase_thresh);
    fprintf(fileID,'      %s%d%s%d\n', 'Factor: ', settings.PROC.omc_factor, '; Window: ', settings.PROC.omc_window);
else
    fprintf(fileID,'    %s\n', 'Check of observed minus (omc) computed is OFF.');
end

if settings.PROC.bool_rec_clk_jump
    fprintf(fileID,'  %s\n', 'Receiver clock jumps are detected and compensated.');
else
    fprintf(fileID,'  %s\n', 'Receiver clock jumps are NOT detected and NOT compensated.');
end
fprintf(fileID,'\n');



%% Station information
fprintf(fileID,'General Information (Observation File):\n');
fprintf(fileID,'  Long station name: %s\n', obs.station_long);
fprintf(fileID,'  Station name: %s\n', obs.stationname);
fprintf(fileID,'  Observation interval: %02.2f seconds\n', obs.interval);
fprintf(fileID,'  Antenna:  %s\n', obs.antenna_type);
fprintf(fileID,'  Receiver: %s\n', obs.receiver_type);
fprintf(fileID,'  Receiver antenna delta (H/E/N): %02.4f / %02.4f / %02.4f\n', obs.rec_ant_delta(3), obs.rec_ant_delta(2), obs.rec_ant_delta(1));

fprintf(fileID,'  Time of first observation (y, m, d, h, min, sec): ');
fprintf(fileID,'%04.0f %02.0f %02.0f %02.0f %02.0f %10.7f\n', obs.startdate(1), obs.startdate(2), obs.startdate(3), obs.startdate(4), obs.startdate(5), obs.startdate(6));
fprintf(fileID,'    jd: %13.5f', obs.startdate_jd);
fprintf(fileID,', doy: %01.0f', floor(obs.doy));
fprintf(fileID,', gps-date: %04.0f / %02.0f\n', obs.startGPSWeek, floor(obs.startSow/86400));

fprintf(fileID,'  Leap seconds: %02.2f\n', obs.leap_sec);
fprintf(fileID,'\n');


%% Export options
fprintf(fileID,'Export options:\n');
% Output
fprintf(fileID,'  Output\n');
if settings.EXP.settings
    fprintf(fileID,'    settings.mat is exported\n');
end
if settings.EXP.data4plot
    fprintf(fileID,'    data4plot.mat is exported\n');
end
if settings.EXP.model_save
    fprintf(fileID,'    model_save is saved to data4plot.mat\n');
end
if settings.EXP.settings_summary
    fprintf(fileID,'    settings_summary.txt is written\n');
end
if settings.EXP.results_txt
    fprintf(fileID,'    results_float.txt is written\n');
end
if settings.EXP.results_txt && settings.AMBFIX.bool_AMBFIX
    fprintf(fileID,'    results_fixed.txt is written\n');
end
if settings.EXP.results_csv
    fprintf(fileID,'    results_float.csv is written\n');
end
if settings.EXP.results_csv && settings.AMBFIX.bool_AMBFIX
    fprintf(fileID,'    results_fixed.csv is written\n');
end
if settings.EXP.results_csv && settings.EXP.bool_csv_utc
    fprintf(fileID,'      UTC timestamps are included in CSV\n');
end
% Variables: obs
fprintf(fileID,'  Variables\n');
if settings.EXP.obs_bias
    fprintf(fileID,'    C1_/.../L1_/.../L3_bias is saved to obs\n');
end
if settings.EXP.obs_epochheader
    fprintf(fileID,'    epochheader is saved to obs\n');
end
% Variables: storeData
if settings.EXP.storeData && settings.EXP.storeData_iono_mf
    fprintf(fileID,'    iono_mf is saved to storeData\n');
end
if settings.EXP.storeData && settings.EXP.storeData_vtec
    fprintf(fileID,'    vtec is saved to storeData\n');
end
if settings.EXP.storeData && settings.EXP.storeData_mp_1_2
    fprintf(fileID,'    mp1, mp2 is saved to storeData\n');
end
if settings.EXP.storeData && settings.EXP.storeData_sat_status
    fprintf(fileID,'    sat_status is saved to storeData\n');
end
% Variables: satellites
if settings.EXP.satellites && settings.EXP.satellites_D
    fprintf(fileID,'    .D1, .D2, .D3 is saved to satellites\n');
end

%% Processing end and time
fprintf(fileID,'\n\n');
fprintf(fileID,'Processing:\n');
if ~settings.INPUT.bool_batch
    fprintf(fileID,'  Type: Single File\n');
else
    if settings.INPUT.bool_parfor
        fprintf(fileID,'  Type: Batch, parfor loop\n');
    else
        fprintf(fileID,'  Type: Batch, for loop\n');
    end
end
proc_time = toc(tStart);
sec = mod(proc_time,60);
min = floor(proc_time/60);
proc_string = ['  Duration: ' sprintf('%.0f', min) 'min ' sprintf('%02.02f',sec) 'sec'];
fprintf(fileID,'%s\n',proc_string);
fprintf(fileID,'  End: %s\n', datetime('now'));



%% raPPPid version
try
    [~,git_hash_str] = system('git rev-parse HEAD');
    git_hash_str = strtrim(git_hash_str);
    if contains(git_hash_str, 'not a git repository') || ...
            contains(git_hash_str, 'not recognized as an internal or external command') || ...
            contains(git_hash_str, 'Der Befehl "git" ist entweder falsch geschrieben')
        fprintf(fileID,'  Git commit detection failed\n');
    else
        fprintf(fileID,'  Git commit: %s\n', git_hash_str);
    end
catch
    fprintf(fileID,'  Git commit detection failed\n');
end
fprintf(fileID,'  raPPPid %s', DEF.version);


%% close file
fclose(fileID);






