/*
* Copyright (C) 2010-2014 Andreas Maier
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/
package edu.stanford.rsl.conrad.phantom;
import edu.stanford.rsl.conrad.geometry.General;
import edu.stanford.rsl.conrad.geometry.Rotations;
import edu.stanford.rsl.conrad.geometry.shapes.simple.Ellipsoid;
import edu.stanford.rsl.conrad.geometry.transforms.ComboTransform;
import edu.stanford.rsl.conrad.geometry.transforms.ScaleRotate;
import edu.stanford.rsl.conrad.geometry.transforms.Translation;
import edu.stanford.rsl.conrad.numerics.SimpleMatrix;
import edu.stanford.rsl.conrad.numerics.SimpleVector;
import edu.stanford.rsl.conrad.physics.PhysicalObject;
import edu.stanford.rsl.conrad.physics.materials.Material;
import edu.stanford.rsl.conrad.physics.materials.database.MaterialsDB;
/**
* 3-D definition of the Shepp-Logan Phantom. The center slice is identical to the original publication
* of Shepp and Logan. The third dimension was created by the taking the minimal extent of the x- and y-directions.
* <br><br><b>Be careful when using this phantom and have a look at <a href=http://lists.fau.de/pipermail/project-conrad/2014-October/000054.html>this comment</a> on the CONRAD mailing list</b>
* @author Happy Coding Seminar
*
*/
public class SheppLoganPhantom extends AnalyticPhantom {
/**
*
*/
private static final long serialVersionUID = 5781085850910993618L;
@Override
public String getBibtexCitation() {
String bibtex = "@Article{Shepp74-TFR,\n" +
" author = {{Shepp}, L. A. and {Logan}, B. F.},\n" +
" title = {{The Fourier reconstruction of a head section}},\n" +
" journal = {IEEE Transactions on Nuclear Science},\n" +
" volume = {21},\n" +
" pages = {21-43},\n" +
" year = {1974}\n" +
"}";
return bibtex;
}
@Override
public String getMedlineCitation() {
return "Shepp LA, Logan BF. The Fourier reconstruction of a head section. IEEE Transactions on nuclear science 21:21-43. 1974";
}
@Override
public String getName() {
return "Shepp Logan Phantom (Adapted)";
}
public SheppLoganPhantom() {
float scalingFactor = 100;
ScaleRotate scaling = new ScaleRotate(new SimpleMatrix("[[1 0 0];[0 1 0];[0 0 1]]").multipliedBy(scalingFactor));
// Body of the phantom.
Ellipsoid a = new Ellipsoid(.69, .92, .69);
Ellipsoid b = new Ellipsoid(.6624, .874, .6624);
Ellipsoid c = new Ellipsoid(.11, .31, .11);
Ellipsoid d = new Ellipsoid(.16, .41, .16);
Ellipsoid e = new Ellipsoid(.21, .25, .21);
Ellipsoid f = new Ellipsoid(.046, .046, .046);
Ellipsoid g = new Ellipsoid(.046, .046, .046);
Ellipsoid h = new Ellipsoid(.046, .023, .023);
Ellipsoid i = new Ellipsoid(.023, .023, .023);
Ellipsoid j = new Ellipsoid(.023, .046, .023);
a.applyTransform(scaling);
b.applyTransform(new ComboTransform(new Translation(new SimpleVector(0, -.0184, 0)), scaling));
c.applyTransform(new ComboTransform(new ScaleRotate(Rotations.createBasicZRotationMatrix(General.toRadians(-18))),
new Translation(new SimpleVector(.22, 0, 0)),
scaling));
d.applyTransform(new ComboTransform(new ScaleRotate(Rotations.createBasicZRotationMatrix(General.toRadians(18))),
new Translation(new SimpleVector(-.22, 0, 0)),
scaling));
e.applyTransform(new ComboTransform(new Translation(new SimpleVector(0, .35, 0)), scaling));
f.applyTransform(new ComboTransform(new Translation(new SimpleVector(0, .1, 0)), scaling));
g.applyTransform(new ComboTransform(new Translation(new SimpleVector(0, -.1, 0)), scaling));
h.applyTransform(new ComboTransform(new Translation(new SimpleVector(-.08, -.605, 0)), scaling));
i.applyTransform(new ComboTransform(new Translation(new SimpleVector(0, -.605, 0)), scaling));
j.applyTransform(new ComboTransform(new Translation(new SimpleVector(.06, -.605, 0)), scaling));
PhysicalObject po;
Material water = MaterialsDB.getMaterial("water");
po = new PhysicalObject();
Material mat = (Material) water.clone();
mat.setDensity(2.0);
po.setMaterial(mat);
po.setShape(a);
add(po);
po = new PhysicalObject();
mat = (Material) water.clone();
mat.setDensity(2.0-.98);
po.setMaterial(mat); // D = 1.95
po.setShape(b);
add(po);
po = new PhysicalObject();
mat = (Material) water.clone();
mat.setDensity(1.0-.02);
po.setMaterial(mat); // D = 1.95
po.setShape(c);
add(po);
po = new PhysicalObject();
mat = (Material) water.clone();
mat.setDensity(1.0-.02);
po.setMaterial(mat); // D = 1.95
po.setShape(d);
add(po);
po = new PhysicalObject();
mat = (Material) water.clone();
mat.setDensity(1.01);
po.setMaterial(mat); // D = 1.95
po.setShape(e);
add(po);
po = new PhysicalObject();
mat = (Material) water.clone();
mat.setDensity(1.01);
po.setMaterial(mat); // D = 1.95
po.setShape(f);
add(po);
po = new PhysicalObject();
mat = (Material) water.clone();
mat.setDensity(1.01);
po.setMaterial(mat); // D = 1.95
po.setShape(g);
add(po);
po = new PhysicalObject();
mat = (Material) water.clone();
mat.setDensity(1.01);
po.setMaterial(mat); // D = 1.95
po.setShape(h);
add(po);
po = new PhysicalObject();
mat = (Material) water.clone();
mat.setDensity(1.01);
po.setMaterial(mat); // D = 1.95
po.setShape(i);
add(po);
po = new PhysicalObject();
mat = (Material) water.clone();
mat.setDensity(1.01);
po.setMaterial(mat); // D = 1.95
po.setShape(j);
add(po);
}
}