r626: no message
[ctsim.git] / libctsim / projections.cpp
index 627ccb91f11ba32f85e8feabbca0297487f57509..b3d6d35b2df647b5595d60c01bebcf30771af957 100644 (file)
@@ -8,7 +8,7 @@
 **  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
@@ -687,6 +687,11 @@ Projections::convertPolar (ImageFile& rIF, int iInterpolationID)
 
   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);
@@ -727,6 +732,11 @@ Projections::convertFFTPolar (ImageFile& rIF, int iInterpolationID, int iZeropad
   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
@@ -784,11 +794,6 @@ Projections::calcArrayPolarCoordinates (unsigned int nx, unsigned int ny, double
   
   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++) {
@@ -952,7 +957,7 @@ Projections::initFromSomatomAR_STAR (int iNViews, int iNDets, unsigned char* pDa
     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);
@@ -963,3 +968,74 @@ Projections::initFromSomatomAR_STAR (int iNViews, int iNDets, unsigned char* pDa
   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;
+  }
+}