diff --git a/matlab/TCV/gdat_tcv.m b/matlab/TCV/gdat_tcv.m
index 4b443b3bb37f3f3fb908e8d7b9fad714eae9d104..8ce621c5708f9a2b75df0b45afb5920ee67795b5 100644
--- a/matlab/TCV/gdat_tcv.m
+++ b/matlab/TCV/gdat_tcv.m
@@ -1639,7 +1639,7 @@ elseif strcmp(mapping_for_tcv.method,'switchcase')
 
           % power deposition related:
           ec_data.p_abs_plasma.data = pabs_gyro.data * 1e6;
-          ec_data.p_abs_plasma.data(end+1,:) = sum(ec_data.p_abs_plasma.data,1,'omitnan');
+          ec_data.p_abs_plasma.data(end+1,:) = sum(ec_data.p_abs_plasma.data,1,'omitnan');  % add total
           ec_data.p_abs_plasma.label = [strrep(pabs_gyro.comment,'MW','W') ' ; last index is total'];
           ec_data.p_abs_plasma.units = 'W';
           ec_data.p_abs_plasma.x = launchers_grid;
@@ -1648,21 +1648,21 @@ elseif strcmp(mapping_for_tcv.method,'switchcase')
           ec_data.p_abs_plasma.dimunits = {launchers_label, 's'};
           %
           ec_data.p_dens.data = pow_dens.data * 1e6;
-          ec_data.p_dens.data(:,end+1,:) = sum(ec_data.p_dens.data,2,'omitnan');
+          ec_data.p_dens.data(:,end+1,:) = sum(ec_data.p_dens.data,2,'omitnan'); % add total
           ec_data.p_dens.label = [strrep(pow_dens.comment,'MW','W') ' ; last index is total'];
           ec_data.p_dens.units = 'W/m^3';
-          ec_data.p_dens.x = pow_dens.rgrid';
-          ec_data.p_dens.rhotor_norm = ec_data.p_dens.x;
+          ec_data.p_dens.x = pow_dens.rgrid;
+          ec_data.p_dens.grids = pow_dens.grids;
           ec_data.p_dens.t = pow_dens.tgrid;
           ec_data.p_dens.dim = {ec_data.p_dens.x, launchers_grid, ec_data.p_dens.t};
           ec_data.p_dens.dimunits = {'rhotor_norm', launchers_label, 's'};
           %
           ec_data.p_integrated.data = power_integrated.data * 1e6;
-          ec_data.p_integrated.data(:,end+1,:) = sum(ec_data.p_integrated.data,2,'omitnan');
+          ec_data.p_integrated.data(:,end+1,:) = sum(ec_data.p_integrated.data,2,'omitnan');  % add total
           ec_data.p_integrated.label = [strrep(power_integrated.comment,'MW','W') ' ; last index is total'];
           ec_data.p_integrated.units = 'W';
-          ec_data.p_integrated.x = power_integrated.rgrid';
-          ec_data.p_integrated.rhotor_norm = ec_data.p_integrated.x;
+          ec_data.p_integrated.x = power_integrated.rgrid;
+          ec_data.p_integrated.grids = power_integrated.grids;
           ec_data.p_integrated.t = power_integrated.tgrid;
           ec_data.p_integrated.dim = {ec_data.p_integrated.x, launchers_grid, ec_data.p_integrated.t};
           ec_data.p_integrated.dimunits = {'rhotor_norm', launchers_label, 's'};
@@ -1693,7 +1693,7 @@ elseif strcmp(mapping_for_tcv.method,'switchcase')
 
           % current drive deposition related:
           ec_data.cd_tot.data = icdtot.data * 1e6;
-          ec_data.cd_tot.data(end+1,:) = sum(ec_data.cd_tot.data,1,'omitnan');
+          ec_data.cd_tot.data(end+1,:) = sum(ec_data.cd_tot.data,1,'omitnan'); % add total
           ec_data.cd_tot.label = [strrep(icdtot.comment,'MA','A') ' ; last index is total'];
           ec_data.cd_tot.units = 'A';
           ec_data.cd_tot.x = launchers_grid;
@@ -1702,28 +1702,28 @@ elseif strcmp(mapping_for_tcv.method,'switchcase')
           ec_data.cd_tot.dimunits = {launchers_label, 's'};
           %
           ec_data.cd_dens.data = currentdrive_dens.data * 1e6;
-          ec_data.cd_dens.data(:,end+1,:) = sum(ec_data.cd_dens.data,2,'omitnan');
+          ec_data.cd_dens.data(:,end+1,:) = sum(ec_data.cd_dens.data,2,'omitnan');  % add total
           ec_data.cd_dens.label = [strrep(currentdrive_dens.comment,'MA','A') ' ; last index is total'];
-          ec_data.cd_dens.units = 'A/m^2';
-          ec_data.cd_dens.x = currentdrive_dens.rgrid';
-          ec_data.cd_dens.rhotor_norm = ec_data.cd_dens.x;
+          ec_data.cd_dens.units = 'A/m^3';
+          ec_data.cd_dens.x = currentdrive_dens.rgrid;
+          ec_data.cd_dens.grids = currentdrive_dens.grids;
           ec_data.cd_dens.t = currentdrive_dens.tgrid;
           ec_data.cd_dens.dim = {ec_data.cd_dens.x, launchers_grid, ec_data.cd_dens.t};
           ec_data.cd_dens.dimunits = {'rhotor_norm', launchers_label, 's'};
           %
           ec_data.cd_integrated.data = currentdrive_integrated.data * 1e6;
-          ec_data.cd_integrated.data(:,end+1,:) = sum(ec_data.cd_integrated.data,2,'omitnan');
+          ec_data.cd_integrated.data(:,end+1,:) = sum(ec_data.cd_integrated.data,2,'omitnan'); % add total
           ec_data.cd_integrated.label = [strrep(currentdrive_integrated.comment,'MA','A') ' ; last index is total'];
           ec_data.cd_integrated.units = 'A';
-          ec_data.cd_integrated.x = currentdrive_integrated.rgrid';
-          ec_data.cd_integrated.rhotor_norm = ec_data.cd_integrated.x;
+          ec_data.cd_integrated.x = currentdrive_integrated.rgrid;
+          ec_data.cd_integrated.grids = currentdrive_integrated.grids;
           ec_data.cd_integrated.t = currentdrive_integrated.tgrid;
           ec_data.cd_integrated.dim = {ec_data.cd_integrated.x, launchers_grid, ec_data.cd_integrated.t};
           ec_data.cd_integrated.dimunits = {'rhotor_norm', launchers_label, 's'};
           %
           ec_data.max_cd_dens.data = icdmax.data * 1e6;
           ec_data.max_cd_dens.label = strrep(icdmax.comment,'MA','A');
-          ec_data.max_cd_dens.units = 'A/m^2';
+          ec_data.max_cd_dens.units = 'A/m^3';
           ec_data.max_cd_dens.x = [];
           ec_data.max_cd_dens.t = icdmax.tgrid;
           ec_data.max_cd_dens.dim = {ec_data.max_cd_dens.t};
@@ -1746,8 +1746,9 @@ elseif strcmp(mapping_for_tcv.method,'switchcase')
           ec_data.width_cd_dens.dimunits = {'s'};
           %
           ec_data.cd_dens_doublewidth.data = currentdrive_dens_w2.data * 1e6;
+          ec_data.cd_dens_doublewidth.data(:,end+1,:) = sum(ec_data.cd_dens_doublewidth.data,2,'omitnan');  % add total
           ec_data.cd_dens_doublewidth.label = [strrep(currentdrive_dens_w2.comment,'MA','A') ' ; last index is total'];
-          for subfields={'x','rhotor_norm','t','dim','dimunits','units'}
+          for subfields={'x','grids','t','dim','dimunits','units'}
             ec_data.cd_dens_doublewidth.(subfields{1}) = ec_data.cd_dens.(subfields{1});
           end
 
@@ -1755,7 +1756,6 @@ elseif strcmp(mapping_for_tcv.method,'switchcase')
           filled_successfully = true; %set flag to true
         catch ME
           warning('Problem retrieving TORAY data. \nError message: %s',ME.message);
-          getReport(ME) % without ; to get output
           % try to identify cause of the error
           if ~check_nodes_filled(shot,'toray')
             if ~isempty(ec_inputs.launchers_active)
@@ -1764,6 +1764,8 @@ elseif strcmp(mapping_for_tcv.method,'switchcase')
               else
                 msg = 'write_pyro(shot) found active launchers, but TORAY nodes are not filled, check hldsi(shot), and (ask to) relaunch TORAY.';
               end
+            else
+              msg = 'Run gdat(shot,''ec_data'',''ec_inputs'',1) to check whether there were active launchers in this shot or not.';
             end
           elseif ~isempty(gdat_data.gdat_params.trialindx)
             msg = 'Is the trial index filled? Check TORAY nodes with hdlsi(shot).';
