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) $
8 ***********************************************************
10 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
14 * A PICTURE RECONSTRUCTION PROGRAM *
16 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
18 WRITTEN- DECEMBER 1974
21 DEPT. OF COMPUTER SCIENCE
24 AMHERST, NEW YORK 14226
27 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
29 REVISED BY- G. T. HERMAN
33 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
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
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
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.
56 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
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
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
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
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.
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.
99 THESE CHANGES HAVE BEEN IMPLEMENTED BY-
100 S. W. ROWLAND AND THE MEDICAL IMAGE PROCESSING GROUP (MIPG).
102 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
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.
110 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
114 The major advances that are incorporated into SNARK05 are:
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.
126 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
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.
136 #include <sys/types.h>
137 #include <sys/stat.h>
165 #include "superior.h"
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)
181 #define NUMBER_OF_COMMANDS 16
188 SNARK_COMMAND_CREATE,
189 SNARK_COMMAND_PICTURE,
190 SNARK_COMMAND_PROJECTION,
191 SNARK_COMMAND_BASSIS,
192 SNARK_COMMAND_SELECT,
194 SNARK_COMMAND_EXECUTE,
195 SNARK_COMMAND_EVALUATE,
196 SNARK_COMMAND_DISPLAY,
200 SNARK_COMMAND_SUPERIORIZE
203 static const INTEGER main_codes[NUMBER_OF_COMMANDS] =
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')
223 static const char* kLockFilename = "snark.lock";
224 static int gLockFd = -1;
226 int FindKeywordCode(int word)
228 for(int i = 0; i < NUMBER_OF_COMMANDS; i++) { // find keyword code
229 if(word == main_codes[i]) {
236 INTEGER GetCommandPhase(INTEGER code)
238 static const INTEGER Phase[NUMBER_OF_COMMANDS] =
246 2, // proj Projection
256 3 // supe Superiorize
259 if(code >= NUMBER_OF_COMMANDS) {
266 void atExitCleanup(void) {
270 if (unlink(kLockFilename) != 0) {
271 fprintf(stderr, "Error unlinking lock file\n");
277 int snark(int argc, char *argv[])
279 ///static const INTEGER syst = CHAR2INT('a','y','s','t');
280 //static const INTEGER snar = CHAR2INT('s','n','a','r');
281 //static const INTEGER rand_1 = CHAR2INT('r','a','n','d');
286 INTEGER lphase; // last phase
287 INTEGER phase; // current phase
288 BOOLEAN iptflg; // picture command called
289 BOOLEAN iprflg; // projection command called
291 BOOLEAN islflg; // select command called, by wei 1/05
298 // bug 179 - swr - 10/30/05
300 // bug 167 - swr - 9/24/05
301 gLockFd = open(kLockFilename,O_RDWR|O_CREAT,0640);
303 fprintf(stderr, "can't create lock file in current directory - check directory permissions\n");
304 exit(1); /* can not open */
306 if (lockf(gLockFd,F_TLOCK,0)<0) {
307 fprintf(stderr, "multiple snark executions in the same directory are not allowed!\n");
308 exit(0); /* can not lock */
310 /* only first instance continues */
312 sprintf(str,"%d\n",getpid());
313 write(gLockFd,str,strlen(str)); /* record pid to lockfile */
315 atexit(atExitCleanup);
319 // bug 187 - allow input filename on command line - swr - 11/11/05
321 close(fileno(stdin));
322 if (open(argv[1], O_RDONLY) < 0) {
332 islflg = FALSE; //initialization islflg, by wei 1/05
334 std::string progName = argv[0]; // bug89 - fix header - swr - 2/25/05
336 progName = progName.substr(progName.find_last_of('/')+1);
338 fprintf(output, " %s.s170710 - A PICTURE RECONSTRUCTION PROGRAM\n", progName.c_str());
346 InFile.getnxt(TRUE); // get next line of input // changed "FALSE" to "TRUE. Lajos, Jan 25, 2005
348 word = InFile.getwrd(FALSE, &eol, main_codes, NUMBER_OF_COMMANDS); // check for the keyword
350 // added echoing. Lajos, Jan 25, 2005
352 InFile.echoline(TRUE);
353 continue; // got to next line if end of line
354 } else InFile.echoline(FALSE);
357 if((CommandCode = FindKeywordCode(word)) < 0) {
358 // VALID COMMAND NOT FOUND
360 fprintf(output, " **** command ignored"); // invalid command
361 continue; // goto next line
365 // VALID COMMAND FOUND
367 phase = GetCommandPhase(CommandCode);
369 if(phase != 0) { // check phase
372 // INCORRECT CONTROL CARD SEQUENCE
373 fprintf(output, "\n **** command sequence error");
374 fprintf(output, "\n **** program aborted\n");
378 // if end of execs close recfile
379 // if changing phase to 4 or end encoutnered before phase 4
380 if((lphase < 4) && (phase == 4)) {
387 if((CommandCode == SNARK_COMMAND_END) && (lphase < 4)) {
392 // INSERT OVERLAY CALL BASED ON LPHASE HERE
393 // PASS I-LPHASE*5 TO THE OVERLAY TO CALL THE RIGHT FUNCTION
394 // DELETE THE COMPUTED GO TO AND ITS ASSOCIATED CALLS
396 switch(CommandCode) {
398 // case SNARK_COMMAND_COMENT: // comment
401 case SNARK_COMMAND_MODE: // ESTABLISH CONSTRAINT MODE
405 case SNARK_COMMAND_TRACE: // CHANGE THE TRACE SWITCH
409 case SNARK_COMMAND_END:
410 ///fprintf(output, "\n %10i storage units needed", maxsp);
411 //fprintf(output, "\n %10i storage units needed\n", 0); // Obsolete
413 // free the dinamically allocated global array objects
414 if(MAX_NUMBER_OF_OBJECTS>0) delete[] objects;
416 fprintf(output, "\n");
419 case SNARK_COMMAND_CREATE: // CREATE TEST PATTERN AND/OR PROJECTION DATA
420 if(File11.Open(TRUE) != 0) {
421 fprintf(output, "\n **** unable to open file11 for wrting");
422 fprintf(output, "\n **** program aborted\n");
429 case SNARK_COMMAND_PICTURE: // SET PICT CALLED FLAG
430 File11.isOpen = FALSE;
431 rdpict(); // READ TEST PATTERN
435 case SNARK_COMMAND_PROJECTION: // BE SURE THAT PICTURE CMD HAS BEEN ENCOUNTERED
436 // IF NOT ERROR MSG AND STOP
438 rdproj(); // READ PROJECTION DATA
440 if (File11.isOpen) File11.Close();
444 ///write (output,1060)
445 fprintf(output, "\n **** command picture is required before projection");
446 fprintf(output, "\n **** program aborted\n");
451 case SNARK_COMMAND_BASSIS: // ESTABLISH THE BASIS
455 case SNARK_COMMAND_SELECT: // RAY SELECTION CONDITIONS FOR PICK
457 islflg = TRUE; //user specified select, by wei 1/05
460 case SNARK_COMMAND_STOP: // ESTABLISH ALGORITHM TERMINATING CONDITIONS
464 case SNARK_COMMAND_EXECUTE: // EXECUTE THE RECONSTRUCTION ALGORITHM
466 if(!islflg) select(TRUE);
467 islflg = TRUE; //no select command, select default efficient , by wei 1/05
471 fprintf(output, "\n **** command projection is required before execute");
472 fprintf(output, "\n **** program aborted\n");
477 case SNARK_COMMAND_EVALUATE: // EVALUATION OF THE RECONSTRUCTIONS
481 case SNARK_COMMAND_DISPLAY: // DIGITAL DISPLAY OF THE RECONSTRUCTIONS
485 case SNARK_COMMAND_PUNCH: // PUNCH THE RECONSTRUCTIONS
489 case SNARK_COMMAND_LINES: // LINES DISPLAY OF THE DIFFERENCE
493 case SNARK_COMMAND_SKUNK: // PSEUDO HALF TONE DISPLSY OF THE RECONSTRUCTIONS
497 case SNARK_COMMAND_SUPERIORIZE: // ESTABLISH SUPERIORIZATION OPTIONS
498 initSuperiorization();
503 dur = curr_time - begin;
505 fprintf(output, "\n %10.3f seconds used for processing command %s\n", dur, int2str(word)); // changed precision to three digits - swr 1/21/06
508 fprintf(output, "\n");