From 1ce974716dd014a08f69194b3c32378f7b4c4f1d Mon Sep 17 00:00:00 2001 From: Michele Marin <michele.marin@epfl.ch> Date: Mon, 14 Oct 2024 11:49:33 +0200 Subject: [PATCH 01/11] Add possibility of choosing cxrs systems for raw data --- matlab/TCV_IMAS/tcv2ids.m | 2 ++ matlab/TCV_IMAS/tcv2ids2database.m | 2 ++ matlab/TCV_IMAS/tcv_get_ids_core_profiles.m | 17 +++++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/matlab/TCV_IMAS/tcv2ids.m b/matlab/TCV_IMAS/tcv2ids.m index 83662207..85f6a664 100644 --- a/matlab/TCV_IMAS/tcv2ids.m +++ b/matlab/TCV_IMAS/tcv2ids.m @@ -54,6 +54,8 @@ p.addOptional('nverbose', 1, @(x) isempty(x) || isnumeric(x) ); p.addOptional('time_out', [], @(x) isempty(x) || isnumeric(x) ); p.addOptional('trialindx', [], @(x) isempty(x) || isnumeric(x) ); p.addOptional('liuqe', [], @(x) isempty(x) || isnumeric(x) ); +p.addOptional('cxrs_source_ti', [], @(x) isempty(x) || isnumeric(x) ); +p.addOptional('cxrs_source_ni', [], @(x) isempty(x) || isnumeric(x) ); params_not_for_gdat_params = {'shot','ids_names'}; diff --git a/matlab/TCV_IMAS/tcv2ids2database.m b/matlab/TCV_IMAS/tcv2ids2database.m index 916ec438..2c7de5b6 100644 --- a/matlab/TCV_IMAS/tcv2ids2database.m +++ b/matlab/TCV_IMAS/tcv2ids2database.m @@ -63,6 +63,8 @@ p.addOptional('b0sign_out', 0, @(x) isempty(x) || (isscalar(x) && (x==0 || x==-1 p.addOptional('nverbose', 1, @(x) isempty(x) || isnumeric(x) ); p.addOptional('time_out', [], @(x) isempty(x) || isnumeric(x) ); p.addOptional('trialindx', [], @(x) isempty(x) || isnumeric(x) ); +p.addOptional('cxrs_source_ti', [], @(x) isempty(x) || isnumeric(x) ); +p.addOptional('cxrs_source_ni', [], @(x) isempty(x) || isnumeric(x) ); p.parse; defaults_tcv2ids2database = p.Results; % to keep track of defaults diff --git a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m index e31c6fad..00b87105 100644 --- a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m +++ b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m @@ -244,11 +244,20 @@ end %% ion struct % assume only D if no CXRS (need to ask how to check if H...) params_eff_fit1.data_request = 'cxrs'; + +% Extract ti here +if isfield(gdat_params, 'cxrs_source_ti') + params_eff_fit1.source = gdat_params.cxrs_source_ti; +else + params_eff_fit1.source = [1,2,3]; +end + try temp_1d.cxrs_rho = gdat(params_cores_profiles.shot,params_eff_fit1); temp_1d_desc.cxrs_rho = params_eff_fit1.data_request; catch temp_1d.cxrs_rho.data = []; + temp_1d.cxrs_rho.error_bar = []; temp_1d_desc.cxrs_rho = ['Problem with gdat ' params_eff_fit1.data_request ' ; no data']; end params_eff_fit1.data_request = 'results.conf:ti'; @@ -275,6 +284,14 @@ temp_1d_desc.ti.raw = data_fullpath_fit; temp_1d.ti.fit = temp_1d.ti_conf_rho; temp_1d.ti.fit =get_grids_1d(temp_1d.ti.fit,1,1); temp_1d_desc.ti.fit = temp_1d_desc.ti_conf_rho; + +% Extract ni here +if isfield(gdat_params, 'cxrs_source_ni') + params_eff_fit1.source = gdat_params.cxrs_source_ni; +else + params_eff_fit1.source = [1,2,3]; +end + temp_1d.ni.fit = temp_1d.ni_conf_rho; temp_1d.ni.fit =get_grids_1d(temp_1d.ni.fit,1,1); temp_1d_desc.ni.fit = temp_1d_desc.ni_conf_rho; -- GitLab From f2d882cad1444f2c96be03cb52dee9f33cfa3aa6 Mon Sep 17 00:00:00 2001 From: Michele Marin <michele.marin@epfl.ch> Date: Mon, 14 Oct 2024 11:53:40 +0200 Subject: [PATCH 02/11] Add check for disrupted shot --- matlab/TCV_IMAS/tcv2ids.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/matlab/TCV_IMAS/tcv2ids.m b/matlab/TCV_IMAS/tcv2ids.m index 85f6a664..90752abd 100644 --- a/matlab/TCV_IMAS/tcv2ids.m +++ b/matlab/TCV_IMAS/tcv2ids.m @@ -123,6 +123,13 @@ for i=1:length(gdat_params_fields) end end gdat_params.data_request = 'ids'; + +%Check that the shot did not disrupt very early. +t_disrupted = gdat(shot,'time_disrupted()'); +if t_disrupted.data <= 0.04 | t_disrupted.data > 128 + error('the shot disrupted') +end + for i=1:length(params_tcv2ids.ids_names) ids_to_get = params_tcv2ids.ids_names{i}; gdat_params.source = ids_to_get; -- GitLab From 401210d1caa9f134fecc78bd7082ecb2b5125847 Mon Sep 17 00:00:00 2001 From: Michele Marin <michele.marin@epfl.ch> Date: Tue, 18 Feb 2025 19:19:17 +0100 Subject: [PATCH 03/11] Add errorbars for ion temperature and impurity density --- matlab/TCV_IMAS/tcv_get_ids_core_profiles.m | 81 +++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m index 00b87105..92a735ff 100644 --- a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m +++ b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m @@ -292,6 +292,25 @@ else params_eff_fit1.source = [1,2,3]; end +params_eff_fit1.data_request = 'results.conf:ni'; +temp_1d.ni_conf_rho = gdat(params_cores_profiles.shot,params_eff_fit1); +temp_1d_desc.ni_conf_rho = params_eff_fit1.data_request; +if ~isempty(temp_1d.cxrs_rho.data) + data_fullpath_raw = 'ni(C sometimes B) from cxrs system 1 to 3'; + temp_1d.ni.raw = temp_1d.cxrs_rho.ni.raw; + temp_1d.ni.raw.shot = temp_1d.cxrs_rho.shot;temp_1d.ni.raw.gdat_params = temp_1d.cxrs_rho.gdat_params; + temp_1d.ni.raw.x =temp_1d.cxrs_rho.ni.raw.rho; temp_1d.ni.raw.t =temp_1d.cxrs_rho.t; + if ~isempty(temp_1d.cxrs_rho.ni.raw.data) + data_fullpath_fit = 'ni from fit from cxrs thus ni(C)'; + temp_1d.ni.raw =get_grids_1d(temp_1d.ni.raw,2,1); + else + data_fullpath_fit = 'ni from fit in CONF node'; + end +else + data_fullpath_fit = 'ni from fit in CONF node'; +end + + temp_1d.ni.fit = temp_1d.ni_conf_rho; temp_1d.ni.fit =get_grids_1d(temp_1d.ni.fit,1,1); temp_1d_desc.ni.fit = temp_1d_desc.ni_conf_rho; @@ -353,6 +372,68 @@ if ~isempty(temp_1d.cxrs_rho.data) && ~isempty(temp_1d.cxrs_rho.ti.fit.data) end end +if ~isempty(temp_1d.cxrs_rho.error_bar) + switch error_bar + case 'delta' + for it=1:length(ids_core_profiles.time) + ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured_error_upper = temp_1d.cxrs_rho.ti.raw.error_bar(:,it_raw(it)); + ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured_error_upper = temp_1d.cxrs_rho.ti.raw.error_bar(:,it_raw(it)); + ids_core_profiles.profiles_1d{it}.t_i_average_fit.rho_tor_norm = temp_1d.cxrs_rho.ti.raw.rho(:,it_raw(it)); + ids_core_profiles.profiles_1d{it}.t_i_average_fit.rho_tor_norm_error_upper = temp_1d.cxrs_rho.ti.raw.error_bar_rho(:,it_raw(it)); + ids_core_profiles.profiles_1d{it}.t_i_average_fit.time_measurement = temp_1d.ti.raw.t(it_raw(it)); + end + case 'delta_with_lower' + for it=1:length(ids_core_profiles.time) + ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured_error_upper = temp_1d.cxrs_rho.error_bar(:,it_thom(it)); + ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured_error_lower = ... + ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured_error_upper; + ids_core_profiles.profiles_1d{it}.t_i_average_fit.time_measurement = temp_1d.ti.raw.t(it_raw(it)); + end + case 'added' + for it=1:length(ids_core_profiles.time) + ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured_error_upper = ... + ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured ... + + temp_1d.cxrs_rho.error_bar(:,it_thom(it)); + ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured_error_lower = ... + ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured ... + - temp_1d.cxrs_rho.error_bar(:,it_thom(it)); + ids_core_profiles.profiles_1d{it}.t_i_average_fit.time_measurement = temp_1d.ti.raw.t(it_raw(it)); + end + otherwise + error(['tcv_ids_cxrs_extraction: error_bar option not known: ' error_bar]) + end + switch error_bar + case 'delta' + for it=1:length(ids_core_profiles.time) + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured_error_upper = temp_1d.cxrs_rho.ni.raw.error_bar(:,it_raw(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured_error_upper = temp_1d.cxrs_rho.ni.raw.error_bar(:,it_raw(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.rho_tor_norm = temp_1d.cxrs_rho.ni.raw.rho(:,it_raw(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.rho_tor_norm_error_upper = temp_1d.cxrs_rho.ni.raw.error_bar_rho(:,it_raw(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.time_measurement = temp_1d.ni.raw.t(it_raw(it)); + end + case 'delta_with_lower' + for it=1:length(ids_core_profiles.time) + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured_error_upper = temp_1d.cxrs_rho.error_bar(:,it_thom(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured_error_lower = ... + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured_error_upper; + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.time_measurement = temp_1d.ni.raw.t(it_raw(it)); + end + case 'added' + for it=1:length(ids_core_profiles.time) + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured_error_upper = ... + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured ... + + temp_1d.cxrs_rho.error_bar(:,it_thom(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured_error_lower = ... + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured ... + - temp_1d.cxrs_rho.error_bar(:,it_thom(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.time_measurement = temp_1d.ni.raw.t(it_raw(it)); + end + otherwise + error(['tcv_ids_cxrs_extraction: error_bar option not known: ' error_bar]) + end +end + + %% q profile and magnetic shear params_eff.data_request = 'q_rho'; temp_1d.q = gdat(params_cores_profiles.shot,params_eff); -- GitLab From f1617a0ceead352331cc21c03c50286e2a6f118b Mon Sep 17 00:00:00 2001 From: Michele Marin <michele.marin@epfl.ch> Date: Tue, 18 Mar 2025 19:23:45 +0100 Subject: [PATCH 04/11] draft start improvements --- matlab/TCV_IMAS/tcv_get_ids_core_profiles.m | 62 +++++++++++++++++++-- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m index 92a735ff..cd43b682 100644 --- a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m +++ b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m @@ -260,12 +260,10 @@ catch temp_1d.cxrs_rho.error_bar = []; temp_1d_desc.cxrs_rho = ['Problem with gdat ' params_eff_fit1.data_request ' ; no data']; end + params_eff_fit1.data_request = 'results.conf:ti'; temp_1d.ti_conf_rho = gdat(params_cores_profiles.shot,params_eff_fit1); temp_1d_desc.ti_conf_rho = params_eff_fit1.data_request; -params_eff_fit1.data_request = 'results.conf:ni'; -temp_1d.ni_conf_rho = gdat(params_cores_profiles.shot,params_eff_fit1); -temp_1d_desc.ni_conf_rho = params_eff_fit1.data_request; if ~isempty(temp_1d.cxrs_rho.data) data_fullpath_raw = 'Ti(C sometimes B) from cxrs system 1 to 3'; temp_1d.ti.raw = temp_1d.cxrs_rho.ti.raw; @@ -292,6 +290,15 @@ else params_eff_fit1.source = [1,2,3]; end +try + temp_1d.cxrs_rho = gdat(params_cores_profiles.shot,params_eff_fit1); + temp_1d_desc.cxrs_rho = params_eff_fit1.data_request; +catch + temp_1d.cxrs_rho.data = []; + temp_1d.cxrs_rho.error_bar = []; + temp_1d_desc.cxrs_rho = ['Problem with gdat ' params_eff_fit1.data_request ' ; no data']; +end + params_eff_fit1.data_request = 'results.conf:ni'; temp_1d.ni_conf_rho = gdat(params_cores_profiles.shot,params_eff_fit1); temp_1d_desc.ni_conf_rho = params_eff_fit1.data_request; @@ -348,6 +355,7 @@ for it=1:length(ids_core_profiles.time) ids_core_profiles.profiles_1d{it}.ion{2}.z_ion = 6.; ids_core_profiles.profiles_1d{it}.ion{2}.multiple_states_flag = 0; ids_core_profiles.profiles_1d{it}.ion{2}.temperature = ids_core_profiles.profiles_1d{it}.ion{1}.temperature; + ids_core_profiles.profiles_1d{it}.ion{2}.density = (ids_core_profiles.profiles_1d{it}.electrons.density - ids_core_profiles.profiles_1d{it}.ion{1}.density) ./ ids_core_profiles.profiles_1d{it}.ion{2}.z_ion; ids_core_profiles.profiles_1d{it}.ion{2}.density_thermal = ids_core_profiles.profiles_1d{it}.ion{2}.density; ids_core_profiles.profiles_1d{it}.ion{2}.pressure_thermal = 1.6022e-19.*ids_core_profiles.profiles_1d{it}.ion{2}.density_thermal ... @@ -365,13 +373,48 @@ end if ~isempty(temp_1d.cxrs_rho.data) && ~isempty(temp_1d.cxrs_rho.ti.fit.data) it_raw = iround_os(temp_1d.ti.raw.t,ids_core_profiles.time); for it=1:length(ids_core_profiles.time) - % ids_core_profiles.profiles_1d{it}.ion{1}.temperature_fit = temp_1d.ti.fit(:,it_ti(it)); - ids_core_profiles.profiles_1d{it}.ion{1}.density_fit.source = {'from Zeff and ne profile'}; + % ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit.measured = temp_1d.ti.fit(:,it_ti(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit.measured = temp_1d.ti.raw.data(:,it_raw(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit.source = {'from CXRS on C usually'}; + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured = temp_1d.ni.fit(:,it_ti(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.source = {'from CXRS on C usually'}; + + ids_core_profiles.profiles_1d{it}.ion{1}.temperature_fit = ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit + ids_core_profiles.profiles_1d{it}.ion{1}.density_fit.source = {'from CXRS on C usually, same as C temperature'}; + ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured = temp_1d.ti.raw.data(:,it_raw(it)); ids_core_profiles.profiles_1d{it}.t_i_average_fit.source = {'from CXRS on C usually'}; end end + +time_measurement_slice_method +time_measurement_slice_method.name='exact' or 'local' +time_measurement_slice_method.index=0 +time_measurement_slice_method.description='using Thomson scattering measurement at the given time' +time_measurement_width + +time_measurement_slice_method +time_measurement_slice_method.name='exact' or 'local' +time_measurement_slice_method.index=0 +time_measurement_slice_method.description='using Thomson scattering measurement at the given time' +local = 1 +chi_squared = \tcv_shot::top.results.proffit.avg_time:teft_chi2 + +time_measurement_width(:) = gdat(84927,'\tcv_shot::top.results.proffit.avg_time:time_avg','doplot',1); % nargout = 1 + + +% I am guessing that in gdat params_eff.fit_type = 'avg' takes the data from the avg_time and not local_time proffit nodes? +name='exact' or 'local' +index=0 +description='using Thomson scattering measurement at the given time' +(if only one TS laser time was used ) +or may be: +name='avg' or 'average' +index=-1 +description='average with TS at this time and other TS within +-delta_t' (delta_t is provided in the proffit:local tree), conf should know if nodes from local or avg + + if ~isempty(temp_1d.cxrs_rho.error_bar) switch error_bar case 'delta' @@ -434,6 +477,15 @@ if ~isempty(temp_1d.cxrs_rho.error_bar) end +%For the time integration of the Charge Exchange +timer_nodes = String2Struct(mdsdata('\ATLAS::CXRS_00X.ACQ:TIMING')); +mdsdata(timer_nodes.PeriodName) + + + + + + %% q profile and magnetic shear params_eff.data_request = 'q_rho'; temp_1d.q = gdat(params_cores_profiles.shot,params_eff); -- GitLab From 0580b1639c366634a6e3015a8c595501f48b813f Mon Sep 17 00:00:00 2001 From: Michele Marin <michele.marin@epfl.ch> Date: Wed, 19 Mar 2025 22:37:08 +0100 Subject: [PATCH 05/11] work in progress --- matlab/TCV_IMAS/tcv_get_ids_core_profiles.m | 28 +++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m index cd43b682..5041dde7 100644 --- a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m +++ b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m @@ -162,6 +162,34 @@ for ir=1:length(temp_1d.area.x) % map tmp_1d.area to core_profiles.time area_cpt(ir,:) = interpos(temp_1d.area.t,temp_1d.area.data(ir,:),ids_core_profiles.time,tens_time); end + +%% ----------------------------- WORK IN PROGRESS ---------------------------------- + +% Need to check if the temperature is local or averaged. Best way is to check the data themselves + +te_local_time = gdat(params_cores_profiles.shot, /'proffit:local_time:teft'); +te_avg_time = gdat(params_cores_profiles.shot, /'proffit:avg_time:teft'); + +te_conf = gdat(params_cores_profiles.shot, /'results::conf:te'); + +% Getting the call done to get the data in the description + +te_info = gdat(params_cores_profiles.shot, '\results::proffit:subcall:trial'); +te_profit_calls = te_info.data; +te_profit_standard_call = te_profit_calls{2}; + + + + +%% ----------------------------- WORK IN PROGRESS --------------------------------- + +[aa, bb] = hldsi(shot); + + + + + + it_thom = iround_os(temp_1d.te_rho.t,ids_core_profiles.time); for it=1:length(ids_core_profiles.time) % fill grid -- GitLab From 51de653bd7839441e30e30a9a92a2e4fb506d04f Mon Sep 17 00:00:00 2001 From: Michele Marin <michele.marin@epfl.ch> Date: Fri, 11 Apr 2025 12:09:05 +0200 Subject: [PATCH 06/11] adding work in progress sections --- matlab/TCV_IMAS/tcv_get_ids_core_profiles.m | 50 +++++++++++---------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m index 5041dde7..54fe0b3c 100644 --- a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m +++ b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m @@ -167,10 +167,10 @@ end % Need to check if the temperature is local or averaged. Best way is to check the data themselves -te_local_time = gdat(params_cores_profiles.shot, /'proffit:local_time:teft'); -te_avg_time = gdat(params_cores_profiles.shot, /'proffit:avg_time:teft'); +te_local_time = gdat(params_cores_profiles.shot, '\proffit:local_time:teft'); +te_avg_time = gdat(params_cores_profiles.shot, '\proffit:avg_time:teft'); -te_conf = gdat(params_cores_profiles.shot, /'results::conf:te'); +te_conf = gdat(params_cores_profiles.shot, '\results::conf:te'); % Getting the call done to get the data in the description @@ -185,7 +185,9 @@ te_profit_standard_call = te_profit_calls{2}; [aa, bb] = hldsi(shot); - +aa +bb +return @@ -416,31 +418,31 @@ if ~isempty(temp_1d.cxrs_rho.data) && ~isempty(temp_1d.cxrs_rho.ti.fit.data) end -time_measurement_slice_method -time_measurement_slice_method.name='exact' or 'local' -time_measurement_slice_method.index=0 -time_measurement_slice_method.description='using Thomson scattering measurement at the given time' -time_measurement_width +%time_measurement_slice_method +%time_measurement_slice_method.name='exact' or 'local' +%time_measurement_slice_method.index=0 +%time_measurement_slice_method.description='using Thomson scattering measurement at the given time' +%time_measurement_width -time_measurement_slice_method -time_measurement_slice_method.name='exact' or 'local' -time_measurement_slice_method.index=0 -time_measurement_slice_method.description='using Thomson scattering measurement at the given time' -local = 1 -chi_squared = \tcv_shot::top.results.proffit.avg_time:teft_chi2 +%time_measurement_slice_method +%time_measurement_slice_method.name='exact' or 'local' +%time_measurement_slice_method.index=0 +%time_measurement_slice_method.description='using Thomson scattering measurement at the given time' +%local = 1 +%chi_squared = \tcv_shot::top.results.proffit.avg_time:teft_chi2 -time_measurement_width(:) = gdat(84927,'\tcv_shot::top.results.proffit.avg_time:time_avg','doplot',1); % nargout = 1 +%time_measurement_width(:) = gdat(84927,'\tcv_shot::top.results.proffit.avg_time:time_avg','doplot',1); % nargout = 1 % I am guessing that in gdat params_eff.fit_type = 'avg' takes the data from the avg_time and not local_time proffit nodes? -name='exact' or 'local' -index=0 -description='using Thomson scattering measurement at the given time' -(if only one TS laser time was used ) -or may be: -name='avg' or 'average' -index=-1 -description='average with TS at this time and other TS within +-delta_t' (delta_t is provided in the proffit:local tree), conf should know if nodes from local or avg +%name='exact' or 'local' +%index=0 +%description='using Thomson scattering measurement at the given time' +%(if only one TS laser time was used ) +%or may be: +%name='avg' or 'average' +%index=-1 +%description='average with TS at this time and other TS within +-delta_t' (delta_t is provided in the proffit:local tree), conf should know if nodes from local or avg if ~isempty(temp_1d.cxrs_rho.error_bar) -- GitLab From 8d12cdd3992c6c1e66f3cf93afd156ae707043c5 Mon Sep 17 00:00:00 2001 From: Michele Marin <michele.marin@epfl.ch> Date: Tue, 15 Apr 2025 16:09:47 +0200 Subject: [PATCH 07/11] First draft checks on cxrs dependencies --- matlab/TCV_IMAS/tcv2ids.m | 1 + matlab/TCV_IMAS/tcv2ids2database.m | 5 ++ matlab/TCV_IMAS/tcv_get_ids_core_profiles.m | 51 +++++++++++++-------- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/matlab/TCV_IMAS/tcv2ids.m b/matlab/TCV_IMAS/tcv2ids.m index 90752abd..b06f247a 100644 --- a/matlab/TCV_IMAS/tcv2ids.m +++ b/matlab/TCV_IMAS/tcv2ids.m @@ -56,6 +56,7 @@ p.addOptional('trialindx', [], @(x) isempty(x) || isnumeric(x) ); p.addOptional('liuqe', [], @(x) isempty(x) || isnumeric(x) ); p.addOptional('cxrs_source_ti', [], @(x) isempty(x) || isnumeric(x) ); p.addOptional('cxrs_source_ni', [], @(x) isempty(x) || isnumeric(x) ); +p.addOptional('ignore_dependencies', [], @(x) isempty(x) || isnumeric(x) ); params_not_for_gdat_params = {'shot','ids_names'}; diff --git a/matlab/TCV_IMAS/tcv2ids2database.m b/matlab/TCV_IMAS/tcv2ids2database.m index 2c7de5b6..57a1e6f0 100644 --- a/matlab/TCV_IMAS/tcv2ids2database.m +++ b/matlab/TCV_IMAS/tcv2ids2database.m @@ -24,6 +24,9 @@ function [ids_from_tcv,varargout] = tcv2ids2database(shot,run_out,varargin); % 'time_out': if 2 values provided: get all time data within that time interval % otherwise get values at these times provided in time_out (with linear interpolation and cst extrapolation) % 'trialindx': trial_indx for relevant nodes, in particular CONF kinetic profiles nodes +% 'cxrs_source_ti': specify which sources to use for the charge exchange data and fits of ion temperature. Default all (1,2,3) +% 'cxrs_source_ni': specify which sources to use for the charge exchange data and fits of impurity density. Default all (1,2,3) +% 'ignore_dependencies': ignore unfulfilled dependencies in extracting cxrs data % % example: % ids_from_tcv = tcv2ids2database(62745,9999,'ids_names',{'pf_active'},'error_bar','added'); % to test only one ids @@ -65,6 +68,8 @@ p.addOptional('time_out', [], @(x) isempty(x) || isnumeric(x) ); p.addOptional('trialindx', [], @(x) isempty(x) || isnumeric(x) ); p.addOptional('cxrs_source_ti', [], @(x) isempty(x) || isnumeric(x) ); p.addOptional('cxrs_source_ni', [], @(x) isempty(x) || isnumeric(x) ); +p.addOptional('ignore_dependencies', [], @(x) isempty(x) || isnumeric(x) ); + p.parse; defaults_tcv2ids2database = p.Results; % to keep track of defaults diff --git a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m index 54fe0b3c..87b39f1c 100644 --- a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m +++ b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m @@ -167,28 +167,19 @@ end % Need to check if the temperature is local or averaged. Best way is to check the data themselves -te_local_time = gdat(params_cores_profiles.shot, '\proffit:local_time:teft'); -te_avg_time = gdat(params_cores_profiles.shot, '\proffit:avg_time:teft'); - -te_conf = gdat(params_cores_profiles.shot, '\results::conf:te'); - -% Getting the call done to get the data in the description - -te_info = gdat(params_cores_profiles.shot, '\results::proffit:subcall:trial'); -te_profit_calls = te_info.data; -te_profit_standard_call = te_profit_calls{2}; - +%te_local_time = gdat(params_cores_profiles.shot, '\proffit:local_time:teft'); +%te_avg_time = gdat(params_cores_profiles.shot, '\proffit:avg_time:teft'); +%te_local_time.t +%te_avg_time.t +%te_conf = gdat(params_cores_profiles.shot, '\results::conf:te'); -%% ----------------------------- WORK IN PROGRESS --------------------------------- - -[aa, bb] = hldsi(shot); - -aa -bb -return +% Getting the call done to get the data in the description +%te_info = gdat(params_cores_profiles.shot, '\results::proffit:subcall:trial'); +%te_profit_calls = te_info.data; +%te_profit_standard_call = te_profit_calls{2}; @@ -275,8 +266,29 @@ end % assume only D if no CXRS (need to ask how to check if H...) params_eff_fit1.data_request = 'cxrs'; +% Check that CXRS exists and that the fits are updated. Stop the generation if action should be taken. +[index_hldsi, info_hldsi] = hldsi(params_cores_profiles.shot); + +if isfield(info_hldsi.CXRS, 'timefilled') + date_CXRS = datetime(info_hldsi.CXRS.timefilled, 'InputFormat', 'dd-MMM-yyyy HH:mm:ss.SS'); + date_CONF = datetime(info_hldsi.CONF.timefilled, 'InputFormat', 'dd-MMM-yyyy HH:mm:ss.SS'); + + if date_CXRS > date_CONF + if (info_hldsi.CONF.trialindex{2}.index == 1) && strcmpi(info_hldsi.CONF.trialindex{2}.user{1}, 'ANANOCD_ANASRV ') + warning('Fits in conf nodes are not up to date with CXRS analysis.') + disp('Please run [status, info] = anaprofs_standard_no_currentdrive(shot,username,global_option);') + else + warning('Fits in conf nodes are not up to date with CXRS analysis.') + disp(strjoin({'The analysis was not automatic. Contact', info_hldsi.CONF.trialindex{2}.user{1}, 'for more info'}, ' ')) + end + if ~isfield(gdat_params, 'ignore_dependencies') + error('Use the ignore_dependencies flag to extract the data anyway'); + end + end +end + % Extract ti here -if isfield(gdat_params, 'cxrs_source_ti') +if isfield(gdat_params, 'cxrs_source_ti') params_eff_fit1.source = gdat_params.cxrs_source_ti; else params_eff_fit1.source = [1,2,3]; @@ -314,6 +326,7 @@ temp_1d.ti.fit =get_grids_1d(temp_1d.ti.fit,1,1); temp_1d_desc.ti.fit = temp_1d_desc.ti_conf_rho; % Extract ni here +params_eff_fit1.data_request = 'cxrs'; if isfield(gdat_params, 'cxrs_source_ni') params_eff_fit1.source = gdat_params.cxrs_source_ni; else -- GitLab From 8dabc3fbf0956d363edef892f04bd6e196d08259 Mon Sep 17 00:00:00 2001 From: Michele Marin <michele.marin@epfl.ch> Date: Tue, 15 Apr 2025 20:19:06 +0200 Subject: [PATCH 08/11] Improve description of cxrs data origin --- matlab/TCV_IMAS/tcv_get_ids_core_profiles.m | 50 ++++++++++++--------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m index 87b39f1c..cd139436 100644 --- a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m +++ b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m @@ -285,6 +285,8 @@ if isfield(info_hldsi.CXRS, 'timefilled') error('Use the ignore_dependencies flag to extract the data anyway'); end end +else + warning('CXRS analysis was not performed. Please rerun if data is available') end % Extract ti here @@ -305,9 +307,9 @@ end params_eff_fit1.data_request = 'results.conf:ti'; temp_1d.ti_conf_rho = gdat(params_cores_profiles.shot,params_eff_fit1); -temp_1d_desc.ti_conf_rho = params_eff_fit1.data_request; +temp_1d_desc.ti_conf_rho = [params_eff_fit1.data_request, ' which took data from ', temp_1d.ti_conf_rho.help]; if ~isempty(temp_1d.cxrs_rho.data) - data_fullpath_raw = 'Ti(C sometimes B) from cxrs system 1 to 3'; + data_fullpath_raw = ['Ti(C sometimes B) from cxrs system(s) ', char(strjoin(string(params_eff_fit1.source), ', '))]; temp_1d.ti.raw = temp_1d.cxrs_rho.ti.raw; temp_1d.ti.raw.shot = temp_1d.cxrs_rho.shot;temp_1d.ti.raw.gdat_params = temp_1d.cxrs_rho.gdat_params; temp_1d.ti.raw.x =temp_1d.cxrs_rho.ti.raw.rho; temp_1d.ti.raw.t =temp_1d.cxrs_rho.t; @@ -315,15 +317,17 @@ if ~isempty(temp_1d.cxrs_rho.data) data_fullpath_fit = 'Ti from fit from cxrs thus Ti(C)'; temp_1d.ti.raw =get_grids_1d(temp_1d.ti.raw,2,1); else - data_fullpath_fit = 'Ti from fit in CONF node'; + data_fullpath_fit = ['Ti from fit in CONF node, from call ', temp_1d_desc.ti_conf_rho]; end else - data_fullpath_fit = 'Ti from fit in CONF node'; + data_fullpath_fit = ['Ti from fit in CONF node, from call ', temp_1d_desc.ti_conf_rho]; end -temp_1d_desc.ti.raw = data_fullpath_fit; + temp_1d.ti.fit = temp_1d.ti_conf_rho; temp_1d.ti.fit =get_grids_1d(temp_1d.ti.fit,1,1); -temp_1d_desc.ti.fit = temp_1d_desc.ti_conf_rho; +temp_1d_desc.ti.raw = data_fullpath_raw; +temp_1d_desc.ti.fit = data_fullpath_fit; +temp_1d_desc.ti.tot = ['Raw data taken from ', data_fullpath_raw, ' and fits taken from ', data_fullpath_fit]; % Extract ni here params_eff_fit1.data_request = 'cxrs'; @@ -344,9 +348,9 @@ end params_eff_fit1.data_request = 'results.conf:ni'; temp_1d.ni_conf_rho = gdat(params_cores_profiles.shot,params_eff_fit1); -temp_1d_desc.ni_conf_rho = params_eff_fit1.data_request; +temp_1d_desc.ni_conf_rho = [params_eff_fit1.data_request, ' which took data from ', temp_1d.ni_conf_rho.help]; if ~isempty(temp_1d.cxrs_rho.data) - data_fullpath_raw = 'ni(C sometimes B) from cxrs system 1 to 3'; + data_fullpath_raw = ['ni(C sometimes B) from cxrs system(s) ', char(strjoin(string(params_eff_fit1.source), ', '))]; temp_1d.ni.raw = temp_1d.cxrs_rho.ni.raw; temp_1d.ni.raw.shot = temp_1d.cxrs_rho.shot;temp_1d.ni.raw.gdat_params = temp_1d.cxrs_rho.gdat_params; temp_1d.ni.raw.x =temp_1d.cxrs_rho.ni.raw.rho; temp_1d.ni.raw.t =temp_1d.cxrs_rho.t; @@ -354,16 +358,17 @@ if ~isempty(temp_1d.cxrs_rho.data) data_fullpath_fit = 'ni from fit from cxrs thus ni(C)'; temp_1d.ni.raw =get_grids_1d(temp_1d.ni.raw,2,1); else - data_fullpath_fit = 'ni from fit in CONF node'; + data_fullpath_fit = ['ni from fit in CONF node, from call ', temp_1d_desc.ni_conf_rho]; end else - data_fullpath_fit = 'ni from fit in CONF node'; + data_fullpath_fit = ['ni from fit in CONF node, from call ', temp_1d_desc.ni_conf_rho]; end - - +temp_1d_desc.ni.raw = data_fullpath_fit; temp_1d.ni.fit = temp_1d.ni_conf_rho; temp_1d.ni.fit =get_grids_1d(temp_1d.ni.fit,1,1); temp_1d_desc.ni.fit = temp_1d_desc.ni_conf_rho; +temp_1d_desc.ni.tot = ['Raw data taken from ', data_fullpath_raw, ' and fits taken from ', data_fullpath_fit]; + it_ti = iround_os(temp_1d.ti.fit.t,ids_core_profiles.time); % assumed 1 impurity with Zp=6 Zp = 6.; @@ -416,17 +421,18 @@ end if ~isempty(temp_1d.cxrs_rho.data) && ~isempty(temp_1d.cxrs_rho.ti.fit.data) it_raw = iround_os(temp_1d.ti.raw.t,ids_core_profiles.time); for it=1:length(ids_core_profiles.time) - % ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit.measured = temp_1d.ti.fit(:,it_ti(it)); ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit.measured = temp_1d.ti.raw.data(:,it_raw(it)); - ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit.source = {'from CXRS on C usually'}; - ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured = temp_1d.ni.fit(:,it_ti(it)); - ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.source = {'from CXRS on C usually'}; + ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit.source = temp_1d_desc.ti.tot; + temp_1d_desc.ti.tot + return + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured = temp_1d.ni.raw.data(:,it_raw(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.source = temp_1d_desc.ni.tot; - ids_core_profiles.profiles_1d{it}.ion{1}.temperature_fit = ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit - ids_core_profiles.profiles_1d{it}.ion{1}.density_fit.source = {'from CXRS on C usually, same as C temperature'}; + ids_core_profiles.profiles_1d{it}.ion{1}.temperature_fit = ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit; + ids_core_profiles.profiles_1d{it}.ion{1}.density_fit.source = {'Same as C temperature'}; - ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured = temp_1d.ti.raw.data(:,it_raw(it)); - ids_core_profiles.profiles_1d{it}.t_i_average_fit.source = {'from CXRS on C usually'}; + ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured = ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit; + ids_core_profiles.profiles_1d{it}.t_i_average_fit.source = {'Same as C temperature'}; end end @@ -521,8 +527,8 @@ end %For the time integration of the Charge Exchange -timer_nodes = String2Struct(mdsdata('\ATLAS::CXRS_00X.ACQ:TIMING')); -mdsdata(timer_nodes.PeriodName) +%timer_nodes = String2Struct(mdsdata('\ATLAS::CXRS_00X.ACQ:TIMING')); +%mdsdata(timer_nodes.PeriodName) -- GitLab From d729dffe2a9f2ff938bbbe6ccefce538f29bbdf6 Mon Sep 17 00:00:00 2001 From: Michele Marin <michele.marin@epfl.ch> Date: Wed, 30 Apr 2025 11:27:36 +0200 Subject: [PATCH 09/11] adding widths and extra descriptions for experimental data. Add errorbars for version > 2 --- matlab/TCV_IMAS/tcv_get_ids_core_profiles.m | 179 +++++++++++++------- 1 file changed, 121 insertions(+), 58 deletions(-) diff --git a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m index cd139436..23c36b37 100644 --- a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m +++ b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m @@ -23,6 +23,16 @@ machine = 'tcv'; tens_time = -1; tens_rho = -0.1; +% Extract imas version +imas_version_path = which('ids_gen'); +tokens = regexp(imas_version_path, 'IMAS/(\d+)', 'tokens'); + +if ~isempty(tokens) + imas_major_version = str2double(tokens{1}{1}); +else + error('Problems loading IMAS'); +end + if exist('gdat_params','var') [ids_core_profiles, params_cores_profiles] = ... tcv_ids_headpart(shot,ids_equil_empty,'cores_profiles','gdat_params',gdat_params,varargin{:}); @@ -35,6 +45,23 @@ end params_eff_ref = gdat_params; params_eff_ref.doplot=0; try params_eff_ref=rmfield(params_eff_ref,'source');catch;end % make sure no source (from ids def) + +% Find the times for cxrs integration for the various cxrs systems +system_ref = '\\ATLAS::CXRS_%03d.ACQ:TIMING'; %or '\tcv_shot::top.atlas.acquired.cxrs.system_001.acq:timing' +times_cxrs_integration = []; +for ii = 1:12 + system_names = sprintf(system_ref, ii); + warning('off'); + timings_cxrs = gdat(params_cores_profiles.shot,system_names); + warning('off'); + if timings_cxrs.data + period_name = regexp(timings_cxrs.data, 'PeriodName=''([^'']*)''', 'tokens', 'once'); + time = gdat(params_cores_profiles.shot, period_name); + times_cxrs_integration = [times_cxrs_integration,time.data*1e-6]; + end +end + + % initialize description ids_core_profiles_description = []; @@ -162,26 +189,31 @@ for ir=1:length(temp_1d.area.x) % map tmp_1d.area to core_profiles.time area_cpt(ir,:) = interpos(temp_1d.area.t,temp_1d.area.data(ir,:),ids_core_profiles.time,tens_time); end - -%% ----------------------------- WORK IN PROGRESS ---------------------------------- - +%% Extracting info about Thomson data % Need to check if the temperature is local or averaged. Best way is to check the data themselves +te_local_time = gdat(params_cores_profiles.shot, '\proffit:local_time:teft'); +te_avg_time = gdat(params_cores_profiles.shot, '\proffit:avg_time:teft'); +te_conf = gdat(params_cores_profiles.shot, '\results::conf:te'); + +if isequal(te_local_time.t, te_conf.t) || isequal(te_local_time.t, te_avg_time.t) + thomson_description = 'using Thomson scattering measurement at the given time'; +elseif isequal(te_avg_time.t, te_conf.t) + thomson_description = 'using Thomson scattering measurement averaged over respective width'; +else + thomson_description = 'unrecongnized'; + warning('Time series for Thomson not recognized. Check CONF nodes') +end -%te_local_time = gdat(params_cores_profiles.shot, '\proffit:local_time:teft'); -%te_avg_time = gdat(params_cores_profiles.shot, '\proffit:avg_time:teft'); - -%te_local_time.t -%te_avg_time.t - -%te_conf = gdat(params_cores_profiles.shot, '\results::conf:te'); - -% Getting the call done to get the data in the description - -%te_info = gdat(params_cores_profiles.shot, '\results::proffit:subcall:trial'); -%te_profit_calls = te_info.data; -%te_profit_standard_call = te_profit_calls{2}; +% Dimension is larger but times are the same, data exists after the end of the shot till end of acquisition. +% This is for now not used anywhere. The IDS chi_squared is for each datapoint, this is for the whole profile +% To calculate individual chi_squared the weights are needed. Where are they stored? +params_eff.data_request = '\tcv_shot::top.results.proffit.avg_time:teft_chi2'; +temp_1d.te_rho.chi_squared = gdat(params_cores_profiles.shot, params_eff); +temp_1d_desc.te_rho_chi_squared = params_eff.data_request; +time_measurement_width_all = gdat(params_cores_profiles.shot,'\tcv_shot::top.results.proffit.avg_time:time_avg'); +time_measurement_width_thomson = time_measurement_width_all.data(1) - time_measurement_width_all.data(2); it_thom = iround_os(temp_1d.te_rho.t,ids_core_profiles.time); for it=1:length(ids_core_profiles.time) @@ -206,6 +238,13 @@ for it=1:length(ids_core_profiles.time) size(ids_core_profiles.profiles_1d{it}.electrons.temperature_fit.measured)); ids_core_profiles.profiles_1d{it}.electrons.temperature_fit.rho_tor_norm = temp_1d.te_rho.grids_1d.rhotornorm(:,it_thom(it)); ids_core_profiles.profiles_1d{it}.electrons.temperature_fit.source = {'Thomson, interpos fit'}; + ids_core_profiles.profiles_1d{it}.electrons.temperature_fit.time_measurement_slice_method.name='local'; + ids_core_profiles.profiles_1d{it}.electrons.temperature_fit.time_measurement_slice_method.index=0; + ids_core_profiles.profiles_1d{it}.electrons.temperature_fit.time_measurement_slice_method.description= thomson_description; + ids_core_profiles.profiles_1d{it}.electrons.temperature_fit.local = 1; + %ids_core_profiles.profiles_1d{it}.electrons.temperature_fit.chi_squared = + ids_core_profiles.profiles_1d{it}.electrons.temperature_fit.time_measurement_width = time_measurement_width_thomson; + ids_core_profiles.profiles_1d{it}.electrons.density = temp_1d.fit.ne_rho.data(:,it); ids_core_profiles.profiles_1d{it}.electrons.density_thermal = ids_core_profiles.profiles_1d{it}.electrons.density; ids_core_profiles.profiles_1d{it}.electrons.density_fit.measured = temp_1d.ne_rho.data(:,it_thom(it)); @@ -213,6 +252,14 @@ for it=1:length(ids_core_profiles.time) size(ids_core_profiles.profiles_1d{it}.electrons.density_fit.measured)); ids_core_profiles.profiles_1d{it}.electrons.density_fit.rho_tor_norm = temp_1d.ne_rho.grids_1d.rhotornorm(:,it_thom(it)); ids_core_profiles.profiles_1d{it}.electrons.density_fit.source = {'Thomson, interpos fit'}; + ids_core_profiles.profiles_1d{it}.electrons.density_fit.time_measurement_slice_method.name='local'; + ids_core_profiles.profiles_1d{it}.electrons.density_fit.time_measurement_slice_method.index=0; + ids_core_profiles.profiles_1d{it}.electrons.density_fit.time_measurement_slice_method.description= thomson_description; + ids_core_profiles.profiles_1d{it}.electrons.density_fit.local = 1; + %ids_core_profiles.profiles_1d{it}.electrons.density_fit.chi_squared = + ids_core_profiles.profiles_1d{it}.electrons.density_fit.time_measurement_width = time_measurement_width_thomson; + + ids_core_profiles.profiles_1d{it}.electrons.pressure_thermal = 1.6022e-19.*ids_core_profiles.profiles_1d{it}.electrons.density_thermal ... .* ids_core_profiles.profiles_1d{it}.electrons.temperature; % fill zeff @@ -220,6 +267,7 @@ for it=1:length(ids_core_profiles.time) ones(size(ids_core_profiles.profiles_1d{it}.electrons.density)); end +if imas_major_version > 2 zeff_error = 0.5; switch error_bar case 'delta' @@ -261,6 +309,7 @@ switch error_bar otherwise error(['tcv_ids_bpol_loop: error_bar option not known: ' error_bar]) end +end %% ion struct % assume only D if no CXRS (need to ask how to check if H...) @@ -290,10 +339,12 @@ else end % Extract ti here +all_sources = [1,2,3,4,7]; + if isfield(gdat_params, 'cxrs_source_ti') params_eff_fit1.source = gdat_params.cxrs_source_ti; else - params_eff_fit1.source = [1,2,3]; + params_eff_fit1.source = all_sources; end try @@ -334,7 +385,7 @@ params_eff_fit1.data_request = 'cxrs'; if isfield(gdat_params, 'cxrs_source_ni') params_eff_fit1.source = gdat_params.cxrs_source_ni; else - params_eff_fit1.source = [1,2,3]; + params_eff_fit1.source = all_sources; end try @@ -346,6 +397,48 @@ catch temp_1d_desc.cxrs_rho = ['Problem with gdat ' params_eff_fit1.data_request ' ; no data']; end +% Extract sources to find integration time for each data +mask_sources = zeros(size(temp_1d.cxrs_rho.ti.raw.data)); + +% Retrive the source for each datapoint +for isource = all_sources + try + params_eff_fit1.source = [isource]; + temp_1d.cxrs_rho_partial = gdat(params_cores_profiles.shot,params_eff_fit1); + [isCommon, idxA] = ismember(temp_1d.cxrs_rho.ti.raw.data, temp_1d.cxrs_rho_partial.ti.raw.data); + isCommon = isource*isCommon; + mask_sources(isCommon ~= 0) = isCommon(isCommon ~= 0); + end +end + +% Find the times for cxrs integration for the various cxrs systems +system_ref = '\\ATLAS::CXRS_%03d.ACQ:TIMING'; %or '\tcv_shot::top.atlas.acquired.cxrs.system_001.acq:timing' +times_cxrs_integration = []; +for ii = 1:12 + system_names = sprintf(system_ref, ii); + warning('off'); + timings_cxrs = gdat(params_cores_profiles.shot,system_names); + warning('off'); + if timings_cxrs.data + period_name = regexp(timings_cxrs.data, 'PeriodName=''([^'']*)''', 'tokens', 'once'); + bursts_name = regexp(timings_cxrs.data, 'BurstsName=''([^'']*)''', 'tokens', 'once'); + + %period = gdat(params_cores_profiles.shot, period_name); + %bursts = gdat(params_cores_profiles.shot, bursts_name); + %time_aquisition = period.data * bursts.data; %This is the total acquisition time in a shot. + time_acquisition = gdat(params_cores_profiles.shot, period_name); + times_cxrs_integration = [times_cxrs_integration,time_acquisition.data.*1e-6]; + else + times_cxrs_integration = [times_cxrs_integration,0]; + end +end + +% Assign widths of integration time +widths = zeros(size(temp_1d.cxrs_rho.ti.raw.data)); +for isource = all_sources + widths(mask_sources == isource) = times_cxrs_integration(isource); +end + params_eff_fit1.data_request = 'results.conf:ni'; temp_1d.ni_conf_rho = gdat(params_cores_profiles.shot,params_eff_fit1); temp_1d_desc.ni_conf_rho = [params_eff_fit1.data_request, ' which took data from ', temp_1d.ni_conf_rho.help]; @@ -423,48 +516,27 @@ if ~isempty(temp_1d.cxrs_rho.data) && ~isempty(temp_1d.cxrs_rho.ti.fit.data) for it=1:length(ids_core_profiles.time) ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit.measured = temp_1d.ti.raw.data(:,it_raw(it)); ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit.source = temp_1d_desc.ti.tot; - temp_1d_desc.ti.tot - return ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.measured = temp_1d.ni.raw.data(:,it_raw(it)); ids_core_profiles.profiles_1d{it}.ion{2}.density_fit.source = temp_1d_desc.ni.tot; + ids_core_profiles.profiles_1d{it}.ion{2}.rho_tor_norm = temp_1d.cxrs_rho.ti.raw.rho(:,it_raw(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.time_measurement = temp_1d.ti.raw.t(it_raw(it)); + ids_core_profiles.profiles_1d{it}.ion{2}.time_measurement_slice_method.name = 'local'; + ids_core_profiles.profiles_1d{it}.ion{2}.time_measurement_slice_method.index = 0; + ids_core_profiles.profiles_1d{it}.ion{2}.time_measurement_slice_method.description = 'Using cxrs at given time'; + ids_core_profiles.profiles_1d{it}.ion{2}.time_measurement_width = widths(:,it_raw(it)); ids_core_profiles.profiles_1d{it}.ion{1}.temperature_fit = ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit; ids_core_profiles.profiles_1d{it}.ion{1}.density_fit.source = {'Same as C temperature'}; ids_core_profiles.profiles_1d{it}.t_i_average_fit.measured = ids_core_profiles.profiles_1d{it}.ion{2}.temperature_fit; ids_core_profiles.profiles_1d{it}.t_i_average_fit.source = {'Same as C temperature'}; + ids_core_profiles.profiles_1d{it}.t_i_average_fit.rho_tor_norm = ids_core_profiles.profiles_1d{it}.ion{2}.rho_tor_norm; + ids_core_profiles.profiles_1d{it}.t_i_average_fit.time_measurement = ids_core_profiles.profiles_1d{it}.ion{2}.time_measurement; + end end - -%time_measurement_slice_method -%time_measurement_slice_method.name='exact' or 'local' -%time_measurement_slice_method.index=0 -%time_measurement_slice_method.description='using Thomson scattering measurement at the given time' -%time_measurement_width - -%time_measurement_slice_method -%time_measurement_slice_method.name='exact' or 'local' -%time_measurement_slice_method.index=0 -%time_measurement_slice_method.description='using Thomson scattering measurement at the given time' -%local = 1 -%chi_squared = \tcv_shot::top.results.proffit.avg_time:teft_chi2 - -%time_measurement_width(:) = gdat(84927,'\tcv_shot::top.results.proffit.avg_time:time_avg','doplot',1); % nargout = 1 - - -% I am guessing that in gdat params_eff.fit_type = 'avg' takes the data from the avg_time and not local_time proffit nodes? -%name='exact' or 'local' -%index=0 -%description='using Thomson scattering measurement at the given time' -%(if only one TS laser time was used ) -%or may be: -%name='avg' or 'average' -%index=-1 -%description='average with TS at this time and other TS within +-delta_t' (delta_t is provided in the proffit:local tree), conf should know if nodes from local or avg - - -if ~isempty(temp_1d.cxrs_rho.error_bar) +if ~isempty(temp_1d.cxrs_rho.error_bar) && imas_major_version > 2 switch error_bar case 'delta' for it=1:length(ids_core_profiles.time) @@ -526,15 +598,6 @@ if ~isempty(temp_1d.cxrs_rho.error_bar) end -%For the time integration of the Charge Exchange -%timer_nodes = String2Struct(mdsdata('\ATLAS::CXRS_00X.ACQ:TIMING')); -%mdsdata(timer_nodes.PeriodName) - - - - - - %% q profile and magnetic shear params_eff.data_request = 'q_rho'; temp_1d.q = gdat(params_cores_profiles.shot,params_eff); -- GitLab From aaef687ec13915ceae05b1135916c0030735cb33 Mon Sep 17 00:00:00 2001 From: Michele Marin <michele.marin@epfl.ch> Date: Fri, 23 May 2025 13:37:19 +0200 Subject: [PATCH 10/11] Do not check for disruption for planned shot --- matlab/TCV_IMAS/tcv2ids.m | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/matlab/TCV_IMAS/tcv2ids.m b/matlab/TCV_IMAS/tcv2ids.m index b06f247a..0737d094 100644 --- a/matlab/TCV_IMAS/tcv2ids.m +++ b/matlab/TCV_IMAS/tcv2ids.m @@ -126,9 +126,11 @@ end gdat_params.data_request = 'ids'; %Check that the shot did not disrupt very early. -t_disrupted = gdat(shot,'time_disrupted()'); -if t_disrupted.data <= 0.04 | t_disrupted.data > 128 - error('the shot disrupted') +if shot != -1 + t_disrupted = gdat(shot,'time_disrupted()'); + if t_disrupted.data <= 0.04 | t_disrupted.data > 128 + error('the shot disrupted') + end end for i=1:length(params_tcv2ids.ids_names) -- GitLab From 12b5147dfa1749a2de17165b31ae11ae78c100c4 Mon Sep 17 00:00:00 2001 From: Michele Marin <michele.marin@epfl.ch> Date: Fri, 23 May 2025 14:06:29 +0200 Subject: [PATCH 11/11] minor bugfix on previous commit --- matlab/TCV_IMAS/tcv2ids.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matlab/TCV_IMAS/tcv2ids.m b/matlab/TCV_IMAS/tcv2ids.m index 0737d094..c94bea2b 100644 --- a/matlab/TCV_IMAS/tcv2ids.m +++ b/matlab/TCV_IMAS/tcv2ids.m @@ -126,9 +126,9 @@ end gdat_params.data_request = 'ids'; %Check that the shot did not disrupt very early. -if shot != -1 +if shot ~= -1 t_disrupted = gdat(shot,'time_disrupted()'); - if t_disrupted.data <= 0.04 | t_disrupted.data > 128 + if t_disrupted.data <= 0.04 || t_disrupted.data > 128 error('the shot disrupted') end end -- GitLab