@@ -1866,7 +1868,7 @@ elseif strcmp(mapping_for_tcv.method,'switchcase')
       data_fullpath = '';
       ohm_help = '';
       if strcmp(lower(source_icd.ohm),'ibs')
-        ohm_data.cd_tot = gdat_tcv(shot,'\results::ibs:iohm');
+        ohm_data.cd_tot = gdat_tcv(shot,'\results::ibs:iohm','trialindx',gdat_params.trialindx);
         if gdat_data.mapping_for.tcv.gdat_timedim ==2
           tgrid_to_change = {'ohm_data.cd_tot.t','ohm_data.cd_tot.dim{1}'};
           for i=1:length(tgrid_to_change)
@@ -1875,7 +1877,7 @@ elseif strcmp(mapping_for_tcv.method,'switchcase')
         end
         ohm_data.cd_tot.data = ohm_data.cd_tot.data';
         ohm_data.cd_tot.units = strrep(ohm_data.cd_tot.units,'kA','A');
-        ohm_data.cd_dens = gdat_tcv(shot,'\results::ibs:johmav'); % =jtild=<j.B> / R0 / <Bphi/R>, with Bphi=F(psi)/R
+        ohm_data.cd_dens = gdat_tcv(shot,'\results::ibs:johmav','trialindx',gdat_params.trialindx); % =jtild=<j.B> / R0 / <Bphi/R>, with Bphi=F(psi)/R
         if gdat_data.mapping_for.tcv.gdat_timedim ==2
           tgrid_to_change = {'ohm_data.cd_dens.t','ohm_data.cd_dens.dim{2}'};
           for i=1:length(tgrid_to_change)
@@ -1913,7 +1915,7 @@ elseif strcmp(mapping_for_tcv.method,'switchcase')
       data_fullpath = '';
       bs_help = '';
       if strcmp(lower(source_icd.bs),'ibs')
-        bs_data.cd_tot = gdat_tcv(shot,'\results::ibs:ibs');
+        bs_data.cd_tot = gdat_tcv(shot,'\results::ibs:ibs','trialindx',gdat_params.trialindx);
         if gdat_data.mapping_for.tcv.gdat_timedim ==2
           tgrid_to_change = {'bs_data.cd_tot.t','bs_data.cd_tot.dim{1}'};
           for i=1:length(tgrid_to_change)
@@ -1922,7 +1924,7 @@ elseif strcmp(mapping_for_tcv.method,'switchcase')
         end
         bs_data.cd_tot.data = bs_data.cd_tot.data';
         bs_data.cd_tot.units = strrep(bs_data.cd_tot.units,'kA','A');
-        bs_data.cd_dens = gdat_tcv(shot,'\results::ibs:jbsav'); % =jtild=<j.B> / R0 / <Bphi/R>, with Bphi=F(psi)/R
+        bs_data.cd_dens = gdat_tcv(shot,'\results::ibs:jbsav','trialindx',gdat_params.trialindx); % =jtild=<j.B> / R0 / <Bphi/R>, with Bphi=F(psi)/R
         if gdat_data.mapping_for.tcv.gdat_timedim ==2
           tgrid_to_change = {'bs_data.cd_dens.t','bs_data.cd_dens.dim{2}'};
           for i=1:length(tgrid_to_change)
diff --git a/matlab/TCV/tcv_requests_mapping.m b/matlab/TCV/tcv_requests_mapping.m
index 04dcc1f5c8e483714b1882bb15b8e965bb07ed20..824348abb9c6997c13fe4206e93a67bdc80ab41f 100644
--- a/matlab/TCV/tcv_requests_mapping.m
+++ b/matlab/TCV/tcv_requests_mapping.m
@@ -473,6 +473,11 @@ switch lower(data_request)
                     'bb=interpos(aa.t,aa.data(ix,:),gdat_tmp.t,-100);' ...
                     'gdat_tmp.data = 4e-7*pi.*gdat_tmp.data.^2.*bb./1.22; gdat_tmp.label=''\tau_R'';gdat_tmp.gdat_request=''tau_r'';' ...
                     'gdat_tmp.units=''s'';gdat_tmp.help=''tauR=mu0 a^2 / 1.22 etaneo(rhopol=0.4)'''];
+ case 'tau_tot'
+  mapping.timedim = 1;
+  mapping.label = 'total energy confinment time';
+  mapping.method = 'tdi';
+  mapping.expression = '\results::conf:tau';
  case 'te'
   mapping.timedim = 2;
   mapping.label = 'Te';
diff --git a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m
index 2891e6dd8eb526d7740d301ba93a1edcc597bd27..a230c9351cf0fb4a1dadfbec902eb2903aed5d5f 100644
--- a/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m
+++ b/matlab/TCV_IMAS/tcv_get_ids_core_profiles.m
@@ -1,10 +1,12 @@
-function [ids_core_profiles,ids_core_profiles_description,varargout] = tcv_get_ids_core_profiles(shot,ids_equil_empty, gdat_params,varargin)
+function [ids_core_profiles,ids_core_profiles_description,varargout] = ...
+  tcv_get_ids_core_profiles(shot,ids_equil_empty,gdat_params,varargin)
 %
-%  [ids_core_profiles,ids_core_profiles_description,varargout] = tcv_get_ids_core_profiles(shot,ids_equil_empty,varargin);
+% [ids_core_profiles,ids_core_profiles_description,varargout] = ...
+%     tcv_get_ids_core_profiles(shot,ids_equil_empty,gdat_params,varargin);
 %
 %
-% gdat_params: gdat_data.gdat_params to get all params passed from original call, in particular error_bar options
-%
+% gdat_params: gdat_data.gdat_params to get all params passed from original call,
+%              in particular error_bar options
 %
 % error_bar: from gdat_params.error_bar
 %            'delta' (default): error_bar to be added inserted in "upper" only as mentioned in description
@@ -22,18 +24,22 @@ tens_time = -1;
 tens_rho = -0.1;
 
 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{:});
+  [ids_core_profiles, params_cores_profiles] = ...
+    tcv_ids_headpart(shot,ids_equil_empty,'cores_profiles','gdat_params',gdat_params,varargin{:});
 else
-  [ids_core_profiles, params_cores_profiles] = tcv_ids_headpart(shot,ids_equil_empty,'cores_profiles',varargin{:});
+  [ids_core_profiles, params_cores_profiles] = ...
+    tcv_ids_headpart(shot,ids_equil_empty,'cores_profiles',varargin{:});
   aa=gdat_tcv;
   gdat_params = aa.gdat_params; % to get default params
 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)
 
+% initialize description
 ids_core_profiles_description = [];
 
-% base all from times fro nete_rho (which should be conf by default)
+%% setup profiles_1d
+% base all from times for nete_rho (which should be conf by default)
 params_eff = params_eff_ref;
 params_eff.data_request='ne_rho'; params_eff.fit = 1;
 temp_1d.ne_rho = gdat(params_cores_profiles.shot,params_eff);
@@ -70,13 +76,11 @@ ids_core_profiles.profiles_1d{1}.ion{1}.state = {};
 ids_core_profiles.profiles_1d{1}.neutral{1}.state = {};
 ids_core_profiles.profiles_1d(1:length(ids_core_profiles.time)) = ids_core_profiles.profiles_1d(1);
 
-
 % As a general rule, for a new substructure under the main ids, construct a local structure like:
 % "global_quantities" with subfields being the relevant data to get and a local structure:
 % "global_quantities_desc" which contains the same subfields themselves containing the gdat string aftre shot used
-%
-% vacuum_toroidal_field and time, using homogeneous
-%
+
+%% vacuum_toroidal_field and time, using homogeneous
 params_eff = params_eff_ref;
 params_eff.data_request='b0';
 vacuum_toroidal_field.b0=gdat(params_cores_profiles.shot,params_eff);
@@ -85,7 +89,10 @@ ids_core_profiles.vacuum_toroidal_field.r0 = vacuum_toroidal_field.b0.r0;
 ids_core_profiles.vacuum_toroidal_field.b0 = interpos(63,vacuum_toroidal_field.b0.t,vacuum_toroidal_field.b0.data,ids_core_profiles.time,-1);
 ids_core_profiles_description.vacuum_toroidal_field = [vacuum_toroidal_field_desc.b0 ' on ids_core_profiles.time, with interpos(63)'];
 
-% global_quantities data into local global_quantities.* structure with correct end names and global_quantities_desc.* with description. Use temp.* and temp_desc.* structures for temporary data
+%% global_quantities
+% data into local global_quantities.* structure with correct end names and
+% global_quantities_desc.* with description.
+% Use temp.* and temp_desc.* structures for temporary data
 
 params_eff.data_request='ip';
 global_quantities.ip = gdat(params_cores_profiles.shot,'ip','machine',machine);
