//************************************************************************************************** // PrcGnuCap.cpp * // --------------- * // Started : 2003-09-01 * // Last Update : 2016-07-24 * // Copyright : (C) 2003-2016 MSWaters * //************************************************************************************************** //************************************************************************************************** // * // This program is free software; you can redistribute it and/or modify it under the * // terms of the GNU General Public License as published by the Free Software Foundation; * // either version 3 of the License, or (at your option) any later version. * // * //************************************************************************************************** #include "PrcGnuCap.hpp" //************************************************************************************************** // Constructor. PrcGnuCap::PrcGnuCap( void ) : PrcSimEngBase( ) { // Set the simulation engine type m_eSimEng = eSIMR_GNUCAP; // Set the simulator binary file name if it can be found bSetBinFile( BIN_GNUCAP ); } //************************************************************************************************** // Destructor. PrcGnuCap::~PrcGnuCap( ) { } //************************************************************************************************** // Check / format the component lines in the simulation object so that they are // compatible with GNU-Cap. Ie. add the substrate node to BJT components which // are missing it, the substrate node is assumed to be connected to the // collector. Eg. "Q1 nc nb ne BC109" would become "Q1 nc nb ne nc BC109". // // Argument List : // roaCpnts - An array of ArrayComponent objects // // Return Values : // true - Success // false - Failure /* ??? 17/08/2009 bool PrcGnuCap::bFmtCpnts( ArrayComponent & roaCpnts ) { wxString os1; size_t sz1; for( sz1=0; sz1SetPath( wxT("/GNU-Cap") ); // Delete unwanted columns of data for( ostk1.SetString( m_oFileResults.GetFirstLine( ) ); !m_oFileResults.Eof( ); ostk1.SetString( m_oFileResults.GetNextLine( ) ) ) { if( ostk1.CountTokens( ) != 7 ) continue; // Get the operator field ie. frequency os1 = ostk1.GetNextToken( ); // Do we want actual or relative magnitude? poConfig->Read( wxT("FO_MagRel"), &b1, false ); if( b1 ) for( sz1=0; sz1<3; sz1++ ) ostk1.GetNextToken( ); // Do we want dB magnitude? poConfig->Read( wxT("FO_MagDB"), &b1, false ); if( b1 ) { ostk1.GetNextToken( ); os1 << wxT(' ') << ostk1.GetNextToken( ); } else { os1 << wxT(' ') << ostk1.GetNextToken( ); ostk1.GetNextToken( ); } // Do we want phase? poConfig->Read( wxT("FO_Phase"), &b1, false ); if( b1 ) os1 << wxT(' ') << ostk1.GetNextToken( ); // Record the data m_oFileResults[ m_oFileResults.GetCurrentLine( ) ] = os1; } // Construct the data column headers os1 = wxT("#Freq"); for( ostk1.SetString( m_oFileResults.GetFirstLine( ) ); !m_oFileResults.Eof( ); ostk1.SetString( m_oFileResults.GetNextLine( ) ) ) { // Look for header lines if( ostk1.GetNextToken( ) != wxT("#") ) continue; os2 = ostk1.GetNextToken( ); // Do we want dB magnitude? os3 = os2; poConfig->Read( wxT("FO_MagDB"), &b1, false ); if( b1 ) os3.insert( 1, wxT("DB") ); os1 << wxT(' ') << os3; // Do we want phase? poConfig->Read( wxT("FO_Phase"), &b1, false ); if( b1 ) { os3 = os2; os3.insert( 1, wxT("P") ); os1 << wxT(' ') << os3; } // Remove the unwanted header lines if( m_oFileResults.GetCurrentLine( ) > 0 ) m_oFileResults.RemoveLine( m_oFileResults.GetCurrentLine( ) ); } m_oFileResults[ 0 ] = os1; // Determine the number of unique data lines ostk1.SetString( m_oFileResults.GetFirstLine( ) ); ostk1.SetString( m_oFileResults.GetNextLine( ) ); os1 = ostk1.GetNextToken( ); for( ostk1.SetString( m_oFileResults.GetNextLine( ) ), sz1=1; !m_oFileResults.Eof( ); ostk1.SetString( m_oFileResults.GetNextLine( ) ), sz1++ ) { if( os1 == ostk1.GetNextToken( ) ) break; } // Concatinate data lines according to frequency for( sz2=1; sz2<=sz1; sz2++ ) { m_oFileResults.GoToLine( sz2-1 ); ostk1.SetString( m_oFileResults.GetNextLine( ) ); os1 = ostk1.GetNextToken( ); for( ostk1.SetString( m_oFileResults.GetNextLine( ) ); !m_oFileResults.Eof( ); ostk1.SetString( m_oFileResults.GetNextLine( ) ) ) { if( os1 == ostk1.GetNextToken( ) ) m_oFileResults[ sz2 ] << wxT(' ') << ostk1.GetString( ); } } // Delete data lines which are no longer needed m_oFileResults.GoToLine( sz1+1 ); while( ! m_oFileResults.Eof( ) ) m_oFileResults.RemoveLine( m_oFileResults.GetCurrentLine( ) ); // Format the column header line and insert it at the start of the file bRtn = bFmtColLabels( ); // Format the data lines if( ! bFmtDataLines( ) ) bRtn = false; return( bRtn ); } //************************************************************************************************** // Make the process argument list based on the contents of a simulation object. // // Argument List : // roSimn - The simulation object // // Return Values : // true - Success // false - Failure bool PrcGnuCap::bMakeArgLst( SimnBase & roSimn ) { wxString os1; // Record the sweep source component name since GNU-Cap has a bug in the DC // analysis results. The column label for the sweep source values is missing. m_osSwpSrcName = roSimn.m_oCpntSwpSrc.rosGetName( ); // Envoke the base class operations if( ! PrcSimEngBase::bMakeArgLst( roSimn ) ) return( false ); // Construct the command line to execute the simulation os1 = wxT("-b ") + roSimn.roGetSaveFile( ).GetFullPath( ); if( ! bSetArgLst( os1 ) ) { SetErrMsg( wxT("Couldn't set argument list") ); return( false ); } return( true ); } //************************************************************************************************** // Format the contents of the results file so that gWave can read it ie. a header line at the top // containing parameter names followed by the columns of data. // // Return Values : // true - Success // false - Failure bool PrcGnuCap::bFmtResults( void ) { bool bRtn; wxString os1; m_osErrMsg.Empty( ); // Check that the results file exists if( ! roGetResultsFile( ).FileExists( ) ) { os1.Empty( ); os1 << wxT("Results file doesn't exist : \n\n") << roGetResultsFile( ).GetFullPath( ); SetErrMsg( os1 ); return( false ); } // Attempt to open the results file if( ! m_oFileResults.Open( roGetResultsFile( ).GetFullPath( ) ) ) { os1.Empty( ); os1 << wxT("Results file couldn't be opened : \n\n") << roGetResultsFile( ).GetFullPath( ); SetErrMsg( os1 ); return( false ); } // Format the simulation results os1 = roGetResultsFile( ).GetFullName( ).Right( 3 ); if( os1 != wxT(".fo") ) { bRtn = bFmtGeneral( ); // Format the column header line and insert it at the start of the file if( bRtn ) bRtn = bFmtColLabels( ); // Format the data lines if( bRtn ) bRtn = bFmtDataLines( ); } else bRtn = bFmtResultsFO( ); // Align all the columns in the results file if( bRtn ) bRtn = PrcSimEngBase::bFmtResults( ); m_oFileResults.Write( ); // Save the changes to disk m_oFileResults.Close( ); // Close the file return( bRtn ); } //**************************************************************************************************