Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

Dimon.c File Reference

#include <stdio.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <math.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "Imon.h"
#include "l_mcw_glob.h"
#include "thd_iochan.h"
#include "realtime.h"
#include "mri_image.h"
#include "dbtrace.h"

Go to the source code of this file.


Data Structures

struct  dimon_stuff_t

Defines

#define DIMON_VERSION   "version 2.0 (August 01, 2005)"
#define MAIN
#define IFM_PROG_NAME   "Dimon"

Functions

int compare_finfo (const void *v0, const void *v1)
int dicom_order_files (param_t *p)
MRI_IMAGEr_mri_read_dicom (char *fname, int debug, void **data)
int read_dicom_image (char *pathname, finfo_t *fp, int get_data)
int add_to_string_list (string_list *list, char *str)
int alloc_x_im (im_store_t *is, int bytes)
int check_error (int *retry, float tr, char *note)
int check_im_byte_order (int *order, vol_t *v, param_t *p)
int check_im_store_space (im_store_t *is, int num_images)
int check_stalled_run (int run, int seq_num, int naps, int nap_time)
int complete_orients_str (vol_t *v, param_t *p)
int create_gert_script (stats_t *s, param_t *p)
int create_gert_reco (stats_t *s, opts_t *opts)
int create_gert_dicom (stats_t *s, param_t *p)
int dir_expansion_form (char *sin, char **sexp)
int disp_ftype (char *info, int ftype)
int empty_string_list (string_list *list, int free_mem)
int find_first_volume (vol_t *v, param_t *p, ART_comm *ac)
int find_fl_file_index (param_t *p)
int find_more_volumes (vol_t *v, param_t *p, ART_comm *ac)
int find_next_zoff (param_t *p, int start, float zoff)
int init_extras (param_t *p, ART_comm *ac)
int init_options (param_t *p, ART_comm *a, int argc, char *argv[])
int nap_time_from_tr (float tr)
int path_to_dir_n_suffix (char *dir, char *suff, char *path)
int read_ge_files (param_t *p, int start, int max)
int read_ge_image (char *pathname, finfo_t *fp, int get_image, int need_memory)
int scan_ge_files (param_t *p, int next, int nfiles)
int set_nice_level (int level)
int set_volume_stats (param_t *p, stats_t *s, vol_t *v)
int show_run_stats (stats_t *s)
int str_char_count (char *str, int len, char target)
int swap_4 (void *ptr)
void hf_signal (int signum)
int check_one_volume (param_t *p, int start, int *fl_start, int bound, int state, int *r_first, int *r_last, float *r_delta)
int volume_match (vol_t *vin, vol_t *vout, param_t *p, int start)
int volume_search (vol_t *V, param_t *p, int start, int maxsl, int *fl_start, int *state)
int idisp_opts_t (char *info, opts_t *opt)
int idisp_param_t (char *info, param_t *p)
int idisp_vol_t (char *info, vol_t *v)
int idisp_ge_extras (char *info, ge_extras *E)
int idisp_ge_header_info (char *info, ge_header_info *I)
int idisp_im_store_t (char *info, im_store_t *is)
int usage (char *prog, int level)
unsigned long l_THD_filesize (char *pathname)
int main (int argc, char *argv[])

Variables

char g_history []
char DI_MRL_orients [8]
float DI_MRL_tr
dimon_stuff_t gr_dimon_stuff
IFM_debug gD
param_t gP
stats_t gS
ART_comm gAC

Define Documentation

#define DIMON_VERSION   "version 2.0 (August 01, 2005)"
 

Definition at line 15 of file Dimon.c.

Referenced by usage().

#define IFM_PROG_NAME   "Dimon"
 

Definition at line 78 of file Dimon.c.

Referenced by create_gert_dicom(), create_gert_reco(), and init_options().

#define MAIN
 

Definition at line 77 of file Dimon.c.


Function Documentation

int add_to_string_list string_list   list,
char *    str
[static]
 

Definition at line 3731 of file Dimon.c.

References IFM_debug::level, string_list::nalloc, string_list::nused, realloc, and string_list::str.

03732 {
03733     if ( !list || !str )
03734         return -1;
03735 
03736     /* if needed, just add 10 at a time to nalloc (they're only pointers) */
03737     if ( list->nalloc == 0 || (list->nalloc <= list->nused) )
03738     {
03739         list->nalloc += 10;
03740         list->str = (char **)realloc(list->str, list->nalloc*sizeof(char *));
03741         if ( !list->str )
03742         {
03743             fprintf(stderr,"** failed to allocate for %d (char *)s\n",
03744                     list->nalloc);
03745             return -1;
03746         }
03747         if( gD.level > 2 )
03748             fprintf(stderr,"+d realloc %d (char *)'s\n",list->nalloc);
03749     }
03750 
03751     list->str[list->nused] = str;
03752     list->nused++;
03753 
03754     return 0;
03755 }

int alloc_x_im im_store_t   is,
int    bytes
[static]
 

Definition at line 3428 of file Dimon.c.

References im_store_t::im_size, IFM_debug::level, malloc, and im_store_t::x_im.

03429 {
03430     if ( (is == NULL) || (bytes <= 0) )
03431     {
03432         fprintf( stderr, "** bad params to AXI (%p,%d)\n", is, bytes );
03433         return -1;
03434     }
03435 
03436     is->im_size = bytes;
03437 
03438     if ( (is->x_im = malloc( bytes )) == NULL )
03439     {
03440         fprintf( stderr, "** AXI: failed to malloc %d bytes for x_im\n",
03441                  bytes );
03442         return -1;
03443     }
03444 
03445     if ( gD.level > 1 )
03446         fprintf( stderr, "++ allocating %d bytes for is->x_im\n", bytes );
03447 
03448     return 0;
03449 }

int check_error int *    retry,
float    tr,
char *    note
[static]
 

Definition at line 928 of file Dimon.c.

References CHECK_NULL_STR, IFM_debug::level, and nap_time_from_tr().

00929 {
00930     if ( !retry )
00931         return -1;
00932 
00933     if ( *retry == 1 )
00934     {
00935         /* let user know we're checking */
00936         if ( gD.level > 0 )
00937             fprintf(stderr," (volume retry test for warning '%s'...)\n",
00938                     CHECK_NULL_STR(note));
00939 
00940         *retry = 0;
00941         sleep( nap_time_from_tr(tr) );
00942         return 0;
00943     }
00944 
00945     /* so calling function should print error */
00946 
00947     *retry = 2;
00948 
00949     return 1;
00950 }

int check_im_byte_order int *    order,
vol_t   v,
param_t   p
[static]
 

Definition at line 3462 of file Dimon.c.

References vol_t::fl_1, param_t::flist, IFM_debug::level, param_t::opts, p, opts_t::rev_bo, and v.

03463 {
03464     int one = 1;
03465 
03466     if ( (order == NULL) || (v == NULL) || (p == NULL) )
03467     {
03468         fprintf( stderr, "** invalid paramters to CIBO (%p,%p,%p)\n",
03469                  order, v, p );
03470         return -1;
03471     }
03472 
03473     /* note the order for the current system */
03474     *order = (*(char *)&one == 1) ? LSB_FIRST : MSB_FIRST;
03475 
03476     if ( gD.level > 1 )
03477         fprintf( stderr, "-- system order is %s, ",
03478                  (*order == MSB_FIRST) ? "MSB_FIRST" : "LSB_FIRST" );
03479 
03480     /* are the images the opposite of this?  does the user want the opposite? */
03481     if ( p->flist[v->fl_1].gex.swap ^ p->opts.rev_bo )
03482         *order = LSB_FIRST + MSB_FIRST - *order;      /* for entertainment */
03483 
03484     if ( gD.level > 1 )
03485         fprintf( stderr, "image order is %s\n",
03486                  (*order == MSB_FIRST) ? "MSB_FIRST" : "LSB_FIRST" );
03487 
03488     return 0;
03489 }

int check_im_store_space im_store_t   is,
int    num_images
[static]
 

Definition at line 3385 of file Dimon.c.

References im_store_t::ary_len, im_store_t::im_ary, IFM_debug::level, and realloc.

03386 {
03387     if ( (is == NULL) || (num_images <= 0) )
03388     {
03389         fprintf( stderr, "** CISS: invalid parameters (%p,%d)\n",
03390                  is, num_images );
03391         return -1;
03392     }
03393 
03394     if ( is->ary_len >= num_images )
03395         return 0;
03396 
03397     /* so we need memory */
03398 
03399     if ( gD.level > 2 )
03400         fprintf( stderr, "++ allocating %d image pointers (was %d)\n",
03401                  num_images, is->ary_len );
03402 
03403     is->im_ary = realloc(is->im_ary, num_images * sizeof(void *));
03404 
03405     if ( is->im_ary == NULL )
03406     {
03407         fprintf( stderr, "** failure: cannot allocate %d image pointers\n",
03408                  num_images );
03409         return -1;
03410     }
03411 
03412     /* clear the new pointers */
03413     memset(is->im_ary+is->ary_len, 0, (num_images-is->ary_len)*sizeof(void*));
03414 
03415     is->ary_len = num_images;
03416 
03417     return 1;
03418 }

int check_one_volume param_t   p,
int    start,
int *    fl_start,
int    bound,
int    state,
int *    r_first,
int *    r_last,
float *    r_delta
 

Definition at line 595 of file Dimon.c.

References param_t::flist, param_t::fnames, finfo_t::geh, IFM_EPSILON, IFM_debug::level, param_t::opts, p, opts_t::use_dicom, ge_header_info::uv17, and ge_header_info::zoff.

Referenced by volume_search().

00597 {
00598     finfo_t * fp;
00599     float     delta, z_orig, prev_z, dz;
00600     int       run0, run1, first, next, last;
00601 
00602     if( bound <= start )
00603     {
00604         fprintf(stderr,"error: COV: bad bound, start (%d,%d)\n", bound, start);
00605         return -2;
00606     }
00607 
00608     /* if state is 2 and we have only 1 or 2 images, return quickly */
00609     if( state == 2 && (bound-start) < 3 )
00610     {
00611         if( gD.level > 1 )
00612             fprintf(stderr,"-d stall after only %d slices\n", bound-start);
00613         *r_first = start;
00614         if( (bound-start) == 1 ) /* then only one slice */
00615         {
00616             *r_last = start;
00617             *r_delta = 1.0;  /* doesn't really matter, but 0 may be bad */
00618         }
00619         else /* 2 slices, so 1 volume of 2 slices or 2 volumes of 1 slice */
00620         {
00621             delta = p->flist[start+1].geh.zoff - p->flist[start].geh.zoff;
00622             if ( fabs(delta) < IFM_EPSILON )  /* one slice per volume */
00623             {
00624                 *r_last = start;
00625                 *r_delta = 1.0;
00626             }
00627             else                              /* two slices per volume */
00628             {
00629                 *r_last = start+1;
00630                 *r_delta = delta;
00631             }
00632         }
00633         return 1;  /* done */
00634     }
00635     else if ( bound-start < 3 )
00636         return 0;
00637 
00638     first = start;
00639     delta = p->flist[first+1].geh.zoff - p->flist[first].geh.zoff;
00640 
00641     run0  = p->flist[first  ].geh.uv17;
00642     run1  = p->flist[first+1].geh.uv17;
00643 
00644     /* if apparent 1-slice volume, skip and start over */
00645     if ( (fabs(delta) < IFM_EPSILON) || (run1 != run0) )
00646     {
00647         /* consider this a single slice volume */
00648         if ( p->opts.use_dicom )
00649         {
00650             if( gD.level > 1 ) fprintf(stderr,"+d found single slice volume\n");
00651             *r_first = *r_last = first;
00652             *r_delta = 1.0;   /* make one up, zero may be bad */
00653             return 1;         /* success */
00654         }
00655 
00656         if ( gD.level > 1 )
00657             fprintf( stderr, "-- skipping single slice volume <%s>\n",
00658                      p->fnames[p->flist[first].index] );
00659         first++;
00660         delta = p->flist[first+1].geh.zoff - p->flist[first].geh.zoff;
00661         run0  = run1;
00662 
00663         if ( fabs(delta) < IFM_EPSILON )
00664         {
00665             fprintf( stderr, "Error: 3 slices with 0 delta, beginning with"
00666                      "file <%s>\n", p->fnames[p->flist[start].index] );
00667             *fl_start = p->flist[start+2].index;
00668             return -1;
00669         }
00670     }
00671 
00672     fp = p->flist + first;                      /* initialize flist posn  */
00673     z_orig = fp->geh.zoff;                      /* note original position */
00674 
00675     /* set current values at position (first+1) */
00676     fp++;
00677     prev_z = fp->geh.zoff;
00678     run1   = fp->geh.uv17;
00679     dz     = delta;
00680 
00681     /* scan for volume break */
00682     next = first + 2;                           /* next z to look at      */
00683     while ( (next < bound) && (fabs(dz - delta) < IFM_EPSILON) &&
00684             (run1 == run0) )
00685     {
00686         fp++;                             /* good index so get new values */
00687 
00688         dz     = fp->geh.zoff - prev_z;
00689         run1   = fp->geh.uv17;
00690         prev_z = fp->geh.zoff;
00691 
00692         next++;
00693     }
00694 
00695     /* note final image in current volume -                        */
00696     /* if we left the current volume, next is too far by 2, else 1 */
00697     if ( (fabs(dz - delta) > IFM_EPSILON) || (run1 != run0) ) last = next - 2;
00698     else                                                      last = next - 1;
00699 
00700     /* set return values */
00701     *r_first = first;
00702     *r_last  = last;
00703     *r_delta = delta;
00704 
00705     if( gD.level > 1 )
00706         fprintf(stderr,"+d cov: returning first, last, delta = %d, %d, %f\n",
00707                 first, last, delta);
00708 
00709     /* If we have found the same slice location, we are done. */
00710     if ( fabs(fp->geh.zoff - p->flist[first].geh.zoff) < IFM_EPSILON )
00711     {
00712         if ( gD.level > 1 )
00713             fprintf(stderr,"+d found first slice of second volume\n");
00714         return 1;  /* success */
00715     }
00716 
00717     /* Also, if we are still waiting for the same location, but are in
00718        state 2, then we seem to have only a single volume to read. */
00719     if ( ( state == 2 && fabs(dz-delta)<IFM_EPSILON) && run1 == run0 )
00720     {
00721         if ( gD.level > 1 )
00722             fprintf(stderr,"+d no new data after finding sufficient slices\n"
00723                            "   --> assuming completed single volume\n");
00724         return 1;
00725     }
00726     /* otherwise, if we have not changed the delta or run, continue */
00727     if ( (fabs(dz - delta) < IFM_EPSILON) && (run1 == run0) ) /* not state 2 */
00728         return 0;  /* not done yet */
00729     if ( dz * delta < 0.0 ) return -1;   /* wrong direction */
00730 
00731     /* all other cases, until we hear of a new one to watch for */
00732     return -2;
00733 }

int check_stalled_run int    run,
int    seq_num,
int    naps,
int    nap_time
[static]
 

Definition at line 3305 of file Dimon.c.

References run_t::f1name, IFM_MAX_RUN_NAPS, stats_t::nused, stats_t::nvols, stats_t::runs, and run_t::volumes.

03306 {
03307     static int func_failure =  0;
03308     static int prev_run     = -1;
03309     static int prev_seq     = -1;
03310 
03311     if ( func_failure != 0 )
03312         return 0;
03313 
03314     if ( ( run < 1 ) || ( seq_num < 1 ) || ( naps <= IFM_MAX_RUN_NAPS ) )
03315         return 0;
03316 
03317     /* verify that we have already taken note of the previous volume */
03318     if ( (((gS.nused + 1) < run) || (gS.runs[run].volumes < seq_num)) &&
03319          ( func_failure == 0 ) )
03320     {
03321         fprintf( stderr, "** warning: CSR - stats inconsistancy!\n" );
03322         func_failure = 1;
03323 
03324         return -1;
03325     }
03326 
03327     if ( seq_num < gS.nvols )      /* are we done with the run yet? */
03328     {
03329         /* if we haven't printed before, this is the first stalled case */
03330         if ( (run != prev_run) || (seq_num != prev_seq) )
03331         {
03332             fprintf( stderr, "\007\n"
03333                      "****************************************************\n"
03334                      "Warning: run seems to be stalled\n"
03335                      "\n"
03336                      "    run                    : %d\n"
03337                      "    TRs completed          : %d (of %d)\n"
03338                      "    approximate idle time  : %d seconds\n"
03339                      "    first file of this run : %s\n"
03340                      "****************************************************\n",
03341                      run, seq_num, gS.nvols,
03342                      naps*nap_time, gS.runs[run].f1name );
03343 
03344             prev_run = run;
03345             prev_seq = seq_num;
03346 
03347             return 2;
03348         }
03349     }
03350     /* else (we are done) */
03351     else if ( (run != prev_run) || (seq_num != prev_seq) )
03352     {
03353         /* this is our first visit, note the fact */
03354         prev_run = run;
03355         prev_seq = seq_num;
03356 
03357         return 1;
03358     }
03359 
03360     return 0;
03361 }

int compare_finfo const void *    v0,
const void *    v1
 

Definition at line 1342 of file Dimon.c.

References ge_header_info::index, ge_header_info::uv17, and v1.

Referenced by dicom_order_files().

01343 {
01344     ge_header_info * h0 = &((finfo_t *)v0)->geh;
01345     ge_header_info * h1 = &((finfo_t *)v1)->geh;
01346 
01347     /* check for non-DICOM files first */
01348     if     ( h1->uv17 < 0 ) return -1;
01349     else if( h0->uv17 < 0 ) return 1;
01350 
01351     /* check the run */
01352     if( h0->uv17 != h1->uv17 )
01353     {
01354         if( h0->uv17 < h1->uv17 ) return -1;
01355         return 1;
01356     }
01357 
01358     /* check the image index */
01359     if     ( h0->index < h1->index ) return -1;
01360     else if( h0->index > h1->index ) return 1;
01361 
01362     return 0;  /* equal */
01363 }

int complete_orients_str vol_t   v,
param_t   p
[static]
 

Definition at line 3504 of file Dimon.c.

References DI_MRL_orients, vol_t::fl_1, param_t::flist, param_t::ftype, vol_t::geh, IFM_IM_FTYPE_DICOM, IFM_debug::level, ge_header_info::orients, p, v, and vol_t::z_delta.

03505 {
03506     int kk;
03507 
03508     if ( (v == NULL) || (p == NULL) )
03509     {
03510         fprintf( stderr, "** invalid paramters to COS (%p,%p)\n", v, p );
03511         return -1;
03512     }
03513 
03514     if ( gD.level > 2 )
03515         fprintf(stderr,"completing orients from '%s' to", v->geh.orients);
03516 
03517     if ( p->ftype == IFM_IM_FTYPE_DICOM )
03518         strncpy(v->geh.orients + 4, DI_MRL_orients + 4, 2 );
03519     else
03520     {
03521         kk = p->flist[v->fl_1].gex.kk;
03522 
03523         switch( kk )
03524         {
03525             case 1:                                     /* LR */
03526                 if ( v->z_delta > 0 )
03527                 {
03528                     v->geh.orients[4] = 'L';
03529                     v->geh.orients[5] = 'R';
03530                 }
03531                 else
03532                 {
03533                     v->geh.orients[4] = 'R';
03534                     v->geh.orients[5] = 'L';
03535                 }
03536                 break;
03537 
03538             case 2:                                     /* PA */
03539                 if ( v->z_delta > 0 )
03540                 {
03541                     v->geh.orients[4] = 'P';
03542                     v->geh.orients[5] = 'A';
03543                 }
03544                 else
03545                 {
03546                     v->geh.orients[4] = 'A';
03547                     v->geh.orients[5] = 'P';
03548                 }
03549                 break;
03550                 
03551             case 3:                                     /* IS */
03552                 if ( v->z_delta > 0 )
03553                 {
03554                     v->geh.orients[4] = 'I';
03555                     v->geh.orients[5] = 'S';
03556                 }
03557                 else
03558                 {
03559                     v->geh.orients[4] = 'S';
03560                     v->geh.orients[5] = 'I';
03561                 }
03562                 break;
03563                 
03564             default:
03565             {
03566                 fprintf(stderr, "** COS failure: kk (%d) not in [1,3]\n", kk);
03567                 return -1;
03568             }
03569         }
03570     }
03571 
03572     v->geh.orients[6] = '\0';
03573 
03574     if ( gD.level > 2 ) fprintf(stderr,"'%s'\n", v->geh.orients);
03575                                 
03576     return 0;
03577 }

int create_gert_dicom stats_t   s,
param_t   p
[static]
 

Definition at line 3030 of file Dimon.c.

References c, param_t::fnames, IFM_GERT_DICOM, IFM_PROG_NAME, IFM_SLICE_PAT, stats_t::nused, param_t::opts, p, stats_t::runs, stats_t::slices, and opts_t::sp.

Referenced by create_gert_script().

03031 {
03032     opts_t * opts = &p->opts;
03033     FILE   * fp, * nfp;                   /* script and name file pointers */
03034     char   * script = IFM_GERT_DICOM;     /* output script filename */
03035     char   * spat;                        /* slice acquisition pattern */
03036     char     outfile[32];                 /* run files */
03037     int      num_valid, c, findex;
03038 
03039     /* if the user did not give a slice pattern string, use the default */
03040     spat = opts->sp ? opts->sp : IFM_SLICE_PAT;
03041 
03042     for ( c = 0, num_valid = 0; c < s->nused; c++ )
03043         if ( s->runs[c].volumes > 0 )
03044             num_valid++;
03045 
03046     if ( num_valid == 0 )
03047     {
03048         fprintf( stderr, "-- no runs to use for '%s'\n", script );
03049         return 0;
03050     }
03051 
03052     /* create run files, containing lists of all files in a run */
03053     for ( c = 0; c < s->nused; c++ )
03054         if ( s->runs[c].volumes > 0 )
03055         {
03056         }
03057 
03058     if ( (fp = fopen( script, "w" )) == NULL )
03059     {
03060         fprintf( stderr, "failure: cannot open '%s' for writing, "
03061                  "check permissions\n", script );
03062         return -1;
03063     }
03064 
03065     /* output text casually, uh, borrowed from Ifile.c */
03066     fprintf( fp,
03067              "#!/bin/tcsh\n"
03068              "\n"
03069              "# This script was automatically generated by '%s'.\n"
03070              "#\n"
03071              "# Please modify the following options for your own evil uses.\n"
03072              "\n"
03073              "set OutlierCheck = ''         # use '-skip_outliers' to skip\n"
03074              "set OutPrefix    = 'OutBrick' # prefix for datasets\n"
03075              "\n"
03076              "\n",
03077              IFM_PROG_NAME
03078            );
03079 
03080     for ( c = 0; c < s->nused; c++ )
03081         if ( s->runs[c].volumes > 0 )
03082         {
03083             /* create name file */
03084             sprintf(outfile, "dimon.files.run.%03d", c);
03085             if ( (nfp = fopen( outfile, "w" )) == NULL )
03086             {
03087                 fprintf( stderr, "** DF: cannot open '%s' for writing",outfile);
03088                 fclose(fp);
03089                 return -1;
03090             }
03091             /* write image filenames to file, one per line */
03092             for(findex = 0; findex < s->runs[c].volumes*s->slices; findex++)
03093                 fprintf(nfp, "%s\n", p->fnames[s->runs[c].f1index+findex]);
03094             fclose(nfp);
03095 
03096             /* and write to3d command */
03097             fprintf(fp, "to3d -prefix ${OutPrefix}_run_%03d  \\\n"
03098                         "     -time:zt %d %d 0 %s \\\n"
03099                         "     -@ < %s\n\n",
03100                     c, s->slices, s->runs[c].volumes, spat, outfile);
03101         }
03102 
03103     fclose( fp );
03104 
03105     /* now make it an executable */
03106     system( "chmod u+x " IFM_GERT_DICOM );
03107 
03108     return 0;
03109 }