@@ -141,25 +148,20 @@ for i=1:length(global_quantities_fieldnames_eff)
     end
   end
 end
-% special case
-
 
-%
 %% profiles_1d (cannot use eqdsk since not same radial mesh)
+
+% prepare area for ids_core_profiles.profiles_1d{*}.grid.area
 params_eff.data_request = 'area_rho';
 temp_1d.area = gdat(params_cores_profiles.shot,params_eff);
 temp_1d_desc.area = params_eff.data_request;
-for ir=1:length(temp_1d.area.x)
+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
-params_eff.data_request = 'q_rho';
-temp_1d.q = gdat(params_cores_profiles.shot,params_eff);
-temp_1d_desc.q = params_eff.data_request;
-for ir=1:length(temp_1d.q.x)
-  q_cpt(ir,:) = interpos(temp_1d.q.t,temp_1d.q.data(ir,:),ids_core_profiles.time,tens_time);
-end
+
 it_thom = iround_os(temp_1d.te_rho.t,ids_core_profiles.time);
 for it=1:length(ids_core_profiles.time)
+  % fill grid
   ids_core_profiles.profiles_1d{it}.grid.rho_tor_norm = temp_1d.fit.te_rho.grids_1d.rhotornorm(:,it);
   ids_core_profiles.profiles_1d{it}.grid.rho_tor = temp_1d.fit.te_rho.grids_1d.rhotornorm(:,it) ...
       .* temp_1d.fit.te_rho.grids_1d.rhotor_edge(it);
@@ -171,7 +173,9 @@ for it=1:length(ids_core_profiles.time)
       .* temp_1d.fit.te_rho.grids_1d.volume_edge(it);
   ids_core_profiles.profiles_1d{it}.grid.area = interpos(temp_1d.area.x,area_cpt(:,it),temp_1d.fit.te_rho.grids_1d.rhopolnorm, ...
           tens_rho,[1 2],[0 area_cpt(end,it)]);
+  % fill time
   ids_core_profiles.profiles_1d{it}.time = ids_core_profiles.time(it);
+  % fill electrons struct
   ids_core_profiles.profiles_1d{it}.electrons.temperature = temp_1d.fit.te_rho.data(:,it);
   ids_core_profiles.profiles_1d{it}.electrons.temperature_fit.measured = temp_1d.te_rho.data(:,it_thom(it));
   ids_core_profiles.profiles_1d{it}.electrons.temperature_fit.time_measurement = temp_1d.te_rho.t(it_thom(it));
@@ -185,6 +189,7 @@ for it=1:length(ids_core_profiles.time)
   ids_core_profiles.profiles_1d{it}.electrons.density_fit.source = {'Thomson, interpos fit'};
   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
   ids_core_profiles.profiles_1d{it}.zeff = global_quantities.z_eff_resistive.data(it) .* ...
       ones(size(ids_core_profiles.profiles_1d{it}.electrons.density));
 end
@@ -231,7 +236,8 @@ switch error_bar
   error(['tcv_ids_bpol_loop: error_bar option not known: ' error_bar])
 end
 
-% ion, assume only D if no CXRS (need to ask how to check if H...)
+%% ion struct
+% assume only D if no CXRS (need to ask how to check if H...)
 params_eff_fit1.data_request = 'cxrs';
 temp_1d.cxrs_rho = gdat(params_cores_profiles.shot,params_eff_fit1);
 temp_1d_desc.cxrs_rho = params_eff_fit1.data_request;
@@ -316,9 +322,14 @@ if ~isempty(temp_1d.cxrs_rho.ti.fit.data)
   end
 end
 
-for ir=1:length(temp_1d.q.x)
+%% q profile and magnetic shear
+params_eff.data_request = 'q_rho';
+temp_1d.q = gdat(params_cores_profiles.shot,params_eff);
+temp_1d_desc.q = params_eff.data_request;
+for ir=1:length(temp_1d.q.x) % map tmp_1d.q to core_profiles.time
   q_cpt(ir,:) = interpos(temp_1d.q.t,temp_1d.q.data(ir,:),ids_core_profiles.time,tens_time);
 end
+
 for it=1:length(ids_core_profiles.time)
   ij=isfinite(q_cpt(:,it));
   if sum(ij) >= 5
@@ -335,9 +346,28 @@ for it=1:length(ids_core_profiles.time)
     ids_core_profiles.profiles_1d{it}.magnetic_shear = -9.e40;
   end
 end
+temp_1d_desc.magnetic_shear = 'from interpos with rhotor';
+
+%% Current densities
+
+for it=1:length(ids_core_profiles.time)
+  ids_core_profiles.profiles_1d{it}.j_bootstrap = ...
+    current_bootstrap.bs.bs_data.cd_dens.data(:,it);
+  temp_1d_desc.j_bootstrap = current_bootstrap.bs.bs_data.cd_dens.label;
+  ids_core_profiles.profiles_1d{it}.j_ohmic = ...
+    current_non_inductive.ohm.ohm_data.cd_dens.data(:,it);
+  temp_1d_desc.j_ohmic = current_non_inductive.ohm.ohm_data.cd_dens.label;
+end
+
+%% parallel conductivity (neoclassical)
+signeo = gdat(params_cores_profiles.shot,'\results::ibs:signeo');
+for it=1:length(ids_core_profiles.time)
+  ids_core_profiles.profiles_1d{it}.conductivity_parallel = signeo.data(:,it);
+  temp_1d_desc.conductivity_parallel = signeo.label;
+end
 
-ids_core_profiles_description.temp_1d_desc = temp_1d_desc;
-ids_core_profiles_description.profiles_1d.magnetic_shear = 'from interpos with rhotor';
+%% add descriptions for profiles_1d
+ids_core_profiles_description.profiles_1d = temp_1d_desc;
 
 if nargin <= 2
   ids_core_profiles.code.name = ['tcv_get_ids_core_profiles, within gdat, with shot= ' num2str(params_cores_profiles.shot) ];
