1 #include "mrilib.h"
2
3 #define NFMAX 26
4
main(int argc,char * argv[])5 int main( int argc , char *argv[] )
6 {
7 int iarg=1 ;
8 int do_divorce=0 ;
9 char *sep = "*," ; int nsep=2 ;
10 char *filex[NFMAX] ; int nfilex , vv ;
11 float filler=3.e+33 ;
12
13 /*------------------------------------------------------------------------*/
14
15 if( argc < 3 || strcmp(argv[1],"-help") == 0 ){
16 printf(
17 "Usage: 1dMarry [options] file1 file2 ...\n"
18 "\n"
19 " Joins together 2 (or more) ragged-right .1D files, for use with\n"
20 " 3dDeconvolve -stim_times_AM2.\n"
21 " **_OR_**\n"
22 " Breaks up 1 married file into 2 (or more) single-valued files.\n"
23 "\n"
24 "OPTIONS:\n"
25 "=======\n"
26 " -sep abc == Use the first character (e.g., 'a') as the separator\n"
27 " between values 1 and 2, the second character (e.g., 'b')\n"
28 " as the separator between values 2 and 3, etc.\n"
29 " * These characters CANNOT be a blank, a tab, a digit,\n"
30 " or a non-printable control character!\n"
31 " * Default separator string is '*,' which will result\n"
32 " in output similar to '3*4,5,6'\n"
33 "\n"
34 " -divorce == Instead of marrying the files, assume that file1\n"
35 " is already a married file: split time*value*value... tuples\n"
36 " into separate files, and name them in the pattern\n"
37 " 'file2_A.1D' 'file2_B.1D' et cetera.\n"
38 "\n"
39 "If not divorcing, the 'married' file is written to stdout, and\n"
40 "probably should be captured using a redirection such as '>'.\n"
41 "\n"
42 "NOTES:\n"
43 "=====\n"
44 "* You cannot use column [...] or row {...} selectors on\n"
45 " ragged-right .1D files, so don't even think about trying!\n"
46 "* The maximum number of values that can be married is %d.\n"
47 " (No polygamy or polyandry jokes here, please.)\n"
48 "* For debugging purposes, with '-divorce', if 'file2' is '-',\n"
49 " then all the divorcees are written directly to stdout.\n"
50 "\n"
51 "-- RWCox -- written hastily in March 2007 -- hope I don't repent\n"
52 " -- modified to deal with multiple marriages -- December 2008\n"
53
54 , NFMAX
55 ) ;
56 PRINT_COMPILE_DATE ; exit(0) ;
57 }
58
59 /*------------------------------------------------------------------------*/
60
61 while( iarg < argc && argv[iarg][0] == '-' ){
62
63 if( strcmp(argv[iarg],"-divorce") == 0 ){
64 do_divorce = 1 ; iarg++ ; continue ;
65 }
66
67 if( strcmp(argv[iarg],"-sep") == 0 ){
68 int jj ;
69 iarg++ ;
70 if( iarg >= argc )
71 ERROR_exit("1dMarry: need argument after '-sep'") ;
72 sep = argv[iarg] ; nsep = strlen(sep) ;
73 if( nsep < 1 ){
74 WARNING_message("Replacing empty '-sep' option with default") ;
75 sep = "*," ; nsep = 2 ;
76 }
77 for( jj=0 ; jj < nsep ; jj++ ){
78 if( isspace(sep[jj]) || iscntrl(sep[jj]) || isdigit(sep[jj]) )
79 ERROR_exit("1dMarry: Illegal character after '-sep'") ;
80 }
81 iarg++ ; continue ;
82 }
83
84 ERROR_exit("1dMarry: Unknown option '%s'",argv[iarg]) ;
85 }
86
87 /*------------------------------------------------------------------------*/
88
89 /** copy filenames to something more convenient **/
90
91 for( nfilex=0 ; iarg < argc && nfilex < NFMAX ; iarg++,nfilex++ )
92 filex[nfilex] = argv[iarg] ;
93
94 /** check for various stoopidities **/
95
96 if( nfilex == 0 )
97 ERROR_exit("1dMarry: need filenames at end of command line!") ;
98
99 if( !do_divorce && nfilex == NFMAX && iarg < argc )
100 WARNING_message("Maximum number of marriages (%d) exceeded!",NFMAX) ;
101 else if( do_divorce && nfilex > 2 )
102 WARNING_message("Divorcing ==> filenames after #2 are ignored!") ;
103
104 if( !THD_is_file(filex[0]) )
105 ERROR_exit("1dMarry: file '%s' does not exist!",filex[0]) ;
106
107 if( !do_divorce ){ /* check all input files to see if */
108 int nbad ; /* they are willing to be married */
109 if( nfilex < 2 )
110 ERROR_exit("Need at least 2 input filenames to perform the marriage!") ;
111 for( nbad=0,vv=1 ; vv < nfilex ; vv++ ){
112 if( !THD_is_file(filex[vv]) ){
113 ERROR_message("1Dmarry: file '%s' does not exist!",filex[vv]) ;
114 nbad++ ;
115 }
116 }
117 if( nbad > 0 )
118 ERROR_exit("The desired nuptials cannot take place!") ;
119
120 } else if( nfilex == 1 ){ /* must create name of divorce file */
121 /* since user didn't give us one */
122 filex[1] = filex[0] ;
123 INFO_message(
124 "No filename given to get divorce results ==> using '%s'",filex[1]) ;
125 }
126
127 /******----------- divorce first, it's easier -----------******/
128
129 if( do_divorce ){
130
131 MRI_IMAGE *vim ; MRI_IMARR *vimar ;
132 MRI_IMAGE *aim ; float *aar ; FILE *afp ; char *aname ;
133 int ii,jj , nx,ny , itop , needmult , vdim ;
134
135 vim = mri_read_ascii_ragged_fvect( filex[0] , filler , 0 ) ;
136 if( vim == NULL )
137 ERROR_exit("1dMarry: can't read file '%s' for divorce",filex[0]) ;
138 vimar = mri_fvect_to_imarr(vim) ; mri_free(vim) ;
139 if( vimar == NULL )
140 ERROR_exit("1dMarry: can't process file '%s' for divorce!?!",filex[0]);
141
142 vdim = IMARR_COUNT(vimar) ;
143 if( vdim < 2 )
144 ERROR_exit("1dMarry: file '%s' doesn't have 2+ values to divorce!",filex[0]) ;
145 else if( vdim > NFMAX )
146 ERROR_exit("1dMarry: file '%s' has more than %s values to divorce!",
147 filex[0],NFMAX) ;
148 else
149 INFO_message("1dMarry: divorcing %d values from file '%s'",vdim,filex[0]) ;
150
151 aim = IMARR_SUBIM(vimar,0) ; nx = aim->nx ; ny = aim->ny ;
152 aname = malloc(strlen(filex[1])+20) ;
153
154 for( vv=0 ; vv < vdim ; vv++ ){ /* loop over images */
155 aim = IMARR_SUBIM(vimar,vv) ; aar = MRI_FLOAT_PTR(aim) ;
156 if( strcmp(filex[1],"-") == 0 ){
157 afp = stdout ; strcpy(aname,"stdout") ;
158 } else {
159 sprintf(aname,"%s_%c.1D",filex[1],'A'+vv) ; afp = fopen(aname,"w") ;
160 }
161 if( afp == NULL )
162 ERROR_exit("1dMarry: can't open file '%s' for output!",aname) ;
163
164 needmult = (nx > 1) ;
165 for( jj=0 ; jj < ny ; jj++ ){ /* loop over rows */
166 for( itop=nx-1 ; itop >= 0 ; itop-- ) /* find last good value */
167 if( aar[itop+jj*nx] < filler ) break ;
168 if( itop < 0 ){
169 fprintf(afp," *\n") ; /* indicates no data on this line */
170 } else {
171 needmult = needmult && (itop == 0) ;
172 for( ii=0 ; ii <= itop ; ii++ ){
173 if( aar[ii+jj*nx] < filler ) fprintf(afp," %g",aar[ii+jj*nx]) ;
174 else fprintf(afp," *") ;
175 }
176 }
177 if( itop == 0 && ny > 1 && needmult ){
178 fprintf(afp," *") ; needmult = 0 ;
179 }
180 fprintf(afp,"\n") ;
181 }
182 if( afp != stdout ) fclose(afp) ; else fflush(stdout) ;
183 INFO_message("1dMarry: wrote out file '%s'",aname) ;
184 }
185 DESTROY_IMARR(vimar) ;
186 }
187
188 /******---------------------- Wedding Bells! ----------------------******/
189
190 else {
191
192 MRI_IMAGE *aim ; MRI_IMARR *vimar ;
193 float vval ;
194 int ii,jj , nx=0,ny=0 , itop , needmult , ngood,vdim=nfilex ;
195 FILE *fp=stdout ;
196
197 INIT_IMARR(vimar) ;
198 for( vv=0 ; vv < nfilex ; vv++ ){
199 aim = mri_read_ascii_ragged( filex[vv] , filler ) ;
200 if( aim == NULL )
201 ERROR_exit("1dMarry: can't read file '%s'",filex[vv]) ;
202 if( vv == 0 ){ nx = aim->nx ; ny = aim->ny ; }
203 else if( aim->ny != ny )
204 ERROR_exit("files '%s' and '%s' don't have same number of rows!",
205 filex[0] , filex[vv] ) ;
206 else if( aim->nx != nx )
207 ERROR_exit("files '%s' and '%s' don't have same length of rows!",
208 filex[0] , filex[vv] ) ;
209 ADDTO_IMARR(vimar,aim) ;
210 }
211
212 needmult = (nx > 1) ;
213
214 #define VAL(v,i,j) (MRI_FLOAT_PTR(IMARR_SUBIM(vimar,(v))))[(i)+(j)*nx]
215 #define SEP(i) sep[ ((i)<nsep) ? (i) : nsep-1 ]
216
217 for( jj=0 ; jj < ny ; jj++ ){ /* loop over rows */
218
219 for( itop=nx-1 ; itop >= 0 ; itop-- ){ /* find last good value */
220 for( ngood=vv=0 ; vv < vdim ; vv++ )
221 if( VAL(vv,itop,jj) < filler ) ngood++ ;
222 if( ngood == vdim ) break ; /* at least one good value found at itop */
223 }
224 if( itop < 0 ){
225 fprintf(fp," *\n") ; /* signal that no values are in this row */
226 } else {
227 needmult = needmult && (itop == 0) ;
228 for( ii=0 ; ii <= itop ; ii++ ){
229 fprintf(fp," ") ;
230 for( ngood=vv=0 ; vv < vdim ; vv++ )
231 if( VAL(vv,itop,jj) < filler ) ngood++ ;
232 if( ngood == vdim ){
233 for( vv=0 ; vv < vdim ; vv++ ){
234 vval = VAL(vv,ii,jj) ;
235 if( vval < filler ) fprintf(fp,"%g",vval) ;
236 else fprintf(fp,"*") ;
237 if( vv < vdim-1 ) fprintf(fp,"%c",SEP(vv)) ;
238 }
239 } else {
240 fprintf(fp," *") ;
241 }
242 }
243 if( itop == 0 && ny > 1 && needmult ){ fprintf(fp," *"); needmult = 0; }
244 fprintf(fp,"\n") ; fflush(fp) ;
245 }
246 }
247 if( fp != stdout ) fclose(fp) ;
248 DESTROY_IMARR(vimar) ;
249 }
250
251 exit(0) ;
252 }
253