int create_gert_reco stats_t   s,
opts_t   opts
[static]
 

Definition at line 3118 of file Dimon.c.

References c, opts_t::gert_outdir, IFM_GERT_SCRIPT, IFM_PROG_NAME, IFM_SLICE_PAT, IFM_SUFFIX_LEN, stats_t::nused, path_to_dir_n_suffix(), stats_t::runs, stats_t::slices, and opts_t::sp.

Referenced by create_gert_script().

03119 {
03120     FILE * fp;
03121     char * spat;                        /* slice acquisition pattern */
03122     char   cdir[4], csuff[IFM_SUFFIX_LEN];
03123     int    num_valid, c;
03124 
03125     /* if the user did not give a slice pattern string, use the default */
03126     spat = opts->sp ? opts->sp : IFM_SLICE_PAT;
03127 
03128     for ( c = 0, num_valid = 0; c < s->nused; c++ )
03129         if ( s->runs[c].volumes > 0 )
03130             num_valid++;
03131 
03132     if ( num_valid == 0 )
03133     {
03134         fprintf( stderr, "-- no runs to use for '%s'\n", IFM_GERT_SCRIPT );
03135         return 0;
03136     }
03137 
03138     if ( (fp = fopen( IFM_GERT_SCRIPT, "w" )) == NULL )
03139     {
03140         fprintf( stderr, "failure: cannot open '%s' for writing, "
03141                  "check permissions\n", IFM_GERT_SCRIPT );
03142         return -1;
03143     }
03144 
03145     /* output text casually, uh, borrowed from Ifile.c */
03146     fprintf( fp,
03147              "#!/bin/tcsh\n"
03148              "\n"
03149              "# This script was automatically generated by '%s'.\n"
03150              "# The script format was, uh, borrowed from Ziad's Ifile.c.\n"
03151              "#\n"
03152              "# Please modify the following options for your own evil uses.\n"
03153              "\n"
03154              "set OutlierCheck = '-oc'         # use '' to skip outlier check\n"
03155              "set OutPrefix    = 'OutBrick'    # prefix for datasets\n"
03156              "set OutputDir    = '-od %s'    # where to put output datasets\n"
03157              "\n"
03158              "\n",
03159              IFM_PROG_NAME,
03160              opts->gert_outdir ? opts->gert_outdir : "afni"
03161            );
03162 
03163     for ( c = 0; c < s->nused; c++ )
03164         if ( s->runs[c].volumes > 0 )
03165         {
03166             if ( path_to_dir_n_suffix(cdir, csuff, s->runs[c].f1name) < 0 )
03167             {
03168                 fclose( fp );
03169                 return -1;
03170             }
03171 
03172             fprintf( fp, "@RenamePanga %s %s %d %d $OutPrefix "
03173                          "-sp %s $OutlierCheck $OutputDir\n",
03174                      cdir, csuff, s->slices, s->runs[c].volumes, spat );
03175         }
03176 
03177     fputc( '\n', fp );
03178     fclose( fp );
03179 
03180     /* now make it an executable */
03181     system( "chmod u+x " IFM_GERT_SCRIPT );
03182 
03183     return 0;
03184 }

int create_gert_script stats_t   s,
param_t   p
[static]
 

Definition at line 3019 of file Dimon.c.

References create_gert_dicom(), create_gert_reco(), param_t::opts, p, and opts_t::use_dicom.

03020 {
03021     /* for either GEMS I-files or DICOM files */
03022     if( p->opts.use_dicom ) return create_gert_dicom(s, p);
03023     else                    return create_gert_reco (s, &p->opts);
03024 }

int dicom_order_files param_t   p [static]
 

Definition at line 1213 of file Dimon.c.

References c, calloc, compare_finfo(), param_t::fnames, free, finfo_t::index, IFM_debug::level, malloc, param_t::nfiles, p, and read_dicom_image().

Referenced by read_ge_files().

01214 {
01215     finfo_t *  flist;
01216     char    ** new_names;
01217     int        rv, bad, c, dcount;
01218     int        scount, mcount, smax;
01219 
01220     if( p->nfiles <= 0 )
01221     {
01222         fprintf(stderr,"** no DICOM files to order\n");
01223         return 0;
01224     }
01225 
01226     if( gD.level > 0 )
01227         fprintf(stderr,"-- checking %d potential DICOM files...  00%%",
01228                 p->nfiles);
01229 
01230     flist = (finfo_t *)calloc(p->nfiles, sizeof(finfo_t));
01231     if( !flist )
01232     {
01233         fprintf(stderr,"** failed to malloc %d finfo_t structs\n", p->nfiles);
01234         return -1;
01235     }
01236 
01237     /* read all files, counting DICOM files */
01238     dcount = 0;
01239     scount = mcount = 0;  /* status counters */
01240     smax = (p->nfiles+99)/100;
01241     for( c = 0; c < p->nfiles; c++ )
01242     {
01243         if( read_dicom_image(p->fnames[c], flist+c, 0) != 0 )
01244         {
01245             if( gD.level > 1 )  /* do not assume all files are DICOM */
01246                 fprintf(stderr,"** failed to read DICOM file %d of %d, '%s'\n",
01247                         c, p->nfiles, p->fnames[c]);
01248             flist[c].geh.uv17 = -1;  /* flag as non-DICOM */
01249         }
01250         else
01251             dcount++;
01252         flist[c].index = c;
01253 
01254         /* check status printing */
01255         if( mcount < smax ) mcount++;
01256         else
01257         {
01258             mcount = 0;
01259             scount++;
01260             if(gD.level>0) fprintf(stderr,"%c%c%c%c%c %3d%%",8,8,8,8,8,scount);
01261         }
01262     }
01263     if(gD.level > 0) fprintf(stderr,"%c%c%c%c%c 100%%\n",8,8,8,8,8);
01264     if(gD.level > 0) fprintf(stderr,"++ found %d DICOM files\n", dcount);
01265 
01266     if( dcount == 0 )
01267     {
01268         fprintf(stderr,"** found no DICOM files to process\n");
01269         free(flist);
01270         return -1;
01271     }
01272     /* sort the structs by geh.run/index (DICOM files first) */
01273     qsort(flist, p->nfiles, sizeof(finfo_t), compare_finfo);
01274 
01275     if( gD.level > 1 && p->nfiles > dcount )
01276        fprintf(stderr,"-d first non-DICOM file is '%s', index %d\n",
01277                p->fnames[flist[dcount].index], flist[dcount].index);
01278 
01279     /* test the sort */
01280     bad = 0;
01281     scount = 0;  /* (now) sort inversion counter */
01282     for( c = 0; c < dcount-1; c++ )
01283         if( compare_finfo((const void *)(flist+c),
01284                           (const void *)(flist+c+1)) >= 0 )
01285         {
01286             bad = 1;
01287             fprintf(stderr,"** flist sort failed for files %s, %s\n"
01288                            "   (run,index) pairs (%d,%d), (%d,%d)\n",
01289                     p->fnames[flist[c].index], p->fnames[flist[c+1].index],
01290                     flist[c  ].geh.uv17, flist[c  ].geh.index,
01291                     flist[c+1].geh.uv17, flist[c+1].geh.index);
01292         }
01293         else if( flist[c].index >= flist[c+1].index )
01294             scount++;  /* count sort inversions, say */
01295 
01296     if( bad == 1 ){ free(flist);  return -1; }
01297  
01298     /* if we don't accomplish anything, return 0, else 1 */
01299     if( scount == 0 && p->nfiles == dcount ) rv = 0;
01300     else                                     rv = 1;
01301 
01302     if(gD.level > 0)
01303     {
01304         fprintf(stderr,"-- dicom sort : %d inversions, %d non-DICOM files\n",
01305                 scount, p->nfiles-dcount);
01306         if( rv == 0 ) fprintf(stderr,"   (dicom_org unnecessary)\n");
01307         else          fprintf(stderr,"   (dicom_org was useful)\n");
01308     }
01309 
01310     /* now create a new fnames list */
01311     new_names = (char **)malloc(dcount * sizeof(char *));
01312     if( !new_names ) {
01313         fprintf(stderr,"** failed to malloc %d name ptrs\n",dcount);
01314         free(flist);
01315         return -1;
01316     }
01317 
01318     /* just grab the appropriate names, in order */
01319     for( c = 0; c < dcount; c++ )
01320         new_names[c] = p->fnames[flist[c].index];
01321     /* and lose the ones we don't want */
01322     for( ; c < p->nfiles; c++ )
01323     {
01324         if( gD.level > 2 )
01325             fprintf(stderr,"-d ignoring non-DICOM file, %s\n",
01326                     p->fnames[flist[c].index]);
01327         free(p->fnames[flist[c].index]);
01328     }
01329 
01330     /* and pull the ol' switcheroo... */
01331     free(p->fnames);
01332     p->fnames = new_names;
01333     p->nfiles = dcount;
01334 
01335     free(flist);
01336 
01337     if(gD.level > 1) fprintf(stderr,"-d dicom_org complete\n");
01338 
01339     return 0;
01340 }

int dir_expansion_form char *    sin,
char **    sexp
[static]
 

Definition at line 1824 of file Dimon.c.

References free, IFM_PAD_LEN, and malloc.

01825 {
01826     char * out;
01827     char * cp;
01828     char   d0, d1, d2;                  /* the three relevant digits */
01829     int    len;
01830 
01831     if ( (sin == NULL) || (sexp == NULL) )
01832         return -1;
01833 
01834     *sexp = NULL;
01835     len = strlen(sin);
01836 
01837     out = (char *)malloc((len + IFM_PAD_LEN) * sizeof(char));
01838     if ( out == NULL )
01839     {
01840         fprintf( stderr, "failure: dir_expansion_form malloc\n" );
01841         return -1;
01842     }
01843 
01844     *sexp = out;                        /* save resulting malloc'd address */
01845 
01846     strcpy( out,sin );
01847 
01848     cp = out + len - 1;                         /* point to end */
01849 
01850     /* we'd better find 0[01]n - ignore the rest??? */
01851     while ( (cp > (out+2)) && !isdigit( *cp ) )
01852         cp--;
01853 
01854     if ( !isdigit(*cp) )                        /* didn't find even one */
01855     {
01856         fprintf( stderr, "error: dir <%s> is not of the form 00n (e.g. 003)\n",
01857                  sin );
01858         free(out);
01859         return -1;
01860     }
01861 
01862     cp -= 2;                                    /* should be first zero  */
01863 
01864     d0 = cp[0];                                 /* note the three digits */
01865     d1 = cp[1];
01866     d2 = cp[2];
01867 
01868     if ( (d0 != '0') ||                         /* first is not a zero   */
01869          ( (d1 != '0') && (d1 != '1')) )        /* second is not 0 or 1  */
01870     {
01871         fprintf( stderr, "error: dir <%s> is not of the form 0[01]n"
01872                          " (e.g. 003)\n", sin );
01873         free(out);
01874         return -1;
01875     }
01876 
01877     /* woohooo!  we're good to go! */
01878     /* set to "...[0-9][02468]n/I.*" (or with [13579]) */
01879 
01880     strcpy( cp, "[0-9]" );                      /* add and skip "[0-9]" */
01881     cp += strlen( "[0-9]" );
01882 
01883     if ( d1 == '0' )                            /* adding 2 to each     */
01884         strcpy( cp, "[02468]" );
01885     else
01886         strcpy( cp, "[13579]" );
01887     cp += strlen( "[02468]" );
01888 
01889     *cp++ = d2;                                 /* insert final digit */
01890 
01891     /* allow either I.* or i.*  - v2.11 */
01892     strcpy( cp, "/[Ii].*" );                    /* the big finish */
01893 
01894     return 0;
01895 }

int disp_ftype char *    info,
int    ftype
[static]
 

Definition at line 2312 of file Dimon.c.

References IFM_IM_FTYPE_DICOM, and IFM_IM_FTYPE_GEMS5.

Referenced by find_first_volume().

02313 {
02314     if ( info ) fputs(info, stdout);
02315 
02316     switch( ftype )
02317     {
02318         case IFM_IM_FTYPE_GEMS5:
02319             printf("GEMS 5.x\n");
02320             break;
02321 
02322         case IFM_IM_FTYPE_DICOM:
02323             printf("DICOM\n");
02324             break;
02325 
02326         default:
02327             printf("UNKNOWN (%d)\n", ftype);
02328             break;
02329     }
02330 
02331     fflush(stdout);
02332 
02333     return 0;
02334 }

int empty_string_list string_list   list,
int    free_mem
[static]
 

Definition at line 3762 of file Dimon.c.

References free, string_list::nalloc, string_list::nused, and string_list::str.

03763 {
03764     if ( list->str && free_mem )
03765         free( list->str );
03766 
03767     list->str    = NULL;
03768     list->nalloc = 0;
03769     list->nused  = 0;
03770 
03771     return 0;
03772 }

int find_first_volume vol_t   v,
param_t   p,
ART_comm   ac
[static]
 

Definition at line 200 of file Dimon.c.

References ART_idisp_ART_comm(), ART_open_afni_link(), ART_send_control_info(), ART_send_volume(), ART_STATE_IN_USE, ART_STATE_TO_OPEN, ART_STATE_TO_SEND_CTRL, ART_comm::byte_order, check_im_byte_order(), complete_orients_str(), disp_ftype(), param_t::flist, param_t::ftype, idisp_im_store_t(), idisp_param_t(), idisp_vol_t(), IFM_MAX_IM_ALLOC, param_t::im_store, IFM_debug::level, param_t::nalloc, nap_time_from_tr(), vol_t::nim, param_t::nused, p, read_ge_files(), realloc, ART_comm::state, v, and volume_search().

00201 {
00202     int max_im_alloc = IFM_MAX_IM_ALLOC;
00203     int ret_val;
00204     int sleep_secs = -1; /* has not been set from data yet */
00205     int vs_state = 0;    /* state for volume search, can reset */
00206     int fl_start = 0;    /* starting offset into the current flist */
00207 
00208     if ( gD.level > 0 )                 /* status */
00209         fprintf( stderr, "-- scanning for first volume\n" );
00210 
00211     ret_val = 0;
00212     while ( ret_val == 0 )
00213     {
00214         ret_val = read_ge_files( p, fl_start, max_im_alloc );
00215 
00216         if ( ret_val > 0 )
00217         {
00218             ret_val = volume_search( v, p, 0, 0, &fl_start, &vs_state );
00219 
00220             /* try to recover from a data error */
00221             if ( ret_val == -1 ) ret_val = 0;
00222 
00223             /* If we don't have a volume yet, but have used "too much" of our
00224              * available memory, request more, making sure there is enough for
00225              * a volume, despite the previous max_im_alloc limitation.  */
00226             if ( (ret_val == 0) && (p->nused > (max_im_alloc / 2)) )
00227                 max_im_alloc *= 2;
00228         }
00229 
00230         if ( ret_val == 0 )                     /* we are not done yet */
00231         {
00232             if ( gD.level > 0 ) fprintf( stderr, "." );   /* status    */
00233 
00234             /* try to update nap time */
00235             if( sleep_secs < 0 && p->nused > 0 )
00236                 sleep_secs = nap_time_from_tr(p->flist->geh.tr);
00237 
00238             if( sleep_secs < 0 ) sleep( 4 );              /* nap time! */
00239             else                 sleep(sleep_secs);
00240         }
00241         else if ( ret_val > 0 )         /* success - we have a volume! */
00242         {
00243             if ( gD.level > 0 )
00244             {
00245                 fprintf( stderr, "\n-- first volume found\n" );
00246                 if ( gD.level > 1 )
00247                 {
00248                     idisp_vol_t( "+d first volume : ", v );
00249                     idisp_param_t( "-d first vol - new params : ", p );
00250                     disp_ftype("-d ftype: ", p->ftype);
00251                 }
00252             }
00253 
00254             /* make sure there is enough memory for bad volumes */
00255             if ( p->nalloc < (4 * v->nim) )
00256             {
00257                 p->nalloc = 4 * v->nim;
00258                 p->flist = (finfo_t *)realloc( p->flist,
00259                                                p->nalloc*sizeof(finfo_t) );
00260                 if ( p->flist == NULL )
00261                 {
00262                     fprintf( stderr, "** FFV: failure to allocate %d finfo_t "
00263                                      "structs!\n", p->nalloc );
00264                     return -1;
00265                 }
00266 
00267                 if ( gD.level > 1 )
00268                     idisp_param_t( "++ final realloc of flist : ", p );
00269             }
00270 
00271             /* use this volume to complete the geh.orients string */
00272             if ( complete_orients_str( v, p ) < 0 )
00273                 return -1;
00274 
00275             /* use this volume to note the byte order of image data */
00276             if ( check_im_byte_order( &ac->byte_order, v, p ) < 0 )
00277                 return -1;
00278 
00279             /* if wanted, verify afni link, send image info and first volume */
00280             if ( ac->state == ART_STATE_TO_OPEN )
00281                 ART_open_afni_link( ac, 5, 0, gD.level );
00282 
00283             if ( ac->state == ART_STATE_TO_SEND_CTRL )
00284                 ART_send_control_info( ac, v, gD.level );
00285 
00286             if ( ac->state == ART_STATE_IN_USE )
00287                 ART_send_volume( ac, v, gD.level );
00288 
00289             if ( gD.level > 1 )
00290             {
00291                 ART_idisp_ART_comm( "-- first vol ", ac );
00292                 idisp_im_store_t( "-- first vol ", &p->im_store );
00293             }
00294         }
00295         else
00296             return ret_val;             /* fatal error condition */
00297     }
00298 
00299     if ( ret_val > 0 )
00300         return 0;
00301     else
00302         return ret_val;
00303 }

int find_fl_file_index param_t   p [static]
 

Definition at line 3589 of file Dimon.c.

References param_t::fnames, IFM_debug::level, param_t::nfiles, param_t::opts, p, opts_t::start_dir, and opts_t::start_file.

03590 {
03591     char ** nlp;
03592     char  * sd, * sf;
03593     int     index, found = 0;
03594     int     dlen;
03595 
03596     if ( ! p || (! p->opts.start_file && ! p->opts.start_dir) )
03597         return 0;
03598 
03599     sd = p->opts.start_dir;
03600     sf = p->opts.start_file;
03601 
03602     if ( gD.level > 2 )
03603         fprintf(stderr,"-d searching for initial dir, file: %s, %s\n",
03604                 sd ? sd : "<no start_dir>", sf ? sf : "<no start_file>");
03605 
03606     index = 0;       /* init search params */
03607     nlp = p->fnames;
03608 
03609     if ( sd )
03610     {
03611         dlen = strlen(sd);
03612         for ( ; index < p->nfiles; index++, nlp++ )
03613             if ( ! strncmp(*nlp, sd, dlen) ) { found = 1; break; }
03614     }
03615 
03616     if ( sf )  /* then further continue the search until the file is found */
03617     {
03618         found = 0;
03619         for ( ; index < p->nfiles; index++, nlp++ )
03620             if ( ! strcmp(*nlp, sf) ) { found = 1; break; }
03621     }
03622 
03623     if ( gD.level > 2 )
03624     {
03625         if(found) fprintf(stderr,"-d found match at entry %d: %s\n",index,*nlp);
03626         else      fprintf(stderr,"-d no match found (yet)...\n");
03627     }
03628 
03629     if ( found ) return index;
03630     else         return -1;
03631 }

int find_more_volumes vol_t   v,
param_t   p,
ART_comm   ac
[static]
 

Definition at line 315 of file Dimon.c.

References ART_send_control_info(), ART_send_end_of_run(), ART_send_volume(), ART_STATE_IN_USE, ART_STATE_TO_SEND_CTRL, check_stalled_run(), complete_orients_str(), vol_t::fn_n, vol_t::geh, hf_signal(), idisp_vol_t(), iochan_sleep(), IFM_debug::level, param_t::nalloc, nap_time_from_tr(), vol_t::nim, param_t::opts, p, opts_t::pause, opts_t::quit, read_ge_files(), vol_t::run, vol_t::seq_num, set_volume_stats(), show_run_stats(), SIGHUP, SIGQUIT, ART_comm::state, ge_header_info::tr, and volume_match().

00316 {
00317     vol_t vn;
00318     int   ret_val, done;
00319     int   run, seq_num, next_im;
00320     int   fl_index;                     /* current index into p->flist    */
00321     int   naps;                         /* keep track of consecutive naps */
00322     int   nap_time;                     /* sleep time, in seconds         */
00323 
00324     if ( v0 == NULL || p == NULL )
00325     {
00326         fprintf( stderr, "error: IFM:FMV() lacking parameters\n" );
00327         return -1;
00328     }
00329 
00330     done     = 0;
00331     naps     = 0;
00332 
00333     run      = v0->run;
00334     seq_num  = v0->seq_num = 1;         /* set first seq_num to 1 */
00335     fl_index = v0->fn_n + 1;            /* start looking past first volume */
00336     next_im  = v0->fn_n + 1;            /* for read_ge_files()             */
00337 
00338     nap_time = nap_time_from_tr( v0->geh.tr );
00339 
00340     if ( gD.level > 0 )                 /* status */
00341     {
00342         fprintf( stderr, "-- scanning for additional volumes...\n" );
00343         fprintf( stderr, "-- run %d: %d ", run, seq_num );
00344     }
00345 
00346     /* give stats when user quits */
00347     signal( SIGHUP,  hf_signal );
00348     signal( SIGINT,  hf_signal );
00349     signal( SIGQUIT,  hf_signal );
00350     signal( SIGTRAP,  hf_signal );
00351     signal( SIGABRT,  hf_signal );
00352     signal( SIGTERM, hf_signal );
00353     signal( SIGSEGV,  hf_signal );
00354 
00355     if ( set_volume_stats( p, &gS, v0 ) )
00356         return -1;
00357 
00358     while ( ! done )
00359     {
00360         /* check all of the volumes we've already scanned in */
00361         ret_val = 1;
00362         while ( (ret_val == 1) || (ret_val == -1) )
00363         {
00364             ret_val = volume_match( v0, &vn, p, fl_index );
00365 
00366             if ( ret_val < -1 )                 /* bail out on fatal error */
00367                 return ret_val;
00368 
00369             if ( (ret_val == 1) || (ret_val == -1) )
00370             {
00371                 if ( gD.level > 2 )
00372                     idisp_vol_t( "-- new volume: ", &vn );
00373 
00374                 fl_index += vn.nim;             /* note the new position   */
00375                 next_im   = vn.fn_n + 1;        /* for read_ge_files()     */
00376 
00377                 if ( vn.run != run )            /* new run?                */
00378                 {
00379                     /* pass run and seq_num before they are updated */
00380                     if ( ac->state == ART_STATE_IN_USE )
00381                         ART_send_end_of_run( ac, run, seq_num, gD.level );
00382 
00383                     run = vn.run;               /* reset                   */
00384                     seq_num = 1;
00385 
00386                     if ( gD.level > 0 )
00387                         fprintf( stderr, "\n-- run %d: %d ", run, seq_num );
00388                 }
00389                 else
00390                 {
00391                     seq_num++;
00392 
00393                     if ( gD.level > 0 )
00394                         fprintf( stderr, "%d ", seq_num );
00395                 }
00396 
00397                 vn.seq_num = seq_num;
00398 
00399                 if ( set_volume_stats( p, &gS, &vn ) )
00400                     return -1;
00401 
00402                 if ( complete_orients_str( &vn, p ) < 0 )
00403                     return -1;
00404 
00405                 if ( ac->state == ART_STATE_TO_SEND_CTRL )
00406                     ART_send_control_info( ac, &vn, gD.level );
00407 
00408                 /* only send good volumes to afni   - 2003.03.10 */
00409                 if ( (ac->state == ART_STATE_IN_USE) && (ret_val == 1) )
00410                     ART_send_volume( ac, &vn, gD.level );
00411 
00412                 naps = 0;                       /* reset on existing volume */
00413 
00414                 if( p->opts.pause > 0 ) iochan_sleep(p->opts.pause);
00415             }
00416         }
00417 
00418         /* now we need new data - skip past last file name index */
00419 
00420         ret_val = read_ge_files( p, next_im, p->nalloc );
00421         fl_index = 0;                   /* reset flist index          */
00422 
00423         while ( (ret_val >= 0 ) &&      /* no fatal error, and        */
00424                 (ret_val < v0->nim) )   /* didn't see full volume yet */
00425         {
00426             if ( naps > 0 )
00427             {
00428                 if ( p->opts.quit )     /* then we are outta here */
00429                 {
00430                     if ( ac->state == ART_STATE_IN_USE )
00431                         ART_send_end_of_run( ac, run, seq_num, gD.level );
00432 
00433                     show_run_stats( &gS );
00434                     return 0;
00435                 }
00436 
00437                 /* continue, regardless */
00438                 if ( check_stalled_run( run, seq_num, naps, nap_time ) > 0 )
00439                     if ( ac->state == ART_STATE_IN_USE )
00440                         ART_send_end_of_run( ac, run, seq_num, gD.level );
00441 
00442                 if ( gD.level > 0 )     /* status */
00443                     fprintf( stderr, ". " );
00444             }
00445 
00446             sleep( nap_time );          /* wake after a couple of TRs */
00447             naps ++;
00448 
00449             ret_val = read_ge_files( p, next_im, p->nalloc );
00450         }
00451 
00452         if ( ret_val < 0 )              /* aaaaagh!  panic!  wet pants! */
00453         {
00454             fprintf( stderr, "\n** failure: IFM:RGF fatal error\n" );
00455             return -1;
00456         }
00457     }
00458 
00459     return 0;   /* success */
00460 }

