diff --git a/matlab/TCV/gdat_tcv.m b/matlab/TCV/gdat_tcv.m index b9ae1b6f5655f1938d46419175b47b6811d08148..17fc6996771adc33d57106bfa80a8d9dc7588db4 100644 --- a/matlab/TCV/gdat_tcv.m +++ b/matlab/TCV/gdat_tcv.m @@ -1939,11 +1939,11 @@ elseif strcmp(mapping_for_tcv.method,'switchcase') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% case {'ne','te'} % ne or Te from Thomson data on raw z mesh vs (z,t) - if ~(isfield(gdat_data.gdat_params,'edge') && ~isempty(gdat_data.gdat_params.edge) && ... - gdat_data.gdat_params.edge>0) - gdat_data.gdat_params.edge = 0; + if ~(isfield(gdat_data.gdat_params,'systems') && ~isempty(gdat_data.gdat_params.systems) && ... + all(ismember(gdat_data.gdat_params.systems,{'all','main','edge'}))) + gdat_data.gdat_params.systems = {'all'}; end - [gdat_data] = get_thomson_raw_data(shot,data_request_eff,gdat_data,gdat_data.gdat_params.edge,gdat_params.nverbose); + [gdat_data] = get_thomson_raw_data(shot,data_request_eff,gdat_data,gdat_data.gdat_params.systems,gdat_params.nverbose); if isfield(gdat_data.gdat_params,'time_out') && ~isempty(gdat_data.gdat_params.time_out) [gdat_data] = gdat2time_out(gdat_data,1,{'error_bar'}); end @@ -1957,33 +1957,31 @@ elseif strcmp(mapping_for_tcv.method,'switchcase') else gdat_data.gdat_params.zshift = zshift; end - if ~(isfield(gdat_data.gdat_params,'edge') && ~isempty(gdat_data.gdat_params.edge) && ... - gdat_data.gdat_params.edge>0) - gdat_data.gdat_params.edge = 0; + if ~(isfield(gdat_data.gdat_params,'systems') && ~isempty(gdat_data.gdat_params.systems) && ... + all(ismember(gdat_data.gdat_params.systems,{'all','main','edge'}))) + gdat_data.gdat_params.systems = {'all'}; end - [gdat_data] = get_thomson_raw_data(shot,data_request_eff,gdat_data,gdat_data.gdat_params.edge,gdat_params.nverbose); + [gdat_data] = get_thomson_raw_data(shot,data_request_eff,gdat_data,gdat_data.gdat_params.systems,gdat_params.nverbose); % construct rho mesh - edge_str_dot = ''; - if gdat_data.gdat_params.edge - edge_str_dot = '.edge'; - end - if liuqe_matlab==1 && strcmp(substr_liuqe,'_1'); substr_liuqe = ''; end % psiscatvol obtained from linear interpolation in fact so not quite ok near axis where psi is quadratic % NOTE: Since 2019 psi_scatvol uses psitbx with cubic-spline interpolation, unsure what shots have new data or not ... recompute_psiscatvol_always = 1; if liuqe_version==-1; recompute_psiscatvol_always = 1; end % NOTE: Since oct.2019 psi_scatvol stored in nodes now uses LIUQE.M (shot range to check if any ...) if all(abs(zshift)<1e-5) && liuqe_matlab==0 && recompute_psiscatvol_always==0 - psi_max=gdat_tcv([],['\results::thomson' edge_str_dot ':psi_max' substr_liuqe],'nverbose',gdat_params.nverbose); - psiscatvol=gdat_tcv([],['\results::thomson' edge_str_dot ':psiscatvol' substr_liuqe],'nverbose',gdat_params.nverbose); + if strcmp(substr_liuqe,'_1'); substr_liuqe = ''; end + [psiscatvol,psi_max] = get_thomson_psiscatvol(shot,gdat_data.gdat_params.systems,substr_liuqe,gdat_params.nverbose); + % NOTE: time and Z are switched here (same as previous state) and + % code is not reachable anyway) ... waiting for a fix else % calculate new psiscatvol [psiscatvol,psi_max] = psi_scatvol_zshift(gdat_data, zshift, psitbx_str, gdat_params); - - % Add the results to the output of gdat - gdat_data.psiscatvol = psiscatvol; - gdat_data.psi_max = psi_max; end + + % Add the results to the output of gdat + gdat_data.psiscatvol = psiscatvol; + gdat_data.psi_max = psi_max; + if ~isempty(psiscatvol.data) && ~ischar(psiscatvol.data) && ~isempty(psi_max.data) && ~ischar(psi_max.data) psi_norm = 1.-psiscatvol.data./repmat(psi_max.data(:).',[size(psiscatvol.data,1),1]); mask = psi_norm < 0; @@ -2018,15 +2016,12 @@ elseif strcmp(mapping_for_tcv.method,'switchcase') gdat_data.ne.units = 'm^{-3}'; gdat_data = rmfield(gdat_data,{'firrat','data_raw','error_bar_raw'}); % - nodenameeff=['\results::thomson' edge_str_dot ':te']; - tracetdi=tdi(nodenameeff); - nodenameeff=['\results::thomson' edge_str_dot ':te; error_bar']; - tracestd=tdi(['\results::thomson' edge_str_dot ':te:error_bar']); - gdat_data.te.data=tracetdi.data'; - gdat_data.te.error_bar=tracestd.data'; - gdat_data.te.units = tracetdi.units; - gdat_data.data_fullpath=['pe=1.6e-19*ne*Te in data, .ne, .te from \results::thomson' ... - edge_str_dot ':ne and te and projected on rhopol\_norm']; + te = get_thomson_raw_data(shot,'te',gdat_data,gdat_data.gdat_params.systems,gdat_params.nverbose); + gdat_data.te.data=te.data; + gdat_data.te.error_bar=te.error_bar; + gdat_data.te.units = te.units; + gdat_data.data_fullpath=['pe=1.6e-19*ne*Te in data, .ne, .te from \results::thomson for systems (' ... + strjoin(gdat_data.gdat_params.systems,'/') ') and projected on rhopol\_norm']; gdat_data.units='N/m^2; 1.6022e-19 ne Te'; gdat_data.data = 1.6022e-19 .* gdat_data.ne.data .* gdat_data.te.data; gdat_data.error_bar = 1.6022e-19 .* (gdat_data.ne.data .* gdat_data.te.error_bar ... @@ -2075,7 +2070,7 @@ elseif strcmp(mapping_for_tcv.method,'switchcase') def_rhotornorm = '\results::conf:rhotor'; def_rhovolnorm = '\results::conf:rhovol'; otherwise - if (gdat_params.nverbose>=1); + if (gdat_params.nverbose>=1) disp('should not be in switch gdat_data.gdat_params.fit_type') disp('ask olivier.sauter@epfl.ch') end @@ -2089,7 +2084,7 @@ elseif strcmp(mapping_for_tcv.method,'switchcase') elseif strcmp(data_request_eff(1:2),'te') nodenameeff = [def_proffit 'teft']; else - if (gdat_params.nverbose>=1); + if (gdat_params.nverbose>=1) disp(['should not be here: data_request_eff, data_request_eff(1:2)= ',data_request_eff, data_request_eff(1:2)]); end end @@ -2504,7 +2499,6 @@ elseif strcmp(mapping_for_tcv.method,'switchcase') % add extra fields then correct [gdat_data] = gdat2time_out(gdat_data,21); end - case {'phi_tor', 'phitor', 'toroidal_flux'} % Phi(LCFS) = int(Bphi dSphi), can use Eq.(11) of "Tokamak coordinate conventions: COCOS" paper: % O. Sauter, S.Yu. Medvedev, Comput. Phys. Commun. 184 (2013) 293–302 @@ -2633,7 +2627,6 @@ elseif strcmp(mapping_for_tcv.method,'switchcase') if isfield(gdat_data.gdat_params,'time_out') && ~isempty(gdat_data.gdat_params.time_out) [gdat_data] = gdat2time_out(gdat_data,1); end - case {'pressure', 'pressure_rho', 'p_rho'} if liuqe_matlab==0 nodenameeff = ['tcv_eq("' liuqefortran2liuqematlab('p_rho',1,0) '",''' psitbx_str ''')']; @@ -3435,7 +3428,7 @@ if ~isempty(tracefirrat.data) && ~ischar(tracefirrat.data) && any(isfinite(trace end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -function [gdat_data] = get_thomson_raw_data(shot,data_request_eff,gdat_data,doedge,nverbose); +function [gdat_data] = get_thomson_raw_data(shot,data_request_eff,gdat_data,systems,nverbose) % try time=mdsdata('\results::thomson:times'); @@ -3455,57 +3448,149 @@ catch return end if isempty(time) || ischar(time) - thomsontimes=time; if (nverbose>=1) && shot<100000 warning('!!!!!!!!!!!!!!!!!!!!!!!!!\results::thomson:times is empty? Check') disp(['!!!!!!!!!!!!!!!!!!!!!!!!! cannot continue with ' data_request_eff]) end return end -edge_str = ''; -if doedge - edge_str = '.edge'; + +systems = cellstr(systems); +if numel(systems) == 1 && strcmpi(systems{1},'all') + if shot > 24381 && shot < 49896, systems = {'main','edge'}; + else, systems = {'main'}; + end end +nsys = numel(systems); +data_tmp = repmat(struct,nsys,1); +status = false(nsys,1); + +for is = 1:nsys + switch lower(systems{is}) + case 'main' + edge_str = ''; + case 'edge' + edge_str = '.edge'; + otherwise + warning('Unrecognised thomson scattering system name: %s',systems{is}); + disp(['!!!!!!!!!!!!!!!!!!!!!!!!! cannot continue with ' data_request_eff]) + return + end + + nodenameeff = ['\results::thomson' edge_str ':' data_request_eff(1:2)]; + tracetdi=tdi(nodenameeff); + if isempty(tracetdi.data) || ischar(tracetdi.data) || isempty(tracetdi.dim) + data_tmp(is).data = []; + data_tmp(is).error_bar = []; + data_tmp(is).data_fullpath = ''; + data_tmp(is).dim = {[],[]}; + continue + end + + data_tmp(is).data=tracetdi.data.'; % Thomson data as (t,z) + tracestd=tdi(['\results::thomson' edge_str ':' data_request_eff(1:2) ':error_bar']); + data_tmp(is).error_bar=tracestd.data'; + data_tmp(is).data_fullpath=nodenameeff; + z=mdsdata(['\diagz::thomson_set_up' edge_str ':vertical_pos']); + data_tmp(is).dim={z,time}; + data_tmp(is).units=tracetdi.units; + data_tmp(is).system=repmat({lower(systems{is})},numel(z),1); + status(is) = true; -nodenameeff = ['\results::thomson' edge_str ':' data_request_eff(1:2)]; -tracetdi=tdi(nodenameeff); -if isempty(tracetdi.data) || ischar(tracetdi.data) || isempty(tracetdi.dim) - gdat_data.error_bar = []; - gdat_data.firrat = []; - gdat_data.data_raw = []; - gdat_data.error_bar_raw = []; - return end -gdat_data.data=tracetdi.data'; % Thomson data as (t,z) -tracestd=tdi(['\results::thomson' edge_str ':' data_request_eff(1:2) ':error_bar']); -gdat_data.error_bar=tracestd.data'; -gdat_data.data_fullpath=[nodenameeff '; error_bar']; -% add fir if ne requested +% One system with good data +status_any = any(status); +isys_ref = find(status,1,'first'); + +gdat_data.data = vertcat(data_tmp.data); +gdat_data.error_bar = vertcat(data_tmp.error_bar); +if status_any,gdat_data.data_fullpath = [strjoin({data_tmp(status).data_fullpath},'; '),'; error_bar'];end +z = arrayfun(@(x) x.dim{1}, data_tmp, 'UniformOutput', false); +gdat_data.dim = {vertcat(z{:}),time}; +gdat_data.dimunits = {'Z [m]' ; 'time [s]'}; +gdat_data.x = gdat_data.dim{1}; +gdat_data.t = time; +gdat_data.system=vertcat(data_tmp.system); +if status_any,gdat_data.units = data_tmp(isys_ref).units;end + +% add fir if ne requested +% NOTE: not a system dependent value so far. Only the main fir ratio was ever stored if strcmp(data_request_eff(1:2),'ne') tracefirrat_data = get_fir_thom_rat_data(shot,time,nverbose); gdat_data.firrat=tracefirrat_data; gdat_data.data_raw = gdat_data.data; - gdat_data.data = gdat_data.data_raw * diag(tracefirrat_data); gdat_data.error_bar_raw = gdat_data.error_bar; - gdat_data.error_bar = gdat_data.error_bar_raw * diag(tracefirrat_data); + if status_any + gdat_data.data = gdat_data.data_raw * diag(tracefirrat_data); + gdat_data.error_bar = gdat_data.error_bar_raw * diag(tracefirrat_data); + end gdat_data.data_fullpath=[gdat_data.data_fullpath '; fir_thom_rat ; _raw without firrat']; - ij=find(isfinite(tracefirrat_data)); - if isempty(ij) + if ~any(isfinite(tracefirrat_data)) gdat_data.data_fullpath=[gdat_data.data_fullpath ' WARNING use ne_raw since firrat has NaNs thus ne=NaNs; fir_thom_rat ; _raw without firrat']; disp('***********************************************************************') disp('WARNING: ne from Thomson has fir_thom_rat with Nans so only ne_raw can be used'); disp('***********************************************************************') end end -z=mdsdata(['\diagz::thomson_set_up' edge_str_dot ':vertical_pos']); -gdat_data.dim=[{z};{time}]; -gdat_data.dimunits=[{'Z [m]'} ; {'time [s]'}]; -gdat_data.x=z; -gdat_data.t=time; -% isfield does not work since tracetdi is not a 'struct' but a tdi object, thus use fieldnames -if any(strcmp(fieldnames(tracetdi),'units')) - gdat_data.units=tracetdi.units; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [psiscatvol,psi_max] = get_thomson_psiscatvol(shot,systems,substr_liuqe,nverbose) +% Subfunction to join multiple systems if needed +% +systems = cellstr(systems); +if numel(systems) == 1 && strcmpi(systems{1},'all') + if shot > 24381 && shot < 49896, systems = {'main','edge'}; + else, systems = {'main'}; + end +end +nsys = numel(systems); +[psi_max_,psiscatvol_] = deal(cell(nsys,1)); +status = false(nsys,1); + +validdata = @(x) ~isempty(x.data) & ~ischar(x.data) & ~isempty(x.dim); + +for is = 1:nsys + switch lower(systems{is}) + case 'main' + edge_str = ''; + case 'edge' + edge_str = '.edge'; + otherwise + warning('Unrecognised thomson scattering system name: %s',systems{is}); + disp(['!!!!!!!!!!!!!!!!!!!!!!!!! cannot continue with ' data_request_eff]) + return + end + + psi_max_{is} =gdat_tcv([],['\results::thomson',edge_str,':psi_max' substr_liuqe],'nverbose',nverbose); + psiscatvol_{is}=gdat_tcv([],['\results::thomson',edge_str,':psiscatvol' substr_liuqe],'nverbose',nverbose); + + status(is) = validdata(psi_max_{is}) & validdata(psiscatvol_{is}); +end + +% Systems with good data +nsysv = sum(status); + +if nsysv == 0 + psi_max = psi_max_{1}; + psiscatvol = psiscatvol_{1}; +else + % Select and concatenate + psi_max_v = [psi_max_{status}]; + psiscatvol_v = [psiscatvol_{status}]; + + psi_max = psi_max_v(1); + psi_max.data = horzcat(psi_max_v.data); + psi_max.data_fullpath = strjoin({psi_max_v.data_fullpath},'; '); + psi_max.label = strjoin({psi_max_v.data_fullpath},'; '); + + psiscatvol = psiscatvol_v(1); + psiscatvol.data = horzcat(psiscatvol_v.data); + z = arrayfun(@(x) x.dim{2}, psiscatvol_v, 'UniformOutput', false); + psiscatvol.dim{2} = vertcat(z{:}); + psiscatvol.t = psiscatvol.dim{2}; %TODO: Time and space are inverted for now + psiscatvol.data_fullpath = strjoin({psiscatvol_v.data_fullpath},'; '); + psiscatvol.label = strjoin({psiscatvol_v.data_fullpath},'; '); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%