package edu.stanford.rsl.conrad.reconstruction.iterative;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
import java.text.NumberFormat;
import java.util.Locale;
import edu.stanford.rsl.conrad.data.numeric.Grid2D;
import edu.stanford.rsl.conrad.data.numeric.Grid3D;
import edu.stanford.rsl.conrad.filtering.ImageFilteringTool;
import edu.stanford.rsl.conrad.geometry.trajectories.Trajectory;
import edu.stanford.rsl.conrad.numerics.SimpleMatrix;
import edu.stanford.rsl.conrad.numerics.SimpleVector;
public abstract class ModelBasedIterativeReconstruction extends IterativeReconstruction{
private static final long serialVersionUID = 1L;
protected boolean Debug = false;
protected long time;
protected Grid3D volumeImage = null;
protected Grid3D projectionViews = null;
protected double lineOffset;
protected int maxK = 0;
protected int maxI = 0;
protected int maxJ = 0;
protected int maxU = 0;
protected int maxV = 0;
protected double dx = 0.0;
protected double dy = 0.0;
protected double dz = 0.0;
protected Trajectory dataTrajectory;
@Override
public void prepareForSerialization(){
super.prepareForSerialization();
init = false;
}
protected synchronized void initialize(ImageProcessor projection) throws Exception{
if (!init){
super.init();
// Precompute offsets
lineOffset = 0;
if (getGeometry().getDetectorWidth() != -1){
System.out.println("row size projection: " + projection.getWidth() + "\nrow size detector: " + getGeometry().getDetectorWidth());
lineOffset = (projection.getWidth() - getGeometry().getDetectorWidth()) / 2;
}
maxI = getGeometry().getReconDimensionX();
maxJ = getGeometry().getReconDimensionY();
maxK = getGeometry().getReconDimensionZ();
maxU = getGeometry().getDetectorWidth(); //or it should be projection.getWidth();
maxV = getGeometry().getDetectorHeight();
dx = getGeometry().getVoxelSpacingX();
dy = getGeometry().getVoxelSpacingY();
dz = getGeometry().getVoxelSpacingZ();
time = System.currentTimeMillis();
//projectionViews = InitializeProjectionViews();
//volumeImage = InitializeVolumeImage();
}
}
public Grid3D InitializeProjectionViews() throws Exception{
if (Debug) System.out.println("Created projection views");
if (nImages == 0 || maxU == 0 || maxV == 0 ){
System.out.println("Errpr: Wrong projection views size!");
}
Grid3D views;
views = new Grid3D(nImages,maxU,maxV);
computeOffsets();
return views;
}
public Grid3D InitializeVolumeImage() throws Exception{
if (Debug) System.out.println("Created volume image");
if (maxI == 0 || maxJ == 0 || maxK == 0 ){
System.out.println("Errpr: Wrong volume image size!");
}
Grid3D image;
image = new Grid3D(maxI,maxJ,maxK);
computeOffsets();
return image;
}
protected void copyProjectionViews()throws Exception{
FloatProcessor currentProjection;
for ( int ip = 0; ip < nImages; ip++ ){
try {
Grid2D projection = inputQueue.get(ip);
currentProjection = new FloatProcessor(projection.getWidth(), projection.getHeight(), projection.getBuffer(), null);
for (int iu = 0; iu <= maxU ; iu ++ ){
for (int iv = 0; iv <= maxV ; iv++){
// there may be a problem
projectionViews.setAtIndex(ip, iu, iv, currentProjection.getf(iu, iv));
}
}
} catch (Exception e){
System.out.println("An error occured during copying projection views " + ip);
}
}
}
public Grid3D getProjectionViews(){
return projectionViews;
}
public Grid3D getvolumeImage(){
return volumeImage;
}
@Override
public void configure() throws Exception{
boolean success = true;
NumberFormat nf = NumberFormat.getInstance(Locale.US);
nf.setMaximumFractionDigits(1);
nf.setMinimumFractionDigits(1);
nf.setMaximumIntegerDigits(1);
nf.setMinimumIntegerDigits(1);
initializeProjectionVolume();
configured = success;
}
/**
* Back projects a single projection into the reconstruction space.
* @param projection the projection to back project
* @throws Exception may happen.
*/
protected abstract void backproject( Grid3D projImage, Grid3D volImage ) throws Exception;
/**
* Forward projects the object onto the projection image.
* @param the object volume to back project
* @throws Exception may happen.
*/
protected abstract void forwardproject( Grid3D projImage, Grid3D volImage ) throws Exception;
@Override
public String getName() {
return "Model-based Iterative Reconstruction.";
}
@Override
public String getToolName() {
return "Model-based Iterative Reconstruction";
}
@Override
public synchronized void close() {
super.close();
//if (true) throw new RuntimeException("Happended");
System.out.println("Closing iterative reconstruction");
//done = true;
}
@Override
public ImageFilteringTool clone() {
return this;
}
//----------------Methods for testing ----------------//
public static void printSimpleMatrix( SimpleMatrix A ){
int n = A.getRows();
int m = A.getCols();
for (int i = 0; i < n ; i++ ){
for (int j = 0; j < m ; j++){
System.out.print( A.getElement(i, j) + "\t");
}
System.out.print("\n");
}
}
public static void printSimpleVector( SimpleVector B ){
int n = B.getLen();
for (int i = 0; i < n ; i++ ){
System.out.print( B.getElement(i) + "\t");
}
System.out.print("\n");
}
//constructor overrides geometry for testing
public ModelBasedIterativeReconstruction( Trajectory dataTraj ){
dataTrajectory = dataTraj;
}
//override for testing
public Trajectory getGeometry() {
return dataTrajectory;
}
public synchronized void initializeTest() throws Exception{
if (!init){
super.init();
nImages = getGeometry().getNumProjectionMatrices();
maxI = getGeometry().getReconDimensionX();
maxJ = getGeometry().getReconDimensionY();
maxK = getGeometry().getReconDimensionZ();
maxU = getGeometry().getDetectorWidth(); //or it should be projection.getWidth();
maxV = getGeometry().getDetectorHeight();
dx = getGeometry().getVoxelSpacingX();
dy = getGeometry().getVoxelSpacingY();
dz = getGeometry().getVoxelSpacingZ();
time = System.currentTimeMillis();
//projectionViews = InitializeProjectionViews();
//volumeImage = InitializeVolumeImage();
}
}
public void printOutGeometry(){
System.out.println("Detector Size: " + maxU + " X " + maxV );
System.out.println("Volume Size: " + maxI + " X " + maxJ + " X " + maxK );
System.out.println("Voxel Dimension: " + dx + " X " + dy + " X " + dz );
System.out.println( "Offsets: " + offsetX + ", " + offsetY + ", " + offsetZ) ;
if (volumeImage != null && projectionViews != null ){
System.out.println( "volumeImage and projectionViews created successfully!");
}
}
}
/*
* Copyright (C) 2010-2014 Meng Wu
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/