Change Eclipse configuration
[jabaws.git] / website / archive / binaries / mac / src / fasta34 / map_db.c
1 /* map_db.c - read a FASTA or GCG format database and generate a list
2    of indices for rapid memory mapping */
3
4 /* copyright (c) 1999 William R. Pearson */
5
6 /* $Name: fa_34_26_5 $ - $Id: map_db.c,v 1.9 2005/09/27 15:32:58 wrp Exp $ */
7
8 /* input is a libtype 1,5, or 6 sequence database */
9 /* output is a BLAST2 formatdb type index file */
10
11 /* format of the index file:
12
13 1)  map_db version number ["MP"+2 bytes]
14 2)  number of sequences in database [4 bytes]
15 3)  total length of database        [8 bytes]  (MP1, 4 bytes for MP0)
16 4)  longest sequence in database    [8 bytes]  (MP1, 4 bytes for MP0)
17 5) list of offsets to definitions  [num_seq+1] int*8 (MP1, 4 bytes for MP0)
18 6) list of offsets to sequences    [num_seq+1] int*8 (MP1, 4 bytes for MP1)
19 7) list of flag characters for sequences [num_seq+1]bytes
20     (used for GCG binary to encode 2bit or 4 bit representation)
21
22     sequence files will be as defined by their format
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31
32 #include "uascii.h"
33 #include "ncbl2_head.h"
34
35 #define GCGBIN 6
36 #define LASTLIB 6
37
38 int (*get_entry) ();
39
40 int a_get_ent(long *, long *);
41 int v_get_ent(long *, long *);
42 int gcg_get_ent(long *, long *);
43 int gbf_get_ent(long *, long *);
44
45 void src_int4_write(FILE *, int);
46 void src_int4_read(FILE *, int *);
47 void src_long4_write(FILE *, long);
48 void src_long4_read(FILE *, long *);
49 void src_long8_write(FILE *, long);
50 void src_long8_read(FILE *, long *);
51
52 void newname(char *nname, char *oname, char *suff, int maxn);
53
54 int (*get_ent_arr[LASTLIB+1])()={a_get_ent, gbf_get_ent, NULL, NULL, NULL,
55                                  v_get_ent, gcg_get_ent};
56
57 long openlib(char *, int);
58
59 static int *sascii;
60
61 main(int argc, char **argv)
62 {
63   FILE *libi;
64   char lname[256];
65   char iname[256];
66   char format[4];
67   char *bp;
68
69   int i;
70   int nlib;     /* number of entries */
71
72   long max_len; /* longest sequence */
73   long tot_len; /* total sequence length */
74
75   int n1;
76   
77   long f_size;  /* file size from fstat() */
78   int lib_size; /* current space available - may be realloc'ed */
79   int lib_inc;
80   int lib_type; /* 1 for protein, 0 for DNA */
81   int lib_aa;   /* dna=1; prot=0; */
82
83   /* file offsets */
84   long d_pos;   /* start of description */
85   long s_pos;   /* start of sequence */
86   long *d_pos_arr;      /* array of description pointers */
87   long *s_pos_arr;      /* array of description pointers */
88
89   lib_type = 0;
90   lib_size = 200000;
91   lib_inc  = 100000;
92
93   lib_aa = 1;
94
95   while (argc > 1 && *argv[1]=='-') {
96     if (strcmp(argv[1],"-n")==0) lib_aa = 0;
97     argv++;
98     argc--;
99   }
100
101   /* open the database */
102   if (argc > 1) strncpy(lname, argv[1],sizeof(lname));
103   else {
104     fprintf(stderr," Entry library name: ");
105     fgets(lname,sizeof(lname),stdin);
106     if ((bp=strchr(lname,'\n'))!=NULL) *bp='\0';
107   }
108     
109   if ((bp=strchr(lname,' '))!=NULL) {
110     lib_type = atoi(bp+1);
111     *bp='\0';
112   }
113   else lib_type = 0;
114
115   if (get_ent_arr[lib_type] == NULL) {
116     fprintf(stderr," cannot index file %s type %d\n",lname,lib_type);
117     exit(1);
118   }
119   
120   if (lib_type == 6) lib_aa = 0;
121   if (lib_type == 1) lib_aa = 0;
122   
123   if (lib_aa == 1) sascii = aascii;
124   else sascii = nascii;
125
126   if ((f_size=openlib(lname,lib_type))==0) {
127     fprintf(stderr," cannot open %s (type: %d)\n",lname,lib_type);
128     exit(1);
129   }
130
131   /* allocate array of description pointers */
132   if ((d_pos_arr=(long *)calloc(lib_size, sizeof(long)))==NULL) {
133     fprintf(stderr," cannot allocate %d for desc. array\n",lib_size);
134     exit(1);
135   }
136   /* allocate array of sequence pointers */
137   if ((s_pos_arr=(long *)calloc(lib_size, sizeof(long)))==NULL) {
138     fprintf(stderr," cannot allocate %d for seq. array\n",lib_size);
139     exit(1);
140   }
141
142   /* allocate array of sequence flags */
143
144   nlib = 0; tot_len=0; max_len=-1;
145   while ((n1=get_entry(&d_pos, &s_pos)) > 0) {
146     d_pos_arr[nlib] = d_pos;
147     s_pos_arr[nlib] = s_pos;
148     nlib++;
149     tot_len += n1;
150     if (n1 > max_len) max_len = n1;
151     if (nlib >= lib_size) { /* too many entries */
152       lib_size += lib_inc;
153       if ((d_pos_arr=(long *)realloc(d_pos_arr,lib_size*sizeof(long)))==NULL) {
154         fprintf(stderr," cannot realloc allocate %d for desc.. array\n",
155                 lib_size);
156         exit(1);
157       }
158       if ((s_pos_arr=(long *)realloc(s_pos_arr,lib_size*sizeof(long)))==NULL) {
159         fprintf(stderr," cannot realloc allocate %d for seq. array\n",
160                 lib_size);
161         exit(1);
162       }
163     }
164   }
165
166   d_pos_arr[nlib]= d_pos;       /* put in the end of the file */
167   s_pos_arr[nlib]=0;
168
169   /* all the information is in, write it out */
170   
171   newname(iname,lname,"xin",sizeof(iname));
172
173   if ((libi=fopen(iname,"w"))==NULL) {
174     fprintf(stderr," cannot open %s for writing\n",iname);
175     exit(1);
176   }
177
178   /* write out format version */
179   format[0]='M';
180   format[1]='P';
181 #ifdef BIG_LIB64
182   format[2]= 1;         /* format 1 for 8-byte offsets */
183 #else
184   format[2]='\0';       /* format '\0' for original 4-byte */
185 #endif
186
187   format[3]=lib_type;
188   fwrite(format,4,sizeof(char),libi);
189
190   /* write out sequence type */
191   src_int4_write(libi, lib_aa);
192
193   /* write out file fstat as integrity check */
194 #ifdef BIG_LIB64
195   src_long8_write(libi, f_size);
196 #else
197   src_int4_write(libi, f_size);
198 #endif
199
200   /* write out num_seq */
201   src_int4_write(libi, nlib);
202
203 #ifdef BIG_LIB64
204   /* write out tot_len, max_len */
205   src_long8_write(libi, tot_len);
206 #else
207   src_int4_write(libi, tot_len);
208 #endif
209   src_int4_write(libi, max_len);
210
211 #ifdef BIG_LIB64
212   for (i=0; i<=nlib; i++) src_long8_write(libi,d_pos_arr[i]);
213   for (i=0; i<=nlib; i++) src_long8_write(libi,s_pos_arr[i]);
214 #else
215   for (i=0; i<=nlib; i++) src_int4_write(libi,d_pos_arr[i]);
216   for (i=0; i<=nlib; i++) src_int4_write(libi,s_pos_arr[i]);
217 #endif
218
219   fclose(libi);
220
221 #ifdef BIG_LIB64
222   fprintf(stderr," wrote %d sequences (tot=%ld, max=%ld) to %s\n",
223           nlib,tot_len,max_len,iname);
224 #else
225   fprintf(stderr," wrote %d sequences (tot=%ld, max=%ld) to %s\n",
226           nlib,tot_len,max_len,iname);
227 #endif
228 }
229
230
231 FILE *libf=NULL;
232 long lpos;
233
234 #define MAXLINE 4096
235 char lline[MAXLINE+1];
236
237 long
238 openlib(char *lname, int lib_type)
239 {
240   long f_size;
241   struct stat stat_buf;
242
243   if (stat(lname,&stat_buf)<0) {
244     fprintf(stderr," cannot stat library: %s\n",lname);
245     return 0;
246   }
247
248   if ((libf=fopen(lname,"r"))==NULL) {
249     fprintf(stderr," cannot open library: %s (type: %d)\n",
250             lname, lib_type);
251     return 0;
252   }
253   
254   f_size = stat_buf.st_size;
255
256   get_entry = get_ent_arr[lib_type];
257
258   lpos = ftell(libf);
259   if (fgets(lline,MAXLINE,libf)==NULL) return 0;
260   return f_size;
261 }
262
263 int
264 a_get_ent(long *d_pos, long *s_pos)
265 {
266   register char *cp;
267   register int *ap, n1;
268
269   ap = sascii;
270
271   while (lline[0]!='>' && lline[0]!=';') {
272     lpos = ftell(libf);
273     if (fgets(lline,sizeof(lline),libf)==NULL) {
274       *d_pos = lpos;
275       return 0;
276     }
277   }
278
279   *d_pos = lpos;
280
281   /* make certain we have the end of the line */
282   while (strchr((char *)lline,'\n')==NULL) {
283     if (fgets(lline,sizeof(lline),libf)==NULL) break;
284   }
285
286   *s_pos = ftell(libf);
287   lline[0]='\0';
288   n1 = 0;
289   while (fgets(lline,sizeof(lline),libf)!=NULL) {
290     if (lline[0]=='>') break;
291     if (lline[0]==';') {
292       if (strchr(lline,'\n')==NULL) {
293         fprintf(stderr," excessive continuation\n%s",lline);
294         return -1;
295       }
296     }
297
298     for (cp=lline; *cp; ) if (ap[*cp++]<NA) n1++;
299     lpos = ftell(libf);
300   }
301   return n1;
302 }
303
304 int
305 v_get_ent(long *d_pos, long *s_pos)
306 {
307   register char *cp;
308   register int *ap;
309   int n1;
310
311   ap = sascii;
312
313   /* check for seq_id line */
314   while (lline[0]!='>' && lline[0]!=';') {
315     lpos = ftell(libf);
316     if (fgets(lline,sizeof(lline),libf)==NULL) {
317       *d_pos = lpos;
318       return 0;
319     }
320   }
321   *d_pos = lpos;
322
323   /* get the description line */
324   if (fgets(lline,sizeof(lline),libf)==NULL) return 0;
325   /* make certain we have the end of the line */
326   while (strchr((char *)lline,'\n')==NULL) {
327     if (fgets(lline,sizeof(lline),libf)==NULL) break;
328   }
329
330   *s_pos = ftell(libf);
331   lline[0]='\0';
332   n1 = 0;
333   while (fgets(lline,sizeof(lline),libf)!=NULL) {
334     if (lline[0]=='>') break;
335
336     for (cp=lline; *cp; ) if (ap[*cp++]<NA) n1++;
337     lpos = ftell(libf);
338   }
339   return n1;
340 }
341
342 static char gcg_type[10];
343 static long gcg_len;
344 static int gcg_bton[4]={2,4,1,3};
345
346 int
347 gcg_get_ent(long *d_pos, long *s_pos)
348 {
349   register char *cp;
350   register int *ap;
351   char libstr[20], dummy[20];
352   char gcg_date[6];
353   int r_block;
354   int n1;
355
356   /* check for seq_id line */
357   while (lline[0]!='>') {
358     lpos = ftell(libf);
359     if (fgets(lline,sizeof(lline),libf)==NULL) {
360       *d_pos = lpos;
361       return 0;
362     }
363   }
364   *d_pos = lpos;
365
366   /* get the encoding/sequence length info */
367
368   sscanf(&lline[4],"%s %s %s %s %ld",
369          libstr,gcg_date,gcg_type,dummy,&gcg_len);
370
371   /* get the description line */
372   if (fgets(lline,MAXLINE,libf)==NULL) return;
373
374   *s_pos = ftell(libf);
375   /* seek to the end of the sequence; +1 to jump over newline */
376   if (gcg_type[0]=='2') {
377     r_block = (gcg_len+3)/4;
378     fseek(libf,r_block+1,SEEK_CUR);
379   }
380   else fseek(libf,gcg_len+1,SEEK_CUR);
381
382   lpos = ftell(libf);
383   fgets(lline,MAXLINE,libf);
384
385   return gcg_len;
386 }
387
388 int
389 gbf_get_ent(long *d_pos, long *s_pos)
390 {
391   int n1;
392   char *cp;
393   register int *ap;
394
395 #if !defined(TFAST)
396   ap = sascii;
397 #else
398   ap = nascii;
399 #endif
400
401   while (lline[0]!='L' || lline[1]!='O' || 
402          strncmp(lline,"LOCUS",5)) { /* find LOCUS */
403     lpos = ftell(libf);
404     if (fgets(lline,MAXLINE,libf)==NULL) return (-1);
405   }
406   *d_pos=lpos;
407
408   while (lline[0]!='O' || lline[1]!='R' ||
409          strncmp(lline,"ORIGIN",6)) { /* find ORIGIN */
410     if (fgets(lline,MAXLINE,libf)==NULL) return (-1);
411   }
412   *s_pos = ftell(libf);
413
414   lline[0]='\0';
415   n1=0;
416   while (fgets(lline,MAXLINE,libf)!=NULL) {
417     if (lline[0]=='/') break;
418     for (cp=lline; *cp; ) if (ap[*cp++]<NA) n1++;
419   }
420   lpos = ftell(libf);
421   fgets(lline,MAXLINE,libf);
422
423   return n1;
424 }
425
426 void src_int4_read(FILE *fd,  int *val)
427 {
428 #ifdef IS_BIG_ENDIAN
429   fread((char *)val,(size_t)4,(size_t)1,fd);
430 #else
431   unsigned char b[4];
432
433   fread((char *)&b[0],(size_t)1,(size_t)4,fd);
434   *val = 0;
435   *val = (int)((int)((int)(b[0]<<8)+(int)b[1]<<8)+(int)b[2]<<8)
436           +(int)b[3];
437 #endif
438 }
439
440 void src_int4_write(FILE *fd,  int val)
441 {
442 #ifdef IS_BIG_ENDIAN
443   fwrite(&val,(size_t)4,(size_t)1,fd);
444 #else
445   unsigned char b[4];
446
447   b[3] = val & 255;
448   b[2] = (val=val>>8)&255;
449   b[1] = (val=val>>8)&255;
450   b[0] = (val=val>>8)&255;
451
452   fwrite(b,(size_t)1,(size_t)4,fd);
453 #endif
454 }
455
456 void src_long8_write(FILE *fd,  long val)
457 {
458 #ifdef IS_BIG_ENDIAN
459   fwrite(&val,(size_t)8,(size_t)1,fd);
460 #else
461   unsigned char b[8];
462
463   b[7] = val & 255;
464   b[6] = (val=val>>8)&255;
465   b[5] = (val=val>>8)&255;
466   b[4] = (val=val>>8)&255;
467   b[3] = (val=val>>8)&255;
468   b[2] = (val=val>>8)&255;
469   b[1] = (val=val>>8)&255;
470   b[0] = (val=val>>8)&255;
471
472   fwrite(b,(size_t)1,(size_t)8,fd);
473 #endif
474 }
475
476 void
477 newname(char *nname, char *oname, char *suff, int maxn)
478 {
479   strncpy(nname,oname,maxn-1);
480   strncat(nname,".",1);
481   strncat(nname,suff,maxn-strlen(nname));
482 }