GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
sigset.c
Go to the documentation of this file.
1 #include <string.h>
2 #include <stdlib.h>
3 #include <grass/imagery.h>
4 #include <grass/gis.h>
5 
6 static int gettag(FILE *, char *);
7 static int get_nbands(FILE *, struct SigSet *);
8 static int get_title(FILE *, struct SigSet *);
9 static int get_class(FILE *, struct SigSet *);
10 static int get_classnum(FILE *, struct ClassSig *);
11 static int get_classtype(FILE *, struct ClassSig *);
12 static int get_classtitle(FILE *, struct ClassSig *);
13 static int get_subclass(FILE *, struct SigSet *, struct ClassSig *);
14 static int get_subclass_pi(FILE *, struct SubSig *);
15 static int get_subclass_means(FILE *, struct SubSig *, int);
16 static int get_subclass_covar(FILE *, struct SubSig *, int);
17 
18 static double **alloc_matrix(int rows, int cols)
19 {
20  double **m;
21  int i;
22 
23  m = (double **)G_calloc(rows, sizeof(double *));
24  m[0] = (double *)G_calloc(rows * cols, sizeof(double));
25  for (i = 1; i < rows; i++)
26  m[i] = m[i - 1] + cols;
27 
28  return m;
29 }
30 
31 int I_SigSetNClasses(struct SigSet *S)
32 {
33  int i, count;
34 
35  for (i = 0, count = 0; i < S->nclasses; i++)
36  if (S->ClassSig[i].used)
37  count++;
38 
39  return count;
40 }
41 
42 
43 struct ClassData *I_AllocClassData(struct SigSet *S,
44  struct ClassSig *C, int npixels)
45 {
46  struct ClassData *Data;
47 
48  Data = &(C->ClassData);
49  Data->npixels = npixels;
50  Data->count = 0;
51  Data->x = alloc_matrix(npixels, S->nbands);
52  Data->p = alloc_matrix(npixels, C->nsubclasses);
53  return Data;
54 }
55 
56 int I_InitSigSet(struct SigSet *S)
57 {
58  S->nbands = 0;
59  S->nclasses = 0;
60  S->ClassSig = NULL;
61  S->title = NULL;
62 
63  return 0;
64 }
65 
66 int I_SigSetNBands(struct SigSet *S, int nbands)
67 {
68  S->nbands = nbands;
69 
70  return 0;
71 }
72 
73 struct ClassSig *I_NewClassSig(struct SigSet *S)
74 {
75  struct ClassSig *Sp;
76 
77  if (S->nclasses == 0)
78  S->ClassSig = (struct ClassSig *)G_malloc(sizeof(struct ClassSig));
79  else
80  S->ClassSig = (struct ClassSig *)G_realloc((char *)S->ClassSig,
81  sizeof(struct ClassSig) *
82  (S->nclasses + 1));
83 
84  Sp = &S->ClassSig[S->nclasses++];
85  Sp->classnum = 0;
86  Sp->nsubclasses = 0;
87  Sp->used = 1;
89  Sp->title = NULL;
90  return Sp;
91 }
92 
93 struct SubSig *I_NewSubSig(struct SigSet *S, struct ClassSig *C)
94 {
95  struct SubSig *Sp;
96  int i;
97 
98  if (C->nsubclasses == 0)
99  C->SubSig = (struct SubSig *)G_malloc(sizeof(struct SubSig));
100  else
101  C->SubSig = (struct SubSig *)G_realloc((char *)C->SubSig,
102  sizeof(struct SubSig) *
103  (C->nsubclasses + 1));
104 
105  Sp = &C->SubSig[C->nsubclasses++];
106  Sp->used = 1;
107  Sp->R = (double **)G_calloc(S->nbands, sizeof(double *));
108  Sp->R[0] = (double *)G_calloc(S->nbands * S->nbands, sizeof(double));
109  for (i = 1; i < S->nbands; i++)
110  Sp->R[i] = Sp->R[i - 1] + S->nbands;
111  Sp->Rinv = (double **)G_calloc(S->nbands, sizeof(double *));
112  Sp->Rinv[0] = (double *)G_calloc(S->nbands * S->nbands, sizeof(double));
113  for (i = 1; i < S->nbands; i++)
114  Sp->Rinv[i] = Sp->Rinv[i - 1] + S->nbands;
115  Sp->means = (double *)G_calloc(S->nbands, sizeof(double));
116  Sp->N = 0;
117  Sp->pi = 0;
118  Sp->cnst = 0;
119  return Sp;
120 }
121 
122 #define eq(a,b) strcmp(a,b)==0
123 
124 int I_ReadSigSet(FILE * fd, struct SigSet *S)
125 {
126  char tag[256];
127 
128  I_InitSigSet(S);
129 
130  while (gettag(fd, tag)) {
131  if (eq(tag, "title:"))
132  if (get_title(fd, S) != 0)
133  return -1;
134  if (eq(tag, "nbands:"))
135  if (get_nbands(fd, S) != 0)
136  return -1;
137  if (eq(tag, "class:"))
138  if (get_class(fd, S) != 0)
139  return -1;
140  }
141  return 1; /* for now assume success */
142 }
143 
144 static int gettag(FILE * fd, char *tag)
145 {
146  if (fscanf(fd, "%s", tag) != 1)
147  return 0;
148  G_strip(tag);
149  return 1;
150 }
151 
152 static int get_nbands(FILE * fd, struct SigSet *S)
153 {
154  if (fscanf(fd, "%d", &S->nbands) != 1)
155  return -1;
156 
157  return 0;
158 }
159 
160 static int get_title(FILE * fd, struct SigSet *S)
161 {
162  char title[1024];
163 
164  *title = 0;
165  if (fscanf(fd, "%[^\n]", title) != 1)
166  return -1;
167  I_SetSigTitle(S, title);
168 
169  return 0;
170 }
171 
172 static int get_class(FILE * fd, struct SigSet *S)
173 {
174  char tag[1024];
175  struct ClassSig *C;
176 
177  C = I_NewClassSig(S);
178  while (gettag(fd, tag)) {
179  if (eq(tag, "endclass:"))
180  break;
181  if (eq(tag, "classnum:"))
182  if (get_classnum(fd, C) != 0)
183  return -1;
184  if (eq(tag, "classtype:"))
185  if (get_classtype(fd, C) != 0)
186  return -1;
187  if (eq(tag, "classtitle:"))
188  if (get_classtitle(fd, C) != 0)
189  return -1;
190  if (eq(tag, "subclass:"))
191  if (get_subclass(fd, S, C) != 0)
192  return -1;
193  }
194 
195  return 0;
196 }
197 
198 static int get_classnum(FILE * fd, struct ClassSig *C)
199 {
200  if (fscanf(fd, "%ld", &C->classnum) != 1)
201  return -1;
202 
203  return 0;
204 }
205 
206 static int get_classtype(FILE * fd, struct ClassSig *C)
207 {
208  if (fscanf(fd, "%d", &C->type) != 1)
209  return -1;
210 
211  return 0;
212 }
213 
214 static int get_classtitle(FILE * fd, struct ClassSig *C)
215 {
216  char title[1024];
217 
218  *title = 0;
219  if (fscanf(fd, "%[^\n]", title) != 1)
220  return -1;
221  I_SetClassTitle(C, title);
222 
223  return 0;
224 }
225 
226 static int get_subclass(FILE * fd, struct SigSet *S, struct ClassSig *C)
227 {
228  struct SubSig *Sp;
229  char tag[1024];
230 
231  Sp = I_NewSubSig(S, C);
232 
233  while (gettag(fd, tag)) {
234  if (eq(tag, "endsubclass:"))
235  break;
236  if (eq(tag, "pi:"))
237  if (get_subclass_pi(fd, Sp) != 0)
238  return -1;
239  if (eq(tag, "means:"))
240  if (get_subclass_means(fd, Sp, S->nbands) != 0)
241  return -1;
242  if (eq(tag, "covar:"))
243  if (get_subclass_covar(fd, Sp, S->nbands) != 0)
244  return -1;
245  }
246 
247  return 0;
248 }
249 
250 static int get_subclass_pi(FILE * fd, struct SubSig *Sp)
251 {
252  if (fscanf(fd, "%lf", &Sp->pi) != 1)
253  return -1;
254 
255  return 0;
256 }
257 
258 static int get_subclass_means(FILE * fd, struct SubSig *Sp, int nbands)
259 {
260  int i;
261 
262  for (i = 0; i < nbands; i++)
263  if (fscanf(fd, "%lf", &Sp->means[i]) != 1)
264  return -1;
265 
266  return 0;
267 }
268 
269 static int get_subclass_covar(FILE * fd, struct SubSig *Sp, int nbands)
270 {
271  int i, j;
272 
273  for (i = 0; i < nbands; i++)
274  for (j = 0; j < nbands; j++)
275  if (fscanf(fd, "%lf", &Sp->R[i][j]) != 1)
276  return -1;
277 
278  return 0;
279 }
280 
281 int I_SetSigTitle(struct SigSet *S, const char *title)
282 {
283  if (title == NULL)
284  title = "";
285  if (S->title)
286  free(S->title);
287  S->title = G_store(title);
288 
289  return 0;
290 }
291 
292 const char *I_GetSigTitle(const struct SigSet *S)
293 {
294  if (S->title)
295  return S->title;
296  else
297  return "";
298 }
299 
300 int I_SetClassTitle(struct ClassSig *C, const char *title)
301 {
302  if (title == NULL)
303  title = "";
304  if (C->title)
305  free(C->title);
306  C->title = G_store(title);
307 
308  return 0;
309 }
310 
311 const char *I_GetClassTitle(const struct ClassSig *C)
312 {
313  if (C->title)
314  return C->title;
315  else
316  return "";
317 }
318 
319 int I_WriteSigSet(FILE * fd, const struct SigSet *S)
320 {
321  const struct ClassSig *Cp;
322  const struct SubSig *Sp;
323  int i, j, b1, b2;
324 
325  fprintf(fd, "title: %s\n", I_GetSigTitle(S));
326  fprintf(fd, "nbands: %d\n", S->nbands);
327  for (i = 0; i < S->nclasses; i++) {
328  Cp = &S->ClassSig[i];
329  if (!Cp->used)
330  continue;
331  if (Cp->nsubclasses <= 0)
332  continue;
333  fprintf(fd, "class:\n");
334  fprintf(fd, " classnum: %ld\n", Cp->classnum);
335  fprintf(fd, " classtitle: %s\n", I_GetClassTitle(Cp));
336  fprintf(fd, " classtype: %d\n", Cp->type);
337 
338  for (j = 0; j < Cp->nsubclasses; j++) {
339  Sp = &Cp->SubSig[j];
340  fprintf(fd, " subclass:\n");
341  fprintf(fd, " pi: %g\n", Sp->pi);
342  fprintf(fd, " means:");
343  for (b1 = 0; b1 < S->nbands; b1++)
344  fprintf(fd, " %g", Sp->means[b1]);
345  fprintf(fd, "\n");
346  fprintf(fd, " covar:\n");
347  for (b1 = 0; b1 < S->nbands; b1++) {
348  fprintf(fd, " ");
349  for (b2 = 0; b2 < S->nbands; b2++)
350  fprintf(fd, " %g", Sp->R[b1][b2]);
351  fprintf(fd, "\n");
352  }
353  fprintf(fd, " endsubclass:\n");
354  }
355  fprintf(fd, "endclass:\n");
356  }
357 
358  return 0;
359 }
#define G_malloc(n)
Definition: defs/gis.h:112
int nclasses
Definition: imagery.h:104
double ** Rinv
Definition: imagery.h:77
Definition: imagery.h:71
const char * I_GetSigTitle(const struct SigSet *S)
Definition: sigset.c:292
int count
char * title
Definition: imagery.h:105
#define SIGNATURE_TYPE_MIXED
Definition: imagery.h:197
double pi
Definition: imagery.h:74
int I_InitSigSet(struct SigSet *S)
Definition: sigset.c:56
double ** x
Definition: imagery.h:86
void G_strip(char *)
Removes all leading and trailing white space from string.
Definition: strings.c:300
struct SubSig * SubSig
Definition: imagery.h:97
void free(void *)
#define NULL
Definition: ccmath.h:32
#define eq(a, b)
Definition: sigset.c:122
int type
Definition: imagery.h:95
int I_SetClassTitle(struct ClassSig *C, const char *title)
Definition: sigset.c:300
int I_SetSigTitle(struct SigSet *S, const char *title)
Definition: sigset.c:281
#define G_calloc(m, n)
Definition: defs/gis.h:113
struct ClassSig * I_NewClassSig(struct SigSet *S)
Definition: sigset.c:73
char * title
Definition: imagery.h:93
struct ClassSig * ClassSig
Definition: imagery.h:106
double ** R
Definition: imagery.h:76
int nbands
Definition: imagery.h:103
double * means
Definition: imagery.h:75
int I_SigSetNClasses(struct SigSet *S)
Definition: sigset.c:31
struct ClassData * I_AllocClassData(struct SigSet *S, struct ClassSig *C, int npixels)
Definition: sigset.c:43
double N
Definition: imagery.h:73
long classnum
Definition: imagery.h:92
int I_WriteSigSet(FILE *fd, const struct SigSet *S)
Definition: sigset.c:319
int I_SigSetNBands(struct SigSet *S, int nbands)
Definition: sigset.c:66
struct SubSig * I_NewSubSig(struct SigSet *S, struct ClassSig *C)
Definition: sigset.c:93
int npixels
Definition: imagery.h:84
#define G_realloc(p, n)
Definition: defs/gis.h:114
double cnst
Definition: imagery.h:78
char * G_store(const char *)
Copy string to allocated memory.
Definition: strings.c:87
int used
Definition: imagery.h:79
double ** p
Definition: imagery.h:87
int I_ReadSigSet(FILE *fd, struct SigSet *S)
Definition: sigset.c:124
int used
Definition: imagery.h:94
const char * I_GetClassTitle(const struct ClassSig *C)
Definition: sigset.c:311
struct ClassData ClassData
Definition: imagery.h:98
int nsubclasses
Definition: imagery.h:96
int count
Definition: imagery.h:85