r121: *** empty log message ***
authorKevin M. Rosenberg <kevin@rosenberg.net>
Mon, 26 Jun 2000 21:15:24 +0000 (21:15 +0000)
committerKevin M. Rosenberg <kevin@rosenberg.net>
Mon, 26 Jun 2000 21:15:24 +0000 (21:15 +0000)
26 files changed:
ChangeLog
README
cgi-bin/ctsim.cgi.in
configure.in
include/Makefile.am
include/array2d.h
include/array2dfile.h [new file with mode: 0644]
include/ct.h
include/imagefile.h
libctsim/Makefile.am
libctsim/array2dfile.cpp [new file with mode: 0644]
libctsim/imagefile.cpp
libctsupport/Makefile.am
libctsupport/timedate.cpp [deleted file]
src/Makefile.am
src/ctrec.cpp [deleted file]
src/if-1.cpp
src/if-2.cpp
src/if2img.cpp
src/ifinfo.cpp
src/phm2if.cpp
src/phm2pj.cpp
src/pj2if.cpp
src/pjrec.cpp [new file with mode: 0644]
src/sample-ctrec.sh.in [deleted file]
src/sample-ctsim.sh.in [new file with mode: 0755]

index 332a837..76d6a7a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+1.9.8 - 6/27/2000
+   Rewrote Array2dFile class to be non-templated
+   Rewrote Array2dFile class to make reads and writes atomic. No disk files are kept open.
+   Rewrote Array2dFileLabel class to make members private, added access routines
+   Removed timedate.cpp in favor of standard C library time/date functions
+   Renamed ctrec to pjrec
+       
 1.9.7 - 6/25/2000
    Standardized string option processing by classes. All classes use character strings
        to select options rather than numeric constants. Added fail() and failMessage()
diff --git a/README b/README
index 1bf5d38..56ab90b 100644 (file)
--- a/README
+++ b/README
@@ -86,7 +86,10 @@ Perform CT reconstruction and create viewable image file
   ctrec ...
   if2img ...
 
-There is a sample shell script installed called 'sample-ctrec.sh' that performs 
+Display image information and comparative statistics
+  ifinfo ...
+
+There is a sample shell script installed called 'sample-ctsim.sh' that performs 
 the above commands.n
 
 These functions can be invoked via a web interface with a CGI program 
index 5e27ccb..06d16e8 100755 (executable)
@@ -94,20 +94,20 @@ my $ir_png_url = "$::url_datadir/ir-$tmpid.png";
 my $pj_png_url = "$::url_datadir/pj-$tmpid.png";
 my $diff_png_url = "$::url_datadir/diff-$tmpid.png";
 
-my $ctrec_ver = "$::bindir/ctrec";
+my $pjrec_ver = "$::bindir/pjrec";
 my $phm2pj_ver = "$::bindir/phm2pj";
 my $phm2if_ver = "$::bindir/phm2if";
 my $diff_ver = "$::bindir/if-2";
 my $ifinfo_ver = "$::bindir/ifinfo";
 
-$ctrec_ver = "/opt/lam/bin/mpirun N N $::lamrundir/ctrec-lam" if $MPI;
+$pjrec_ver = "/opt/lam/bin/mpirun N N $::lamrundir/pjrec-lam" if $MPI;
 $phm2pj_ver = "/opt/lam/bin/mpirun N N $::lamrundir/phm2pj-lam" if $MPI;
 $phm2if_ver = "/opt/lam/bin/mpirun N N $::lamrundir/phm2if-lam" if $MPI;
 
 my $gp_cmd = "$phm2if_ver $phantom_fname $Phantom_Nx $Phantom_Ny --phantom $Phantom_Name --nsample $Phantom_NSample";
 my $pj_cmd = "$phm2pj_ver $pj_fname $PJ_NDet $PJ_NRot --phantom $Phantom_Name --nray $PJ_NRay --rotangle $PJ_RotAngle";
 my $pj_if_cmd = "$::bindir/pj2if $pj_fname $pj_if_fname";
-my $ir_cmd = "$ctrec_ver $pj_fname $ir_fname $IR_Nx $IR_Ny --filter $IR_Filter --filter-param $IR_Filter_Param --interp $IR_Interp --backproj $IR_Backproj";
+my $pjrec_cmd = "$pjrec_ver $pj_fname $ir_fname $IR_Nx $IR_Ny --filter $IR_Filter --filter-param $IR_Filter_Param --interp $IR_Interp --backproj $IR_Backproj";
 my $diff_cmd = "$diff_ver $phantom_fname $ir_fname $diff_fname --comp";
 my $compare_cmd = "$ifinfo_ver $phantom_fname $ir_fname";
 
@@ -133,7 +133,7 @@ $out .= "<H1>$title</H1><HR>\n";
 
 if ($opt_d) {
     $out .= "<H2>Commands</H2>\n";
-    $out .= "$gp_cmd<br>\n$pj_cmd<br>\n$pj_if_cmd<br>\n$ir_cmd<br>\n$diff_cmd<br>\n$png1_cmd<br>\n$png2_cmd<br>\n" .
+    $out .= "$gp_cmd<br>\n$pj_cmd<br>\n$pj_if_cmd<br>\n$pjrec_cmd<br>\n$diff_cmd<br>\n$png1_cmd<br>\n$png2_cmd<br>\n" .
             "$png3_cmd<br>\n$png4_cmd<br>\n";
 }
 
