+Projections*
+Projections::interpolateToParallel () const
+{
+ if (m_geometry == Scanner::GEOMETRY_PARALLEL)
+ return const_cast<Projections*>(this);
+
+ int nDet = m_nDet;
+ int nView = m_nView;
+ Projections* pProjNew = new Projections (nView, nDet);
+ pProjNew->m_geometry = Scanner::GEOMETRY_PARALLEL;
+ pProjNew->m_dFocalLength = m_dFocalLength;
+ pProjNew->m_dSourceDetectorLength = m_dSourceDetectorLength;
+ pProjNew->m_dViewDiameter = m_dViewDiameter;
+ pProjNew->m_dFanBeamAngle = m_dFanBeamAngle;
+ pProjNew->m_calcTime = 0;
+ pProjNew->m_remark = m_remark;
+ pProjNew->m_remark += "; Interpolate to Parallel";
+ pProjNew->m_label.setLabelType (Array2dFileLabel::L_HISTORY);
+ pProjNew->m_label.setLabelString (pProjNew->m_remark);
+ pProjNew->m_label.setCalcTime (pProjNew->m_calcTime);
+ pProjNew->m_label.setDateTime (pProjNew->m_year, pProjNew->m_month, pProjNew->m_day, pProjNew->m_hour, pProjNew->m_minute, pProjNew->m_second);
+
+ pProjNew->m_rotStart = 0;
+#ifdef CONVERT_PARALLEL_PI
+ pProjNew->m_rotInc = PI / nView;;
+#else
+ pProjNew->m_rotInc = TWOPI / nView;
+#endif
+ pProjNew->m_detStart = -m_dViewDiameter / 2;
+ pProjNew->m_detInc = m_dViewDiameter / nDet;
+ if (isEven (nDet)) // even
+ pProjNew->m_detInc = m_dViewDiameter / (nDet - 1);
+
+ ParallelRaysums parallel (this, ParallelRaysums::THETA_RANGE_NORMALIZE_TO_TWOPI);
+
+ double* pdThetaValuesForT = new double [pProjNew->nView()];
+ double* pdRaysumsForT = new double [pProjNew->nView()];
+
+ // interpolate to evenly spaced theta (views)
+ double dDetPos = pProjNew->m_detStart;
+ for (int iD = 0; iD < pProjNew->nDet(); iD++, dDetPos += pProjNew->m_detInc) {
+ parallel.getThetaAndRaysumsForT (iD, pdThetaValuesForT, pdRaysumsForT);
+
+ double dViewAngle = m_rotStart;
+ int iLastFloor = -1;
+ for (int iV = 0; iV < pProjNew->nView(); iV++, dViewAngle += pProjNew->m_rotInc) {
+ DetectorValue* detValues = pProjNew->getDetectorArray (iV).detValues();
+ LinearInterpolator<double> interp (pdThetaValuesForT, pdRaysumsForT, pProjNew->nView(), false);
+ detValues[iD] = interp.interpolate (dViewAngle, &iLastFloor);
+ }
+ }
+ delete pdThetaValuesForT;
+ delete pdRaysumsForT;
+
+ // interpolate to evenly space t (detectors)
+ double* pdOriginalDetPositions = new double [pProjNew->nDet()];
+ parallel.getDetPositions (pdOriginalDetPositions);
+
+ double* pdDetValueCopy = new double [pProjNew->nDet()];
+ double dViewAngle = m_rotStart;
+ for (int iV = 0; iV < pProjNew->nView(); iV++, dViewAngle += pProjNew->m_rotInc) {
+ DetectorArray& detArray = pProjNew->getDetectorArray (iV);
+ DetectorValue* detValues = detArray.detValues();
+ detArray.setViewAngle (dViewAngle);
+
+ for (int i = 0; i < pProjNew->nDet(); i++)
+ pdDetValueCopy[i] = detValues[i];
+
+ double dDetPos = pProjNew->m_detStart;
+ int iLastFloor = -1;
+ LinearInterpolator<double> interp (pdOriginalDetPositions, pdDetValueCopy, pProjNew->nDet(), false);
+ for (int iD = 0; iD < pProjNew->nDet(); iD++, dDetPos += pProjNew->m_detInc)
+ detValues[iD] = interp.interpolate (dDetPos, &iLastFloor);
+ }
+ delete pdDetValueCopy;
+ delete pdOriginalDetPositions;
+
+ return pProjNew;
+}
+