My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
touchstone_producer.cpp
Go to the documentation of this file.
1 /*
2  * touchstone_producer.cpp - the Touchstone data file producer
3  *
4  * Copyright (C) 2007 Stefan Jahn <stefan@lkcc.org>
5  *
6  * This is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This software is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this package; see the file COPYING. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  * $Id: touchstone_producer.cpp 1825 2011-03-11 20:42:14Z ela $
22  *
23  */
24 
25 #if HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <time.h>
32 #include <ctype.h>
33 #include <string.h>
34 
35 #include "touchstone_producer.h"
36 #include "matrix.h"
37 #include "matvec.h"
38 #include "constants.h"
39 
40 /* Global variables. */
41 /* dataset * qucs_data = NULL; -- already defined in CSV producer */
42 /* FILE * touchstone_out = NULL; -- already defined in Touchstone lexer */
43 
45  char parameter; // type of variable
46  int ports; // number of S-parameter ports
47  double resistance; // reference impedance
48  const char * format; // data format
49  vector * vd; // appropriate dependency vector
50  matvec * mv; // appropriate data matrix vector
51  vector * fmin; // minimum noise figure
52  vector * sopt; // optimum input refelction for minimum noise figure
53  vector * rn; // effective noise resistance
54  vector * vf; // dependency vector for noise
55 }
57 
58 /* Definition of line separator. */
59 #ifdef __MINGW32__
60 #define touchstone_crlf "\n"
61 #else
62 #define touchstone_crlf "\r\n"
63 #endif
64 
65 /* The Touchstone noise data printer. */
67  if (touchstone_data.vf != NULL && touchstone_data.sopt != NULL &&
68  touchstone_data.rn != NULL && touchstone_data.fmin != NULL) {
69  // blank line separator
71  // noise data
72  for (int i = 0; i < touchstone_data.vf->getSize (); i++) {
73  nr_double_t f = real (touchstone_data.vf->get (i));
74  fprintf (touchstone_out, "%." NR_DECS "e"
75  " %+." NR_DECS "e"
76  " %+." NR_DECS "e" " %+." NR_DECS "e"
77  " %+." NR_DECS "e"
78  touchstone_crlf, f,
79  10.0 * log10 (real (touchstone_data.fmin->get (i))),
82  real (touchstone_data.rn->get (i)) /
84  }
85  }
86 }
87 
88 /* The Touchstone data printer. */
89 void touchstone_print (void) {
90  // header line
91  fprintf (touchstone_out, "# %s %c %s R %g" touchstone_crlf,
94  // one-port file
95  if (touchstone_data.ports == 1) {
96  for (int i = 0; i < touchstone_data.vd->getSize (); i++) {
98  nr_double_t f = real (touchstone_data.vd->get (i));
99  fprintf (touchstone_out, "%." NR_DECS "e"
100  " %+." NR_DECS "e" " %+." NR_DECS "e"
101  touchstone_crlf, f, real (S(0,0)), imag (S(0,0)));
102  }
103  }
104  // two-port file
105  else if (touchstone_data.ports == 2) {
106  for (int i = 0; i < touchstone_data.vd->getSize (); i++) {
108  nr_double_t f = real (touchstone_data.vd->get (i));
109  fprintf (touchstone_out, "%." NR_DECS "e"
110  " %+." NR_DECS "e" " %+." NR_DECS "e"
111  " %+." NR_DECS "e" " %+." NR_DECS "e"
112  " %+." NR_DECS "e" " %+." NR_DECS "e"
113  " %+." NR_DECS "e" " %+." NR_DECS "e"
114  touchstone_crlf, f,
115  real (S(0,0)), imag (S(0,0)),
116  real (S(1,0)), imag (S(1,0)),
117  real (S(0,1)), imag (S(0,1)),
118  real (S(1,1)), imag (S(1,1)));
119  }
120  }
121  // three-port file
122  else if (touchstone_data.ports == 3) {
123  for (int i = 0; i < touchstone_data.vd->getSize (); i++) {
125  nr_double_t f = real (touchstone_data.vd->get (i));
126  fprintf (touchstone_out, "%." NR_DECS "e"
127  " %+." NR_DECS "e" " %+." NR_DECS "e"
128  " %+." NR_DECS "e" " %+." NR_DECS "e"
129  " %+." NR_DECS "e" " %+." NR_DECS "e"
130  touchstone_crlf " %" NR_DECS "s"
131  " %+." NR_DECS "e" " %+." NR_DECS "e"
132  " %+." NR_DECS "e" " %+." NR_DECS "e"
133  " %+." NR_DECS "e" " %+." NR_DECS "e"
134  touchstone_crlf " %" NR_DECS "s"
135  " %+." NR_DECS "e" " %+." NR_DECS "e"
136  " %+." NR_DECS "e" " %+." NR_DECS "e"
137  " %+." NR_DECS "e" " %+." NR_DECS "e"
139  f,
140  real (S(0,0)), imag (S(0,0)),
141  real (S(0,1)), imag (S(0,1)),
142  real (S(0,2)), imag (S(0,2)), " ",
143  real (S(1,0)), imag (S(1,0)),
144  real (S(1,1)), imag (S(1,1)),
145  real (S(1,2)), imag (S(1,2)), " ",
146  real (S(2,0)), imag (S(2,0)),
147  real (S(2,1)), imag (S(2,1)),
148  real (S(2,2)), imag (S(2,2)));
149  }
150  }
151  // four-port and above files
152  else if (touchstone_data.ports >= 4) {
153  for (int i = 0; i < touchstone_data.vd->getSize (); i++) {
155  nr_double_t f = real (touchstone_data.vd->get (i));
156  int cs = S.getCols ();
157  int rs = S.getRows ();
158  fprintf (touchstone_out, "%." NR_DECS "e", f);
159  for (int r = 0; r < rs; r++) {
160  if (r >= 1)
161  fprintf (touchstone_out, " %" NR_DECS "s", " ");
162  for (int c = 0; c < cs; c++) {
163  if (c > 1 && (c & 3) == 0)
164  fprintf (touchstone_out, " %" NR_DECS "s", " ");
165  fprintf (touchstone_out, " %+." NR_DECS "e" " %+." NR_DECS "e",
166  real (S(r,c)), imag (S(r,c)));
167  if ((c > 1 && (c & 3) == 3) || (c == cs - 1))
169  }
170  }
171  }
172  }
173 }
174 
175 /* The function finds an appropriate S-parameters or other parameter
176  type (G, H, Y, Z, etc.) matrix from the given dataset and stores it
177  into the global Touchstone structure. */
178 void touchstone_find_data (dataset * data, const char * name) {
179  vector * v;
180  char * n, * vn, * vd = NULL, * vf = NULL;
181  strlist * deps;
182  int r, c, rs = -1, cs = -1, s = 0;
183 
184  // find parameter matrix data and its dimensions
185  for (v = data->getVariables (); v != NULL; v = (vector *) v->getNext ()) {
186  vn = v->getName ();
187  // requested matrix vector name found?
188  if (strstr (vn, name) == vn) {
189  if ((n = matvec::isMatrixVector (vn, r, c)) != NULL) {
190  if (rs < r) rs = r;
191  if (cs < c) cs = c;
192  s = v->getSize ();
193  free (n);
194  if ((deps = v->getDependencies ()) != NULL) {
195  vd = deps->get (0);
196  }
197  }
198  }
199  // minimum noise figure?
200  if (!strcmp (vn, "Fmin")) {
201  touchstone_data.fmin = v;
202  if ((deps = v->getDependencies ()) != NULL) vf = deps->get (0);
203  }
204  // optimal input reflection for minimum noise figure?
205  else if (!strcmp (vn, "Sopt")) {
206  touchstone_data.sopt = v;
207  if ((deps = v->getDependencies ()) != NULL) vf = deps->get (0);
208  }
209  // effective noise resitance?
210  else if (!strcmp (vn, "Rn")) {
211  touchstone_data.rn = v;
212  if ((deps = v->getDependencies ()) != NULL) vf = deps->get (0);
213  }
214  }
215 
216  // matrix entries found
217  if (rs >= 0 && cs >= 0 && vd != NULL) {
218  int ss = rs > cs ? rs : cs;
219  // fill in number of ports
220  touchstone_data.ports = ss + 1;
221  // create quadratic matrix vector
222  matvec * mv = new matvec (s, ss + 1, ss + 1);
223  mv->setName (name);
224  // fill in matrix vectors
225  for (v = data->getVariables (); v; v = (vector *) v->getNext ()) {
226  vn = v->getName ();
227  if (strstr (vn, name) == vn) {
228  if ((n = matvec::isMatrixVector (vn, r, c)) != NULL) {
229  mv->set (*v, r, c);
230  free (n);
231  }
232  }
233  }
234  // store in global structure
235  touchstone_data.mv = mv;
236  touchstone_data.parameter = toupper (mv->getName ()[0]);
237  // look for dependency (frequency) vector
238  for (v = data->getDependencies (); v; v = (vector *) v->getNext ()) {
239  if (vd && !strcmp (v->getName (), vd)) {
240  touchstone_data.vd = v;
241  }
242  if (vf && !strcmp (v->getName (), vf)) {
243  touchstone_data.vf = v;
244  }
245  }
246  }
247 }
248 
249 /* This is the overall Touchstone producer. */
250 void touchstone_producer (const char * variable) {
251 
252  // apply data variable name
253  if (variable == NULL) {
254  variable = "S";
255  }
256 
257  // initialize global Touchstone structure
258  touchstone_data.mv = NULL;
259  touchstone_data.vd = NULL;
260  touchstone_data.format = "RI";
262  touchstone_data.fmin = NULL;
263  touchstone_data.sopt = NULL;
264  touchstone_data.rn = NULL;
265  touchstone_data.vf = NULL;
266 
267  // look for appropriate matrix data
268  touchstone_find_data (qucs_data, variable);
269 
270  // print matrix data if available
271  if (touchstone_data.mv != NULL) {
272  touchstone_print ();
273  delete touchstone_data.mv;
275  }
276  else {
277  fprintf (stderr, "no such data variable `%s' found\n", variable);
278  }
279 }