File: numeric_data.c

package info (click to toggle)
poa 2.0%2B20060928-10
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 536 kB
  • sloc: ansic: 5,181; xml: 276; makefile: 91; perl: 35; sh: 16
file content (145 lines) | stat: -rw-r--r-- 4,842 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145


#include <lpo.h>

/**@memo create a new LPONumericData_T record for the designated source_seq.  
 Dynamically allocates data storage array equal in length to the length of 
 the source_seq.  Initializes the array values to initial_value if non-zero.  
 Returns a pointer to the new LPONumericData_T and also adds it to the 
 source_seq->data[] list.
*/
LPONumericData_T *new_numeric_data(LPOSourceInfo_T *source_seq,
				   char name[],
				   char title[],
				   double initial_value)
{
  int i;
  LPONumericData_T *data=NULL;
  REBUFF(source_seq->data,source_seq->ndata,NUMDATA_BUFFER_CHUNK,LPONumericData_T);
  data=source_seq->data + source_seq->ndata++;

  STRNCPY(data->name,name,SEQUENCE_NAME_MAX); /* COPY NAME AND TITLE */
  if (title)
    data->title=strdup(title);

  CALLOC(data->data,source_seq->length,double); /* ALLOCATE THE ARRAY */
  if (initial_value) /* INITIALIZE VALUES IF DESIRED */
    LOOP (i,source_seq->length)
      data->data[i]=initial_value;
  return data; /* RETURN POINTER TO THE NEW DATA HOLDER */
}



LPONumericData_T *cp_numeric_data(LPOSourceInfo_T *source_seq,
				  LPONumericData_T *data)
{
  int i;
  LPONumericData_T *new_data;
  new_data=new_numeric_data(source_seq,data->name,data->title,0);
  LOOP (i,source_seq->length) /* COPY ALL THE VALUES */
    new_data->data[i]=data->data[i];
  return new_data;
}



/**@memo finds LPONumericData from the source_seq, matching the specified 
   name, or returns NULL if not found. */
LPONumericData_T *find_numeric_data(LPOSourceInfo_T *source_seq,
				   char name[])
{
  int i;
  LOOP (i,source_seq->ndata)
    if (0==strcmp(source_seq->data[i].name,name)) /*FOUND IT. RETURN POINTER*/
      return source_seq->data+i;
  return NULL; /* NOT FOUND! */
}



/**@memo frees the set of numeric_data passed as arguments.  If requested, 
 will also free the block of memory for the array of entries data[]. */
void free_lpo_numeric_data(int ndata,LPONumericData_T *data,
			   int please_free_block)
{
  int i;
  LOOP (i,ndata) { /* DUMP ASSOCIATED ARRAYS */
    FREE(data[i].title);
    FREE(data[i].data);
  }
  if (please_free_block) /* DUMP THE BLOCK ITSELF */
    free(data);
}





/**@memo creates one or more new numeric_data for a given sequence, 
  based on the presence of corresponding named numeric_data.  Specifically, 
  the list of set_names[] is processed one by one, creating a source_name
  according to the source_name_fmt string, and finding a numeric_data 
  entry with that name.  If it is not found, the routine calls exit(-1).  
  If it is found, a new set of numeric_data is created, with a name 
  created according to target_name_fmt, and titled according to 
  the title_fmt string and source_data->title. */
void new_numeric_data_sets(LPOSourceInfo_T *source_seq,
			   int nset,char *set_names[],
			   char source_name_fmt[],
			   char target_name_fmt[],
			   char title_fmt[])
{
  int j;
  LPONumericData_T *data;
  char name[256],title[4096];

  LOOPF (j,nset) {
    sprintf(name,source_name_fmt,set_names[j]); /* GENERATE NAME TO MATCH*/
    data=find_numeric_data(source_seq,name); /*FIND SOURCE DATA*/
    if (!data) {
      WARN_MSG(USERR,(ERRTXT,"*** could not find dataset %s for seq %s.\nExiting\n\n",
	      name,source_seq->name),"$Revision: 1.2 $");
      exit(-1);
    }
    sprintf(name,target_name_fmt,set_names[j]); /* GENERATE NEW NAME */
    sprintf(title,title_fmt,data->title);
    new_numeric_data(source_seq,name,title,0.); /* CREATE NEW ARRAY */
  }
}




/**@memo reads a stream of FASTA-formatted numeric data, and stores them in 
the corresponding set of source_seq, matching the sequences by name.  
Multiple numeric data entries can be read from a single stream. */
void read_numeric_data(int nsource_seq,
		       LPOSourceInfo_T source_seq[],
		       FILE *ifile)
{
  int i,j;
  char line[4096],seq_name[128],data_name[1024],title[2048];
  LPONumericData_T *data;

  while (fgets(line,sizeof(line),ifile)) {
    title[0]='\0';
    if (sscanf(line,">%s NUMERIC_DATA=%s %s",seq_name,data_name,title)>=2) {
      LOOP (i,nsource_seq) /* FIND THE MATCHING SEQUENCE */
	if (0==strcmp(seq_name,source_seq[i].name)) /* MATCH */
	  break;
      if (LOOP_FINISHED(i,nsource_seq)) /* SEQ NOT FOUND!! */
	WARN_MSG(USERR,(ERRTXT,"Error! NUMERIC_DATA %s, sequence %s does not exist.  Skipping.\n\n",data_name,seq_name),"$Revision: 1.2 $");
      else { /* FOUND THE SEQ, SAVE THE DATA */
	if (data=find_numeric_data(source_seq+i,data_name)) /*REUSE EXISTING*/
	  WARN_MSG(WARN,(ERRTXT,"NUMERIC_DATA %s already exists on sequence %s.  Overwriting.\n",data_name,seq_name),"$Revision: 1.2 $");
	else /* CREATE A NEW DATA HOLDER */
	  data=new_numeric_data(source_seq+i,data_name,title,0.);
	LOOPF (j,source_seq[i].length) /* READ IN THE VALUES */
	  fscanf(ifile," %lf",data->data+j);
      }
    }
  }
}