diff --git a/matlab/TCV_IMAS/tcv_get_ids_core_sources.m b/matlab/TCV_IMAS/tcv_get_ids_core_sources.m
new file mode 100644
index 0000000000000000000000000000000000000000..6f630945d23ad81bdf831e41bc201d4ec6e3602f
--- /dev/null
+++ b/matlab/TCV_IMAS/tcv_get_ids_core_sources.m
@@ -0,0 +1,508 @@
+function [ids_core_sources,ids_core_sources_description,varargout] = ...
+  tcv_get_ids_core_sources(shot,ids_equil_empty,gdat_params,varargin)
+%
+% [ids_core_sources,ids_core_sources_description,varargout] = ...
+%     tcv_get_ids_core_sources(shot,ids_equil_empty,gdat_params,varargin);
+%
+%
+% gdat_params: gdat_data.gdat_params to get all params passed from original call
+%
+
+machine = 'tcv';
+tens_time = -1;
+tens_rho = -0.1;
+
+if exist('gdat_params','var')
+  [ids_core_sources, params_core_sources] = ...
+    tcv_ids_headpart(shot,ids_equil_empty,'cores_sources','gdat_params',gdat_params,...
+    'homogeneous_time',0,varargin{:});
+else
+  [ids_core_sources, params_core_sources] = ...
+    tcv_ids_headpart(shot,ids_equil_empty,'cores_sources','homogeneous_time',0,varargin{:});
+  aa=gdat_tcv;
+  gdat_params = aa.gdat_params; % to get default params
+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)
+
+% initialize description
+ids_core_sources_description = [];
+
+%% fill vacuum_toroidal field
+params_eff = params_eff_ref; params_eff.data_request='b0';
+b0_gdat=gdat(params_core_sources.shot,params_eff);
+ids_core_sources.vacuum_toroidal_field.r0 = b0_gdat.r0;
+ids_core_sources.vacuum_toroidal_field.b0 = b0_gdat.data;
+ids_core_sources_description.vacuum_toroidal_field = b0_gdat.request_description;
+ids_core_sources.time = b0_gdat.t;
+%%
+% save source template to fill for differnet source options
+source_template = ids_core_sources.source{1};
+profiles_template = source_template.profiles_1d{1};
+globals_template = source_template.global_quantities{1};
+
+last_index = 0; % index to be incremented when sources are added
+
+%% get time grid and data from gdat
+params_eff = params_eff_ref; params_eff.data_request='ohm_data';
+ohm_gdat = gdat(params_core_sources.shot,params_eff);
+params_eff = params_eff_ref; params_eff.data_request='powers';
+powers_gdat = gdat(params_core_sources.shot,params_eff);
+
+%% load liuqe data from nodes for conversions
+if params_eff_ref.liuqe == 1
+  nodes_liuqe = 'equil';
+else
+  nodes_liuqe = ['equil',num2str(params_eff_ref.liuqe)];
+end
+if check_nodes_filled(params_core_sources.shot,nodes_liuqe)
+  params_eff = params_eff_ref;
+  % normalized sqrt poloidal flux including axis
+  params_eff.data_request='\tcv_shot::top.results.equil_1.results:rho';
+  rho_pol_norm_liu = gdat(params_core_sources.shot,params_eff);
+  % <1/R^2>
+  params_eff.data_request='\tcv_shot::top.results.equil_1.results:gpsi0_r2_fsa';
+  Rm2_fs_liu = gdat(params_core_sources.shot,params_eff);
+  % Volume
+  params_eff.data_request='\tcv_shot::top.results.equil_1.results:vol';
+  vol_liu= gdat(params_core_sources.shot,params_eff);
+  % T(\psi) = R*B_tor
+  params_eff.data_request='\tcv_shot::top.results.equil_1.results:rbtor_rho';
+  T_liu = gdat(params_core_sources.shot,params_eff);
+  % safety factor q = -dPhi/dPsi
+  params_eff.data_request='\tcv_shot::top.results.equil_1.results:q';
+  q_liu = gdat(params_core_sources.shot,params_eff);
+  % I_tor = I_p, total plasma current
+  params_eff.data_request='\tcv_shot::top.results.equil_1.results:i_pl';
+  Ip_liu = gdat(params_core_sources.shot,params_eff);
+  % define liuqe_time from Ip_liu
+  liuqe_time = Ip_liu.t;
+else
+  error('Liuqe nodes %s not filled. Contact O. Sauter.',nodes_liuqe)
+end
+%% initialize source from template
+% ohm
+ohm_tgrid = powers_gdat.ohm.t; ohm_n_t = numel(ohm_tgrid);
+
+main_desc = 'Source from ohmic heating'; production = 'IBS nodes';
+id_ohm.description = sprintf('%s from %s',main_desc,production);
+id_ohm.index = 7; id_ohm.name = 'ohmic';
+ids_core_sources.source{last_index+1} = source_template;
+ids_core_sources.source{last_index+1}.identifier = id_ohm;
+ids_core_sources.source{last_index+1}.profiles_1d(1:ohm_n_t) = {profiles_template};
+ids_core_sources.source{last_index+1}.global_quantities(1:ohm_n_t) = {globals_template};
+ohm_data = ohm_gdat.ohm.ohm_data;
+
+% load LIUQE data to convert
+% \tilde{j}_// = <jdotB>/(R0<Bphi/R>) to j_//0 = <jdotB>/B0; Bphi=T(psi)/R
+% interpolate liuqe outputs on ohm_tgrid
+T      = interp1(liuqe_time,T_liu.data.',     ohm_tgrid)';
+Rm2_fs = interp1(liuqe_time,Rm2_fs_liu.data.',ohm_tgrid)';
+vol    = interp1(liuqe_time,vol_liu.data.',   ohm_tgrid)';
+% get vacuum field data from ids
+R0 = ids_core_sources.vacuum_toroidal_field.r0;
+B0 = interp1(ids_core_sources.time,ids_core_sources.vacuum_toroidal_field.b0,ohm_tgrid);
+
+jpar_tilde_to_jpar_0 = R0*T.*Rm2_fs./B0';
+
+% map volume and conversion factor on rho_pol grid of ohm_data cd_dens
+jpar_tilde_to_jpar_0_mapped = ...
+  interp1(rho_pol_norm_liu.data,jpar_tilde_to_jpar_0,ohm_data.cd_dens.rhopol_norm);
+vol_mapped = interp1(rho_pol_norm_liu.data,vol,ohm_data.cd_dens.rhopol_norm);
+
+for ii = 1:ohm_n_t
+  % profiles_1d
+  ids_core_sources.source{last_index+1}.profiles_1d{ii}.time = ohm_tgrid(ii);
+  ids_core_sources.source{last_index+1}.profiles_1d{ii}.grid.rho_pol_norm = ...
+    ohm_data.cd_dens.rhopol_norm';
+  ids_core_sources.source{last_index+1}.profiles_1d{ii}.grid.rho_tor_norm = ...
+    ohm_data.cd_dens.rhotor_norm(:,ii)';
+  jpar_0_tmp = ohm_data.cd_dens.data(:,ii)'.*jpar_tilde_to_jpar_0_mapped(:,ii)';
+  ids_core_sources.source{last_index+1}.profiles_1d{ii}.j_parallel = jpar_0_tmp;
+  integrated_jpar_0_tmp = cumtrapz(vol_mapped(:,ii),jpar_0_tmp)/2/pi/R0;
+  ids_core_sources.source{last_index+1}.profiles_1d{ii}.current_parallel_inside = integrated_jpar_0_tmp;
+
+  % globals
+  ids_core_sources.source{last_index+1}.global_quantities{ii}.time = ohm_tgrid(ii);
+  ids_core_sources.source{last_index+1}.global_quantities{ii}.power = powers_gdat.ohm.data(ii);
+  ids_core_sources.source{last_index+1}.global_quantities{ii}.current_parallel = integrated_jpar_0_tmp(end);
+end
+
+last_index = last_index+1;  % add if statement to only increment if ohmic source has been added
+
+%% bs
+params_eff = params_eff_ref; params_eff.data_request='bs_data';
+bs_gdat = gdat(params_core_sources.shot,params_eff); bs_data = bs_gdat.bs.bs_data;
+bs_tgrid = bs_gdat.bs.t; bs_n_t = numel(bs_tgrid);
+
+main_desc = 'Bootstrap current'; production = 'IBS nodes';
+id_bs.description = sprintf('%s from %s',main_desc,production);
+id_bs.index = 13; id_bs.name = 'bootstrap_current';
+ids_core_sources.source{last_index+1} = source_template;
+ids_core_sources.source{last_index+1}.identifier = id_bs;
+ids_core_sources.source{last_index+1}.profiles_1d(1:bs_n_t) = {profiles_template};
+ids_core_sources.source{last_index+1}.global_quantities(1:bs_n_t) = {globals_template};
+
+for ii = 1:bs_n_t
+  % profiles_1d
+  ids_core_sources.source{last_index+1}.profiles_1d{ii}.time = bs_tgrid(ii);
+  ids_core_sources.source{last_index+1}.profiles_1d{ii}.grid.rho_pol_norm = ...
+    bs_data.cd_dens.rhopol_norm';
+  ids_core_sources.source{last_index+1}.profiles_1d{ii}.grid.rho_tor_norm = ...
+    bs_data.cd_dens.rhotor_norm(:,ii)';
+  % use same conversion as for ohmic data from LIUQE
+  jpar_0_tmp = bs_data.cd_dens.data(:,ii)'.*jpar_tilde_to_jpar_0_mapped(:,ii)';
+  ids_core_sources.source{last_index+1}.profiles_1d{ii}.j_parallel = jpar_0_tmp;
+  integrated_jpar_0_tmp = cumtrapz(vol_mapped(:,ii),jpar_0_tmp)/2/pi/R0;
+  ids_core_sources.source{last_index+1}.profiles_1d{ii}.current_parallel_inside = integrated_jpar_0_tmp;
+
+  % globals
+  ids_core_sources.source{last_index+1}.global_quantities{ii}.time = bs_tgrid(ii);
+  ids_core_sources.source{last_index+1}.global_quantities{ii}.current_parallel = integrated_jpar_0_tmp(end);
+end
+
+last_index = last_index+1;  % add if statement to only increment if bs source has been added
+
+%% ec
+params_eff = params_eff_ref;
+params_eff.data_request='ec_data';
+params_eff.ec_inputs = 1; % load EC input information
+ec_gdat = gdat(params_core_sources.shot,params_eff);
+
+if ~isempty(ec_gdat.ec.data) % if EC data available, fill sources
+
+  ec_data = ec_gdat.ec.ec_data; ec_inputs = ec_gdat.ec.ec_inputs;
+  % get tgrid from gdat ec_data
+  ec_tgrid_toray = ec_data.p_dens.t; nt_ec_toray = numel(ec_tgrid_toray);
+
+  % retrieve active launcher information from ec_inputs
+  nb_launchers = numel(ec_inputs.launchers_active.data);
+  active_launchers = find(ec_inputs.launchers_active.data==1)';
+
+  % find times of injected EC power to interpolate power & current densities
+  % on p_ec_injected tgrid
+  ec_powers_tgrid = powers_gdat.ec.t; %nt_ec_powers = numel(ec_powers_tgrid);
+  % find times where EC is on to define time grid with extra time slice just
+  % before/after  EC power and at start/end of shot
+  itime_ec = find(powers_gdat.ec.data(:,end)>0);
+  if ec_powers_tgrid(itime_ec(end))>=ohm_tgrid(end)
+    i_time_end = iround(ec_powers_tgrid,ohm_tgrid(end));
+    ec_tgrid_out = [ohm_tgrid(1),ec_powers_tgrid(itime_ec(1)-1:i_time_end)'];
+  else
+    ec_tgrid_out = [ohm_tgrid(1),ec_powers_tgrid(itime_ec(1)-1:itime_ec(end)+1)',ohm_tgrid(end)];
+  end
+  nt_ec_out = numel(ec_tgrid_out);
+  p_ec_injected = interpos(ec_powers_tgrid,powers_gdat.ec.data(:,end),ec_tgrid_out);
+
+  % Setup source structs for active launchers from template
+  main_desc = 'Source from electron cyclotron heating and current drive';
+  production = 'TORAY';
+  id_ec.index = 3; id_ec.name = 'ec';
+  for i_lau = active_launchers
+    id_ec.description = sprintf('L%i/G%i, %s from %s double width CD profiles',i_lau,ec_inputs.gyro2launcher.data(i_lau),main_desc,production);
+    ids_core_sources.source{last_index+i_lau} = source_template;
+    ids_core_sources.source{last_index+i_lau}.identifier = id_ec;
+    ids_core_sources.source{last_index+i_lau}.profiles_1d(1:nt_ec_out) = {profiles_template};
+    ids_core_sources.source{last_index+i_lau}.global_quantities(1:nt_ec_out) = {globals_template};
+  end
+
+  % get vacuum field data from ids
+  R0 = ids_core_sources.vacuum_toroidal_field.r0;
+  B0 = interp1(ids_core_sources.time,ids_core_sources.vacuum_toroidal_field.b0,ec_tgrid_toray);
+
+  % do conversion j_{V,TORAY} = dI_\phi/dV = (1/2\pi)<j_\phi/R> to j_//0 = <jdotB>/B0;
+  % via j_tilde// = <jdotB>/(R0 <Bphi/R>) = 2*pi/R0/Rm2_fs[j_{V,TORAY}-dT/dV/T*I_{phi,cd}]
+
+  % interpolate liuqe outputs on ec_tgrid_toray
+  T      = interp1(liuqe_time,T_liu.data.',     ec_tgrid_toray)';
+  Rm2_fs = interp1(liuqe_time,Rm2_fs_liu.data.',ec_tgrid_toray)';
+  vol    = interp1(liuqe_time,vol_liu.data.',   ec_tgrid_toray)';
+
+%  % alternative conversion, slightly mismatching with the conversion
+%  % above, to be clarified
+%  % using j_//,cd = <j_cd/B> B, thus j_// = 2\pi <B^2> / (B_0 <B_\phi/R>)
+%   mu0     = 4*pi*10^-7;
+%   q      = interp1(liuqe_time,q_liu.data.',     ec_tgrid_toray)';
+%   Ip     = interp1(liuqe_time,Ip_liu.data,      ec_tgrid_toray);
+%   Vprime = -2*pi*q./T./Rm2_fs;
+%   B2_fs   = -mu0*Ip./Vprime + T.^2.*Rm2_fs;
+%   jtoray_to_jpar0 = 2*pi./B0./T./Rm2_fs.*B2_fs;
+%   jtoray_to_jpar0_mapped = nan(size(ec_data.cd_dens.x));
+
+  % interpolate on ec_data rho_pol grid
+  vol_mapped    = nan(size(ec_data.cd_dens.x));
+  T_mapped      = nan(size(ec_data.cd_dens.x));
+  dTdV_mapped   = nan(size(ec_data.cd_dens.x));
+  Rm2_fs_mapped = nan(size(ec_data.cd_dens.x));
+  for ii = 1:nt_ec_toray
+%     jtoray_to_jpar0_mapped(:,ii) = ...
+%       interp1(rho_pol_norm_liu.data,jtoray_to_jpar0(:,ii),ec_data.cd_dens.grids.rho_pol_norm(:,ii));
+    vol_mapped(:,ii)      = interpos(...
+      rho_pol_norm_liu.data,vol(:,ii),ec_data.cd_dens.grids.rho_pol_norm(:,ii));
+    T_mapped(:,ii)        = interpos(...
+      rho_pol_norm_liu.data,T(:,ii),ec_data.cd_dens.grids.rho_pol_norm(:,ii));
+    [~,dTdV_mapped(:,ii)] = interpos(vol_mapped(:,ii),T_mapped(:,ii));
+    Rm2_fs_mapped(:,ii)   = interpos(...
+      rho_pol_norm_liu.data,Rm2_fs(:,ii),ec_data.cd_dens.grids.rho_pol_norm(:,ii));
+  end
+
+  % load 1d_profiles from ec_data
+  p_dens        = ec_data.p_dens.data;
+  p_dens(isnan(p_dens)) = 0;
+  p_integrated  = ec_data.p_integrated.data;
+  p_integrated(isnan(p_integrated)) = 0;
+  cd_dens       = ec_data.cd_dens_doublewidth.data; % use double width to have realistic deposition broadening
+  cd_dens(isnan(cd_dens)) = 0;
+  cd_integrated = ec_data.cd_integrated.data;
+  cd_integrated(isnan(cd_integrated)) = 0;
+
+  % initialize variables
+  jpar_tilde       = zeros(size(cd_dens));
+  jpar0            = zeros(size(cd_dens));
+  jpar0_integrated = zeros(size(cd_dens));
+
+  % convert and integrate j_TORAY to j//0
+  for i_lau = active_launchers
+%     % alternative conversion
+%     jpar0(:,i_lau,:) = squeeze(cd_dens(:,i_lau,:)).*jtoray_to_jpar0_mapped;
+
+    jpar_tilde(:,i_lau,:) = 2*pi/R0./Rm2_fs_mapped.*(squeeze(cd_dens(:,i_lau,:))...
+      -dTdV_mapped./T_mapped.*squeeze(cd_integrated(:,i_lau,:)));
+    jpar0(:,i_lau,:) = squeeze(jpar_tilde(:,i_lau,:)).*R0.*T_mapped.*Rm2_fs_mapped./B0;
+
+    for ii = 1:nt_ec_toray
+      % integrate j//0
+      [~,~,~,jpar0_integrated(:,i_lau,ii)] = interpos(vol_mapped(:,ii),jpar0(:,i_lau,ii)/(2*pi*R0));
+    end
+  end
+
+%% interpolating 1d_profiles from 'ec_tgrid_toray' grid (toray tgrid) to 'interp_tgrid' (powers tgrid when powers.data>0)
+  ij = iround_os(ec_tgrid_out,ec_tgrid_toray);
+  sparse_p_ec_injected = p_ec_injected(ij); % injected ec power vals corresponding to ec_tgrid_toray
+  n_rho = size(p_dens, 1);
+  %rho grids to be interpolated on power time grid
+  rho_pol_norm = ec_data.cd_dens.grids.rho_pol_norm;
+  rho_tor_norm = ec_data.cd_dens.grids.rho_tor_norm;
+
+  % calculate normalised profiles on ec_tgrid_toray grid
+  norm_p_dens           = zeros(n_rho,nb_launchers+1,nt_ec_toray);
+  norm_p_integrated     = zeros(n_rho,nb_launchers+1,nt_ec_toray);
+  norm_jpar0            = zeros(n_rho,nb_launchers+1,nt_ec_toray);
+  norm_jpar0_integrated = zeros(n_rho,nb_launchers+1,nt_ec_toray);
+  for it = 1:nt_ec_toray
+    norm_p_dens(:,:,it)           = p_dens(:,:,it)          ./sparse_p_ec_injected(it);
+    norm_p_integrated(:,:,it)     = p_integrated(:,:,it)    ./sparse_p_ec_injected(it);
+    norm_jpar0(:,:,it)            = jpar0(:,:,it)           ./sparse_p_ec_injected(it);
+    norm_jpar0_integrated(:,:,it) = jpar0_integrated(:,:,it)./sparse_p_ec_injected(it);
+  end
+
+  % interpolate normalised p_dens profiles on ec_powers_tgrid
+  interp_norm_p_dens           = zeros(n_rho,nb_launchers+1,nt_ec_out);
+  interp_norm_p_integrated     = zeros(n_rho,nb_launchers+1,nt_ec_out);
+  interp_norm_jpar0            = zeros(n_rho,nb_launchers+1,nt_ec_out);
+  interp_norm_jpar0_integrated = zeros(n_rho,nb_launchers+1,nt_ec_out);
+  for i_lau = active_launchers
+    for irho = 1:n_rho
+      % get power and current density at each rho
+      trace_p_dens        = squeeze(norm_p_dens(irho,i_lau,:));
+      trace_p_integrated  = squeeze(norm_p_integrated(irho,i_lau,:));
+      trace_jpar0       = squeeze(norm_jpar0(irho,i_lau,:));
+      trace_jpar0_integrated = squeeze(norm_jpar0_integrated(irho,i_lau,:));
+      % interpolate on gdat powers tgrid, interpos 21 to extrapolate,
+      % taking constant value y_edge; needed for time window between start of EC and first TS time
+      interp_norm_p_dens(          irho,i_lau,3:end-2) = interpos(21,ec_tgrid_toray,trace_p_dens,          ec_tgrid_out(3:end-2));
+      interp_norm_p_integrated(    irho,i_lau,3:end-2) = interpos(21,ec_tgrid_toray,trace_p_integrated,    ec_tgrid_out(3:end-2));
+      interp_norm_jpar0(           irho,i_lau,3:end-2) = interpos(21,ec_tgrid_toray,trace_jpar0,           ec_tgrid_out(3:end-2));
+      interp_norm_jpar0_integrated(irho,i_lau,3:end-2) = interpos(21,ec_tgrid_toray,trace_jpar0_integrated,ec_tgrid_out(3:end-2));
+    end
+  end
+
+  % interpolate the rho_pol & rho_tor on ec_powers_tgrid
+  interp_rho_pol = zeros(n_rho,nt_ec_out);
+  interp_rho_tor = zeros(n_rho,nt_ec_out);
+  for irho = 1:n_rho
+    interp_rho_pol(irho,3:end-2) = interpos(21,ec_tgrid_toray,rho_pol_norm(irho,:),ec_tgrid_out(3:end-2));
+    interp_rho_tor(irho,3:end-2) = interpos(21,ec_tgrid_toray,rho_tor_norm(irho,:),ec_tgrid_out(3:end-2));
+  end
+  % fill rho_pol just outside of TORAY times(zero power) with the known profiles one time slice after/before
+  interp_rho_pol(:,2) = interp_rho_pol(:,3); interp_rho_pol(:,end-1) = interp_rho_pol(:,end-2);
+
+  % normalised & interpolated profiles * p_ec_injected on interp_tgrid
+  interp_p_dens        = zeros(n_rho,nb_launchers+1,nt_ec_out);
+  interp_p_integrated  = zeros(n_rho,nb_launchers+1,nt_ec_out);
+  interp_jpar0         = zeros(n_rho,nb_launchers+1,nt_ec_out);
+  interp_jpar0_integrated = zeros(n_rho,nb_launchers+1,nt_ec_out);
+  for it = 1:nt_ec_out % fill profiles only for time slices when EC is nonzero, thus it+2 assignment
+    interp_p_dens(:,:,it)           = interp_norm_p_dens(:,:,it)          .*p_ec_injected(it);
+    interp_p_integrated(:,:,it)     = interp_norm_p_integrated(:,:,it)    .*p_ec_injected(it);
+    interp_jpar0(:,:,it)            = interp_norm_jpar0(:,:,it)           .*p_ec_injected(it);
+    interp_jpar0_integrated(:,:,it) = interp_norm_jpar0_integrated(:,:,it).*p_ec_injected(it);
+  end
+
+  % fill the ids entries
+  for i_lau = active_launchers
+    for ii = 1:nt_ec_out
+      % 1d_profiles
+      ids_core_sources.source{last_index+i_lau}.profiles_1d{ii}.time = ec_tgrid_out(ii);
+      % grids (do not fill for first and last time slice)
+      if ii~=1 || ii~=nt_ec_out
+        ids_core_sources.source{last_index+i_lau}.profiles_1d{ii}.grid.rho_tor_norm = interp_rho_tor(:,ii);
+        ids_core_sources.source{last_index+i_lau}.profiles_1d{ii}.grid.rho_pol_norm = interp_rho_pol(:,ii);
+        % power density
+        ids_core_sources.source{last_index+i_lau}.profiles_1d{ii}.electrons.energy = ...
+          interp_p_dens(:,i_lau,ii);
+        % integrated power density
+        ids_core_sources.source{last_index+i_lau}.profiles_1d{ii}.electrons.power_inside = ...
+          interp_p_integrated(:,i_lau,ii);
+        % current density
+        ids_core_sources.source{last_index+i_lau}.profiles_1d{ii}.j_parallel = ...
+          interp_jpar0(:,i_lau,ii);
+        % integrated current density
+        ids_core_sources.source{last_index+i_lau}.profiles_1d{ii}.current_parallel_inside = ...
+          interp_jpar0_integrated(:,i_lau,ii);
+      end
+
+      % globals
+      ids_core_sources.source{last_index+i_lau}.global_quantities{ii}.time = ec_tgrid_out(ii);
+      ids_core_sources.source{last_index+i_lau}.global_quantities{ii}.power = ...
+        interp_p_integrated(end,i_lau,ii);
+      ids_core_sources.source{last_index+i_lau}.global_quantities{ii}.current_parallel = ...
+        interp_jpar0_integrated(end,i_lau,ii);
+    end
+  end
+
+  %add empty sources for rest of unused launchers
+  if numel(ids_core_sources.source)-last_index ~= nb_launchers
+    ids_core_sources.source{last_index+nb_launchers} = [];
+  end
+
+  last_index = last_index+nb_launchers;
+end
+
+%% NBI. same tgrid for NBI1 and NBI2
+
+check_nbi = [~isempty(powers_gdat.nbi1.data),~isempty(powers_gdat.nbi2.data)];
+active_nbi = find(check_nbi==1);
+nb_nbi = numel(check_nbi);
+nbi_names = {'nbi1','nbi2'};
+
+if numel(active_nbi)>0
+  % get tgrid (same for NBI1 & 2 if both active) from active_nbi(1)
+  nbi_powers_tgrid = powers_gdat.(nbi_names{active_nbi(1)}).t;
+  % find times where NBI is on to define time grid with extra time slice just
+  % before/after  NBI power and at start/end of shot
+  itime_nbi = find((powers_gdat.(nbi_names{active_nbi(1)}).data>0));
+  if nbi_powers_tgrid(itime_nbi(end))>=ohm_tgrid(end)
+    i_time_end = iround(nbi_powers_tgrid,ohm_tgrid(end));
+    nbi_tgrid_out = [ohm_tgrid(1),nbi_powers_tgrid(itime_nbi(1)-1:i_time_end)'];
+  else
+    nbi_tgrid_out = [ohm_tgrid(1),nbi_powers_tgrid(itime_nbi(1)-1:itime_nbi(end)+1)',ohm_tgrid(end)];
+  end
+  nt_nbi_out = numel(nbi_tgrid_out);
+
+  % Setup source structs for active nbi from template
+  main_desc = 'Source from Neutral Beam Injection';
+  id_nbi.index = 2; id_nbi.name = 'nbi';
+  for i_nbi = active_nbi
+    id_nbi.description = sprintf('NBI%i %s',i_nbi,main_desc);
+    ids_core_sources.source{last_index+i_nbi} = source_template;
+    ids_core_sources.source{last_index+i_nbi}.identifier = id_nbi;
+    ids_core_sources.source{last_index+i_nbi}.profiles_1d(1:nt_nbi_out) = {profiles_template};
+    ids_core_sources.source{last_index+i_nbi}.global_quantities(1:nt_nbi_out) = {globals_template};
+  end
+
+  disp('Loading of current & power densities from ASTRA not implemented yet.')
+  disp('Checking if ASTRA run available on partition /Lac8_D:')
+  [~,hostname] = unix('hostname');
+  if strcmp(hostname,'lac8.epfl.ch')
+    unix(sprintf('ls /Lac8_D/ASTRA/ | grep ''%i'' && echo File for shotnumber exists! || echo File for shotnumber does not exist!',shot));
+  else
+    unix(sprintf('ssh $(whoami)@lac8 "ls /Lac8_D/ASTRA/ | grep ''%i'' && echo File for shotnumber exists! || echo File for shotnumber does not exist! && exit"',shot));
+  end
+
+  for i_nbi = active_nbi
+    p_nbi_injected_tmp = interpos(nbi_powers_tgrid,powers_gdat.(nbi_names{i_nbi}).data,nbi_tgrid_out);
+    for ii = 1:nt_nbi_out
+      % globals
+      ids_core_sources.source{last_index+i_nbi}.global_quantities{ii}.time = nbi_tgrid_out(ii);
+      ids_core_sources.source{last_index+i_nbi}.global_quantities{ii}.power = p_nbi_injected_tmp(ii);
+    end
+  end
+
+  % add empty for unused NBI
+  if numel(ids_core_sources.source)-last_index ~= nb_nbi
+    ids_core_sources.source{last_index+nb_nbi} = [];
+  end
+
+  last_index = last_index+nb_nbi;
+end
+
+%% DNBI has it's own time grid
+if ~isempty(powers_gdat.dnbi)
+  % get tgrid (same for NBI1 & 2 if both active) from active_nbi(1)
+  dnbi_powers_tgrid = powers_gdat.dnbi.t;
+  % find times where DNBI is on to define time grid with extra time slice just
+  % before/after  DNBI power and at start/end of shot
+  itime_dnbi = find((powers_gdat.dnbi.data>0));
+  if dnbi_powers_tgrid(itime_dnbi(end))>=ohm_tgrid(end)
+    i_time_end = iround(dnbi_powers_tgrid,ohm_tgrid(end));
+    dnbi_tgrid_out = [ohm_tgrid(1),dnbi_powers_tgrid(itime_dnbi(1)-1:i_time_end)'];
+  else
+    dnbi_tgrid_out = [ohm_tgrid(1),dnbi_powers_tgrid(itime_dnbi(1)-1:itime_dnbi(end)+1)',ohm_tgrid(end)];
+  end
+  nt_dnbi_out = numel(dnbi_tgrid_out);
+
+  id_dnbi.description = 'DNBI Source from Neutral Beam Injection';
+  id_dnbi.index = 2; id_dnbi.name = 'nbi';
+  ids_core_sources.source{last_index+1} = source_template;
+  ids_core_sources.source{last_index+1}.identifier = id_dnbi;
+  ids_core_sources.source{last_index+1}.profiles_1d(1:nt_dnbi_out) = {profiles_template};
+  ids_core_sources.source{last_index+1}.global_quantities(1:nt_dnbi_out) = {globals_template};
+
+  p_dnbi_injected = interpos(dnbi_powers_tgrid,powers_gdat.dnbi.data,dnbi_tgrid_out);
+  for ii = 1:nt_dnbi_out
+    % globals
+    ids_core_sources.source{last_index+1}.global_quantities{ii}.time = nbi_tgrid_out(ii);
+    ids_core_sources.source{last_index+1}.global_quantities{ii}.power = p_dnbi_injected(ii);
+  end
+
+  last_index = last_index+1;
+end
+
+%% total
+% id_total.description = 'Total source; combines all sources';
+% id_total.index = 1; id_total.name = 'total';
+% ids_core_sources.source{} = source_template;
+% ids_core_sources.source{}.identifier = id_total;
+% ids_core_sources.source{}.profiles_1d(1:n_t) = {profiles_template};
+% ids_core_sources.source{}.global_quantities(1:n_t) = {globals_template};
+
+%% add descriptions for profiles_1d
+
+desc.source = ...
+  'available by now {source_index}: ohmic {1}, bootstrap {2}, ec {3+} for individual launchers (if present in shot), nbi {3+|14+} if available, dnbi {3|14|16} if available';
+desc.profiles_1d.electrons.energy = 'absorbed power density';
+desc.profiles_1d.electrons.power_inside = 'integrated absorbed power density';
+desc.profiles_1d.j_parallel = 'parallel current density';
+desc.profiles_1d.current_parallel_inside = 'integrated parallel current density';
+desc.globals.power = 'total power coupled to the plasma';
+desc.globals.current_parallel = 'total parallel current driven';
+ids_core_sources_description = desc;
+
+%%
+if nargin <= 2
+  ids_core_sources.code.name = ['tcv_get_ids_core_sources, within gdat, with shot= ' num2str(params_core_sources.shot) ];
+else
+  ids_core_sources.code.name = ['tcv_get_ids_core_sources, within gdat, with shot= ' num2str(params_core_sources.shot) '; varargin: ' varargin{:}];
+end
+ids_core_sources_description.code.name = ids_core_sources.code.name;
+
+ids_core_sources.code.output_flag = zeros(size(ids_core_sources.time));
+
+% cocos automatic transform
+if ~isempty(which('ids_generic_cocos_nodes_transformation_symbolic'))
+  [ids_core_sources,cocoscoeff]=ids_generic_cocos_nodes_transformation_symbolic(ids_core_sources,'core_sources',gdat_params.cocos_in, ...
+    gdat_params.cocos_out,gdat_params.ipsign_out,gdat_params.b0sign_out,gdat_params.ipsign_in,gdat_params.b0sign_in, ...
+    gdat_params.error_bar,gdat_params.nverbose);
+
+end
diff --git a/matlab/TCV_IMAS/tcv_get_ids_core_transport.m b/matlab/TCV_IMAS/tcv_get_ids_core_transport.m
new file mode 100644
index 0000000000000000000000000000000000000000..89421f6b67f9dc1df5be26547c118a17c3614fe0
--- /dev/null
+++ b/matlab/TCV_IMAS/tcv_get_ids_core_transport.m
@@ -0,0 +1,83 @@
+function [ids_core_transport,ids_core_transport_description,varargout] = ...
+  tcv_get_ids_core_transport(shot,ids_equil_empty,gdat_params,varargin)
+%
+% [ids_core_transport,ids_core_transport_description,varargout] = ...
+%     tcv_get_ids_core_transport(shot,ids_equil_empty,gdat_params,varargin);
+%
+%
+% gdat_params: gdat_data.gdat_params to get all params passed from original call
+%
+
+machine = 'tcv';
+tens_time = -1;
+tens_rho = -0.1;
+
+if exist('gdat_params','var')
+  [ids_core_transport, params_core_transport] = ...
+    tcv_ids_headpart(shot,ids_equil_empty,'cores_profiles','gdat_params',gdat_params,varargin{:});
+else
+  [ids_core_transport, params_core_transport] = ...
+    tcv_ids_headpart(shot,ids_equil_empty,'cores_profiles',varargin{:});
+  aa=gdat_tcv;
+  gdat_params = aa.gdat_params; % to get default params
+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)
+
+% initialize description
+ids_core_transport_description = [];
+
+%%
+last_index = 0;
+
+% fill model [name: transport solver, desc: output from transport solver]
+% setup model and profiles_1d
+comment = 'Output from a transport solver';
+ids_core_transport.model{last_index+1}.comment = comment;
+ids_core_transport.model{last_index+1}.name = comment;
+ids_core_transport.model{last_index+1}.identifier.index = 2;
+ids_core_transport.model{last_index+1}.name = 'transport_solver';
+
+% read data and setup time
+params_eff.data_request='\results::conf:chie';
+temp_1d.chie = gdat(params_core_transport.shot,params_eff.data_request);
+temp_1d_desc.chie = params_eff.data_request;
+
+if isempty(temp_1d.chie.t)
+  warning('no data in chie node, might need to rerun anaprofs')
+  return
+end
+
+ids_core_transport.time = temp_1d.chie.t;
+ids_core_transport_description.time = ['from node' params_eff.data_request];
+
+ids_core_transport.model{last_index+1}.profiles_1d(1:length(ids_core_transport.time)) = ...
+  ids_core_transport.model{last_index+1}.profiles_1d(1);
+
+% fill profiles_1d
+for it=1:length(ids_core_transport.time)
+  ids_core_transport.model{last_index+1}.profiles_1d{it}.time = ids_core_transport.time(it);
+  ids_core_transport.model{last_index+1}.profiles_1d{it}.electrons.energy.d = temp_1d.chie.data(:,it);
+  temp_1d_desc.electrons.energy.d = temp_1d.chie.label;
+end
+
+%% add descriptions for profiles_1d
+ids_core_transport_description.profiles_1d = temp_1d_desc;
+
+%%
+if nargin <= 2
+  ids_core_transport.code.name = ['tcv_get_ids_core_transport, within gdat, with shot= ' num2str(params_core_transport.shot) ];
+else
+  ids_core_transport.code.name = ['tcv_get_ids_core_transport, within gdat, with shot= ' num2str(params_core_transport.shot) '; varargin: ' varargin{:}];
+end
+ids_core_transport_description.code.name = ids_core_transport.code.name;
+
+ids_core_transport.code.output_flag = zeros(size(ids_core_transport.time));
+
+% cocos automatic transform
+if ~isempty(which('ids_generic_cocos_nodes_transformation_symbolic'))
+  [ids_core_transport,cocoscoeff]=ids_generic_cocos_nodes_transformation_symbolic(ids_core_transport,'core_transport',gdat_params.cocos_in, ...
+          gdat_params.cocos_out,gdat_params.ipsign_out,gdat_params.b0sign_out,gdat_params.ipsign_in,gdat_params.b0sign_in, ...
+          gdat_params.error_bar,gdat_params.nverbose);
+
+end
diff --git a/matlab/TCV_IMAS/tcv_get_ids_equilibrium.m b/matlab/TCV_IMAS/tcv_get_ids_equilibrium.m
index 263876023421dd6f1178f48302443aa01b5f807b..b0b22e2d593c954f9091642d07135f68c40c2588 100644
--- a/matlab/TCV_IMAS/tcv_get_ids_equilibrium.m
+++ b/matlab/TCV_IMAS/tcv_get_ids_equilibrium.m
@@ -1,15 +1,20 @@
-function [ids_equilibrium,ids_equilibrium_description,varargout] = tcv_get_ids_equilibrium(shot,ids_equil_empty, gdat_params,varargin)
+function [ids_equilibrium,ids_equilibrium_description,varargout] = ...
+  tcv_get_ids_equilibrium(shot,ids_equil_empty,gdat_params,varargin)
 %
-%  [ids_equilibrium,ids_equilibrium_description,varargout] = tcv_get_ids_equilibrium(shot,ids_equil_empty,varargin);
+% [ids_equilibrium,ids_equilibrium_description,varargout] = ...
+%     tcv_get_ids_equilibrium(shot,ids_equil_empty,gdat_params,varargin);
 %
 %
-% gdat_params: gdat_data.gdat_params to get all params passed from original call, in particular error_bar and cocos_out options
+% gdat_params: gdat_data.gdat_params to get all params passed from original call, 
+% in particular error_bar and cocos_out options
 %
 
 if exist('gdat_params','var')
-  [ids_equilibrium, params_equilibrium] = tcv_ids_headpart(shot,ids_equil_empty,'equilibrium','gdat_params',gdat_params,varargin{:});
+  [ids_equilibrium, params_equilibrium] = ...
+    tcv_ids_headpart(shot,ids_equil_empty,'equilibrium','gdat_params',gdat_params,varargin{:});
 else
-  [ids_equilibrium, params_equilibrium] = tcv_ids_headpart(shot,ids_equil_empty,'equilibrium',varargin{:});
+  [ids_equilibrium, params_equilibrium] = ...
+    tcv_ids_headpart(shot,ids_equil_empty,'equilibrium',varargin{:});
   aa=gdat_tcv;
   gdat_params = aa.gdat_params; % to get default params
 end
diff --git a/matlab/TCV_IMAS/tcv_get_ids_summary.m b/matlab/TCV_IMAS/tcv_get_ids_summary.m
index 2a720beba4e976d3ab1443119ab95159cb7f7bf3..e24b4ee20f0e52a73dd2b1751032eda58bc3efc7 100644
--- a/matlab/TCV_IMAS/tcv_get_ids_summary.m
+++ b/matlab/TCV_IMAS/tcv_get_ids_summary.m
@@ -16,7 +16,7 @@ end
 
 % As a general rule, for a new substructure under the main ids, construct a local structure like:
 % "global_quantities" with subfields being the relevant data to get and a local structure:
-% "global_quantities_desc" which contains the same subfields themselves containing the gdat string aftre shot used
+% "global_quantities_desc" which contains the same subfields themselves containing the gdat string after shot used
 %
 % vacuum_toroidal_field and time, using homogeneous
 %
@@ -36,6 +36,7 @@ ids_summary.code.name = 'gdat';
 ids_summary.code.version = git_release_hash;
 ids_summary.code.repository = git_url;
 
+%% boundary
 % use equilibrium time as reference, so load first elongation(time)
 
 params_eff = params_eff_ref;
@@ -59,7 +60,6 @@ ids_summary.time = unique([t_before; [kappa.t(1):max((kappa.t(end)-kappa.t(1))/(
 ids_summary_description.time = 'time from gdat(shot,''kappa'') and adding from 0 up to t(ip_trapeze(end))';
 params_eff = params_eff_ref;
 
-% boundary:
 boundary.elongation = kappa;
 boundary_desc.elongation = kappa.gdat_params.data_request;
 params_eff.data_request = 'r_geom';
@@ -121,13 +121,13 @@ if ~isempty(special_fields)
 % $$$   end
 end
 
-% disruption, use specific function
+%% disruption, use specific function
 % to be decided if changes only ids_summary_out.disruption or also elsewhere..., if ids_summary_out.time is changed,
 % then all the other data should be related, thus call this first?
 
 [ids_summary_out,ids_summary_out_description] = ids_summary_disruption(shot, ids_summary, gdat_params);
 
-% gas: bottom/top?, deuterium, helium_xx, ?
+%% gas: bottom/top?, deuterium, helium_xx, ?
 params_eff.data_request = 'gas_flux';
 gas_injection_rates.deuterium = gdat(params_summary.shot,params_eff);
 gas_injection_rates_desc.deuterium = params_eff.data_request;
@@ -148,7 +148,8 @@ for i=1:numel(gas_injection_rates_fieldnames)
   end
 end
 %params_eff.doplot=1;
-% global_quantities:
+
+%% global_quantities
 params_eff.data_request = 'b0';
 global_quantities.b0 = gdat(params_summary.shot,params_eff); % do not add 'source','liuqe' to get all times
 global_quantities_desc.b0 = [params_eff.data_request ' ; ' global_quantities.b0.data_fullpath];
@@ -182,6 +183,9 @@ global_quantities_desc.current_non_inductive = [params_eff.data_request ' ; ' gl
 params_eff.data_request = 'w_mhd';
 global_quantities.energy_diamagnetic = gdat(params_summary.shot,params_eff);
 global_quantities_desc.energy_diamagnetic = [params_eff.data_request ' ; ' global_quantities.energy_diamagnetic.data_fullpath];
+params_eff.data_request = 'tau_tot';
+global_quantities.tau_energy = gdat(params_summary.shot,params_eff);
+global_quantities_desc.tau_energy = [params_eff.data_request ' ; ' global_quantities.tau_energy.data_fullpath];
 params_eff.data_request = '\tcv_shot::top.results.conf:we';
 global_quantities.energy_electrons_thermal = gdat(params_summary.shot,params_eff);
 global_quantities_desc.energy_electrons_thermal = [params_eff.data_request ' ; ' global_quantities.energy_electrons_thermal.data_fullpath];
@@ -263,6 +267,7 @@ end
 ids_summary.global_quantities.r0.value = global_quantities.r0.data;
 ids_summary.global_quantities.r0.source = ['gdat request: ' global_quantities_desc.r0];
 
+%% volume average
 % cst zeff
 params_eff.data_request = '\tcv_shot::top.results.ibs:z_eff';
 volume_average.zeff = gdat(params_summary.shot,params_eff);
@@ -283,6 +288,29 @@ for i=1:numel(volume_average_fieldnames)
   end
 end
 
+%% line average
+params_eff.data_request = 'nel';
+line_average.n_e = gdat(params_summary.shot,params_eff);
+line_average_desc.n_e = [params_eff.data_request ' ; ' volume_average.zeff.data_fullpath ' (not vol avrg but to match Iohm)'];
+
+special_fields = {}; % fields needing non-automatic treatments
+line_average_fieldnames = fieldnames(line_average);
+for i=1:numel(line_average_fieldnames)
+  if ~any(strcmp(line_average_fieldnames{i},special_fields))
+    if ~isstruct(ids_summary.line_average.(line_average_fieldnames{i}).value)
+      ids_summary.line_average.(line_average_fieldnames{i}).value = interp1( ...
+          line_average.(line_average_fieldnames{i}).t,line_average.(line_average_fieldnames{i}).data, ...
+          ids_summary.time,'linear',NaN);
+      ids_summary.line_average.(line_average_fieldnames{i}).source = ['gdat request: ' line_average_desc.(line_average_fieldnames{i})];
+    else
+      special_fields{end+1} = line_average_fieldnames{i};
+    end
+  end
+end
+
+
+%%
+
 % cocos automatic transform
 if ~isempty(which('ids_generic_cocos_nodes_transformation_symbolic'))
   [ids_summary,cocoscoeff]=ids_generic_cocos_nodes_transformation_symbolic(ids_summary,'summary',gdat_params.cocos_in, ...
diff --git a/matlab/TCV_IMAS/tcv_ids_headpart.m b/matlab/TCV_IMAS/tcv_ids_headpart.m
index fa90b8cf836577146f499ba9cbe0ff7e2a53d311..53216596c61a9bbccaa9c08fc501e892ad01a1af 100644
--- a/matlab/TCV_IMAS/tcv_ids_headpart.m
+++ b/matlab/TCV_IMAS/tcv_ids_headpart.m
@@ -1,21 +1,20 @@
-function [ids_generic, params_ids_generic] = tcv_ids_headpart(shot,ids_in,ids_name,varargin);
+function [ids_generic, params_ids_generic] = tcv_ids_headpart(shot,ids_in,ids_name,varargin)
 %
 % [ids_generic, params_ids_generic] = tcv_ids_headpart(shot,ids_in,ids_name,varargin);
 %
 % parses inputs and fill in ids_properties
 %
-%
 % varargin options:
-%
-% 'comment': comment to include in ids_properties, using gdat_params for example cocos_in and cocos_out
-% 'homogeneous_time': homogeneous_time in ids_properties: 1 (default) if the whole ids has same time, 0 otherwise
-% 'gdat_params': gdat params structure
+% 'comment':          comment to include in ids_properties, using gdat_params 
+%                     for example cocos_in and cocos_out
+% 'homogeneous_time': homogeneous_time in ids_properties: 
+%                     1 (default) if the whole ids has same time, 0 otherwise
+% 'gdat_params':      gdat params structure
 %
 %
 % example:
 %   [ids_equilibrium, params_ids_equilibrium] = tcv_ids_headpart(shot,ids_equil_empty,'equilibrium','comment','your comment');
 %
-%
 
 % initialize input parser
 p = inputParser;