Initial snark14m import
[snark14.git] / src / snark / eval.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/eval.cpp $
5  $LastChangedRevision: 179 $
6  $Date: 2015-08-03 20:13:24 -0400 (Mon, 03 Aug 2015) $
7  $Author: zye $
8  ***********************************************************
9
10  EVAL IS THE POST-PROCESSING ROUTINE WHICH DRIVES THE TWO
11  RECONSTRUCTION EVALUATION PROCEDURES, DIST AND POINT.
12  THE PARAMETER "TYPE" DETERMINES WHICH OF THESE ROUTINES TO
13  PERFORM.
14  IF TYPE=1 THEN DO DIST ONLY.
15  IF TYPE=2 THEN DO POINT ONLY.
16  OTHERWISE, DO BOTH DIST AND POINT.
17  MODIFIED TO COMPUTE THE RELATIVE ERROR AS DEFINED BY RAMA+LAK.
18  ALSO, MODIFIED SO THAT THE RELATIVE ERROR AND DISTANCE
19  MEASURES ARE NOT NORMALIZED IF ABSSUM AND TSTD ARE
20  TOO SMALL. ...4/27/76
21
22  Modified 4/1/88 to enable evaluation of subregions, either
23  through boundary selection by geomtric descriptions OR (OR BOTH)
24  pixel selection through density windowing wrt to phantom.
25  Only pixels within the specified regions and density window
26  will be used in computing the metrics.
27  A switch ISW is added to indicate whether the phantom is passed through
28  the first array, a(), or the second array, b(), so that density
29  selection can always be referenced wrt the phantom.
30  */
31
32 #include <cstdlib>       
33 #include <cstdio>
34 #include "blkdta.h"
35 #include "consts.h"
36 #include "uiod.h"
37 #include "bldlst.h"
38 #include "int2str.h"
39 #include "recfile.h"
40 #include "projfile.h"
41 #include "infile.h"
42 #include "eval.h"   
43 #include "blob.h"
44
45 Eval_class Eval;
46
47 void Eval_class::eval_1()
48 {
49         BOOLEAN temp;
50         FILE* eval1;
51
52         CHAR prjnam[81];
53         CHAR phnnam[81];
54         CHAR recnam[81];
55         CHAR evalnam[81];
56
57         int i, j;
58
59         static const CHAR * objname[] = { "wholepic", "rect", "elip" };
60
61         REAL *ave;
62         REAL *dis;
63         REAL *rel;
64         REAL *var;
65         REAL *std;
66         REAL *tstd;
67         REAL *tvar;
68         REAL *abssum;
69         REAL resid;
70         REAL klds;
71         REAL wsqd;
72
73         INTEGER nerr;
74         REAL epsil[16];
75         INTEGER flag[51];
76         CHAR algn[5];
77         unsigned INTEGER count;
78         unsigned INTEGER iter;
79         INTEGER flag0;
80         REAL* Phantom;
81         REAL* Recon;
82         INTEGER* list = NULL;
83         REAL* weight = NULL;
84         INTEGER type;
85         INTEGER word;
86         BOOLEAN eol, linef, linef_set = false;
87         BOOLEAN fresid, fklds, fwsqd, fulimg, flagdw;
88
89         int n;
90
91         static bool called = false;
92
93         static const INTEGER eval_codes[9] =
94         {
95                 CHAR2INT('r', 'e', 's', 'o'),
96                 CHAR2INT('p', 'o', 'i', 'n'),
97                 CHAR2INT('l', 'i', 'n', 'e'),
98                 CHAR2INT('s', 't', 'r', 'i'),
99                 CHAR2INT('w', 'h', 'o', 'l'),
100                 CHAR2INT('s', 'e', 'l', 'e'),
101                 CHAR2INT('e', 'l', 'i', 'p'),
102                 CHAR2INT('r', 'e', 'c', 't'),
103                 CHAR2INT('l', 'a', 's', 't')
104         };
105
106         // Parse input
107         // Read evaluation type specifications
108
109         word = InFile.getwrd(FALSE, &eol, eval_codes, 4);
110         if (eol)
111         {
112                 type = 0;
113         }
114         else
115         {
116                 if (word == eval_codes[0] || word == eval_codes[1])
117                 {
118                         type = (word == eval_codes[0]) ? 1 : 2;
119                         word = InFile.getwrd(FALSE, &eol, &(eval_codes[2]), 2);
120                 }
121                 else
122                 {
123                         type = 0;
124                 }
125
126                 if (word == eval_codes[2])
127                 {
128                         linef = TRUE;
129                         linef_set = true;
130                 };
131                 if (word == eval_codes[3])
132                 {
133                         linef = FALSE;
134                         linef_set = true;
135                 };
136         };
137
138         // Read evaluation name
139         InFile.GetComment(evalnam);
140         fprintf(output, "\n         %s", evalnam);
141
142         // Read evaluation region specifications
143         word = InFile.getwrd(TRUE, &eol, &(eval_codes[4]), 2);
144
145         if (eol)
146         {
147                 fprintf(output, "\n **** no region (WHOLEPIC or SELECTIVE) specified");
148                 fprintf(output, "\n **** evaluation aborted\n");
149                 return;
150         };
151
152         if (word == eval_codes[4])
153         {
154                 // Whole picture is specified
155                 ObjN = 1; // set number of objects to 1
156                 Obj = new Object[ObjN];
157                 getden(&flagdw, 0); // get densities
158                 Obj[0].objcod = 0; // set object type
159                 fulimg = TRUE; // set full immage flag
160         }
161         else
162         {
163                 //  Selective is specified
164
165                 ObjN = 0;
166                 fulimg = FALSE;
167
168                 eval_Object_Node *f_object, *t_object;
169                 f_object = new eval_Object_Node();
170                 t_object = f_object;
171
172                 while(true)
173                 {
174                         word = InFile.getwrd(TRUE, &eol, &(eval_codes[6]), 3);
175
176                         if (eol)
177                         {
178                                 fprintf(output, "\n **** missing keyword elip, rect or last");
179                                 fprintf(output, "\n **** program aborted\n");
180                                 exit(999);
181                         };
182
183                         if (word == eval_codes[8])
184                         {
185                                 // keyword last found
186                                 if (ObjN > 0) break;
187
188                                 fprintf(output, "\n **** no region specified for SELECTIVE");
189                                 fprintf(output, "\n **** program aborted\n");
190                                 exit(999);
191                         };
192
193                         t_object->data.objcod = (word == eval_codes[7]) ? 1 : 2;
194
195                         // get cx
196                         t_object->data.cx = InFile.getnum(FALSE, &eol);
197                         if (eol)
198                         {
199                                 fprintf(output, "\n **** parameter cx of object %s is missing",int2str(word));
200                                 fprintf(output, "\n **** program aborted\n");
201                                 exit(-1);
202                         };
203
204                         // get cy
205                         t_object->data.cy = InFile.getnum(FALSE, &eol);
206                         if (eol)
207                         {
208                                 fprintf(output, "\n **** parameter cy of object %s is missing",int2str(word));
209                                 fprintf(output, "\n **** program aborted\n");
210                                 exit(-1);
211                         };
212
213                         // get u
214                         t_object->data.u = InFile.getnum(FALSE, &eol);
215                         if (eol)
216                         {
217                                 fprintf(output, "\n **** parameter u of object %s is missing",int2str(word));
218                                 fprintf(output, "\n **** program aborted\n");
219                                 exit(-1);
220                         };
221
222                         // get v
223                         t_object->data.v = InFile.getnum(FALSE, &eol);
224                         if (eol)
225                         {
226                                 fprintf(output, "\n **** parameter v of object %s is missing",int2str(word));
227                                 fprintf(output, "\n **** program aborted\n");
228                                 exit(-1);
229                         };
230
231                         // get ang
232                         t_object->data.ang = InFile.getnum(FALSE, &eol);
233                         if (eol)
234                         {
235                                 fprintf(output, "\n **** parameter ang of object %s is missing",int2str(word));
236                                 fprintf(output, "\n **** program aborted\n");
237                                 exit(-1);
238                         };
239
240                         getdens(&flagdw, t_object);
241
242                         t_object->next = new eval_Object_Node();
243                         t_object = t_object->next;
244
245                         ObjN++;
246                 }
247
248                 // copy list elements to array Obj
249                 if (Obj != NULL)
250                 {
251                         delete[] Obj;
252                         delete[] objdon;
253                 }
254                 Obj = new Object[ObjN];
255                 objdon = new BOOLEAN[ObjN];
256
257                 t_object = f_object;
258
259                 for (i = 0; i < ObjN; i++)
260                 {
261                         Obj[i].cx = t_object->data.cx;
262                         Obj[i].cy = t_object->data.cy;
263                         Obj[i].u = t_object->data.u;
264                         Obj[i].v = t_object->data.v;
265                         Obj[i].ang = t_object->data.ang;
266                         Obj[i].objcod = t_object->data.objcod;
267                         Obj[i].t1 = t_object->data.t1;
268                         Obj[i].t2 = t_object->data.t2;
269
270                         t_object = t_object->next;
271                         delete f_object;
272                         f_object = t_object;
273                 };
274
275                 delete f_object;
276         }
277
278         // create arrays
279         ave = new REAL[ObjN];
280         dis = new REAL[ObjN];
281         rel = new REAL[ObjN];
282         var = new REAL[ObjN];
283         std = new REAL[ObjN];
284         tstd = new REAL[ObjN];
285         tvar = new REAL[ObjN];
286         abssum = new REAL[ObjN];
287
288         //  Echo region specifications
289
290         fprintf(output,"\n Region        cx        cy         u         v        ang      t1        t2\n");
291
292         if (Obj[0].objcod == 0)
293         {
294                 fprintf(output,"\n %s                                                     %9.2g %9.2g",objname[0], Obj[0].t1, Obj[0].t2);
295         }
296         else
297         {
298                 for (j = 0; j < ObjN; j++)
299                 {
300                         fprintf(output,"\n %2i %s  %9.2f %9.2f %9.2f %9.2g %9.2g   %9.2g %9.2g", j,objname[Obj[j].objcod], Obj[j].cx, Obj[j].cy, Obj[j].u,Obj[j].v, Obj[j].ang, Obj[j].t1, Obj[j].t2);
301                 }
302         }
303
304         // READ AND ECHO FLAGS
305         InFile.listit(flag);
306         fresid = FALSE;
307         fklds = FALSE;
308         fwsqd = FALSE;
309
310         for(i=1;i<51;i++){
311                 if(flag[0]==flag[i]||flag[i]==0);
312                 else{
313                         fprintf(output, "\n **** The value of fl[0] is %d, but the value of fl[%d] is %d ",flag[0],i,flag[i]);
314                         fprintf(output, "\n **** program aborted\n");
315                         exit(-1);
316                 }
317         }
318         if(flag[0]==2){fresid = TRUE;}
319         if(flag[0]==3){fklds = TRUE; fwsqd = TRUE; fresid = TRUE;}
320
321         /* for (i = 0; i < 51; i++)
322         {
323                 if (flag[i] >= 3)
324                 {
325                         fresid = TRUE;
326                         fklds = TRUE;
327                         fwsqd = TRUE;
328                         break;
329                 }
330                 else if (flag[i] >= 2)
331                 {
332                         fresid = TRUE;
333                         break;
334                 }
335         } */
336
337         // RESIDUAL CANNOT AND WILL NOT BE CALCULATED IF SOME PIXELS
338         // ARE EXCLUDED BY DENSITY WINDOWING OR REGION SELECTION.
339         // RESET RESIDUAL FLAG
340         if (!fulimg)
341         {
342                 fresid = FALSE;
343                 fklds = FALSE;
344                 fwsqd = FALSE;
345         }
346         else if (flagdw)
347         {
348                 fresid = FALSE;
349                 fklds = FALSE;
350                 fwsqd = FALSE;
351         }
352
353         flag0 = (fresid) ? 2 : 1;
354
355         ////////////////////
356         // START evaluate //
357         ////////////////////
358
359         // check if called before
360         if (called == false)
361         {
362                 eval1 = fopen("eval", "w"); // open new file
363                 called = true;
364         }
365         else
366         {
367                 eval1 = fopen("eval", "a+"); // open existing file for appending
368         }
369
370         //  print evaluation name
371         fprintf(eval1, "\n\nevaluation name: %s\n", evalnam);
372
373         // open recfile
374         if (RecFile.Open("recfil") != 0)
375         {
376                 fprintf(output, "\n **** unable to open recfil");
377                 fprintf(output, "\n **** EVAL execution aborted\n");
378                 fclose(eval1);
379                 return;
380         }
381
382         // Get projection name
383         if (RecFile.GetProjName(prjnam) != 0)
384         {
385                 ;
386         }
387
388         // get picture dimension
389         if (RecFile.GetNelem(&(GeoPar.nelem)) != 0)
390         {
391                 ;
392         }
393
394         // get picture dimension
395         if (RecFile.GetPixSize(&(GeoPar.pixsiz)) != 0)
396         {
397                 ;
398         }
399
400         // calculate picture area
401         GeoPar.area = GeoPar.nelem * GeoPar.nelem;
402         GeoPar.midpix = (GeoPar.nelem + 1) / 2;
403
404         // allocate phantom and reconstruction arrays
405         Phantom = new REAL[GeoPar.area];
406         Recon = new REAL[GeoPar.area];
407
408         // read phantom
409         if (RecFile.ReadPhan(phnnam, Phantom) != 0)
410         {
411                 fprintf(output, "\n **** phantom not present");
412                 fprintf(output, "\n **** EVAL execution aborted\n");
413                 fclose(eval1);
414                 return;
415         }
416
417         if (type != 2)
418         {
419                 // calculate resolution
420
421                 // open prjfil only if residual is calculated
422                 if (fresid)
423                 {
424                         if (ProjFile.Open("prjfil") != 0)
425                         {
426                                 fprintf(output, "\n **** unable to open prjfil");
427                                 fprintf(output, "\n **** EVAL execution aborted\n");
428                                 fclose(eval1);
429                                 return;
430                         };
431
432                         ProjFile.ReadHeader(prjnam, &NoisePar, &Spctrm, &Anglst);
433
434                         if (!linef_set) linef = GeoPar.line;
435
436                         bldlst(&list, &weight);
437                 };
438
439                 // COMPUTE AVERAGE, VARIANCE AND STANDARD DEVIATION OF TEST PATTERN
440
441                 for (j = 0; j < GeoPar.area; j++)
442                         Recon[j] = 0.0;
443                 temp=Blob.pix_basis;
444                 Blob.pix_basis = TRUE;
445                 dist(1, Recon, Phantom, linef, list, weight, flag0, ave, dis, abssum, tvar, tstd, &resid, fresid, &klds, fklds, &wsqd, fwsqd);
446                 Blob.pix_basis=temp;
447
448                 fprintf(eval1, "\n  global resolution measures\n");
449
450                 fprintf(eval1, "\n    phantom name:    %s", phnnam);
451
452                 fprintf(eval1, "\n    projection name: %s", prjnam);
453
454                 if (fresid)
455                 {
456                         if (linef)
457                         {
458                                 fprintf(output,"\n    residual calculation using line integration");
459
460                         }
461                         else
462                         {
463                                 fprintf(output,"\n    residual calculation using strip integration");
464                         }
465                 }
466
467                 fprintf(eval1, "\n\n    metrics for test phantom");
468
469                 if (fresid && (fklds || fwsqd))
470                 {
471                         fprintf(eval1,"\n    region    area   average  distance   rel err  variance   std dev   residual         klds         wsqd");
472                 }
473                 else if (fresid)
474                 {
475                         fprintf(eval1,"\n    region    area   average  distance   rel err  variance   std dev   residual");
476                 }
477                 else
478                 {
479                         fprintf(eval1,"\n    region    area   average  distance   rel err  variance   std dev");
480                 }
481
482                 for (j = 0; j < ObjN; j++)
483                 {
484                         Obj[j].avep = ave[j];
485
486                         if (fresid && (fklds || fwsqd))
487                         {
488                                 fprintf(eval1,"\n    %6d %7d %9.4f                     %9.4f %9.4f %10.4f %12.4f %12.4f",j, Obj[j].npt, Obj[j].avep, tvar[j], tstd[j], resid, klds, wsqd);
489                         }
490                         else if (fresid)
491                         {
492                                 fprintf(eval1,"\n    %6d %7d %9.4f                     %9.4f %9.4f %10.4f",j, Obj[j].npt, Obj[j].avep, tvar[j], tstd[j], resid);
493                         }
494                         else
495                         {
496                                 fprintf(eval1,"\n    %6d %7d %9.4f                     %9.4f %9.4f",j, Obj[j].npt, Obj[j].avep, tvar[j], tstd[j]);
497                         }
498                 }
499
500                 while (RecFile.ReadRec(recnam, algn, &count, &iter, Recon) == 0)
501                 {
502
503                         // if first iteration of algorithm print header
504                         if (count == 1)
505                         {
506                                 fprintf(eval1, "\n\n    execution name: %s", recnam);
507
508                                 if (fulimg)
509                                 {
510                                         fprintf(eval1, "\n    metrics for algorithm %s", algn);
511
512                                         if (fresid && (fklds || fwsqd))
513                                         {
514                                                 fprintf(eval1,"\n    iter    area   average  distance   rel err  variance   std dev   residual         klds         wsqd");
515                                         }
516                                         else if (fresid)
517                                         {
518                                                 fprintf(eval1,"\n    iter    area   average  distance   rel err  variance   std dev   residual");
519                                         }
520                                         else
521                                         {
522                                                 fprintf(eval1,"\n    iter    area   average  distance   rel err  variance   std dev");
523                                         }
524                                 }
525                         }
526
527                         // if iteration not selected continue
528                         if (flag[iter - 1] == 0)
529                         {
530                                 continue;
531                         }
532
533                         if (!fulimg)
534                         {
535                                 fprintf(eval1, "\n    metrics for algorithm %4s iteration %4d",algn, count);
536
537                                 fprintf(eval1, "\n    region    area   average  distance   rel err  variance   std dev");
538                         }
539                         temp = Blob.pix_basis;
540                         Blob.pix_basis = TRUE;
541                         dist(0, Phantom, Recon, linef, list, weight, flag[iter - 1], ave, dis, rel, var, std, &resid, fresid, &klds, fklds, &wsqd, fwsqd);
542                         Blob.pix_basis = temp;
543                         // Loop for each regions
544                         for (j = 0; j < ObjN; j++)
545                         {
546                                 if (abssum[j] > Consts.zero)
547                                 {
548                                         rel[j] /= abssum[j];
549                                 }
550
551                                 if (tstd[j] > Consts.zero)
552                                 {
553                                         dis[j] /= tstd[j];
554                                 }
555
556                                 if (((flag[iter - 1] == 1) || (flag[iter - 1] > 1)) && (!fresid))
557                                 {
558                                         if (fulimg)
559                                         {
560                                                 fprintf(eval1,"\n    %4d %7d %9.4f %9.4f %9.4f %9.4f %10.4f", count, Obj[j].npt, ave[j], dis[j], rel[j], var[j], std[j]);
561                                         }
562                                         else
563                                         {
564                                                 fprintf(eval1,"\n    %6d %7d %9.4f %9.4f %9.4f %9.4f %10.4f", j, Obj[j].npt, ave[j], dis[j], rel[j], var[j], std[j]);
565                                         }
566                                 }
567
568                                 if ((flag[iter - 1] > 1) && fresid && (fklds || fwsqd))
569                                 {
570                                         fprintf(eval1,"\n    %4d %7d %9.4f %9.4f %9.4f %9.4f %9.4f %10.4f %12.4f %12.4f", count, Obj[j].npt, ave[j], dis[j], rel[j], var[j], std[j], resid, klds, wsqd);
571                                 }
572                                 else if ((flag[iter - 1] > 1) && fresid)
573                                 {
574                                         fprintf(eval1,"\n    %4d %7d %9.4f %9.4f %9.4f %9.4f %9.4f %10.4f", count, Obj[j].npt, ave[j], dis[j], rel[j], var[j], std[j], resid);
575                                 }
576                         }
577
578                         if (ObjN > 1)
579                         {
580                                 fprintf(eval1, "\n");
581                         }
582                 };
583
584                 if (fresid)
585                 {
586                         ProjFile.Close();
587                 }
588         };
589
590         // calculate point measurements
591         // if type was 1 we are done
592         if (type == 1 || !fulimg || (fulimg && flagdw))
593         {
594
595                 if (type != 1)
596                 {
597
598                         if (!fulimg)
599                         {
600                                 fprintf(output,"\n **** Selective was specified, point measures will not be computed.\n");
601                         }
602                         else
603                         {
604                                 fprintf(output,"\n **** Density range was specified, point measures will not be computed.\n");
605                         }
606                 }
607         }
608         else
609         { // if type != 1 -> type == 0 (both) or type = 2
610
611                 fprintf(eval1, "\n  point by point resolution measures\n");
612
613                 fprintf(eval1, "\n    phantom name:    %s", phnnam);
614
615                 if (fresid || (type != 2))
616                 {
617                         fprintf(eval1, "\n    projection name: %s", prjnam);
618                 }
619
620                 // select first reconstruction in file
621                 RecFile.SelectRec(0);
622
623                 // loop though receonstructions
624                 while (RecFile.ReadRec(recnam, algn, &count, &iter, Recon) == 0)
625                 {
626
627                         BOOLEAN headfl;
628
629                         // if first iteration of algorithm print header
630                         if (count == 1)
631                         {
632                                 headfl = true;
633                         }
634
635                         // if iteration not selected continue
636                         if (flag[iter - 1] == 0)
637                         {
638                                 continue;
639                         }
640
641                         point(Phantom, Recon, Recon, GeoPar.nelem, &nerr, epsil);
642
643                         if (headfl)
644                         {
645                                 fprintf(eval1, "\n\n    execution name:  %s", recnam);
646
647                                 fprintf(eval1, "\n    algn    iter"); // only print out 'e(n)' as many times as there
648                                 for (n = 0; n < nerr; n++)
649                                 { // are values in 'epsil[]' (i.e. 'nerr' times)
650                                         fprintf(eval1, "      e(%d)", n);
651                                 }
652
653                                 headfl = false;
654                         }
655
656                         fprintf(eval1, "\n    %4s  %6d", algn, count);
657                         for (n = 0; n < nerr; n++)
658                         {
659                                 fprintf(eval1, " %9.4f", epsil[n]);
660                         }
661                 }
662         }
663
664         delete[] Obj;
665         Obj = NULL;
666         delete[] ave;
667         ave = NULL;
668         delete[] dis;
669         dis = NULL;
670         delete[] rel;
671         rel = NULL;
672         delete[] var;
673         var = NULL;
674         delete[] std;
675         std = NULL;
676         delete[] tstd;
677         tstd = NULL;
678         delete[] tvar;
679         tvar = NULL;
680         delete[] abssum;
681         abssum = NULL;
682
683         fprintf(eval1, "\n ");
684         fclose(eval1);
685
686         RecFile.Close();
687
688         delete[] Phantom;
689         Phantom = NULL;
690         delete[] Recon;
691         Recon = NULL;
692         if (list != NULL) delete[] list;
693         list = NULL;
694         if (weight != NULL) delete[] weight;
695         weight = NULL;
696 }