int find_next_zoff param_t   p,
int    start,
float    zoff
[static]
 

Definition at line 3269 of file Dimon.c.

References param_t::flist, IFM_EPSILON, param_t::nused, and p.

03270 {
03271     int count;
03272 
03273     if ( (p == NULL) || (start < 0) )
03274         return -2;
03275 
03276     if ( start > p->nused )                     /* say not found */
03277         return -1;
03278 
03279     for ( count = start; count <= p->nused; count++ )
03280         if ( fabs( zoff - p->flist[count].geh.zoff ) < IFM_EPSILON )
03281             return count;                       /* found! */
03282 
03283     return -1;
03284 }

void hf_signal int    signum [static]
 

Definition at line 2896 of file Dimon.c.

References ART_exit(), ART_STATE_NO_USE, IFM_debug::level, show_run_stats(), SIGHUP, and ART_comm::state.

Referenced by find_more_volumes().

02897 {
02898     switch ( signum )
02899     {
02900         default :
02901             fprintf( stderr, "\nError: received unknown signal, %d\n",
02902                      signum );
02903             break;
02904 
02905         case SIGHUP  :
02906         case SIGINT  :
02907         case SIGTERM :
02908             show_run_stats( &gS );
02909             break;
02910     }
02911 
02912     if(gD.level > 1) fprintf(stderr, "\n+d received signal, %d\n", signum);
02913 
02914     if( gAC.state != ART_STATE_NO_USE )
02915     {
02916         if( gD.level > 1 )
02917             fprintf(stderr,"-d closing afni connection, state %d\n", gAC.state);
02918         ART_exit();
02919     }
02920 
02921     fflush(stderr);  /* in case it is redirected */
02922     fflush(stdout);
02923 
02924     exit(0);
02925 }

int idisp_ge_extras char *    info,
ge_extras   E
[static]
 

Definition at line 2376 of file Dimon.c.

References ge_extras::bpp, ge_extras::cflag, E, ge_extras::hdroff, ge_extras::kk, ge_extras::skip, ge_extras::swap, ge_extras::xorg, ge_extras::xyz, and ge_extras::yorg.

02377 {
02378     if ( info )
02379         fputs( info, stdout );
02380 
02381     if ( E == NULL )
02382     {
02383         printf( "idisp_ge_extras: E == NULL\n" );
02384         return -1;
02385     }
02386 
02387     printf( "ge_extras at %p :\n"
02388             "    bpp              = %d\n"
02389             "    cflag            = %d\n"
02390             "    hdroff           = %d\n"
02391             "    skip             = %d\n"
02392             "    swap             = %d\n"
02393             "    kk               = %d\n"
02394             "    xorg             = %f\n"
02395             "    yorg             = %f\n"
02396             "    (xyz0,xyz1,xyz2) = (%f,%f,%f)\n"
02397             "    (xyz3,xyz4,xyz5) = (%f,%f,%f)\n"
02398             "    (xyz6,xyz7,xyz8) = (%f,%f,%f)\n",
02399             E, E->bpp, E->cflag, E->hdroff, E->skip, E->swap, E->kk,
02400             E->xorg,   E->yorg,
02401             E->xyz[0], E->xyz[1], E->xyz[2],
02402             E->xyz[3], E->xyz[4], E->xyz[5],
02403             E->xyz[6], E->xyz[7], E->xyz[8]
02404           );
02405     return 0;
02406 }

int idisp_ge_header_info char *    info,
ge_header_info   I
[static]
 

Definition at line 2413 of file Dimon.c.

References ge_header_info::dx, ge_header_info::dy, ge_header_info::dz, ge_header_info::good, ge_header_info::index, ge_header_info::nx, ge_header_info::ny, ge_header_info::orients, ge_header_info::te, ge_header_info::tr, ge_header_info::uv17, and ge_header_info::zoff.

02414 {
02415     if ( info )
02416         fputs( info, stdout );
02417 
02418     if ( I == NULL )
02419     {
02420         printf( "idisp_ge_header_info: I == NULL\n" );
02421         return -1;
02422     }
02423 
02424     printf( "ge_header_info at %p :\n"
02425             "    good        = %d\n"
02426             "    (nx,ny)     = (%d,%d)\n"
02427             "    uv17        = %d\n"
02428             "    index        = %d\n"
02429             "    (dx,dy,dz)  = (%f,%f,%f)\n"
02430             "    zoff        = %f\n"
02431             "    (tr,te)     = (%f,%f)\n"
02432             "    orients     = %-8s\n",
02433             I, I->good, I->nx, I->ny, I->uv17, I->index,
02434             I->dx, I->dy, I->dz, I->zoff, I->tr, I->te,
02435             CHECK_NULL_STR(I->orients)
02436           );
02437 
02438     return 0;
02439 }

int idisp_im_store_t char *    info,
im_store_t   is
[static]
 

Definition at line 2207 of file Dimon.c.

References im_store_t::ary_len, im_store_t::im_ary, im_store_t::im_size, im_store_t::nalloc, im_store_t::nused, and im_store_t::x_im.

02208 {
02209     if ( info )
02210         fputs( info, stdout );
02211 
02212     if ( is == NULL )
02213     {
02214         printf( "idisp_im_store_t: is == NULL\n" );
02215         return -1;
02216     }
02217 
02218     printf( "im_store_t struct at %p :\n"
02219             "   (nalloc, nused)    = (%d, %d)\n"
02220             "   (ary_len, im_size) = (%d, %d)\n"
02221             "   (im_ary, x_im)     = (%p, %p)\n",
02222             is, is->nalloc, is->nused,
02223             is->ary_len, is->im_size, is->im_ary, is->x_im );
02224 
02225     return 0;
02226 }

int idisp_opts_t char *    info,
opts_t   opt
[static]
 

Definition at line 2263 of file Dimon.c.

References opts_t::argc, opts_t::argv, CHECK_NULL_STR, opts_t::debug, opts_t::dicom_glob, opts_t::drive_list, opts_t::gert_outdir, opts_t::gert_reco, opts_t::host, string_list::nalloc, opts_t::nice, opts_t::nt, string_list::nused, opts_t::pause, opts_t::quit, opts_t::rev_bo, opts_t::rt, opts_t::rt_list, opts_t::sp, opts_t::start_dir, opts_t::start_file, string_list::str, opts_t::swap, and opts_t::use_dicom.

Referenced by init_options().

02264 {
02265     if ( info )
02266         fputs( info, stdout );
02267 
02268     if ( opt == NULL )
02269     {
02270         printf( "idisp_opts_t: opt == NULL\n" );
02271         return -1;
02272     }
02273 
02274     printf( "opts_t struct at %p :\n"
02275             "   start_file         = %s\n"
02276             "   start_dir          = %s\n"
02277             "   dicom_glob         = %s\n"
02278             "   sp                 = %s\n"
02279             "   gert_outdir        = %s\n"
02280             "   (argv, argc)       = (%p, %d)\n"
02281             "   (nt, nice)         = (%d, %d)\n"
02282             "   pause              = %d\n"
02283             "   (debug, gert_reco) = (%d, %d)\n"
02284             "   use_dicom, quit    = %d, %d\n"
02285             "   (rt, swap, rev_bo) = (%d, %d, %d)\n"
02286             "   host               = %s\n"
02287             "   drive_list(u,a,p)  = %d, %d, %p\n"
02288             "   rt_list   (u,a,p)  = %d, %d, %p\n",
02289             opt,
02290             CHECK_NULL_STR(opt->start_file),
02291             CHECK_NULL_STR(opt->start_dir),
02292             CHECK_NULL_STR(opt->dicom_glob),
02293             CHECK_NULL_STR(opt->sp),
02294             CHECK_NULL_STR(opt->gert_outdir),
02295             opt->argv, opt->argc,
02296             opt->nt, opt->nice, opt->pause,
02297             opt->debug, opt->gert_reco, opt->use_dicom, opt->quit,
02298             opt->rt, opt->swap, opt->rev_bo,
02299             CHECK_NULL_STR(opt->host),
02300             opt->drive_list.nused, opt->drive_list.nalloc, opt->drive_list.str,
02301             opt->rt_list.nused, opt->rt_list.nalloc, opt->rt_list.str
02302             );
02303 
02304     return 0;
02305 }

int idisp_param_t char *    info,
param_t   p
[static]
 

Definition at line 2233 of file Dimon.c.

References param_t::flist, param_t::fnames, param_t::ftype, param_t::glob_dir, param_t::nalloc, param_t::nfiles, param_t::nused, and p.

Referenced by find_first_volume(), init_options(), and read_ge_files().

02234 {
02235     if ( info )
02236         fputs( info, stdout );
02237 
02238     if ( p == NULL )
02239     {
02240         printf( "idisp_param_t: p == NULL\n" );
02241         return -1;
02242     }
02243 
02244     printf( "param_t struct at %p :\n"
02245             "   ftype             = %d\n"
02246             "   (nused, nalloc)   = (%d, %d)\n"
02247             "   flist             = %p\n"
02248             "   glob_dir          = %s\n"
02249             "   nfiles            = %d\n"
02250             "   fnames            = %p\n",
02251             p, p->ftype, p->nused, p->nalloc, p->flist,
02252             CHECK_NULL_STR(p->glob_dir),
02253             p->nfiles, p->fnames );
02254 
02255     return 0;
02256 }

int idisp_vol_t char *    info,
vol_t   v
[static]
 

Definition at line 2340 of file Dimon.c.

References vol_t::first_file, vol_t::fl_1, vol_t::fn_1, vol_t::fn_n, vol_t::geh, vol_t::gex, idisp_ge_extras(), idisp_ge_header_info(), vol_t::last_file, vol_t::nim, vol_t::run, vol_t::seq_num, v, vol_t::z_delta, vol_t::z_first, and vol_t::z_last.

Referenced by find_first_volume(), find_more_volumes(), and set_volume_stats().

02341 {
02342     if ( info )
02343         fputs( info, stdout );
02344 
02345     if ( v == NULL )
02346     {
02347         printf( "idisp_vol_t: v == NULL\n" );
02348         return -1;
02349     }
02350 
02351     printf( "vol_t struct at %p :\n"
02352             "   nim                 = %d\n"
02353             "   (fl_1, fn_1, fn_n)  = (%d, %d, %d)\n"
02354             "   first_file          = %s\n"
02355             "   last_file           = %s\n"
02356             "   (z_first, z_last)   = (%f, %f)\n"
02357             "   z_delta             = %f\n"
02358             "   (seq_num, run)      = (%d, %d)\n",
02359             v, v->nim, v->fl_1, v->fn_1, v->fn_n,
02360             v->first_file, v->last_file,
02361             v->z_first, v->z_last, v->z_delta,
02362             v->seq_num, v->run );
02363 
02364     idisp_ge_header_info( info, &v->geh );
02365     idisp_ge_extras( info, &v->gex );
02366 
02367     return 0;
02368 }

int init_extras param_t   p,
ART_comm   ac
[static]
 

Definition at line 1745 of file Dimon.c.

References ART_open_afni_link(), ART_STATE_TO_OPEN, atexit(), param_t::glob_dir, IFM_debug::level, ART_comm::mode, opts_t::nice, param_t::opts, p, set_nice_level(), opts_t::start_dir, opts_t::start_file, ART_comm::state, and str_char_count().

01746 {
01747     if ( p->opts.nice && set_nice_level(p->opts.nice) )
01748         return 1;
01749 
01750     if ( ac->state == ART_STATE_TO_OPEN )            /* open afni comm link */
01751     {
01752         atexit( ART_exit );
01753         ac->mode = AFNI_OPEN_CONTROL_MODE;
01754         ART_open_afni_link( ac, 2, 1, gD.level );
01755     }
01756     
01757     /* check directory depth of start_file against glob_dir */
01758     if ( p->opts.start_file != NULL )
01759     {
01760         char * sf     = p->opts.start_file;
01761         char * gd     = p->glob_dir;
01762         int    flevel = str_char_count( sf, strlen(sf), (char)'/' );
01763 
01764         /* check whether the number of slashes match */
01765         if ( flevel != str_char_count( gd, strlen(gd), (char)'/' ) )
01766         {
01767             fprintf( stderr,
01768                      "** warning : relative path to       : '-start_dir  %s'\n"
01769                      "             does not seem to match : '-start_file %s'\n"
01770                      "             (so 'start_file' may never be found)\n\n",
01771                      p->opts.start_file, p->opts.start_dir );
01772         }
01773         else if ( gD.level > 1 )
01774             fprintf( stderr, "-- '-start_file %s' and\n"
01775                              "   '-start_dir  %s' match at dir level %d\n",
01776                              p->opts.start_file, p->opts.start_dir, flevel );
01777     }
01778 
01779     return 0;
01780 }

int init_options param_t   p,
ART_comm   a,
int    argc,
char *    argv[]
[static]
 

Definition at line 1373 of file Dimon.c.

References add_to_string_list(), opts_t::argc, argc, opts_t::argv, ART_init_AC_struct(), ART_NAME_LEN, ART_STATE_TO_OPEN, calloc, opts_t::debug, opts_t::dicom_glob, opts_t::dicom_org, dir_expansion_form(), opts_t::drive_list, empty_string_list(), param_t::ftype, opts_t::gert_outdir, opts_t::gert_reco, param_t::glob_dir, ART_comm::host, opts_t::host, idisp_opts_t(), idisp_param_t(), IFM_DEBUG_DEFAULT, IFM_IM_FTYPE_DICOM, IFM_IM_FTYPE_GEMS5, IFM_MAX_DEBUG, IFM_MAX_NICE_INC, IFM_MAX_NT, IFM_MIN_NICE_INC, IFM_PROG_NAME, IFM_USE_HIST, IFM_USE_LONG, IFM_USE_SHORT, IFM_USE_VERSION, IFM_debug::level, opts_t::nice, opts_t::nt, param_t::opts, p, ART_comm::param, opts_t::pause, opts_t::quit, opts_t::rev_bo, rglob_set_sort_dir(), opts_t::rt, opts_t::rt_list, opts_t::sp, opts_t::start_dir, opts_t::start_file, ART_comm::state, opts_t::swap, ART_comm::swap, usage(), opts_t::use_dicom, and ART_comm::zorder.

01374 {
01375     int ac, errors = 0;
01376 
01377     if ( p == NULL )
01378         return 2;
01379 
01380     if ( argc < 2 )
01381     {
01382         usage( IFM_PROG_NAME, IFM_USE_SHORT );
01383         return 1;
01384     }
01385 
01386     /* basic initialization of data structures */
01387 
01388     memset(  p,  0, sizeof(*p)  );      /* parameters       */
01389     memset( &gD, 0, sizeof(gD)  );      /* debug struct     */
01390     memset( &gS, 0, sizeof(gS)  );      /* stats struct     */
01391     memset(  A,  0, sizeof(gAC) );      /* afni comm struct */
01392 
01393     ART_init_AC_struct( A );            /* init for no real-time comm */
01394     A->param = p;                       /* store the param_t pointer  */
01395     p->opts.use_dicom = 1;              /* will delete this later...  */
01396 
01397     empty_string_list( &p->opts.drive_list, 0 );
01398     empty_string_list( &p->opts.rt_list, 0 );
01399 
01400     /* debug level 1 is now the default - by order of Wen-Ming :) */
01401     gD.level = 1;
01402 
01403     for ( ac = 1; ac < argc; ac++ )
01404     {
01405         if ( ! strncmp( argv[ac], "-debug", 4 ) )
01406         {
01407             if ( ++ac >= argc )
01408             {
01409                 fputs( "option usage: -debug LEVEL\n", stderr );
01410                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01411                 return 1;
01412             }
01413 
01414             p->opts.debug = atoi(argv[ac]);
01415             gD.level      = p->opts.debug;
01416             if ( gD.level < 0 || gD.level > IFM_MAX_DEBUG )
01417             {
01418                 fprintf( stderr, "error: debug level must be in [0,%d]\n",
01419                          IFM_MAX_DEBUG );
01420                 errors++;
01421             }
01422         }
01423         else if ( ! strncmp( argv[ac], "-dicom_org", 10 ) )
01424         {
01425             p->opts.dicom_org = 1;
01426         }
01427         else if ( ! strncmp( argv[ac], "-GERT_Reco", 7 ) )
01428         {
01429             p->opts.gert_reco = 1;      /* output script at the end */
01430         }
01431         else if ( ! strncmp( argv[ac], "-help", 5 ) )
01432         {
01433             usage( IFM_PROG_NAME, IFM_USE_LONG );
01434             return 1;
01435         }
01436         else if ( ! strncmp( argv[ac], "-hist", 5 ) )
01437         {
01438             usage( IFM_PROG_NAME, IFM_USE_HIST );
01439             return 1;
01440         }
01441         else if ( ! strncmp( argv[ac], "-infile_pattern", 11 ) ||
01442                   ! strncmp( argv[ac], "-dicom_glob", 9 ) )
01443         {
01444             if ( ++ac >= argc )
01445             {
01446                 fputs( "option usage: -infile_pattern FILE_PATTERN\n", stderr );
01447                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01448                 return 1;
01449             }
01450 
01451             p->opts.dicom_glob = argv[ac];
01452         }
01453         else if ( ! strncmp( argv[ac], "-infile_prefix", 11 ) )
01454         {
01455             if ( ++ac >= argc )
01456             {
01457                 fputs( "option usage: -infile_prefix FILE_PREFIX\n", stderr );
01458                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01459                 return 1;
01460             }
01461             /* just append a '*' to the PREFIX */
01462             p->opts.dicom_glob = calloc(strlen(argv[ac])+2, sizeof(char));
01463             strcpy(p->opts.dicom_glob, argv[ac]);
01464             strcat(p->opts.dicom_glob, "*");
01465         }
01466         else if ( ! strncmp( argv[ac], "-nice", 4 ) )
01467         {
01468             if ( ++ac >= argc )
01469             {
01470                 fputs( "option usage: -nice INCREMENT\n", stderr );
01471                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01472                 return 1;
01473             }
01474 
01475             p->opts.nice = atoi(argv[ac]);
01476             if ( (p->opts.nice < IFM_MIN_NICE_INC) ||
01477                  (p->opts.nice > IFM_MAX_NICE_INC) )
01478             {
01479                 fprintf( stderr, "error: nice incrment must be in [%d,%d]\n",
01480                          IFM_MIN_NICE_INC, IFM_MAX_NICE_INC );
01481                 errors++;
01482             }
01483         }
01484         else if ( ! strncmp( argv[ac], "-nt", 3 ) )
01485         {
01486             if ( ++ac >= argc )
01487             {
01488                 fputs( "option usage: -nt VOLUMES_PER_RUN\n", stderr );
01489                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01490                 return 1;
01491             }
01492 
01493             p->opts.nt = atoi(argv[ac]);
01494             if ( p->opts.nt < 0 || p->opts.nt > IFM_MAX_NT )
01495             {
01496                 fprintf( stderr,
01497                     "option usage: -nt VOLUMES_PER_RUN\n"
01498                     "       error: VOLUMES_PER_RUN must be in [%d,%d]\n",
01499                     0, IFM_MAX_NT );
01500                 errors++;
01501             }
01502         }
01503         else if ( ! strncmp( argv[ac], "-od", 3 ) ||
01504                   ! strncmp( argv[ac], "-gert_outdir", 9 ) )
01505         {
01506             if ( ++ac >= argc )
01507             {
01508                 fputs( "option usage: -gert_outdir OUTPUT_DIR\n", stderr );
01509                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01510                 return 1;
01511             }
01512 
01513             p->opts.gert_outdir = argv[ac];
01514         }
01515         else if ( ! strncmp( argv[ac], "-pause", 6 ) )
01516         {
01517             if ( ++ac >= argc )
01518             {
01519                 fputs( "option usage: -pause milliseconds\n", stderr );
01520                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01521                 return 1;
01522             }
01523 
01524             p->opts.pause = atoi(argv[ac]);
01525             if ( p->opts.pause < 0 )
01526             {
01527                 fprintf(stderr,"** illegal -pause time: %s\n",argv[ac]);
01528                 errors++;
01529             }
01530         }
01531         else if ( ! strncmp( argv[ac], "-quiet", 6 ) )
01532         {
01533             /* only go quiet if '-debug' option has not changed it */
01534             if ( gD.level == IFM_DEBUG_DEFAULT )
01535                 gD.level = 0;
01536         }
01537         else if ( ! strncmp( argv[ac], "-quit", 5 ) )
01538         {
01539             p->opts.quit = 1;
01540         }
01541         else if ( ! strncmp( argv[ac], "-sp", 3 ) )
01542         {
01543             if ( ++ac >= argc )
01544             {
01545                 fputs( "option usage: -sp PATTERN\n", stderr );
01546                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01547                 return 1;
01548             }
01549 
01550             p->opts.sp = argv[ac];
01551         }
01552         else if ( ! strncmp( argv[ac], "-start_dir", 8 ) )
01553         {
01554             if ( ++ac >= argc )
01555             {
01556                 fputs( "option usage: -start_dir DIRECTORY\n", stderr );
01557                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01558                 return 1;
01559             }
01560 
01561             p->opts.start_dir = argv[ac];
01562         }
01563         else if ( ! strncmp( argv[ac], "-start_file", 8 ) )
01564         {
01565             if ( ++ac >= argc )
01566             {
01567                 fputs( "option usage: -start_file DIR/FIRST_FILE\n", stderr );
01568                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01569                 return 1;
01570             }
01571 
01572             p->opts.start_file = argv[ac];
01573         }
01574         else if ( ! strncmp( argv[ac], "-version", 2 ) )
01575         {
01576             usage( IFM_PROG_NAME, IFM_USE_VERSION );
01577             return 1;
01578         }
01579         /* real-time options */
01580         else if ( ! strncmp( argv[ac], "-drive_afni", 6 ) )
01581         {
01582             if ( ++ac >= argc )
01583             {
01584                 fputs( "option usage: -drive_afni COMMAND\n", stderr );
01585                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01586                 return 1;
01587             }
01588 
01589             if ( add_to_string_list( &p->opts.drive_list, argv[ac] ) != 0 )
01590             {
01591                 fprintf(stderr,"** failed add '%s' to drive_list\n",argv[ac]);
01592                 return 1;
01593             }
01594         }
01595         else if ( ! strncmp( argv[ac], "-host", 4 ) )
01596         {
01597             if ( ++ac >= argc )
01598             {
01599                 fputs( "option usage: -host HOSTNAME\n", stderr );
01600                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01601                 return 1;
01602             }
01603 
01604             p->opts.host = argv[ac];    /* note and store the user option   */
01605             strncpy( A->host, argv[ac], ART_NAME_LEN-1 );
01606             A->host[ART_NAME_LEN-1] = '\0';     /* just to be sure */
01607         }
01608         else if ( ! strncmp( argv[ac], "-rev_byte_order", 4 ) )
01609         {
01610             p->opts.rev_bo = 1;           /* note to send reverse byte order */
01611         }
01612         else if ( ! strncmp( argv[ac], "-rt_cmd", 6 ) )
01613         {
01614             if ( ++ac >= argc )
01615             {
01616                 fputs( "option usage: -rt_cmd COMMAND\n", stderr );
01617                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01618                 return 1;
01619             }
01620 
01621             if ( add_to_string_list( &p->opts.rt_list, argv[ac] ) != 0 )
01622             {
01623                 fprintf(stderr,"** failed add '%s' to rt_list\n",argv[ac]);
01624                 return 1;
01625             }
01626         }
01627         else if ( ! strncmp( argv[ac], "-rt", 3 ) )
01628         {
01629             A->state = ART_STATE_TO_OPEN; /* real-time is open for business */
01630             p->opts.rt = 1;               /* just note the user option      */
01631         }
01632         else if ( ! strncmp( argv[ac], "-swap", 5 ) )
01633         {
01634             A->swap = 1;                /* do byte swapping before sending  */
01635             p->opts.swap = 1;           /* just note the user option        */
01636         }
01637         else if ( ! strncmp( argv[ac], "-use_imon", 7 ) )
01638         {
01639             /* still run as Imon */
01640             p->opts.use_dicom = 0;
01641         }
01642         else if ( ! strncmp( argv[ac], "-zorder", 6 ) )
01643         {
01644             if ( ++ac >= argc )
01645             {
01646                 fputs( "option usage: -zorder ORDER\n", stderr );
01647                 usage( IFM_PROG_NAME, IFM_USE_SHORT );
01648                 return 1;
01649             }
01650 
01651             A->zorder = argv[ac];
01652         }
01653         else
01654         {
01655             fprintf( stderr, "error: invalid option <%s>\n\n", argv[ac] );
01656             usage( IFM_PROG_NAME, IFM_USE_SHORT );
01657             return 1;
01658         }
01659     }
01660 
01661     if ( errors > 0 )          /* check for all minor errors before exiting */
01662     {
01663         usage( IFM_PROG_NAME, IFM_USE_SHORT );
01664         return 1;
01665     }
01666 
01667     if ( p->opts.start_dir == NULL && !p->opts.use_dicom )
01668     {
01669         fputs( "error: missing '-start_dir DIR' option\n", stderr );
01670         usage( IFM_PROG_NAME, IFM_USE_SHORT );
01671         return 1;
01672     }
01673 
01674     if ( p->opts.rev_bo && p->opts.swap )
01675     {
01676         fprintf( stderr, "error: options '-rev_byte_order' and '-swap' "
01677                  "cannot both be used\n");
01678         usage( IFM_PROG_NAME, IFM_USE_SHORT );
01679         return 1;
01680     }
01681 
01682     if ( A->zorder )
01683     {
01684         if ( strcmp(A->zorder, "alt") && strcmp(A->zorder, "seq") )
01685         {
01686             fprintf(stderr,"** order '%s' is invalid for '-zorder' option,\n"
01687                     "   must be either 'alt' or 'seq'\n", A->zorder);
01688             return 1;
01689         }
01690     }
01691 
01692     if ( p->opts.use_dicom )
01693     {   
01694         if( ! p->opts.dicom_glob )
01695         {
01696             fprintf(stderr,"** missing -infile_pattern option\n");
01697             return 1;
01698         }
01699     }
01700 
01701     /* done processing argument list */
01702 
01703     /* if dicom, start_dir is not used for globbing */
01704     if ( p->opts.use_dicom )
01705     {
01706         p->glob_dir = p->opts.dicom_glob;
01707         p->ftype    = IFM_IM_FTYPE_DICOM;
01708     }
01709     else
01710     {
01711         if ( dir_expansion_form(p->opts.start_dir, &p->glob_dir) ) return 2;
01712         p->ftype = IFM_IM_FTYPE_GEMS5;
01713     }
01714 
01715     /* save command arguments to add as a NOTE to any AFNI datasets */
01716     p->opts.argv = argv;
01717     p->opts.argc = argc;
01718 
01719     if ( gD.level > 1 )
01720     {
01721         idisp_opts_t ( "end init_options : ", &p->opts );
01722         idisp_param_t( "end init_options : ", p );
01723     }
01724 
01725     /* rcr - make this an option (large-to-small sort is -1) */
01726     if ( p->opts.use_dicom )
01727         rglob_set_sort_dir( 1 );   /* use a negative sort */
01728 
01729     if ( gD.level > 0 )
01730         fprintf( stderr, "\n%s running, use <ctrl-c> to quit...\n\n",
01731                  IFM_PROG_NAME );
01732 
01733     return 0;
01734 }

