1 /*****************************************************************************
4 ** Name: projections.cpp Projection data classes
5 ** Programmer: Kevin Rosenberg
6 ** Date Started: Aug 84
8 ** This is part of the CTSim program
9 ** Copyright (C) 1983-2000 Kevin Rosenberg
11 ** $Id: projections.cpp,v 1.2 2000/06/19 17:58:20 kevin Exp $
13 ** This program is free software; you can redistribute it and/or modify
14 ** it under the terms of the GNU General Public License (version 2) as
15 ** published by the Free Software Foundation.
17 ** This program is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ** GNU General Public License for more details.
22 ** You should have received a copy of the GNU General Public License
23 ** along with this program; if not, write to the Free Software
24 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 ******************************************************************************/
31 * Projections Constructor for projections matrix storage
34 * proj = projections_create (filename, nView, nDet)
35 * Projections& proj Allocated projections structure & matrix
36 * int nView Number of rotated view
37 * int nDet Number of detectors
41 Projections::Projections (const Scanner& scanner)
44 initFromScanner (scanner);
48 Projections::Projections (const int nView, const int nDet)
54 Projections::Projections (void)
60 Projections::~Projections (void)
67 Projections::init (const int nView, const int nDet)
75 Projections::initFromScanner (const Scanner& scanner)
78 init (scanner.nView(), scanner.nDet());
80 m_phmLen = scanner.phmLen();
81 m_rotInc = scanner.rotInc();
82 m_detInc = scanner.detInc();
84 m_detStart = -scanner.radius() + (scanner.detInc() / 2);
85 m_phmLen = scanner.phmLen();
89 Projections::setNView (int nView) // used by MPI to reduce # of views
99 Projections::newProjData (void)
102 sys_error(ERR_WARNING, "m_projData != NULL [newProjData]");
104 if (m_nView > 0 && m_nDet) {
105 m_projData = new DetectorArray* [m_nView];
107 for (int i = 0; i < m_nView; i++)
108 m_projData[i] = new DetectorArray (m_nDet);
114 * projections_free Free memory allocated to projections
117 * projections_free(proj)
118 * Projections& proj Projectionss to be deallocated
122 Projections::deleteProjData (void)
124 if (m_projData != NULL) {
125 for (int i = 0; i < m_nView; i++)
126 delete m_projData[i];
135 * projections_write_header Write data header for projections file
140 Projections::headerWrite (void)
142 kuint32 _hsize = m_headerSize;
143 kuint32 _nView = m_nView;
144 kuint32 _nDet = m_nDet;
145 kuint32 _geom = m_geometry;
146 kuint32 _remarksize = m_remark.length();
147 kfloat64 _calcTime = m_calcTime;
148 kfloat64 _rotStart = m_rotStart;
149 kfloat64 _rotInc = m_rotInc;
150 kfloat64 _detStart = m_detStart;
151 kfloat64 _detInc = m_detInc;
152 kfloat64 _phmLen = m_phmLen;
155 sys_error (ERR_SEVERE, "m_fd < 0 [projections_write_header]");
159 if (lseek (m_fd, (off_t) 0, SEEK_SET) != (off_t) 0) {
160 sys_error (ERR_WARNING, "Error seeking to beginning of fiel [projections_write_header]");
164 if (! write_nint32 (&_hsize, m_fd) ||
165 ! write_nint32 (&_nView, m_fd) ||
166 ! write_nint32 (&_nDet, m_fd) ||
167 ! write_nint32 (&_geom, m_fd) ||
168 ! write_nfloat64 (&_calcTime, m_fd) ||
169 ! write_nfloat64 (&_rotStart, m_fd) ||
170 ! write_nfloat64 (&_rotInc, m_fd) ||
171 ! write_nfloat64 (&_detStart, m_fd) ||
172 ! write_nfloat64 (&_detInc, m_fd) ||
173 ! write_nfloat64 (&_phmLen, m_fd) ||
174 ! write_nint32 (&_remarksize, m_fd) ||
175 (::write (m_fd, m_remark.c_str(), _remarksize) != _remarksize)) {
176 sys_error (ERR_SEVERE, "Error writing header information [projections_write_header] %ld", _remarksize);
179 m_headerSize = _hsize = lseek(m_fd, (off_t) 0, SEEK_CUR);
180 if ((lseek(m_fd, 0, SEEK_SET) != 0) || ! write_nint32 (&_hsize, m_fd)) {
181 sys_error (ERR_SEVERE, "Error writing header information [projections_write_header]");
190 * projections_read_header Read data header for projections file
195 Projections::headerRead (void)
201 kuint32 _remarksize = 0;
210 sys_error (ERR_SEVERE, "m_fd < 0 [projections_read_header]");
214 if (lseek (m_fd, (off_t) 0, SEEK_SET) != (off_t) 0) {
215 sys_error (ERR_WARNING, "Error seeking to beginning of field [projections_read_header]");
220 if (! read_nint32 (&_hsize, m_fd)) {
221 sys_error (ERR_SEVERE, "Error reading header size , _hsize=%d [projections_read_header]", _hsize);
224 if ( ! read_nint32 (&_nView, m_fd) ||
225 ! read_nint32 (&_nDet, m_fd) ||
226 ! read_nint32 (&_geom, m_fd) ||
227 ! read_nfloat64 (&_calcTime, m_fd) ||
228 ! read_nfloat64 (&_rotStart, m_fd) ||
229 ! read_nfloat64 (&_rotInc, m_fd) ||
230 ! read_nfloat64 (&_detStart, m_fd) ||
231 ! read_nfloat64 (&_detInc, m_fd) ||
232 ! read_nfloat64 (&_phmLen, m_fd) ||
233 ! read_nint32 (&_remarksize, m_fd))
235 sys_error (ERR_SEVERE, "Error reading header information , _remarksize=%d [projections_read_header]", _remarksize);
239 char remarkStorage[_remarksize+1];
240 if (::read (m_fd, &remarkStorage, _remarksize) != _remarksize) {
241 sys_error (ERR_SEVERE, "Error reading remark, _remarksize = %d", _remarksize);
244 remarkStorage[_remarksize] = 0;
245 m_remark = remarkStorage;
247 off_t _hsizeread = lseek(m_fd, 0, SEEK_CUR);
248 if (_hsizeread != _hsize) {
249 sys_error (ERR_WARNING, "File header size read %ld != file header size stored %ld [read_projections_header]\n_remarksize=%ld", (long int) _hsizeread, _hsize, _remarksize);
253 m_headerSize = _hsize;
257 m_calcTime = _calcTime;
258 m_rotStart = _rotStart;
260 m_detStart = _detStart;
269 Projections::read (const char* filename)
271 if ((m_fd = open(filename, OPEN_RDONLY | O_BINARY)) < 0) {
272 sys_error (ERR_SEVERE, "Error opening projections file %s for input [open_projections]", filename);
276 if (! headerRead()) {
277 sys_error (ERR_SEVERE, "Error reading projections file %s [open_projections]", filename);
284 for (int i = 0; i < m_nView; i++) {
285 if (! detarrayRead (*m_projData[i], i))
297 Projections::write (const char* filename)
299 if ((m_fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY
301 , S_IWRITE | S_IREAD | S_IRGRP | S_IROTH
304 sys_error (ERR_SEVERE, "Error opening file %s for output [projections_create]", filename);
307 if (! headerWrite ()) {
308 sys_error(ERR_SEVERE, "Error writing to file %s [create_projections]", filename);
314 if (m_projData != NULL) {
315 for (int i = 0; i < m_nView; i++) {
316 if (! detarrayWrite (*m_projData[i], i))
328 * detarrayRead Read a Detector Array structure from the disk
331 * detarrayRead (proj, darray, view_num)
332 * DETARRAY *darray Detector array storage location to be filled
333 * int view_num View number to read
337 Projections::detarrayRead (DetectorArray& darray, const int iview)
339 const int detval_bytes = darray.nDet() * sizeof(kfloat32);
340 const int detheader_bytes = sizeof(kfloat64) /* view_angle */ + sizeof(kint32) /* nDet */;
341 const int view_bytes = detheader_bytes + detval_bytes;
342 const off_t start_data = m_headerSize + (iview * view_bytes);
343 DetectorValue* detval_ptr = darray.detValues();
348 sys_error (ERR_SEVERE, "Tried to read detector array on closed file [detarrayRead]");
352 if (lseek(m_fd, start_data, SEEK_SET) != start_data) {
353 sys_error (ERR_SEVERE, "Error seeking detectory array [detarrayRead]");
357 if (! read_nfloat64 (&view_angle, m_fd) ||
358 ! read_nint32 (&nDet, m_fd)) {
359 sys_error (ERR_SEVERE, "Error reading detector array [detarrayRead]");
362 darray.setViewAngle (view_angle);
363 // darray.setNDet ( nDet);
365 for (int i = 0; i < nDet; i++) {
367 if (! read_nfloat32 (&detval, m_fd)) {
368 sys_error (ERR_SEVERE, "Error reading detector array [detarrayRead]");
371 detval_ptr[i] = detval;
379 * detarrayWrite Write detector array data to the disk
382 * detarrayWrite (darray, view_num)
383 * DETARRAY *darray Detector array data to be written
384 * int view_num View number to write
387 * This routine writes the detarray data from the disk sequentially to
388 * the file that was opened with open_projections(). Data is written in
393 Projections::detarrayWrite (const DetectorArray& darray, const int iview)
395 const int detval_bytes = darray.nDet() * sizeof(float);
396 const int detheader_bytes = sizeof(kfloat64) /* view_angle */ + sizeof(kint32) /* nDet */;
397 const int view_bytes = detheader_bytes + detval_bytes;
398 const off_t start_data = m_headerSize + (iview * view_bytes);
399 const DetectorValue* const detval_ptr = darray.detValues();
400 kfloat64 view_angle = darray.viewAngle();
401 kuint32 nDet = darray.nDet();
404 sys_error (ERR_SEVERE, "Tried to write detector array with no file open [detarrayWrite]");
408 if (lseek(m_fd, start_data, SEEK_SET) != start_data) {
409 sys_error (ERR_SEVERE, "Error seeking detectory array [detarrayWrite]");
413 if ( ! write_nfloat64 (&view_angle, m_fd)) {
414 sys_error (ERR_SEVERE, "Error writing detector array [detarrayWrite]");
417 if ( ! write_nint32 (&nDet, m_fd)) {
418 sys_error (ERR_SEVERE, "Error writing detector array [detarrayWrite]");
421 for (int i = 0; i < nDet; i++) {
422 kfloat32 detval = detval_ptr[i];
423 if ( ! write_nfloat32 (&detval, m_fd)) {
424 sys_error (ERR_SEVERE, "Error writing detector array [detarrayWrite]");
434 * prt_projections Print projections data
437 * prt_projections (proj)
438 * Projections& proj Projection data to be printed
442 Projections::printProjectionData (void)
444 printf("Projections Print\n\n");
445 printf("Description: %s\n", m_remark.c_str());
446 printf("nView = %d nDet = %d\n", m_nView, m_nDet);
447 printf("rotStart = %8.4f rotInc = %8.4f\n", m_rotStart, m_rotInc);
448 printf("detStart = %8.4f detInc = %8.4f\n", m_detStart, m_detInc);
450 if (m_projData != NULL) {
451 for (int ir = 0; ir < m_nView; ir++) {
452 DetectorValue* detval = m_projData[ir]->detValues();
453 for (int id = 0; id < m_projData[ir]->nDet(); id++)
454 printf("%8.4f ", detval[id]);
461 Projections::printScanInfo (void) const
463 printf ("Number of detectors: %d\n", m_nDet);
464 printf (" Number of views: %d\n", m_nView);
465 printf (" Remark: %s\n", m_remark.c_str());
466 printf (" phmLen: %f\n", m_phmLen);
467 printf (" detStart: %f\n", m_detStart);
468 printf (" detInc: %f\n", m_detInc);
469 printf (" rotStart: %f\n", m_rotStart);
470 printf (" rotInc: %f\n", m_rotInc);