content: /*
   * Copyright (C) 2014 Andreas Maier, Maximilian Dankbar
   * CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
   */
  package edu.stanford.rsl.conrad.physics.detector;
  
  import java.io.IOException;
  import java.util.ArrayList;
  
  import edu.stanford.rsl.conrad.data.numeric.Grid2D;
  import edu.stanford.rsl.conrad.physics.PhysicalObject;
  import edu.stanford.rsl.conrad.physics.absorption.PolychromaticAbsorptionModel;
  import edu.stanford.rsl.conrad.utils.CONRAD;
  import edu.stanford.rsl.conrad.utils.UserUtil;
  
  public class PolychromaticDetectorWithNoise extends XRayDetector {
  
  	/**
  	 * 
  	 */
  	private static final long serialVersionUID = 2186375966931202433L;
  	boolean configured = false;
  	//PolychromaticAbsorptionModel model;
  	boolean photonCounting = false;
  	
  	@Override
  	public void configure(){
  		try {
  			photonCounting = UserUtil.queryBoolean("Do you want to simulate a photon counting detector?");
  			ArrayList<Object> modelList = CONRAD.getInstancesFromConrad(PolychromaticAbsorptionModel.class);
  			Object [] modelArray = new PolychromaticAbsorptionModel [modelList.size()];
  			modelList.toArray(modelArray);
  			model = (PolychromaticAbsorptionModel) UserUtil.chooseObject("Select noise-free model", "Model Selection", modelArray, (Object) modelArray[0]);
  			model.configure();
  			configured = true;
  		} catch (ClassNotFoundException e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		} catch (IOException e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		} catch (Exception e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		}
  	}
  
  	@Override
  	public String toString(){
  		String name = "Polychromatic X-Ray Detector with noise";
  		if (model!= null) name+=" " + model.toString();
  		return name;
  	}
  
  	@Override
  	public boolean isConfigured(){
  		return configured;
  	}
  
  	@Override
  	public void writeToDetector(Grid2D grid, int x, int y, ArrayList<PhysicalObject> segments){
  		double value = ((PolychromaticAbsorptionModel) model).computeIntensity(segments, ((PolychromaticAbsorptionModel) model).getMinimalEnergy(), ((PolychromaticAbsorptionModel) model).getMaximalEnergy(), true, !photonCounting);
  		if (photonCounting){
  			value /= ((PolychromaticAbsorptionModel) model).getTotalPhotonFlux();
  		} else {
  			value /= ((PolychromaticAbsorptionModel) model).getTotalIntensity();
  		}
  		//Due to the accumulation round off error, it is possible for output intensity to be marginally greater  
  		//than input intensity in vacuum. We deal with this problem by bounding output intensity by the input 
  		//intensity.
  		if(value > 1){
  			value = 1;
  			//throw new RuntimeException("PolychromaticAbsorptionModel: numerical instability found.");
  		}
  		//End
  		grid.putPixelValue(x, y,  -Math.log(value));
  	}
  
  
  
  	/**
  	 * @return the photonCounting
  	 */
  	public boolean isPhotonCounting() {
  		return photonCounting;
  	}
  
  	/**
  	 * @param photonCounting the photonCounting to set
  	 */
  	public void setPhotonCounting(boolean photonCounting) {
  		this.photonCounting = photonCounting;
  	}
  
  	/**
  	 * @param configured the configured to set
  	 */
  	public void setConfigured(boolean configured) {
  		this.configured = configured;
  	}
  	
  }
  