function valuesOut = exampleHelperFuseOnGet(layer1, layer2, layer3, weights, fuseLayer, valuesIn, varargin)
%exampleHelperFuseOnGet Callback method used by the fusion layer to fusing readings from multiple sensors.
%
%   This callback is provided to the constructor of the 4th layer in the 
%   ego-centric multiLayerMap. The callback executes during calls to the
%   getMapData method, allowing us to customize the object's behavior.
%   
%   Transformations can be as simple as casting incoming values to
%   an internal datatype when setMapData is called, and converting them to
%   double when getMapData is called.
%   
%   For this example, however, the callback makes it so getMapData returns
%   the fused values from all three of the occupancyMap layers.
%   
%   When a function-handle to this helper function is created, the three 
%   occupancyMap layers (LAYER1, LAYER2, LAYER3) and a 1x3 weighting vector
%   (WEIGHTS) are provided as default inputs. This includes them in the 
%   function-handle workspace. When getMapData is called on a mapLayer, this
%   function is also passed the caller object, FUSELAYER, the values
%   retrieved from the map, VALUESIN, and any inputs passed to the
%   getMapData method, VARARGIN.
%
%   In this example, we treat the FUSELAYER as a purely dependent layer, but
%   more complicated workflows could incorporate data stored on the FUSELAYER
%   itself.
    
% Copyright 2020 The MathWorks, Inc.

    if isempty(varargin) && numel(valuesIn) == 1
        % All get/set callbacks are passed the DefaultValue during layer 
        % construction. Therefore we will skip any calls to this function
        % that pass a scalar with no additional inputs.
        valuesOut = valuesIn;
    else
        % Retrieve data from each layer
        d1 = layer1.getMapData(varargin{:});
        d2 = layer2.getMapData(varargin{:});
        d3 = layer3.getMapData(varargin{:});

        % Fuse the layers using the standard probability to int-logodds method
        % of occupancy fusion.
        valuesOut = rawFuse(d1,d2,d3,weights);
    end
end

function probability = rawFuse(d1,d2,d3,weights)
%rawFusion This transform combines the values of each layer using the Logit function 
    
    % Convert all values to logodds using the Logit transform, log(A) = log(Pr(A)/Pr(~A)).
    d1Log = log(d1./(1-d1));
    d2Log = log(d2./(1-d2));
    d3Log = log(d3./(1-d3));
    
    % Combine in logodds form by simply summing the values.
    dFused = d1Log*weights(1) + d2Log*weights(2) + d3Log*weights(3);
    
    % Convert back to probability
    logoddsRatio = exp(dFused);
    probability = 1-(1./logoddsRatio./(1./logoddsRatio + logoddsRatio));
end