unsigned long l_THD_filesize char *    pathname
 

Return the file length (-1 if file not found).

Definition at line 3367 of file Dimon.c.

03368 {
03369     static struct stat buf ; int ii ;
03370 
03371     if( pathname == NULL ) return -1 ;
03372         ii = stat( pathname , &buf ) ; if( ii != 0 ) return -1 ;
03373 
03374     return buf.st_size ;
03375 }

int main int    argc,
char *    argv[]
 

\** File : SUMA.c

Author:
: Ziad Saad Date : Thu Dec 27 16:21:01 EST 2001
Purpose :

Input paramters :

Parameters:
param  Usage : SUMA ( )
Returns :
Returns:
Support :
See also:
OpenGL prog. Guide 3rd edition , varray.c from book's sample code
Side effects :

Definition at line 166 of file Dimon.c.

References argc, find_first_volume(), find_more_volumes(), init_extras(), init_options(), and p.

00167 {
00168     ART_comm * ac = &gAC;               /* access AFNI comm as local   */
00169     param_t  * p  = &gP;                /* access the global as local  */
00170     vol_t      baseV;                   /* base volume - first scanned */
00171     int        ret_val;
00172 
00173     /* validate inputs and init options structure */
00174     if ( (ret_val = init_options( p, ac, argc, argv )) != 0 )
00175         return ret_val;
00176 
00177     if ( (ret_val = init_extras( p, ac )) != 0 )
00178         return ret_val;
00179 
00180     if ( (ret_val = find_first_volume( &baseV, p, ac )) != 0 )
00181         return ret_val;
00182 
00183     if ( (ret_val = find_more_volumes( &baseV, p, ac )) != 0 )
00184         return ret_val;
00185 
00186     return 0;
00187 }

int nap_time_from_tr float    tr [static]
 

Definition at line 3237 of file Dimon.c.

References IFM_debug::level.

03238 {
03239     float tr2 = 2 * tr;
03240     int   nap_time;
03241 
03242     if ( tr2 < 1 )
03243         return 1;
03244 
03245     if ( tr2 > 10 )
03246         return 10;                      /* ??? tres big */
03247 
03248     nap_time = (int)(tr2 + 0.9);
03249 
03250     if ( gD.level > 1 )
03251         fprintf(stderr,"-d computed nap_time is %d seconds (TR = %.2f)\n",
03252                 nap_time, tr );
03253 
03254     return( nap_time );
03255 }

int path_to_dir_n_suffix char *    dir,
char *    suff,
char *    path
[static]
 

Definition at line 3665 of file Dimon.c.

References IFM_SUFFIX_LEN.

03666 {
03667     char * cp, *cp2;
03668 
03669     if ( (dir == NULL) || (suff == NULL) || (path == NULL) )
03670     {
03671         fprintf( stderr, "failure: PTDNS - invalid params (%p,%p,%p)\n",
03672                  dir, suff, path );
03673         return -1;
03674     }
03675 
03676     /* find last '.' */
03677     for ( cp = path + strlen(path) - 1; (*cp != '.') && (cp > path); cp-- )
03678         ;
03679 
03680     if ( *cp != '.' )
03681     {
03682         fprintf( stderr, "failure: cannot find suffix in '%s'\n", path );
03683         return -1;
03684     }
03685     else if ( strlen( cp ) > IFM_SUFFIX_LEN )          /* '.' not included */
03686     {
03687         fprintf( stderr, "failure: suffix too long in '%s'\n", path );
03688         return -1;
03689     }
03690 
03691     strcpy( suff, cp+1 );               /* copy null-terminated suffix */
03692 
03693     /* make sure all characters are digits (treat as string, not int) */
03694     for ( cp2 = suff; (*cp2 != '\0') && isdigit(*cp2); cp2++ )
03695        ;
03696 
03697     if ( *cp2 != '\0' )
03698     {
03699         fprintf( stderr, "failure: suffix not integer in '%s'\n", path );
03700         return -1;
03701     }
03702 
03703     /* now get dir prefix - should be nnn/I.mmm */
03704     cp -= 5;
03705     if ( ( cp < path )          ||    /* we should have a directory here */
03706          ( ! isdigit( cp[0] ) ) ||    /* then 3 digits */
03707          ( ! isdigit( cp[1] ) ) ||
03708          ( ! isdigit( cp[2] ) ) ||
03709          (   cp[3] != '/'     ) ||
03710          (   cp[4] != 'I'     ) )
03711     {
03712         fprintf( stderr, "failure: PTDNS - ill-formed path '%s'\n", path );
03713         return -1;
03714     }
03715 
03716     /* we are set, just copy the data */
03717     strncpy( dir, cp, 3 );
03718     dir[3] = '\0';
03719 
03720     return 0;
03721 }

MRI_IMAGE* r_mri_read_dicom char *    fname,
int    debug,
void **    data
 

Definition at line 264 of file dimon_afni.c.

References abs, calloc, DI_MRL_orients, DI_MRL_tr, DI_MRL_xcos, DI_MRL_xoff, DI_MRL_ycos, DI_MRL_yoff, DI_MRL_zoff, dt, MRI_IMAGE::dt, MRI_IMAGE::du, MRI_IMAGE::dv, MRI_IMAGE::dw, MRI_IMAGE::dx, MRI_IMAGE::dy, MRI_IMAGE::dz, E_BITS_ALLOCATED, E_BITS_STORED, E_COLUMNS, E_FIELD_OF_VIEW, E_HIGH_BIT, E_ID_MANUFACTURER, E_IMAGE_ORIENTATION, E_IMAGE_POSITION, E_NUMBER_OF_FRAMES, E_PATIENT_ORIENTATION, E_PHOTOMETRIC_INTERPRETATION, E_PIXEL_SPACING, E_REPETITION_TIME, E_RESCALE_INTERCEPT, E_RESCALE_SLOPE, E_ROWS, E_RS_IMAGE_NUM, E_RS_SERIES_NUM, E_RS_STUDY_NUM, E_SAMPLES_PER_PIXEL, E_SIEMENS_2, E_SLICE_LOCATION, E_SLICE_SPACING, E_SLICE_THICKNESS, elist, ENTRY, free, getenv(), gr_dimon_stuff, dimon_stuff_t::image, MRI_IMAGE::kind, l_THD_filesize(), LITTLE_ENDIAN_ARCHITECTURE, mri_dicom_header(), mri_dicom_nohex(), mri_dicom_noname(), mri_dicom_pxlarr(), mri_possibly_dicom(), MRI_IMAGE::nt, MRI_IMAGE::nu, NUM_ELIST, MRI_IMAGE::nv, MRI_IMAGE::nvox, MRI_IMAGE::nw, MRI_IMAGE::nx, MRI_IMAGE::nxy, MRI_IMAGE::nxyz, MRI_IMAGE::nxyzt, MRI_IMAGE::ny, nz, MRI_IMAGE::nz, MRI_IMAGE::pixel_size, RETURN, dimon_stuff_t::series, set_endianosity(), dimon_stuff_t::study, swap, swap_fourbytes(), swap_twobytes(), use_DI_MRL_xcos, use_DI_MRL_xoff, use_DI_MRL_ycos, use_DI_MRL_yoff, use_DI_MRL_zoff, MRI_IMAGE::was_swapped, xc, xn, MRI_IMAGE::xo, yc, yn, MRI_IMAGE::yo, and MRI_IMAGE::zo.

Referenced by read_dicom_image().

