diff --git a/zUtil_Indexter/gtIndexFwdSimGrains.m b/zUtil_Indexter/gtIndexFwdSimGrains.m
new file mode 100644
index 0000000000000000000000000000000000000000..5e5c6e44a00c70c4fcfbab0744802e9b95cef290
--- /dev/null
+++ b/zUtil_Indexter/gtIndexFwdSimGrains.m
@@ -0,0 +1,167 @@
+function grain = gtIndexFwdSimGrains(grain, parameters)
+% GTINDEXFWDSIMGRAINS Forward simulates the spot positions for all 
+% reflections in all grains.
+% 
+% grain = gtIndexFwdSimGrains(grain, parameters)
+%
+% ---------------------------------------------------
+%
+% INPUT
+%   grain      - cell array containing grains as in index.mat
+%   parameters - parameters as in the parameters file 
+%
+% OUTPUT
+%   grain.fsim. - added field containing fwd simulation data:
+%    .cu        - U coordinate of center
+%    .cv        - U coordinate of center
+%    .cw        - W (image no.) coordinate of center
+%    .eta       - eta diffraction angle in degrees
+%    .sinth     - sin(theta)
+%    .plref     - plane normal in reference crystal (unstrained theoretical)
+%    .refind    - linear index of reflection in grain
+%    .thetatype - thetatype
+
+%tic
+
+if ~exist('parameters','var')
+    parameters = load('parameters.mat');
+    parameters = parameters.parameters;
+end
+
+
+labgeo = parameters.labgeo;
+samgeo = parameters.samgeo;
+cryst  = parameters.cryst;
+energy = parameters.acq.energy;
+omstep = 180/parameters.acq.nproj;
+
+% Scaling for Lab -> Detector transformation (mm -> pixels)
+detscaleu = 1/labgeo.pixelsizeu ;
+detscalev = 1/labgeo.pixelsizev ;
+
+% Rotation tensor components
+rotcomp = gtMathsRotationMatrixComp(labgeo.rotdir','col');
+
+% Detector projection matrix
+Qdet = gtFedDetectorProjectionTensor(labgeo.detdiru', labgeo.detdirv', ...
+                                     detscaleu, detscalev);
+
+% B matrix for transformation from (hkl) to Cartesian Crystal reference 
+Bmat = gtCrystHKL2CartesianMatrix(cryst.latticepar);
+
+% Coordinates of the plane normals in the Cartesian Crystal system
+pl_ref  = gtCrystHKL2Cartesian(double(cryst.hklsp), Bmat);
+refind0 = 1:size(pl_ref,2);
+
+% D-spacings in the reference crystal for the given reflections
+dsp_ref = gtCrystDSpacing(double(cryst.hkl(:,cryst.thetatypesp)), Bmat);
+
+                                 
+% Rotation tensor describing crystal orientation; calculate all grains 
+% at once for speed-up.
+% (gtCrystRodriguesVector and gtFedRod2RotTensor (or Rod2g) used together 
+% gives the transformation tensor from CRYSTAL TO SAMPLE coordinates)
+Rvec    = gtIndexAllGrainValues(grain,'R_vector',[],1,1:3);
+cry2sam = gtFedRod2RotTensor(Rvec');
+
+
+% Parallel loop through grains
+parfor ii = 1:length(grain)
+                    
+    % Plane normals in the Sample reference
+    pl_sam = cry2sam(:,:,ii) * pl_ref;
+    
+    % Impose strain on grain
+    if ~isfield(grain{ii},'strain')
+        grain{ii}.strain.strainT = NaN(3,3);
+    end
+    
+    if any(isnan(grain{ii}.strain.strainT(:)))
+        %fprintf('No strain info in grain #%d. Using as measured plane normals.\n',ii)
+        pl_samd = pl_sam;
+        drel    = ones(1,size(pl_sam,2));
+    else
+        % New deformed plane normals and relative elongations
+        [pl_samd, drel] = gtStrainPlaneNormals(pl_sam, grain{ii}.strain.strainT);
+    end
+    
+    % d-spacing after applying the strain tensor
+    dsp_d = drel .* dsp_ref;
+
+    % Bragg angles theta in the deformed state
+    sinth = 0.5*gtConvEnergyToWavelength(energy)./dsp_d;
+    
+    % The plane normals need to be brought in the Lab reference where the
+    % beam direction and rotation axis are defined.
+    % Use the Sample -> Lab orientation transformation assuming omega=0;
+    % (vector length preserved for free vectors)
+    sam2lab = [samgeo.dirx; samgeo.diry; samgeo.dirz]';
+    pl_labd = sam2lab*pl_samd;
+    
+    
+    % Predict omega angles: 4 for each (hkl) plane normal (the Friedel pairs are
+    % om1-om3 and om2-om4); -(hkl) plane normals are assumed not to be in the list 
+    [om4, pllab4, ~, rot4, omind4] = gtFedPredictOmegaMultiple(...
+        pl_labd, sinth, labgeo.beamdir', labgeo.rotdir', rotcomp, []);
+    
+    % warning('Check function here! Possible bug!')
+    
+    % Delete those where no reflection occurs
+    todel              = (isnan(om4(1,:)) | isnan(om4(3,:)));
+    om4(:,todel)       = [];
+    omind4(:,todel)    = [];
+    sinth(todel)       = [];
+    pllab4(:,todel,:)  = [];
+    rot4(:,:,todel,:)  = [];
+    
+    plref  = pl_ref(:,~todel);
+    refind = refind0(~todel);
+    thtype = cryst.thetatypesp(~todel);
+    hklsp  = cryst.hklsp(:,~todel);
+    
+    om = reshape(om4',[],1)';
+    plref4  = [plref, plref, plref, plref];
+    sinth4  = [sinth, sinth, sinth, sinth];
+    thtype4 = [thtype, thtype, thtype, thtype];
+    refind4 = [refind, refind, refind, refind];
+    
+    % Diffraction vectors in Lab and Sample
+    dveclab = gtFedPredictDiffVecMultiple(reshape(pllab4,3,[]), labgeo.beamdir');    
+    %dvecsam = gtGeoLab2Sam(dveclab', om, labgeo,...
+    %          parameters.samgeo, 1, 1)';
+        
+    % Etend grain center
+    gc_sam = grain{ii}.center';
+    gc_sam = gc_sam(:,ones(size(dveclab,2),1));
+    
+    % Absolute detector coordinates U,V in pixels 
+    uv = gtFedPredictUVMultiple(rot4, dveclab, gc_sam, labgeo.detrefpos', ...
+         labgeo.detnorm', Qdet, [labgeo.detrefu; labgeo.detrefv]);
+     
+    % Keep only those spots that fall on the detector 
+    keep = (uv(1,:) >= 1) & (labgeo.detsizeu >= uv(1,:)) & ...
+           (uv(2,:) >= 1) & (labgeo.detsizev >= uv(2,:));
+        
+    % Absolute coordinates U,V,W (pixel,pixel,image); to account for 
+    % measurement errors, do not correct for the image number
+    % to be mod(om,360)/omstep 
+    grain{ii}.fsim.cu = uv(1,keep);
+    grain{ii}.fsim.cv = uv(2,keep);
+    grain{ii}.fsim.cw = om(keep)/omstep;
+    
+    grain{ii}.fsim.eta   = gtGeoEtaFromDiffVec(dveclab(:,keep)', labgeo)';
+    grain{ii}.fsim.sinth = sinth4(keep);
+    grain{ii}.fsim.plref = plref4(:,keep);
+    grain{ii}.fsim.refind = refind4(:,keep);
+    grain{ii}.fsim.thetatype = thtype4(keep);
+    %grain{ii}.fsim.dveclab  = reshape(dveclab,3,[],4);
+    %grain{ii}.fsim.dvecsam  = reshape(dvecsam,3,[],4);
+  
+end
+
+%toc
+
+end % of main function
+
+
+
diff --git a/zUtil_Indexter/gtIndexFwdSimPairs.m b/zUtil_Indexter/gtIndexFwdSimPairs.m
new file mode 100644
index 0000000000000000000000000000000000000000..432f53225b222d81d5d31eef56ace968a56fe073
--- /dev/null
+++ b/zUtil_Indexter/gtIndexFwdSimPairs.m
@@ -0,0 +1,272 @@
+function grain = gtIndexFwdSimPairs(grain, labgeo, samgeo, drift, ...
+                 latticepar, omstep, energy)
+% GTINDEXFWDSIMPAIRS Forward simulates spot positions on the detector 
+% for all spots indexed as Friedel pairs.
+% 
+% grain = gtIndexFwdSimPairs(grain, labgeo, samgeo, drift, ...
+%                            latticepar, omstep, energy)
+%
+% ---------------------------------------------------
+%
+% INPUT
+%   grain       - cell array containing grains as in index.mat
+%   labgeo      - as in parameters.labgeo
+%   samgeo      - as in parameters.samgeo
+%   drift       - sample drifts; if empty, no drifts are considered
+%   latticepar  - lattice parameters (1x6)
+%   omstep      - omega rotational stepping (degrees/image)
+%   energy      - beam energy in keV
+%
+% OUTPUT
+%   grain.fsimA - added field containing fwd simulation data for spots A
+%   grain.fsimB - added field containing fwd simulation data for spots B
+
+
+%%%%%%%%%%%%%%%%%%%
+%% Prepare input
+%%%%%%%%%%%%%%%%%%%
+
+% B matrix for transformation from (hkl) to Cartesian Crystal reference 
+Bmat = gtCrystHKL2CartesianMatrix(latticepar);
+
+% Scaling for Lab -> Detector transformation (mm -> pixels)
+detscaleu = 1/labgeo.pixelsizeu ;
+detscalev = 1/labgeo.pixelsizev ;
+
+% Rotation tensor components
+rotcomp = gtMathsRotationMatrixComp(labgeo.rotdir','col');
+
+% Detector projection matrix
+Qdet = gtFedDetectorProjectionTensor(labgeo.detdiru', labgeo.detdirv', ...
+                                     detscaleu, detscalev);
+
+                                 
+% Rotation tensor describing crystal orientation; calculate all grains 
+% at once for speed-up.
+% (gtCrystRodriguesVector and gtFedRod2RotTensor (or Rod2g) used together 
+% gives the transformation tensor from CRYSTAL TO SAMPLE coordinates)
+Rvec    = gtIndexAllGrainValues(grain,'R_vector',[],1,1:3);
+cry2sam = gtFedRod2RotTensor(Rvec');
+
+
+
+for ii = 1:length(grain)
+     
+    if ~isfield(grain{ii},'strain')
+        grain{ii}.strain.strainT = NaN(3,3);
+    end
+        
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    %% Theoretical plane normals in deformed state
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    
+    % Coordinates of the plane normals in the Cartesian Crystal system
+    pl_cry          = gtCrystHKL2Cartesian(grain{ii}.hklsp, Bmat);
+    grain{ii}.plref = pl_cry;
+     
+    % Plane normals in the undrifted SAMPLE reference
+    pl_sam = cry2sam(:,:,ii) * pl_cry;
+    
+    % Impose strain on grain
+    if any(isnan(grain{ii}.strain.strainT(:)))
+        %fprintf('No strain info in grain #%d. Using as measured plane normals.\n',ii)
+        pl_samd = pl_sam;
+        drel    = ones(1,size(pl_sam,2));
+    else
+        % New deformed plane normals and relative elongations
+        [pl_samd, drel] = gtStrainPlaneNormals(pl_sam, grain{ii}.strain.strainT);
+    end
+    
+    % D-spacings in the reference crystal for the given reflections
+    dsp_ref = gtCrystDSpacing(grain{ii}.hkl, Bmat);
+
+    % d-spacing after applying the strain tensor
+    dsp_d = drel .* dsp_ref;
+    
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    %% Apply rotational drift
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+    if ~isempty(drift)
+        % In case of drifts, need to calculate the omega angles for A and 
+        % B reflections separately.
+        
+        grain{ii}.fsimA = sfApplyDrifts(pl_samd, dsp_d, grain{ii}.center',...
+            grain{ii}.omegaA, drift, labgeo, samgeo, rotcomp, Qdet, omstep, energy);
+        
+        grain{ii}.fsimB = sfApplyDrifts(pl_samd, dsp_d, grain{ii}.center',...
+            grain{ii}.omegaB, drift, labgeo, samgeo, rotcomp, Qdet, omstep, energy);
+        
+    else
+        % In case of no drifts, the omega angles for reflections A and B 
+        % can be calculated together.
+
+        % Bragg angles theta in the deformed state
+        sinth_d = 0.5*gtConvEnergyToWavelength(energy)./dsp_d;
+
+        % The plane normals need to be brought in the Lab reference where the
+        % beam direction and rotation axis are defined.
+        % Use the Sample -> Lab orientation transformation assuming omega=0;
+        % (vector length preserved for free vectors)
+        sam2lab = [samgeo.dirx; samgeo.diry; samgeo.dirz]';        
+        pld     = sam2lab*pl_samd;
+        
+        % Predict omega angles: 4 for each plane normal (the Friedel pairs are
+        % om1-om3 and om2-om4)
+        % Do it only once, for A and B at the same time.
+        [om4, pl_lab4, ~, rot4, omind4] = gtFedPredictOmegaMultiple(...
+            pld, sinth_d, labgeo.beamdir', labgeo.rotdir', rotcomp, []);
+        
+        % Check if all reflections occur
+        noref = any(isnan(om4), 1);
+        if any(noref)
+            msg = sprintf('No reflection was predicted for some pairs in grain #%d', ii);
+            error(msg)
+        end
+      
+        
+        % Get fwd simulated data for reflections A and B.
+        % Find the correct omega index for the pairs where the difference is
+        % the smallest (shouldn't matter if grain.omega is the measured one
+        % or the one corrected for the pair).       
+        grain{ii}.fsimA = sfFwdSim(grain{ii}.omegaA, grain{ii}.center', ...
+            sinth_d, om4, pl_lab4, rot4, omind4, labgeo, samgeo, Qdet, omstep);
+        
+        grain{ii}.fsimB = sfFwdSim(grain{ii}.omegaB, grain{ii}.center', ...
+            sinth_d, om4, pl_lab4, rot4, omind4, labgeo, samgeo, Qdet, omstep);
+               
+    end
+  
+    % Extra info
+    if 1
+        grain{ii}.fsimA.drel  = drel;
+        grain{ii}.fsimB.drel  = drel;
+        grain{ii}.fsimA.plsam = pl_samd;
+        grain{ii}.fsimB.plsam = pl_samd;
+    end
+end
+
+
+end % of main function
+
+
+%%%%%%%%%%%%%%%%%%%%%%
+%% SUB-FUNCTIONS
+%%%%%%%%%%%%%%%%%%%%%%
+
+function fsim = sfApplyDrifts(pl, dsp, gc, om, drift, labgeo, ...
+                samgeo, rotcomp, Qdet, omstep, energy)
+% pl    - plane normals before drifts
+% sinth - sin(theta) in deformed state
+% om    - omega-s to interpolate the rotational drift
+% gc    - grain center in Sample reference before drift
+%
+% Use the measured omega position as an approximation to calculate
+% the drifts, because the fwd simulated is not yet known. As the
+% drifts are assumed smooth and slow, this is a good approximation.
+
+    % Plane normals, grain centers and sin(theta) after drifts
+    [pld, gcd, sinthd] = gtFitApplyDrifts(pl, gc, dsp, om, drift, energy);
+    
+    % The plane normals need to be brought in the Lab reference where the 
+    % beam direction and rotation axis are defined.
+    % Use the Sample -> Lab rotation assuming omega=0;
+    % (samgeo.dir norm is always 1, so sam2lab will be preserve vector norms)
+    sam2lab = [samgeo.dirx; samgeo.diry; samgeo.dirz]';
+    pld     = sam2lab*pld;
+    
+    
+    % Predict omega angles: 4 for each plane normal (the Friedel pairs are
+    % om1-om3 and om2-om4)
+    [om4, pllab4, ~, rot4, omind4] = gtFedPredictOmegaMultiple(...
+        pld, sinthd, labgeo.beamdir', labgeo.rotdir', rotcomp, []);
+    
+    % Check if all reflections occur
+    noref = any(isnan(om4), 1);
+    if any(noref)
+        error('No reflection was predicted for some pairs in grain.');
+    end
+    
+    % Find the correct omega index for the pairs where the difference is
+    % the smallest (shouldn't matter if grain.omega is the measured one
+    % or the one corrected for the pair).
+    
+    % Get fwd simulated data for the observed reflections
+    fsim = sfFwdSim(om, gcd, ...
+           sinthd, om4, pllab4, rot4, omind4, labgeo, samgeo, Qdet, omstep);
+    
+end
+
+
+function fsim = sfFwdSim(om_mes, gcsam, sinth, om4, pllab4, rot4, ...
+                omind4, labgeo, samgeo, Qdet, omstep)
+    % Provides the fwd simulation data for a given omega index set.
+
+    % Absolute differences
+    dom = om4 - om_mes([1 1 1 1],:);
+    
+    % Find the indices with the smallest absolute difference; consider 
+    % errors and periodicity of 360deg in omega
+    [~, ind] = min( abs( [dom; dom - 360; dom + 360] ) , [], 1);
+    
+    % Predicted omega is 360deg more
+    omhigh = ( (5 <= ind) & (ind <= 8) );
+
+    % Predicted omega is 360deg less
+    omlow  = ( (9 <= ind) & (ind <= 12) );
+    
+    % Correct indices
+    ind(omhigh) = ind(omhigh) - 4;
+    ind(omlow)  = ind(omlow)  - 8;
+
+    % Get final omega angles (can be <0) using the corresponding linear
+    % indices of omind4
+    linind          = ind + (0:length(ind)-1)*4;
+    fsim.om         = om4(linind);
+    fsim.om(omhigh) = fsim.om(omhigh) - 360; 
+    fsim.om(omlow)  = fsim.om(omlow)  + 360; 
+
+    % Omega index 
+    fsim.omind = omind4(linind);
+
+    % Omegas in a column vector
+    ind1 = (ind==1);
+    ind2 = (ind==2);
+    ind3 = (ind==3);
+    ind4 = (ind==4);
+   
+    % Extract the correct pllab vectors according to omind
+    fsim.pllab         = zeros(3, length(ind));
+    fsim.pllab(:,ind1) = pllab4(:,ind1,1);
+    fsim.pllab(:,ind2) = pllab4(:,ind2,2);
+    fsim.pllab(:,ind3) = pllab4(:,ind3,3);
+    fsim.pllab(:,ind4) = pllab4(:,ind4,4);
+
+    % Extract the correct rotation matrices according to omind
+    fsim.rot           = zeros(3, 3, length(ind));
+    fsim.rot(:,:,ind1) = rot4(:,:,ind1,1);
+    fsim.rot(:,:,ind2) = rot4(:,:,ind2,2);
+    fsim.rot(:,:,ind3) = rot4(:,:,ind3,3);
+    fsim.rot(:,:,ind4) = rot4(:,:,ind4,4);
+   
+        
+    % Diffraction vector
+    fsim.dveclab = gtFedPredictDiffVecMultiple(fsim.pllab, labgeo.beamdir');
+    fsim.dvecsam = gtGeoLab2Sam(fsim.dveclab', fsim.om, labgeo, samgeo, 1, 1)';
+
+    % Make sure grain center is extended
+    gcsam = gcsam(:,ones(size(fsim.dveclab,2),1));
+    
+    % Absolute detector coordinates U,V in pixels 
+    uv = gtFedPredictUVMultiple(fsim.rot, fsim.dveclab, gcsam, labgeo.detrefpos', ...
+         labgeo.detnorm', Qdet, [labgeo.detrefu; labgeo.detrefv]);
+
+     
+    % Absolute coordinates U,V,W (pixel,pixel,image); to account for 
+    % measurement errors, do not correct for the image number
+    % to be mod(om,360)/omstep 
+    fsim.uvw = [uv; fsim.om/omstep];
+   
+end
+
+