content: package edu.stanford.rsl.conrad.phantom;
  
  import edu.stanford.rsl.conrad.geometry.shapes.simple.Cylinder;
  import edu.stanford.rsl.conrad.geometry.shapes.simple.PointND;
  import edu.stanford.rsl.conrad.geometry.shapes.simple.Sphere;
  import edu.stanford.rsl.conrad.physics.PhysicalObject;
  import edu.stanford.rsl.conrad.physics.materials.database.MaterialsDB;
  import edu.stanford.rsl.conrad.utils.CONRAD;
  import edu.stanford.rsl.conrad.utils.DoubleArrayUtil;
  import edu.stanford.rsl.jpop.utils.UserUtil;
  
  /**
   * Phantom to test forward and back projection resolution.
   * 
   * Creates seven small beads of high contrast at several locations at the boundary of a water cylinder.
   * In the middle of the water cylinder, there is another cylinder representing bones.
   * The material of the beads is set to Plexiglass (density of 1.95).
   * 
   * 
   * @author Martin Berger
   *
   */
  public class BeadRemovalPhantom extends AnalyticPhantom {
  
  
  	/**
  	 * 
  	 */
  	private static final long serialVersionUID = 572931430014588123L;
  
  	int noOfBeads = 8;
  	double beadRadius = 3;
  
  	double beadZRangebegin = 0.05;
  	double beadZRangeend = 0.95;
  
  	double outerCylRadius = 100;
  	double innerCylRadius = 40;
  	double cylHeight = 200;
  
  
  	@Override
  	public String getBibtexCitation() {
  		return CONRAD.CONRADBibtex;
  	}
  
  	@Override
  	public String getMedlineCitation() {
  		return CONRAD.CONRADMedline;
  	}
  
  	@Override
  	public String getName() {
  		return "Bead Removal Test Phantom";
  	}
  
  	@Override
  	public void configure() {
  		try {
  			noOfBeads = UserUtil.queryInt("Number Of Beads", noOfBeads);
  			beadRadius = UserUtil.queryDouble("Bead radius", beadRadius);
  			outerCylRadius = UserUtil.queryDouble("Radius of the outer cylinder", outerCylRadius);
  			innerCylRadius = UserUtil.queryDouble("Radius of the inner cylinder", innerCylRadius);
  			cylHeight = UserUtil.queryDouble("Height of the cylinder", cylHeight);
  			buildPhantom();
  		} catch (Exception e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		}
  	}
  
  	public double giveRandomZBeadPosition(double[] zlimits){
  		double[] minMax = DoubleArrayUtil.minAndMaxOfArray(zlimits);
  		double out = Math.random()*(minMax[1]-minMax[0])+minMax[0];
  		return out;
  	}
  
  	public double giveRandomAngle(double[] angleLimits){
  		return giveRandomZBeadPosition(angleLimits);
  	}
  
  	protected void buildPhantom(){
  
  		Cylinder s = new Cylinder(outerCylRadius, outerCylRadius, cylHeight);
  		s.setName("Water Cylinder");
  		PhysicalObject po = new PhysicalObject();
  		po.setMaterial(MaterialsDB.getMaterialWithName("Water")); // D = 1.95
  		po.setShape(s);
  		add(po);
  
  
  		s = new Cylinder(innerCylRadius, innerCylRadius, cylHeight);
  		s.setName("Bone Cylinder");
  		po = new PhysicalObject();
  		po.setMaterial(MaterialsDB.getMaterialWithName("Femur")); // D = 1.95
  		po.setShape(s);
  		add(po);
  
  		s = new Cylinder(0.9*innerCylRadius, 0.9*innerCylRadius, cylHeight);
  		s.setName("Bone Marrow Cylinder");
  		po = new PhysicalObject();
  		po.setMaterial(MaterialsDB.getMaterialWithName("BoneMarrow")); // D = 1.95
  		po.setShape(s);
  		add(po);
  
  		
  		double beadPosRadius = outerCylRadius+0.8*beadRadius;
  		double alpha = 0;
  		
  		double zInc = 0;
  		double alphaInc = 0;
  		
  		double zpos = cylHeight*beadZRangebegin - cylHeight/2;
  
  		if (noOfBeads > 1){
  			alphaInc = (2*Math.PI)/(noOfBeads-1); 
  			zInc = (beadZRangeend-beadZRangebegin)*cylHeight/(noOfBeads-1);
  		}
  			
  		for (int i = 0; i < noOfBeads; i++) {
  			
  			PointND center = new PointND(Math.cos(alpha)*beadPosRadius, Math.sin(alpha)*beadPosRadius,zpos);
  			
  			// the bead
  			Sphere sp = new Sphere(beadRadius, center);
  			sp.setName("High Constrast Bead");
  			po = new PhysicalObject();
  			po.setMaterial(MaterialsDB.getMaterialWithName("SS304")); // D = 1.95
  			po.setShape(sp);
  			add(po);
  			alpha += alphaInc;
  			zpos += zInc;
  		}
  	}
  
  
  	public BeadRemovalPhantom() {
  
  
  	}
  }
  /*
   * Copyright (C) 2010-2014 Martin Berger
   * CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
  */