00265 {
00266    char *ppp , *ddd ;
00267    off_t poff ;
00268    unsigned int plen ;
00269    char *epos[NUM_ELIST] ;
00270    int ii,jj , ee , bpp , datum ;
00271    int nx,ny,nz , swap ;
00272    float dx,dy,dz,dt ;
00273    MRI_IMAGE *im ;
00274    void *iar ;
00275    FILE *fp ;
00276    int have_orients=0 ;
00277    int ior,jor,kor ;
00278    static int nzoff=0 ;   /* for determining z-axis orientation/offset from multiple calls */
00279 
00280    float dxx,dyy,dzz ;
00281 
00282    char *eee ;
00283    float rescale_slope=0.0 , rescale_inter=0.0 ;  /* 23 Dec 2002 */
00284 
00285    ENTRY("mri_read_dicom") ;
00286 
00287    if( !mri_possibly_dicom(fname) )
00288    {
00289       if(debug > 2) fprintf(stderr,"** MRD: mri_possibly_dicom() failure\n");
00290       RETURN(NULL) ;  /* 07 May 2003 */
00291    }
00292 
00293    /* extract header info from file into a string
00294       - cf. mri_dicom_hdr.[ch]
00295       - run 'dicom_hdr -noname fname' to see the string format */
00296 
00297    mri_dicom_nohex(1) ;              /* don't print ints in hex mode */
00298    mri_dicom_noname(1) ;             /* don't print names, just tags */
00299    ppp = mri_dicom_header( fname ) ; /* print header to malloc()-ed string */
00300    if( ppp == NULL )
00301    {
00302       if(debug > 2) fprintf(stderr,"** MRD: mri_dicom_hdr() failure\n");
00303       RETURN(NULL);   /* didn't work; not a DICOM file? */
00304    }
00305 
00306    /* find out where the pixel array is in the file */
00307 
00308    mri_dicom_pxlarr( &poff , &plen ) ;
00309    if( plen <= 0 ){
00310       if(debug > 2) fprintf(stderr,"** MRD: bad plen, %u\n", plen);
00311       free(ppp) ;
00312       RETURN(NULL);
00313    }
00314    if( debug > 3 )
00315       fprintf(stderr,"-d dicom: poff, plen = %d, %d\n",(int)poff,(int)plen);
00316 
00317    /* check if file is actually this big (maybe it was truncated) */
00318 
00319    { unsigned int psiz , fsiz ;
00320      fsiz = l_THD_filesize( fname ) ;
00321      psiz = (unsigned int)(poff) + plen ;
00322      if( fsiz < psiz ){
00323         if(debug > 2) fprintf(stderr,"** MRD: fsiz < psiz (%d,%d)\n",fsiz,psiz);
00324         free(ppp) ;
00325         RETURN(NULL);
00326      }
00327    }
00328 
00329    /* find positions in header of elements we care about */
00330 
00331    for( ee=0 ; ee < NUM_ELIST ; ee++ )
00332      epos[ee] = strstr(ppp,elist[ee]) ;
00333 
00334    /* see if the header has the elements we absolutely need */
00335 
00336    if( epos[E_ROWS]           == NULL ||
00337        epos[E_COLUMNS]        == NULL ||
00338        epos[E_BITS_ALLOCATED] == NULL   ){
00339       if(debug > 2)
00340          fprintf(stderr,"** MRD: missing ROWS, COLS or BITS (%p,%p,%p)\n",
00341                  epos[E_ROWS], epos[E_COLUMNS], epos[E_BITS_ALLOCATED]);
00342       free(ppp) ;
00343       RETURN(NULL);
00344    }
00345 
00346    /* check if we have 1 sample per pixel (can't deal with 3 or 4 now) */
00347 
00348    if( epos[E_SAMPLES_PER_PIXEL] != NULL ){
00349       ddd = strstr(epos[E_SAMPLES_PER_PIXEL],"//") ;
00350       if( ddd == NULL ){
00351          if(debug > 2) fprintf(stderr,"** MRD: missing E_SAMPLES_PER_PIXEL\n");
00352          free(ppp) ;
00353          RETURN(NULL);
00354       }
00355       ii = 0 ; sscanf(ddd+2,"%d",&ii) ;
00356        if( ii != 1 ){
00357          if(debug > 2) fprintf(stderr,"** MRD: SAM_PER_PIX != 1, %d\n",ii);
00358          free(ppp) ;
00359          RETURN(NULL);
00360       }
00361    }
00362 
00363    /* check if photometric interpretation is MONOCHROME (don't like PALETTE) */
00364 
00365    if( epos[E_PHOTOMETRIC_INTERPRETATION] != NULL ){
00366       ddd = strstr(epos[E_PHOTOMETRIC_INTERPRETATION],"MONOCHROME") ;
00367       if( ddd == NULL ){
00368       if(debug > 2) fprintf(stderr,"** MRD: photometric not monochrome\n");
00369         free(ppp) ;
00370         RETURN(NULL);
00371       }
00372    }
00373 
00374    /* check if we have 8, 16, or 32 bits per pixel */
00375 
00376    ddd = strstr(epos[E_BITS_ALLOCATED],"//") ;
00377    if( ddd == NULL ){
00378       if(debug > 2) fprintf(stderr,"** MRD: missing BITS_ALLOCATED\n");
00379       free(ppp);
00380       RETURN(NULL);
00381    }
00382    bpp = 0 ; sscanf(ddd+2,"%d",&bpp) ;
00383    switch( bpp ){
00384       default:
00385         if(debug > 2) fprintf(stderr,"** MRD: bad bpp value, %d\n",bpp);
00386         free(ppp); RETURN(NULL);    /* bad value */
00387       case  8: datum = MRI_byte ; break ;
00388       case 16: datum = MRI_short; break ;
00389       case 32: datum = MRI_int  ; break ;  /* probably not present in DICOM? */
00390    }
00391    bpp /= 8 ; /* now bytes per pixel, instead of bits */
00392 
00393    if( debug > 3 ) fprintf(stderr,"-d dicom: datum %d\n",datum);
00394 
00395    /*** Print some warnings if appropriate ***/
00396 
00397    /* check if BITS_STORED and HIGH_BIT are aligned */
00398 
00399 #define NWMAX 2
00400    if( epos[E_BITS_STORED] != NULL && epos[E_HIGH_BIT] != NULL ){
00401      int bs=0 , hb=0 ;
00402      ddd = strstr(epos[E_BITS_STORED],"//") ; sscanf(ddd+2,"%d",&bs) ;
00403      ddd = strstr(epos[E_HIGH_BIT],"//")    ; sscanf(ddd+2,"%d",&hb) ;
00404      if( bs != hb+1 ){
00405        static int nwarn=0 ;
00406        if( nwarn < NWMAX )
00407          fprintf(stderr,
00408                  "++ DICOM WARNING: file %s has Bits_Stored=%d and High_Bit=%d\n",
00409                  fname,bs,hb) ;
00410        if( nwarn == NWMAX )
00411          fprintf(stderr,"++ DICOM WARNING: no more Bits_Stored messages will be printed\n") ;
00412        nwarn++ ;
00413      }
00414    }
00415 
00416    /* check if Rescale is ordered */
00417    /* 23 Dec 2002: actually get the rescale params, if environment says to */
00418 
00419    if( epos[E_RESCALE_INTERCEPT] != NULL && epos[E_RESCALE_SLOPE] != NULL ){
00420      if( debug > 0 ){
00421        static int nwarn=0 ;
00422        if( nwarn == 0 ){
00423          fprintf(stderr,"++ DICOM file has Rescale tags, enforcing them...\n");
00424          fprintf(stderr,"   (no more Rescale tags messages will be printed)\n");
00425        }
00426        nwarn++ ;
00427      }
00428      ddd = strstr(epos[E_RESCALE_INTERCEPT],"//") ;
00429      sscanf(ddd+2,"%f",&rescale_inter) ;
00430      ddd = strstr(epos[E_RESCALE_SLOPE    ],"//") ;
00431      sscanf(ddd+2,"%f",&rescale_slope) ;
00432    }
00433 
00434    /*** extract attributes of the image(s) to be read in ***/
00435 
00436    /* get image nx & ny */
00437 
00438    ddd = strstr(epos[E_ROWS],"//") ;                         /* 31 Oct 2002: */
00439    if( ddd == NULL ){                 /* Oops: ROWS is ny and COLUMNS is nx! */
00440       if(debug > 2) fprintf(stderr,"** MRD: missing E_ROWS\n");
00441       free(ppp) ;
00442       RETURN(NULL);
00443    }
00444    ny = 0 ; sscanf(ddd+2,"%d",&ny) ;
00445    if( ny < 2 ){
00446       if(debug > 2) fprintf(stderr,"** MRD: bad ny = %d\n",ny);
00447       free(ppp) ;
00448       RETURN(NULL);
00449    }
00450 
00451    ddd = strstr(epos[E_COLUMNS],"//") ;
00452    if( ddd == NULL ){
00453       if(debug > 2) fprintf(stderr,"** MRD: missing E_COLUMNS\n");
00454       free(ppp) ;
00455       RETURN(NULL);
00456    }
00457    nx = 0 ; sscanf(ddd+2,"%d",&nx) ;
00458    if( nx < 2 ){
00459       if(debug > 2) fprintf(stderr,"** MRD: bad nx = %d\n",nx);
00460       free(ppp) ;
00461       RETURN(NULL);
00462    }
00463 
00464    /* get number of slices */
00465 
00466    nz = 0 ;
00467    if( epos[E_NUMBER_OF_FRAMES] != NULL ){
00468      ddd = strstr(epos[E_NUMBER_OF_FRAMES],"//") ;
00469      if( ddd != NULL ) sscanf(ddd+2,"%d",&nz) ;
00470      if(debug>3) fprintf(stderr,"-d number of frames = %d\n",nz);
00471    }
00472 
00473    /* if didn't get nz above, make up a value */
00474 
00475    if( nz == 0 ) nz = plen / (bpp*nx*ny) ;   /* compute from image array size */
00476    if( nz == 0 ){
00477       if(debug > 2) fprintf(stderr,"** MRD: bad nz = %d\n", nz);
00478       free(ppp) ;
00479       RETURN(NULL);
00480    }
00481 
00482    if( nz != 1 ){
00483       fprintf(stderr,"** MRD: nz = %d, plen,bpp,nx,ny = %d,%d,%d,%d\n",
00484          nz, plen, bpp, nx, ny);
00485       free(ppp);
00486       RETURN(NULL);
00487    }
00488 
00489    /*-- 28 Oct 2002: Check if this is a Siemens mosaic.        --*/
00490    /*-- 02 Dec 2002: Don't use Acquisition Matrix anymore;
00491                      instead, use the Siemens extra info
00492                      in epos[E_SIEMENS_2].                     --*/
00493    /*-- 24 Dec 2002: Extract str_sexinfo even if not a mosaic. --*/
00494 
00495    /* ignore sexinfo for Dimon, since it becomes a mosaic-only case */
00496 
00497    if(        epos[E_ID_MANUFACTURER]            != NULL &&
00498        strstr(epos[E_ID_MANUFACTURER],"SIEMENS") != NULL &&
00499               epos[E_SIEMENS_2]                  != NULL    ){
00500       if( debug > 3 ) fprintf(stderr,"-d ignoring sexinfo\n");
00501    }
00502 
00503    /*-- try to get dx, dy, dz, dt --*/
00504 
00505    dx = dy = dz = dt = 0.0 ;
00506 
00507    /* dx,dy first */
00508 
00509    if( epos[E_PIXEL_SPACING] != NULL ){
00510      ddd = strstr(epos[E_PIXEL_SPACING],"//") ;
00511      if( ddd != NULL ) sscanf( ddd+2 , "%f\\%f" , &dx , &dy ) ;
00512      if( debug > 3 )
00513         fprintf(stderr,"-d dicom: read dx,dy from PIXEL_SP: %f, %f\n", dx, dy);
00514      if( dy == 0.0 && dx > 0.0 ) dy = dx ;
00515    }
00516    if( dx == 0.0 && epos[E_FIELD_OF_VIEW] != NULL ){
00517      ddd = strstr(epos[E_FIELD_OF_VIEW],"//") ;
00518      if( ddd != NULL ) sscanf( ddd+2 , "%f\\%f" , &dx , &dy ) ;
00519      if( debug > 3 )
00520         fprintf(stderr,"-d dicom: read dx,dy from FOV: %f, %f\n", dx, dy);
00521      if( dx > 0.0 ){
00522        if( dy == 0.0 ) dy = dx ;
00523        dx /= nx ; dy /= ny ;
00524      }
00525    }
00526 
00527    /*-- 27 Nov 2002: fix stupid GE error,
00528                      where the slice spacing is really the slice gap --*/
00529 
00530    { int stupid_ge_fix , no_stupidity ;
00531      float sp=0.0 , th=0.0 ;
00532      static int nwarn=0 ;
00533                                                            /* 03 Mar 2003 */
00534      eee           = getenv("AFNI_SLICE_SPACING_IS_GAP") ;
00535      stupid_ge_fix = (eee != NULL && (*eee=='Y' || *eee=='y') );
00536      no_stupidity  = (eee != NULL && (*eee=='N' || *eee=='n') );
00537 
00538      if( epos[E_SLICE_SPACING] != NULL ){    /* get reported slice spacing */
00539        ddd = strstr(epos[E_SLICE_SPACING],"//") ;
00540        if( ddd != NULL ) sscanf( ddd+2 , "%f" , &sp ) ;
00541      }
00542      if( epos[E_SLICE_THICKNESS] != NULL ){  /* get reported slice thickness */
00543        ddd = strstr(epos[E_SLICE_THICKNESS],"//") ;
00544        if( ddd != NULL ) sscanf( ddd+2 , "%f" , &th ) ;
00545      }
00546 
00547      if(debug>3) fprintf(stderr,"-d dicom: thick, spacing = %f, %f\n", th, sp);
00548 
00549      th = fabs(th) ; sp = fabs(sp) ;         /* we don't use the sign */
00550 
00551      if( stupid_ge_fix ){                    /* always be stupid */
00552        dz = sp+th ;
00553      } else {
00554 
00555        if( no_stupidity && sp > 0.0 )        /* 13 Jan 2004: if 'NO', then */
00556          dz = sp ;                           /* always use spacing if present */
00557        else
00558          dz = (sp > th) ? sp : th ;          /* the correct-ish DICOM way */
00559 
00560 #define GFAC 0.99
00561 
00562        if( !no_stupidity ){                 /* unless stupidity is turned off */
00563          if( sp > 0.0 && sp < GFAC*th ) dz = sp+th;/* the stupid GE way again */
00564 
00565          if( sp > 0.0 && sp < GFAC*th && nwarn < NWMAX ){
00566            fprintf(stderr,
00567                    "++ DICOM WARNING: file %s has Slice_Spacing=%f smaller than Slice_Thickness=%f\n",
00568                    fname , sp , th ) ;
00569            if( nwarn == 0 )
00570             fprintf(stderr,
00571               "\n"
00572       "++  Setting environment variable AFNI_SLICE_SPACING_IS_GAP       ++\n"
00573       "++   to YES will make the center-to-center slice distance        ++\n"
00574       "++   be set to Slice_Spacing+Slice_Thickness=%6.3f.             ++\n"
00575       "++  This is against the DICOM standard [attribute (0018,0088)    ++\n"
00576       "++   is defined as the center-to-center spacing between slices,  ++\n"
00577       "++   NOT as the edge-to-edge gap between slices], but it seems   ++\n"
00578       "++   to be necessary for some GE scanners.                       ++\n"
00579       "++                                                               ++\n"
00580       "++  This correction has been made on this data: dz=%6.3f.       ++\n"
00581       "++                                                               ++\n"
00582       "++  Setting AFNI_SLICE_SPACING_IS_GAP to NO means that the       ++\n"
00583       "++  DICOM Slice_Spacing variable will be used for dz, replacing  ++\n"
00584       "++  the Slice_Thickness variable.  This usage may be required    ++\n"
00585       "++  for some pulse sequences on Phillips scanners.               ++\n"
00586               "\n\a" ,
00587              sp+th , dz ) ;
00588          }
00589          if( sp > 0.0 && sp < th && nwarn == NWMAX )
00590            fprintf(stderr,"++ DICOM WARNING: no more Slice_Spacing messages will be printed\n") ;
00591          nwarn++ ;
00592        }
00593      }
00594      if( dz == 0.0 && dx != 0.0 ) dz = 1.0 ;               /* nominal dz */
00595 
00596    } /*-- end of dz code, with all its stupidities --*/
00597 
00598    if(debug > 3) fprintf(stderr,"-d dicom: using dxyz = %f, %f, %f\n",dx,dy,dz);
00599 
00600    /* get dt */
00601 
00602    if( epos[E_REPETITION_TIME] != NULL ){
00603      ddd = strstr(epos[E_REPETITION_TIME],"//") ;
00604      if( ddd != NULL ){
00605        sscanf( ddd+2 , "%f" , &dt ) ;
00606        dt *= 0.001 ;   /* ms to s */
00607        if(debug > 3) fprintf(stderr,"-d dicom: rep. time dt = %f sec.\n",dt);
00608      }
00609    }
00610 
00611    /* check if we might have 16 bit unsigned data that fills all bits */
00612 
00613    if( epos[E_RS_STUDY_NUM] != NULL ){
00614      ddd = strstr(epos[E_RS_STUDY_NUM],"//") ;
00615      if( ddd != NULL ) sscanf( ddd+2 , "%d" , &gr_dimon_stuff.study);
00616    }
00617 
00618    if( epos[E_RS_SERIES_NUM] != NULL ){
00619      ddd = strstr(epos[E_RS_SERIES_NUM],"//") ;
00620      if( ddd != NULL ) sscanf( ddd+2 , "%d" , &gr_dimon_stuff.series);
00621    }
00622 
00623    if( epos[E_RS_IMAGE_NUM] != NULL ){
00624      ddd = strstr(epos[E_RS_IMAGE_NUM],"//") ;
00625      if( ddd != NULL ) sscanf( ddd+2 , "%d" , &gr_dimon_stuff.image);
00626    }
00627 
00628    /** Finally! Read images from file. **/
00629 
00630    fp = fopen( fname , "rb" ) ;
00631    if( fp == NULL ){
00632       if(debug > 2) fprintf(stderr,"** MRD: failed to open file '%s'\n",fname);
00633       free(ppp) ;
00634       RETURN(NULL);
00635    }
00636    lseek( fileno(fp) , poff , SEEK_SET ) ;
00637 
00638    /* DICOM files are stored in LSB first (little endian) mode */
00639 
00640    set_endianosity() ; swap = !LITTLE_ENDIAN_ARCHITECTURE ;
00641 
00642    /* use pre-(28 Oct 2002) method, mosaics are not allowed now */
00643 
00644    { /* no mri_new(), as we don't want to link everything */
00645      im = (MRI_IMAGE *)calloc(1, sizeof(MRI_IMAGE));
00646      if( !im ){
00647         fprintf(stderr,"** MRD: im malloc failure!\n");
00648         free(ppp);
00649         RETURN(NULL);
00650      }
00651      im->nx = nx;  im->ny = ny;
00652      im->nxy = nx * ny;
00653      im->nz = im->nt = im->nu = im->nv = im->nw = 1;
00654      im->nxyz = im->nxyzt = im->nvox = im->nxy; 
00655      im->kind = datum;
00656      im->dx = im->dy = im->dz = im->dt = im->du = im->dv = 1.0;
00657      im->dw = -666.0;
00658      im->pixel_size = bpp;
00659      if( data ){ /* if data is not set, do not read it in */
00660         if( ! *data ){
00661            *data = calloc(im->nvox, im->pixel_size);
00662            if( debug > 3 )
00663               fprintf(stderr,"+d dicom: image data alloc: %d x %d bytes\n",
00664                  im->nvox, im->pixel_size);
00665         }
00666         if( ! *data ){
00667            fprintf(stderr,"** MRD: image data alloc failure\n");
00668            free(ppp);
00669            RETURN(NULL);
00670         } 
00671      }
00672    }
00673 
00674    if( dx > 0.0 && dy > 0.0 && dz > 0.0 ){
00675      im->dx = dx; im->dy = dy; im->dz = dz; im->dw = 1.0;
00676    }
00677    if( dt > 0.0 ) im->dt = dt ;
00678    
00679    if( !data ) fclose(fp) ; 
00680    else{
00681       iar = *data;
00682       fread( iar , bpp , nx*ny , fp ) ;    /* read data directly into it */
00683    
00684       if( swap ){                          /* swap bytes? */
00685         switch( im->pixel_size ){
00686           default: break ;
00687           case 2:  swap_twobytes (   im->nvox, iar ) ; break ;  /* short */
00688           case 4:  swap_fourbytes(   im->nvox, iar ) ; break ;  /* int, float */
00689           case 8:  swap_fourbytes( 2*im->nvox, iar ) ; break ;  /* complex */
00690         }
00691         im->was_swapped = 1 ;
00692       }
00693    
00694       /* store auxiliary data in image struct */
00695    
00696       fclose(fp) ;     /* 10 Sep 2002: oopsie - forgot to close file */
00697    
00698       /*-- 23 Dec 2002: implement Rescale, if ordered --*/
00699    
00700       if( rescale_slope > 0.0 ){
00701         for( ii=0 ; ii < 1 ; ii++ ){
00702           switch( im->kind ){
00703             case MRI_byte:{
00704               byte *ar = (byte *)*data;
00705               for( jj=0 ; jj < im->nvox ; jj++ )
00706                 ar[jj] = rescale_slope*ar[jj] + rescale_inter ;
00707             }
00708             break ;
00709    
00710             case MRI_short:{
00711               short *ar = (short *)*data;
00712               for( jj=0 ; jj < im->nvox ; jj++ )
00713                 ar[jj] = rescale_slope*ar[jj] + rescale_inter ;
00714             }
00715             break ;
00716    
00717             case MRI_int:{
00718               int *ar = (int *)*data;
00719               for( jj=0 ; jj < im->nvox ; jj++ )
00720                 ar[jj] = rescale_slope*ar[jj] + rescale_inter ;
00721             }
00722             break ;
00723             default:{
00724               fprintf(stderr,"** MRD: bad kind case (%d) for rescale_slope\n",
00725                       im->kind);
00726               free(ppp);  free(*data);  *data = NULL;
00727               RETURN(NULL);
00728             }
00729             break ;
00730           }
00731         }
00732       } /* end of Rescale */
00733    }
00734 
00735    /*-- no WINDOW in Dimon */
00736 
00737    /*-- store some extra information in DI_MRL globals, too? --*/
00738 
00739    if( dt > 0.0 && DI_MRL_tr <= 0.0 ) DI_MRL_tr = dt ;
00740 
00741    /*-- try to get image orientation fields (also, set ior,jor,kor) --*/
00742 
00743    if( epos[E_IMAGE_ORIENTATION] != NULL ){
00744      /* direction cosines of image plane */
00745 
00746      ddd = strstr(epos[E_IMAGE_ORIENTATION],"//") ;
00747      if( ddd != NULL ){
00748        float xc1=0.0,xc2=0.0,xc3=0.0 , yc1=0.0,yc2=0.0,yc3=0.0 ;
00749        float xn,yn ; int qq ;
00750        qq=sscanf(ddd+2,"%f\\%f\\%f\\%f\\%f\\%f",&xc1,&xc2,&xc3,&yc1,&yc2,&yc3);
00751        xn = sqrt( xc1*xc1 + xc2*xc2 + xc3*xc3 ) ; /* vector norms */
00752        yn = sqrt( yc1*yc1 + yc2*yc2 + yc3*yc3 ) ;
00753        if( qq == 6 && xn > 0.0 && yn > 0.0 ){     /* both vectors OK */
00754 
00755          xc1 /= xn ; xc2 /= xn ; xc3 /= xn ;      /* normalize vectors */
00756          yc1 /= yn ; yc2 /= yn ; yc3 /= yn ;
00757 
00758          if( !use_DI_MRL_xcos ){
00759            DI_MRL_xcos[0] = xc1 ; DI_MRL_xcos[1] = xc2 ;  /* save direction */
00760            DI_MRL_xcos[2] = xc3 ; use_DI_MRL_xcos = 1 ;   /* cosine vectors */
00761          }
00762 
00763          if( !use_DI_MRL_ycos ){
00764            DI_MRL_ycos[0] = yc1 ; DI_MRL_ycos[1] = yc2 ;
00765            DI_MRL_ycos[2] = yc3 ; use_DI_MRL_ycos = 1 ;
00766          }
00767 
00768          /* x-axis orientation */
00769          /* ior determines which spatial direction is x-axis  */
00770          /* and is the direction that has the biggest change */
00771 
00772          dxx = fabs(xc1) ; ior = 1 ;
00773          dyy = fabs(xc2) ; if( dyy > dxx ){ ior=2; dxx=dyy; }
00774          dzz = fabs(xc3) ; if( dzz > dxx ){ ior=3;        }
00775          dxx = DI_MRL_xcos[ior-1] ; if( dxx < 0. ) ior = -ior;
00776 
00777          if( DI_MRL_orients[0] == '\0' ){
00778            switch( ior ){
00779              case -1: DI_MRL_orients[0] = 'L'; DI_MRL_orients[1] = 'R'; break;
00780              case  1: DI_MRL_orients[0] = 'R'; DI_MRL_orients[1] = 'L'; break;
00781              case -2: DI_MRL_orients[0] = 'P'; DI_MRL_orients[1] = 'A'; break;
00782              case  2: DI_MRL_orients[0] = 'A'; DI_MRL_orients[1] = 'P'; break;
00783              case  3: DI_MRL_orients[0] = 'I'; DI_MRL_orients[1] = 'S'; break;
00784              case -3: DI_MRL_orients[0] = 'S'; DI_MRL_orients[1] = 'I'; break;
00785              default: DI_MRL_orients[0] ='\0'; DI_MRL_orients[1] ='\0'; break;
00786            }
00787          }
00788 
00789          /* y-axis orientation */
00790          /* jor determines which spatial direction is y-axis  */
00791          /* and is the direction that has the biggest change */
00792 
00793          dxx = fabs(yc1) ; jor = 1 ;
00794          dyy = fabs(yc2) ; if( dyy > dxx ){ jor=2; dxx=dyy; }
00795          dzz = fabs(yc3) ; if( dzz > dxx ){ jor=3;        }
00796          dyy = DI_MRL_ycos[jor-1] ; if( dyy < 0. ) jor = -jor;
00797          if( DI_MRL_orients[2] == '\0' ){
00798            switch( jor ){
00799              case -1: DI_MRL_orients[2] = 'L'; DI_MRL_orients[3] = 'R'; break;
00800              case  1: DI_MRL_orients[2] = 'R'; DI_MRL_orients[3] = 'L'; break;
00801              case -2: DI_MRL_orients[2] = 'P'; DI_MRL_orients[3] = 'A'; break;
00802              case  2: DI_MRL_orients[2] = 'A'; DI_MRL_orients[3] = 'P'; break;
00803              case  3: DI_MRL_orients[2] = 'I'; DI_MRL_orients[3] = 'S'; break;
00804              case -3: DI_MRL_orients[2] = 'S'; DI_MRL_orients[3] = 'I'; break;
00805              default: DI_MRL_orients[2] ='\0'; DI_MRL_orients[3] ='\0'; break;
00806            }
00807          }
00808 
00809          DI_MRL_orients[6] = '\0' ;   /* terminate orientation string */
00810 
00811          kor = 6 - abs(ior)-abs(jor) ;   /* which spatial direction is z-axis */
00812                                          /* where 1=L-R, 2=P-A, 3=I-S */
00813          have_orients = 1 ;
00814 
00815          if( debug > 3 )
00816            fprintf(stderr,"-d dicom: DI_MRL_orients = %s, [ijk]or = %d,%d,%d\n",
00817                    DI_MRL_orients, ior, jor, kor);
00818        }
00819        else if( debug > 3 )
00820          fprintf(stderr,"-d dicom: bad orient vectors qq = %d, xn,yn = %f,%f\n",
00821                  qq, xn, yn);
00822      }
00823 
00824    } else if( epos[E_PATIENT_ORIENTATION] != NULL ){
00825               /* symbolic orientation of image [not so useful, or common] */
00826      ddd = strstr(epos[E_PATIENT_ORIENTATION],"//") ;
00827      if( ddd != NULL ){
00828        char xc='\0' , yc='\0' ;
00829        sscanf(ddd+2,"%c\\%c",&xc,&yc) ;   /* e.g., "L\P" */
00830        switch( toupper(xc) ){
00831          case 'L': DI_MRL_orients[0]='L'; DI_MRL_orients[1]='R'; ior=-1; break;
00832          case 'R': DI_MRL_orients[0]='R'; DI_MRL_orients[1]='L'; ior= 1; break;
00833          case 'P': DI_MRL_orients[0]='P'; DI_MRL_orients[1]='A'; ior=-2; break;
00834          case 'A': DI_MRL_orients[0]='A'; DI_MRL_orients[1]='P'; ior= 2; break;
00835          case 'F': DI_MRL_orients[0]='I'; DI_MRL_orients[1]='S'; ior= 3; break;
00836                    /* F=foot */
00837          case 'H': DI_MRL_orients[0]='S'; DI_MRL_orients[1]='I'; ior=-3; break;
00838                    /* H=head */
00839          default:  DI_MRL_orients[0]='\0';DI_MRL_orients[1]='\0'; ior= 0; break;
00840        }
00841        switch( toupper(yc) ){
00842          case 'L': DI_MRL_orients[2]='L'; DI_MRL_orients[3]='R'; jor=-1; break;
00843          case 'R': DI_MRL_orients[2]='R'; DI_MRL_orients[3]='L'; jor= 1; break;
00844          case 'P': DI_MRL_orients[2]='P'; DI_MRL_orients[3]='A'; jor=-2; break;
00845          case 'A': DI_MRL_orients[2]='A'; DI_MRL_orients[3]='P'; jor= 2; break;
00846          case 'F': DI_MRL_orients[2]='I'; DI_MRL_orients[3]='S'; jor= 3; break;
00847          case 'H': DI_MRL_orients[2]='S'; DI_MRL_orients[3]='I'; jor=-3; break;
00848          default:  DI_MRL_orients[2]='\0';DI_MRL_orients[3]='\0'; jor= 0; break;
00849        }
00850        DI_MRL_orients[6]='\0' ;      /* terminate orientation string */
00851        kor = 6 - abs(ior)-abs(jor) ;   /* which spatial direction is z-axis */
00852        have_orients = (ior != 0 && jor != 0) ;
00853 
00854        if( debug > 3 )
00855          fprintf(stderr,"-d dicom: DI_MRL_orients P = %s, [ijk]or = %d,%d,%d\n",
00856                  DI_MRL_orients, ior, jor, kor);
00857      }
00858 
00859    }  /* end of 2D image orientation */
00860 
00861    if( !have_orients ){
00862       fprintf(stderr,"** MRD: failed to determine dicom image orientation\n");
00863       free(ppp);  free(im);
00864       if( data ){ free(*data); *data = NULL; }
00865       RETURN(NULL);
00866    }
00867 
00868    /* skip mosaic use for finishing orientation string */
00869 
00870    /** use image position vector to set offsets,
00871        and (2cd time in) the z-axis orientation **/
00872 
00873    if( epos[E_IMAGE_POSITION] == NULL ){
00874       fprintf(stderr,"** MRD: missing image position\n");
00875       free(ppp);  free(im);
00876       if( data ){ free(*data); *data = NULL; }
00877       RETURN(NULL);
00878    }
00879 
00880    ddd = strstr(epos[E_IMAGE_POSITION],"//") ;
00881    if( ddd == NULL ){
00882       fprintf(stderr,"** MRD: missing IMAGE_POSITION\n");
00883       free(ppp);  free(im);
00884       if( data ){ free(*data); *data = NULL; }
00885       RETURN(NULL);
00886    }
00887 
00888    {   /* old mri_read_dicom: line 982 */
00889        float xyz[3] ; int qq ;
00890        qq = sscanf(ddd+2,"%f\\%f\\%f",xyz,xyz+1,xyz+2) ;
00891        if( qq != 3 ){
00892          fprintf(stderr,"** MRD: failed to read IMAGE_POSITION\n");
00893          free(ppp); free(im);
00894          if( data ){ free(*data); *data = NULL; }
00895          RETURN(NULL);
00896        }
00897        /* now use [ijk]or from above */
00898        im->xo = xyz[abs(ior)-1];
00899        im->yo = xyz[abs(jor)-1];
00900        im->zo = xyz[abs(kor)-1];
00901 
00902        if( debug > 3 )
00903           fprintf(stderr,"-d dicom: read RAI image position %f, %f, %f\n"
00904                          "          and dset image position %f, %f, %f\n",
00905                   xyz[0], xyz[1], xyz[2], im->xo, im->yo, im->zo );
00906 
00907        /* fill the orients string */
00908        {
00909          static float zoff ;      /* saved from nzoff=0 case */
00910          float zz = xyz[kor-1] ;  /* kor from orients above */
00911 
00912          if( nzoff == 0 ){  /* 1st DICOM image */
00913 
00914            zoff = zz ;      /* save this for 2nd image calculation */
00915 
00916            /* 01 Nov 2002: in mosaic case, may have set this already */
00917 
00918            if( DI_MRL_orients[4] == '\0' ){
00919              switch( kor ){   /* may be changed on second image */
00920                case  1: DI_MRL_orients[4] = 'L'; DI_MRL_orients[5] = 'R'; break;
00921                case  2: DI_MRL_orients[4] = 'P'; DI_MRL_orients[5] = 'A'; break;
00922                case  3: DI_MRL_orients[4] = 'I'; DI_MRL_orients[5] = 'S'; break;
00923                default: DI_MRL_orients[4] ='\0'; DI_MRL_orients[5] ='\0'; break;
00924              }
00925              DI_MRL_orients[6] = '\0' ;
00926            }
00927 
00928            /* Save x,y offsets of this 1st slice */
00929 
00930            qq = abs(ior) ;
00931            DI_MRL_xoff = xyz[qq-1] ; use_DI_MRL_xoff = 1 ;
00932            if( ior > 0 ) DI_MRL_xoff = -DI_MRL_xoff ;
00933 
00934            qq = abs(jor) ;
00935            DI_MRL_yoff = xyz[qq-1] ; use_DI_MRL_yoff = 1 ;
00936            if( jor > 0 ) DI_MRL_yoff = -DI_MRL_yoff ;
00937 
00938          } else if( nzoff == 1 && !use_DI_MRL_zoff ){  /* 2nd DICOM image */
00939 
00940            float qoff = zz - zoff ;    /* vive la difference */
00941            if( qoff < 0 ) kor = -kor ; /* kor determines z-axis orientation */
00942 #if 0
00943 fprintf(stderr,"  nzoff=1 kor=%d qoff=%f\n",kor,qoff) ;
00944 #endif
00945            switch( kor ){
00946              case  1: DI_MRL_orients[4] = 'R'; DI_MRL_orients[5] = 'L'; break;
00947              case -1: DI_MRL_orients[4] = 'L'; DI_MRL_orients[5] = 'R'; break;
00948              case  2: DI_MRL_orients[4] = 'A'; DI_MRL_orients[5] = 'P'; break;
00949              case -2: DI_MRL_orients[4] = 'P'; DI_MRL_orients[5] = 'A'; break;
00950              case  3: DI_MRL_orients[4] = 'I'; DI_MRL_orients[5] = 'S'; break;
00951              case -3: DI_MRL_orients[4] = 'S'; DI_MRL_orients[5] = 'I'; break;
00952              default: DI_MRL_orients[4] ='\0'; DI_MRL_orients[5] ='\0'; break;
00953            }
00954            DI_MRL_orients[6] = '\0' ;
00955 
00956            /* save spatial offset of first slice              */
00957            /* [this needs to be positive in the direction of] */
00958            /* [the -z axis, so may need to change its sign  ] */
00959 
00960            DI_MRL_zoff = zoff ; use_DI_MRL_zoff = 1 ;
00961            if( kor > 0 ) DI_MRL_zoff = -DI_MRL_zoff ;
00962          }
00963          nzoff++ ;  /* 3rd and later images don't count for z-orientation */
00964        }
00965    }  /* end of using image position */
00966 
00967    /** 23 Dec 2002:
00968        use slice location value to set z-offset,
00969        and (2cd time in) the z-axis orientation
00970        -- only try this if image position vector (code above) isn't present
00971           AND if we don't have a mosaic image (which already did this stuff)
00972        -- shouldn't be necessary, since slice location is deprecated        **/
00973 
00974    /* if this is here, use it for additional accuracy
00975       (it must basically match current zo) */
00976 
00977    { /* just use one warning counter, since these should be unique */
00978      static int nwarn = 0;
00979 
00980      if( ( epos[E_SLICE_LOCATION] == NULL) ||
00981          ( (ddd = strstr(epos[E_SLICE_LOCATION],"//")) == NULL ) )
00982      {
00983        if( nwarn == 0 && debug > 1 )
00984           fprintf(stderr,"-d dimon: missing SLICE_LOCATION, continuing...\n");
00985        nwarn++;
00986      } else {
00987         /* get and test the slice location */
00988         float zz ; int qq;
00989         qq = sscanf(ddd+2,"%f",&zz) ;
00990         if( qq != 1 ){
00991            if( !nwarn )fprintf(stderr,"** failed to extract SLICE_LOCATION\n");
00992            nwarn++;
00993         } else {
00994            /* it seems we have to add our own sign to the slice location */
00995            if( zz * im->zo < 0.0 ){
00996               if( (nwarn == 0) && (debug > 3) )
00997                 fprintf(stderr,"-d image and slice loc diff in sign: %f, %f\n",
00998                         im->zo, zz);
00999               nwarn++;
01000               zz = -zz;
01001            }
01002   
01003            if( fabs(zz - im->zo) > 0.1 ){
01004               fprintf(stderr,
01005                       "** MRD: IMAGE_LOCATION and SLICE_LOCATION disagree!\n"
01006                       "   z coord from IL = %f, from SL = %f\n", im->zo,zz);
01007               free(ppp); free(im);
01008               if( data ){ free(*data); *data = NULL; }
01009               RETURN(NULL);
01010            }
01011 
01012            if( debug > 3 )
01013               fprintf(stderr,"-d dicom: using slice location %f (zo = %f)\n",
01014                       zz, im->zo );
01015            im->zo = zz;
01016         }
01017      }
01018    }
01019 
01020    free(ppp);  /* free the ASCII header */
01021 
01022    RETURN( im );
01023 }

