/*- ******************************************************************************* * Copyright (c) 2011, 2014 Diamond Light Source Ltd. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Peter Chang - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.dawnsci.analysis.api.diffraction; import java.io.Serializable; import java.util.HashSet; import java.util.Set; import javax.vecmath.Matrix3d; import org.eclipse.dawnsci.analysis.api.diffraction.DiffractionCrystalEnvironmentEvent.EventType; /** * Container for parameters that a crystal is subject to in a diffraction experiment */ public class DiffractionCrystalEnvironment implements Serializable, Cloneable { /** * Update this when there are any serious changes to API */ static final long serialVersionUID = 4306363319254548387L; // TODO add transmission private double wavelength; // in Angstroms private double phiStart; // in degrees private double phiRange; // in degrees private double exposureTime; // in seconds private double oscGap; // in degrees private boolean fire = true; private Matrix3d orientation; // TODO move controller away from model? private transient Set<IDiffractionCrystalEnvironmentListener> diffCrystEnvListeners; /** * @param wavelength in Angstroms */ public DiffractionCrystalEnvironment(double wavelength) { this(wavelength, Double.NaN, Double.NaN, Double.NaN, Double.NaN); } /** * @param wavelength in Angstroms * @param phiStart in degrees * @param phiRange in degrees * @param exposureTime in seconds */ public DiffractionCrystalEnvironment(double wavelength, double phiStart, double phiRange, double exposureTime) { this(wavelength, phiStart, phiRange, exposureTime, Double.NaN); } /** * @param wavelength in Angstroms * @param phiStart in degrees * @param phiRange in degrees * @param exposureTime in seconds * @param oscGap in degrees */ public DiffractionCrystalEnvironment(double wavelength, double phiStart, double phiRange, double exposureTime, double oscGap) { this.wavelength = wavelength; this.phiStart = phiStart; this.phiRange = phiRange; this.exposureTime = exposureTime; this.oscGap = oscGap; } /** * null constructor */ public DiffractionCrystalEnvironment() { } /* * @param diffenv The DiffractionCrystalEnvironment to copy */ public DiffractionCrystalEnvironment(DiffractionCrystalEnvironment diffenv) { wavelength = diffenv.getWavelength(); phiStart = diffenv.getPhiStart(); phiRange = diffenv.getPhiRange(); exposureTime = diffenv.getExposureTime(); } public static DiffractionCrystalEnvironment getDefaultDiffractionCrystalEnvironment() { double lambda = 0.9; double startOmega = 0.0; double rangeOmega = 1.0; double exposureTime = 1.0; double oscGap = 0; return new DiffractionCrystalEnvironment(lambda, startOmega, rangeOmega, exposureTime, oscGap); } @Override public DiffractionCrystalEnvironment clone() { return new DiffractionCrystalEnvironment(wavelength, phiStart, phiRange, exposureTime); } @Override public int hashCode() { final int prime = 31; int result = 1; long temp; temp = Double.doubleToLongBits(exposureTime); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(phiRange); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(phiStart); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(wavelength); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(oscGap); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } private boolean equalOrBothNaNs(double a, double b) { if (Double.isNaN(a) && Double.isNaN(b)) return true; return a == b; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; DiffractionCrystalEnvironment other = (DiffractionCrystalEnvironment) obj; if (!equalOrBothNaNs(exposureTime, other.exposureTime)) return false; if (!equalOrBothNaNs(phiRange, other.phiRange)) return false; if (!equalOrBothNaNs(phiStart, other.phiStart)) return false; if (!equalOrBothNaNs(wavelength, other.wavelength)) return false; if (!equalOrBothNaNs(oscGap, other.oscGap)) return false; return true; } /** * @return wavelength in Angstroms */ public double getWavelength() { return wavelength; } /** * Sets the wavelength from energy in keV * @param keV energy */ public void setWavelengthFromEnergykeV(double keV) { // lambda(A) = 10^7 * (h*c/e) / energy(keV) this.wavelength = 1./(0.0806554465*keV); // constant from NIST CODATA 2006 // Tell listeners fireDiffractionCrystalEnvironmentListeners(new DiffractionCrystalEnvironmentEvent(this, EventType.WAVELENGTH)); } /** * Set wavelength in Angstroms * @param wavelength */ public void setWavelength(double wavelength) { this.wavelength = wavelength; fireDiffractionCrystalEnvironmentListeners(new DiffractionCrystalEnvironmentEvent(this, EventType.WAVELENGTH)); } /** * @return the phi value for the start of the image in degrees */ public double getPhiStart() { return phiStart; } /** * Set the phi value at start of the diffraction image in degrees * @param phiStart */ public void setPhiStart(double phiStart) { this.phiStart = phiStart; } /** * @return the phi range of the image in degrees */ public double getPhiRange() { return phiRange; } /** * Set the phi range in degrees * @param phiRange */ public void setPhiRange(double phiRange) { this.phiRange = phiRange; } /** * @return Exposure time in seconds */ public double getExposureTime() { return exposureTime; } /** * Set the exposure time in seconds * @param exposureTime */ public void setExposureTime(double exposureTime) { this.exposureTime = exposureTime; } /** * @return the oscillation gap value of diffraction image in degrees */ public double getOscGap() { return oscGap; } /** * Set the oscillation gap value of diffraction image in degrees * @param oscGap */ public void setOscGap(double oscGap) { this.oscGap = oscGap; } /** * Set the orientation of the crystal * @param orientation */ public void setOrientation(Matrix3d orientation) { this.orientation = orientation; } /** * Get the orientation of the crystal * @return orientation */ public Matrix3d getOrientation() { return orientation; } public void addDiffractionCrystalEnvironmentListener(IDiffractionCrystalEnvironmentListener l) { if (diffCrystEnvListeners==null) diffCrystEnvListeners = new HashSet<IDiffractionCrystalEnvironmentListener>(5); diffCrystEnvListeners.add(l); } /** * Call from dispose of part listening to diffraction crystal environment changing * @param l */ public void removeDiffractionCrystalEnvironmentListener(IDiffractionCrystalEnvironmentListener l) { if (diffCrystEnvListeners==null) return; diffCrystEnvListeners.remove(l); } protected void fireDiffractionCrystalEnvironmentListeners(DiffractionCrystalEnvironmentEvent evt) { if (diffCrystEnvListeners==null || !fire) return; for (IDiffractionCrystalEnvironmentListener l : diffCrystEnvListeners) { l.diffractionCrystalEnvironmentChanged(evt); } } public void restore(DiffractionCrystalEnvironment original) { fire = false; setExposureTime(original.getExposureTime()); setOscGap(original.getOscGap()); setPhiRange(original.getPhiRange()); setPhiStart(original.getPhiStart()); setWavelength(original.getWavelength()); fire = true; } @Override public String toString() { return "CE: " + wavelength; } }