Initial snark14m import
[snark14.git] / src / snark / snark.cpp
1 /*
2  ***********************************************************
3  $SNARK_Header: S N A R K  1 4 - A PICTURE RECONSTRUCTION PROGRAM $
4  $HeadURL: svn://dig.cs.gc.cuny.edu/snark/trunk/src/snark/snark.cpp $
5  $LastChangedRevision: 177 $
6  $Date: 2015-08-03 16:44:07 -0400 (Mon, 03 Aug 2015) $
7  $Author: zye $
8  ***********************************************************
9
10  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
11  *                                                               *
12  *                         S N A R K   9 3                       *
13  *                                                               *
14  *                A PICTURE RECONSTRUCTION PROGRAM               *
15  *                                                               *
16  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
17
18              WRITTEN- DECEMBER 1974
19              STUART W. ROWLAND
20              ROGER W. PERETTI
21              DEPT. OF COMPUTER SCIENCE
22              S.U.N.Y. AT BUFFALO
23              4226 RIDGE LEA ROAD
24              AMHERST, NEW YORK     14226
25              TEL. (716) 831-1351
26
27 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
28
29              REVISED BY-  G. T. HERMAN
30                           K.J. CHEN
31              SUMMER 1975
32
33 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
34
35    SNARK76 - PRELIMINARY VERSION - SPRING 1976
36 THIS VERSION OF SNARK INCORPORATES A NUMBER OF IMPROVEMENTS TO
37 THE SNARK75 PROGRAM.  THE MOST SIGNIFICANT OF WHICH ARE-
38    1) THE ABILITY TO GENERATE PROJECTION DATA SIMULATING A
39       POLYCHROMATIC X-RAY SOURCE.
40    2) THE INTRODUCTION OF AN OVERLAY STRUCTURE GREATLY REDUCING
41       THE MEMORY REQUIREMENTS OF SNARK.  ALSO, CREATR AND SKUNK
42       HAVE BEEN MODIFIED SO THAT THEY ARE CONSIDERABLY SMALLER.
43    3) COMMENTS AND MESSAGES HAVE BEEN MODIFIED SO THAT THEY ARE
44       MORE UNDERSTANDABLE.
45    4) NON-STANDARD SUBSCRIPTING HAS BEEN REMOVED.
46    5) ONLY THE RECONSTRUCTION FILE (RECFIL) NEED BE PRESENT DURING
47       POST-PROCESSING FOR MOST OPERATIONS.  THE EXCEPTION IS THE
48       DISTANCE COMMAND WHICH REQUIRES THE PROJECTION FILE (PRJFIL)
49       TO COMPUTE THE RESIDUAL.
50    6) THE ABILITY TO SPECIFY THE RANDOM NUMBER GENERATOR SEED HAS
51       BEEN ADDED TO CREATE.
52    7) A SIMPLE PHOTON SCATTERING MODEL HAS BEEN ADDED TO CREATE.
53 THESE CHANGES HAVE BEEN IMPLEMENTED BY-
54 S. W. ROWLAND AND G. T. HERMAN.
55
56 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
57
58    SNARK77 - AUTUMN 1977
59 THIS MODIFICATION OF SNARK76 PROVIDES A SIMPLER AND MORE POWERFUL
60 COMMAND LANGUAGE STRUCTURE.  THE MAJOR MODIFICATIONS ARE:
61    1) THE ADDITION OF THE ROUTINES GETINT AND GETNUM TO EXPAND THE
62       CAPABILITIES OF THE COMMAND LANGUAGE.  GETINT REPLACES THE
63       INTEGER OPTION WHICH WAS PART OF THE OLD GETWRD.  GETNUM
64       PROVIDES A FREE FORM FLOATING POINT INPUT FACILITY TO
65       SNARK77.
66    2) THE CREATE (AND THEREFORE PICTURE AND PROJECTION) INPUT
67       SEQUENCE HAS BEEN MODIFIED SO THAT IT IS MORE UNDERSTANDABLE
68       WITHOUT REFERENCING THE SNARK MANUAL.  ALL OF THE INFORMATIO
69       USED TO CREATE A PHANTOM OR PROJECTION DATA IS RETAINED IN
70       THE GENERATED DATA SET HEADERS SO THAT THIS INFORMATION WILL
71       NOT BE LOST TO FUTURE USERS OF THE DATA SET.
72    3) A NAME NOW MUST BE ASSIGNED TO EACH ALGORITHM EXECUTION.
73       THIS NAME IS PRINTED ON ALL POST-PROCESSING OUTPUT TO IDENTI
74       THE PARTICULAR RECONSTRUCTION BEING USED.  IT IS SUGGESTED
75       THAT THIS CARD INCLUDE AN INDICATION OF THE PARAMETERS USED
76       BY THE ALGORITHM.
77    4) ALMOST ALL OF THE SNARK CONTROL CARD FORMATS HAVE CHANGED.
78    5) A CAPABILITY TO GENERATE A PARALLEL PROJECTION DATA SET FROM
79       A DIVERGENT PROJECTION DATA SET VIA THE REBINNING FACILITY
80       OF RDPROJ HAS BEEN ADDED.
81    6) THE LINES COMMAND HAS BEEN EXTENDED TO GENERATE THE OUTPUT
82       ON A DIGITAL PLOTTER.
83
84    THE OVERLAY STATEMENTS FROM THE CDC3500 VERSION OF SNARK76 HAVE
85 BEEN REMOVED FOR THIS BURROUGHS B1700 VERSION.  SINCE THE SIZE OF
86 THE PROGRAM HAS INCREASED TREMENDOUSLY, OVERLAYING WILL HAVE TO BE
87 INSTALLED ON NON-PAGING COMPUTERS.  THE FOLLOWING TWO-LEVEL
88 STRUCTURE IS SUGGESTED:
89    (0,0)- THE MAIN PROGRAM AND COMMON SUBROUTINES.
90    (1,0)- THE CREATER SUBSYSTEM.
91    (2,0)- RDPICT AND RDPROJ.
92    (3,0)- EXALG.
93    (3,N)- EACH OF THE RECONSTRUCTION ALGORITHMS.
94    (4,0)- THE POST-PROCESSING ROUTINES.
95 EVEN WITH THIS STRUCTURE, IT MAY BE THAT SOME OF THE LARGER
96 ALGORITHMS (QUAD, FOR EXAMPLE) MAY NOT FIT IN YOUR LIMITED
97 MEMORY AND SHOULD THEREFORE BE DELETED FROM THE SYSTEM.
98
99 THESE CHANGES HAVE BEEN IMPLEMENTED BY-
100 S. W. ROWLAND AND THE MEDICAL IMAGE PROCESSING GROUP (MIPG).
101
102 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
103
104    SNARK89 Version 1.01 - July 1990
105 The calculation of totden and totlen in the STRIP case in rdproj.f
106 has been changed to agree with the manual.  Checks of nelem and
107 pixsiz have been inserted in rdpict.f.
108 These changes were made by G.T. Herman and D. Odhner.
109
110 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
111
112 SNARK05
113
114 The major advances that are incorporated into SNARK05 are:
115
116 1. SNARK05 is implemented in C++;
117 2. the file structures for holding projection data, phantoms and
118    reconstructions have been redesigned to include XML headers;
119 3. all itertive algorithms are now capable of handling image 
120    representations that use "blobs" as well as "pixels";
121 4. the efficient data access ordering is a standard feature;
122 5. all artificial restrictions on sizes have been removed - the only
123    remaining restrictions are those imposed by the hardware, compiler
124    and operating system.
125
126 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
127
128 MAIN PROGRAM FOR SNARK SYSTEM
129 THIS ROUTINE READS THE SNARK CONTROL CARDS, INTERPRETS THE MAJOR
130 COMMAND ON THE CARD, AND INVOKES THAT ROUTINE.
131
132 */      
133
134 #include <cstdio>
135 #include <string>
136 #include <sys/types.h>
137 #include <sys/stat.h>
138 #include <fcntl.h>
139 #include <unistd.h>
140
141 #include "blkdta.h"
142 #include "uiod.h"
143
144 #include "basis.h"   
145 #include "second.h"
146 #include "mode.h"
147 #include "settra.h"
148 #include "creatr.h"
149 #include "rdpict.h"
150 #include "rdproj.h"
151 #include "select.h"
152 #include "stopex.h"
153 #include "exalg.h"
154 #include "eval.h"
155 #include "disply.h"
156 #include "pnch.h"
157 #include "doline.h"
158 #include "halft.h"
159 #include "settra.h"
160 #include "infile.h" 
161 #include "recfile.h"
162 #include "file11.h"
163 #include "int2str.h"
164 #include "objects.h"
165 #include "superior.h"
166
167 /*
168   "JUST THE PLACE FOR A SNARK!' THE BELLMAN CRIED,
169        AS HE LANDED HIS CREW WITH CARE;
170   SUPPORTING EACH MAN ON THE TOP OF THE TIDE
171        BY A FINGER ENTWINED IN HIS HAIR.
172   "JUST THE PLACE FOR A SNARK!  I HAVE SAID IT TWICE:
173        THAT ALONE SHOULD ENCOURAGE THE CREW.
174   JUST THE PLACE FOR A SNARK!  I HAVE SAID IT THRICE:
175        WHAT I TELL YOU THREE TIMES IS TRUE."
176   FIT THE FIRST - THE LANDING
177   THE HUNTING OF THE SNARK (AN AGONY IN EIGHT FITS)
178   BY LEWIS CARROLL
179 */
180
181 #define NUMBER_OF_COMMANDS 16
182
183 enum SnarkCommands
184 {
185   SNARK_COMMAND_MODE,
186   SNARK_COMMAND_TRACE,
187   SNARK_COMMAND_END,
188   SNARK_COMMAND_CREATE,
189   SNARK_COMMAND_PICTURE,
190   SNARK_COMMAND_PROJECTION,
191   SNARK_COMMAND_BASSIS,
192   SNARK_COMMAND_SELECT,
193   SNARK_COMMAND_STOP,
194   SNARK_COMMAND_EXECUTE,
195   SNARK_COMMAND_EVALUATE,
196   SNARK_COMMAND_DISPLAY,
197   SNARK_COMMAND_PUNCH,
198   SNARK_COMMAND_LINES,
199   SNARK_COMMAND_SKUNK,
200   SNARK_COMMAND_SUPERIORIZE
201 };
202
203 static const INTEGER main_codes[NUMBER_OF_COMMANDS] = 
204 {
205   CHAR2INT('m','o','d','e'),
206   CHAR2INT('t','r','a','c'),
207   CHAR2INT('e','n','d',' '),
208   CHAR2INT('c','r','e','a'),
209   CHAR2INT('p','i','c','t'),
210   CHAR2INT('p','r','o','j'),
211   CHAR2INT('b','a','s','i'),  
212   CHAR2INT('s','e','l','e'),
213   CHAR2INT('s','t','o','p'),
214   CHAR2INT('e','x','e','c'),
215   CHAR2INT('e','v','a','l'),
216   CHAR2INT('d','i','s','p'),
217   CHAR2INT('p','u','n','c'),
218   CHAR2INT('l','i','n','e'),
219   CHAR2INT('s','k','u','n'),
220   CHAR2INT('s','u','p','e')
221 };
222
223 int FindKeywordCode(int word)
224 {
225   for(int i = 0; i < NUMBER_OF_COMMANDS; i++) {       // find keyword code
226     if(word == main_codes[i]) {
227       return i;
228     }
229   }
230   return -1;
231 }
232
233 INTEGER GetCommandPhase(INTEGER code)
234 {
235   static const INTEGER Phase[NUMBER_OF_COMMANDS] =
236   {
237 //    0, // *     Comment
238     0, // mode  Mode
239     0, // trac  Trace 
240     0, // end   End
241     1, // crea  Create
242     2, // pict  Picture
243     2, // proj  Projection
244     3, // basi  Basis
245     3, // sele  Select
246     3, // stop  Stop
247     3, // exec  Execue
248     4, // eval  Evaluate
249     4, // disp  Display
250     4, // punc  Punch
251     4, // line  Lines
252     4, // skun  Skunk
253     3  // supe  Superiorize
254   };
255
256   if(code >= NUMBER_OF_COMMANDS) {
257     return 4;
258   }
259
260   return Phase[code];
261 }
262
263
264 int snark(int argc, char *argv[])
265 {
266   ///static const INTEGER syst = CHAR2INT('a','y','s','t');
267   //static const INTEGER snar = CHAR2INT('s','n','a','r');
268   //static const INTEGER rand_1 = CHAR2INT('r','a','n','d');
269
270   INTEGER word;
271   BOOLEAN eol;
272   //BOOLEAN flag;
273   INTEGER lphase;  // last phase
274   INTEGER phase;   // current phase
275   BOOLEAN iptflg;   // picture command called
276   BOOLEAN iprflg;   // projection command called
277   
278   BOOLEAN islflg;   // select command called, by wei 1/05 
279
280   REAL begin;
281   REAL curr_time;
282   REAL dur;
283   int CommandCode;
284
285   // bug 179 - swr - 10/30/05
286 #ifndef __CYGWIN__
287   // bug 167 - swr - 9/24/05
288   int lfp=open("snark.lock",O_RDWR|O_CREAT,0640);
289   if (lfp<0) {
290     fprintf(stderr, "can't create lock file in current directory - check directory permissions\n");
291     exit(1); /* can not open */
292   }
293   if (lockf(lfp,F_TLOCK,0)<0) {
294     fprintf(stderr, "multiple snark executions in the same directory are not allowed!\n");
295     exit(0); /* can not lock */
296   }
297   /* only first instance continues */
298   char str[10];
299   sprintf(str,"%d\n",getpid());
300   write(lfp,str,strlen(str)); /* record pid to lockfile */
301 #endif
302
303   // bug 187 - allow input filename on command line - swr - 11/11/05
304   if (argc > 1) {
305     close(fileno(stdin));
306     if (open(argv[1], O_RDONLY) < 0) {
307       perror(argv[1]);
308       exit(1);
309     }
310   }
311
312   InFile.Open();
313
314   iptflg = FALSE;
315   iprflg = FALSE;
316   islflg = FALSE;     //initialization islflg, by wei 1/05
317  
318   std::string progName = argv[0];    // bug89 - fix header - swr - 2/25/05
319   
320   progName = progName.substr(progName.find_last_of('/')+1);
321
322   fprintf(output, "   %s.s170710 - A PICTURE RECONSTRUCTION PROGRAM\n", progName.c_str());
323
324   lphase = 0;
325
326   second(&begin);
327
328   for(;;) {      
329
330     InFile.getnxt(TRUE);        // get next line of input  // changed "FALSE" to "TRUE. Lajos, Jan 25, 2005
331
332     word = InFile.getwrd(FALSE, &eol, main_codes, NUMBER_OF_COMMANDS);   // check for the keyword
333
334     // added echoing. Lajos, Jan 25, 2005
335     if(eol == TRUE) {
336       InFile.echoline(TRUE);
337       continue;   // got to next line if end of line
338     } else InFile.echoline(FALSE);
339  
340     // find keyword code
341     if((CommandCode = FindKeywordCode(word)) < 0) {
342       // VALID COMMAND NOT FOUND
343       
344       fprintf(output, " **** command ignored");   // invalid command
345       continue;                          // goto next line 
346
347     }
348
349     // VALID COMMAND FOUND
350
351     phase = GetCommandPhase(CommandCode);
352
353     if(phase != 0) {                // check phase
354       if(phase < lphase) {
355
356         // INCORRECT CONTROL CARD SEQUENCE      
357         fprintf(output, "\n **** command sequence error");
358         fprintf(output, "\n **** program aborted\n");
359         return -1;
360       }
361
362       // if end of execs close recfile
363       // if changing phase to 4 or end encoutnered before phase 4
364       if((lphase < 4) && (phase == 4)) {
365         RecFile.Close();
366       }
367
368       lphase = phase;
369     }
370     else {
371       if((CommandCode == SNARK_COMMAND_END) && (lphase < 4)) {
372         RecFile.Close();
373       }
374     }
375       
376     // INSERT OVERLAY CALL BASED ON LPHASE HERE
377     // PASS I-LPHASE*5 TO THE OVERLAY TO CALL THE RIGHT FUNCTION
378     // DELETE THE COMPUTED GO TO AND ITS ASSOCIATED CALLS
379
380     switch(CommandCode) {
381
382 //    case SNARK_COMMAND_COMENT: // comment
383 //      break;
384
385     case SNARK_COMMAND_MODE: // ESTABLISH CONSTRAINT MODE
386       mode();
387       break;
388       
389     case SNARK_COMMAND_TRACE: // CHANGE THE TRACE SWITCH
390       settra();
391       break;
392       
393     case SNARK_COMMAND_END:
394       ///fprintf(output, "\n         %10i storage units needed", maxsp);
395       //fprintf(output, "\n         %10i storage units needed\n", 0);   // Obsolete
396
397       // free the dinamically allocated global array objects
398       if(MAX_NUMBER_OF_OBJECTS>0) delete[] objects;
399       
400       fprintf(output, "\n");
401       return 0;
402
403     case SNARK_COMMAND_CREATE: // CREATE TEST PATTERN AND/OR PROJECTION DATA
404       if(File11.Open(TRUE) != 0) {
405         fprintf(output, "\n **** unable to open file11 for wrting");
406         fprintf(output, "\n **** program aborted\n");
407               return -1;
408       }
409       creatr();
410       File11.Close();
411       break;
412
413     case SNARK_COMMAND_PICTURE: // SET PICT CALLED FLAG
414       File11.isOpen = FALSE;
415       rdpict(); //  READ TEST PATTERN
416       iptflg = TRUE;
417       break;
418
419     case SNARK_COMMAND_PROJECTION: // BE SURE THAT PICTURE CMD HAS BEEN ENCOUNTERED
420       // IF NOT  ERROR MSG  AND STOP
421       if(iptflg) {
422         rdproj(); // READ PROJECTION DATA
423           
424         if (File11.isOpen) File11.Close();
425         iprflg = TRUE;
426       }
427       else {            
428         ///write (output,1060)
429         fprintf(output, "\n **** command picture is required before projection");
430         fprintf(output, "\n **** program aborted\n");
431         return -1;
432       }
433       break;
434
435     case SNARK_COMMAND_BASSIS: // ESTABLISH THE BASIS 
436       basis();   
437       break;
438
439     case SNARK_COMMAND_SELECT: // RAY SELECTION CONDITIONS FOR PICK
440       select(FALSE);
441        islflg = TRUE;                             //user specified select, by wei 1/05
442       break;
443       
444     case SNARK_COMMAND_STOP: // ESTABLISH ALGORITHM TERMINATING CONDITIONS
445       stopex();
446       break;
447       
448     case SNARK_COMMAND_EXECUTE: // EXECUTE THE RECONSTRUCTION ALGORITHM
449       if(iprflg) {
450         if(!islflg) select(TRUE);        
451         islflg = TRUE;          //no select command, select default efficient , by wei 1/05 
452         exalg();
453       }
454       else {
455         fprintf(output, "\n **** command projection is required before execute");
456         fprintf(output, "\n **** program aborted\n");
457         return -1;
458       }
459       break;
460       
461     case SNARK_COMMAND_EVALUATE: // EVALUATION OF THE RECONSTRUCTIONS
462       Eval.eval_1();
463       break;
464       
465     case SNARK_COMMAND_DISPLAY: // DIGITAL DISPLAY OF THE RECONSTRUCTIONS
466       disply();
467       break;
468       
469     case SNARK_COMMAND_PUNCH: // PUNCH THE RECONSTRUCTIONS
470       pnch();
471       break;
472       
473     case SNARK_COMMAND_LINES: // LINES DISPLAY OF THE DIFFERENCE
474       doline();
475       break;
476       
477     case SNARK_COMMAND_SKUNK: // PSEUDO HALF TONE DISPLSY OF THE RECONSTRUCTIONS
478       halft();
479       break;
480
481     case SNARK_COMMAND_SUPERIORIZE: // ESTABLISH SUPERIORIZATION OPTIONS
482       initSuperiorization();
483       break;
484     }
485       
486     second(&curr_time);
487     dur = curr_time - begin;
488     begin = curr_time;
489     fprintf(output, "\n         %10.3f seconds used for processing command %s\n", dur, int2str(word)); // changed precision to three digits - swr 1/21/06
490   };
491
492   fprintf(output, "\n");
493   return 0;
494 }
495