int read_dicom_image char *    pathname,
finfo_t   fp,
int    get_data
[static]
 

Definition at line 1901 of file Dimon.c.

References ge_extras::bpp, finfo_t::bytes, ge_extras::cflag, DI_MRL_orients, DI_MRL_tr, MRI_IMAGE::dx, ge_header_info::dx, MRI_IMAGE::dy, ge_header_info::dy, MRI_IMAGE::dz, ge_header_info::dz, free, finfo_t::geh, finfo_t::gex, ge_header_info::good, gr_dimon_stuff, ge_extras::hdroff, dimon_stuff_t::image, finfo_t::image, ge_header_info::index, ge_extras::kk, IFM_debug::level, MRI_IMAGE::nvox, MRI_IMAGE::nx, ge_header_info::nx, MRI_IMAGE::ny, ge_header_info::ny, ge_header_info::orients, MRI_IMAGE::pixel_size, r_mri_read_dicom(), dimon_stuff_t::series, ge_extras::skip, dimon_stuff_t::study, ge_extras::swap, ge_header_info::te, ge_header_info::tr, ge_header_info::uv17, MRI_IMAGE::was_swapped, MRI_IMAGE::xo, ge_extras::xorg, MRI_IMAGE::yo, ge_extras::yorg, MRI_IMAGE::zo, and ge_header_info::zoff.

Referenced by dicom_order_files(), and scan_ge_files().

01902 {
01903     MRI_IMAGE * im;
01904 
01905     im = r_mri_read_dicom( pathname, gD.level, get_data ? &fp->image : NULL);
01906     if ( !im )
01907     {
01908         fprintf(stderr,"** failed to read file '%s' as dicom\n", pathname);
01909         return 1;
01910     }
01911 
01912     if ( gD.level > 2 )
01913     {
01914         fprintf(stderr,"+d dinfo (%s): std, ser, im = (%d, %d, %3d)\n",
01915             pathname,
01916             gr_dimon_stuff.study, gr_dimon_stuff.series, gr_dimon_stuff.image );
01917         fprintf(stderr,"          im->xo,yo,zo =    (%6.1f,%6.1f,%6.1f)\n",
01918                 im->xo, im->yo, im->zo);
01919     }
01920 
01921     /* fill the finfo_t struct */
01922 
01923     fp->geh.good  = 1;
01924     fp->geh.nx    = im->nx;
01925     fp->geh.ny    = im->ny;
01926     fp->geh.uv17  = gr_dimon_stuff.series;
01927     fp->geh.index = gr_dimon_stuff.image;   /* image index number */
01928     fp->geh.dx    = im->dx;
01929     fp->geh.dy    = im->dy;
01930     fp->geh.dz    = im->dz;
01931     fp->geh.zoff  = im->zo;
01932 
01933     /* get some stuff from mrilib */
01934     fp->geh.tr = DI_MRL_tr;
01935     fp->geh.te = 0; /* rcr - none to set? */
01936     memset(fp->geh.orients, 0, 8);
01937     strncpy(fp->geh.orients, DI_MRL_orients, 7);
01938 
01939     /* ge_extras */
01940     fp->gex.bpp    = im->pixel_size;
01941     fp->gex.cflag  = 0;
01942     fp->gex.hdroff = -1;
01943     fp->gex.skip   = -1;
01944     fp->gex.swap   = im->was_swapped;
01945     fp->gex.kk     = 0;
01946     fp->gex.xorg   = im->xo;
01947     fp->gex.yorg   = im->yo;
01948 
01949     /* skip xyz[9] */
01950 
01951     fp->bytes = im->nvox * im->pixel_size;
01952 
01953     free(im);  /* do not free data, of course */
01954 
01955     return 0;
01956 }

int read_ge_files param_t   p,
int    start,
int    max
[static]
 

Definition at line 966 of file Dimon.c.

References dicom_order_files(), opts_t::dicom_org, find_fl_file_index(), param_t::flist, param_t::fnames, fnum, param_t::glob_dir, idisp_param_t(), IFM_debug::level, MCW_file_expand(), MCW_free_expand(), param_t::nalloc, param_t::nfiles, param_t::nused, param_t::opts, p, realloc, scan_ge_files(), opts_t::start_dir, opts_t::start_file, and opts_t::use_dicom.

00970 {
00971     static int org_todo = 1;    /* only organize once, so flag it   */
00972     int n2scan;                 /* number of files to actually scan */
00973     int next = start;           /* initialize next index to start   */
00974 
00975     if ( p == NULL )
00976     {
00977         fputs( "failure: RAF: no param_t struct\n", stderr  );
00978         return -1;
00979     }
00980 
00981     /* clear away old file list, unless we are using the DICOM organizer */
00982     if ( p->fnames && !p->opts.dicom_org )
00983     {
00984         if ( p->nfiles <= 0 )
00985         {
00986             fputs( "failure: RAF: fnames does not match nfiles\n", stderr );
00987             return -1;
00988         }
00989 
00990         MCW_free_expand( p->nfiles, p->fnames );
00991         p->fnames = NULL;
00992     }
00993 
00994     /* get files (check for dicom) */
00995     if ( p->opts.use_dicom )
00996     {
00997         if ( p->opts.dicom_org ) /* organize? */
00998         {
00999             if( org_todo )       /* may be used only once */
01000             {
01001                 MCW_file_expand(1, &p->glob_dir, &p->nfiles, &p->fnames);
01002                 if ( dicom_order_files( p ) != 0 ) return -1;
01003                 org_todo = 0;  /* now don't do it again */
01004             }
01005         }
01006         else
01007             MCW_file_expand( 1, &p->glob_dir, &p->nfiles, &p->fnames );
01008     }
01009     else
01010         MCW_file_expand( 1, &p->glob_dir, &p->nfiles, &p->fnames );
01011 
01012     /* if next is 0, search for any first_file */
01013     if ( (next == 0 ) && (p->opts.start_file || p->opts.start_dir) )
01014     {
01015         next = find_fl_file_index( p );
01016 
01017         if ( next < 0 )         /* if not found, try again later */
01018         {
01019             if ( gD.level > 0 ) /* inform the user */
01020             {
01021                 static int attempts = 0;
01022 
01023                 if ( attempts == 0 )
01024                     fprintf(stderr, "-- still searching for start_file, '%s'\n",
01025                             p->opts.start_file );
01026 
01027                 attempts++;
01028             }
01029             return 0;
01030         }
01031     }
01032     
01033     if ( gD.level > 4 )
01034     {
01035         int fnum;
01036         for ( fnum = next; fnum < p->nfiles; fnum++ )
01037             printf( "file %4d: %s\n", fnum, p->fnames[fnum] );
01038     }
01039 
01040     if ( p->nfiles <= 0 )
01041         return 0;
01042 
01043     /* set the number of files to scan - if max is usable, use it */
01044     if ( (max > 0) && (max <= (p->nfiles - next)) )
01045         n2scan = max;                           /* scan next max files */
01046     else
01047         n2scan = p->nfiles - next;              /* scan rest of files  */
01048 
01049     /* do we need/want more memory? */
01050     if ( (n2scan > p->nalloc) || (max > p->nalloc) )
01051     {
01052         int nalloc;
01053 
01054         /* allow a request to allocate 'max' entries */
01055         nalloc = (n2scan >= max) ? n2scan : max;
01056 
01057         p->flist = (finfo_t *)realloc( p->flist, nalloc * sizeof(finfo_t) );
01058 
01059         if ( p->flist == NULL )
01060         {
01061             fprintf(stderr, "failure to allocate %d finfo_t structs\n", nalloc);
01062             return -1;
01063         }
01064 
01065         p->nalloc = nalloc;
01066 
01067         if ( gD.level > 1 )
01068         {
01069             idisp_param_t( "++ realloc of flist : ", p );
01070             fprintf( stderr,  "-- n2scan = %d, max = %d\n", n2scan, max );
01071         }
01072     }
01073 
01074     p->nused = scan_ge_files( p, next, n2scan );
01075 
01076     if ( gD.level > 2 )
01077         idisp_param_t( "end read_ge_files : ", p );
01078 
01079     /* may be negative for an error condition */
01080     return p->nused;
01081 }

int read_ge_image char *    pathname,
finfo_t   fp,
int    get_image,
int    need_memory
[static]
 

Definition at line 1966 of file Dimon.c.

References abs, ge_extras::bpp, finfo_t::bytes, ge_extras::cflag, ge_header_info::dx, ge_header_info::dy, ge_header_info::dz, finfo_t::geh, finfo_t::gex, ge_header_info::good, ge_extras::hdroff, finfo_t::image, ge_extras::kk, L, l_THD_filesize(), malloc, ge_header_info::nx, ge_header_info::ny, ge_header_info::orients, ge_extras::skip, skip, ge_extras::swap, swap, swap_4(), ge_header_info::te, ge_header_info::tr, ge_header_info::uv17, ge_extras::xorg, ge_extras::xyz, ge_extras::yorg, and ge_header_info::zoff.

01968 {
01969    ge_header_info * hi  = &fp->geh;
01970 
01971    FILE *imfile ;
01972    int  length , skip , swap=0 ;
01973    char orients[8] , str[8] ;
01974    int nx , ny , bpp , cflag , hdroff ;
01975         float uv17 = -1.0;
01976         
01977    if( hi == NULL ) return -1;            /* bad */
01978    hi->good = 0 ;                       /* not good yet */
01979    if( pathname    == NULL ||
01980        pathname[0] == '\0'   ) return -1; /* bad */
01981 
01982    length = l_THD_filesize( pathname ) ;
01983    if( length < 1024 ) return -1;         /* bad */
01984 
01985    imfile = fopen( pathname , "r" ) ;
01986    if( imfile == NULL ) return -1;        /* bad */
01987 
01988    strcpy(str,"JUNK") ;     /* initialize string */
01989    fread(str,1,4,imfile) ;  /* check for "IMGF" at start of file */
01990 
01991    if( str[0]!='I' || str[1]!='M' || str[2]!='G' || str[3]!='F' ){ /* bad */
01992       fclose(imfile) ; return -2;
01993    }
01994 
01995    /*-- read next 5 ints (after the "IMGF" string) --*/
01996 
01997    fread( &skip , 4,1, imfile ) ; /* offset into file of image data */
01998    fread( &nx   , 4,1, imfile ) ; /* x-size */
01999    fread( &ny   , 4,1, imfile ) ; /* y-size */
02000    fread( &bpp  , 4,1, imfile ) ; /* bits per pixel (should be 16) */
02001    fread( &cflag, 4,1, imfile ) ; /* compression flag (1=uncompressed)*/
02002 
02003         /*-- check if nx is funny --*/
02004 
02005    if( nx < 0 || nx > 8192 ){      /* have to byte swap these 5 ints */
02006      swap = 1 ;                    /* flag to swap data, too */
02007      swap_4(&skip); swap_4(&nx); swap_4(&ny); swap_4(&bpp); swap_4(&cflag);
02008    } else {
02009      swap = 0 ;  /* data is ordered for this CPU */
02010    }
02011    if( nx < 0 || nx > 8192 || ny < 0 || ny > 8192 ){  /* bad */
02012       fclose(imfile) ; return -1;
02013    }
02014 
02015    hi->nx = nx ;
02016    hi->ny = ny ;
02017 
02018    if( skip+2*nx*ny >  length ||               /* file is too short */
02019        skip         <= 0      ||               /* bizarre  */
02020        cflag        != 1      ||               /* data is compressed */
02021        bpp          != 16        ){
02022       fclose(imfile); return -1;    /* data is not shorts */
02023    }
02024 
02025    /*-- try to read image header data as well --*/
02026 
02027    fseek( imfile , 148L , SEEK_SET ) ; /* magic GEMS offset */
02028    fread( &hdroff , 4,1 , imfile ) ;   /* location of image header */
02029    if( swap ) swap_4(&hdroff) ;
02030 
02031    if( hdroff > 0 && hdroff+256 < length ){   /* can read from image header */
02032        float dx,dy,dz, xyz[9], zz ; int itr, ii,jj,kk ;
02033 
02034        /*-- get voxel grid sizes --*/
02035 
02036        fseek( imfile , hdroff+26 , SEEK_SET ) ;    /* dz */
02037        fread( &dz , 4,1 , imfile ) ;
02038 
02039        fseek( imfile , hdroff+50 , SEEK_SET ) ;    /* dx and dy */
02040        fread( &dx , 4,1 , imfile ) ;
02041        fread( &dy , 4,1 , imfile ) ;
02042 
02043        if( swap ){ swap_4(&dx); swap_4(&dy); swap_4(&dz); }
02044 
02045        hi->dx = dx ; hi->dy = dy ; hi->dz = dz ;
02046 
02047        /* grid orientation: from 3 sets of LPI corner coordinates: */
02048        /*   xyz[0..2] = top left hand corner of image     (TLHC)   */
02049        /*   xyz[3..5] = top right hand corner of image    (TRHC)   */
02050        /*   xyz[6..8] = bottom right hand corner of image (BRHC)   */
02051        /* GEMS coordinate orientation here is LPI                  */
02052 
02053        fseek( imfile , hdroff+154 , SEEK_SET ) ;  /* another magic number */
02054        fread( xyz , 4,9 , imfile ) ;
02055        if( swap ){
02056           swap_4(xyz+0); swap_4(xyz+1); swap_4(xyz+2);
02057           swap_4(xyz+3); swap_4(xyz+4); swap_4(xyz+5);
02058           swap_4(xyz+6); swap_4(xyz+7); swap_4(xyz+8);
02059        }
02060 
02061        /* x-axis orientation */
02062        /* ii determines which spatial direction is x-axis  */
02063        /* and is the direction that has the biggest change */
02064        /* between the TLHC and TRHC                        */
02065 
02066        dx = fabs(xyz[3]-xyz[0]) ; ii = 1 ;
02067        dy = fabs(xyz[4]-xyz[1]) ; if( dy > dx ){ ii=2; dx=dy; }
02068        dz = fabs(xyz[5]-xyz[2]) ; if( dz > dx ){ ii=3;        }
02069        dx = xyz[ii+2]-xyz[ii-1] ; if( dx < 0. ){ ii = -ii;    }
02070        switch( ii ){
02071         case  1: orients[0]= 'L'; orients[1]= 'R'; break;
02072         case -1: orients[0]= 'R'; orients[1]= 'L'; break;
02073         case  2: orients[0]= 'P'; orients[1]= 'A'; break;
02074         case -2: orients[0]= 'A'; orients[1]= 'P'; break;
02075         case  3: orients[0]= 'I'; orients[1]= 'S'; break;
02076         case -3: orients[0]= 'S'; orients[1]= 'I'; break;
02077         default: orients[0]='\0'; orients[1]='\0'; break;
02078        }
02079 
02080        /* y-axis orientation */
02081        /* jj determines which spatial direction is y-axis  */
02082        /* and is the direction that has the biggest change */
02083        /* between the BRHC and TRHC                        */
02084 
02085        dx = fabs(xyz[6]-xyz[3]) ; jj = 1 ;
02086        dy = fabs(xyz[7]-xyz[4]) ; if( dy > dx ){ jj=2; dx=dy; }
02087        dz = fabs(xyz[8]-xyz[5]) ; if( dz > dx ){ jj=3;        }
02088        dx = xyz[jj+5]-xyz[jj+2] ; if( dx < 0. ){ jj = -jj;    }
02089        switch( jj ){
02090          case  1: orients[2] = 'L'; orients[3] = 'R'; break;
02091          case -1: orients[2] = 'R'; orients[3] = 'L'; break;
02092          case  2: orients[2] = 'P'; orients[3] = 'A'; break;
02093          case -2: orients[2] = 'A'; orients[3] = 'P'; break;
02094          case  3: orients[2] = 'I'; orients[3] = 'S'; break;
02095          case -3: orients[2] = 'S'; orients[3] = 'I'; break;
02096          default: orients[2] ='\0'; orients[3] ='\0'; break;
02097        }
02098 
02099        orients[4] = '\0' ;   /* terminate orientation string */
02100 
02101        kk = 6 - abs(ii)-abs(jj) ;   /* which spatial direction is z-axis   */
02102                                     /* where 1=LR, 2=PA, 3=IS               */
02103                                     /* (can't tell orientation from 1 slice) */
02104 
02105        zz = xyz[kk-1] ;             /* z-coordinate of this slice */
02106 
02107        hi->zoff = zz ;
02108        strcpy(hi->orients,orients) ;
02109 
02110        /* similarly (with zoff), store x and y origins in ge_extras */
02111        /*                                       2003 Jun 25 [rickr] */
02112        fp->gex.xorg = xyz[abs(ii)-1];
02113        fp->gex.yorg = xyz[abs(jj)-1];
02114 
02115        /*-- get TR in seconds --*/
02116 
02117        fseek( imfile , hdroff+194 , SEEK_SET ) ;
02118        fread( &itr , 4,1 , imfile ) ; /* note itr is an int */
02119        if( swap ) swap_4(&itr) ;
02120        hi->tr = 1.0e-6 * itr ;        /* itr is in microsec */
02121 
02122        /*-- get TE in milliseconds --*/
02123 
02124        fseek( imfile , hdroff+202 , SEEK_SET ) ;
02125        fread( &itr , 4,1 , imfile ) ; /* itr is an int, in microsec */
02126        if( swap ) swap_4(&itr) ;
02127        hi->te = 1.0e-6 * itr ;
02128 
02129        /* zmodify: get User Variable 17, a likely indicator of a new scan,
02130         * info by S. Marrett, location from S. Inati's matlab function
02131         * GE_readHeaderImage.m
02132         */
02133 
02134         /* printf ("\nuv17 = \n"); */
02135         fseek ( imfile , hdroff+272+202, SEEK_SET ) ;
02136         fread( &uv17 , 4, 1 , imfile ) ;
02137         if( swap ) swap_4(&uv17) ;
02138         /* printf ("%d ", (int)uv17);  */
02139         hi->uv17 = (int)uv17; 
02140         /* printf ("\n"); */
02141 
02142         /* store the ge_extra info */
02143         fp->gex.bpp    = bpp;
02144         fp->gex.cflag  = cflag;
02145         fp->gex.hdroff = hdroff;
02146         fp->gex.skip   = skip;
02147         fp->gex.swap   = swap;
02148         fp->gex.kk     = kk;
02149 
02150         memcpy( fp->gex.xyz, xyz, sizeof(xyz) );
02151         
02152         hi->good = 1 ;                  /* this is a good file */
02153 
02154     } /* end of actually reading image header */
02155 
02156     /* read image in as well */
02157     if ( get_image )
02158     {
02159         int elements = hi->nx * hi->ny;
02160 
02161         fp->bytes = elements * 2;                       /* bpp == 16 */
02162 
02163         if ( need_memory )
02164             fp->image = malloc( fp->bytes );
02165 
02166         if ( fp->image == NULL )
02167         {
02168             fprintf(stderr, "** RGI: no memory for %d byte image\n", fp->bytes);
02169             hi->good = 0;
02170             return -1;
02171         }
02172 
02173         fseek ( imfile, skip, SEEK_SET );
02174         if ( fread( fp->image , 2, elements, imfile ) != elements )
02175         {
02176             fprintf( stderr, "** RGI: failed to read %d shorts from %s\n",
02177                      elements, pathname );
02178             hi->good = 0;               /* signal file problem */
02179             return -1;
02180         }
02181     }
02182 
02183     fclose(imfile);
02184     return 0;
02185 }

