Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

io.h

Go to the documentation of this file.
00001 // SuperMix version 1.0  C++ source file
00002 //
00003 // Copyright (c) 1999 California Institute of Technology.
00004 // All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms for noncommercial
00007 // purposes are permitted provided that the above copyright notice and
00008 // this paragraph are duplicated in all such forms and that any
00009 // documentation and other materials related to such distribution and
00010 // use acknowledge that the software was developed by California
00011 // Institute of Technology. Redistribution and/or use in source or
00012 // binary forms is not permitted for any commercial purpose. Use of
00013 // this software does not include a permitted use of the Institute's
00014 // name or trademark for any purpose.
00015 //
00016 // DISCLAIMER:
00017 // THIS SOFTWARE AND/OR RELATED MATERIALS ARE PROVIDED "AS-IS" WITHOUT
00018 // WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR
00019 // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE (AS SET
00020 // FORTH IN UCC 23212-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
00021 // LICENSED PRODUCT, HOWEVER USED.  IN NO EVENT SHALL CALTECH/JPL BE
00022 // LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING BUT NOT LIMITED TO
00023 // INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, INCLUDING ECONOMIC
00024 // DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF
00025 // WHETHER CALTECH/JPL SHALL BE ADVISED, HAVE REASON TO KNOW, OR IN
00026 // FACT SHALL KNOW OF THE POSSIBILITY.  THE USER BEARS ALL RISK
00027 // RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE AND/OR RELATED
00028 // MATERIALS.
00029 //
00030 // ********************************************************************
00031 // io.h
00032 // classes and functions to aid in reading and writing formatted data
00033 //
00034 // F.R. 9/27/99
00035 //
00036 // 10/2/00:  Added cabability to read HFSS-output Touchstone files with
00037 //           more than 4 ports.
00038 //
00039 // ********************************************************************
00040 
00041 #ifndef IO_H
00042 #define IO_H
00043 
00044 #include <string>
00045 #include <vector>
00046 #include <iostream>
00047 #include <fstream>
00048 #include "matmath.h"
00049 #include "units.h"
00050 
00051 // ********************************************************************
00052 class data_parser
00053 {
00054 public:
00055 
00056   // Constructor can take a reference to the input stream.
00057   data_parser();
00058   data_parser(istream &);
00059 
00060   // Set or change the input stream.
00061   data_parser & input(istream & i) { pin = &i ; return *this ; }
00062 
00063   // Parse the next line of data; return the number of doubles found.
00064   // parse() has a voracious appetite for doubles but complete indifference
00065   // to anything else on a line. To qualify as a double, a token must look
00066   // like what you would think of as a double. It must be separated from
00067   // any previous token by some white space, but need not be separated from
00068   // any following token by white space. Consequently the string "-2Volts"
00069   // contains the double -2.0, while "Perfect-10.0" contains no doubles, since
00070   // "-10.0" is not preceded by white space. A comment character on the line
00071   // causes parse to stop looking for doubles following it. 
00072   unsigned parse();
00073 
00074   // Like parse, except first skip any lines without uncommented numbers;
00075   // returns 0 if end of file or error encountered.
00076   unsigned skip_parse();
00077 
00078   // Parse the string supplied as an argument as though it were input.
00079   unsigned parse(const std::string &);
00080   unsigned parse(const char * const);
00081 
00082 
00083   // A STL vector<double> containing the uncommented doubles found by
00084   // the latest call to parse().
00085   const std::vector<double> & data() { return data_ ; }
00086 
00087   // The latest input line read by parse(), parsed into a STL vector of C++
00088   // string tokens which were found separated by one or more whitespace char's
00089   // in the line. Whitespace chars are those identified as such by the C macro
00090   // isspace().
00091   const std::vector<string> & tokens();
00092 
00093 
00094   // Convert the data in data() into the supplied container.
00095   // Returns number of elements stored to the container (0 if an error).
00096   // Uses Complex::dtoz() to convert doubles to Complex. Optionally scales
00097   // converted values by multiplying by "units" following conversion.
00098 
00099   int convert(real_vector &, double units = 1.0);    // Starts with index = 1 in the
00100   int convert(complex_vector &, double units = 1.0); // receiving containers.
00101 
00102 
00103   // Convert the data in data() into the supplied double and container;
00104   // returns number of elements stored to the container (0 if an error).
00105   // Uses Complex::dtoz() to convert doubles to Complex. data()[0] (the first value
00106   // found on the line) goes into the double, the rest into the container. Optionally
00107   // scales converted values by multiplying by "u1" for the double, "u2" for the
00108   // values in the container following conversion. There must be at least two
00109   // doubles in data() for a conversion to be performed.
00110 
00111   int convert(double &, real_vector &, double u1 = 1.0, double u2 = 1.0);
00112   int convert(double &, complex_vector &, double u1 = 1.0, double u2 = 1.0);
00113 
00114 
00115   // String containing the entire line text found by parse().
00116   const std::string & line() { return line_ ; }
00117 
00118   // String containing the comment text found by parse(). The comment delimiter
00119   // is the first character of the string.
00120   const std::string & comment() { return comment_ ; }
00121 
00122 
00123   // String containing the comment delimiter chars recognized by parse().
00124   // Since the reference returned is not const, you can change this string,
00125   // changing the subsequent behavior of parse().
00126   std::string & delim() { return delim_ ; }
00127 
00128   // String constaining the default comment delimiter chars, '#' and '!'.
00129   // Each newly created data_parser object will use this string to initialize
00130   // delim(). You can change this string.
00131   static std::string & default_delim() { return def_delim_ ; }
00132 
00133 
00134 private:
00135   istream * pin ;                  // pointer to the input stream
00136   std::string line_ ;              // hold the line being parsed
00137   std::string comment_ ;           // hold the comment found in current line
00138   std::string delim_ ;             // hold a list of comment delimiter chars
00139   std::vector<string> tokens_ ;    // hold the tokens found on the line
00140   std::vector<double> data_ ;      // hold the numbers found on the line
00141   static std::string def_delim_ ;  // hold the default comment delimiters
00142 
00143 };
00144 
00145 
00146 // ********************************************************************
00147 // class touchstone_base
00148 //
00149 // Base class containing common elements of the touchstone file classes
00150 // touchstone_read and touchstone_write
00151 
00152 class touchstone_base
00153 {
00154 public:
00155 
00156   // the recognized matrix types
00157   enum types { S, Y, Z };
00158 
00159 };
00160 
00161 
00162 // ********************************************************************
00163 // class touchstone_read
00164 //
00165 // This class can input frequency response data from most properly-formatted
00166 // Touchstone files, and many "improperly" formatted ones.. It understands
00167 // S, Z, and Y type matrix data in any of MA, DB, or RI number formats.
00168 //
00169 // It can interpret files which are minor generalizations of the strict
00170 // Touchstone format: it ignores lines containing no doubles (as interpreted by
00171 // data_parser::parse(), see above), even if they do not use a comment delimiter
00172 // ('!'), and can handle numbers of ports exceeding 4 by looking for a
00173 // generalization of the Touchstone format of 4-port data. The genereralized
00174 // data format for an N-port (with N > 4) may be either of the following 2
00175 // formats:
00176 //
00177 // Format 1 (all S parameters for a row on a single line):
00178 //
00179 //   freq1  S(1,1)  S(1,2)  S(1,3)  S(1,4)  ... S(1,N)
00180 //          S(2,1)  S(2,2)  S(2,3)  S(2,4)  ... S(2,N)
00181 //          S(3,1)  S(3,2)  S(3,3)  S(3,4)  ... S(3,N)
00182 //           ...
00183 //          S(N,1)  S(N,2)  S(N,3)  S(N,4)  ... S(N,N)
00184 //
00185 //   freq2  S(1,1)  S(1,2)  S(1,3)  S(1,4)  ... S(1,N)
00186 //          S(2,1)  S(2,2)  S(2,3)  S(2,4)  ... S(2,N)
00187 //           ...
00188 //
00189 // Format 2 (at least 4 S parameters per line; a single row's data wraps): 
00190 //
00191 //   freq1  S(1,1)  S(1,2)  S(1,3)  S(1,4)
00192 //          S(1,5)  S(1,6)  S(1,7)  S(1,8)
00193 //           ...  S(1,N-1)  S(1,N)
00194 //          S(2,1)  S(2,2)  S(2,3)  S(2,4)
00195 //          S(2,5)  S(2,6)  S(2,7)  S(2,8)
00196 //           ...  S(2,N-1)  S(2,N)
00197 //           ...
00198 //          S(N,1)  S(N,2)  S(N,3)  S(N,4)
00199 //          S(N,5)  S(N,6)  S(N,7)  S(N,8)
00200 //           ...
00201 //           ...  S(N,N-1)  S(N,N)
00202 //
00203 //   freq2  S(1,1)  S(1,2)  S(1,3)  S(1,4)
00204 //          S(1,5)  S(1,6)  S(1,7)  S(1,8)
00205 //           ...  S(1,N-1)  S(1,N)
00206 //           ...
00207 //
00208 // Each freq value is a single number; the S matrix values are each a pair
00209 // of numbers. Format 2 is output by programs such as HFSS and HPADS.
00210 
00211 class touchstone_read : public touchstone_base
00212 {
00213 public:
00214 
00215   // -------------------
00216   // Create object and open a file:
00217 
00218   touchstone_read();  // the only constructor is the default.
00219 
00220   // Open the named file. Look for and interpret a specification line, if present.
00221   // Any previously-opened file is first closed. Returns false if unable to open or
00222   // can't find any numerical data in the file. f_scale gives the default scaling
00223   // for the file's frequency data; it will be overridden by the file's specification
00224   // line frequency scaling, if present. In the event a specification line is not
00225   // present (specification lines begin with "# "), uses the default format which would
00226   // have a specification line of:   "# <f_scale> S MA R 50" (f_scale frequency scale,
00227   // S parameter in Magnitude-Degree, 50 Ohm normalization). Note that white space must
00228   // separate the '#' and the rest of the specification line.
00229   bool open(const char * const name, int ports = 2, double f_scale = GHz);
00230 
00231 
00232   // -------------------
00233   // Get the matrix data:
00234 
00235   // Returns the type of matrix data in the file. Returns S if something went wrong.
00236   typedef touchstone_base::types types;
00237   types type() const { return type_ ; }
00238 
00239   // Fills in the frequency and Matrix data from the next data line of the file.
00240   // Returns false when no more Matrix data could be read from file, or data improperly
00241   // formatted, or no file has been specified with open(); f and M will not be
00242   // modified in this case. The data returned in the Matrix argument to value()
00243   // will be properly converted to supermix internal values using this impedance. In
00244   // the case of types Y and Z, the matrix elements are individually scaled using z()
00245   // to accomplish this conversion. In the case of type S, the matrix data is
00246   // renormalized to the normalizing impedance in the current value of device::Z0. 
00247   bool value(double & f, Matrix & M);
00248 
00249   // Svalue() is like value, except that if the file contains Y or Z data, it converts
00250   // the data to the equivalent S matrix normalized to device::Z0.
00251   bool Svalue(double & f, Matrix & S);
00252 
00253   // Yvalue() is like Svalue, except that it returns the equivalent Y matrix.
00254   bool Yvalue(double & f, Matrix & Y);
00255 
00256   // Zvalue() is like Svalue, except that it returns the equivalent Z matrix.
00257   bool Zvalue(double & f, Matrix & Z);
00258 
00259 
00260   // -------------------
00261   // Get the noise data:
00262 
00263   // Container for noise data read from a file
00264   struct noise {
00265     double  Fmin;   // min noise figure in dB
00266     complex Gopt;   // optimum source reflection coefficient (Gamma)
00267     double  Reff;   // effective noise resistance
00268   };
00269 
00270   // Returns true if noise data is detected in the file.
00271   bool has_noise() const { return (N == 2) && noise_ ; }
00272 
00273   // If the next lines in the file contain noise data (file must be for a 2-port),
00274   // fill in the members of N with that data. f will get the frequency of the data.
00275   // If there is no properly formatted noise data remaining, returns false. f and N will
00276   // not be modified in this case. N.Gopt will contain the source Gamma properly
00277   // renormalized to device::Z0; N.Reff will be a real (unnormalized) resistance.
00278   bool get_noise(double & f, noise & N);
00279   
00280 
00281   // -------------------
00282   // Other functions:
00283 
00284   // Returns false if data format was improper on latest call to open() or value().
00285   // If a call to value() returns false, but good() returns true, then the end of
00286   // the matrix data values has been reached. Returns false if open() has not been called.
00287   bool good() const { return (N != 0); }
00288 
00289   // Returns the normalizing impedance of the data in the file. The data
00290   // returned in the Matrix argument to value() will be properly converted to
00291   // supermix internal values using this impedance. In the case of types Y and Z,
00292   // the matrix elements are individually scaled using z() to accomplish this
00293   // conversion. In the case of type S, the matrix data is renormalized to the
00294   // normalizing impedance in the current value of device::Z0.
00295   double z() const { return z_ ; }
00296 
00297   // Verbosity. The default is for verbose behavior to be enabled. If verbose, then
00298   // warnings will be issued for problems encountered. If quiet, then no warnings will
00299   // be issued, so the return values of functions will give the only indications of
00300   // bad behavior.
00301   touchstone_read & verbose() { verbose_ = true;  return *this; }
00302   touchstone_read & quiet()   { verbose_ = false; return *this; }
00303   
00304   // -------------------
00305   // A static (global) function to determine the number of ports in a Touchstone file
00306 
00307   // Examine the named file. If it is a properly-formatted Touchstone file, return the
00308   // number of ports for the device described by the file. Return 0 if the file is not
00309   // a proper Touchstone file. This function only checks the specification line format
00310   // and examines the first data set in the file, so its checks are not at all
00311   // comprehensive. It should correctly interpret an "extended" Touchstone format for
00312   // files with more than 4 ports.
00313   static int ports(const char * const name);
00314 
00315 private:
00316 
00317   touchstone_read(const touchstone_read &);  // no copy constructor!
00318   void operator = (const touchstone_read &); // no assignment operator!
00319 
00320   std::string name_; // the name of the file opened
00321   ifstream s;        // the stream for this file
00322   data_parser d;     // the data parser object used to parse the file
00323   int N;             // number of ports in the data (0 if something went wrong)
00324   bool end_;         // true when the end of the matrix data has been seen.
00325   bool noise_;       // true when noise data is available
00326   bool verbose_;     // warning behavior
00327 
00328   double f_units;    // units for file frequency data
00329   double z_;         // normalizing impedance of file data
00330   types type_;       // the type of matrix in the file
00331   double f_last;     // the latest frequency seen
00332 
00333   Matrix normalize(const Matrix &);  // use type_ and z_ to normalize data
00334 
00335   Complex::io_mode mode;     // the input mode (format) of the S data
00336   Complex::io_mode old_mode; // saves the io_mode at entry to value()
00337 
00338 };
00339 
00340 #endif /* IO_H */

Please direct comments and corrections to supermix@submm.caltech.edu
Go to the supermix home page
Generated by doxygen1.2.7