** This is part of the CTSim program
** Copyright (c) 1983-2001 Kevin Rosenberg
**
-** $Id: projections.cpp,v 1.54 2001/03/05 21:59:55 kevin Exp $
+** $Id: projections.cpp,v 1.55 2001/03/10 23:14:16 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
if (! v || nx == 0 || ny == 0)
return false;
+
+ if (m_geometry != Scanner::GEOMETRY_PARALLEL) {
+ sys_error (ERR_WARNING, "convertPolar supports Parallel only");
+ return false;
+ }
Array2d<double> adView (nx, ny);
Array2d<double> adDet (nx, ny);
if (! v || nx == 0 || ny == 0)
return false;
+ if (m_geometry != Scanner::GEOMETRY_PARALLEL) {
+ sys_error (ERR_WARNING, "convertFFTPolar supports Parallel only");
+ return false;
+ }
+
#ifndef HAVE_FFT
return false;
#else
int iDetCenter = (m_nDet - 1) / 2; // index refering to L=0 projection
- if (m_geometry != Scanner::GEOMETRY_PARALLEL) {
- sys_error (ERR_WARNING, "convertPolar supports Parallel only");
- return false;
- }
-
// Calculates polar coordinates (view#, det#) for each point on phantom grid
double x = xMin + xInc / 2; // Rectang coords of center of pixel
for (unsigned int ix = 0; ix < nx; x += xInc, ix++) {
double dTempScale = 2294.4871 * dEScale;
for (int id = 0; id < iNDets; id++) {
int iV = pData[lDataPos+1] + 256 * pData[lDataPos];
- if (iV > 32767)
+ if (iV > 32767) // two's complement signed conversion
iV = iV - 65536;
double dCosScale = cos ((id + 1 - iCenter) * dBetaInc);
detval[id] = iV / (dTempScale * dCosScale);
return true;
}
+
+ParallelRaysums::ParallelRaysums (Projections* pProjections)
+: m_ppCoordinates(NULL), m_iNumCoordinates(0)
+{
+ int nDet = pProjections->nDet();
+ int nView = pProjections->nView();
+ int iGeometry = pProjections->geometry();
+ double dDetInc = pProjections->detInc();
+ double dDetStart = pProjections->detStart();
+ double dFocalLength = pProjections->focalLength();
+
+ m_iNumCoordinates = nDet * nView;
+ m_ppCoordinates = new ParallelRaysumCoordinate* [m_iNumCoordinates];
+ for (int i = 0; i < m_iNumCoordinates; i++)
+ m_ppCoordinates[i] = new ParallelRaysumCoordinate;
+
+ ParallelRaysumCoordinate** ppCurrentCoordinate = m_ppCoordinates;
+
+ for (int iV = 0; iV < nView; iV++) {
+ double dViewAngle = pProjections->getDetectorArray(iV).viewAngle();
+ for (int iD = 0; iD < nDet; iD++) {
+ ParallelRaysumCoordinate* pC = *ppCurrentCoordinate;
+ if (iGeometry == Scanner::GEOMETRY_PARALLEL) {
+ pC->m_dTheta = dViewAngle;
+ pC->m_dT = dDetStart + (iD * dDetInc);
+ } else if (iGeometry == Scanner::GEOMETRY_EQUILINEAR) {
+ double dDetPos = dDetStart + (iD * dDetInc);
+ double dFanAngle = atan (dDetPos / pProjections->sourceDetectorLength());
+ pC->m_dTheta = dViewAngle + dFanAngle;
+ pC->m_dT = dFocalLength * sin(dFanAngle);
+ } else if (iGeometry == Scanner::GEOMETRY_EQUIANGULAR) {
+ double dFanAngle = dDetStart + (iD * dDetInc);
+ pC->m_dTheta = dViewAngle + dFanAngle;
+ pC->m_dT = dFocalLength * sin(dFanAngle);
+ }
+ ++ppCurrentCoordinate;
+ }
+ }
+}
+
+ParallelRaysums::~ParallelRaysums()
+{
+ for (int i = 0; i < m_iNumCoordinates; i++)
+ delete m_ppCoordinates[i];
+
+ delete m_ppCoordinates;
+}
+
+void
+ParallelRaysums::getLimits (double* dMinT, double* dMaxT, double* dMinTheta, double* dMaxTheta) const
+{
+ if (m_iNumCoordinates <= 0)
+ return;
+
+ *dMinT = *dMaxT = m_ppCoordinates[0]->m_dT;
+ *dMinTheta = *dMaxTheta = m_ppCoordinates[0]->m_dTheta;
+
+ for (int i = 0; i < m_iNumCoordinates; i++) {
+ double dT = m_ppCoordinates[i]->m_dT;
+ double dTheta = m_ppCoordinates[i]->m_dTheta;
+ if (dT < *dMinT)
+ *dMinT = dT;
+ else if (dT > *dMaxT)
+ *dMaxT = dT;
+
+ if (dTheta < *dMinTheta)
+ *dMinTheta = dTheta;
+ else if (dTheta > *dMaxTheta)
+ *dMaxTheta = dTheta;
+ }
+}