int scan_ge_files param_t   p,
int    next,
int    nfiles
[static]
 

Definition at line 1090 of file Dimon.c.

References alloc_x_im(), finfo_t::bytes, check_im_store_space(), param_t::flist, param_t::fnames, fnum, finfo_t::geh, finfo_t::gex, ge_header_info::good, idisp_ge_extras(), idisp_ge_header_info(), IFM_MAX_GE_FAILURES, im_store_t::im_ary, im_store_t::im_size, param_t::im_store, finfo_t::image, finfo_t::index, IFM_debug::level, im_store_t::nalloc, im_store_t::nused, param_t::opts, p, read_dicom_image(), read_ge_image(), and opts_t::use_dicom.

01094 {
01095     finfo_t    * fp;
01096     int          im_num, fnum;
01097     int          files_read, rv = 0;
01098     int          need_M;                /* do we need image memory?    */
01099 
01100     if ( nfiles <= 0 )
01101         return 0;
01102 
01103     if ( check_im_store_space( &p->im_store, nfiles ) < 0 )
01104         return -1;
01105 
01106     p->im_store.nused = 0;
01107     /* scan from 'next' to 'next + nfiles - 1' */
01108     for ( im_num = 0, fnum = next, fp = p->flist;
01109           im_num < nfiles;
01110           im_num++, fnum++, fp++ )
01111     {
01112         /* do we need image memory? */
01113         if ( im_num < p->im_store.nalloc )
01114         {
01115             fp->image = p->im_store.im_ary[im_num];
01116             need_M    = 0;
01117         }
01118         else                                    /* get it from read_ge_image */
01119         {
01120             fp->image = NULL;
01121             need_M    = 1;
01122         }
01123 
01124         if ( p->opts.use_dicom )
01125             rv = read_dicom_image( p->fnames[fnum], fp, 1 );
01126         else 
01127             rv = read_ge_image( p->fnames[fnum], fp, 1, need_M );
01128 
01129         /* don't lose any allocated memory, regardless of the return value */
01130         if ( (need_M == 1) && (fp->image != NULL) )
01131         {
01132             p->im_store.im_ary[im_num] = fp->image;
01133             p->im_store.nalloc++;
01134 
01135             /* note the size of the image and get memory for x_im */
01136             if ( p->im_store.im_size == 0 )
01137             {
01138                 if ( alloc_x_im( &p->im_store, fp->bytes ) < 0 )
01139                     return -1;
01140             }
01141 
01142             if ( gD.level > 1 )
01143                 fprintf( stderr, "++ allocated image %d at address %p\n",
01144                          im_num, p->im_store.im_ary[im_num] );
01145         }
01146 
01147         if ( (rv != 0) || (fp->geh.good != 1) )
01148         {
01149             static int read_failure = -1;  /* last read_ge_image failure    */
01150             static int fail_count   =  0;  /* get multiple tries to succeed */
01151 
01152             /* on first failure, note file and set fail_count to 1 */
01153             if ( read_failure != fnum )
01154             {
01155                 read_failure = fnum;
01156                 fail_count   = 1;
01157             }
01158             else
01159                 fail_count++;
01160 
01161             /* after too many failure, we give up */
01162             if ( fail_count > IFM_MAX_GE_FAILURES )
01163             {
01164                 fprintf( stderr, "\n** failure: cannot read image file for "
01165                          "file <%s>\n", p->fnames[fnum] );
01166                 return -1;
01167             }
01168 
01169             /* we failed, but will try again later - maybe inform user */
01170             if ( gD.level > 1 )
01171                 fprintf( stderr, "\n-- (%d) failures to read image file for "
01172                          "file <%s>, trying again...\n",
01173                          fail_count, p->fnames[fnum] );
01174 
01175             break;
01176         }
01177         else
01178         {
01179             p->im_store.nused++;        /* keep track of used images     */
01180             fp->index = fnum;           /* store index into fnames array */
01181 
01182             if ( gD.level > 2 )
01183             {
01184                 idisp_ge_header_info( p->fnames[fp->index], &fp->geh );
01185                 idisp_ge_extras( p->fnames[fp->index], &fp->gex );
01186             }
01187         }
01188     }
01189 
01190     /* even on failure, this non-negative integer is accurate */
01191     files_read = fnum - next;
01192 
01193     if ( rv == 0 && gD.level > 1 )
01194         printf( "-- scanned %d image files, from <%s> to <%s>\n",
01195                 files_read, p->fnames[next], p->fnames[next+files_read-1] );
01196 
01197     return files_read;
01198 }

int set_nice_level int    level [static]
 

Definition at line 1790 of file Dimon.c.

References IFM_debug::level.

01791 {
01792     int rv;
01793 
01794     rv = nice( level );
01795     if ( rv != 0 )
01796     {
01797         if ( level < 0 )
01798             fprintf( stderr, "error: only root may decrement nice value\n"
01799                              "       (errno = %d, rv = %d)\n", errno, rv );
01800         else
01801             fprintf( stderr,
01802                      "error: failure to adjust nice by %d\n"
01803                      "       (errno = %d, rv = %d)\n", level, errno, rv );
01804     }
01805     else if ( gD.level > 1 )
01806         fprintf( stderr, "-- nice value incremented by %d\n", level );
01807 
01808     return rv;
01809 }

int set_volume_stats param_t   p,
stats_t   s,
vol_t   v
[static]
 

Definition at line 2932 of file Dimon.c.

References calloc, run_t::f1index, run_t::f1name, vol_t::first_file, vol_t::fn_1, idisp_vol_t(), IFM_MAX_FLEN, IFM_STAT_ALLOC, IFM_debug::level, stats_t::nalloc, vol_t::nim, opts_t::nt, stats_t::nused, stats_t::nvols, param_t::opts, p, realloc, vol_t::run, stats_t::runs, vol_t::seq_num, stats_t::slices, v, run_t::volumes, vol_t::z_delta, stats_t::z_delta, vol_t::z_first, stats_t::z_first, vol_t::z_last, and stats_t::z_last.

02933 {
02934     run_t * rp;           /* for a little speed, this will be called often */
02935 
02936     if ( v == NULL || v->seq_num < 0 || v->run < 0 )
02937     {
02938         fprintf( stderr, "failure: SVS - insufficient data\n\n" );
02939         idisp_vol_t ( "-- VOLUME FAILURE INFO : ", v );
02940     }
02941 
02942     /* initialize the stats structure */
02943     if ( s->nalloc == 0 )
02944     {
02945         s->runs = (run_t *)calloc( IFM_STAT_ALLOC, sizeof(run_t) );
02946         if ( s->runs == NULL )
02947         {
02948             fprintf( stderr, "failure: cannot allocate space for run info\n" );
02949             return -1;
02950         }
02951 
02952         /* first time caller - fill initial stats info */
02953         s->slices  = v->nim;
02954         s->z_first = v->z_first;
02955         s->z_last  = v->z_last;
02956         s->z_delta = v->z_delta;
02957 
02958         s->nalloc  = IFM_STAT_ALLOC;
02959         s->nused   = 0;
02960         s->nvols   = gP.opts.nt;        /* init with any user input value */
02961 
02962         if ( gD.level > 1 )
02963             fprintf( stderr, "\n-- svs: init alloc - vol %d, run %d, file %s\n",
02964                      v->seq_num, v->run, v->first_file );
02965     }
02966 
02967     if ( v->run >= s->nalloc )          /* run is 0-based */
02968     {
02969         /* make space for many more runs - we don't want to do this often */
02970         s->runs = (run_t *)realloc( s->runs, (v->run + IFM_STAT_ALLOC) *
02971                                              sizeof(run_t) );
02972         if ( s->runs == NULL )
02973         {
02974             fprintf( stderr, "failure: cannot realloc space for run info\n" );
02975             return -1;
02976         }
02977 
02978         s->nalloc = v->run + IFM_STAT_ALLOC;
02979 
02980         /* zero out any new memory */
02981         memset( s->runs + s->nused, 0, (s->nalloc - s->nused)*sizeof(run_t) );
02982 
02983         if ( gD.level > 1 )
02984             fprintf( stderr,
02985                 "\n-- svs: realloc (%d entries) - vol %d, run %d, file %s\n",
02986                 s->nalloc, v->seq_num, v->run, v->first_file );
02987 
02988     }
02989 
02990     /* we have memory - the current run number is an index into runs */
02991 
02992     rp = s->runs + v->run;
02993 
02994     if ( s->nused < v->run+1 )
02995         s->nused = v->run+1;
02996 
02997     if ( rp->volumes == 0 )
02998     {
02999         rp->f1index = v->fn_1; /* index into flist (matching f1name) */
03000         strncpy( rp->f1name, v->first_file, IFM_MAX_FLEN );
03001     }
03002 
03003     rp->volumes = v->seq_num;
03004 
03005     /* update nvols (if the user did not specify it and it is small) */
03006     if ( (p->opts.nt <= 0) && (s->nvols < v->seq_num) )
03007         s->nvols = v->seq_num;
03008 
03009     if ( gD.level > 2 )
03010         fprintf( stderr, "\n-- svs: run %d, seq_num %d\n", v->run, v->seq_num );
03011 
03012     return 0;
03013 }

int show_run_stats stats_t   s [static]
 

Definition at line 3192 of file Dimon.c.

References c, create_gert_script(), opts_t::gert_reco, stats_t::nalloc, stats_t::nused, param_t::opts, putchar, stats_t::runs, stats_t::slices, stats_t::z_delta, stats_t::z_first, and stats_t::z_last.

03193 {
03194     int c;
03195 
03196     if ( s == NULL )
03197     {
03198         fprintf( stderr, "failure, SRS - no stats struct!\n" );
03199         return -1;
03200     }
03201 
03202     if ( s->nalloc <= 0 || s->nused <= 0 )
03203         return 0;
03204 
03205     printf( "\n\n"
03206             "final run statistics:\n"
03207             "    volume info :\n"
03208             "        slices  : %d\n"
03209             "        z_first : %.4f\n"
03210             "        z_last  : %.4f\n"
03211             "        z_delta : %.4f\n"
03212             "\n",
03213             s->slices, s->z_first, s->z_last, s->z_delta );
03214 
03215     for ( c = 0; c < s->nused; c++ )
03216     {
03217         if ( s->runs[c].volumes > 0 )
03218             printf( "    run #%4d : volumes = %3d, first file (#%d) = %s\n",
03219                     c,s->runs[c].volumes,s->runs[c].f1index,s->runs[c].f1name);
03220     }
03221 
03222     putchar( '\n' );
03223 
03224     if ( gP.opts.gert_reco )
03225         (void)create_gert_script( s, &gP );
03226 
03227     fflush( stdout );
03228 
03229     return 0;
03230 }

int str_char_count char *    str,
int    len,
char    target
[static]
 

Definition at line 3637 of file Dimon.c.

03638 {
03639     char * cp;
03640     char * last = str + len;
03641     int    num = 0;
03642 
03643     if ( (str == NULL) || (len <= 0) )
03644         return 0;
03645 
03646     for ( cp = str; cp < last; cp++ )
03647         if ( *cp == target )
03648             num++;
03649 
03650     return num;
03651 }

int swap_4 void *    ptr [static]
 

Swap the 4 bytes pointed to by ppp: abcd -> dcba.

Definition at line 2192 of file Dimon.c.

02193 {
02194     unsigned char * addr = ptr;
02195 
02196     addr[0] ^= addr[3]; addr[3] ^= addr[0]; addr[0] ^= addr[3];
02197     addr[1] ^= addr[2]; addr[2] ^= addr[1]; addr[1] ^= addr[2];
02198 
02199     return 0;
02200 }

int usage char *    prog,
int    level
[static]
 

Definition at line 2445 of file Dimon.c.

References DIMON_VERSION, g_history, IFM_USE_HIST, IFM_USE_LONG, IFM_USE_SHORT, and IFM_USE_VERSION.

02446 {
02447     if ( level == IFM_USE_SHORT )
02448     {
02449         fprintf( stderr,
02450             "usage: %s [options] -start_dir DIR\n"
02451             "usage: %s -help\n",
02452             prog, prog );
02453         return 0;
02454     }
02455     else if ( level == IFM_USE_LONG )
02456     {
02457         printf(
02458           "\n"
02459           "%s - monitor real-time acquisition of DICOM image files\n"
02460           "    (or GEMS 5.x I-files, as 'Imon')\n"
02461           "\n"
02462           "    This program is intended to be run during a scanning session\n"
02463           "    on a scanner, to monitor the collection of image files.  The\n"
02464           "    user will be notified of any missing slice or any slice that\n"
02465           "    is aquired out of order.\n"
02466           "\n"
02467           "    When collecting DICOM files, it is recommended to run this\n"
02468           "    once per run, only because it is easier to specify the input\n"
02469           "    file pattern for a single run (it may be very difficult to\n"
02470           "    predict the form of input filenames runs that have not yet\n"
02471           "    occurred.\n"
02472           "\n"
02473           "    This program can also be used off-line (away from the scanner)\n"
02474           "    to organize the files, run by run.  If the DICOM files have\n"
02475           "    a correct DICOM 'image number' (0x0020 0013), then Dimon can\n"
02476           "    use the information to organize the sequence of the files, \n"
02477           "    particularly when the alphabetization of the filenames does\n"
02478           "    not match the sequencing of the slice positions.  This can be\n"
02479           "    used in conjunction with the '-GERT_Reco' option, which will\n"
02480           "    write a script that can be used to create AFNI datasets.\n"
02481           "\n"
02482           "    See the '-dicom_org' option, under 'other options', below.\n"
02483           "\n"
02484           "    If no -quit option is provided, the user should terminate the\n"
02485           "    program when it is done collecting images according to the\n"
02486           "    input file pattern.\n"
02487           "\n"
02488           "    Dimon can be terminated using <ctrl-c>.\n"
02489           "\n"
02490           "  ---------------------------------------------------------------\n"
02491           "  realtime notes for running afni remotely:\n"
02492           "\n"
02493           "    - The afni program must be started with the '-rt' option to\n"
02494           "      invoke the realtime plugin functionality.\n"
02495           "\n"
02496           "    - If afni is run remotely, then AFNI_TRUSTHOST will need to be\n"
02497           "      set on the host running afni.  The value of that variable\n"
02498           "      should be set to the IP address of the host running %s.\n"
02499           "      This may set as an environment variable, or via the .afnirc\n"
02500           "      startup file.\n"
02501           "\n"
02502           "    - The typical default security on a Linux system will prevent\n"
02503           "      %s from communicating with afni on the host running afni.\n"
02504           "      The iptables firewall service on afni's host will need to be\n"
02505           "      configured to accept the communication from the host running\n"
02506           "      %s, or it (iptables) will need to be turned off.\n"
02507           "  ---------------------------------------------------------------\n"
02508           "  usage: %s [options] -infile_prefix PREFIX\n"
02509           "     OR: %s [options] -infile_pattern \"PATTERN\"\n"
02510           "\n"
02511           "  ---------------------------------------------------------------\n"
02512           "  examples (no real-time options):\n"
02513           "\n"
02514           "    %s -infile_pattern 's8912345/i*'\n"
02515           "    %s -infile_prefix   s8912345/i\n"
02516           "    %s -help\n"
02517           "    %s -infile_prefix   s8912345/i  -quit\n"
02518           "    %s -infile_prefix   s8912345/i  -nt 120 -quit\n"
02519           "    %s -infile_prefix   s8912345/i  -debug 2\n"
02520           "    %s -infile_prefix   s8912345/i  -dicom_org -GERT_Reco -quit\n"
02521           "\n"
02522           "  examples (with real-time options):\n"
02523           "\n"
02524           "    %s -infile_prefix s8912345/i -rt \n"
02525           "\n"
02526           "    %s -infile_pattern 's*/i*' -rt \n"
02527           "    %s -infile_pattern 's*/i*' -rt -nt 120\n"
02528           "    %s -infile_pattern 's*/i*' -rt -quit\n"
02529           "\n"
02530           "  ** detailed real-time example:\n"
02531           "    %s                                    \\\n"
02532           "       -infile_pattern 's*/i*'               \\\n"
02533           "       -rt -nt 120                           \\\n"
02534           "       -host some.remote.computer            \\\n"
02535           "       -rt_cmd \"PREFIX 2005_0513_run3\"     \\\n"
02536           "       -quit                                 \n"
02537           "\n"
02538           "    This example scans data starting from directory 003, expects\n"
02539           "    160 repetitions (TRs), and invokes the real-time processing,\n"
02540           "    sending data to a computer called some.remote.computer.name\n"
02541           "    (where afni is running, and which considers THIS computer to\n"
02542           "    be trusted - see the AFNI_TRUSTHOST environment variable).\n"
02543           "\n"
02544           "  ---------------------------------------------------------------\n"
02545           "    Multiple DRIVE_AFNI commands are passed through '-drive_afni'\n"
02546           "    options, one requesting to open an axial image window, and\n"
02547           "    another requesting an axial graph, with 160 data points.\n"
02548           "\n"
02549           "    See README.driver for acceptable DRIVE_AFNI commands.\n"
02550           "\n"
02551           "    Also, multiple commands specific to the real-time plugin are\n"
02552           "    passed via '-rt_cmd' options.  The PREFIX command sets the\n"
02553           "    prefix for the datasets output by afni.  The GRAPH_XRANGE and\n"
02554           "    GRAPH_YRANGE commands set the graph dimensions for the 3D\n"
02555           "    motion correction graph (only).  And the GRAPH_EXPR command\n"
02556           "    is used to replace the 6 default motion correction graphs with\n"
02557           "    a single graph, according to the given expression, the square\n"
02558           "    root of the average squared entry of the 3 rotaion parameters,\n"
02559           "    roll, pitch and yaw, ignoring the 3 shift parameters, dx, dy\n"
02560           "    and dz.\n"
02561           "\n"
02562           "    See README.realtime for acceptable DRIVE_AFNI commands.\n"
02563           "\n"
02564           "    %s                                                   \\\n"
02565           "       -infile_pattern 's*/i*.dcm'                         \\\n"
02566           "       -nt 160                                             \\\n"
02567           "       -rt                                                 \\\n"
02568           "       -host some.remote.computer.name                     \\\n"
02569           "       -drive_afni 'OPEN_WINDOW axialimage'                \\\n"
02570           "       -drive_afni 'OPEN_WINDOW axialgraph pinnum=160'     \\\n"
02571           "       -rt_cmd 'PREFIX eat.more.cheese'                    \\\n"
02572           "       -rt_cmd 'GRAPH_XRANGE 160'                          \\\n"
02573           "       -rt_cmd 'GRAPH_YRANGE 1.02'                         \\\n"
02574           "       -rt_cmd 'GRAPH_EXPR sqrt((d*d+e*e+f*f)/3)'            \n"
02575           "\n"
02576           "  ---------------------------------------------------------------\n",
02577           prog, prog, prog, prog, prog, prog,
02578           prog, prog, prog, prog, prog, prog,
02579           prog, prog, prog, prog, prog, prog, prog );
02580           
02581         printf(
02582           "  notes:\n"
02583           "\n"
02584           "    - Once started, unless the '-quit' option is used, this\n"
02585           "      program exits only when a fatal error occurs (single\n"
02586           "      missing or out of order slices are not considered fatal).\n"
02587           "      Otherwise, it keeps waiting for new data to arrive.\n"
02588           "\n"
02589           "      With the '-quit' option, the program will terminate once\n"
02590           "      there is a significant (~2 TR) pause in acquisition.\n"
02591           "\n"
02592           "    - To terminate this program, use <ctrl-c>.\n"
02593           "\n"
02594           "  ---------------------------------------------------------------\n"
02595           "  main options:\n"
02596           "\n"
02597           "    For DICOM images, either -infile_pattern or -infile_prefix\n"
02598           "    is required.\n"
02599           "\n"
02600           "    -infile_pattern PATTERN : specify pattern for input files\n"
02601           "\n"
02602           "        e.g. -infile_pattern 'run1/i*.dcm'\n"
02603           "\n"
02604           "        This option is used to specify a wildcard pattern matching\n"
02605           "        the names of the input DICOM files.  These files should be\n"
02606           "        sorted in the order that they are to be assembled, i.e.\n"
02607           "        when the files are sorted alphabetically, they should be\n"
02608           "        sequential slices in a volume, and the volumes should then\n"
02609           "        progress over time (as with the 'to3d' program).\n"
02610           "\n"
02611           "        The pattern for this option must be within quotes, because\n"
02612           "        it will be up to the program to search for new files (that\n"
02613           "        match the pattern), not the shell.\n"
02614           "\n"
02615           "    -infile_prefix PREFIX   : specify prefix matching input files\n"
02616           "\n"
02617           "        e.g. -infile_prefix run1/i\n"
02618           "\n"
02619           "        This option is similar to -infile_pattern.  By providing\n"
02620           "        only a prefix, the user need not use wildcard characters\n"
02621           "        with quotes.  Using PREFIX with -infile_prefix is\n"
02622           "        equivalent to using 'PREFIX*' with -infile_pattern (note\n"
02623           "        the needed quotes).\n"
02624           "\n"
02625           "        Note that it may not be a good idea to use, say 'run1/'\n"
02626           "        for the prefix, as there might be a readme file under\n"
02627           "        that directory.\n"
02628           "\n"
02629           "        Note also that it is necessary to provide a '/' at the\n"
02630           "        end, if the prefix is a directory (e.g. use run1/ instead\n"
02631           "        of simply run1).\n"
02632           "\n"
02633           "  ---------------------------------------------------------------\n"
02634           "  real-time options:\n"
02635           "\n"
02636           "    -rt                : specify to use the real-time facility\n"
02637           "\n"
02638           "        With this option, the user tells '%s' to use the real-time\n"
02639           "        facility, passing each volume of images to an existing\n"
02640           "        afni process on some machine (as specified by the '-host'\n"
02641           "        option).  Whenever a new volume is aquired, it will be\n"
02642           "        sent to the afni program for immediate update.\n"
02643           "\n"
02644           "        Note that afni must also be started with the '-rt' option\n"
02645           "        to make use of this.\n"
02646           "\n"
02647           "        Note also that the '-host HOSTNAME' option is not required\n"
02648           "        if afni is running on the same machine.\n"
02649           "\n"
02650           "    -drive_afni CMND   : send 'drive afni' command, CMND\n"
02651           "\n"
02652           "        e.g.  -drive_afni 'OPEN_WINDOW axialimage'\n"
02653           "\n"
02654           "        This option is used to pass a single DRIVE_AFNI command\n"
02655           "        to afni.  For example, 'OPEN_WINDOW axialimage' will open\n"
02656           "        such an axial view window on the afni controller.\n"
02657           "\n"
02658           "        Note: the command 'CMND' must be given in quotes, so that\n"
02659           "              the shell will send it as a single parameter.\n"
02660           "\n"
02661           "        Note: this option may be used multiple times.\n"
02662           "\n"
02663           "        See README.driver for more details.\n"
02664           "\n"
02665           "    -host HOSTNAME     : specify the host for afni communication\n"
02666           "\n"
02667           "        e.g.  -host mycomputer.dot.my.network\n"
02668           "        e.g.  -host 127.0.0.127\n"
02669           "        e.g.  -host mycomputer\n"
02670           "        the default host is 'localhost'\n"
02671           "\n"
02672           "        The specified HOSTNAME represents the machine that is\n"
02673           "        running afni.  Images will be sent to afni on this machine\n"
02674           "        during the execution of '%s'.\n"
02675           "\n"
02676           "        Note that the enviroment variable AFNI_TRUSTHOST must be\n"
02677           "        set on the machine running afni.  Set this equal to the\n"
02678           "        name of the machine running Imon (so that afni knows to\n"
02679           "        accept the data from the sending machine).\n"
02680           "\n"
02681           "    -pause TIME_IN_MS : pause after each new volume\n"
02682           "\n"
02683           "        e.g.  -pause 200\n"
02684           "\n"
02685           "        In some cases, the user may wish to slow down a real-time\n"
02686           "        process.  This option will cause a delay of TIME_IN_MS\n"
02687           "        milliseconds after each volume is found.\n"
02688           "\n"
02689           "    -rev_byte_order   : pass the reverse of the BYTEORDER to afni\n"
02690           "\n"
02691           "        Reverse the byte order that is given to afni.  In case the\n"
02692           "        detected byte order is not what is desired, this option\n"
02693           "        can be used to reverse it.\n"
02694           "\n"
02695           "        See the (obsolete) '-swap' option for more details.\n"
02696           "\n"
02697           "    -rt_cmd COMMAND   : send COMMAND(s) to realtime plugin\n"
02698           "\n"
02699           "        e.g.  -rt_cmd 'GRAPH_XRANGE 120'\n"
02700           "        e.g.  -rt_cmd 'GRAPH_XRANGE 120 \\n GRAPH_YRANGE 2.5'\n"
02701           "\n"
02702           "        This option is used to pass commands to the realtime\n"
02703           "        plugin.  For example, 'GRAPH_XRANGE 120' will set the\n"
02704           "        x-scale of the motion graph window to 120 (repetitions).\n"
02705           "\n"
02706           "        Note: the command 'COMMAND' must be given in quotes, so\n"
02707           "        that the shell will send it as a single parameter.\n"
02708           "\n"
02709           "        Note: this option may be used multiple times.\n"
02710           "\n"
02711           "        See README.realtime for more details.\n"
02712           "\n"
02713           "    -swap  (obsolete) : swap data bytes before sending to afni\n"
02714           "\n"
02715           "        Since afni may be running on a different machine, the byte\n"
02716           "        order may differ there.  This option will force the bytes\n"
02717           "        to be reversed, before sending the data to afni.\n"
02718           "\n"
02719           "        ** As of version 3.0, this option should not be necessary.\n"
02720           "           '%s' detects the byte order of the image data, and then\n"
02721           "           passes that information to afni.  The realtime plugin\n"
02722           "           will (now) decide whether to swap bytes in the viewer.\n"
02723           "\n"
02724           "           If for some reason the user wishes to reverse the order\n"
02725           "           from what is detected, '-rev_byte_order' can be used.\n"
02726           "\n"
02727           "    -zorder ORDER     : slice order over time\n"
02728           "\n"
02729           "        e.g. -zorder alt\n"
02730           "        e.g. -zorder seq\n"
02731           "        the default is 'alt'\n"
02732           "\n"
02733           "        This options allows the user to alter the slice\n"
02734           "        acquisition order in real-time mode, simliar to the slice\n"
02735           "        pattern of the '-sp' option.  The main differences are:\n"
02736           "            o  only two choices are presently available\n"
02737           "            o  the syntax is intentionally different (from that\n"
02738           "               of 'to3d' or the '-sp' option)\n"
02739           "\n"
02740           "        ORDER values:\n"
02741           "            alt   : alternating in the Z direction (over time)\n"
02742           "            seq   : sequential in the Z direction (over time)\n"
02743           "\n"
02744           "  ---------------------------------------------------------------\n"
02745           "  other options:\n"
02746           "\n"
02747           "    -debug LEVEL       : show debug information during execution\n"
02748           "\n"
02749           "        e.g.  -debug 2\n"
02750           "        the default level is 1, the domain is [0,3]\n"
02751           "        the '-quiet' option is equivalent to '-debug 0'\n"
02752           "\n"
02753           "    -dicom_org         : organize files before other processing\n"
02754           "\n"
02755           "        e.g.  -dicom_org\n"
02756           "\n"
02757           "        When this flag is set, the program will attempt to read in\n"
02758           "        all files subject to -infile_prefix or -infile_pattern,\n"
02759           "        determine which are DICOM image files, and organize them\n"
02760           "        into an ordered list of files per run.\n"
02761           "\n"
02762           "        This may be necessary since the alphabetized list of files\n"
02763           "        will not always match the sequential slice and time order\n"
02764           "        (which means, for instance, that '*.dcm' may not list\n"
02765           "        files in the correct order.\n"
02766           "\n"
02767           "        In this case, if the DICOM files contain a valid 'image\n"
02768           "        number' field (0x0020 0013), then they will be sorted\n"
02769           "        before any further processing is done.\n"
02770           "\n"
02771           "        Notes:\n"
02772           "\n"
02773           "        - This does not work in real-time mode, since the files\n"
02774           "          must all be organized before processing begins.\n"
02775           "\n"
02776           "        - The DICOM images need valid 'image number' fields for\n"
02777           "          organization to be possible (DICOM field 0x0020 0013).\n"
02778           "\n"
02779           "        - This works will in conjunction with '-GERT_Reco', to\n"
02780           "          create a script to make AFNI datasets.  There will be\n"
02781           "          a single file per run that contains the image filenames\n"
02782           "          for that run (in order).  This is fed to 'to3d'.\n"
02783           "\n"
02784           "    -help              : show this help information\n"
02785           "\n"
02786           "    -hist              : display a history of program changes\n"
02787           "\n"
02788           "    -nice INCREMENT    : adjust the nice value for the process\n"
02789           "\n"
02790           "        e.g.  -nice 10\n"
02791           "        the default is 0, and the maximum is 20\n"
02792           "        a superuser may use down to the minimum of -19\n"
02793           "\n"
02794           "        A positive INCREMENT to the nice value of a process will\n"
02795           "        lower its priority, allowing other processes more CPU\n"
02796           "        time.\n"
02797           "\n"
02798           "    -nt VOLUMES_PER_RUN : set the number of time points per run\n"
02799           "\n"
02800           "        e.g.  -nt 120\n"
02801           "\n"
02802           "        With this option, if a run stalls before the specified\n"
02803           "        VOLUMES_PER_RUN is reached (notably including the first\n"
02804           "        run), the user will be notified.\n"
02805           "\n"
02806           "        Without this option, %s will compute the expected number\n"
02807           "        of time points per run based on the first run (and will\n"
02808           "        allow the value to increase based on subsequent runs).\n"
02809           "        Therefore %s would not detect a stalled first run.\n"
02810           "\n"
02811           "    -quiet             : show only errors and final information\n"
02812           "\n"
02813           "    -quit              : quit when there is no new data\n"
02814           "\n"
02815           "        With this option, the program will terminate once a delay\n"
02816           "        in new data occurs.  This is most appropriate to use when\n"
02817           "        the image files have already been collected.\n"
02818           "\n"
02819           "    -start_file S_FILE : have %s process starting at S_FILE\n"
02820           "\n"
02821           "        e.g.  -start_file 043/I.901\n"
02822           "\n"
02823           "        With this option, any earlier I-files will be ignored\n"
02824           "        by %s.  This is a good way to start processing a later\n"
02825           "        run, if it desired not to look at the earlier data.\n"
02826           "\n"
02827           "        In this example, all files in directories 003 and 023\n"
02828           "        would be ignored, along with everything in 043 up through\n"
02829           "        I.900.  So 043/I.901 might be the first file in run 2.\n"
02830           "\n"
02831           "    -use_imon          : revert to Imon functionality\n"
02832           "\n"
02833           "    -version           : show the version information\n"
02834           "\n"
02835           "  ---------------------------------------------------------------\n"
02836           "  GERT_Reco options:\n"
02837           "\n"
02838           "    -GERT_Reco        : output a GERT_Reco_dicom script\n"
02839           "\n"
02840           "        Create a script called 'GERT_Reco_dicom', similar to the\n"
02841           "        one that Ifile creates.  This script may be run to create\n"
02842           "        the AFNI datasets corresponding to the I-files.\n"
02843           "\n"
02844           "    -gert_outdir OUTPUT_DIR  : set output directory in GERT_Reco\n"
02845           "\n"
02846           "        e.g. -gert_outdir subject_A7\n"
02847           "        e.g. -od subject_A7\n"
02848           "        the default is '-gert_outdir .'\n"
02849           "\n"
02850           "        This will add '-od OUTPUT_DIR' to the @RenamePanga command\n"
02851           "        in the GERT_Reco script, creating new datasets in the\n"
02852           "        OUTPUT_DIR directory, instead of the 'afni' directory.\n"
02853           "\n"
02854           "    -sp SLICE_PATTERN  : set output slice pattern in GERT_Reco\n"
02855           "\n"
02856           "        e.g. -sp alt-z\n"
02857           "        the default is 'alt+z'\n"
02858           "\n"
02859           "        This options allows the user to alter the slice\n"
02860           "        acquisition pattern in the GERT_Reco script.\n"
02861           "\n"
02862           "        See 'to3d -help' for more information.\n"
02863           "\n"
02864           "  ---------------------------------------------------------------\n"
02865           "\n"
02866           "  Author: R. Reynolds - %s\n"
02867           "\n",
02868           prog, prog, prog, prog, prog, prog, prog,
02869           DIMON_VERSION
02870         );
02871 
02872         return 0;
02873     }
02874     else if ( level == IFM_USE_HIST )
02875     {
02876         fputs( g_history, stdout );
02877         return 0;
02878     }
02879     else if ( level == IFM_USE_VERSION )
02880     {
02881         printf( "%s: %s, compile date: %s\n",
02882                 prog, DIMON_VERSION, __DATE__ );
02883         return 0;
02884     }
02885 
02886     fprintf( stderr, "error: usage() called with illegal level <%d>\n", level );
02887 
02888     return -1;
02889 }