@@ -146,10 +146,10 @@ if ($error ne "") {
   my $gp_out;
   my $pj_out;
   my $pj_if_out;
-  my $ir_out;
+  my $pjrec_out;
   my $diff_out;
   my $png_gp_out;
-  my $png_ir_out;
+  my $png_pjrec_out;
   my $png_pj_out;
   my $png_diff_out;
   my $compare_out;
@@ -160,9 +160,9 @@ if ($error ne "") {
     if (-s $pj_fname) {
       $pj_if_out .= `$pj_if_cmd`;
       $png_pj_out .= `$png3_cmd`;
-      $ir_out .= `$ir_cmd`;
+      $pjrec_out .= `$pjrec_cmd`;
       if (-s $ir_fname) {
-       $png_ir_out .= `$png2_cmd`;
+       $png_pjrec_out .= `$png2_cmd`;
        $diff_out .= `$diff_cmd`;
        $png_diff_out .= `$png4_cmd`;
        $compare_out = `$compare_cmd`;
@@ -170,7 +170,7 @@ if ($error ne "") {
     }
   }
 
-  $cmdout = "$gp_cmd\n $gp_out $pj_cmd\n $pj_out $pj_if_cmd\n $pj_if_out $ir_cmd\n $ir_out $diff_cmd\n $diff_out $png1_cmd\n $png_gp_out $png2_cmd\n $png_ir_out $png3_cmd\n $png_pj_out $png4_cmd\n $png_diff_out";
+  $cmdout = "$gp_cmd\n $gp_out $pj_cmd\n $pj_out $pj_if_cmd\n $pj_if_out $pjrec_cmd\n $pjrec_out $diff_cmd\n $diff_out $png1_cmd\n $png_gp_out $png2_cmd\n $png_pjrec_out $png3_cmd\n $png_pj_out $png4_cmd\n $png_diff_out";
   if (open(LOGFILE,">> $logfile")) {
     flock(LOGFILE,LOCK_EX);
     seek(LOGFILE, 0, 2);
@@ -186,16 +186,16 @@ if ($error ne "") {
     $out .= "<H3>Command Output</H3>$cmdout<HR>\n";
   }
   my $png_gp_out_html = $png_gp_out;
-  my $png_ir_out_html = $png_ir_out;
+  my $png_pjrec_out_html = $png_pjrec_out;
   my $png_pj_out_html = $png_pj_out;
   my $png_diff_out_html = $png_diff_out;
   $png_gp_out_html =~ s/\n/<br>/gms;
-  $png_ir_out_html =~ s/\n/<br>/gms;
+  $png_pjrec_out_html =~ s/\n/<br>/gms;
   $png_pj_out_html =~ s/\n/<br>/gms;
   $png_diff_out_html =~ s/\n/<br>/gms;
   $out .= "<TABLE><TR><TD>Phantom Image</TD><TD>Reconstructed Image</TD></TR>\n";
   $out .= "<TR><TD><IMG SRC=\"$phantom_png_url\"><br><FONT SIZE=1>$png_gp_out</FONT></TD>\n";
-  $out .= "<TD><IMG SRC=\"$ir_png_url\"><br><FONT SIZE=1>$png_ir_out</FONT></TD></TR>\n";
+  $out .= "<TD><IMG SRC=\"$ir_png_url\"><br><FONT SIZE=1>$png_pjrec_out</FONT></TD></TR>\n";
   $out .= "<TR><TD>Projection Sinusoid</TD><TD>Phantom/Reconst Error</TD></TR>\n";
   $out .= "<TR><TD><IMG SRC=\"$pj_png_url\"><br><FONT SIZE=1>$png_pj_out</FONT></TD>\n";
   $out .= "<TD><IMG SRC=\"$diff_png_url\"><br><FONT SIZE=2>$diff_out</FONT><br><FONT SIZE=1>$png_diff_out</FONT></TD></TR>\n";
index 43e4a12..761d95a 100644 (file)
@@ -3,7 +3,7 @@ dnl Process this file with autoconf to produce a configure script.
 dnl Must reset CDPATH so that bash's cd does not print to stdout
 dnl CDPATH=
 
-AC_INIT(src/ctrec.cpp)
+AC_INIT(src/pjrec.cpp)
 AM_INIT_AUTOMAKE(ctsim,1.9.7)
 AM_CONFIG_HEADER(config.h)
 
@@ -311,8 +311,8 @@ ctlibs="$ctlibs_base -lctsim $ctlibs_graphics -lctsupport $ctlibs_tools"
 AC_SUBST(ctlibs)
 
 if test -n "$lamdir" ; then
-  lamprograms="ctrec-lam phm2if-lam phm2pj-lam"
+  lamprograms="pjrec-lam phm2if-lam phm2pj-lam"
   AC_SUBST(lamprograms)
 fi
 
-AC_OUTPUT(Makefile src/Makefile libctgraphics/Makefile libctsupport/Makefile libctsim/Makefile Makefile man/Makefile cgi-bin/ctsim.cgi cgi-bin/Makefile html/simulate.html html/Makefile include/Makefile getopt/Makefile src/sample-ctrec.sh cgi-bin/ctsim.conf)
+AC_OUTPUT(Makefile src/Makefile libctgraphics/Makefile libctsupport/Makefile libctsim/Makefile Makefile man/Makefile cgi-bin/ctsim.cgi cgi-bin/Makefile html/simulate.html html/Makefile include/Makefile getopt/Makefile src/sample-ctsim.sh cgi-bin/ctsim.conf)
index fa5be04..5303c5e 100644 (file)
@@ -1,4 +1,5 @@
-noinst_HEADERS=ct.h ezplot.h pol.h sgp.h array2d.h imagefile.h backprojectors.h mpiworld.h fnetorderstream.h phantom.h timer.h sstream scanner.h projections.h ctsupport.h filter.h
+noinst_HEADERS=ct.h ezplot.h pol.h sgp.h array2d.h imagefile.h backprojectors.h mpiworld.h fnetorderstream.h phantom.h timer.h sstream scanner.h projections.h ctsupport.h filter.h array2dfile.h
+
 
 
 
index 5eb23b3..9caca5c 100644 (file)
@@ -9,17 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: array2d.h,v 1.5 2000/06/19 19:04:05 kevin Exp $
-**  $Log: array2d.h,v $
-**  Revision 1.5  2000/06/19 19:04:05  kevin
-**  reorganized header files
-**
-**  Revision 1.4  2000/06/09 11:03:08  kevin
-**  Made ImageFile inherit from Array2dFile
-**
-**  Revision 1.3  2000/06/09 01:35:33  kevin
-**  Convert MPI structure to C++ class
-**
+**  $Id: array2d.h,v 1.6 2000/06/26 21:15:24 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
@@ -109,7 +99,7 @@ class Array2d {
        }
 
 
-    Array2d& operator= (const Array2d& rhs);
+    Array2d& operator= (const Array2d& rhs); //assignment operator
     Array2d (const Array2d& rhs);  // copy constructor
 };
 
diff --git a/include/array2dfile.h b/include/array2dfile.h
new file mode 100644 (file)
index 0000000..da4671e
--- /dev/null
@@ -0,0 +1,218 @@
+/*****************************************************************************
+** FILE IDENTIFICATION
+**
+**     Name:         array2dfile.h
+**      Purpose:      2-dimension array file class
+**     Programmer:   Kevin Rosenberg
+**     Date Started: June 2000
+**
+**  This is part of the CTSim program
+**  Copyright (C) 1983-2000 Kevin Rosenberg
+**
+**  $Id: array2dfile.h,v 1.1 2000/06/26 21:15:24 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
+**  published by the Free Software Foundation.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+**
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+******************************************************************************/
+
+#ifndef ARRAY2DFILE_H
+#define ARRAY2DFILE_H
+
+#include <sys/types.h>
+#include <string.h>
+#include <unistd.h>
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <vector>
+#include "ctsupport.h"
+#include "fnetorderstream.h"
+#include "array2d.h"
+
+using namespace std;
+
+class Array2dFileLabel
+{
+public:
+    static const int L_EMPTY = 0;
+    static const int L_HISTORY = 1;
+    static const int L_USER = 2;
+
+    Array2dFileLabel(); 
+
+    Array2dFileLabel(const char* const str, double ctime = 0.);
+
+    Array2dFileLabel(const int type, const char* const str, double ctime = 0.);
+
+    ~Array2dFileLabel();
+
+    const string& getLabelString (void) const
+       { return m_strLabel; }
+
+    kfloat64 getCalcTime (void) const
+       { return m_calcTime; }
+
+    int getLabelType (void) const
+       { return m_labelType; }
+
+    string& setLabelString (const char* const str)
+       { m_strLabel = str; return (m_strLabel); }
+
+    string& setLabelString (const string& str)
+       { m_strLabel = str; return (m_strLabel); }
+
+    void setDateTime (int year, int month, int day, int hour, int minute, int second);
+
+    void getDateTime (int& year, int& month, int& day, int& hour, int& minute, int& second) const;
+
+    const string& getDateString () const;
+
+    // Array2dFileLabel (const Array2dFileLabel&);
+
+    // Array2dFileLabel& operator= (const Array2dFileLabel&);
+
+private:
+    void init (void);
+
+    kuint16 m_labelType;
+    kuint16 m_year;
+    kuint16 m_month;
+    kuint16 m_day;
+    kuint16 m_hour;
+    kuint16 m_minute;
+    kuint16 m_second;
+    string m_strLabel;
+    kfloat64 m_calcTime;
+
+    mutable string m_strDate;
+};
+
+
+class Array2dFile 
+{
+public:
+  static const int PIXEL_INVALID = 0;
+  static const int PIXEL_INT8 = 1;
+  static const int PIXEL_UINT8 = 2;
+  static const int PIXEL_INT16 = 3;
+  static const int PIXEL_UINT16 = 4;
+  static const int PIXEL_INT32 = 5;
+  static const int PIXEL_UINT32 = 6;
+  static const int PIXEL_FLOAT32 = 7;
+  static const int PIXEL_FLOAT64 = 8;
+
+  Array2dFile (int nx, int ny, int pixelSize, int pixelFormat = PIXEL_INVALID);
+  Array2dFile (void);
+  ~Array2dFile ();
+
+  void setArraySize (int nx, int ny, int pixelSize, int pixelFormat = PIXEL_INVALID);
+
+  void setArraySize (int nx, int ny);
+
+  unsigned int getNumLabels (void) const
+      { return m_labels.size(); }
+
+  const Array2dFileLabel& labelGet (int label_num) const;
+
+  void labelAdd (const Array2dFileLabel& label);
+
+  void labelAdd (const char* const m_strLabel, double calc_time=0.);
+
+  void labelAdd (int type, const char* const m_strLabel, double calc_time=0.);
+
+  void labelsCopy (Array2dFile& file, const char* const idStr = NULL);
+
+  void setPixelFormat (int type)
+      { m_pixelFormat = type; }
+
+  void setPixelSize (int size)
+      { m_pixelSize = size; }
+
+  kuint32 nx (void) const
+      { return m_nx; }
+
+  kuint32 ny (void) const
+      { return m_ny; }
+
+  void setAxisIncrement (double axisIncX, double axisIncY);
+
+  void setAxisExtent (double minX, double maxX, double minY, double maxY);
+
+  void getPixelValueRange (double& pvmin, double& pvmax) const;
+      
+  void doPixelOffsetScale (double offset, double scale);
+
+  void arrayDataClear (void);
+
+  bool fileRead (const char* const filename);
+
+  bool fileWrite (const char* const filename);
+
+  const string& getFilename (void) const 
+      {  return m_filename; }
+
+  void printLabels (ostream& os) const;
+
+  typedef vector<Array2dFileLabel*>::iterator labelIterator;
+  typedef vector<Array2dFileLabel*>::const_iterator constLabelIterator;
+
+ protected:
+  typedef vector<Array2dFileLabel*> labelContainer;
+
+  static const kuint16 m_signature = ('I'*256+'F');
+  kuint16 m_headersize;
+  string  m_filename;
+
+  kuint16 m_pixelSize;
+  kuint16 m_pixelFormat;
+  kuint16 m_axisIncrementKnown;
+  kfloat64 m_axisIncrementX, m_axisIncrementY;
+  kuint16 m_axisExtentKnown;
+  kfloat64 m_minX, m_maxX, m_minY, m_maxY;
+  kfloat64 m_offsetPV, m_scalePV;
+  kuint32 m_nx;
+  kuint32 m_ny;
+  kuint32 m_arraySize;
+  labelContainer m_labels;
+  kuint16 m_numFileLabels;
+  unsigned char** m_arrayData;
+
+private:
+  void init (void);
+
+  bool headerRead (frnetorderstream& fs);
+
+  bool headerWrite (frnetorderstream& fs);
+
+  bool arrayDataRead (frnetorderstream& fs);
+
+  bool arrayDataWrite (frnetorderstream& fs);
+
+  bool labelsRead (frnetorderstream& fs);
+
+  bool labelsWrite (frnetorderstream& fs);
+
+  bool labelSeek (int label_num);
+
+  void allocArray (void);
+  
+  void freeArray (void);
+
+  Array2dFile (const Array2dFile& rhs);        // copy constructor
+  Array2dFile& operator= (const Array2dFile&); // assignment operator
+
+};
+
+
+
+#endif
index 10f7feb..3788f9d 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: ct.h,v 1.22 2000/06/22 10:42:39 kevin Exp $
+**  $Id: ct.h,v 1.23 2000/06/26 21:15:24 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
@@ -135,6 +135,7 @@ using namespace std;
 #endif
 
 #include "array2d.h"
+#include "array2dfile.h"
 #include "fnetorderstream.h"
 #include "imagefile.h"
 #include "phantom.h"
index 7c6c84a..c5a68e7 100644 (file)
@@ -1,5 +1,32 @@
-#ifndef IDF_H
-#define IDF_H
+/*****************************************************************************
+** FILE IDENTIFICATION
+**
+**     Name:         imagefile.h
+**      Purpose:      imagefile class header
+**     Programmer:   Kevin Rosenberg
+**     Date Started: June 2000
+**
+**  This is part of the CTSim program
+**  Copyright (C) 1983-2000 Kevin Rosenberg
+**
+**  $Id: imagefile.h,v 1.15 2000/06/26 21:15:24 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
+**  published by the Free Software Foundation.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+**
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+******************************************************************************/
+
+#ifndef IMAGEFILE_H
+#define IMAGEFILE_H
 
 #include <string>
 #include <sys/types.h>
 #include <iostream>
 #include "ctsupport.h"
 #include "fnetorderstream.h"
-#include "array2d.h"
+#include "array2dfile.h"
 
 using namespace std;
 
-
-class Array2dFileLabel
-{
-public:
-    kfloat64 m_calcTime;
-    kuint16 m_labelType;
-    kuint16 m_year;
-    kuint16 m_month;
-    kuint16 m_day;
-    kuint16 m_hour;
-    kuint16 m_minute;
-    kuint16 m_second;
-    string m_strLabel;
-    mutable string m_strDate;
-
-    static const int L_EMPTY = 0;
-    static const int L_HISTORY = 1;
-    static const int L_USER = 2;
-
-    Array2dFileLabel(); 
-
-    Array2dFileLabel(const char* const str, double ctime = 0.);
-
-    Array2dFileLabel(const int type, const char* const str, double ctime = 0.);
-
-    ~Array2dFileLabel();
-
-    const string& getLabelString (void) const
-       { return m_strLabel; }
-
-    kfloat64 getCalcTime (void) const
-       { return m_calcTime; }
-
-    kfloat64 getLabelType (void) const
-       { return m_labelType; }
-
-    string& setLabelString (const char* const str)
-       { m_strLabel = str; return (m_strLabel); }
-
-    string& setLabelString (const string& str)
-       { m_strLabel = str; return (m_strLabel); }
-
-    const string& getDateString () const;
-
-private:
-    void init (void);
-    Array2dFileLabel (const Array2dFileLabel&);
-    Array2dFileLabel& operator= (const Array2dFileLabel&);
-};
-
-
-template<class T>
-class Array2dFile 
-{
-private:
-  void init (void);
-
-  bool headerWrite (void);
-
-  bool headerRead (void);
-
-  bool arrayDataRead (void);
-
-  bool labelSeek (unsigned int label_num);
-
-  Array2dFile (const Array2dFile& rhs);        // copy constructor
-  Array2dFile& operator= (const Array2dFile&); // assignment operator
-
- protected:
-  kuint16 signature;
-  kuint16 num_labels;
-  kuint16 headersize;
-  string  filename;
-  int file_id;
-  frnetorderstream *m_pFS;
-  bool bHeaderWritten;
-  bool bDataWritten;
-
-  kuint16 mPixelSize;
-  kuint16 axis_increment_known;
-  kfloat64 mIncX, mIncY;
-  kuint16 axis_extent_known;
-  kfloat64 mMinX, mMaxX, mMinY, mMaxY;
-  kfloat64 mOffsetPV, mScalePV;
-  kuint16 mPixelType;
-  kuint32 mNX;
-  kuint32 mNY;
-
-
-public:
-
-  Array2d<T> array;
-
-  static const int INT8 = 1;
-  static const int UINT8 = 2;
-  static const int INT16 = 3;
-  static const int UINT16 = 4;
-  static const int INT32 = 5;
-  static const int UINT32 = 6;
-  static const int FLOAT32 = 7;
-  static const int FLOAT64 = 8;
-
-  Array2dFile (unsigned int nx, unsigned int ny);
-  Array2dFile (const char* const filename);
-  Array2dFile (const char* const filename, unsigned int nx, unsigned int ny);
-  ~Array2dFile ();
-
-  unsigned int getNumLabels (void) const
-      { return num_labels; }
-
-  bool labelRead (Array2dFileLabel& label, unsigned int label_num);
-
-  void labelAdd (const Array2dFileLabel& label);
-
-  void labelAdd (const char* const m_strLabel, double calc_time=0.);
-
-  void labelAdd (int type, const char* const m_strLabel, double calc_time=0.);
-
-  void labelsCopy (Array2dFile& file, const char* const idStr = NULL);
-
-  void fileClose (void);
-
-  void setPixelType (int type)
-      { mPixelType = type; }
-
-  kuint32 nx (void) const
-      { return mNX; }
-
-  kuint32 ny (void) const
-      { return mNY; }
-
-  void setAxisIncrement (double mIncX, double mIncY);
-
-  void setAxisExtent (double mMinX, double mMaxX, double mMinY, double mMaxY);
-
-  void getPixelValueRange (T& pvmin, T& pvmax) const;
-      
-  void doPixelOffsetScale (double offset, double scale);
-
-  void printLabels (ostream& os);
-
-  T** getArray (void) const
-      { return (array.getArray()); }
-
-  bool arrayDataWrite (void);
-
-  void arrayDataClear (void);
-
-  bool fileRead (void);
-
-  bool fileCreate (void);
-
-  const string& GetFilename (void) const 
-      {  return filename; }
-};
-
-
-template<class T>
-Array2dFile<T>::Array2dFile (unsigned int x, unsigned int y)
-{
-    init();
-    mNX = x;
-    mNY = y;
-    array.initSetSize(mNX, mNY);
-}
-
-template<class T>
-Array2dFile<T>::Array2dFile (const char * const str, unsigned int x, unsigned int y)
-  : filename(str)
-{
-    init();
-    mNX = x;
-    mNY = y;
-    array.initSetSize(mNX, mNY);
-}
-
-template<class T>
-Array2dFile<T>::Array2dFile (const char * const str)
-  : filename(str)
-{
-    init();
-}
-
-template<class T>
-void
-Array2dFile<T>::init (void)
-{
-  mPixelSize = sizeof(T);
-  signature = ('I' * 256 + 'F');
-  mNX = 0;
-  mNY = 0;
-  headersize = 0;
-  num_labels = 0;
-  axis_increment_known = false;
-  axis_extent_known = false;
-  mIncX = mMinY = 0;
-  mMinX = mMaxX = mMinY = mMaxY = 0;
-  mOffsetPV = 0;
-  mScalePV = 1;
-  m_pFS = NULL;
-
-#if 0
-  const type_info& t_id = typeid(T);
-  cout << t_id.name() << endl;
-  const type_info& comp_id = typeid(T);
-
-  if (t_id == comp_id)
-      mPixelType = FLOAT64;
-  else if (t_id == typeid(kfloat32))
-    mPixelType = FLOAT32;
-  else if (t_id == typeid(kint32))
-    mPixelType = INT32;
-  else if (t_id == typeid(kuint32))
-    mPixelType = UINT32;
-  else if (t_id == typeid(kint16))
-    mPixelType = INT16;
-  else if (t_id == typeid(kuint16))
-    mPixelType = UINT16;
-  else if (t_id == typeid(kint8))
-    mPixelType = INT8;
-  else if (t_id == typeid(kuint8))
-    mPixelType = UINT8;
-  else
-#endif
-      mPixelType = 0;
-
-  bHeaderWritten = false;
-  bDataWritten = false;
-}
-
-template<class T>
-Array2dFile<T>::~Array2dFile (void)
-{
-    fileClose ();
-}
-
-
-template<class T>
-void
-Array2dFile<T>::fileClose (void)
-{
-  if (m_pFS) {
-      headerWrite ();
-      m_pFS->close ();
-      m_pFS = NULL;
-  }
-}
-
-template<class T>
-bool
-Array2dFile<T>::fileCreate (void)
-{
-  m_pFS = new frnetorderstream (filename.c_str(), ios::out | ios::in | ios::trunc | ios::binary);
-  if (! m_pFS) {
-      sys_error (ERR_WARNING, "Error opening file %s for writing [fileCreate]", filename.c_str());
-      return (false);
-  }
-  headerWrite();
-  return (true);
-}
-
-template<class T>
-bool
-Array2dFile<T>::fileRead (void)
-{
-  m_pFS = new frnetorderstream (filename.c_str(), ios::out | ios::in | ios::binary | ios::nocreate);
-  if (m_pFS->fail()) {
-    sys_error (ERR_WARNING, "Unable to open file %s [fileRead]", filename.c_str());
-    return (false);
-  }
-
-  if (! headerRead())
-      return false;
-
-  array.initSetSize(mNX, mNY);
-
-  arrayDataRead();
-
-  return (true);
-}
-
-template<class T>
-void
-Array2dFile<T>::setAxisIncrement (double incX, double incY)
-{
-    axis_increment_known = true;
-    mIncX = incX;
-    mIncY = incY;
-}
-
-template<class T>
-void 
-Array2dFile<T>::setAxisExtent (double minX, double maxX, double minY, double maxY)
-{
-    axis_extent_known = true;
-    mMinX = minX;
-    mMaxY = maxX;
-    mMinX = minX;
-    mMaxY = maxY;
-}
-
-template<class T>
-void 
-Array2dFile<T>::getPixelValueRange (T& pvmin, T& pvmax) const
-{
-    T** da = array.getArray();
-    if (da) {
-       pvmax = pvmin = da[0][0];
-       for (int ix = 0; ix < mNX; ix++)
-           for (int iy = 0; iy < mNY; iy++)
-               if (pvmax < da[ix][iy])
-                   pvmax = da[ix][iy];
-               else if (pvmin > da[ix][iy])
-                   pvmin = da[ix][iy];
-    }
-}
-
-template<class T>
-void
-Array2dFile<T>::doPixelOffsetScale (double offset, double scale)
-{
-    T** ad = array.getArray();
-    if (ad) {
-       mOffsetPV = offset;
-       mScalePV = scale;
-
-       for (unsigned int ix = 0; ix < mNX; ix++) 
-           for (unsigned int iy = 0; iy < mNY; iy++)
-               ad[ix][iy] = (ad[ix][iy] - offset) * scale;
-    }
-}
-
-template<class T>
-bool
-Array2dFile<T>::headerRead (void)
-{
-  if (! m_pFS) {
-    sys_error (ERR_WARNING, "Tried to read header with file closed [headerRead]");
-    return (false);
-  }
-
-  m_pFS->seekg (0);
-  kuint16 file_signature;
-  kuint16 file_mPixelSize;
-  kuint16 file_mPixelType;
-
-  m_pFS->readInt16 (headersize);
-  m_pFS->readInt16 (file_signature);
-  m_pFS->readInt16 (num_labels);
-  m_pFS->readInt16 (file_mPixelType);
-  m_pFS->readInt16 (file_mPixelSize);
-  m_pFS->readInt32 (mNX);
-  m_pFS->readInt32 (mNY);
-  m_pFS->readInt16 (axis_increment_known);
-  m_pFS->readFloat64 (mIncX);
-  m_pFS->readFloat64 (mIncY);
-  m_pFS->readInt16 (axis_extent_known);
-  m_pFS->readFloat64 (mMinX);
-  m_pFS->readFloat64 (mMaxX);
-  m_pFS->readFloat64 (mMinY);
-  m_pFS->readFloat64 (mMaxY);
-  m_pFS->readFloat64 (mOffsetPV);
-  m_pFS->readFloat64 (mScalePV);
-
-  int read_headersize = m_pFS->tellg();
-  if (read_headersize != headersize) {
-    sys_error (ERR_WARNING, "Read headersize %d != file headersize %d", read_headersize, headersize);
-    return (false);
-  }
-  if (file_signature != signature) {
-    sys_error (ERR_WARNING, "File signature %d != true signature %d", file_signature, signature);
-    return (false);
-  }
-  if (file_mPixelType != mPixelType) {
-    sys_error (ERR_WARNING, "File pixel type %d != class pixel type %d", file_mPixelType, mPixelType);
-    return (false);
-  }
-  if (file_mPixelSize != mPixelSize) {
-    sys_error (ERR_WARNING, "File pixel size %d != class pixel size %d", file_mPixelSize, mPixelSize);
-    return (false);
-  }
-
-  return (true);
-}
-
-template<class T>
-bool
-Array2dFile<T>::headerWrite (void)
-{
-  if (! m_pFS) {
-    sys_error (ERR_WARNING, "Tried to write header with file closed");
-    return (false);
-  }
-
-  m_pFS->seekp (0);
-  m_pFS->writeInt16 (headersize);
-  m_pFS->writeInt16 (signature);
-  m_pFS->writeInt16 (num_labels);
-  m_pFS->writeInt16 (mPixelType);
-  m_pFS->writeInt16 (mPixelSize);
-  m_pFS->writeInt32 (mNX);
-  m_pFS->writeInt32 (mNY);
-  m_pFS->writeInt16 (axis_increment_known);
-  m_pFS->writeFloat64 (mIncX);
-  m_pFS->writeFloat64 (mIncY);
-  m_pFS->writeInt16 (axis_extent_known);
-  m_pFS->writeFloat64 (mMinX);
-  m_pFS->writeFloat64 (mMaxX);
-  m_pFS->writeFloat64 (mMinY);
-  m_pFS->writeFloat64 (mMaxY);
-  m_pFS->writeFloat64 (mOffsetPV);
-  m_pFS->writeFloat64 (mScalePV);
-
-  headersize = m_pFS->tellp();
-  m_pFS->writeInt16 (headersize);
-  
-  return (true);
-}
-
-template<class T>
-bool
-Array2dFile<T>::arrayDataWrite (void)
-{
-  if (! m_pFS) {
-    sys_error (ERR_WARNING, "Tried to arrayDataWrite with !m_pFS");
-    return (false);
-  }
-
-  T** da = array.getArray();
-  if (! da) 
-      return (false);
-
-  m_pFS->seekp (headersize);
-  for (unsigned int ix = 0; ix < mNX; ix++) {
-      if (NativeBigEndian()) {
-         for (unsigned int iy = 0; iy < mNY; iy++) {
-             T value = da[ix][iy];
-             ConvertReverseNetworkOrder (&value, sizeof(T));
-             m_pFS->write (&value, mPixelSize);
-         }
-      } else 
-         m_pFS->write (da[ix], sizeof(T) * mNY);
-  }
-
-  return (true);
-}
-
-template<class T>
-bool
-Array2dFile<T>::arrayDataRead (void)
-{
-  if (! m_pFS) {
-    sys_error (ERR_WARNING, "Tried to arrayDataRead with !m_pFS");
-    return (false);
-  }
-
-  T** da = array.getArray();
-  if (! da) 
-      return (false);
-
-  m_pFS->seekg (headersize);
-  T pixelBuffer;
-  for (int ix = 0; ix < mNX; ix++) {
-      if (NativeBigEndian()) {
-         for (unsigned int iy = 0; iy < mNY; iy++) {
-             m_pFS->read (&pixelBuffer, mPixelSize);
-             ConvertReverseNetworkOrder (&pixelBuffer, sizeof(T));
-             da[ix][iy] = pixelBuffer;
-         } 
-      } else
-         m_pFS->read (da[ix], sizeof(T) * mNY);
-  }
-
-
-  return (true);
-}
-
-template<class T>
-bool
-Array2dFile<T>::labelSeek (unsigned int label_num)
-{
-  if (label_num > num_labels) {
-    sys_error (ERR_WARNING, "label_num %d > num_labels %d [labelSeek]");
-    return (false);
-  }
-
-  if (array.getArray() == NULL) {    // Could not have written data if array not allocated
-    sys_error (ERR_WARNING, "array == NULL [labelSeek]");
-    return (false);
-  }
-
-  off_t pos = headersize + array.sizeofArray();
-  m_pFS->seekg (pos);
-
-  for (int i = 0; i < label_num; i++)
-      {
-         pos += 22;  // Skip to string length
-         m_pFS->seekg (pos);
-             
-         kuint16 strlength;
-         m_pFS->readInt16 (strlength);
-         pos += 2 + strlength;  // Skip label string length + data
-         m_pFS->seekg (pos);
-      }
-  
-  if (! m_pFS)
-      return false;
-
-  return (true);
-}
-
-template<class T>
-bool
-Array2dFile<T>::labelRead (Array2dFileLabel& label, unsigned int label_num)
-{
-  if (label_num >= num_labels) {
-    sys_error (ERR_WARNING, "Trying to read past number of labels [labelRead]");
-    return (false);
-  }
-
-  if (! labelSeek (label_num)) {
-    sys_error (ERR_WARNING, "Error calling labelSeek");
-    return (false);
-  }
-
-  m_pFS->readInt16 (label.m_labelType);
-  m_pFS->readInt16 (label.m_year);
-  m_pFS->readInt16 (label.m_month);
-  m_pFS->readInt16 (label.m_day);
-  m_pFS->readInt16 (label.m_hour);
-  m_pFS->readInt16 (label.m_minute);
-  m_pFS->readInt16 (label.m_second);
-  m_pFS->readFloat64 (label.m_calcTime);
-
-  kuint16 strlength;
-  m_pFS->readInt16 (strlength);
-  char str [strlength+1];
-  m_pFS->read (str, strlength);
-  str[strlength] = 0;
-  label.m_strLabel = str;
-
-  return (true);
-}
-
-
-template<class T>
-void
-Array2dFile<T>::labelAdd (const char* const lstr, double calc_time=0.)
-{
-  labelAdd (Array2dFileLabel::L_HISTORY, lstr, calc_time);
-}
-
-template<class T>
-void
-Array2dFile<T>::labelAdd (int type, const char* const lstr, double calc_time=0.)
-{
-  Array2dFileLabel label (type, lstr, calc_time);
-
-  labelAdd (label);
-}
-
-template<class T>
-void
-Array2dFile<T>::labelAdd (const Array2dFileLabel& label)
-{
-  labelSeek (num_labels);
-  
-  m_pFS->writeInt16 (label.m_labelType);
-  m_pFS->writeInt16 (label.m_year);
-  m_pFS->writeInt16 (label.m_month);
-  m_pFS->writeInt16 (label.m_day);
-  m_pFS->writeInt16 (label.m_hour);
-  m_pFS->writeInt16 (label.m_minute);
-  m_pFS->writeInt16 (label.m_second);
-  m_pFS->writeFloat64 (label.m_calcTime);
-  kuint16 strlength = label.m_strLabel.length();
-  m_pFS->writeInt16 (strlength);
-  m_pFS->write (label.m_strLabel.c_str(), strlength);
-
-  num_labels++;
-
-  headerWrite();
-}
-
-template<class T>
-void
-Array2dFile<T>::labelsCopy (Array2dFile& copyFile, const char* const idStr)
-{
-    string id = idStr;
-    for (int i = 0; i < copyFile.getNumLabels(); i++) {
-      Array2dFileLabel l;
-      copyFile.labelRead (l, i);
-      string lstr = l.getLabelString();
-      lstr = idStr + lstr;
-      l.setLabelString (lstr);
-      labelAdd (l);
-    }
-}
-
-template<class T>
-void 
-Array2dFile<T>::arrayDataClear (void)
-{
-    T** v = array.getArray();
-    if (v) {
-       for (unsigned int ix = 0; ix < mNX; ix++)
-           for (unsigned int iy = 0; iy < mNY; iy++)
-               v[ix][iy] = 0;
-    }
-}
-
-template<class T>
-void
-Array2dFile<T>::printLabels (ostream& os)
-{
-    int nlabels = getNumLabels();
-
-    for (int i = 0; i < nlabels; i++) {
-       Array2dFileLabel label;
-       labelRead (label, i);
-
-       if (label.getLabelType() == Array2dFileLabel::L_HISTORY) {
-           os << "History: " << endl;
-           os << "  " << label.getLabelString() << endl;
-           os << "  calc time = " << label.getCalcTime() << " secs" << endl;
-           os << "  Timestamp = " << label.getDateString() << endl;
-       } else if (label.getLabelType() == Array2dFileLabel::L_USER) {
-           os << "Note: " <<  label.getLabelString() << endl;
-           os << "  Timestamp = %s" << label.getDateString() << endl;
-       }
-       os << endl;
-    }
-}
-
 #ifdef HAVE_MPI
 #include <mpi++.h>
 #endif
 
-class F32Image : public Array2dFile<kfloat32>
+class F32Image : public Array2dFile
 {
 public:
-  F32Image (const char* const fname, unsigned int nx, unsigned int ny)
-      : Array2dFile<kfloat32>::Array2dFile (fname, nx, ny)
+  F32Image (int nx, int ny)
+      : Array2dFile::Array2dFile (nx, ny, sizeof(kfloat32), Array2dFile::PIXEL_FLOAT32)
   {
-      setPixelType (FLOAT32);
   }
 
-  F32Image (unsigned int nx, unsigned int ny)
-      : Array2dFile<kfloat32>::Array2dFile (nx, ny)
+  F32Image (void)
+      : Array2dFile::Array2dFile()
   {
-      setPixelType (FLOAT32);
+      setPixelFormat (Array2dFile::PIXEL_FLOAT32);
+      setPixelSize (sizeof(kfloat32));
   }
 
-  F32Image (const char* const fname)
-      : Array2dFile<kfloat32>::Array2dFile (fname)
-  {
-      setPixelType (FLOAT32);
-  }
+  kfloat32** getArray (void)
+      { return (kfloat32**) (m_arrayData); }
+
+  const kfloat32** getArray (void) const
+       { return (const kfloat32**) (m_arrayData); }
 
 #ifdef HAVE_MPI
   MPI::Datatype getMPIDataType (void) const
@@ -682,27 +75,27 @@ public:
 };
 
 
-class F64Image : public Array2dFile<kfloat64>
+class F64Image : public Array2dFile
 {
  public:
 
-  F64Image (const char* const fname, unsigned int nx, unsigned int ny)
-      : Array2dFile<kfloat64>::Array2dFile (fname, nx, ny)
+  F64Image (int nx, int ny)
+      : Array2dFile::Array2dFile (nx, ny, sizeof(kfloat64), Array2dFile::PIXEL_FLOAT64)
   {
-      setPixelType (FLOAT64);
   }
 
-  F64Image (unsigned int nx, unsigned int ny)
-      : Array2dFile<kfloat64>::Array2dFile (nx, ny)
+  F64Image (void)
+      : Array2dFile::Array2dFile ()
   {
-      setPixelType (FLOAT64);
+      setPixelFormat (PIXEL_FLOAT64);
+      setPixelSize (sizeof(kfloat64));
   }
 
-  F64Image (const char* const fname)
-      : Array2dFile<kfloat64>::Array2dFile (fname)
-  {
-      setPixelType (FLOAT64);
-  }
+  kfloat64** getArray (void)
+      { return (kfloat64**) (m_arrayData); }
+
+  const kfloat64** getArray (void) const
+      { return (const kfloat64**) (m_arrayData); }
 
 #ifdef HAVE_MPI
   MPI::Datatype getMPIDataType (void) const
@@ -730,16 +123,12 @@ typedef kfloat32** ImageFileArray;
 class ImageFile : public ImageFileBase
 {
  public:
-  ImageFile (const char* const fname, unsigned int nx, unsigned int ny)
-      : ImageFileBase (fname, nx, ny)
-  {}
-
-  ImageFile (unsigned int nx, unsigned int ny)
+  ImageFile (int nx, int ny)
       : ImageFileBase (nx, ny)
   {}
 
-  ImageFile (const char* const fname)
-      : ImageFileBase (fname)
+  ImageFile (void)
+      : ImageFileBase ()
   {}
 
   void filterResponse (const char* const domainName, double bw, const char* const filterName, double filt_param);
@@ -760,6 +149,3 @@ class ImageFile : public ImageFileBase
 
 
 #endif
-
-
-
index b932178..1d340b8 100644 (file)
@@ -1,5 +1,5 @@
 noinst_LIBRARIES = libctsim.a 
-libctsim_a_SOURCES = filter.cpp scanner.cpp projections.cpp phantom.cpp imagefile.cpp backprojectors.cpp
+libctsim_a_SOURCES = filter.cpp scanner.cpp projections.cpp phantom.cpp imagefile.cpp backprojectors.cpp array2dfile.cpp
 
 INCLUDES=@my_includes@
 EXTRA_DIST=Makefile.nt
diff --git a/libctsim/array2dfile.cpp b/libctsim/array2dfile.cpp
new file mode 100644 (file)
index 0000000..d603813
--- /dev/null
@@ -0,0 +1,548 @@
+/*****************************************************************************
+** FILE IDENTIFICATION
+**
+**     Name:         array2dfile.cpp
+**      Purpose:      2-dimension array file class
+**     Programmer:   Kevin Rosenberg
+**     Date Started: June 2000
+**
+**  This is part of the CTSim program
+**  Copyright (C) 1983-2000 Kevin Rosenberg
+**
+**  $Id: array2dfile.cpp,v 1.1 2000/06/26 21:15:24 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
+**  published by the Free Software Foundation.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+**
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+******************************************************************************/
+
+#include "array2dfile.h"
+#include <ctime>
+#include <sstream>
+
+using namespace std;
+
+
+///////////////////////////////////////////////////////////////////////////
+// CLASS IMPLEMENTATION
+//
+//     Name: Array2dFileLabel
+//     Purpose: Labels for Array2dFiles
+///////////////////////////////////////////////////////////////////////////
+
+void
+Array2dFileLabel::init (void)
+{
+    m_calcTime = 0;
+    m_labelType = L_EMPTY;
+    time_t t = time(0);
+    tm* lt = localtime(&t);
+    m_year = lt->tm_year + 1900;
+    m_month = lt->tm_mon + 1;
+    m_day = lt->tm_mday;
+    m_hour = lt->tm_hour;
+    m_minute = lt->tm_min;
+    m_second = lt->tm_sec;
+}
+
+Array2dFileLabel::Array2dFileLabel() 
+{
+    init();
+}
+
+Array2dFileLabel::Array2dFileLabel(const char* const str, double ctime = 0.)
+  : m_strLabel (str)
+{
+    init();
+
+    m_labelType = L_USER;
+    m_calcTime = ctime;
+}
+
+Array2dFileLabel::Array2dFileLabel(const int type, const char* const str, double ctime = 0.)
+  :  m_strLabel (str)
+{
+    init();
+
+    m_labelType = type;
+    m_calcTime = ctime;
+}
+
+Array2dFileLabel::~Array2dFileLabel()
+{
+}
+
+void 
+Array2dFileLabel::setDateTime (int year, int month, int day, int hour, int minute, int second)
+{
+  m_year = year;
+  m_month = month;
+  m_day = day;
+  m_hour = hour;
+  m_minute = minute;
+  m_second = second;
+}
+
+void 
+Array2dFileLabel::getDateTime (int& year, int& month, int& day, int& hour, int& minute, int& second) const
+{
+  year = m_year;
+  month = m_month;
+  day = m_day;
+  hour = m_hour;
+  minute = m_minute;
+  second = m_second;
+}
+
+const string& 
+Array2dFileLabel::getDateString (void) const
+{
+  ostringstream oss;
+  oss <<  m_month <<"/"<< m_day <<"/"<< m_year << " " << m_hour <<":"<<  m_minute <<":"<< m_second;
+  m_strDate = oss.str();
+  return m_strDate;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+// CLASS IMPLEMENTATION
+//
+//     Name: Array2dFile
+//     Purpose: Array2dFiles
+///////////////////////////////////////////////////////////////////////////
+
+
+Array2dFile::Array2dFile (int x, int y, int pixelSize, int pixelFormat)
+{
+    init();
+    setArraySize (x, y, pixelSize, pixelFormat);
+}
+
+Array2dFile::~Array2dFile (void)
+{
+    freeArray ();
+    for (labelIterator l = m_labels.begin(); l != m_labels.end(); l++)
+       delete *l;
+}
+
+Array2dFile::Array2dFile (void)
+{
+    init();
+}
+
+void
+Array2dFile::init (void)
+{
+  m_pixelSize = 0;
+  m_pixelFormat = PIXEL_INVALID;
+  m_arrayData = NULL;
+  m_nx = 0;
+  m_ny = 0;
+  m_headersize = 0;
+  m_axisIncrementKnown = false;
+  m_axisIncrementX = m_axisIncrementY = 0;
+  m_axisExtentKnown = false;
+  m_minX = m_maxX = m_minY = m_maxY = 0;
+  m_offsetPV = 0;
+  m_scalePV = 1;
+}
+
+
+void
+Array2dFile::setArraySize (int x, int y, int pixelSize, int pixelFormat)
+{
+    m_nx = x;
+    m_ny = y;
+    m_pixelSize = pixelSize;
+    m_arraySize = m_nx * m_ny * m_pixelSize;
+    m_pixelFormat = pixelFormat;
+    allocArray ();
+}
+
+void
+Array2dFile::setArraySize (int x, int y)
+{
+    m_nx = x;
+    m_ny = y;
+    allocArray ();
+}
+
+void 
+Array2dFile::allocArray (void)
+{
+    if (m_arrayData)
+       freeArray();
+
+    m_arraySize = m_nx * m_ny * m_pixelSize;
+    m_arrayData = new unsigned char* [m_nx];
+    
+    int columnBytes = m_ny * m_pixelSize;
+    for (int i = 0; i < m_nx; i++)
+       m_arrayData[i] = new unsigned char [columnBytes];
+}
+
+void 
+Array2dFile::freeArray (void)
+{
+    if (m_arrayData) {
+       for (int i = 0; i < m_nx; i++)
+           delete m_arrayData[i];
+       delete m_arrayData;
+       m_arrayData = NULL;
+    }
+}
+
+bool
+Array2dFile::fileWrite (const char* const filename)
+{
+    m_filename = filename;
+
+    frnetorderstream fs (m_filename.c_str(), ios::out | ios::in | ios::trunc | ios::binary);
+    if (fs.fail()) {
+       sys_error (ERR_WARNING, "Error opening file %s for writing [fileCreate]", m_filename.c_str());
+      return false;
+    }
+    if (! headerWrite(fs))
+       return false;
+    
+    if (! arrayDataWrite (fs))
+       return false;
+    
+    if (! labelsWrite (fs))
+       return false;
+
+    return true;
+}
+
+bool
+Array2dFile::fileRead (const char* const filename)
+{
+    m_filename = filename;
+
+    frnetorderstream fs (m_filename.c_str(), ios::out | ios::in | ios::binary | ios::nocreate);
+    if (fs.fail()) {
+      sys_error (ERR_WARNING, "Unable to open file %s [fileRead]", m_filename.c_str());
+      return false;
+    }
+
+    if (! headerRead(fs))
+      return false;
+    
+    allocArray ();
+    
+    if (! arrayDataRead(fs))
+      return false;;
+
+    if (! labelsRead (fs))
+      return false;
+    
+    return true;
+}
+
+void
+Array2dFile::setAxisIncrement (double incX, double incY)
+{
+  m_axisIncrementKnown = true;
+  m_axisIncrementX = incX;
+  m_axisIncrementY = incY;
+}
+
+void 
+Array2dFile::setAxisExtent (double minX, double maxX, double minY, double maxY)
+{
+    m_axisExtentKnown = true;
+    m_minX = minX;
+    m_maxY = maxX;
+    m_minX = minX;
+    m_maxY = maxY;
+}
+
+bool
+Array2dFile::headerRead (frnetorderstream& fs)
+{
+  if (! fs) {
+    sys_error (ERR_WARNING, "Tried to read header with file closed [headerRead]");
+    return false;
+  }
+
+  fs.seekg (0);
+  kuint16 file_signature;
+
+  fs.readInt16 (m_headersize);
+  fs.readInt16 (file_signature);
+  fs.readInt16 (m_pixelFormat);
+  fs.readInt16 (m_pixelSize);
+  fs.readInt16 (m_numFileLabels);
+  fs.readInt32 (m_nx);
+  fs.readInt32 (m_ny);
+  fs.readInt16 (m_axisIncrementKnown);
+  fs.readFloat64 (m_axisIncrementX);
+  fs.readFloat64 (m_axisIncrementY);
+  fs.readInt16 (m_axisExtentKnown);
+  fs.readFloat64 (m_minX);
+  fs.readFloat64 (m_maxX);
+  fs.readFloat64 (m_minY);
+  fs.readFloat64 (m_maxY);
+  fs.readFloat64 (m_offsetPV);
+  fs.readFloat64 (m_scalePV);
+
+  int read_m_headersize = fs.tellg();
+  if (read_m_headersize != m_headersize) {
+    sys_error (ERR_WARNING, "Read m_headersize %d != file m_headersize %d", read_m_headersize, m_headersize);
+    return false;
+  }
+  if (file_signature != m_signature) {
+    sys_error (ERR_WARNING, "File signature %d != true signature %d", file_signature, m_signature);
+    return false;
+  }
+
+  return true;
+}
+
+
+bool
+Array2dFile::headerWrite (frnetorderstream& fs)
+{
+  if (! fs) {
+    sys_error (ERR_WARNING, "Tried to write header with ! fs");
+    return false;
+  }
+
+  m_numFileLabels = m_labels.size();
+
+  fs.seekp (0);
+  fs.writeInt16 (m_headersize);
+  fs.writeInt16 (m_signature);
+  fs.writeInt16 (m_pixelFormat);
+  fs.writeInt16 (m_pixelSize);
+  fs.writeInt16 (m_numFileLabels);
+  fs.writeInt32 (m_nx);
+  fs.writeInt32 (m_ny);
+  fs.writeInt16 (m_axisIncrementKnown);
+  fs.writeFloat64 (m_axisIncrementX);
+  fs.writeFloat64 (m_axisIncrementY);
+  fs.writeInt16 (m_axisExtentKnown);
+  fs.writeFloat64 (m_minX);
+  fs.writeFloat64 (m_maxX);
+  fs.writeFloat64 (m_minY);
+  fs.writeFloat64 (m_maxY);
+  fs.writeFloat64 (m_offsetPV);
+  fs.writeFloat64 (m_scalePV);
+
+  m_headersize = fs.tellp();
+  fs.seekp (0);
+  fs.writeInt16 (m_headersize);
+  
+  return true;
+}
+
+
+bool
+Array2dFile::arrayDataWrite (frnetorderstream& fs)
+{
+  if (! fs) {
+    sys_error (ERR_WARNING, "Tried to arrayDataWrite with !fs");
+    return false;
+  }
+
+  if (! m_arrayData) 
+      return false;
+
+  fs.seekp (m_headersize);
+  int columnSize = m_ny * m_pixelSize;
+  for (unsigned int ix = 0; ix < m_nx; ix++) {
+      unsigned char* ptrColumn = m_arrayData[ix];
+      if (NativeBigEndian()) {
+         for (unsigned int iy = 0; iy < m_ny; iy++) {
+             ConvertReverseNetworkOrder (ptrColumn, m_pixelSize);
+             fs.write (ptrColumn, m_pixelSize);
+             ptrColumn += m_pixelSize;
+         }
+      } else 
+         fs.write (ptrColumn, columnSize);
+  }
+
+  return true;
+}
+
+
+bool
+Array2dFile::arrayDataRead (frnetorderstream& fs)
+{
+  if (! fs) {
+    sys_error (ERR_WARNING, "Tried to arrayDataRead with ! fs");
+    return false;
+  }
+
+  if (! m_arrayData)
+      return false;
+
+  fs.seekg (m_headersize);
+  int columnSize = m_ny * m_pixelSize;
+  for (int ix = 0; ix < m_nx; ix++) {
+      unsigned char* ptrColumn = m_arrayData[ix];
+      if (NativeBigEndian()) {
+         for (unsigned int iy = 0; iy < m_ny; iy++) {
+             fs.read (ptrColumn, m_pixelSize);
+             ConvertReverseNetworkOrder (ptrColumn, m_pixelSize);
+             ptrColumn += m_pixelSize;
+         } 
+      } else
+         fs.read (ptrColumn, columnSize);
+  }
+
+  return true;
+}
+
+bool
+Array2dFile::labelsRead (frnetorderstream& fs)
+{
+    off_t pos = m_headersize + m_arraySize;
+    fs.seekg (pos);
+    if (fs.fail())
+       return false;
+
+    for (int i = 0; i < m_numFileLabels; i++) {
+       kuint16 labelType, year, month, day, hour, minute, second;
+       kfloat64 calcTime;
+
+       fs.readInt16 (labelType);
+       fs.readInt16 (year);
+       fs.readInt16 (month);
+       fs.readInt16 (day);
+       fs.readInt16 (hour);
+       fs.readInt16 (minute);
+       fs.readInt16 (second);
+       fs.readFloat64 (calcTime);
+       
+       kuint16 strLength;
+       fs.readInt16 (strLength);
+       char labelStr [strLength+1];
+       fs.read (labelStr, strLength);
+       labelStr[strLength] = 0;
+
+       Array2dFileLabel* pLabel = new Array2dFileLabel(labelType, labelStr, calcTime);
+       pLabel->setDateTime (year, month, day, hour, minute, second);
+       m_labels.push_back (pLabel);
+    }
+
+    return true;
+}
+
+bool
+Array2dFile::labelsWrite (frnetorderstream& fs)
+{
+    off_t pos = m_headersize + m_arraySize;
+    fs.seekp (pos);
+
+    for (constLabelIterator l = m_labels.begin(); l != m_labels.end(); l++) {
+       const Array2dFileLabel& label = **l;
+       kuint16 labelType = label.getLabelType();
+       kfloat64 calcTime = label.getCalcTime();
+       const char* const labelString = label.getLabelString().c_str();
+       int year, month, day, hour, minute, second;
+       kuint16 yearBuf, monthBuf, dayBuf, hourBuf, minuteBuf, secondBuf;
+
+       label.getDateTime (year, month, day, hour, minute, second);
+       yearBuf = year; monthBuf = month; dayBuf = day;
+       hourBuf = hour; minuteBuf = minute; secondBuf = second;
+
+       fs.writeInt16 (labelType);
+       fs.writeInt16 (yearBuf);
+       fs.writeInt16 (monthBuf);
+       fs.writeInt16 (dayBuf);
+       fs.writeInt16 (hourBuf);
+       fs.writeInt16 (minuteBuf);
+       fs.writeInt16 (secondBuf);
+       fs.writeFloat64 (calcTime);
+       kuint16 strlength = strlen (labelString);
+       fs.writeInt16 (strlength);
+       fs.write (labelString, strlength);
+    }
+
+    return true;
+}
+
+void
+Array2dFile::labelAdd (const char* const lstr, double calc_time=0.)
+{
+  labelAdd (Array2dFileLabel::L_HISTORY, lstr, calc_time);
+}
+
+
+void
+Array2dFile::labelAdd (int type, const char* const lstr, double calc_time=0.)
+{
+  Array2dFileLabel label (type, lstr, calc_time);
+
+  labelAdd (label);
+}
+
+
+void
+Array2dFile::labelAdd (const Array2dFileLabel& label)
+{
+    Array2dFileLabel* pLabel = new Array2dFileLabel(label);
+
+    m_labels.push_back (pLabel);
+}
+
+void
+Array2dFile::labelsCopy (Array2dFile& copyFile, const char* const idStr)
+{
+    string id = idStr;
+    for (int i = 0; i < copyFile.getNumLabels(); i++) {
+      Array2dFileLabel l = copyFile.labelGet (i);
+      string lstr = l.getLabelString();
+      lstr = idStr + lstr;
+      l.setLabelString (lstr);
+      labelAdd (l);
+    }
+}
+
+void 
+Array2dFile::arrayDataClear (void)
+{
+    if (m_arrayData) {
+       int columnSize = m_ny * m_pixelSize;
+       for (int ix = 0; ix < m_nx; ix++)
+           memset (m_arrayData[ix], 0, columnSize);
+    }
+}
+
+void
+Array2dFile::printLabels (ostream& os) const
+{
+    int nlabels = getNumLabels();
+
+    for (constLabelIterator l = m_labels.begin(); l != m_labels.end(); l++) {
+      const Array2dFileLabel& label = **l;
+
+      if (label.getLabelType() == Array2dFileLabel::L_HISTORY) {
+       os << "History: " << endl;
+       os << "  " << label.getLabelString() << endl;
+       os << "  calc time = " << label.getCalcTime() << " secs" << endl;
+       os << "  Timestamp = " << label.getDateString() << endl;
+      } else if (label.getLabelType() == Array2dFileLabel::L_USER) {
+       os << "Note: " <<  label.getLabelString() << endl;
+           os << "  Timestamp = %s" << label.getDateString() << endl;
+      }
+       os << endl;
+    }
+}
+
+
+const Array2dFileLabel&
+Array2dFile::labelGet (int i) const
+{
+  return *m_labels[i];
+}
index 7f1c6a0..a05eae7 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: imagefile.cpp,v 1.4 2000/06/25 17:32:24 kevin Exp $
+**  $Id: imagefile.cpp,v 1.5 2000/06/26 21:15:24 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
 #include "ct.h"
 
 
-///////////////////////////////////////////////////////////////////////////
-// CLASS IMPLEMENTATION
-//
-//     Name: Array2dFileLabel
-//     Purpose: Labels for Array2dFiles
-///////////////////////////////////////////////////////////////////////////
-
-void
-Array2dFileLabel::init (void)
-{
-    m_calcTime = 0;
-    m_labelType = L_EMPTY;
-    TIMEDATE td;
-    td_get_tmdt (&td);
-    m_year = td.d.year;
-    m_month = td.d.month;
-    m_day = td.d.date;
-    m_hour = td.t.hour;
-    m_minute = td.t.minute;
-    m_second = td.t.second;
-}
-
-Array2dFileLabel::Array2dFileLabel() 
-{
-    init();
-}
-
-Array2dFileLabel::Array2dFileLabel(const char* const str, double ctime = 0.)
-  : m_strLabel (str)
-{
-    init();
-
-    m_labelType = L_USER;
-    m_calcTime = ctime;
-}
-
-Array2dFileLabel::Array2dFileLabel(const int type, const char* const str, double ctime = 0.)
-  :  m_strLabel (str)
-{
-    init();
-
-    m_labelType = type;
-    m_calcTime = ctime;
-}
-
-Array2dFileLabel::~Array2dFileLabel()
-{
-}
-
-const string& 
-Array2dFileLabel::getDateString (void) const
-{
-  ostringstream oss;
-  oss <<  m_month <<"/"<< m_day <<"/"<< m_year << " " << m_hour <<":"<<  m_minute <<":"<< m_second;
-  m_strDate = oss.str();
-  return m_strDate;
-}
-
-
-/* FILE
- *   image.c                           Routines for managing images
- */
-
 
 void 
 ImageFile::filterResponse (const char* const domainName, double bw, const char* const filterName, double filt_param)
 {
-  int hx = (mNX - 1) / 2;
-  int hy = (mNY - 1) / 2;
+  int hx = (m_nx - 1) / 2;
+  int hy = (m_ny - 1) / 2;
   ImageFileArray v = getArray();
   SignalFilter filter (filterName, domainName, bw, filt_param);
 
@@ -112,9 +49,9 @@ ImageFile::filterResponse (const char* const domainName, double bw, const char*
 int
 ImageFile::display (void)
 {
-    ImageFileValue pmin, pmax;
+    double pmin, pmax;
 
-    getPixelValueRange (pmin, pmax);
+    //    getPixelValueRange (pmin, pmax);
 
     return (displayScaling (1, pmin, pmax));
 }
@@ -123,8 +60,8 @@ int
 ImageFile::displayScaling (const int scale, const ImageFileValue pmin, const ImageFileValue pmax)
 {
     int grayscale[256];
-    int nx = mNX;
-    int ny = mNY;
+    int nx = m_nx;
+    int ny = m_ny;
     ImageFileArray v = getArray();
 
 #if HAVE_G2_H
@@ -171,27 +108,27 @@ ImageFile::displayScaling (const int scale, const ImageFileValue pmin, const Ima
 bool
 ImageFile::comparativeStatistics (const ImageFile& imComp, double& d, double& r, double& e) const
 {
-    if (imComp.nx() != mNX && imComp.ny() != mNY) {
+    if (imComp.nx() != m_nx && imComp.ny() != m_ny) {
        sys_error (ERR_WARNING, "Image sizes differ [ImageFile::comparativeStatistics]");
        return false;
     }
-    ImageFileArray v = getArray();
+    const ImageFileArray const v = getArray();
     ImageFileArray vComp = imComp.getArray();
 
     double myMean = 0.;
-    for (int ix = 0; ix < mNX; ix++) {
-       for (int iy = 0; iy < mNY; iy++) {
+    for (int ix = 0; ix < m_nx; ix++) {
+       for (int iy = 0; iy < m_ny; iy++) {
            myMean += v[ix][iy];
        }
     }
-    myMean /= (mNX * mNY);
+    myMean /= (m_nx * m_ny);
 
     double sqErrorSum = 0.;
     double absErrorSum = 0.;
     double sqDiffFromMeanSum = 0.;
     double absValueSum = 0.;
-    for (int ix = 0; ix < mNX; ix++) {
-       for (int iy = 0; iy < mNY; iy++) {
+    for (int ix = 0; ix < m_nx; ix++) {
+       for (int iy = 0; iy < m_ny; iy++) {
            double diff = v[ix][iy] - vComp[ix][iy];
            sqErrorSum += diff * diff;
            absErrorSum += fabs(diff);
@@ -204,8 +141,8 @@ ImageFile::comparativeStatistics (const ImageFile& imComp, double& d, double& r,
     d = sqrt (sqErrorSum / sqDiffFromMeanSum);
     r = absErrorSum / absValueSum;
 
-    int hx = mNX / 2;
-    int hy = mNY / 2;
+    int hx = m_nx / 2;
+    int hy = m_ny / 2;
     double eMax = -1;
     for (int ix = 0; ix < hx; ix++) {
       for (int iy = 0; iy < hy; iy++) {
@@ -255,9 +192,9 @@ ImageFile::printStatistics (ostream& os) const
 void
 ImageFile::statistics (double& min, double& max, double& mean, double& mode, double& median, double& stddev) const
 {
-    int nx = mNX;
-    int ny = mNY;
-    ImageFileArray v = getArray();
+    int nx = m_nx;
+    int ny = m_ny;
+    const ImageFileArray v = getArray();
     
     mean = 0;
     min = v[0][0];
index 0082f1f..57a3fb3 100644 (file)
@@ -1,6 +1,6 @@
 noinst_LIBRARIES = libctsupport.a
 INCLUDES=@my_includes@
-libctsupport_a_SOURCES= filefuncs.cpp strfuncs.cpp syserror.cpp timedate.cpp fnetorderstream.cpp consoleio.cpp mathfuncs.cpp xform.cpp clip.cpp
+libctsupport_a_SOURCES= filefuncs.cpp strfuncs.cpp syserror.cpp fnetorderstream.cpp consoleio.cpp mathfuncs.cpp xform.cpp clip.cpp
 EXTRA_DIST=Makefile.nt
 
 
diff --git a/libctsupport/timedate.cpp b/libctsupport/timedate.cpp
deleted file mode 100644 (file)
index 458066f..0000000
+++ /dev/null
@@ -1,393 +0,0 @@
-/*****************************************************************************
-**  This is part of the CTSim program
-**  Copyright (C) 1983-2000 Kevin Rosenberg
-**
-**  $Id: timedate.cpp,v 1.2 2000/06/19 19:04:05 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
-**  published by the Free Software Foundation.
-**
-**  This program is distributed in the hope that it will be useful,
-**  but WITHOUT ANY WARRANTY; without even the implied warranty of
-**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-**  GNU General Public License for more details.
-**
-**  You should have received a copy of the GNU General Public License
-**  along with this program; if not, write to the Free Software
-**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-******************************************************************************/
-
-/*----------------------------------------------------------------------*/
-/*                     ROUTINES THAT MANAGE TIME                       */
-/*----------------------------------------------------------------------*/
-
-#include <stdio.h>
-#include <time.h>
-#include "ctsupport.h"
-
-
-/* NAME
- *    td_get_time                      Return time of day
- *
- * SYNOPSIS
- *    t = td_get_time (t)
- *    TIME *t;                         Returned time
- */
-
-TIME *
-td_get_time (TIME *t)
-{
-  time_t currtime;
-  struct tm *tm;
-
-  currtime = time(NULL);
-  tm = localtime(&currtime);
-
-  t->hour   = tm->tm_hour;
-  t->minute = tm->tm_min; 
-  t->second = tm->tm_sec; 
-  t->ms     = 0;       
-
-  return (t);
-}
-
-
-DATE *
-td_get_date (DATE *d)
-{
-  time_t t = time(NULL);
-  struct tm *lt = localtime(&t);
-
-  d->year = lt->tm_year + 1900;
-  d->month = lt->tm_mon;
-  d->month++;
-  d->date = lt->tm_mday;
-  d->dow = lt->tm_wday;
-  d->dow++;
-
-  return (d);
-}
-
-double td_current_sec (void)
-{
-       TIME t;
-
-       td_get_time (&t);
-       return (td_time_to_sec (&t));
-}
-
-
-double 
-td_time_to_sec (TIME *t)
-{
-       double ts;
-
-       ts = t->hour * 3600.;
-       ts += t->minute * 60.;
-       ts += t->second;
-       ts += t->ms / 1000.;
-
-       return (ts);
-}
-
-
-TIME *
-td_time_sub (const TIME *t1, const TIME *t2, TIME *tdiff)
-{
-       tdiff->hour   = t1->hour   - t2->hour;
-       tdiff->minute = t1->minute - t2->minute;
-       tdiff->second = t1->second - t2->second;
-       tdiff->ms     = t1->ms     - t2->ms;
-
-       return td_time_norm (tdiff);
-}
-
-
-TIME *
-td_time_add (const TIME *t1, const TIME *t2, TIME *tsum)
-{
-       tsum->ms       = t1->ms     + t2->ms;
-       tsum->second   = t1->second + t2->second;
-       tsum->minute   = t1->minute + t2->minute;
-       tsum->hour     = t1->hour   + t2->hour;
-
-       return td_time_norm (tsum);
-}
-
-
-TIME *
-td_time_copy (TIME *to, const TIME *from)
-{
-       to->ms       = from->ms;
-       to->second   = from->second;
-       to->minute   = from->minute;
-       to->hour     = from->hour;
-
-       return (to);
-}
-
-
-/* NAME
- *     td_time_norm                    Normalize time in structure
- *
- * SYNOPSIS
- *     t = td_time_norm (t)
- *     TIME *t                         Time to be normalized
- */
-
-TIME *
-td_time_norm (TIME *t)
-{
-       while (t->ms < 0) {
-           t->ms += 1000;
-           t->second--;
-       }
-       while (t->second < 0) {
-           t->second += 60;
-           t->minute--;
-       }
-       while (t->minute < 0) {
-           t->minute += 60;
-           t->hour--;
-       }
-
-       while (t->ms > 1000) {
-           t->ms -= 1000;
-           t->second++;
-       }
-       while (t->second > 60) {
-           t->second -= 60;
-           t->minute++;
-       }
-       while (t->minute > 60) {
-           t->minute -= 60;
-           t->hour++;
-       }
-
-       return (t);
-}
-
-
-/* NAME
- *    td_get_tmdt                      Return current time and date
- *
- * SYNOPSIS
- *    get_tmdt (td)
- *    TIMEDATE *td                     Pointer to structure that holds time & date
- */
-
-void 
-td_get_tmdt (TIMEDATE *td)
-{
-       td_get_date (&td->d);
-       td_get_time (&td->t);
-}
-
-
-/* NAME
- *     td_str_tmdt             Put time & date into string
- *
- * SYNOPSIS
- *     str = td_str_tmdt (td)
- *     TIMEDATE *td            Pointer ot time & date structure
- *     char *str               Pointer to output string (Width = 21 chars)
- *
- * NOTES
- *         str points to a area of memory devoted to this routine
- *     DO NOT make any changes to str
- */
-
-const char *
-td_str_tmdt (const TIMEDATE *td)
-{
-       static char str[80];
-
-       strncpy (str, td_str_date(&td->d), sizeof(str));
-       strncat (str, " ", sizeof(str));
-       strncat (str, td_str_stime(&td->t), sizeof(str));
-
-       return (str);
-}
-
-
-/* NAME
- *   td_str_time                       Convert time into long string form
- *
- * SYNOPSIS
- *   str = td_str_time (t)
- *   char *str                         Output string (Field width = 12 chars)
- *   TIME *t                           Time to be converted
- */
-const char *
-td_str_time (const TIME *t)
-{
-       static char str[80];
-       char am_pm;
-       int hour;
-
-       hour = t->hour;
-       if (hour < 12) {
-           am_pm = 'a';
-           if (hour == 0)
-               hour = 12;
-       } else if (hour >= 12) {
-           am_pm = 'p';
-           if (hour > 12)
-               hour -= 12;
-       }
-
-       snprintf (str, sizeof(str), "%2d:%02d:%02d.%03d%c",
-               hour, t->minute, t->second, t->ms, am_pm);
-
-       return (str);
-}
-
-
-
-/* NAME
- *   td_str_stime                      Convert time into short string form
- *
- * SYNOPSIS
- *   str = td_str_stime (t)
- *   char *str                         Output string (Field width = 6 chars)
- *   TIME *t                           Time to be converted
- */
-const char *
-td_str_stime (const TIME *t)
-{
-       static char str[80];
-       char am_pm;
-       int hour;
-
-       hour = t->hour;
-       if (hour < 12) {
-           am_pm = 'a';
-           if (hour == 0)
-               hour = 12;
-       } else if (hour >= 12) {
-           am_pm = 'p';
-           if (hour > 12)
-               hour -= 12;
-       }
-
-       snprintf (str, sizeof(str), "%2d:%02d%c",
-               hour, t->minute, am_pm);
-
-       return (str);
-}
-
-
-/* NAME
- *     td_str_date             Convert date to string form
- *
- * SYNOPSIS
- *     str = td_str_date (d)
- *     DATE *d                 Date to be converted
- *     char *str               Pointer to output string (Width = 8 chars)
- *
- * NOTES
- *     DO NOT make any changes to str.  It belongs to this routine
- */
-
-const char *
-td_str_date (const DATE *d)
-{
-       static char str[80];
-
-       snprintf (str, sizeof(str), "%2d-%02d-%02d", d->month, d->date, d->year - 1900);
-
-       return (str);
-}
-
-/*-----------------------------------------------------------------------------
- * NAME
- *   td_str_cdate                      Convert date to a character string
- *
- * SYNOPSIS
- *   str = td_str_cdate (d)
- *   DATE *d                           Date to convert
- *   char *str                         Pointer to date in character format
- *
- * DESCRIPTION
- *    The date is put in the form:
- *         <day name>, <month name> <date>, <year>
- *
- *    Field width ranges from 17 to 29 characters
- *
- * NOTES
- *    str belongs to this routine, do NOT alter str
- *---------------------------------------------------------------------------*/
-
-
-char *
-td_str_cdate (DATE *d)
-{
-       static char str[50];
-       char temp[50];
-
-       strcpy (str, "");
-
-       if (d->dow != 0) {                      /* only print day name if dow != 0 */
-           strcat (str, td_day_name(d->dow));
-           strcat (str, ", ");
-       }
-
-       snprintf (temp, sizeof(temp), "%s %d, %d", td_month_name(d->month), d->date, d->year);
-       strcat (str, temp);
-
-       return (str);
-}
-
-
-/*--------------------------------------------------------------*/
-/* td_month_name(int n)                                                */
-/*     return pointer to name of month given month number, n   */
-/*--------------------------------------------------------------*/
-char *
-td_month_name (        /* return name of n-th month */
-    int n
-)
-{
-       static char *name[] = {
-           "",
-           "January",
-           "February",
-           "March",
-           "April",
-           "May",
-           "June",
-           "July",
-           "August",
-           "September",
-           "October",
-           "November",
-           "December"
-       };
-
-       return ((n < 1 || n > 12) ? name[0] : name[n]);
-}
-
-
-/*--------------------------------------------------------------*/
-/* td_day_name(int n)                                          */
-/*     return pointer to name of day given day number, n (1..7)*/
-/*--------------------------------------------------------------*/
-char *
-td_day_name (int n)
-{
-       static char *name[] = {
-           "",
-           "Monday",
-           "Tuesday",
-           "Wednesday",
-           "Thursday",
-           "Friday",
-           "Saturday",
-           "Sunday"
-       };
-
-       return ((n < 1 || n > 7) ? name[0] : name[n]);
-}
index 383818f..5349601 100644 (file)
@@ -1,13 +1,13 @@
-bin_PROGRAMS = ctsim ctrec phm2pj pj2if @lamprograms@  ifinfo phm2if if-1 if-2 if2img 
-bin_SCRIPTS = sample-ctrec.sh
-EXTRA_PROGRAMS = ctrec-lam phm2pj-lam phm2if-lam
+bin_PROGRAMS = ctsim pjrec phm2pj pj2if @lamprograms@  ifinfo phm2if if-1 if-2 if2img 
+bin_SCRIPTS = sample-pjrec.sh
+EXTRA_PROGRAMS = pjrec-lam phm2pj-lam phm2if-lam
 INCLUDES=@my_includes@
 EXTRA_DIST=Makefile.nt mpiworld.cpp
 
 ctsim_SOURCES = ctsim.cpp
 ctsim_LDADD = @ctlibs@
-ctrec_SOURCES = ctrec.cpp 
-ctrec_LDADD=@ctlibs@
+pjrec_SOURCES = pjrec.cpp 
+pjrec_LDADD=@ctlibs@
 phm2pj_SOURCES=phm2pj.cpp
 phm2pj_LDADD=@ctlibs@
 phm2if_SOURCES = phm2if.cpp
@@ -23,8 +23,8 @@ if_2_LDADD=@ctlibs@
 ifinfo_SOURCES = ifinfo.cpp
 ifinfo_LDADD=@ctlibs@
 
-ctrec_lam_SOURCES=ctrec.cpp
-ctrec_lam_LDADD=@ctlamlibs@
+pjrec_lam_SOURCES=pjrec.cpp
+pjrec_lam_LDADD=@ctlamlibs@
 phm2if_lam_SOURCES=phm2if.cpp
 phm2if_lam_LDADD=@ctlamlibs@
 phm2pj_lam_SOURCES=phm2pj.cpp
@@ -37,8 +37,8 @@ if USE_LAM
 CC_LAM = $(lamdir)/bin/balky
 LAM_EXTRA_SRC = mpiworld.cpp
 
-ctrec-lam: ctrec.cpp mpiworld.cpp ../include/ct.h  ../libctsim/libctsim.a ../libctsupport/libctsupport.a
-       $(CC_LAM) @DEFS@ $(CFLAGS) $(INCLUDES) -DHAVE_MPI ctrec.cpp -o ctrec-lam $(LDFLAGS) $(LAM_EXTRA_SRC) @ctlibs@
+pjrec-lam: pjrec.cpp mpiworld.cpp ../include/ct.h  ../libctsim/libctsim.a ../libctsupport/libctsupport.a
+       $(CC_LAM) @DEFS@ $(CFLAGS) $(INCLUDES) -DHAVE_MPI pjrec.cpp -o pjrec-lam $(LDFLAGS) $(LAM_EXTRA_SRC) @ctlibs@
 
 phm2pj-lam: phm2pj.cpp mpiworld.cpp ../include/ct.h ../libctsim/libctsim.a ../libctsupport/libctsupport.a
        $(CC_LAM) @DEFS@ $(CFLAGS) $(INCLUDES) -DHAVE_MPI phm2pj.cpp -o phm2pj-lam $(LDFLAGS) $(LAM_EXTRA_SRC) @ctlibs@
@@ -48,8 +48,8 @@ phm2if-lam: phm2if.cpp mpiworld.cpp ../include/ct.h ../libctsim/libctsim.a ../li
 
 endif
 
-shared: ctrec.cpp phm2pj.cpp 
-       $(CC) @DEFS@ $(CFLAGS) $(INCLUDES) -DNO_MAIN -shared phm2pj.cpp ctrec.cpp @ctlibs@ $(LDFLAGS) -o ir.so
+shared: pjrec.cpp phm2pj.cpp 
+       $(CC) @DEFS@ $(CFLAGS) $(INCLUDES) -DNO_MAIN -shared phm2pj.cpp pjrec.cpp @ctlibs@ $(LDFLAGS) -o ir.so
 
 
 
diff --git a/src/ctrec.cpp b/src/ctrec.cpp
deleted file mode 100644 (file)
index dc945e3..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-/*****************************************************************************
-** FILE IDENTIFICATION
-**
-**   Name:          ctrec.cpp
-**   Purpose:       Reconstruct an image from projections
-**   Programmer:    Kevin Rosenberg
-**   Date Started:  Aug 1984
-**
-**  This is part of the CTSim program
-**  Copyright (C) 1983-2000 Kevin Rosenberg
-**
-**  $Id: ctrec.cpp,v 1.14 2000/06/25 17:32:24 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
-**  published by the Free Software Foundation.
-**
-**  This program is distributed in the hope that it will be useful,
-**  but WITHOUT ANY WARRANTY; without even the implied warranty of
-**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-**  GNU General Public License for more details.
-**
-**  You should have received a copy of the GNU General Public License
-**  along with this program; if not, write to the Free Software
-**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-******************************************************************************/
-
-#include "ct.h"
-#include "timer.h"
-
-
-enum {O_INTERP, O_FILTER, O_FILTER_PARAM, O_BACKPROJ, O_VERBOSE, O_TRACE, O_HELP, O_DEBUG, O_VERSION};
-
-static struct option my_options[] =
-{
-  {"interp", 1, 0, O_INTERP},
-  {"filter", 1, 0, O_FILTER},
-  {"filter-param", 1, 0, O_FILTER_PARAM},
-  {"backproj", 1, 0, O_BACKPROJ},
-  {"trace", 1, 0, O_TRACE},
-  {"debug", 0, 0, O_DEBUG},
-  {"verbose", 0, 0, O_VERBOSE},
-  {"help", 0, 0, O_HELP},
-  {"version", 0, 0, O_VERSION},
-  {0, 0, 0, 0}
-};
-
-
-void 
-ctrec_usage (const char *program)
-{
-  cout << "usage: " << fileBasename(program) << " raysum-file image-file nx-image ny-image [OPTIONS]" << endl;
-  cout << "Image reconstruction from raysum projections" << endl;
-  cout << endl;
-  cout << "   raysum-file     Input raysum file" << endl;
-  cout << "   image-file      Output image file in SDF2D format" << endl;
-  cout << "   nx-image        Number of columns in output image" << endl;
-  cout << "   ny-image        Number of rows in output image" << endl;
-  cout << "   --interp        Interpolation method during backprojection" << endl;
-  cout << "       nearest     Nearest neighbor interpolation" << endl;
-  cout << "       linear      Linear interpolation" << endl;
-#if HAVE_BSPLINE_INTERP
-  cout << "       bspline     B-spline interpolation" << endl;
-#endif
-  cout << "    --filter       Filter name" << endl;
-  cout << "       abs_bandlimit Abs * Bandlimiting (default)" << endl;
-  cout << "       abs_sinc      Abs * Sinc" << endl;
-  cout << "       abs_cos       Abs * Cosine" << endl;
-  cout << "       abs_hamming   Abs * Hamming" << endl;
-  cout << "       shepp         Shepp-Logan" << endl;
-  cout << "       bandlimit     Bandlimiting" << endl;
-  cout << "       sinc          Sinc" << endl;
-  cout << "       cos           Cosine" << endl;
-  cout << "       triangle      Triangle" << endl;
-  cout << "       hamming       Hamming" << endl;
-  cout << "    --backproj     Backprojection Method" << endl;
-  cout << "       trig        Trigometric functions at every point" << endl;
-  cout << "       table       Trigometric functions with precalculated table" << endl;
-  cout << "       diff        Difference method" << endl;
-  cout << "       diff2       Optimized difference method (default)" << endl;
-  cout << "       idiff2      Optimized difference method with integer math" << endl;
-  cout << "    --filter-param Alpha level for Hamming filter" << endl;
-  cout << "    --trace        Set tracing to level" << endl;
-  cout << "         none      No tracing (default)" << endl;
-  cout << "         text      Text level tracing" << endl;
-  cout << "         phm       Trace phantom" << endl;
-  cout << "         rays      Trace allrays" << endl;
-  cout << "         plot      Trace plotting" << endl;
-  cout << "         clipping  Trace clipping" << endl;
-  cout << "    --verbose      Turn on verbose mode" << endl;
-  cout << "    --debug        Turn on debug mode" << endl;
-  cout << "    --version      Print version" << endl;
-  cout << "    --help         Print this help message" << endl;
-}
-
-
-#ifdef HAVE_MPI
-static void ScatterProjectionsMPI (MPIWorld& mpiWorld, Projections& projGlobal, Projections& projLocal, const int debug);
-static void ReduceImageMPI (MPIWorld& mpiWorld, ImageFile* imLocal, ImageFile* imGlobal);
-#endif
-
-
-int 
-ctrec_main (int argc, char * argv[])
-{
-  Projections projGlobal;
-  ImageFile* imGlobal = NULL;
-  char* filenameProj = NULL;
-  char* filenameImage = NULL;
-  string remark;
-  char *endptr;
-  int optVerbose = 0;
-  int optDebug = 0;
-  int optTrace = TRACE_NONE;
-  double optFilterParam = -1;
-  string optFilterName = SignalFilter::FILTER_ABS_BANDLIMIT_STR;
-  string optInterpName = Backprojector::INTERP_LINEAR_STR;
-  string optBackprojName = Backprojector::BPROJ_IDIFF2_STR;
-  //  string optFilterMethodName = SignalFilter::FILTER_METHOD_CONVOLUTION_STR;
-  int optInterpParam = 1;
-  int nx, ny;
-#ifdef HAVE_MPI
-  ImageFile* imLocal;
-  int mpi_nview, mpi_ndet;
-  double mpi_detinc, mpi_rotinc, mpi_phmlen;
-  MPIWorld mpiWorld (argc, argv);
-#endif
-
-  Timer timerProgram;
-
-#ifdef HAVE_MPI
-  if (mpiWorld.getRank() == 0) {
-#endif
-    while (1) {
-      int c = getopt_long(argc, argv, "", my_options, NULL);
-      char *endptr = NULL;
-      
-      if (c == -1)
-       break;
-      
-      switch (c)
-       {
-       case O_INTERP:
-         optInterpName = optarg;
-         break;
-       case O_FILTER:
-         optFilterName = optarg;
-         break;
-       case O_BACKPROJ:
-         optBackprojName = optarg;
-         break;
-       case O_FILTER_PARAM:
-         optFilterParam = strtod(optarg, &endptr);
-         if (endptr != optarg + strlen(optarg)) {
-           ctrec_usage(argv[0]);
-         }
-         break;
-       case O_VERBOSE:
-         optVerbose = 1;
-         break;
-       case O_DEBUG:
-         optDebug = 1;
-         break;
-       case O_TRACE:
-         if ((optTrace = opt_set_trace(optarg)) < 0) {
-           ctrec_usage(argv[0]);
-           return (1);
-         }
-         break;
-        case O_VERSION:
-#ifdef VERSION
-         cout <<  "Version " <<  VERSION << endl;
-#else
-          cout << "Unknown version number" << endl;
-#endif
-         return (0);
-       case O_HELP:
-       case '?':
-         ctrec_usage(argv[0]);
-         return (0);
-       default:
-         ctrec_usage(argv[0]);
-         return (1);
-       }
-    }
-  
-    if (optind + 4 != argc) {
-      ctrec_usage(argv[0]);
-      return (1);
-    }
-
-    filenameProj = argv[optind];
-  
-    filenameImage = argv[optind + 1];
-  
-    nx = strtol(argv[optind + 2], &endptr, 10);
-    ny = strtol(argv[optind + 3], &endptr, 10);
-  
-    ostringstream filterDesc;
-    if (optFilterParam >= 0)
-      filterDesc << optFilterName << ": alpha=" << optFilterParam; 
-    else
-      filterDesc << optFilterName;
-
-    ostringstream label;
-    label << "Reconstruct: " << nx << "x" << ny << ", " << filterDesc.str() << ", " << optInterpName << ", " << optBackprojName;
-    remark = label.str();
-  
-    if (optVerbose)
-      cout << "Remark: " << remark << endl;
-#ifdef HAVE_MPI
-  }
-#endif
-
-#ifdef HAVE_MPI
-  if (mpiWorld.getRank() == 0) {
-    projGlobal.read (filenameProj);
-    if (optVerbose)
-      projGlobal.printScanInfo();
-
-    mpi_ndet = projGlobal.nDet();
-    mpi_nview = projGlobal.nView();
-    mpi_detinc = projGlobal.detInc();
-    mpi_phmlen = projGlobal.phmLen();
-    mpi_rotinc = projGlobal.rotInc();
-  }
-
-  TimerCollectiveMPI timerBcast (mpiWorld.getComm());
-  mpiWorld.BcastString (optBackprojName);
-  mpiWorld.BcastString (optFilterName);
-  mpiWorld.BcastString (optInterpName);
-  mpiWorld.getComm().Bcast (&optVerbose, 1, MPI::INT, 0);
-  mpiWorld.getComm().Bcast (&optDebug, 1, MPI::INT, 0);
-  mpiWorld.getComm().Bcast (&optTrace, 1, MPI::INT, 0);
-  mpiWorld.getComm().Bcast (&optFilterParam, 1, MPI::DOUBLE, 0);
-  mpiWorld.getComm().Bcast (&optInterpParam, 1, MPI::INT, 0);
-  mpiWorld.getComm().Bcast (&mpi_ndet, 1, MPI::INT, 0);
-  mpiWorld.getComm().Bcast (&mpi_nview, 1, MPI::INT, 0);
-  mpiWorld.getComm().Bcast (&mpi_detinc, 1, MPI::DOUBLE, 0);
-  mpiWorld.getComm().Bcast (&mpi_phmlen, 1, MPI::DOUBLE, 0);
-  mpiWorld.getComm().Bcast (&mpi_rotinc, 1, MPI::DOUBLE, 0);
-  mpiWorld.getComm().Bcast (&nx, 1, MPI::INT, 0);
-  mpiWorld.getComm().Bcast (&ny, 1, MPI::INT, 0);
-  if (optVerbose)
-      timerBcast.timerEndAndReport ("Time to broadcast variables");
-
-  mpiWorld.setTotalWorkUnits (mpi_nview);
-
-  Projections projLocal (mpiWorld.getMyLocalWorkUnits(), mpi_ndet);
-  projLocal.setDetInc (mpi_detinc);
-  projLocal.setPhmLen (mpi_phmlen);
-  projLocal.setRotInc (mpi_rotinc);
-
-  TimerCollectiveMPI timerScatter (mpiWorld.getComm());
-  ScatterProjectionsMPI (mpiWorld, projGlobal, projLocal, optDebug);
-  if (optVerbose)
-      timerScatter.timerEndAndReport ("Time to scatter projections");
-
-  if (mpiWorld.getRank() == 0) {
-    imGlobal = new ImageFile (filenameImage, nx, ny);
-    imGlobal->fileCreate();
-  }
-
-  imLocal = new ImageFile (nx, ny);
-#else
-  projGlobal.read (filenameProj);
-  if (optVerbose)
-    projGlobal.printScanInfo();
-
-  imGlobal = new ImageFile (filenameImage, nx, ny);
-  imGlobal->fileCreate();
-#endif
-
-#ifdef HAVE_MPI
-  TimerCollectiveMPI timerReconstruct (mpiWorld.getComm());
-  projLocal.reconstruct (*imLocal, optFilterName.c_str(), optFilterParam, optInterpName.c_str(), optInterpParam, optBackprojName.c_str(), optTrace);
-  if (optVerbose)
-      timerReconstruct.timerEndAndReport ("Time to reconstruct");
-
-  TimerCollectiveMPI timerReduce (mpiWorld.getComm());
-  ReduceImageMPI (mpiWorld, imLocal, imGlobal);
-  if (optVerbose)
-      timerReduce.timerEndAndReport ("Time to reduce image");
-#else
-  projGlobal.reconstruct (*imGlobal, optFilterName.c_str(), optFilterParam, optInterpName.c_str(), optInterpParam, optBackprojName.c_str(), optTrace);
-#endif
-
-#ifdef HAVE_MPI
-  if (mpiWorld.getRank() == 0)
-#endif
-    {
-      double calcTime = timerProgram.timerEnd();
-      imGlobal->arrayDataWrite ();
-      imGlobal->labelAdd (Array2dFileLabel::L_HISTORY, projGlobal.remark(), projGlobal.calcTime());
-      imGlobal->labelAdd (Array2dFileLabel::L_HISTORY, remark.c_str(), calcTime);
-      imGlobal->fileClose ();
-      if (optVerbose)
-       cout << "Run time: " << calcTime << " seconds" << endl;
-    }
-#ifdef HAVE_MPI
-  MPI::Finalize();
-#endif
-
-  return (0);
-}
-
-
-//////////////////////////////////////////////////////////////////////////////////////
-// MPI Support Routines
-//
-//////////////////////////////////////////////////////////////////////////////////////
-
-#ifdef HAVE_MPI
-static void ScatterProjectionsMPI (MPIWorld& mpiWorld, Projections& projGlobal, Projections& projLocal, const int optDebug)
-{
-  if (mpiWorld.getRank() == 0) {
-    for (int iProc = 0; iProc < mpiWorld.getNumProcessors(); iProc++) {
-      for (int iw = mpiWorld.getStartWorkUnit(iProc); iw <= mpiWorld.getEndWorkUnit(iProc); iw++) {
-       DetectorArray& detarray = projGlobal.getDetectorArray( iw );
-       int nDet = detarray.nDet();
-       DetectorValue* detval = detarray.detValues();
-
-       double viewAngle = detarray.viewAngle();
-       mpiWorld.getComm().Send(&nDet, 1, MPI::INT, iProc, 0);
-       mpiWorld.getComm().Send(&viewAngle, 1, MPI::DOUBLE, iProc, 0);
-       mpiWorld.getComm().Send(detval, nDet, MPI::FLOAT, iProc, 0);
-      }
-    }
-  }
-
-  for (int iw = 0; iw < mpiWorld.getMyLocalWorkUnits(); iw++) {
-    MPI::Status status;
-    int nDet;
-    double viewAngle;
-    DetectorValue* detval = projLocal.getDetectorArray(iw).detValues();
-
-    mpiWorld.getComm().Recv(&nDet, 1, MPI::INT, 0, 0, status);
-    mpiWorld.getComm().Recv(&viewAngle, 1, MPI::DOUBLE, 0, 0, status);
-    mpiWorld.getComm().Recv(detval, nDet, MPI::FLOAT, 0, 0, status);
-    projLocal.getDetectorArray(iw).setViewAngle( viewAngle );
-  }
-}
-
-static void
-ReduceImageMPI (MPIWorld& mpiWorld, ImageFile* imLocal, ImageFile* imGlobal)
-{
-  ImageFileArray vLocal = imLocal->getArray();
-
-  for (int ix = 0; ix < imLocal->nx(); ix++) {
-    void *recvbuf = NULL;
-    if (mpiWorld.getRank() == 0) {
-      ImageFileArray vGlobal = imGlobal->getArray();
-      recvbuf = vGlobal[ix];
-    }
-    mpiWorld.getComm().Reduce (vLocal[ix], recvbuf, imLocal->ny(), imLocal->getMPIDataType(), MPI::SUM, 0);
-  }
-}
-
-#endif
-
-
-#ifndef NO_MAIN
-int 
-main (int argc, char* argv[])
-{
-  int retval = 1;
-
-  try {
-    retval = ctrec_main(argc, argv);
-  } catch (exception e) {
-    cerr << "Exception: " << e.what() << endl;
-  } catch (...) {
-    cerr << "Unknown exception" << endl;
-  }
-
-  return (retval);
-}
-#endif
-
index 07359a0..b1d352b 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: if-1.cpp,v 1.8 2000/06/19 17:58:13 kevin Exp $
+**  $Id: if-1.cpp,v 1.9 2000/06/26 21:15:24 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
@@ -135,12 +135,11 @@ if1_main (int argc, char *const argv[])
   if (opt_invert || opt_log || opt_exp || opt_sqr || opt_sqrt) {
     int ix, iy;
 
-    im_in = new ImageFile (in_file);
-    im_in->fileRead ();
+    im_in = new ImageFile ();
+    im_in->fileRead (in_file);
     int nx = im_in->nx();
     int ny = im_in->ny();
-    im_out = new ImageFile (out_file, nx, ny);
-    im_out->fileCreate ();
+    im_out = new ImageFile (nx, ny);
 
     ImageFileArray vIn = im_in->getArray();
     ImageFileArray vOut = im_out->getArray();
@@ -176,10 +175,9 @@ if1_main (int argc, char *const argv[])
       histString = "Sqrt transformation";
     }
 
-    im_out->arrayDataWrite ();
     im_out->labelsCopy (*im_in);
     im_out->labelAdd (Array2dFileLabel::L_HISTORY, histString.c_str());
-    im_out->fileClose ();
+    im_out->fileWrite (out_file);
   }
 
   return (0);
index 951b431..cbf0e79 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: if-2.cpp,v 1.7 2000/06/25 17:32:24 kevin Exp $
+**  $Id: if-2.cpp,v 1.8 2000/06/26 21:15:24 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
@@ -126,12 +126,12 @@ if2_main (int argc, char *const argv[])
   in_file2 = argv[optind + 1];
   out_file = argv[optind + 2];
 
-  pim_in1 = new ImageFile (in_file1);
-  pim_in2 = new ImageFile (in_file2);
+  pim_in1 = new ImageFile ();
+  pim_in2 = new ImageFile ();
   ImageFile& im_in1 = *pim_in1;
   ImageFile& im_in2 = *pim_in2;
 
-  if (! im_in1.fileRead() || ! im_in2.fileRead()) {
+  if (! im_in1.fileRead(in_file1) || ! im_in2.fileRead(in_file2)) {
       sys_error (ERR_WARNING, "Error reading an image");
       return (1);
   }
@@ -146,12 +146,8 @@ if2_main (int argc, char *const argv[])
       return(1);
   }
 
-  pim_out = new ImageFile (out_file, im_in1.nx(), im_in1.ny());
+  pim_out = new ImageFile (im_in1.nx(), im_in1.ny());
   ImageFile& im_out = *pim_out;
-  if (! im_out.fileCreate()) {
-    sys_error (ERR_WARNING, "Could not open output file %s", out_file);
-    return (1);
-  }
 
   string strOperation;
   ImageFileArray v1 = im_in1.getArray();
@@ -202,12 +198,11 @@ if2_main (int argc, char *const argv[])
     cout << "d=" << d << ", r=" << r << ", e=" << e << endl;
   }
 
-  im_out.arrayDataWrite();
   im_out.labelsCopy (im_in1, "if-2 file 1: ");
   im_out.labelsCopy (im_in2, "if-2 file 2: ");
   im_out.labelAdd (Array2dFileLabel::L_HISTORY, strOperation.c_str());
 
-  im_out.fileClose();
+  im_out.fileWrite(out_file);
 
   return (0);
 }
index a230974..1aa8a39 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: if2img.cpp,v 1.8 2000/06/22 10:17:28 kevin Exp $
+**  $Id: if2img.cpp,v 1.9 2000/06/26 21:15:24 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
@@ -279,30 +279,15 @@ if2img_main (int argc, char *const argv[])
       out_file = argv[optind+1];
   else out_file = NULL;
 
-  pim = new ImageFile (in_file);
+  pim = new ImageFile ();
   ImageFile& im = *pim;
-  if (! im.fileRead()) {
+  if (! im.fileRead(in_file)) {
     sys_error (ERR_FATAL, "File %s does not exist", in_file);
     return (1);
   }
 
-  if (opt_labels) {
-    int nlabels = im.getNumLabels();
-
-    for (int i = 0; i < nlabels; i++) {
-      Array2dFileLabel label;
-      im.labelRead (label, i);
-
-      if (label.getLabelType() == Array2dFileLabel::L_HISTORY) {
-       cout << "History: " << label.getLabelString() << endl;
-       cout << "  calc time = " << label.getCalcTime() << " secs" << endl;
-       cout << "  Timestamp = " << label.getDateString() << endl;
-      } else if (label.getLabelType() == Array2dFileLabel::L_USER) {
-       cout << "Note: " <<  label.getLabelString() << endl;
-       cout << "  Timestamp = %s" << label.getDateString() << endl;
-      }
-    }
-  }
+  if (opt_labels)
+    im.printLabels(cout);
 
   if (opt_stats || (! (opt_set_max && opt_set_min))) {
     double minfound = HUGE_VAL, maxfound = -HUGE_VAL;
index f6c8da7..bf730ad 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: ifinfo.cpp,v 1.10 2000/06/25 17:32:24 kevin Exp $
+**  $Id: ifinfo.cpp,v 1.11 2000/06/26 21:15:24 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
@@ -129,14 +129,14 @@ ifinfo_main (int argc, char *const argv[])
   
   in_file = argv[optind];
 
-  im = new ImageFile (in_file.c_str());
-  if (! im->fileRead ()) {
+  im = new ImageFile ();
+  if (! im->fileRead (in_file.c_str())) {
     sys_error (ERR_WARNING, "Unable to read file %s", in_file.c_str());
     return (1);
   }
   if (in2_file != "") {
-    im2 = new ImageFile(in2_file.c_str());
-    if (! im2->fileRead ()) {
+    im2 = new ImageFile();
+    if (! im2->fileRead (in2_file.c_str())) {
       sys_error (ERR_WARNING, "Unable to read file %s", in2_file.c_str());
       return (1);
     }
index 91d0521..a6a7e26 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: phm2if.cpp,v 1.14 2000/06/25 17:32:24 kevin Exp $
+**  $Id: phm2if.cpp,v 1.15 2000/06/26 21:15:24 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
@@ -236,7 +236,7 @@ phm2if_main (int argc, char* argv[])
     }
     
     ostringstream oss;
-    oss << "nx=" << opt_nx << ", ny=" << opt_ny << ", nsample=" << opt_nsample << ", ";
+    oss << "phm2if: nx=" << opt_nx << ", ny=" << opt_ny << ", nsample=" << opt_nsample << ", ";
     if (opt_phmFileName != "")
       oss << "phantom=" << opt_phmFileName;
     else if (optPhmName != "")
@@ -296,13 +296,11 @@ phm2if_main (int argc, char* argv[])
       phm.createFromPhantom (optPhmName.c_str());
 
   if (mpiWorld.getRank() == 0) {
-    imGlobal = new ImageFile (opt_outfile, opt_nx, opt_ny);
-    imGlobal->fileCreate();
+    imGlobal = new ImageFile (opt_nx, opt_ny);
   }
   imLocal = new ImageFile (opt_nx, opt_ny);
 #else
-  imGlobal = new ImageFile (opt_outfile, opt_nx, opt_ny);
-  imGlobal->fileCreate ();
+  imGlobal = new ImageFile (opt_nx, opt_ny);
 #endif
 
   ImageFileArray v;
@@ -348,10 +346,9 @@ phm2if_main (int argc, char* argv[])
   if (mpiWorld.getRank() == 0) 
 #endif
   {
-    imGlobal->arrayDataWrite ();
     double calctime = timerProgram.timerEnd ();
     imGlobal->labelAdd (Array2dFileLabel::L_HISTORY, opt_desc.c_str(), calctime);
-    imGlobal->fileClose ();
+    imGlobal->fileWrite (opt_outfile);
     if (opt_verbose)
       cout << "Time to rasterized phantom: " << calctime << " seconds" << endl;
 
index 4ed549e..439fa83 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: phm2pj.cpp,v 1.4 2000/06/25 17:32:24 kevin Exp $
+**  $Id: phm2pj.cpp,v 1.5 2000/06/26 21:15:24 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
@@ -203,7 +203,7 @@ phm2pj_main (int argc, char* argv[])
     }
 
     ostringstream desc;
-    desc << "Raysum_Collect: NDet=" << opt_ndet << ", Nview=" << opt_nview << ", NRay=" << opt_nray << ", RotAngle=" << opt_rotangle << ", ";
+    desc << "phm2pj: NDet=" << opt_ndet << ", Nview=" << opt_nview << ", NRay=" << opt_nray << ", RotAngle=" << opt_rotangle << ", ";
     if (optPhmFileName.length()) {
       desc << "PhantomFile=" << optPhmFileName;
     } else if (optPhmName != "") {
index 26c5376..963a5cb 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: pj2if.cpp,v 1.3 2000/06/19 17:58:13 kevin Exp $
+**  $Id: pj2if.cpp,v 1.4 2000/06/26 21:15:24 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
@@ -112,7 +112,7 @@ pj2if_main (const int argc, char *const argv[])
   if (opt_verbose)
       pj.printScanInfo();
   
-  ImageFile im (im_name, pj.nDet(), pj.nView());
+  ImageFile im (pj.nDet(), pj.nView());
   
   ImageFileArray v = im.getArray();
 
@@ -126,11 +126,9 @@ pj2if_main (const int argc, char *const argv[])
        }
     }
 
-  im.fileCreate ();
-  im.arrayDataWrite ();
   im.labelAdd (Array2dFileLabel::L_HISTORY, pj.remark(), pj.calcTime());
   im.labelAdd (Array2dFileLabel::L_HISTORY, "Conversion from .pj to .if");
-  im.fileClose ();
+  im.fileWrite (im_name);
   
   return(0);
 }
diff --git a/src/pjrec.cpp b/src/pjrec.cpp
new file mode 100644 (file)
index 0000000..b5760a7
--- /dev/null
@@ -0,0 +1,376 @@
+/*****************************************************************************
+** FILE IDENTIFICATION
+**
+**   Name:          pjrec.cpp
+**   Purpose:       Reconstruct an image from projections
+**   Programmer:    Kevin Rosenberg
+**   Date Started:  Aug 1984
+**
+**  This is part of the CTSim program
+**  Copyright (C) 1983-2000 Kevin Rosenberg
+**
+**  $Id: pjrec.cpp,v 1.1 2000/06/26 21:15:24 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
+**  published by the Free Software Foundation.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+**
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+******************************************************************************/
+
+#include "ct.h"
+#include "timer.h"
+
+
+enum {O_INTERP, O_FILTER, O_FILTER_PARAM, O_BACKPROJ, O_VERBOSE, O_TRACE, O_HELP, O_DEBUG, O_VERSION};
+
+static struct option my_options[] =
+{
+  {"interp", 1, 0, O_INTERP},
+  {"filter", 1, 0, O_FILTER},
+  {"filter-param", 1, 0, O_FILTER_PARAM},
+  {"backproj", 1, 0, O_BACKPROJ},
+  {"trace", 1, 0, O_TRACE},
+  {"debug", 0, 0, O_DEBUG},
+  {"verbose", 0, 0, O_VERBOSE},
+  {"help", 0, 0, O_HELP},
+  {"version", 0, 0, O_VERSION},
+  {0, 0, 0, 0}
+};
+
+
+void 
+pjrec_usage (const char *program)
+{
+  cout << "usage: " << fileBasename(program) << " raysum-file image-file nx-image ny-image [OPTIONS]" << endl;
+  cout << "Image reconstruction from raysum projections" << endl;
+  cout << endl;
+  cout << "   raysum-file     Input raysum file" << endl;
+  cout << "   image-file      Output image file in SDF2D format" << endl;
+  cout << "   nx-image        Number of columns in output image" << endl;
+  cout << "   ny-image        Number of rows in output image" << endl;
+  cout << "   --interp        Interpolation method during backprojection" << endl;
+  cout << "       nearest     Nearest neighbor interpolation" << endl;
+  cout << "       linear      Linear interpolation" << endl;
+#if HAVE_BSPLINE_INTERP
+  cout << "       bspline     B-spline interpolation" << endl;
+#endif
+  cout << "    --filter       Filter name" << endl;
+  cout << "       abs_bandlimit Abs * Bandlimiting (default)" << endl;
+  cout << "       abs_sinc      Abs * Sinc" << endl;
+  cout << "       abs_cos       Abs * Cosine" << endl;
+  cout << "       abs_hamming   Abs * Hamming" << endl;
+  cout << "       shepp         Shepp-Logan" << endl;
+  cout << "       bandlimit     Bandlimiting" << endl;
+  cout << "       sinc          Sinc" << endl;
+  cout << "       cos           Cosine" << endl;
+  cout << "       triangle      Triangle" << endl;
+  cout << "       hamming       Hamming" << endl;
+  cout << "    --backproj     Backprojection Method" << endl;
+  cout << "       trig        Trigometric functions at every point" << endl;
+  cout << "       table       Trigometric functions with precalculated table" << endl;
+  cout << "       diff        Difference method" << endl;
+  cout << "       diff2       Optimized difference method (default)" << endl;
+  cout << "       idiff2      Optimized difference method with integer math" << endl;
+  cout << "    --filter-param Alpha level for Hamming filter" << endl;
+  cout << "    --trace        Set tracing to level" << endl;
+  cout << "         none      No tracing (default)" << endl;
+  cout << "         text      Text level tracing" << endl;
+  cout << "         phm       Trace phantom" << endl;
+  cout << "         rays      Trace allrays" << endl;
+  cout << "         plot      Trace plotting" << endl;
+  cout << "         clipping  Trace clipping" << endl;
+  cout << "    --verbose      Turn on verbose mode" << endl;
+  cout << "    --debug        Turn on debug mode" << endl;
+  cout << "    --version      Print version" << endl;
+  cout << "    --help         Print this help message" << endl;
+}
+
+
+#ifdef HAVE_MPI
+static void ScatterProjectionsMPI (MPIWorld& mpiWorld, Projections& projGlobal, Projections& projLocal, const int debug);
+static void ReduceImageMPI (MPIWorld& mpiWorld, ImageFile* imLocal, ImageFile* imGlobal);
+#endif
+
+
+int 
+pjrec_main (int argc, char * argv[])
+{
+  Projections projGlobal;
+  ImageFile* imGlobal = NULL;
+  char* filenameProj = NULL;
+  char* filenameImage = NULL;
+  string remark;
+  char *endptr;
+  int optVerbose = 0;
+  int optDebug = 0;
+  int optTrace = TRACE_NONE;
+  double optFilterParam = -1;
+  string optFilterName = SignalFilter::FILTER_ABS_BANDLIMIT_STR;
+  string optInterpName = Backprojector::INTERP_LINEAR_STR;
+  string optBackprojName = Backprojector::BPROJ_IDIFF2_STR;
+  //  string optFilterMethodName = SignalFilter::FILTER_METHOD_CONVOLUTION_STR;
+  int optInterpParam = 1;
+  int nx, ny;
+#ifdef HAVE_MPI
+  ImageFile* imLocal;
+  int mpi_nview, mpi_ndet;
+  double mpi_detinc, mpi_rotinc, mpi_phmlen;
+  MPIWorld mpiWorld (argc, argv);
+#endif
+
+  Timer timerProgram;
+
+#ifdef HAVE_MPI
+  if (mpiWorld.getRank() == 0) {
+#endif
+    while (1) {
+      int c = getopt_long(argc, argv, "", my_options, NULL);
+      char *endptr = NULL;
+      
+      if (c == -1)
+       break;
+      
+      switch (c)
+       {
+       case O_INTERP:
+         optInterpName = optarg;
+         break;
+       case O_FILTER:
+         optFilterName = optarg;
+         break;
+       case O_BACKPROJ:
+         optBackprojName = optarg;
+         break;
+       case O_FILTER_PARAM:
+         optFilterParam = strtod(optarg, &endptr);
+         if (endptr != optarg + strlen(optarg)) {
+           pjrec_usage(argv[0]);
+         }
+         break;
+       case O_VERBOSE:
+         optVerbose = 1;
+         break;
+       case O_DEBUG:
+         optDebug = 1;
+         break;
+       case O_TRACE:
+         if ((optTrace = opt_set_trace(optarg)) < 0) {
+           pjrec_usage(argv[0]);
+           return (1);
+         }
+         break;
+        case O_VERSION:
+#ifdef VERSION
+         cout <<  "Version " <<  VERSION << endl;
+#else
+          cout << "Unknown version number" << endl;
+#endif
+         return (0);
+       case O_HELP:
+       case '?':
+         pjrec_usage(argv[0]);
+         return (0);
+       default:
+         pjrec_usage(argv[0]);
+         return (1);
+       }
+    }
+  
+    if (optind + 4 != argc) {
+      pjrec_usage(argv[0]);
+      return (1);
+    }
+
+    filenameProj = argv[optind];
+  
+    filenameImage = argv[optind + 1];
+  
+    nx = strtol(argv[optind + 2], &endptr, 10);
+    ny = strtol(argv[optind + 3], &endptr, 10);
+  
+    ostringstream filterDesc;
+    if (optFilterParam >= 0)
+      filterDesc << optFilterName << ": alpha=" << optFilterParam; 
+    else
+      filterDesc << optFilterName;
+
+    ostringstream label;
+    label << "pjrec: " << nx << "x" << ny << ", " << filterDesc.str() << ", " << optInterpName << ", " << optBackprojName;
+    remark = label.str();
+  
+    if (optVerbose)
+      cout << "Remark: " << remark << endl;
+#ifdef HAVE_MPI
+  }
+#endif
+
+#ifdef HAVE_MPI
+  if (mpiWorld.getRank() == 0) {
+    projGlobal.read (filenameProj);
+    if (optVerbose)
+      projGlobal.printScanInfo();
+
+    mpi_ndet = projGlobal.nDet();
+    mpi_nview = projGlobal.nView();
+    mpi_detinc = projGlobal.detInc();
+    mpi_phmlen = projGlobal.phmLen();
+    mpi_rotinc = projGlobal.rotInc();
+  }
+
+  TimerCollectiveMPI timerBcast (mpiWorld.getComm());
+  mpiWorld.BcastString (optBackprojName);
+  mpiWorld.BcastString (optFilterName);
+  mpiWorld.BcastString (optInterpName);
+  mpiWorld.getComm().Bcast (&optVerbose, 1, MPI::INT, 0);
+  mpiWorld.getComm().Bcast (&optDebug, 1, MPI::INT, 0);
+  mpiWorld.getComm().Bcast (&optTrace, 1, MPI::INT, 0);
+  mpiWorld.getComm().Bcast (&optFilterParam, 1, MPI::DOUBLE, 0);
+  mpiWorld.getComm().Bcast (&optInterpParam, 1, MPI::INT, 0);
+  mpiWorld.getComm().Bcast (&mpi_ndet, 1, MPI::INT, 0);
+  mpiWorld.getComm().Bcast (&mpi_nview, 1, MPI::INT, 0);
+  mpiWorld.getComm().Bcast (&mpi_detinc, 1, MPI::DOUBLE, 0);
+  mpiWorld.getComm().Bcast (&mpi_phmlen, 1, MPI::DOUBLE, 0);
+  mpiWorld.getComm().Bcast (&mpi_rotinc, 1, MPI::DOUBLE, 0);
+  mpiWorld.getComm().Bcast (&nx, 1, MPI::INT, 0);
+  mpiWorld.getComm().Bcast (&ny, 1, MPI::INT, 0);
+  if (optVerbose)
+      timerBcast.timerEndAndReport ("Time to broadcast variables");
+
+  mpiWorld.setTotalWorkUnits (mpi_nview);
+
+  Projections projLocal (mpiWorld.getMyLocalWorkUnits(), mpi_ndet);
+  projLocal.setDetInc (mpi_detinc);
+  projLocal.setPhmLen (mpi_phmlen);
+  projLocal.setRotInc (mpi_rotinc);
+
+  TimerCollectiveMPI timerScatter (mpiWorld.getComm());
+  ScatterProjectionsMPI (mpiWorld, projGlobal, projLocal, optDebug);
+  if (optVerbose)
+      timerScatter.timerEndAndReport ("Time to scatter projections");
+
+  if (mpiWorld.getRank() == 0) {
+    imGlobal = new ImageFile (nx, ny);
+  }
+
+  imLocal = new ImageFile (nx, ny);
+#else
+  projGlobal.read (filenameProj);
+  if (optVerbose)
+    projGlobal.printScanInfo();
+
+  imGlobal = new ImageFile (nx, ny);
+#endif
+
+#ifdef HAVE_MPI
+  TimerCollectiveMPI timerReconstruct (mpiWorld.getComm());
+  projLocal.reconstruct (*imLocal, optFilterName.c_str(), optFilterParam, optInterpName.c_str(), optInterpParam, optBackprojName.c_str(), optTrace);
+  if (optVerbose)
+      timerReconstruct.timerEndAndReport ("Time to reconstruct");
+
+  TimerCollectiveMPI timerReduce (mpiWorld.getComm());
+  ReduceImageMPI (mpiWorld, imLocal, imGlobal);
+  if (optVerbose)
+      timerReduce.timerEndAndReport ("Time to reduce image");
+#else
+  projGlobal.reconstruct (*imGlobal, optFilterName.c_str(), optFilterParam, optInterpName.c_str(), optInterpParam, optBackprojName.c_str(), optTrace);
+#endif
+
+#ifdef HAVE_MPI
+  if (mpiWorld.getRank() == 0)
+#endif
+    {
+      double calcTime = timerProgram.timerEnd();
+      imGlobal->labelAdd (Array2dFileLabel::L_HISTORY, projGlobal.remark(), projGlobal.calcTime());
+      imGlobal->labelAdd (Array2dFileLabel::L_HISTORY, remark.c_str(), calcTime);
+      imGlobal->fileWrite (filenameImage);
+      if (optVerbose)
+       cout << "Run time: " << calcTime << " seconds" << endl;
+    }
+#ifdef HAVE_MPI
+  MPI::Finalize();
+#endif
+
+  return (0);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////
+// MPI Support Routines
+//
+//////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef HAVE_MPI
+static void ScatterProjectionsMPI (MPIWorld& mpiWorld, Projections& projGlobal, Projections& projLocal, const int optDebug)
+{
+  if (mpiWorld.getRank() == 0) {
+    for (int iProc = 0; iProc < mpiWorld.getNumProcessors(); iProc++) {
+      for (int iw = mpiWorld.getStartWorkUnit(iProc); iw <= mpiWorld.getEndWorkUnit(iProc); iw++) {
+       DetectorArray& detarray = projGlobal.getDetectorArray( iw );
+       int nDet = detarray.nDet();
+       DetectorValue* detval = detarray.detValues();
+
+       double viewAngle = detarray.viewAngle();
+       mpiWorld.getComm().Send(&nDet, 1, MPI::INT, iProc, 0);
+       mpiWorld.getComm().Send(&viewAngle, 1, MPI::DOUBLE, iProc, 0);
+       mpiWorld.getComm().Send(detval, nDet, MPI::FLOAT, iProc, 0);
+      }
+    }
+  }
+
+  for (int iw = 0; iw < mpiWorld.getMyLocalWorkUnits(); iw++) {
+    MPI::Status status;
+    int nDet;
+    double viewAngle;
+    DetectorValue* detval = projLocal.getDetectorArray(iw).detValues();
+
+    mpiWorld.getComm().Recv(&nDet, 1, MPI::INT, 0, 0, status);
+    mpiWorld.getComm().Recv(&viewAngle, 1, MPI::DOUBLE, 0, 0, status);
+    mpiWorld.getComm().Recv(detval, nDet, MPI::FLOAT, 0, 0, status);
+    projLocal.getDetectorArray(iw).setViewAngle( viewAngle );
+  }
+}
+
+static void
+ReduceImageMPI (MPIWorld& mpiWorld, ImageFile* imLocal, ImageFile* imGlobal)
+{
+  ImageFileArray vLocal = imLocal->getArray();
+
+  for (int ix = 0; ix < imLocal->nx(); ix++) {
+    void *recvbuf = NULL;
+    if (mpiWorld.getRank() == 0) {
+      ImageFileArray vGlobal = imGlobal->getArray();
+      recvbuf = vGlobal[ix];
+    }
+    mpiWorld.getComm().Reduce (vLocal[ix], recvbuf, imLocal->ny(), imLocal->getMPIDataType(), MPI::SUM, 0);
+  }
+}
+
+#endif
+
+
+#ifndef NO_MAIN
+int 
+main (int argc, char* argv[])
+{
+  int retval = 1;
+
+  try {
+    retval = pjrec_main(argc, argv);
+  } catch (exception e) {
+    cerr << "Exception: " << e.what() << endl;
+  } catch (...) {
+    cerr << "Unknown exception" << endl;
+  }
+
+  return (retval);
+}
+#endif
+
diff --git a/src/sample-ctrec.sh.in b/src/sample-ctrec.sh.in
deleted file mode 100755 (executable)
index 1a9f105..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-
-if test "$1" != "" ; then
-  bin=$1
-else
-  bin="@prefix@/bin/"
-fi
-
-if test "$1" = "clean" ; then
-  rm -f sample-phm.png sample-phm16.png sample-phm.if sample-pj.pj sample-pj.if sample-pj.png sample-pj16.png sample-rec.if sample-rec.png sample-rec16.png
-  exit
-fi
-
-# Generate phantom image
-
-${bin}phm2if sample-phm.if 256 256 --nsample 2 --phantom herman
-if [ -f sample-phm.if ] ; then
-  ${bin}if2img sample-phm.if sample-phm.png --format png
-  ${bin}if2img sample-phm.if sample-phm16.png --format png16
-fi
-
-# Simulate CT data collection and generate raysum sinugram for display
-${bin}phm2pj  sample-pj.pj 367 320 --nray 2  --phantom herman
-if [ -f sample-pj.pj ]; then
-  ${bin}pj2if  sample-pj.pj sample-pj.if
-fi
-if [ -f sample-pj.if ]; then
-  ${bin}if2img sample-pj.if sample-pj.png --format png
-  ${bin}if2img sample-pj.if sample-pj16.png --format png16
-fi
-
-# Reconstruct raysums and generate image for display
-${bin}ctrec   sample-pj.pj sample-rec.if 256 256 
-if [ -f sample-rec.if ]; then 
-  ${bin}if2img sample-rec.if sample-rec.png --format png
-  ${bin}if2img sample-rec.if sample-rec16.png --format png16
-fi
-
-# Files sample-phm.png, sample-pj.png, and sample-rec.png are ready for display
diff --git a/src/sample-ctsim.sh.in b/src/sample-ctsim.sh.in
new file mode 100755 (executable)
index 0000000..efc14e2
--- /dev/null
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+if test "$1" != "" ; then
+  bin=$1
+else
+  bin="@prefix@/bin/"
+fi
+
+if test "$1" = "clean" ; then
+  rm -f sample-phm.png sample-phm16.png sample-phm.if sample-pj.pj sample-pj.if sample-pj.png sample-pj16.png sample-rec.if sample-rec.png sample-rec16.png
+  exit
+fi
+
+# Generate phantom image
+
+${bin}phm2if sample-phm.if 256 256 --nsample 2 --phantom herman
+if [ -f sample-phm.if ] ; then
+  ${bin}if2img sample-phm.if sample-phm.png --format png
+  ${bin}if2img sample-phm.if sample-phm16.png --format png16
+fi
+
+# Simulate CT data collection and generate raysum sinugram for display
+${bin}phm2pj  sample-pj.pj 367 320 --nray 2  --phantom herman
+if [ -f sample-pj.pj ]; then
+  ${bin}pj2if  sample-pj.pj sample-pj.if
+fi
+if [ -f sample-pj.if ]; then
+  ${bin}if2img sample-pj.if sample-pj.png --format png
+  ${bin}if2img sample-pj.if sample-pj16.png --format png16
+fi
+
+# Reconstruct raysums and generate image for display
+${bin}pjrec   sample-pj.pj sample-rec.if 256 256 
+if [ -f sample-rec.if ]; then 
+  ${bin}if2img sample-rec.if sample-rec.png --format png
+  ${bin}if2img sample-rec.if sample-rec16.png --format png16
+
+  ${bin}ifinfo sample-phm.if sample-rec.if
+fi
+
+# Files sample-phm.png, sample-pj.png, and sample-rec.png are ready for display