1 /**********
2 *
3 * Copyright (c) 2003, Division of Imaging Science and Biomedical Engineering,
4 * University of Manchester, UK. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 *
9 * . Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * . Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * . Neither the name of the University of Manchester nor the names of its
17 * contributors may be used to endorse or promote products derived from this
18 * software without specific prior written permission.
19 *
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 **********
34 *
35 * Program : TINA
36 * File :
37 * Date :
38 * Version :
39 * CVS Id :
40 *
41 * Author : Legacy TINA
42 *
43 * Notes :
44 *
45 *
46 *
47 *********
48 */
49
50 /**
51 * @file
52 * @brief Tina Tool for providing Talairach atlas locations for image sequences.
53 *
54 * Having co-registered your sequence to the Talairach atlas, this tool allows you to specify in the
55 * sequence tool via left mouse clicks or via the interface the position of interest and the appropriate
56 * label for the position is returned.
57 *
58 */
59
60
61
62 #include "tlmedTal_tool.h"
63
64
65 #if HAVE_CONFIG_H
66 #include <config.h>
67 #endif
68
69
70 #include <stdio.h>
71 #include <sys/param.h>
72 #include <string.h>
73 #include <math.h>
74
75 #include <tina/sys/sysDef.h>
76 #include <tina/sys/sysPro.h>
77 #include <tina/math/mathDef.h>
78 #include <tina/math/mathPro.h>
79 #include <tina/file/fileDef.h>
80 #include <tina/file/filePro.h>
81 #include <tina/image/imgDef.h>
82 #include <tina/image/imgPro.h>
83 #include <tinatool/draw/drawDef.h>
84 #include <tinatool/draw/drawPro.h>
85 #include <tinatool/tlbase/tlbaseDef.h>
86 #include <tinatool/tlbase/tlbasePro.h>
87 #include <tinatool/tlmedical/tlmedPro.h>
88 #include <tinatool/wdgts/wdgtsDef.h>
89 #include <tinatool/wdgts/wdgtsPro.h>
90
91
92 Loaded_Files *file_list_head = NULL;
93 int no_of_files_loaded;
94 int conf_file;
95 /*char taldata_dir[]="/usr/local/Taliarach/X";*/
96 static char taldata_dir[512]; /* Path to the files of the Taliarach Atlas */
97
98 /* interactive global variables for access via dialog box */
99 static int x_coord;
100 static void *px_coord=NULL;
101 static int y_coord;
102 static void *py_coord=NULL;
103 static int z_coord;
104 static void *pz_coord=NULL;
105 static int x_var = 0.0;
106 static int y_var = 0.0;
107 static int z_var = 0.0;
108 static Ipos start_pos;
109 static Imrect **talvol=NULL;
110 static char *taltag;
111 static int maxx = 0,minx = 0;
112 static int maxy = 0,miny = 0;
113 static int maxz = 0,minz = 0;
114 static void *ptalatlas=NULL;
115
116 /** All The Taliarach stuff goes in here **/
117
118
119 static void alloc_talvol()
120 {
121 Imregion roi;
122 int i,x;
123 roi.lx = MINXFILES;
124 roi.ux = MAXXFILES;
125 roi.ly = MINYFILES;
126 roi.uy = MAXYFILES;
127 talvol = (Imrect **)pvector_alloc(MINZFILES,MAXZFILES);
128 taltag = (char *)cvector_alloc(MINXFILES,MAXXFILES);
129 for (i=MINZFILES;i<MAXZFILES;i++)
130 {
131 talvol[i] = im_alloc(roi.uy-roi.ly,roi.ux-roi.lx, &roi, ptr_v);
132 }
133 /*
134 for (x= MINXFILES;x<MAXXFILES; x++)
135 {
136 open_database_file((ListEntry *) NULL, x);
137 }
138 format("max and min %d %d %d %d %d %d",minx,maxx,miny,maxy,minz,maxz);
139 */
140 }
141
142 void open_database_file(ListEntry * Head, int x) {
143
144 int i;
145 ListEntry *file_data;
146 FILE *pFileptr;
147 Imrect *im;
148 void ***array;
149 char xfile[5];
150 char file[128];
151 char file_ext[]=".fin";
152
153 sprintf(file,"%s%d%s\0",taldata_dir,x,file_ext);
154
155 if ( ( pFileptr = fopen( file, "r" ) ) !=NULL )
156 {
157 for ( i=0; i<MAXRECORDS; i++ ) {
158
159 file_data = (ListEntry *) malloc(sizeof(ListEntry));
160 if (fscanf(pFileptr, "%d %d %d %d %d %d %d", &file_data->y, &file_data->z,
161 &file_data->field1, &file_data->field2, &file_data->field3,
162 &file_data->field4, &file_data->field5) == 7)
163 {
164 im = talvol[file_data->z];
165 file_data->x = x;
166 array = im->data;
167 array[file_data->y][x] = (void *)file_data;
168 if (file_data->x > maxx) maxx = file_data->x;
169 if (file_data->x < minx) minx = file_data->x;
170 if (file_data->y > maxy) maxy = file_data->y;
171 if (file_data->y < miny) miny = file_data->y;
172 if (file_data->z > maxz) maxz = file_data->z;
173 if (file_data->z < minz) minz = file_data->z;
174 }
175 else
176 free(file_data);
177 }
178 fclose(pFileptr);
179 no_of_files_loaded++;
180 taltag[x] =1;
181 }
182 else
183 format("\nError opening database %s \n", file);
184
185 }
186
187 InputData *open_coordinate_file(const char *to_open, InputData *input) {
188
189 FILE *pFileptr;
190 InputData input_d;
191 char x[5];
192 char y[5];
193 char z[5];
194
195 input_d.next = NULL;
196 if ( (pFileptr = fopen( to_open, "r")) !=NULL )
197 {
198 while ( !feof(pFileptr) )
199 {
200 fscanf(pFileptr, "%s %s %s", input_d.x_file, y, z);
201 input_d.x = atoi (input_d.x_file);
202 input_d.y = atoi (y);
203 input_d.z = atoi (z);
204 input = (InputData *) add_to_list(input, &input_d, COORD_RECORD);
205 }
206 fclose(pFileptr);
207 }
208 else
209 format("\nError opening coordinate %s \n", to_open);
210
211 return(input);
212 }
213
214 void *add_to_list(void *head, void *ToAdd, int type) {
215
216 /* For use when a file of coordinates is read */
217 InputData * new_in = NULL;
218 InputData * adding = NULL;
219
220 /* To hold coordinate data read in */
221 if (type==COORD_RECORD)
222 {
223 new_in = (InputData *)ToAdd;
224 if (head == NULL)
225 {
226 adding = (InputData *) malloc(sizeof(InputData));
227 head= (InputData *) adding;
228 adding->next=NULL;
229 strcpy( adding->x_file, new_in->x_file);
230 adding->x = new_in->x;
231 adding->y = new_in->y;
232 adding->z = new_in->z;
233 }
234 else
235 {
236 adding = (InputData *) malloc(sizeof(InputData));
237 strcpy( adding->x_file, new_in->x_file);
238 adding->x = new_in->x;
239 adding->y = new_in->y;
240 adding->z = new_in->z;
241 adding->next = (InputData *) head;
242 head = (InputData *) adding;
243 }
244 return ((InputData *) head);
245 }
246 }
247
248 ListEntry * record_to_print(InputData * UsrVal) {
249
250 Imrect *im;
251 ListEntry *current=NULL;
252 void ***array;
253 if (talvol ==NULL) alloc_talvol();
254 if (UsrVal->z < MAXZFILES && UsrVal->z > MINZFILES)
255 {
256 if ( (UsrVal->x < MAXXFILES) && (UsrVal->x > MINXFILES)
257 && (taltag[UsrVal->x]==0))
258 open_database_file((ListEntry *) NULL, UsrVal->x);
259
260 im = talvol[UsrVal->z];
261 array = im->data;
262 current = (ListEntry *) im_get_ptr(im, UsrVal->y, UsrVal->x);
263 }
264 return(current);
265 }
266
267 void record_output(ListEntry * ToPrint) {
268
269 if (ToPrint !=NULL)
270 {
271 format("\n");
272 format("Field 1: %s\n", pLexRecords[ToPrint->field1]);
273 format("Field 2: %s\n", pLexRecords[ToPrint->field2]);
274 format("Field 3: %s\n", pLexRecords[ToPrint->field3]);
275 format("Field 4: %s\n", pLexRecords[ToPrint->field4]);
276 format("Field 5: %s\n", pLexRecords[ToPrint->field5]);
277 format("\n");
278 }
279
280 if (ToPrint==NULL)
281 {
282 format("\nNo description available at this point! \n");
283 }
284 }
285
286 void destroy_app(void) {
287
288 /* For deleting list of files loaded */
289 Loaded_Files * current;
290 ListEntry * in_file_list;
291 Loaded_Files * nextrec;
292 ListEntry * next_file;
293
294 if (no_of_files_loaded > 0)
295 {
296 }
297 no_of_files_loaded = 0;
298 }
299
300 void DeleteCoordList (InputData * head) {
301
302 /* For deleting coordinate file */
303 InputData * current;
304 InputData * next_rec;
305
306 current = head;
307 while (current != NULL)
308 {
309 next_rec=current->next;
310 free(current);
311 current = next_rec;
312 }
313 }
314
315 void multiple_search_control(const char *to_open) {
316
317 InputData * first = NULL;
318 InputData * current = NULL;
319 InputData * next_rec = NULL;
320 ListEntry *thisone;
321
322 format("File to open is %s\n", to_open);
323 first = open_coordinate_file(to_open, first);
324 format("\n Read Coordinate file - Searching \n");
325
326 current = first;
327 while ( current != NULL)
328 {
329 thisone = record_to_print(current);
330 record_output(thisone);
331 next_rec = current->next;
332 current = next_rec;
333 }
334 DeleteCoordList(first);
335 }
336
337 void single_search_control() {
338
339 InputData input_data; /* shouldn't this be a pointer?*/
340 ListEntry * thisone = NULL;
341
342 input_data.x = x_coord;
343 input_data.y = y_coord;
344 input_data.z = z_coord;
345 sprintf(input_data.x_file, "%d", x_coord);
346 input_data.next = NULL;
347 thisone = record_to_print( &input_data);
348 record_output(thisone);
349
350 }
351
352 ListEntry *hist_fill_search(Vec3 tal3_pos)
353 {
354 InputData * input_data = NULL;
355 ListEntry * thisone = NULL;
356
357 input_data = (InputData *) malloc(sizeof(InputData));
358 input_data->x = tina_int(tal3_pos.el[0]);
359 input_data->y = tina_int(tal3_pos.el[1]);
360 input_data->z = tina_int(tal3_pos.el[2]);
361 sprintf(input_data->x_file, "%d", tina_int(tal3_pos.el[0]));
362 input_data->next = NULL;
363 thisone = record_to_print(input_data);
364
365 return(thisone);
366 }
367
368
369 /** End of the stuff from the tal_app program **/
370
371 /* Taliarach conversion factors for Tbrain64 brain standard */
372 Vec3 tal_convert(Vec3 tal3)
373 {
374 tal3.el[0] = (32.0-tal3.el[0])*72.0/20.0;
375 tal3.el[1] = (29.5-tal3.el[1])*72.0/20.0;
376 tal3.el[2] = (tal3.el[2]-17.5)*74.0/20.0;
377 return(tal3);
378 }
379
380 static void fmri_count_proc(double *thresh)
381 {
382 Vec3 ex,ey,ez,posi,post;
383 int i,j,k;
384 double x,y,z;
385 double val;
386 int imptrlx, imptrux,imptrly, imptruy, imptrlz, imptruz;
387 float nearest_pixel(void ***rasptrs, Vec3 pos);
388 void ***coreg_limits(int *lz, int *uz, int *ly, int *uy, int *lx, int *ux);
389 Vec3 tal3;
390 void ***imptrs;
391
392 imptrs = seq_limits(&imptrlz,&imptruz,&imptrly,&imptruy,&imptrlx,&imptrux);
393 seq_init_interp(imptrlx,imptrux, imptrly,imptruy, imptrlz,imptruz);
394
395
396 for (k=imptrlz;k<imptruz;k++)
397 {
398 for (i=imptrly;i<imptruy;i++)
399 {
400 for (j=imptrlx;j<imptrux;j++)
401 {
402 posi.el[0] = ((float)j+0.5 );
403 posi.el[1] = ((float)i+0.5 );
404 posi.el[2] = ((float)k+0.5 );
405 tal3 = coreg_proj(posi.el[0],posi.el[1], posi.el[2]);
406
407 if ((val = nearest_pixel(imptrs,posi))> *thresh)
408 {
409 tal3 = tal_convert(tal3);
410 format("%d %d %d \n",
411 (int)tina_int(tal3.el[0]),(int)tina_int(tal3.el[1]),(int)tina_int(tal3.el[2]));
412 }
413 }
414 }
415 }
416 }
417
418 static void grey_matter_proc(double *thresh)
419 {
420 Sequence *seq_get_current();
421 Sequence *seq;
422 InputData input_data;
423 Vec3 ex,ey,ez,posi,post;
424 int i,j,k,grey;
425 Imrect *im;
426 Imregion roi;
427 double x,y,z;
428 double val;
429 int imptrlx, imptrux,imptrly, imptruy, imptrlz, imptruz;
430 float nearest_pixel(void ***rasptrs, Vec3 pos);
431 void ***coreg_limits(int *lz, int *uz, int *ly, int *uy, int *lx, int *ux);
432 Vec3 tal3;
433 void ***imptrs;
434 char **array=NULL;
435 ListEntry *thisone;
436
437 imptrs = seq_limits(&imptrlz,&imptruz,&imptrly,&imptruy,&imptrlx,&imptrux);
438 seq_init_interp(imptrlx,imptrux, imptrly,imptruy, imptrlz,imptruz);
439 roi.lx = imptrlx;
440 roi.ux = imptrux;
441 roi.ly = imptrly;
442 roi.uy = imptruy;
443 im = im_alloc(imptruy-imptrly,imptrux-imptrlx, &roi, uchar_v);
444 seq = seq_get_current();
445 if (seq == NULL)
446 return;
447 k = get_seq_current_frame(seq);
448 array = im->data;
449 for (i=imptrly;i<imptruy;i++)
450 {
451 for (j=imptrlx;j<imptrux;j++)
452 {
453 posi.el[0] = ((float)j+0.5 );
454 posi.el[1] = ((float)i+0.5 );
455 posi.el[2] = ((float)k+0.5 );
456 if ((val = nearest_pixel(imptrs,posi))> *thresh)
457 {
458 tal3 = coreg_proj(posi.el[0],posi.el[1], posi.el[2]);
459 tal3 = tal_convert(tal3);
460 x_coord = (int)tina_int(tal3.el[0]);
461 tw_iglobal_reset(px_coord);
462 y_coord = (int)tina_int(tal3.el[1]);
463 tw_iglobal_reset(py_coord);
464 z_coord = (int)tina_int(tal3.el[2]);
465 tw_iglobal_reset(pz_coord);
466 input_data.x = x_coord;
467 input_data.y = y_coord;
468 input_data.z = z_coord;
469 sprintf(input_data.x_file, "%d", x_coord);
470 input_data.next = NULL;
471 thisone = record_to_print(&input_data);
472 if (thisone&&thisone->field4==79)
473 {
474 IM_PIX_SET(im, i,j, 1);
475 }
476 }
477 }
478 }
479 stack_push(im, IMRECT, im_free);
480 }
481
482
483 static void talairach_param_dialog(void)
484 {
485 static void *dialog = NULL;
486
487 if (dialog)
488 {
489 tw_show_dialog(dialog);
490 return;
491 }
492
493 dialog = tw_dialog("Search Parameters");
494 format("Search Parameters opened\n");
495 tw_iglobal("x variance : ", &x_var, 20);
496 tw_newrow();
497 tw_iglobal("y variance : ", &y_var, 20);
498 tw_newrow();
499 tw_iglobal("z variance : ", &z_var, 20);
500
501 tw_end_dialog();
502 }
503
504 /*** Start the search for the Talairach Description **/
505
506 static void talairach_search_proc(void)
507 {
508 format("Values to search are :\n");
509 format("x coord : %d +/- %d y coord: %d +/- %d, z coord: %d +/- %d\n", x_coord, x_var, y_coord, y_var, z_coord, z_var);
510 single_search_control();
511
512 }
513
514 static void set_tal_down(Tv * tv, Ipos pos)
515 {
516 Vec2 tv_backproj2();
517
518 tv_save_draw(tv);
519 tv_set_overlay(tv);
520 start_pos = pos;
521 tv_cross(tv, pos, 7);
522 }
523
524 static void draw_tal_drag(Tv * tv, Ipos pos)
525 {
526 tv_cross(tv, start_pos, 7);
527 tv_cross(tv, pos, 7);
528 start_pos = pos;
529 }
530
531 static void tal_comp(Tv * tv, Ipos pos)
532 {
533 Vec2 talpos;
534 Vec3 tal3;
535 Sequence *seq_get_current();
536 Sequence *seq;
537 int z;
538
539 tv_reset_draw(tv);
540
541 seq = seq_get_current();
542
543 if (seq == NULL)
544 return;
545
546 z = get_seq_current_frame(seq);
547 talpos = tv_backproj2(tv, pos);
548 format(" x = %f y = %f z = %d \n",talpos.el[0]+0.5,talpos.el[1]+0.5, z+0.5);
549 tal3 = coreg_proj((double)talpos.el[0]+0.5,(double)talpos.el[1]+0.5, (double)z+0.5);
550 tal3 = tal_convert(tal3);
551 /*
552 format(" x = %f y = %f z = %d \n",tal3.el[0],tal3.el[1], tal3.el[2]);
553 */
554 x_coord = (int)tina_int(tal3.el[0]);
555 tw_iglobal_reset(px_coord);
556 y_coord = (int)tina_int(tal3.el[1]);
557 tw_iglobal_reset(py_coord);
558 z_coord = (int)tina_int(tal3.el[2]);
559 tw_iglobal_reset(pz_coord);
560 single_search_control();
561 }
562
563
564 Tv_mouse taliarach_mouse(void)
565 {
566 return (mouse_define(MOUSE_NAME, "taliarach",
567 LEFT_NAME, "locate",
568 LEFT_DOWN, set_tal_down,
569 LEFT_DRAG, draw_tal_drag,
570 LEFT_UP, tal_comp,
571 NULL));
572
573 }
574
575 static void seq_mouse_proc(Tv_mouse(*func)())
576 {
577 Tv *seq_tv_get();
578
579 tv_set_mouse(seq_tv_get(), (*func) ());
580 tv_set_activity(seq_tv_get(), MOUSE);
581 }
582
583 /********** Tool creation **********/
584
585 void taliarach_tool(int x, int y)
586 {
587 static void *tool = NULL;
588 static double thresh = 4.0;
589
590 if (tool)
591 {
592 tw_show_tool(tool);
593 return;
594 }
595
596 tool = (void *)tw_tool("Talairach Tool", x, y);
597
598 tw_menubar("Sequence Pick: ",
599 "taliarach",
600 "locate", seq_mouse_proc, taliarach_mouse,
601 NULL, NULL);
602
603 tw_newrow();
604 ptalatlas = (void *)tw_sglobal("Talairach Atlas: ", taldata_dir, 40);
605 tw_newrow();
606 px_coord = tw_iglobal("x coord : ", &x_coord, 5);
607 py_coord = tw_iglobal("y coord : ", &y_coord, 5);
608 pz_coord = tw_iglobal("z coord : ", &z_coord, 5);
609 tw_newrow();
610 tw_fglobal("Threshold : ", &thresh, 5);
611 tw_newrow();
612 tw_button("Search Parameters", talairach_param_dialog, NULL);
613 tw_button("GO!", talairach_search_proc, NULL);
614 tw_button("Activations", fmri_count_proc, (void *)&thresh);
615 tw_button("Grey matter", grey_matter_proc,(void *)&thresh);
616 tw_button("Press to finish", destroy_app, NULL);
617
618 tw_end_tool();
619 }
620
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.