int volume_match vol_t   vin,
vol_t   vout,
param_t   p,
int    start
[static]
 

Definition at line 747 of file Dimon.c.

References check_error(), find_next_zoff(), vol_t::first_file, vol_t::fl_1, param_t::flist, vol_t::fn_1, vol_t::fn_n, param_t::fnames, vol_t::geh, finfo_t::geh, vol_t::gex, IFM_BIG_ERROR_MESG, IFM_EPSILON, IFM_MAX_FLEN, finfo_t::index, vol_t::last_file, IFM_debug::level, vol_t::nim, param_t::nused, p, vol_t::run, vol_t::seq_num, ge_header_info::tr, ge_header_info::uv17, vol_t::z_delta, vol_t::z_first, vol_t::z_last, and ge_header_info::zoff.

00748 {
00749     static int   retry = 1;                             /* v2.12 */
00750     finfo_t    * fp;
00751     finfo_t    * fp_test;
00752     float        z;
00753     int          count, next_start = -1;
00754     int          missing = 0;
00755 
00756     if ( vin == NULL || vout == NULL ||
00757          p == NULL || p->flist == NULL || start < 0 )
00758     {
00759         fprintf( stderr, "failure: FMV: bad parameter data\n" );
00760         return -2;
00761     }
00762 
00763     if ( (p->nused - start) < vin->nim )        /* enough files to scan? */
00764         return 0;
00765 
00766     /* now 'everything' should match */
00767 
00768     fp = p->flist+start;
00769     for ( count = 0; count < vin->nim - 1; count++ )   /* last is separate */
00770     {
00771         z = vin->z_first + count * vin->z_delta;        /* note expected z */
00772 
00773         if ( fabs( z - fp->geh.zoff ) > IFM_EPSILON )
00774         {
00775             /* slice is either missing or out of order */
00776 
00777             fp_test = fp + 1;                          /* check next image */
00778             if ( fabs( z + vin->z_delta - fp_test->geh.zoff ) < IFM_EPSILON )
00779             {
00780                 /* report the error?                v2.12 */
00781                 if ( !check_error(&retry, vin->geh.tr, "slice out of order") )
00782                     return 0;
00783 
00784                 /* next slice as expected, so current is out of order */
00785                 /* nothing to do but warn the user and continue */
00786 
00787                 IFM_BIG_ERROR_MESG( "slice out of order!",
00788                         p->fnames[fp->index], z, fp->geh.zoff,
00789                         fp->geh.uv17, count + 1, vin->nim );
00790             }
00791             else if ( fabs(z + vin->z_delta - fp->geh.zoff) < IFM_EPSILON )
00792             {
00793                 /* current slice matches next expected - slice missing */
00794 
00795                 /* report the error? */
00796                 if ( !check_error(&retry, vin->geh.tr, "slice missing") )
00797                     return 0;
00798 
00799                 /* nothing to do but note error, warn user and continue */
00800                 missing++;
00801 
00802                 IFM_BIG_ERROR_MESG( "slice missing!",
00803                         p->fnames[fp->index], z, fp->geh.zoff,
00804                         fp->geh.uv17, count + 1, vin->nim );
00805 
00806                 count++;    /* attempt to continue by skipping this slice */
00807             }
00808             else        /* unknown error - find start of next volume */
00809             {
00810                 /* search for a next starting point */
00811                 next_start = find_next_zoff( p, start+count, vin->z_first );
00812 
00813                 if ( next_start < 0 )   /* come back and try again later */
00814                     return 0;
00815                 else
00816                 {
00817                     /* report error? */
00818                     if ( !check_error(&retry, vin->geh.tr, "vol toasted") )
00819                         return 0;
00820 
00821                     IFM_BIG_ERROR_MESG( "volume severely toasted!",
00822                             p->fnames[fp->index], z, fp->geh.zoff,
00823                             fp->geh.uv17, count + 1, vin->nim );
00824 
00825                     break;      /* terminate for loop and try to recover */
00826                 }
00827             }
00828         }
00829 
00830         fp++;
00831     }
00832 
00833     z = vin->z_first + count * vin->z_delta;      /* note expected z   */
00834 
00835     if ( count >= vin->nim )    /* missed second to last slice */
00836         next_start = start + vin->nim - missing;
00837     else if ( (next_start < 0) && (fabs( z - fp->geh.zoff ) > IFM_EPSILON) )
00838     {
00839         /* check last slice - count and fp should be okay*/
00840         if ( (p->nused - start) <= vin->nim )   /* no more images to check */
00841             return 0;                           /* wait for more data      */
00842         
00843         fp_test = fp + 1;                              /* check next image */
00844         if ( fabs( vin->z_first - fp_test->geh.zoff ) < IFM_EPSILON )
00845         {
00846             /* next image starts next run, slice is probably out of order */
00847 
00848             /* report error? */
00849             if ( !check_error(&retry, vin->geh.tr, "last slice out of order") )
00850                 return 0;
00851 
00852             IFM_BIG_ERROR_MESG( "last slice out of order!",
00853                     p->fnames[fp->index], z, fp->geh.zoff,
00854                     fp->geh.uv17, count + 1, vin->nim );
00855         }
00856         else if ( fabs(vin->z_first - fp->geh.zoff) < IFM_EPSILON )
00857         {
00858             /* this image starts next run, slice is missing */
00859 
00860             /* report error? */
00861             if ( !check_error(&retry, vin->geh.tr, "last slice missing") )
00862                 return 0;
00863 
00864             missing++;
00865 
00866             IFM_BIG_ERROR_MESG( "last slice missing!",
00867                     p->fnames[fp->index], z, fp->geh.zoff,
00868                     fp->geh.uv17, count + 1, vin->nim );
00869         }
00870         else    /* unknown error - find start of next volume */
00871         {
00872             /* search for a next starting point */
00873             next_start = find_next_zoff( p, start+count+1, vin->z_first );
00874 
00875             if ( next_start < 0 )       /* come back and try again later */
00876                 return 0;
00877             else
00878             {
00879                 /* report error? */
00880                 if ( !check_error(&retry, vin->geh.tr, "Vol toasted") )
00881                     return 0;
00882 
00883                 IFM_BIG_ERROR_MESG( "Volume severely toasted!",
00884                         p->fnames[fp->index], z, fp->geh.zoff,
00885                         fp->geh.uv17, count + 1, vin->nim );
00886             }
00887         }
00888     }
00889 
00890     if ( next_start < 0)
00891         next_start = start + vin->nim - missing;
00892 
00893     if ( retry == 0 && gD.level > 0 )                   /* v2.12 */
00894         fprintf(stderr," (retry OK - no errors)\n");
00895 
00896     retry = 1;                          /* next error gets two tries - v2.12 */
00897 
00898     /* fill volume structure */
00899 
00900     vout->geh      = p->flist[start].geh;
00901     vout->gex      = p->flist[start].gex;
00902     vout->nim      = next_start - start;
00903     vout->fl_1     = start;
00904     vout->fn_1     = p->flist[start].index;
00905     vout->fn_n     = p->flist[start+vout->nim-1].index;
00906     strncpy( vout->first_file, p->fnames[vout->fn_1], IFM_MAX_FLEN );
00907     strncpy( vout->last_file,  p->fnames[vout->fn_n],  IFM_MAX_FLEN );
00908     vout->z_first  = vin->z_first;
00909     vout->z_last   = vin->z_last;
00910     vout->z_delta  = vin->z_delta;
00911     vout->seq_num  = -1;                                /* uninitialized */
00912     vout->run      = vout->geh.uv17;
00913 
00914     if ( vout->nim != vin->nim )
00915         return -1;
00916     else
00917         return 1;
00918 }

int volume_search vol_t   V,
param_t   p,
int    start,
int    maxsl,
int *    fl_start,
int *    state
[static]
 

Definition at line 479 of file Dimon.c.

References abs, check_one_volume(), vol_t::first_file, vol_t::fl_1, param_t::flist, vol_t::fn_1, vol_t::fn_n, param_t::fnames, vol_t::geh, vol_t::gex, IFM_EPSILON, IFM_MAX_FLEN, vol_t::last_file, vol_t::nim, param_t::nused, param_t::opts, p, vol_t::run, vol_t::seq_num, opts_t::use_dicom, ge_header_info::uv17, vol_t::z_delta, vol_t::z_first, and vol_t::z_last.

00486 {
00487     float      delta;
00488     int        bound;                   /* upper bound on image slice  */
00489     static int prev_bound = -1;         /* note previous 'bound' value */
00490     int        first = start;           /* first image (start or s+1)  */
00491     int        last;                    /* final image in volume       */
00492     int        rv;
00493 
00494     if ( V == NULL || p == NULL || p->flist == NULL || start < 0 )
00495     {
00496         fprintf( stderr, "failure: FNV: bad parameter data\n" );
00497         return -2;
00498     }
00499 
00500     /* note the bound on the slice index */
00501     if ( (maxsl <= 0) || ((maxsl + first) >= p->nused) )
00502         bound = p->nused;
00503     else
00504         bound = first + maxsl;
00505 
00506     if ( ( bound-first < 1) ||      /* from 3              8 Jul 2005 */
00507          ((bound-first < 4) && !p->opts.use_dicom) )
00508         return 0;                   /* not enough data to work with   */
00509 
00510     /* maintain the state */
00511     if ( *state == 1 && bound == prev_bound ) *state = 2;  /* try to finish */
00512     else                                      *state = 1;  /* continue mode */
00513     prev_bound = bound;
00514 
00515     rv = check_one_volume(p,start,fl_start,bound,*state, &first,&last,&delta);
00516 
00517     if ( rv == 1 )
00518     {
00519         /* One volume exists from slice 'first' to slice 'last'. */
00520 
00521         V->geh      = p->flist[first].geh;         /* copy GE structure  */
00522         V->gex      = p->flist[first].gex;         /* copy GE extras     */
00523         V->nim      = last - first + 1;
00524         V->fl_1     = first;
00525         V->fn_1     = p->flist[first].index;
00526         V->fn_n     = p->flist[last].index;
00527         strncpy( V->first_file, p->fnames[V->fn_1], IFM_MAX_FLEN );
00528         strncpy( V->last_file,  p->fnames[V->fn_n], IFM_MAX_FLEN );
00529         V->z_first  = p->flist[first].geh.zoff;
00530         V->z_last   = p->flist[last].geh.zoff;
00531         V->z_delta  = delta;
00532         V->seq_num  = -1;                               /* uninitialized */
00533         V->run      = V->geh.uv17;
00534 
00535         return 1;
00536     }
00537     else if ( rv == 0 )
00538         return 0;                           /* we did not finish a volume */
00539     else if ( rv == -1 )
00540     {
00541         /* We have gone in the wrong direction.  This means that the
00542          * starting slice was not the first in the volume.  Try restarting
00543          * from the current position.  */
00544         fprintf( stderr, "\n"
00545                 "*************************************************\n"
00546                 "Error: missing slice(s) in first volume!\n"
00547                 "       attempting to re-start at file: %s\n"
00548                 "*************************************************\n",
00549                 p->fnames[p->flist[last+1].index] );
00550         *fl_start = p->flist[last+1].index;
00551     }
00552     else /* ( rv == -2 ) : right direction, but bad delta */
00553     {
00554         /* the next slice does not match the original - interleaving? */
00555         int testc;
00556         for ( testc = last; testc < bound; testc++ )
00557             if ( abs( p->flist[first].geh.zoff -
00558                       p->flist[testc].geh.zoff ) < IFM_EPSILON )
00559             {
00560                 /* aaaaagh!  we are missing data from the first volume!   */
00561                 /* print error, and try to skip this volume               */
00562                 fprintf( stderr, "\n"
00563                         "*************************************************\n"
00564                         "Error: missing slice in first volume!\n"
00565                         "       detected    at file: %s\n"
00566                         "       re-starting at file: %s\n"
00567                         "*************************************************\n",
00568                         p->fnames[p->flist[last+1].index],
00569                         p->fnames[p->flist[testc].index] );
00570 
00571                 /* try to skip this volume and recover */
00572                 *fl_start = p->flist[testc].index;
00573 
00574                 return -1;
00575             }
00576 
00577         /* we didn't find the original zoff, wait for more files */
00578         return 0;
00579     }
00580 
00581     return -1;  /* should not reach here */
00582 }

Variable Documentation

char DI_MRL_orients[8]
 

Definition at line 87 of file Dimon.c.

Referenced by complete_orients_str(), r_mri_read_dicom(), and read_dicom_image().

float DI_MRL_tr
 

Definition at line 88 of file Dimon.c.

Referenced by r_mri_read_dicom(), and read_dicom_image().

char g_history[] [static]
 

Initial value:

    "----------------------------------------------------------------------\n"
    " history:\n"
    "\n"
    " 1.0  Jul  5, 2005 [rickr] - initial release\n"
    " 1.1  Jul 13, 2005 [rickr] - process run of fewer than 3 slices\n"
    " 1.2  Jul 22, 2005 [rickr] - use IOCHAN_CLOSENOW() in realtime.c\n"
    " 1.3  Jul 25, 2005 [rickr] - force tcp close for multiple term signals\n"
    " 2.0  Jul 29, 2005 [rickr] - DICOM file organizer\n"
    "      - add -dicom_org option, to try to organize the image files\n"
    "      - enable GERT_Reco option for DICOM files\n"
    "----------------------------------------------------------------------\n"

Definition at line 2 of file Dimon.c.

Referenced by usage().

ART_comm gAC
 

Definition at line 163 of file Dimon.c.

IFM_debug gD
 

Definition at line 160 of file Dimon.c.

param_t gP
 

Definition at line 161 of file Dimon.c.

struct dimon_stuff_t gr_dimon_stuff
 

Referenced by read_dicom_image().

stats_t gS
 

Definition at line 162 of file Dimon.c.

 

Powered by Plone

This site conforms to the following standards: