ch.epfl.leb.sass.models.illuminations.internal.SquareUniformIllumination.java Source code

Java tutorial

Introduction

Here is the source code for ch.epfl.leb.sass.models.illuminations.internal.SquareUniformIllumination.java

Source

/*
 * Copyright (C) 2017-2018 Laboratory of Experimental Biophysics
 * Ecole Polytechnique Fdrale de Lausanne
 * 
 * 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/>.
 */
package ch.epfl.leb.sass.models.illuminations.internal;

import ch.epfl.leb.sass.logging.Message;
import ch.epfl.leb.sass.logging.MessageType;
import ch.epfl.leb.sass.logging.WrongMessageTypeException;
import ch.epfl.leb.sass.logging.internal.AbstractObservable;
import ch.epfl.leb.sass.models.illuminations.Illumination;
import ch.epfl.leb.sass.models.illuminations.IlluminationBuilder;
import ch.epfl.leb.sass.models.illuminations.ElectricField;
import ch.epfl.leb.sass.models.samples.RefractiveIndex;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;

/**
 * Implements a linearly polarized uniform illumination profile of square shape.
 * 
 * @author Kyle M. Douglass
 */
public class SquareUniformIllumination extends AbstractObservable implements Illumination {

    private final static Logger LOGGER = Logger.getLogger(SquareUniformIllumination.class.getName());

    /**
     * The electric field that propagates through the sample.
     */
    private ElectricField electricField;

    /**
     * The extent of the illumination from y = 0 to y = height.
     */
    private double height;

    /**
     * The current illumination power.
     */
    private double power;

    /**
     * The extent of the illumination from x = 0 to x = width.
     */
    private double width;

    /**
     * A Builder for creating new SquareUniformIllumination instances.
     */
    public static class Builder implements IlluminationBuilder {
        private double height;
        private Vector3D orientation;
        private double power;
        private RefractiveIndex refractiveIndex;
        private double wavelength;
        private double width;

        public Builder height(double height) {
            this.height = height;
            return this;
        }

        public Builder orientation(Vector3D orientation) {
            this.orientation = orientation;
            return this;
        }

        @Override
        public Builder power(double power) {
            this.power = power;
            return this;
        }

        @Override
        public Builder refractiveIndex(RefractiveIndex refractiveIndex) {
            this.refractiveIndex = refractiveIndex;
            return this;
        }

        @Override
        public Builder wavelength(double wavelength) {
            this.wavelength = wavelength;
            return this;
        }

        public Builder width(double width) {
            this.width = width;
            return this;
        }

        public SquareUniformIllumination build() {
            return new SquareUniformIllumination(this.power, this.width, this.height, this.orientation,
                    this.wavelength, this.refractiveIndex);
        }
    }

    /**
     * Creates a new illumination profile that is square and uniform.
     * 
     * @param power The power carried by the radiation.
     * @param width The extent of the field in x from 0 to width.
     * @param height The extend of the field in y from 0 to height.
     * @param orientation The orientation of the electric field vector.
     * @param wavelength The wavelength of the radiation.
     * @param refractiveIndex The sample's refractive index distribution.
     */
    private SquareUniformIllumination(double power, double width, double height, Vector3D orientation,
            double wavelength, RefractiveIndex refractiveIndex) {

        // Create The electric field for this illumination.
        SquareUniformElectricField.Builder builder = new SquareUniformElectricField.Builder();
        builder.width(width).height(height).orientation(orientation).refractiveIndex(refractiveIndex)
                .wavelength(wavelength);
        electricField = builder.build();

        this.power = power;
        this.width = width;
        this.height = height;
    }

    /**
     * Retrieves the complex electric field.
     * 
     * @return The complex electric field.
     */
    @Override
    public ElectricField getElectricField() {
        return electricField;
    }

    /**
     * Returns the irradiance in the sample at the point (x, y, z).
     * 
     * @param x The x-position in the sample.
     * @param y The y-position in the sample.
     * @param z The z-position in the sample.
     */
    @Override
    public double getIrradiance(double x, double y, double z) {
        // Compute the absorption, if any.
        double abs = Math.exp(-4 * Math.PI * electricField.getRefractiveIndex().getN(x, y, z).getImaginary() * z
                / electricField.getWavelength());
        double irrad = this.power * abs / width / height;

        // TODO: Change this to an exception!
        assert (irrad != Double.NaN);
        return irrad;
    }

    /**
     * Returns the power carried by the illumination profile.
     * 
     * This quantity is the irradiance integrated over the illuminated area and
     * is controlled by the laser power.
     * 
     * @return The power carried by the illumination profile.
     * @see #setPower(double) 
     */
    @Override
    public double getPower() {
        return power;
    }

    /**
     * Sets the power carried by the illumination.
     * 
     * @param power The power carried by the illumination.
     */
    @Override
    public void setPower(double power) {
        this.power = power;

        setChanged();
        this.notifyListeners();
    }

    /**
     * This method is called by an illumination source when its state has changed.
     * 
     * @param data The message that is passed from the illumination source.
     */
    @Override
    public void update(Object data) throws WrongMessageTypeException {
        if (data == null) {
            // No data reported by the Observable.
            return;
        }
        try {
            Message msg = (Message) data;
            assert (msg.getType() == MessageType.LASER_POWER_CHANGE);
            double power = msg.toJson().getAsJsonObject().get("power").getAsDouble();
            this.setPower(power);
        } catch (AssertionError ex) {
            String err = "The message from the illumination source was not " + "the expected type.";
            LOGGER.log(Level.WARNING, err);
            throw new WrongMessageTypeException(err);
        } catch (Exception ex) {
            String err = "Could not coerce the illumination source message " + "into a known message type.";
            LOGGER.log(Level.WARNING, err);
            ex.printStackTrace();
        }
    }

}