classdef Retina < handle
    %RETINA  A biological retina model for image spatio-temporal noise and luminance changes enhancement
    %
    % Class which allows the Gipsa/Listic Labs model to be used with OpenCV.
    %
    % This retina model allows spatio-temporal image processing (applied on
    % still images, video sequences).
    %
    % As a summary, these are the retina model properties:
    %
    % - It applies a spectral whithening (mid-frequency details enhancement)
    % - high frequency spatio-temporal noise reduction
    % - low frequency luminance to be reduced (luminance range compression)
    % - local logarithmic luminance compression allows details to be enhanced
    %   in low light conditions
    %
    % **USE**: this model can be used basically for spatio-temporal video
    % effects but also for:
    %
    % - using the `getParvo` method output matrix: texture analysis with
    %   enhanced signal to noise ratio and enhanced details robust against
    %   input images luminance ranges
    % - using the `getMagno` method output matrix: motion analysis also with
    %   the previously cited properties
    %
    % For more information, refer to the following papers [Benoit2010] and
    % [Herault2010].
    %
    % ## Retina class overview
    %
    % ### Introduction
    %
    % This class provides the main controls of the Gipsa/Listic labs human
    % retina model. This is a non separable spatio-temporal filter modelling
    % the two main retina information channels:
    %
    % - foveal vision for detailed color vision: the parvocellular pathway.
    % - peripheral vision for sensitive transient signals detection (motion
    %   and events): the magnocellular pathway.
    %
    % This model originates from Jeanny Herault work [Herault2010]. It has
    % been involved in Alexandre Benoit phd and his current research
    % [Benoit2010], [Benoit2014]. He currently maintains this module within
    % OpenCV. It includes the work of other Jeanny's phd student such as
    % [Chaix2007] and the log polar transformations of Barthelemy Durette
    % described in Jeanny's book.
    %
    % More into details here is an overview of the retina properties that are
    % implemented here:
    %
    % Regarding luminance and details enhancement:
    %
    % - local logarithmic luminance compression (at the entry point by
    %   photoreceptors and at the output by ganglion cells).
    % - spectral whitening at the Outer Plexiform Layer level (photoreceptors
    %   and horizontal cells spatio-temporal filtering).
    %
    % The former behavior compresses luminance range and allows very bright
    % areas and very dark ones to be visible on the same picture with lots of
    % details. The latter reduces low frequency luminance energy (mean
    % luminance) and enhances mid-frequencies (details). Applied all together,
    % retina well prepares visual signals prior high level analysis. Those
    % properties are really interesting with videos where light changes are
    % dramatically reduced with an interesting temporal consistency.
    %
    % Regarding noise filtering :
    %
    % - high frequency spatial and temporal noise is filtered out. Both
    %   outputs Parvo and Magno pathways benefit from this. Noise reduction
    %   benefits from the non separable spatio-temporal filtering.
    % - at the Parvo output, static textures are enhanced and noise is
    %   filtered (on videos, temporal noise is nicely removed). However, as
    %   human behaviors, moving textures are smoothed. Then, moving object
    %   details can be only enhanced  if the retina tracks it and keeps it
    %   static from its point of view.
    % - at Magno output, it allows a cleaner detection of events (motion,
    %   changes) with reduced noise errors even in difficult lighting
    %   conditions. As a compromise, the Magno output is a low spatial
    %   frequency signal and allows events' blobs to be reliably extracted
    %   (check the cv.TransientAreasSegmentationModule module for that).
    %
    % ### Use
    %
    % This model can be used as a preprocessing stage in the aim of:
    %
    % - performing texture analysis with enhanced signal to noise ratio and
    %   enhanced details which are robust against input images luminance
    %   ranges (check out the parvocellular retina channel output, by using
    %   the provided `getParvo` methods)
    % - performing motion analysis that is also taking advantage of the
    %   previously cited properties (check out the magnocellular retina
    %   channel output, by using the provided `getMagno` methods)
    % - general image/video sequence description using either one or both
    %   channels. An example of the use of Retina in a Bag of Words approach
    %   is given in [Benoit2014].
    %
    % Note:
    %
    % - For ease of use in computer vision applications, the two retina
    %   channels are applied on all the input images. This does not follow the
    %   real retina topology but it is practical from an image processing
    %   point of view. If retina mapping (foveal and parafoveal vision) is
    %   required, use the log sampling capabilities proposed within the class.
    % - Please do not hesitate to contribute by extending the retina
    %   description, code, use cases for complementary explanations and
    %   demonstrations.
    %
    % ### Use case illustrations
    %
    % #### Image preprocessing using the Parvocellular pathway (parvo retina output)
    %
    % As a preliminary presentation, let's start with a visual example. We
    % propose to apply the filter on a low quality color jpeg image with
    % backlight problems. Here is the considered input...
    % *"Well,i could see more with my eyes than what i captured with my camera..."*
    %
    % ![image](https://docs.opencv.org/3.3.1/retinaInput.jpg)
    %
    % Below, the retina foveal model applied on the entire image with default
    % parameters. Details are enforced whatever the local luminance is. Here
    % there contours are strongly enforced but the noise level is kept low.
    % Halo effects are voluntary visible with this configuration. See
    % parameters discussion below and increase `HorizontalCellsGain` near 1 to
    % remove them.
    %
    % ![image](https://docs.opencv.org/3.3.1/retinaOutput_default.jpg)
    %
    % Below, a second retina foveal model output applied on the entire image
    % with a parameters setup focused on naturalness perception.
    % *"Hey, i now recognize my cat, looking at the mountains at the end of the day!"*.
    % Here contours are enforced, luminance is corrected but halos are avoided
    % with this configuration. The backlight effect is corrected and highlight
    % details are still preserved. Then, even on a low quality jpeg image, if
    % some luminance's information remains, the retina is able to reconstruct
    % a proper visual signal. Such configuration is also useful for High
    % Dynamic Range (HDR) images compression to 8bit images as discussed in
    % [Benoit2010] and in the demonstration codes discussed below. As shown at
    % the end of the page, parameter changes from defaults are:
    %
    % - `HorizontalCellsGain = 0.3`
    % - `PhotoreceptorsLocalAdaptationSensitivity = GanglioncellsSensitivity = 0.89`.
    %
    % ![image](https://docs.opencv.org/3.3.1/retinaOutput_realistic.jpg)
    %
    % As observed in this preliminary demo, the retina can be settled up with
    % various parameters, by default, as shown on the figure above, the retina
    % strongly reduces mean luminance energy and enforces all details of the
    % visual scene. Luminance energy and halo effects can be modulated
    % (exaggerated to cancelled as shown on the two examples). In order to use
    % your own parameters, you can use at least one time the cv.Retina.write
    % method which will write a proper XML file with all default parameters.
    % Then, tweak it on your own and reload them at any time using method
    % cv.Retina.setup. These methods update a `RetinaParameters` member
    % structure that is described hereafter. XML parameters file samples are
    % shown at the end of the page.
    %
    % #### Tone mapping processing capability using the Parvocellular pathway (parvo retina output)
    %
    % This retina model naturally handles luminance range compression. Local
    % adaptation stages and spectral whitening contribute to luminance range
    % compression. In addition, high frequency noise that often corrupts tone
    % mapped images is removed at early stages of the process thus leading to
    % natural perception and noise free tone mapping.
    %
    % Compared to the demos shown above, setup differences are the following
    % ones:
    %
    % * load HDR images (OpenEXR format is supported by OpenCV) and cut
    %   histogram borders at ~5% and 95% to eliminate salt&pepper like pixel's
    %   corruption.
    % * apply retina with default parameters along with the following changes
    %   (generic parameters used for the presented illustrations of the
    %   section):
    %   * `HorizontalCellsGain=0.4` (the main change compared to the default
    %     configuration: it strongly reduces halo effects)
    %   * `PhotoreceptorsLocalAdaptationSensitivity=0.99` (a little higher
    %     than default value to enforce local adaptation)
    %   * `GanglionCellsSensitivity=0.95` (also slightly higher than default
    %     for local adaptation enforcement)
    % * get the parvo output using the cv.Retina.getParvo method.
    %
    % Have a look at the end of this page to see how to specify these
    % parameters in a configuration file.
    %
    % The following two illustrations show the effect of such configuration on
    % 2 image samples.
    %
    % - HDR image tone mapping example with generic parameters.
    %   Original image comes from [OpenEXR](http://openexr.com/) samples
    %   (`openexr-images-1.7.0/ScanLines/CandleGlass.exr`)
    %
    %   ![image](https://docs.opencv.org/3.3.1/HDRtoneMapping_candleSample.jpg)
    %
    % - HDR image tone mapping example with the same generic parameters.
    %   Original image comes from
    %   [memorial.exr](http://www.pauldebevec.com/Research/HDR/memorial.exr)
    %
    %   ![image](https://docs.opencv.org/3.3.1/HDRtoneMapping_memorialSample.jpg)
    %
    % #### Motion and event detection using the Magnocellular pathway (magno retina output)
    %
    % Spatio-temporal events can be easily detected using *magno* output of
    % the retina (use the cv.Retina.getMagno method). Its energy linearly
    % increases with motion speed.
    %
    % An event blob detector is proposed with the
    % cv.TransientAreasSegmentationModule class also provided in the
    % bioinspired module. The basic idea is to detect local energy drops with
    % regard of the neighborhood and then to apply a threshold. Such process
    % has been used in a bag of words description of videos on the TRECVid
    % challenge [Benoit2014] and only allows video frames description on
    % transient areas.
    %
    % We present here some illustrations of the retina outputs on some
    % examples taken from [CDNET](http://changedetection.net/) with RGB and
    % thermal videos.
    %
    % NOTE: here, we use the default retina setup that generates halos around
    % strong edges. Note that temporal constants allow a temporal effect to be
    % visible on moting objects (useful for still image illustrations of a
    % video). Halos can be removed by increasing retina Hcells gain while
    % temporal effects can be reduced by decreasing temporal constant values.
    % Also take into account that the two retina outputs are rescaled in range
    % `[0:255]` such that magno output can show a lot of "noise" when nothing
    % moves while drawing it. However, its energy remains low if you retrieve
    % it using cv.Retina.getMagnoRAW getter instead.
    %
    % - Retina processing on RGB image sequence: example from
    %   [CDNET](http://changedetection.net/) (baseline/PETS2006).
    %   Parvo enforces static signals but smooths moving persons since they do
    %   not remain static from its point of view.
    %   Magno channel highligths moving persons, observe the energy mapping on
    %   the one on top, partly behind a dark glass.
    %
    %   ![image](https://docs.opencv.org/3.3.1/VideoDemo_RGB_PETS2006.jpg)
    %
    % - Retina processing on gray levels image sequence: example from
    %   [CDNET](http://changedetection.net/) (thermal/park).
    %   On such grayscale images, parvo channel enforces contrasts while mango
    %   strongly reacts on moving pedestrians
    %
    %   ![image](https://docs.opencv.org/3.3.1/VideoDemo_thermal_park.jpg)
    %
    % ### Literature
    %
    % For more information, refer to the following papers:
    %
    % - Model description: [Benoit2010]
    % - Model use in a Bag of Words approach: [Benoit2014]
    % - Please have a look at the reference work of Jeanny Herault that you
    %   can read in his book: [Herault2010]
    %
    % This retina filter code includes the research contributions of
    % phd/research collegues from which code has been redrawn by the author:
    %
    % - take a look at the `retinacolor.hpp` module to discover Brice Chaix
    %   de Lavarene phD color mosaicing/demosaicing and his reference paper
    %   [Chaix2007]
    %
    % - take a look at `imagelogpolprojection.hpp` to discover retina spatial
    %   log sampling which originates from Barthelemy Durette phd with Jeanny
    %   Herault. A Retina / V1 cortex projection is also proposed and
    %   originates from Jeanny's discussions. More information in the above
    %   cited Jeanny Heraults's book.
    %
    % - Meylan et al. work on HDR tone mapping that is implemented as a
    %   specific method within the model [Meylan2007]
    %
    % ## Retina programming interfaces
    %
    % The proposed class allows the [Gipsa](http://www.gipsa-lab.inpg.fr)
    % (preliminary work) / [Listic](http://www.listic.univ-savoie.fr) labs
    % retina model to be used. It can be applied on still images, images
    % sequences and video sequences.
    %
    % ### Setting up Retina
    %
    % #### Managing the configuration file
    %
    % When using the cv.Retina.write and cv.Retina.load methods, you create or
    % load a XML file that stores Retina configuration.
    %
    % The default configuration is presented below.
    %
    % ```xml
    % <?xml version="1.0"?>
    % <opencv_storage>
    % <OPLandIPLparvo>
    %     <colorMode>1</colorMode>
    %     <normaliseOutput>1</normaliseOutput>
    %     <photoreceptorsLocalAdaptationSensitivity>7.5e-01</photoreceptorsLocalAdaptationSensitivity>
    %     <photoreceptorsTemporalConstant>9.0e-01</photoreceptorsTemporalConstant>
    %     <photoreceptorsSpatialConstant>5.7e-01</photoreceptorsSpatialConstant>
    %     <horizontalCellsGain>0.01</horizontalCellsGain>
    %     <hcellsTemporalConstant>0.5</hcellsTemporalConstant>
    %     <hcellsSpatialConstant>7.</hcellsSpatialConstant>
    %     <ganglionCellsSensitivity>7.5e-01</ganglionCellsSensitivity>
    % </OPLandIPLparvo>
    % <IPLmagno>
    %     <normaliseOutput>1</normaliseOutput>
    %     <parasolCells_beta>0.</parasolCells_beta>
    %     <parasolCells_tau>0.</parasolCells_tau>
    %     <parasolCells_k>7.</parasolCells_k>
    %     <amacrinCellsTemporalCutFrequency>2.0e+00</amacrinCellsTemporalCutFrequency>
    %     <V0CompressionParameter>9.5e-01</V0CompressionParameter>
    %     <localAdaptintegration_tau>0.</localAdaptintegration_tau>
    %     <localAdaptintegration_k>7.</localAdaptintegration_k>
    % </IPLmagno>
    % </opencv_storage>
    % ```
    %
    % Here are some words about all those parameters, tweak them as you wish
    % to amplify or moderate retina effects (contours enforcement, halos
    % effects, motion sensitivity, motion blurring, etc.)
    %
    % #### Basic parameters
    %
    % The simplest parameters are as follows:
    %
    % * __ColorMode__: let the retina process color information (if 1) or gray
    %   scale images (if 0). In that last case, only the first channels of the
    %   input will be processed.
    % * __NormaliseOutput__: each channel has such parameter: if the value is
    %   set to 1, then the considered channel's output is rescaled between 0
    %   and 255. Be aware at this case of the Magnocellular output level
    %   (motion/transient channel detection). Residual noise will also be
    %   rescaled!
    %
    % **Note**: using color requires color channels multiplexing/demultipexing
    % which also demands more processing. You can expect much faster processing
    % using gray levels: it would require around 30 product per pixel for all
    % of the retina processes and it has recently been parallelized for
    % multicore architectures.
    %
    % #### Photo-receptors parameters
    %
    % The following parameters act on the entry point of the retina
    % (photo-receptors) and has impact on all of the following processes.
    % These sensors are low pass spatio-temporal filters that smooth temporal
    % and spatial data and also adjust their sensitivity to local luminance,
    % thus, leads to improving details extraction and high frequency noise
    % canceling.
    %
    % * __PhotoreceptorsLocalAdaptationSensitivity__ between 0 and 1. Values
    %   close to 1 allow high luminance log compression's effect at the
    %   photo-receptors level. Values closer to 0 provide a more linear
    %   sensitivity. Increased alone, it can burn the *Parvo (details channel)*
    %   output image. If adjusted in collaboration with
    %   `GanglionCellsSensitivity`, images can be very contrasted whatever the
    %   local luminance there is at the cost of a naturalness decrease.
    % * __PhotoreceptorsTemporalConstant__ this setups the temporal constant
    %   of the low pass filter effect at the entry of the retina. High value
    %   leads to strong temporal smoothing effect: moving objects are blurred
    %   and can disappear while static object are favored. But when starting
    %   the retina processing, stable state is reached later.
    % * __PhotoreceptorsSpatialConstant__ specifies the spatial constant
    %   related to photo-receptors' lowpass filter's effect. Those parameters
    %   specify the minimum value of the spatial signal period allowed in what
    %   follows. Typically, this filter should cut high frequency noise. On
    %   the other hand, a 0 value cuts none of the noise while higher values
    %   start to cut high spatial frequencies, and progressively lower
    %   frequencies... Be aware to not go to high levels if you want to see
    %   some details of the input images! A good compromise for color images
    %   is a 0.53 value since such choice won't affect too much the color
    %   spectrum. Higher values would lead to gray and blurred output images.
    %
    % #### Horizontal cells parameters
    %
    % This parameter set tunes the neural network connected to the
    % photo-receptors, the horizontal cells. It modulates photo-receptors
    % sensitivity and completes the processing for final spectral whitening
    % (part of the spatial band pass effect thus favoring visual details
    % enhancement).
    %
    % * __HorizontalCellsGain__ here is a critical parameter! If you are not
    %   interested with the mean luminance and want just to focus on details
    %   enhancement, then, set this parameterto zero. However, if you want to
    %   keep some environment luminance's data, let some low spatial
    %   frequencies pass into the system and set a higher value (<1).
    % * __HCellsTemporalConstant__ similar to photo-receptors, this parameter
    %   acts on the temporal constant of a low pass temporal filter that
    %   smooths input data. Here, a high value generates a high retina after
    %   effect while a lower value makes the retina more reactive. This value
    %   should be lower than `PhotoreceptorsTemporalConstant` to limit strong
    %   retina after effects.
    % * __HCellsSpatialConstant__ is the spatial constant of these cells
    %   filter's low pass one. It specifies the lowest spatial frequency
    %   allowed in what follows. Visually, a high value leads to very low
    %   spatial frequencies processing and leads to salient halo effects.
    %   Lower values reduce this effect but has the limit of not go lower than
    %   the value of `PhotoreceptorsSpatialConstant`. Those 2 parameters
    %   actually specify the spatial band-pass of the retina.
    %
    % **NOTE**: Once the processing managed by the previous parameters is done,
    % input data is cleaned from noise and luminance is already partly
    % enhanced. The following parameters act on the last processing stages of
    % the two outing retina signals.
    %
    % #### Parvo (details channel) dedicated parameter
    %
    % * __GanglionCellsSensitivity__ specifies the strength of the final local
    %   adaptation occurring at the output of this details' dedicated channel.
    %   Parameter values remain between 0 and 1. Low value tend to give a
    %   linear response while higher values enforce the remaining low
    %   contrasted areas.
    %
    % **Note**: this parameter can correct eventual burned images by favoring
    % low energetic details of the visual scene, even in bright areas.
    %
    % #### IPL Magno (motion/transient channel) parameters
    %
    % Once image's information are cleaned, this channel acts as a high pass
    % temporal filter that selects only the signals related to transient
    % signals (events, motion, etc.). A low pass spatial filter smooths
    % extracted transient data while a final logarithmic compression enhances
    % low transient events thus enhancing event sensitivity.
    %
    % * __ParasolCellsBeta__ generally set to zero, can be considered as an
    %   amplifier gain at the entry point of this processing stage. Generally
    %   set to 0.
    % * __ParasolCellsTau__ the temporal smoothing effect that can be added
    % * __ParasolCellsK__ the spatial constant of the spatial filtering
    %   effect, set it at a high value to favor low spatial frequency signals
    %   that are lower subject for residual noise.
    % * __AmacrinCellsTemporalCutFrequency__ specifies the temporal constant
    %   of the high pass filter. High values let slow transient events to be
    %   selected.
    % * __V0CompressionParameter__ specifies the strength of the log
    %   compression. Similar behaviors to previous description but here
    %   enforces sensitivity of transient events.
    % * __LocalAdaptintegrationTau__ generally set to 0, has no real use
    %   actually in here.
    % * __LocalAdaptintegrationK__ specifies the size of the area on which
    %   local adaptation is performed. Low values lead to short range local
    %   adaptation (higher sensitivity to noise), high values secure log
    %   compression.
    %
    % ### Demos and experiments
    %
    % #### First time experiments
    %
    % Here are some code snippets to shortly show how to use Retina with
    % default parameters (with halo effects). Next section redirects to more
    % complete demos provided with the main retina class.
    %
    % Here is presented how to process a webcam stream with the following
    % steps:
    %
    % - load a frist input image to get its size
    % - allocate a retina instance with appropriate input size
    % - loop over grabbed frames:
    %   - grab a new frame
    %   - run on a frame
    %   - call the two output getters
    %   - display retina outputs
    %
    % See `retina_demo.m` MATLAB sample.
    %
    % #### More complete demos
    %
    % Note: Complementary to the following examples, have a look at the Retina
    % tutorial in the tutorial/contrib section for complementary explanations.
    %
    % ## References
    % [Benoit2010]:
    % > Benoit A., Caplier A., Durette B., Herault, J.; "Using Human Visual
    % > System Modeling For Bio-inspired Low Level Image Processing", Elsevier,
    % > Computer Vision and Image Understanding 114 (2010), pp. 758-773,
    % > [DOI](http://dx.doi.org/10.1016/j.cviu.2010.01.011)
    %
    % [Benoit2014]:
    % > Strat S.T., Benoit A., Lambert P.; "Retina enhanced bag of words
    % > descriptors for video classification". In Proceedings of the 22nd
    % > European Signal Processing Conference (EUSIPCO), 2014, pp. 1307-1311.
    %
    % [Herault2010]:
    % > Jeanny Herault; "Vision: Images, Signals and Neural Networks: Models
    % > of Neural Processing in Visual Perception" (Progress in Neural
    % > Processing), ISBN: 9814273686. WAPI (Tower ID): 113266891.
    %
    % [Chaix2007]:
    % > B. Chaix de Lavarene, D. Alleysson, B. Durette, J. Herault (2007).
    % > "Efficient demosaicing through recursive filtering". IEEE
    % > International Conference on Image Processing ICIP 2007.
    %
    % [Meylan2007]:
    % > Meylan L., Alleysson D., and Susstrunk S., "A Model of Retinal Local
    % > Adaptation for the Tone Mapping of Color Filter Array Images", Journal
    % > of Optical Society of America, A, Vol. 24, N. 9, September, 1st, 2007,
    % > pp. 2807-2816
    %
    % See also: cv.RetinaFastToneMapping, cv.TransientAreasSegmentationModule
    %

    properties (SetAccess = private)
        % Object ID
        id
    end

    methods
        function this = Retina(inputSize, varargin)
            %RETINA  Constructor from standardized interface to create a Retina instance
            %
            %     obj = cv.Retina(inputSize)
            %     obj = cv.Retina(inputSize, 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __inputSize__ the input frame size `[w,h]`.
            %
            % ## Options
            % * __ColorMode__ the chosen processing mode: with or without
            %   color processing. default true
            % * __ColorSamplingMethod__ specifies which kind of color sampling
            %   will be used, default 'Bayer'. One of:
            %   * __Random__ each pixel position is either R, G or B in a
            %     random choice
            %   * __Diagonal__ color sampling is RGBRGBRGB...,
            %     line 2 BRGBRGBRG..., line 3 GBRGBRGBR...
            %   * __Bayer__ standard bayer sampling
            % * __UseRetinaLogSampling__ activate retina log sampling. If true,
            %   the 2 following parameters can be used. default false
            % * __ReductionFactor__ only useful if param
            %   `UseRetinaLogSampling=true`, specifies the reduction factor of
            %   the output frame (as the center (fovea) is high resolution and
            %   corners can be underscaled, then a reduction of the output is
            %   allowed without precision leak). default 1.0
            % * __SamplingStrength__ only useful if param
            %   `UseRetinaLogSampling=true`, specifies the strength of the log
            %   scale that is applied. default 10.0
            %
            % See also: cv.Retina.run
            %
            this.id = Retina_(0, 'new', inputSize, varargin{:});
        end

        function delete(this)
            %DELETE  Destructor
            %
            %     obj.delete()
            %
            % See also: cv.Retina
            %
            if isempty(this.id), return; end
            Retina_(this.id, 'delete');
        end
    end

    %% Algorithm
    methods
        function clear(this)
            %CLEAR  Clears the algorithm state
            %
            %     obj.clear()
            %
            % See also: cv.Retina.empty, cv.Retina.load
            %
            Retina_(this.id, 'clear');
        end

        function b = empty(this)
            %EMPTY  Checks if detector object is empty
            %
            %     b = obj.empty()
            %
            % ## Output
            % * __b__ Returns true if the detector object is empty (e.g in the
            %   very beginning or after unsuccessful read).
            %
            % See also: cv.Retina.clear, cv.Retina.load
            %
            b = Retina_(this.id, 'empty');
        end

        function save(this, filename)
            %SAVE  Saves the algorithm parameters to a file
            %
            %     obj.save(filename)
            %
            % ## Input
            % * __filename__ Name of the file to save to.
            %
            % This method stores the algorithm parameters in the specified
            % XML or YAML file.
            %
            % See also: cv.Retina.load
            %
            Retina_(this.id, 'save', filename);
        end

        function load(this, fname_or_str, varargin)
            %LOAD  Loads algorithm from a file or a string
            %
            %     obj.load(fname)
            %     obj.load(str, 'FromString',true)
            %     obj.load(..., 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __fname__ Name of the file to read.
            % * __str__ String containing the serialized model you want to
            %   load.
            %
            % ## Options
            % * __ObjName__ The optional name of the node to read (if empty,
            %   the first top-level node will be used). default empty
            % * __FromString__ Logical flag to indicate whether the input is a
            %   filename or a string containing the serialized model.
            %   default false
            %
            % This method reads algorithm parameters from the specified XML or
            % YAML file (either from disk or serialized string). The previous
            % algorithm state is discarded.
            %
            % See also: cv.Retina.save
            %
            Retina_(this.id, 'load', fname_or_str, varargin{:});
        end

        function name = getDefaultName(this)
            %GETDEFAULTNAME  Returns the algorithm string identifier
            %
            %     name = obj.getDefaultName()
            %
            % ## Output
            % * __name__ This string is used as top level XML/YML node tag
            %   when the object is saved to a file or string.
            %
            % See also: cv.Retina.save, cv.Retina.load
            %
            name = Retina_(this.id, 'getDefaultName');
        end
    end

    %% Retina
    methods
        function sz = getInputSize(this)
            %GETINPUTSIZE  Retreive retina input buffer size
            %
            %     sz = obj.getInputSize()
            %
            % ## Output
            % * __sz__ the retina input buffer size
            %
            % See also: cv.Retina.getOutputSize
            %
            sz = Retina_(this.id, 'getInputSize');
        end

        function sz = getOutputSize(this)
            %GETOUTPUTSIZE  Retreive retina output buffer size that can be different from the input if a spatial log transformation is applied
            %
            %     sz = obj.getOutputSize()
            %
            % ## Output
            % * __sz__ the retina output buffer size
            %
            % See also: cv.Retina.getInputSize
            %
            sz = Retina_(this.id, 'getOutputSize');
        end

        function setup(this, retinaParameterFile, varargin)
            %SETUP  Try to open an XML retina parameters file to adjust current retina instance setup
            %
            %     obj.setup(retinaParameterFile)
            %     obj.setup(retinaParameterFile, 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __retinaParameterFile__ the parameters filename.
            %
            % ## Options
            % * __ApplyDefaultSetupOnFailure__ set to true if an error must be
            %   thrown on error. default true
            %
            % If the xml file does not exist, then default setup is applied.
            % Warning: Exceptions are thrown if read XML file is not valid.
            %
            % You can retrieve the current parameters structure using the
            % method cv.Retina.getParameters and update it before running
            % method cv.Retina.setupParameters.
            %
            % See also: cv.Retina.setupParameters, cv.Retina.write
            %
            Retina_(this.id, 'setup', retinaParameterFile, varargin{:});
        end

        function setupParameters(this, varargin)
            %SETUPPARAMETERS  Pass retina parameters to adjust current retina instance setup
            %
            %     obj.setupParameters('OptionName',optionValue, ...)
            %
            % ## Options
            % * __OPLandIplParvo__ Outer Plexiform Layer (OPL) and Inner
            %   Plexiform Layer Parvocellular (IplParvo) parameters.
            % * __IplMagno__ Inner Plexiform Layer Magnocellular channel
            %   (IplMagno).
            %
            % ### `OPLandIplParvo` options
            % See cv.Retina.setupOPLandIPLParvoChannel options.
            %
            % ### `IplMagno` options
            % See cv.Retina.setupIPLMagnoChannel options.
            %
            % Specify retina model parameters structure, with the new target
            % configuration.
            %
            % For better clarity, check explenations on the comments of
            % methods `setupOPLandIPLParvoChannel` and `setupIPLMagnoChannel`.
            %
            % Here is the default configuration file of the retina module. It
            % gives results such as the first retina output shown on the top
            % of this page.
            %
            % ```xml
            % <?xml version="1.0"?>
            % <opencv_storage>
            % <OPLandIPLparvo>
            %     <colorMode>1</colorMode>
            %     <normaliseOutput>1</normaliseOutput>
            %     <photoreceptorsLocalAdaptationSensitivity>7.5e-01</photoreceptorsLocalAdaptationSensitivity>
            %     <photoreceptorsTemporalConstant>9.0e-01</photoreceptorsTemporalConstant>
            %     <photoreceptorsSpatialConstant>5.3e-01</photoreceptorsSpatialConstant>
            %     <horizontalCellsGain>0.01</horizontalCellsGain>
            %     <hcellsTemporalConstant>0.5</hcellsTemporalConstant>
            %     <hcellsSpatialConstant>7.</hcellsSpatialConstant>
            %     <ganglionCellsSensitivity>7.5e-01</ganglionCellsSensitivity>
            % </OPLandIPLparvo>
            % <IPLmagno>
            %     <normaliseOutput>1</normaliseOutput>
            %     <parasolCells_beta>0.</parasolCells_beta>
            %     <parasolCells_tau>0.</parasolCells_tau>
            %     <parasolCells_k>7.</parasolCells_k>
            %     <amacrinCellsTemporalCutFrequency>2.0e+00</amacrinCellsTemporalCutFrequency>
            %     <V0CompressionParameter>9.5e-01</V0CompressionParameter>
            %     <localAdaptintegration_tau>0.</localAdaptintegration_tau>
            %     <localAdaptintegration_k>7.</localAdaptintegration_k>
            % </IPLmagno>
            % </opencv_storage>
            % ```
            %
            % Here is the "realistic" setup used to obtain the second retina
            % output shown on the top of this page.
            %
            % ```xml
            % <?xml version="1.0"?>
            % <opencv_storage>
            % <OPLandIPLparvo>
            %     <colorMode>1</colorMode>
            %     <normaliseOutput>1</normaliseOutput>
            %     <photoreceptorsLocalAdaptationSensitivity>8.9e-01</photoreceptorsLocalAdaptationSensitivity>
            %     <photoreceptorsTemporalConstant>9.0e-01</photoreceptorsTemporalConstant>
            %     <photoreceptorsSpatialConstant>5.3e-01</photoreceptorsSpatialConstant>
            %     <horizontalCellsGain>0.3</horizontalCellsGain>
            %     <hcellsTemporalConstant>0.5</hcellsTemporalConstant>
            %     <hcellsSpatialConstant>7.</hcellsSpatialConstant>
            %     <ganglionCellsSensitivity>8.9e-01</ganglionCellsSensitivity>
            % </OPLandIPLparvo>
            % <IPLmagno>
            %     <normaliseOutput>1</normaliseOutput>
            %     <parasolCells_beta>0.</parasolCells_beta>
            %     <parasolCells_tau>0.</parasolCells_tau>
            %     <parasolCells_k>7.</parasolCells_k>
            %     <amacrinCellsTemporalCutFrequency>2.0e+00</amacrinCellsTemporalCutFrequency>
            %     <V0CompressionParameter>9.5e-01</V0CompressionParameter>
            %     <localAdaptintegration_tau>0.</localAdaptintegration_tau>
            %     <localAdaptintegration_k>7.</localAdaptintegration_k>
            % </IPLmagno>
            % </opencv_storage>
            % ```
            %
            % See also: cv.Retina.setup, cv.Retina.setupOPLandIPLParvoChannel,
            %  cv.Retina.setupIPLMagnoChannel
            %
            Retina_(this.id, 'setupParameters', varargin{:});
        end

        function setupOPLandIPLParvoChannel(this, varargin)
            %SETUPOPLANDIPLPARVOCHANNEL  Setup the OPL and IPL parvo channels (see biologocal model)
            %
            %     obj.setupOPLandIPLParvoChannel('OptionName',optionValue, ...)
            %
            % ## Options
            % * __ColorMode__ specifies if (true) color is processed of not
            %   (false) to then processing gray level image. default true
            % * __NormaliseOutput__ specifies if (true) output is rescaled
            %   between 0 and 255 of not (false). default true
            % * __PhotoreceptorsLocalAdaptationSensitivity__ the photoreceptors
            %   sensitivity renage is 0-1 (more log compression effect when
            %   value increases). default 0.7
            % * __PhotoreceptorsTemporalConstant__ the time constant of the
            %   first order low pass filter of the photoreceptors, use it to
            %   cut high temporal frequencies (noise or fast motion), unit is
            %   frames, typical value is 1 frame. default 0.5
            % * __PhotoreceptorsSpatialConstant__ the spatial constant of the
            %   first order low pass filter of the photoreceptors, use it to
            %   cut high spatial frequencies (noise or thick contours), unit
            %   is pixels, typical value is 1 pixel. default 0.53
            % * __HorizontalCellsGain__ gain of the horizontal cells network,
            %   if 0, then the mean value of the output is zero, if the
            %   parameter is near 1, then, the luminance is not filtered and
            %   is still reachable at the output, typicall value is 0.
            %   default 0.0
            % * __HCellsTemporalConstant__ the time constant of the first
            %   order low pass filter of the horizontal cells, use it to cut
            %   low temporal frequencies (local luminance variations), unit is
            %   frames, typical value is 1 frame, as the photoreceptors.
            %   default 1.0
            % * __HCellsSpatialConstant__ the spatial constant of the first
            %   order low pass filter of the horizontal cells, use it to cut
            %   low spatial frequencies (local luminance), unit is pixels,
            %   typical value is 5 pixel, this value is also used for local
            %   contrast computing when computing the local contrast
            %   adaptation at the ganglion cells level (Inner Plexiform Layer
            %   parvocellular channel model). default 7.0
            % * __GanglionCellsSensitivity__ the compression strengh of the
            %   ganglion cells local adaptation output, set a value between
            %   0.6 and 1 for best results, a high value increases more the
            %   low value sensitivity and the output saturates faster,
            %   recommended value: 0.7. default 0.7
            %
            % OPL is referred as Outer Plexiform Layer of the retina, it
            % allows the spatio-temporal filtering which withens the spectrum
            % and reduces spatio-temporal noise while attenuating global
            % luminance (low frequency energy) IPL parvo is the OPL next
            % processing stage, it refers to a part of the Inner Plexiform
            % layer of the retina, it allows high contours sensitivity in
            % foveal vision. See reference papers for more information. For
            % more information, please have a look at the paper [Benoit2010].
            %
            % See also: cv.Retina.setupIPLMagnoChannel
            %
            Retina_(this.id, 'setupOPLandIPLParvoChannel', varargin{:});
        end

        function setupIPLMagnoChannel(this, varargin)
            %SETUPIPLMAGNOCHANNEL  Set parameters values for the Inner Plexiform Layer (IPL) magnocellular channel
            %
            %     obj.setupIPLMagnoChannel('OptionName',optionValue, ...)
            %
            % ## Options
            % * __NormaliseOutput__ specifies if (true) output is rescaled
            %   between 0 and 255 of not (false). default true
            % * __ParasolCellsBeta__ the low pass filter gain used for local
            %   contrast adaptation at the IPL level of the retina (for
            %   ganglion cells local adaptation), typical value is 0.
            %   default 0.0
            % * __ParasolCellsTau__ the low pass filter time constant used for
            %   local contrast adaptation at the IPL level of the retina (for
            %   ganglion cells local adaptation), unit is frame, typical value
            %   is 0 (immediate response). default 0.0
            % * __ParasolCellsK__ the low pass filter spatial constant used
            %   for local contrast adaptation at the IPL level of the retina
            %   (for ganglion cells local adaptation), unit is pixels, typical
            %   value is 5. default 7.0
            % * __AmacrinCellsTemporalCutFrequency__ the time constant of the
            %   first order high pass fiter of the magnocellular way (motion
            %   information channel), unit is frames, typical value is 1.2.
            %   default 1.2
            % * __V0CompressionParameter__ the compression strengh of the
            %   ganglion cells local adaptation output, set a value between
            %   0.6 and 1 for best results, a high value increases more the
            %   low value sensitivity and the output saturates faster,
            %   recommended value: 0.95. default 0.95
            % * __LocalAdaptintegrationTau__ specifies the temporal constant
            %   of the low pas filter involved in the computation of the local
            %   "motion mean" for the local adaptation computation. default 0.0
            % * __LocalAdaptintegrationK__ specifies the spatial constant of
            %   the low pas filter involved in the computation of the local
            %   "motion mean" for the local adaptation computation. default 7.0
            %
            % This channel processes signals output from OPL processing stage
            % in peripheral vision, it allows motion information enhancement.
            % It is decorrelated from the details channel. See reference
            % papers for more details.
            %
            % See also: cv.Retina.setupOPLandIPLParvoChannel
            %
            Retina_(this.id, 'setupIPLMagnoChannel', varargin{:});
        end

        function params = getParameters(this)
            %GETPARAMETERS  Retrieve the current retina parameters values in a structure
            %
            %     params = obj.getParameters()
            %
            % ## Output
            % * __params__ the current parameters setup.
            %
            % See also: cv.Retina.setupParameters, cv.Retina.printSetup
            %
            params = Retina_(this.id, 'getParameters');
        end

        function str = printSetup(this)
            %PRINTSETUP  Outputs a string showing the used parameters setup
            %
            %     str = obj.printSetup()
            %
            % ## Output
            % * __str__ a string which contains formatted parameters
            %   information.
            %
            % See also: cv.Retina.getParameters
            %
            str = Retina_(this.id, 'printSetup');
        end

        function varargout = write(this, fs)
            %WRITE  Write xml/yml formatted parameters information
            %
            %     obj.write(fs)
            %     str = obj.write(fs)
            %
            % ## Input
            % * __fs__ the filename of the xml file that will be open and
            %   writen with formatted parameters information.
            %
            % ## Output
            % * __str__ optional output. If requested, the parameters are
            %   persisted to a string in memory instead of writing to disk.
            %
            % See also: cv.Retina.setup
            %
            [varargout{1:nargout}] = Retina_(this.id, 'write', fs);
        end

        function run(this, inputImage)
            %RUN  Method which allows retina to be applied on an input image
            %
            %     obj.run(inputImage)
            %
            % ## Input
            % * __inputImage__ the input image to be processed, can be gray
            %   level or BGR coded in any format (from 8bit to 16bits).
            %
            % After run, encapsulated retina module is ready to deliver its
            % outputs using dedicated acccessors, see `getParvo` and
            % `getMagno` methods.
            %
            % See also: cv.Retina.getParvo, cv.Retina.getMagno
            %
            if true
                %HACK: temp fix to get around an issue when OpenCL is enabled
                val = cv.Utils.useOptimized();
                cv.Utils.setUseOptimized(false);
                cObj = onCleanup(@() cv.Utils.setUseOptimized(val));
            end
            Retina_(this.id, 'run', inputImage);
        end

        function outputToneMappedImage = applyFastToneMapping(this, inputImage)
            %APPLYFASTTONEMAPPING  Method which processes an image in the aim to correct its luminance correct backlight problems, enhance details in shadows
            %
            %     outputToneMappedImage = obj.applyFastToneMapping(inputImage)
            %
            % ## Input
            % * __inputImage__ the input image to process (should be coded in
            %   float format `single`: 1/3/4-channels, the 4th channel won't
            %   be considered).
            %
            % ## Output
            % * __outputToneMappedImage__ the output 8bit/channel tone mapped
            %   image (`uint8` with 1/3-channels format).
            %
            % This method is designed to perform High Dynamic Range image tone
            % mapping (compress >8bit/pixel images to 8bit/pixel). This is a
            % simplified version of the Retina Parvocellular model (simplified
            % version of the `run`/`getParvo` methods call) since it does not
            % include the spatio-temporal filter modelling the Outer Plexiform
            % Layer of the retina that performs spectral whitening and many
            % other stuff. However, it works great for tone mapping and in a
            % faster way.
            %
            % Check the demos and experiments section to see examples and the
            % way to perform tone mapping using the original retina model and
            % the method.
            %
            % See also: cv.RetinaFastToneMapping
            %
            outputToneMappedImage = Retina_(this.id, 'applyFastToneMapping', inputImage);
        end

        function parvo = getParvo(this)
            %GETPARVO  Accessor of the details channel of the retina (models foveal vision)
            %
            %     parvo = obj.getParvo()
            %
            % ## Output
            % * __parvo__ the output buffer, format can be:
            %   * a matrix, this output is rescaled for standard 8bits image
            %     processing use in OpenCV
            %   * RAW methods actually return a 1D matrix (encoding is
            %     `R1, R2, ..., Rn, G1, G2, ..., Gn, B1, B2, ..., Bn`), this
            %     output is the original retina filter model output, without
            %     any quantification or rescaling.
            %
            % Warning, `getParvoRAW` methods return buffers that are not
            % rescaled within range [0;255] while the non RAW method allows a
            % normalized matrix to be retrieved.
            %
            % See also: cv.Retina.getParvoRAW
            %
            parvo = Retina_(this.id, 'getParvo');
        end

        function parvo = getParvoRAW(this)
            %GETPARVORAW  Accessor of the details channel of the retina (models foveal vision)
            %
            %     parvo = obj.getParvoRAW()
            %
            % ## Output
            % * __parvo__ the output buffer, format can be:
            %   * a matrix, this output is rescaled for standard 8bits image
            %     processing use in OpenCV
            %   * RAW methods actually return a 1D matrix (encoding is
            %     `R1, R2, ..., Rn, G1, G2, ..., Gn, B1, B2, ..., Bn`), this
            %     output is the original retina filter model output, without
            %     any quantification or rescaling.
            %
            % Warning, `getParvoRAW` methods return buffers that are not
            % rescaled within range [0;255] while the non RAW method allows a
            % normalized matrix to be retrieved.
            %
            % See also: cv.Retina.getParvo
            %
            parvo = Retina_(this.id, 'getParvoRAW');
        end

        function magno = getMagno(this)
            %GETMAGNO  Accessor of the motion channel of the retina (models peripheral vision)
            %
            %     magno = obj.getMagno()
            %
            % ## Output
            % * __magno__ the output buffer, format can be:
            %   * a matrix, this output is rescaled for standard 8bits image
            %     processing use in OpenCV
            %   * RAW methods actually return a 1D matrix (encoding is
            %     `M1, M2, ..., Mn`), this output is the original retina filter
            %     model output, without any quantification or rescaling.
            %
            % Warning, `getMagnoRAW` methods return buffers that are not
            % rescaled within range [0;255] while the non RAW method allows a
            % normalized matrix to be retrieved.
            %
            % See also: cv.Retina.getMagnoRAW
            %
            magno = Retina_(this.id, 'getMagno');
        end

        function magno = getMagnoRAW(this)
            %GETMAGNORAW  Accessor of the motion channel of the retina (models peripheral vision)
            %
            %     magno = obj.getMagnoRAW()
            %
            % ## Output
            % * __magno__ the output buffer, format can be:
            %   * a matrix, this output is rescaled for standard 8bits image
            %     processing use in OpenCV
            %   * RAW methods actually return a 1D matrix (encoding is
            %     `M1, M2, ..., Mn`), this output is the original retina filter
            %     model output, without any quantification or rescaling.
            %
            % Warning, `getMagnoRAW` methods return buffers that are not
            % rescaled within range [0;255] while the non RAW method allows a
            % normalized matrix to be retrieved.
            %
            % See also: cv.Retina.getMagno
            %
            magno = Retina_(this.id, 'getMagnoRAW');
        end

        function setColorSaturation(this, varargin)
            %SETCOLORSATURATION  Activate color saturation as the final step of the color demultiplexing process
            %
            %     obj.setColorSaturation('OptionName',optionValue, ...)
            %
            % ## Options
            % * __SaturateColors__ boolean that activates color saturation (if
            %   true) or desactivate (if false). default true
            % * __ColorSaturationValue__ the saturation factor: a simple
            %   factor applied on the chrominance buffers. default 4.0
            %
            % This saturation is a sigmoide function applied to each channel
            % of the demultiplexed image.
            %
            % See also: cv.Retina.run
            %
            Retina_(this.id, 'setColorSaturation', varargin{:});
        end

        function clearBuffers(this)
            %CLEARBUFFERS  Clears all retina buffers
            %
            %     obj.clearBuffers()
            %
            % (equivalent to opening the eyes after a long period of eye
            % close) whatchout the temporal transition occuring just after
            % this method call.
            %
            % See also: cv.Retina.run
            %
            Retina_(this.id, 'clearBuffers');
        end

        function activateMovingContoursProcessing(this, activate)
            %ACTIVATEMOVINGCONTOURSPROCESSING  Activate/desactivate the Magnocellular pathway processing (motion information extraction)
            %
            %     obj.activateMovingContoursProcessing(activate)
            %
            % ## Input
            % * __activate__ true if Magnocellular output should be activated,
            %   false if not. If activated, the Magnocellular output can be
            %   retrieved using the cv.Retina.getMagno method.
            %
            % By default, it is activated.
            %
            % See also: cv.Retina.activateContoursProcessing
            %
            Retina_(this.id, 'activateMovingContoursProcessing', activate);
        end

        function activateContoursProcessing(this, activate)
            %ACTIVATECONTOURSPROCESSING  Activate/desactivate the Parvocellular pathway processing (contours information extraction)
            %
            %     obj.activateContoursProcessing(activate)
            %
            % ## Input
            % * __activate__ true if Parvocellular (contours information
            %   extraction) output should be activated, false if not. If
            %   activated, the Parvocellular output can be retrieved using the
            %   cv.Retina.getParvo method.
            %
            % By default, it is activated.
            %
            % See also: cv.Retina.activateMovingContoursProcessing
            %
            Retina_(this.id, 'activateContoursProcessing', activate);
        end
    end

end


filename='Cantilever_triangle_coarse';
 ptype = 'MACRO';
method = 'SIMPALL';
materialType = 'ISOTROPIC';
initial_case = 'full';
cost = {'compliance'};
weights = [1, 0.1];
constraint = {'volumeConstraint'};
optimizer = 'IPOPT';
incrementFactor = 1;
designVariable = 'Density';
filterType = 'P1';

nsteps = 1;
Vfrac_final = 0.4;
Perimeter_target = 1;
optimality_final = 1e-3;
constr_final =1e-3;

Vfrac_initial = 1;
optimality_initial = 1e-3;
constr_initial = 1e-3;
TOL.rho_plus = 1;
TOL.rho_minus = 0;
TOL.E_plus = 1;
TOL.E_minus = 1e-3;
TOL.nu_plus = 1/3;
TOL.nu_minus = 1/3;


% example: get s
%
% load ROIfile
% for each voxel:
%   - remove session means
%   - HP filter
%   - convert to percent change
%   - fit model
%   - save fits and residual

/Users/tor/Documents/Tor_Documents/CurrentExperiments/VNL/ROIFILES
load ../vnl_condf.mat

hrf = hrf ./ max(hrf);
[LinearX] = getPredictors(vnl_condf,hrf);
LinearX = LinearX - repmat(mean(LinearX),size(LinearX,1),1);

xtxitx = pinv(LinearX);

D = dir('*vis.mat');
b_by_ymean = [];

for s = 1:length(D)

    % load the file
    load(D(s).name)
    eval(['ROI = ' D(s).name(1:end-4)])

    clear b, clear sigma

for i = 1:size(ROI.ts.indiv,2),

        if length(ROI.adjustedy) == 6020
			[y,ymean] = voistat('adjusty',ROI.ts.indiv(:,i),41,.5,7);
		else
			[y,ymean] = voistat('adjusty',ROI.ts.indiv(:,i),41,.5,8);
		end

    b(:,i) = xtxitx(:,1:length(y)) * y;
    sigma(i) = std(y - LinearX(1:length(y),:) * b(:,i));,

end

%mean(b')
%sigma

%btmp = xtxitx * ROI.adjustedy
%figure; plot(ROI.adjustedy); hold on; plot(LinearX * btmp,'r')

    B(s,:) = mean(b');
    SIGMA(s) = mean(sigma);
    SNR(s,:) = mean(b ./ repmat(sigma,6,1),2)';

end

save vnl_snr_out B SIGMA SNR b_by_ymean D

B(1:2,:) = [];
sigma(1:2) = [];
SNR(1:2,:) = [];

% mean B, 1 2 5 6 10 11 flashes
% 0.8258    1.1419    1.2200    1.2461    0.8393    0.9499

% mean SNR
% 0.4724    0.6557    0.7084    0.7278    0.5038    0.5574

% mean sigma
% 1.6684    percent change

% to get betas from UNSCALED data, to assess fits of betas by mean
% level...does the signal scale with baseline levels?

b_by_ymean = [];

for s = 3:length(D)

    % load the file
    load(D(s).name)
    eval(['ROI = ' D(s).name(1:end-4)])

    clear b, clear sigma

for i = 1:size(ROI.ts.indiv,2),

    %   ALTER VOISTAT TO GET RID OF SCALING BEFORE DOING THIS
        if length(ROI.adjustedy) == 6020
			[y,ymean] = voistat('adjusty',ROI.ts.indiv(:,i),41,.5,7);
		else
			[y,ymean] = voistat('adjusty',ROI.ts.indiv(:,i),41,.5,8);
		end

    b(:,i) = xtxitx(:,1:length(y)) * y;
    sigma(i) = std(y - LinearX(1:length(y),:) * b(:,i));,

    b_by_ymean(end+1,:) = [b(:,i)' ymean s];

end

end

figure;gscatter(b_by_ymean(:,7),b_by_ymean(:,1),b_by_ymean(:,8),'rgbycmk','o+xv^s');
t1 = unique(b_by_ymean(:,8));
for i = t1'

    tmp = b_by_ymean(b_by_ymean(:,8) == i,[1 7]);
    t2 = corrcoef(tmp);  b_by_mean_r(i) = t2(1,2);
    bb = polyfit(tmp(:,2),tmp(:,1),1); h = refcurve(bb);
    set(h,'Color',rand(1,3))
end

set(gca,'FontSize',16); xlabel('Mean scanner signal'),ylabel('Estimated response magnitude'),title('Estimated magnitude as a function of mean signal')


function c = digit_inc ( c )

%*****************************************************************************80
%
%% DIGIT_INC increments a digit.
%
%  Discussion:
%
%    0 goes to 1, 1 goes to 2 and so on, but 9 goes back to 0.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 June 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character C, a character.
%
%    Output, character C, the incremented character.
%
  if ( '0' <= c & c < '9' )
    c = char ( 1 + double ( c ) );
  elseif ( c == '9' )
    c = '0';
  end

  return
end


%%*****************************************************************
%% convertcmpsdp: convert SDP with complex data into one
%%                with real data by converting
%%
%%  C - sum_{k=1}^m yk*Ak psd
%%  to
%%  [CR,-CI] - sum ykR*[AkR,-AkI] psd
%%  [CI, CR]           [AkI, AkR]
%%
%%  ykI = 0 for k = 1:m
%%
%% [bblk,AAt,CC,bb] = convertcmpsdp(blk,A,C,b);
%%*****************************************************************
%% SDPT3: version 4.0
%% Copyright (c) 1997 by
%% K.C. Toh, M.J. Todd, R.H. Tutuncu
%% Last Modified: 16 Sep 2004
%%*****************************************************************

  function [bblk,AAt,CC,bb,iscmp] = convertcmpsdp(blk,A,C,b);

  m = length(b);
  [pp,mm] = size(A);
  if (pp ~= size(blk,1))
     error('blk and A not compatible');
  end
  numblk = size(blk,1);
  iscmp = zeros(numblk,m+1);
  for p = 1:size(blk,1)
     pblk = blk(p,:);
     len = size(A(p),2);
     for k = 1:len
        if ~isempty(A{p,k})
           iscmp(p,k) = 1-isreal(A{p,k});
        end
     end
     iscmp(p,m+1) = 1-isreal(C{p});
  end
  iscmp = norm(iscmp,'fro');
%%
  if (iscmp == 0)
     %% data is real
     bblk = blk; AAt = A; CC = C; bb = b;
     return;
  end
%%
  bb = [real(b)];
  bblk = cell(size(blk,1),2);
  for p = 1:size(blk,1)
     pblk = blk(p,:);
     if (size(pblk{2},1) > size(pblk{2},2))
        pblk{2} = pblk{2}';
     end
     if strcmp(pblk{1},'s')
        ss = [0,cumsum(pblk{2})];
        ss2 = [0,cumsum(2*pblk{2})];
        n = sum(pblk{2});
        n2 = sum(pblk{2}.*(pblk{2}+1))/2;
        AR = cell(1,m); Ctmp = sparse(2*n,2*n);
        if (size(A{p},1)==n2 & size(A{p},2)==m);
           Atype = 1;
        elseif (size(A(p),1)==1 & size(A(p),2)==1);
           Atype = 2;
        else
           error('convertcmp: At is not properly coded');
        end
        for k = 0:m
           if (k == 0)
              Ak = C{p};
           else
              if (Atype == 1)
                 Ak = smat(pblk,A{p}(:,k),1);
              elseif (Atype == 2)
                 Ak = A{p,k};
              end
           end
           Atmp = sparse(2*n,2*n);
           if (length(pblk{2}) == 1)
              tmp = [real(Ak),-imag(Ak);  imag(Ak), real(Ak)];
              if (k==0)
                 Ctmp = tmp;
              else
                 Atmp = tmp;
              end
           else
              for j = 1:length(pblk{2})
                 idx = [ss(j)+1: ss(j+1)];
                 Akj = Ak(idx,idx);
                 tmp = [real(Akj),-imag(Akj);  imag(Akj), real(Akj)];
                 idx2 = [ss2(j)+1: ss2(j+1)];
                 if (k==0)
                    Ctmp(idx2,idx2) = tmp;
                 else
   	            Atmp(idx2,idx2) = tmp;
                 end
              end
           end
           if (k==0);
              CC{p,1} = Ctmp;
           else
              AR{k} = Atmp;
           end
        end
        bblk{p,1} = 's'; bblk{p,2} = 2*pblk{2};
        AAt(p,1) = svec(bblk(p,:),AR);
     elseif strcmp(pblk{1},'q');
        error('SOCP block with complex data is currently not allowed');
     elseif strcmp(pblk{1},'l');
        if isreal(A{p}) & isreal(C{p})
           bblk(p,:) = blk(p,:);
           AAt{p,1} = A{p}; CC{p,1} = C{p};
        else
           error('data for linear block must be real');
        end
     elseif strcmp(pblk{1},'u');
        if isreal(A{p}) & isreal(C{p})
           bblk(p,:) = blk(p,:);
           AAt{p,1} = A{p}; CC{p,1} = C{p};
        else
           error('data for unrestricted block must be real');
        end
     end
  end
%%*********************************************************


function G = kronMatrix( varargin )

%
% G = kronMatrix( varargin )
%
% Constructor for the kronMatrix class.  This class is used to
% represent objects of the form:
%       \sum [A{i} (x) B{i}]
%
% Object's fields are:
%    G.a = cell array containing A{i} if i>1.
%    G.b = cell array containing B{i} if i>1.
%
% Calling Syntax:
%       G = kronMatrix
%       G = kronMatrix(G);
%       G = kronMatrix(A, B);
%
%   where
%       G = a pre-existing kronMatrix object
%       A, B = both matrices or both cell arrays (same length) such that
%              \sum [A{i} (x) B{i}] represents a bigger matrix.
%

%  L. Perrone, 5/13/03

%  Modifications:
%  6/4/03, J. Nagy
%          Cosmetic changes to incorporate into RestoreTools
%

%
% build the kronMatrix based on number and type of input arguments
%
switch nargin

  case 0
   G.a = cell(0);
   G.b = cell(0);
   G = class(G, 'kronMatrix');

  case 1
   if isa(varargin{1}, 'kronMatrix')
      G = varargin{1};
   else
      error('Wrong input argument')
   end

  case 2

   if isa(varargin{1}, 'double') & isa(varargin{2}, 'double')
     A = cell(1);, A{1} = varargin{1};
     B = cell(1);, B{1} = varargin{2};
     G.a = A;
     G.b = B;
     G = class(G, 'kronMatrix');

   elseif isa(varargin{1}, 'cell') & isa(varargin{2}, 'cell')
     if length(varargin{1}) == length(varargin{2})
        G.a = varargin{1};
        G.b = varargin{2};
        G = class(G, 'kronMatrix');
     else
        error('Input cell arrays must have the same length')
     end

   else
     error('Wrong input arguments')

   end % case 2

  otherwise
    error('Wrong input arguments')

end % switch nargin


function SD = opto2homer(opto)

% OPTO2HOMER constructs a Homer-compatible sensor definition (SD) from a FieldTrip
% opto structure.
%
% See https://www.nitrc.org/plugins/mwiki/index.php/homer2:Homer_Input_Files#NIRS_data_file_format
%
% The Homer SD structure contains the source/detector geometry and has the following fields:
%
% nSrcs    - Number of lasers; scalar variable
% nDets    - Number of detectors; scalar variable
% SrcPos   - Array of probe coordinates of the lasers; dimensions <number of lasers> by 3
% DetPos   - Array of probe coordinates of the detectors; dimensions <number of detectors> by 3
% Lambda   - Wavelengths used for data acquisition; dimensions <number of wavelengths> by 1
% MeasList - List of source/detector/wavelength measurement channels. It’s an array with dimensions, <number of channels> by 4.The meaning of the 4 columns are as follows:
%   Column 1 index of the source from the SD.SrcPos list.
%   Column 2 index of the detector from the SD.DetPos list.
%   Column 3 is unused right now and contains all ones.
%   Column 4 index of the wavelength from SD.Lambda.
%
% The FieldTrip optode structure is defined in FT_DATATYPE_SENS
%
% See also HOMER2OPTO, FT_DATATYPE_SENS

% Copyright (C) 2020, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

[nchan, noptode] = size(opto.tra);
transmitters = find(strcmp(opto.optotype, 'transmitter'));
receivers    = find(strcmp(opto.optotype, 'receiver'));

SD = [];
SD.nSrcs = length(transmitters);
SD.nDets = length(receivers);
SD.SrcPos = opto.optopos(transmitters,:);
SD.DetPos = opto.optopos(receivers,:);
SD.Lambda = opto.wavelength;

SD.MeasList = zeros(nchan, 4);
for i=1:nchan
  optodes = opto.tra(i,:);
  SD.MeasList(i,1) = find(transmitters==find(optodes>0));     % the number of the transmitter
  SD.MeasList(i,2) = find(receivers==find(optodes<0));        % the number of the receiver
  SD.MeasList(i,4) = optodes(optodes>0);                      % the wavelength
end


function [varargout]=voxelDistMarch(varargin)

%% Parse input

%Default option structure
defaultOptionStruct.toleranceLevel=0;
defaultOptionStruct.waitBarOn=false(1,1);
defaultOptionStruct.unitEdgeOn=false(1,1);
defaultOptionStruct.W=[];
defaultOptionStruct.Ws=[];

switch nargin
    case 1
        M=varargin{1};
        indStart=1;
        voxelSize=[1 1 1];
        optionStruct=defaultOptionStruct;
    case 2
        M=varargin{1};
        indStart=varargin{2};
        voxelSize=[1 1 1];
        optionStruct=defaultOptionStruct;
    case 3
        M=varargin{1};
        indStart=varargin{2};
        voxelSize=varargin{3};
        optionStruct=defaultOptionStruct;
    case 4
        M=varargin{1};
        indStart=varargin{2};
        voxelSize=varargin{3};
        optionStruct=varargin{4};
end

if numel(voxelSize)==1
    voxelSize=voxelSize*ones(1,3);
end
defaultOptionStruct.numSeeds=numel(indStart);

[optionStruct]=structComplete(optionStruct,defaultOptionStruct,1);

if nargout==2
    computeSeedIndex=true(1,1);
else
    computeSeedIndex=false(1,1);
end

% Get optionional inputs
toleranceLevel=optionStruct.toleranceLevel;
numSeeds=optionStruct.numSeeds;
waitBarOn=optionStruct.waitBarOn;
unitEdgeOn=optionStruct.unitEdgeOn;

numVoxels=numel(M); %Number of vertices

W=optionStruct.W;
if isempty(W)
    W=ones(numVoxels,1);
end

Ws=optionStruct.Ws;
if isempty(Ws)
    Ws=ones(numel(indStart),1);
end

numStart=numel(indStart);
if numSeeds<numStart
    warning('Number of seeds is smaller than number of start points, assuming these should be additional points')
    numSeeds=numSeeds+numStart;
    optionStruct.numSeeds=numSeeds; %override input in case function is called recursively
end
numSteps=(numSeeds-numStart)+1;

%% Variables and computations outside of iterative loop

if computeSeedIndex
    indAll=(1:1:numVoxels)'; %Row indices for all points
end

% k=sphereIm(1);
% ind=find(k);
% [ii,jj,kk]=ind2sub(size(k),ind);
% ii=ii([1 2 3 5 6 7]);
% jj=jj([1 2 3 5 6 7]);
% kk=kk([1 2 3 5 6 7]);
% ii=ii-2;
% jj=jj-2;
% kk=kk-2;

k=ones(3,3,3);
ind=find(k);
[ii,jj,kk]=ind2sub(size(k),ind);
ii=ii([1:13 15:end]);
jj=jj([1:13 15:end]);
kk=kk([1:13 15:end]);
ii=ii-2;
jj=jj-2;
kk=kk-2;

dd=sqrt((ii.*voxelSize(1)).^2+(jj.*voxelSize(2)).^2+(kk.*voxelSize(3)).^2);

C=maskfind(M,1:numel(M),ii,jj,kk);
siz=size(C); %Size of C
L=C>0; %Logic for valid indices in C

%Calculate edge lengths
if unitEdgeOn
    DE=nan(siz);
    DE(L)=1; %Unit edge lenghts
else
    DE=repmat(dd,[1 numel(M)])';
    DE(~L)=0;
end

%Initialize distance vector
d=nan(numVoxels,1);
d(indStart)=0;
DD=nan(siz);
IND_d=C(L);

%Initialize seed index vector
if computeSeedIndex
    i=nan(numVoxels,1);
    i(indStart)=indStart;
    II=nan(siz);
end

d_previous=d;
i_previous=i;

%% Propagate and iteratively update distances
indSeed=nan(1,numSeeds);
indSeed(1:numStart)=indStart;

if numSteps>1
    numLoopSteps=numSteps+1;
else
    numLoopSteps=1;
end

if waitBarOn
    hw=waitbar(1/numLoopSteps,['meshDistMarch...',num2str(round(100.*1/numLoopSteps)),'%']);
end

for q=1:1:numLoopSteps
    indStart=indSeed(~isnan(indSeed));
    while 1

        %Update distance data
        DD(L)=d(IND_d); %The distance data currently at neighbours
        if isempty(Ws)
            D_check=DD+DE; %Distance data plus edge lenghts
        else
            WS=ones(numVoxels,1);
            WS(indStart)=Ws;
            WS(~isnan(i))=WS(i(~isnan(i)));
            D_check=DD+DE./WS(:,ones(size(DE,2),1)); %Distance data plus edge lenghts
        end

        if computeSeedIndex
            [d,indMin]=min(D_check,[],2,'omitnan'); %Assign minimum distance

            %Update index data
            II(L)=i(IND_d); %The seed indices currently at neighbours
            ind=sub2ind(siz,indAll,indMin); %Linear indices for minimum used
            i=II(ind); %Get seed index at point chosen
            i(indStart)=indStart; %Override start seed indices
        else
            d=min(D_check,[],2,'omitnan'); %Assign minimum distance
        end
        d(indStart)=0; %Override starts to be zero

        logicFix=d_previous<d;
        d(logicFix)=d_previous(logicFix);
        if computeSeedIndex
            i(logicFix)=i_previous(logicFix);
        end

%         sum((d_previous-d).^2,'omitnan')
%         [~,indMax]=nanmax((d_previous-d).^2)

        %Check convergence
        if nnz(isnan(d))==nnz(isnan(d_previous)) %Check if number of NaN's changed
            if sum((d_previous-d).^2,'omitnan')<=toleranceLevel %Check if converged to within tolerance
                break %Stop while loop
            end
        end

        d_previous=d; %Store previous
        if computeSeedIndex
            i_previous=i;
        end

    end
    if q>1 && q<=numSteps
        [~,indSeed(numStart+(q-1))]=max(d.*W,[],'omitnan');
    end

    if waitBarOn
        waitbar(q/numLoopSteps,hw,['meshDistMarch...',num2str(round(100.*q/numLoopSteps)),'%']);
    end
end

if waitBarOn
    close(hw);
end

%% Store output
varargout{1}=reshape(d,size(M));
if nargout==2
    varargout{2}=reshape(i,size(M));
end

end
%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


function [cmps2] = ftps22cmps2(ftps2)
% Convert acceleration from feet per square-second to nanometers per second
% squared.
% Chad A. Greene 2012
cmps2 = ftps2*30.4800000;
end


BTB.MatDir= fullfile(BTB.DataDir, 'demoMat');
filename= fullfile('VPean_10_07_26', 'NIRS', 'real_movementVPean');

%% Load data
[cnt, mrk, mnt] = file_loadNIRSMatlab(filename, 'Signal','oxy');

%% define classes according to makers
stimDef= {1,2;'left','right'};
mrk = mrk_defineClasses(mrk, stimDef);

%% intervalls for display and segmentation, and fequencies for filter
ival_base=  [-1000 0];
ival_epo= [-1000 15000];
ival_scalps= [0:2500:12500];
clab=[];

%% segmentation and baseline correction
epo= proc_segmentation(cnt, mrk, ival_epo);
epo= proc_baseline(epo, ival_base);

%% r-values
epo_r= proc_rSquareSigned(epo);

%% display
fig_set(1)
H= grid_plot(epo, mnt, defopt_erps);
grid_addBars(epo_r, 'HScale',H.scale);

fig_set(2);
H= plot_scalpEvolution(epo, mnt, ival_scalps, ...
                       defopt_scalp_erp, ...
                       'ExtrapolateToMean', 1);

fig_set(4, 'Resize',[1 0.5]);
H= plot_scalpEvolution(epo_r, mnt, ival_scalps, ...
                       defopt_scalp_r);


clear
clc
im = testmat(109,105);
a = 0:17:179;
[W5,p5,t5] = build5(im,a);
[W7,p7,t7] = build7(im,a);
[W8,p8,t8] = build8(im,a);
fprintf(['\nElapsed time:\nbuild5 %f seconds'...
    '\nbuild7 %f seconds\nbuild8 %f seconds\r'],...
    t5,t7,t8);
%Variance
% var_78 = var(W7(:)-W8(:));
% fprintf('\nVariance8: %f\r',var_78);


classdef net_model_acc < mp.net_model_ac & mp.form_acc

%   MATPOWER
%   Copyright (c) 2019-2022, Power Systems Engineering Research Center (PSERC)
%   by Ray Zimmerman, PSERC Cornell
%
%   This file is part of MATPOWER.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://matpower.org for more info.

    properties
        vr = [];
        vi = [];
    end

    methods
        function obj = net_model_acc()
            obj@mp.net_model_ac();
            obj.element_classes = ...
                { @mp.nme_bus_acc, @mp.nme_gen_acc, @mp.nme_load_acc, ...
                    @mp.nme_branch_acc, @mp.nme_shunt_acc };

            %% Due to a bug related to inheritance in constructors in
            %% Octave 5.2 and earlier (https://savannah.gnu.org/bugs/?52614),
            %% INIT_SET_TYPES() cannot be called directly in the
            %% MP_IDX_MANAGER constructor, as desired.
            %%
            %% WORKAROUND:  INIT_SET_TYPES() is called explicitly as needed
            %%              (if obj.node is empty) in BUILD() and DISPLAY(),
            %%              after object construction, but before object use.
        end

        function obj = def_set_types(obj)
            def_set_types@mp.net_model_ac(obj);     % call parent first
            obj.set_types.vr = 'REAL VOLTAGE VARS (vr)';
            obj.set_types.vi = 'IMAG VOLTAGE VARS (vi)';
        end

        function va = initial_voltage_angle(obj, idx)
            vr = obj.params_var('vr');  %% inital value
            vi = obj.params_var('vi');  %% inital value
            if nargin < 2 || isempty(idx)
                va = angle(vr + 1j * vi);
            else
                va = angle(vr(idx) + 1j * vi(idx));
            end
        end
    end     %% methods
end         %% classdef


function [E,Ev,Fe,Ve]=patch2edgeIND(F,V)

%% DERIVE EDGE MATRIX

% E=[]; %Can be improved through memory allocation and indexing in loop
% for i=1:1:size(F,2)-1;
%   E=[E; F(:,i) F(:,i+1)];
% end
% E=[E; F(:,end) F(:,1)];

%Format of column index in F
EColumnInd=[(1:size(F,2)); (1:size(F,2))];
EColumnInd=[EColumnInd(2:end) EColumnInd(1)];

%Derive edges matrix
E=F(:,EColumnInd)'; %Use index into F to create edges matrix
E=reshape(E,2,numel(E)/2)';

%%
E=sort(E,2); %Sort edge order
[E,~,ind2] = unique(E,'rows'); %Removing double edges, i.e. [1  4] = [4  1]

%%

Fe=reshape(1:numel(F),size(F,2),size(F,1))';
Fe=ind2(Fe);

ind_E=(1:size(E,1))'*ones(1,2);

Ve=sort((sparse(E(:),ind_E(:),ind_E(:),size(V,1),size(E,1))),2);
[~,J]=find(Ve);
Ve=full(Ve(:,min(J):end));

A=E(Ve(Ve>0),:);
B=zeros(size(Ve));
B(Ve>0)=A(:,1);
C=zeros(size(Ve));
C(Ve>0)=A(:,2);
D=(1:size(Ve,1))'*ones(1,size(Ve,2));
B(B==D)=0;
C(C==D)=0;
Ev=B+C;

%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


function s = ySegment(x,y1,y2,z)

% YSEGMENT   Horizontal segment in the Y direction
%   YSEGMENT(X,Y1,Y2,Z) makes an horizontal segment at the plane
%   location (X,Z) from widths Y1 to Y2.

%   Copyright 2008-2009 Joan Sola @ LAAS-CNRS.

s = [x;y1;z;x;y2;z];

% ========== End of function - Start GPL license ==========

%   # START GPL LICENSE

%---------------------------------------------------------------------
%
%   This file is part of SLAMTB, a SLAM toolbox for Matlab.
%
%   SLAMTB is free software: you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation, either version 3 of the License, or
%   (at your option) any later version.
%
%   SLAMTB is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public License
%   along with SLAMTB.  If not, see <http://www.gnu.org/licenses/>.
%
%---------------------------------------------------------------------

%   SLAMTB is Copyright:
%   Copyright (c) 2008-2010, Joan Sola @ LAAS-CNRS,
%   Copyright (c) 2010-2013, Joan Sola,
%   Copyright (c) 2014-2015, Joan Sola @ IRI-UPC-CSIC,
%   SLAMTB is Copyright 2009
%   by Joan Sola, Teresa Vidal-Calleja, David Marquez and Jean Marie Codol
%   @ LAAS-CNRS.
%   See on top of this file for its particular copyright.

%   # END GPL LICENSE


function handle = plot_ranking(trackers, accuracy, robustness, varargin)
% plot_ranking Generate an A-R ranking plot
%
% The function generates an A-R ranking plot for a sequence of measurements.
%
% Input:
% - trackers (cell): A cell array of tracker structures.
% - accuracy (matrix): Accuracy ranks.
% - robustness (matrix): Robustness ranks.
% - varargin[Title] (string): A title of the plot.
% - varargin[Limit] (double): A manually set maximum rank.
% - varargin[Visible] (boolean): Is the figure visible on the display.
% - varargin[Width] (double): Figure width hint.
% - varargin[Height] (double): Figure height hint.
% - varargin[Handle] (handle): Plot on existing figure handle.
% - varargin[Legend] (boolean): Render plot legend.
%
% Output:
% - handle (handle): A figure handle.
%

    plot_title = [];
    visible = false;
    plot_limit = numel(trackers);
    width = [];
    height = [];

    handle = [];

    show_legend = true;

    for i = 1:2:length(varargin)
        switch lower(varargin{i})
            case 'title'
                plot_title = varargin{i+1};
            case 'limit'
                plot_limit = varargin{i+1};
            case 'visible'
                visible = varargin{i+1};
            case 'width'
                width = varargin{i+1};
            case 'height'
                height = varargin{i+1};
            case 'handle'
                handle = varargin{i+1};
            case 'legend'
                show_legend = varargin{i+1};
            otherwise
                error(['Unknown switch ', varargin{i},'!']) ;
        end
    end

    if isempty(handle)
        if ~visible
            handle = figure('Visible', 'off');
        else
            handle = figure();
        end
    else
        figure(handle);
    end;

    if isempty(width)
        width = iff(show_legend, 6, 4);
    end

    if isempty(height)
        height = 4;
    end

    hold on; box on; grid on;
    title(plot_title, 'interpreter','none');

    available = true(length(trackers), 1);

    for t = 1:length(trackers)

        if isnan(accuracy(t))
            available(t) = 0;
            continue;
        end;

        plot(robustness(t), accuracy(t), trackers{t}.style.symbol, 'Color', ...
            trackers{t}.style.color, 'MarkerSize', 10, 'LineWidth', trackers{t}.style.width);

    end;
    plot_labels = cellfun(@(tracker) tracker.label, trackers, 'UniformOutput', 0);
    if show_legend
        legend(plot_labels(available), 'Location', 'NorthWestOutside', 'interpreter', 'none', 'FontSize', 9);
    end;
    xlabel('Robustness rank'); set(gca, 'XDir', 'Reverse');
    ylabel('Accuracy rank'); set(gca, 'YDir', 'Reverse');
    xlim([0.9, plot_limit + 0.1]);
    ylim([0.9, plot_limit + 0.1]);

    set(handle, 'PaperUnits', 'inches', 'PaperSize', [width, height], 'PaperPosition', [0, 0, width, height]);

    hold off;


filename='ImprovedBridge_hexahedra';
 ptype = 'MACRO';
method = 'SIMPALL';
materialType = 'ISOTROPIC';
initial_case = 'full';
cost = {'compliance','perimeter'};
weights = [1 0.1];
constraint = {'volume'};
optimizer = 'MMA'; incrementFactor = 1;
filterType = 'P1';
constraint_case = 'INEQUALITY';
line_search_initiator = 'STANDARD';
showBC = true;

nsteps = 10;
Vfrac_final = 0.1;
Perimeter_target = 1;
optimality_final = 1e-3;
constr_final =1e-3;

Vfrac_initial = 1;
optimality_initial = 1e-3;
constr_initial = 1e-3;
TOL.rho_plus = 1;
TOL.rho_minus = 0;
TOL.E_plus = 1;
TOL.E_minus = 1e-3;
TOL.nu_plus = 1/3;
TOL.nu_minus = 1/3;