OptiSystem Tutorials CPP Component
OptiSystem Tutorials CPP Component
Version 14
OptiSystem
Tutorials - C++ Component
Optical Communication System Design Software
All OptiSystem documents, including this one, and the information contained therein, is copyright material.
No part of this document may be reproduced, stored in a retrieval system, or transmitted in any form or by any means whatsoever,
including recording, photocopying, or faxing, without prior written approval of Optiwave.
Disclaimer
Optiwave makes no representation or warranty with respect to the adequacy of this documentation or the programs which it
describes for any particular purpose or with respect to its adequacy to produce any particular result. In no event shall Optiwave, its
employees, its contractors or the authors of this documentation, be liable for special, direct, indirect, or consequential damages,
losses, costs, charges, claims, demands, or claim for lost profits, fees, or expenses of any nature or kind.
Technical support
If you purchased Optiwave software from a distributor that is not listed here, please send technical
questions to your distributor.
Optiwave Canada/US
Tel (613) 224-4700 E-mail [email protected]
Fax (613) 224-4706 URL www.optiwave.com
Tutorial 1: Release and Debug modes, Basic manipulation of a Binary Signal .........7
Tutorial 2: Basic Manipulation of Mary Signals ........................................................23
Tutorial 3: Basic Manipulation of Electrical Signals..................................................37
Tutorial 4: Electrical pulse shaper with M-ary input..................................................43
Tutorial 5: Binary controlled optical switch. ..............................................................49
Tutorial 6: Optical transverse mode converter .........................................................55
Tutorial 7: Working with optical parameterized signals and noise bins....................61
Appendix 1: Overview of signal types ......................................................................67
Appendix 2: Debugging tips (release mode) ............................................................77
Introduction
IMPORTANT!
To create and compile the C++ code for the Cpp Component you must have either
Microsoft Visual Studio 2013 Community or Professional installed on your computer.
(Note: The Cpp Component is not currently compatible with Microsoft Visual Studio
2015!).
Release mode - The component project is compiled as a dynamic link library (.dll) in
release mode. OptiSystem will load the “dll” during runtime. The signal data is passed
directly from OptiSystem to the “dll” and then, after processing, from the “dll” back to
OptiSystem. This is the mode to use when you wish to run OptiSystem and your C++
component within it.
The full documentation and a pre-configured project is available at the Optiwave C++
Component Home Page
The project is large with many classes available to the user. Due to the number of
configuration settings involved, it is recommended to create a copy of this default
project and add code to it for each component the user wishes to define. The user
may add as many classes as they wish to this project but it is not recommended that
the user removes or alters the classes already provided other than at the defined entry
point: Calculate_API() in class DS_SystemManager.cpp.
The project has been set up so that very little changes must be made to switch
between the Release and Debug modes. The user will not need to alter any of their
1
code, just change some configuration settings and add a line of code to tell the project
where to find the XML file mentioned above. The two different modes are explained
in detail in Tutorial 1: Binary Signal Manipulation.
The most effective method to learn the usage of OptiSystem's C++ component is to
follow the tutorials below. They will teach the user how to access and manipulate the
basic data structures, configure the project for release and debug mode, and use
many of the convenience functions built into the project.
It is recommended that the user create a copy of the default project available at the
Optiwave C++ Component Home Page for each tutorial, then follow along for the
manipulations of the C++ code and the creation of the OptiSystem project.
Tutorials
• Tutorial 1: Release and Debug modes, Basic manipulation of a Binary Signal
• Tutorial 2: Basic Manipulation of Mary Signals
• Tutorial 3: Basic Manipulation of Electrical Signals
• Tutorial 4: Electrical pulse shaper with M-ary input
• Tutorial 5: Binary controlled optical switch.
• Tutorial 6: Optical transverse mode converter
• Tutorial 7: Working with optical parameterized signals and noise bins
• Appendix 1: Overview of signal types
• Appendix 2: Debugging tips (release mode)
2
3
4
C++ Component Tutorials
This section contains the following introductory tutorials for the Cpp (C++) Component.
5
6
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
This tutorial describes how to configure a project in either Release mode or Debug
mode. It also demonstrates how to manipulate a binary signal.
Step Action
Figure 1
7
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
Figure 2
Figure 3
8
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
Figure 4
Figure 5
Implementation of code
4 Under CppCoSimulation/Source Files, double-click on
DS_SystemManager.cpp
5 Within this file, navigate to the function bool
CDS_SystemManager:Calculate_API(). (Fig 6)
This represents the entry point for your code into the project. For all of your
projects, you will start your code here. You may create your own classes and
functions which will be called from here.
9
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
Figure 6
if (pOOSignal1 != NULL)
{
if (pOOSignal1->GetSignalName() == "BinarySignal")
{
The first line loads the signal from the first (and in this case only) port. If you
had a second port to load, you would add: CDS_SignalBase * pIOSignal2 =
GetSignalFromInputPort(2). The IF conditions have been added as a safety
precaution. This will ensure that the calculation will only go ahead if the input
port is defined with the proper signal type
Getting binary data
7 Copy the following lines into the function
This binary signal class holds both the sequence of bits (vector<long>
binarySignal1.m_Bits) and the bit rate (binarySignal1.GetBitRate()).
10
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
Manipulating data
8 Now that the data has been placed on a vector, we can manipulate this to our
requirements. In this case we are simply performing a binary inverse
operation. Copy the following lines into the function
if (pOOSignal1 != NULL)
{
if (pOOSignal1->GetSignalName() == "BinarySignal")
{
This will create an output port for our data for OptiSystem to access. Checks
have been added to make sure that the calculation will only go ahead if the
output port on the C++ component is configured correctly
Set the output port signal to the binary signal
10 Copy the following lines into the function
PutBinarySignal(binarySignal1, pOOSignal1);
//put the binary signal onto the output port
Code for error checking
11 Copy the following lines into the function
Ensures that we close all the brackets for our safety precautions
}
else
{
return 0; //returns warning to OptiSystem -- output is not set correctly to binary
} //if (pOOSignal1->GetSignalName() == "BinarySignal")
} //if (pOOSignal1 != NULL)
else
{
return 0; //returns warning to OptiSystem -- output put not created
}
} //if (pIOSignal1 != NULL)
} //if (pIOSignal1->GetSignalName() == "BinarySignal")
SaveOutputDataToFiles();//for debugging purposes
////////////////////////////////////////
return 1; //for successful run
11
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
Note: The full code and an OptiSystem project for this function
(Tutorial1SupplementaryFiles.zip) is available at the Optiwave C++ Component
Home Page. Replace the DS_SystemManager.cpp file in your project with the
one given in the zip file. If you want to run in debug, you must also change the
location of the XML given in CppCoSimulation.cpp. In addition change the
location of the files in the OptiSystem projects to your particular files and
directories
Note we have added some code right at the beginning of the routine (as follows)
//////////////////////////////////////////////////////////////
//do not remove
//////////////////////////////////////////////////////////////
#ifdef _EXE_CONSOLE
m_bInExecutableMode = true;
#else
m_bInExecutableMode = false;
#endif
// this flag can be useful for some parameters to be adjusted depending on the mode
InitializeGlobals(); //set some of the key global parameters so they are avaliable in debug mode
//////////////////////////////////////////////////////////////
//do not remove
//////////////////////////////////////////////////////////////
This code is not necessary to run this example, but it is a good idea to keep in all future
projects.
The variable m_bInExecutableMode will be used in the next example. The command
InitializeGlobals(); is to make sure all global parameters are initialized correctly when
we are running in debug mode.
12
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
Figure 7
Note: Make sure to load the appropriate dll in Step 3 (Part 2).
13
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
Step Action
14
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
15
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
Figure 12
Figure 13
16
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
3 Make sure Save Data As CPP XML Load File is checked (Fig 13)
4 Choose a location and Filename for the XML file by clicking on the grey box.
In this example we will call the file testXML.txt and save it at [your Cpp project
location]\CppCoSimulation\testXML.txt
The XML file is a text file in XML format that will inform the component about
all the ports and the locations of the data files.
5 Set the input and output ports to be exactly the same as the Cpp Component
(binary) - Fig 14
At the present time, the output port is not necessary, but we have included it
for future functionality
Figure 14
6 On CPP Filename click on the grey box and select a name and location for
the binary signal data.
For this example you could choose [your Cpp project
location]\CppCoSimulation\CPPFilename.txt]
Note: You won't have to enter this filename in your code explicitly as this
information will be recorded in the XML file of step 4.
7 Run the program
If you double click on the visualizer, you will see the data for the port
displayed in a format similar to the view signal visualizer. There is an arrow
to scroll through the data on each port. The data you see on this visualizer is
duplicated in the data file specified above and the XML file holds the
information about the ports. These data files are shown in Fig 15.
Note: Do not manipulate these data files, they are auto generated by
OptiSystem
17
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
Figure 15
18
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
Figure 17
Figure 18
19
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
Figure 19
Figure 20 CppCoSimulation.cpp
7 Within this file (see Fig 20), navigate to the function “int _tmain(int argc,
_TCHAR* argv[])”. This is the starting point for your stand alone configuration.
Add the following line to your code:
20
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
End of Tutorial 1
21
TUTORIAL 1: RELEASE AND DEBUG MODES, BASIC MANIPULATION OF A BINARY SIGNAL
22
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
In this tutorial, the user is introduced to the Mary signal class. In addition, it will be
demonstrated how to read in global parameters, define and read in local parameters,
and create results and graphs
The first line loads the signal from the first (and in this case only) port. This is
exactly the same as in Tutorial 1 The IF conditions have been added as a
safety precaution. This will ensure that the calculation will only go ahead if the
input port is defined with the proper signal type.
Getting binary data
4 Copy the following lines into the function
Similar to the binary, the Mary signal class holds both the sequence of
symbols (vector<double> marySignal1.m_Symbols) and the symbol rate
(marySignal1.GetSymbolRate()).
Get the global parameters
5 In this project, as a simple demonstration, we will load the global layout
parameter of the sequence length and then just redisplay it on our local
results. Any of OptiSystem's layout parameters can be accessed by name
using the appropriate function. For example, to access the layout parameters
listed in Fig 1 we could write
23
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
Figure 1
////////////////////////////////////////////////////////////////////////////////////////////////////
//Get global parameter
long nSequenceLength = GetGlobalParameterLong("Sequence length");
//get the sequence length from the layout. The data is in long format.
Get the user defined component parameters
When we set up the OptiSystem project (to be shown later), we will define a
double precision component parameter called “Multiplication Factor”. Here
we will write the code to access this. It is very similar to obtaining the global
parameters above except the function name is now “GetParameterDouble”
for doubles, “GetParameterLong” for longs and “GetParameterBool” for
booleans.
7 Copy the following lines into the function
////////////////////////////////////////////////////////////////////////////////////////////////////
//Get user defined parameter
double dMultiplicationFactor = GetParameterDouble("Multiplication Factor");
24
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
Manipulating data
Now that the data has been placed on a vector, and we have read in our
parameters we can manipulate to our requirements. In this case we are
simply multiplying the Mary data by the defined multiplication factor.
8 Copy the following lines into the function
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Data manipulation
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//multiply MARY elements by given factor
for (int i = 0; i < marySignal1.m_Symbols.size();i++)
{
marySignal1.m_Symbols[i] *= dMultiplicationFactor;
}
Adding a result
Adding a result, which will be displayed in OptiSystem, is very simple. Using
the command below, the value of the variable nSequenceLength will be set
to the name “Global sequence length”
9 Copy the following lines into the function
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Add a result
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AddResult("Global sequence length", nSequenceLength);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Add a graph
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Allocate2DGraph("Mary sequence");
CDS_2DGraph* pGraph1 = Get2DGraph("Mary sequence");
//allocates the graph, the name Mary sequence is simply a unique identifier for this graph. Choose any name you
wish.
arrX1.resize(marySignal1.m_Symbols.size());
arrY1.resize(marySignal1.m_Symbols.size());
25
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
pGraph1->SetXData(arrX1);
pGraph1->SetYData(arrY1);
//adds the axis data to the graph.
Create an output port
11 Copy the following lines into the function
This will create an output port for our data for OptiSystem to access.
Set the output signal data sequence
12 Copy the following lines into the function
PutMarySignal(marySignal1, pOOSignal1);
//puts the mary signal onto the output port
//////////////////////////////////////////////// MARY SIGNAL OUTPUT///////////////////////////////////////////////////
}
else
{
return 0;
//returns warning to OptiSystem -- output is not set correctly to binary
} //if (pOOSignal1->GetSignalName() == "MarySignal")
} //if (pOOSignal1 != NULL)
else
{
return 0; //returns warning to OptiSystem -- output put not created
}
}
}
Note: The full code and an OptiSystem project for this function
(Tutorial2SupplementaryFiles.zip) is available at the Optiwave C++ Component
Home Page. Replace the DS_SystemManager.cpp file in your project with the
one given in the zip file. If you want to run in debug, you must also change the
location of the XML given in CppCoSimulation.cpp. In addition change the
26
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
location of the files in the OptiSystem projects to your particular files and
directories
27
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
Figure 4
Figure 5
The type floating-point will be read in as a double in our code. This parameter
can now be accessed on the main tab of our component.
Note: It is important to make sure the variable type defined in the component
(as shown in Fig 5: “floating-point”) is opened by the correct function
(GetParameterDouble (“Multiplication Factor”)); otherwise the value will
return zero in your code.
28
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
Figure 6
Figure 7
Component Results
The added result “Global sequence length” can be accessed just like the
built-in components: right-clicking on the component and selecting
“Component results” as well as listed in the project browser.
29
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
Figure 8
Component Graphs
The graph we created for the Mary sequence can also be accessed by the
standard method in the component browser.
Figure 9
30
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
double dMultiplicationFactor = 4;
Instead of having to comment out and retype code every time you switch from
Release to Debug mode, we use the binary flag determined from the predefined
project configuration set at the beginning of Calculate_API:
#ifdef _EXE_CONSOLE
m_bInExecutableMode = true;
#else
m_bInExecutableMode = false;
#endif
// this flag can be useful for some parameters to be adjusted depending on the mode
With:
if (!m_bInExecutableMode)
{
dMultiplicationFactor = GetParameterDouble("Multiplication Factor");
}
else
{
dMultiplicationFactor = 4.0;
}
With this condition, when compiling in release/dll mode we obtain the parameter from
the component. When compiling in debug/exe mode we set the parameter explicitly.
It is recommended that the user utilizes this method for all definitions where they need
to redefine them between release and debug modes. For the other steps, they are
very similar to tutorial 1
Step Action
1 Switch to debug mode
31
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
Figure 10
3 Choose the appropriate location for an XML file (for example “[your Cpp
project location]\CppCoSimulation\testXML.txt”
Figure 11
Figure 12
32
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
Figure 13
//////////////////////////////////////////////////////////////////////////////////////////
//Convenience plotting functions using gnuplot
//In order for these to work, you must have gnuplot for windows installed on your computer
//////////////////////////////////////////////////////////////////////////////////////////
void gnuplot2D(DOUBLEVECTOR x, DOUBLEVECTOR y, string title = "", string legend = "", string xlabel = "", string ylabel = "");
void gnuplot2D(DOUBLEVECTOR x1, DOUBLEVECTOR y1, DOUBLEVECTOR x2, DOUBLEVECTOR y2, string title = "", string legend1 = "", string legend2 =
"", string xlabel = "", string ylabel = "");
void gnuplot3DTopViewRealVector(DOUBLEVECTOR x, DOUBLEVECTOR y, DOUBLEVECTOR z, string title = "", string xlabel = "", string ylabel = "");
void gnuplot3DSurfaceRealVector(DOUBLEVECTOR x, DOUBLEVECTOR y, DOUBLEVECTOR z, string title = "", string xlabel = "", string ylabel = "");
void gnuplot3DTopViewTransverseMode(CNDS_OpticalTransverseMode mode, string type = "abs", string title = "");
void gnuplot3DSurfaceTransverseMode(CNDS_OpticalTransverseMode mode, string type = "abs", string title = "");
The 3D plotting functions will be discussed in a later tutorial. Here we have created
two overloaded 2D plotting functions. The first will plot one set of (x,y) data which must
be in double vector format. The second will plot two sets of (x,y) data against each
other. You may add titles and labels if desired.
For example, we plot the output M-ary data using the gnuplot 2D function:
In this case, we already created the appropriate data structures when we created the
OptiSystem graphs. We used arrX1 for the x coordinate data and arrY1 for the y
coordinate data:
pGraph1->SetXData(arrX1);
pGraph1->SetYData(arrY1);
//adds the axis data to the graph.
if (m_bInExecutableMode)
gnuplot2D(arrX1, arrY1, “Mary values versus sequence element”, “”, “Mary Element”, “Mary Value”);
//in executable mode plot the graph with gnuplot
33
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
which will duplicate the graph we created for the component in gnuplot when the
program is run
Figure 14
The “if (m_bInExecutableMode)” statement has been added so that the graph doesn't
show up when running in dll mode.
End of Tutorial 2
34
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
35
TUTORIAL 2: BASIC MANIPULATION OF MARY SIGNALS
36
TUTORIAL 3: BASIC MANIPULATION OF ELECTRICAL SIGNALS
Note: For this tutorial it is expected the user will copy the code provided in the
supplementary files. Here we only describe the key elements of this code.
In this tutorial we introduce the electrical signal class and demonstrate how one can
use our built-in functions of the class
The OptiSystem project and results are shown below. We re-sample the electrical
signal to the defined parameter “New Sample Rate” which we have set as “Sample
rate / 16", which in this case will be 40GHz
Figure 1
Note: The full code and an OptiSystem project for this function
(Tutorial3SupplementaryFiles.zip) is available at the Optiwave C++ Component
Home Page. Replace the DS_SystemManager.cpp file in your project with the
one given in the zip file. If you want to run in debug, you must also change the
location of the XML given in CppCoSimulation.cpp. In addition change the
location of the files in the OptiSystem projects to your particular files and
directories.
37
TUTORIAL 3: BASIC MANIPULATION OF ELECTRICAL SIGNALS
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////// Get Electrical Signal from Input Port 1 /////////////////////////////////////////////////////////
CNDS_ElectricalSampledSignal electricalSampledSignal = GetElectricalSampledSignal(pIOSignal1);
/////////////////////////////////////////// Get Electrical Signal from Input Port 1 /////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// enum types
enum enumSignalDomain
{
domainTime,
domainFrequency
};
The complex amplitude data is stored in m_arrAmplitude. Note that the information
can be defined in the time or frequency domain. Initially, all information (from
OptiSystem in release mode or data files in debug mode) is read in the frequency
domain. To switch domains, use the commands:
electricalSampledSignal.SetDomain(CNDS_ElectricalSampledSignal::domainTime);
or
electricalSampledSignal.SetDomain(CNDS_ElectricalSampledSignal::domainFrequency);
depending on your requirement. The SetDomain function will first check which
domain the signal is currently in. If it is already in the domain required, no further
38
TUTORIAL 3: BASIC MANIPULATION OF ELECTRICAL SIGNALS
Set data vector for signal before resampling (testing purposes in gnuplot)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//create vector of data before resampling for gnuplot2D
electricalSampledSignal.SetDomain(CNDS_ElectricalSampledSignal::domainTime);
DOUBLEVECTOR vecXBeforeResample, vecYBeforeResample;
for (int j = 0; j < electricalSampledSignal.GetSize(); j++)
{
vecXBeforeResample.push_back(j * GetGlobalParameterDouble("Time window") / electricalSampledSignal.GetSize());
vecYBeforeResample.push_back(real(electricalSampledSignal.m_arrAmplitude[j]));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
We will be plotting a graph in gnuplot to compare the real part of the signal (in this
case there is no phase rotation and so no imaginary part) before and after resampling.
Here we set up the vector for the before data.
We first make sure the signal is in the time-domain so that when we access
m_arrAmplitude. Then
sets the x-coordinate (time points vector). This gives the appropriate time divisions
over the total time window. Next the command
vecYBeforeResample.push_back(real(electricalSampledSignal.m_arrAmplitude[j]));
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Read parameter data entered into Cpp component interface in OptiSystem if in dll mode or set value if in exe mode
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
double dSampleRate;
if (m_bInExecutableMode)
{
dSampleRate = 40.0e9;
}
else
{
dSampleRate = GetParameterDouble("New Sample Rate");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Recall that we have defined in the OptiSystem component the parameter “New
Sample Rate” and if we are in debug mode we must define it explicitly as 40GHz (or
whichever value is desired).
39
TUTORIAL 3: BASIC MANIPULATION OF ELECTRICAL SIGNALS
Resampling
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// resample signal using built-in routines
electricalSampledSignal.DownsampleToFrequencyLimits(-dSampleRate / 2.0, dSampleRate / 2.0);
//Cut the signal to this frequency range you can take advantage of the built-in resampling routines in CNDS_ElectricalSampledSignal
//but this is not necessary if you have your own routines that you wish to use.
long nSize = PowerOfTwo(electricalSampledSignal.GetSize());
electricalSampledSignal.Resample(nSize);
//Resample to the newly defined sample rate over the time window
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
We wish to re-sample the data to the new sample rate. This is performed by our built
in class functions
DownsampleToFrequencyLimits this removes any of the higher frequency
components.
A restriction in OptiSystem is that all signals must be 2n samples long. The next two
commands
make sure this the case. Either cutting the frequency range slightly or zero padding it.
Set data vector for signal after resampling (testing purposes in gnuplot) and
plotting
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//create vector of data after resampling for gnuplot2D
electricalSampledSignal.SetDomain(CNDS_ElectricalSampledSignal::domainTime);
DOUBLEVECTOR vecXAfterResample, vecYAfterResample;
for (int j = 0; j < electricalSampledSignal.GetSize(); j++)
{
vecXAfterResample.push_back(j * GetGlobalParameterDouble("Time window") / electricalSampledSignal.GetSize());
vecYAfterResample.push_back(real(electricalSampledSignal.m_arrAmplitude[j]));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
The above is similar to the creation of the data vectors for before resampling. The data
will still be over the same time window, but now the time-divisions will be different.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// plot data
if (m_bInExecutableMode)
gnuplot2D(vecXBeforeResample, vecYBeforeResample, vecXAfterResample, vecYAfterResample, "electrical resampling",
"before resample", "after resample", "time", "amplitude");
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
The data is plotted from the call above. The figure below shows the result of this call
in gnuplot (Notice that this is the same result as we see in the OptiSystem visualizers)
40
TUTORIAL 3: BASIC MANIPULATION OF ELECTRICAL SIGNALS
Figure 2
The output port pOOSignal1 is created the same way as in the first two tutorials.
End of Tutorial 3
41
TUTORIAL 3: BASIC MANIPULATION OF ELECTRICAL SIGNALS
42
TUTORIAL 4: ELECTRICAL PULSE SHAPER WITH M-ARY INPUT
Note: For this tutorial it is expected the user will copy the code provided in the
supplementary files. Here we only describe the key elements of this code.
OptiSystem already has a number of pulse shapers. In this example we show how to
create a custom pulse shaper where the input is an M-ary signal. A pulse shape is
determined from a file of filter taps data (the FIR of the particular filter) which is applied
to the M-ary input to create a shaped electrical signal output. For this example, we will
use the impulse response of a root-raised cosine pulse, but the user can supply any
response file they wish. The component will create a pulse shape as shown in
Oscilloscope Visualizer_1 below.
Figure 1
For simplicity we set up a two level M-ary system with possible values of {-1,1} only.
In this case then, the bit rate will be the same as the symbol rate.
43
TUTORIAL 4: ELECTRICAL PULSE SHAPER WITH M-ARY INPUT
Figure 2
Note: in this example the layout parameter “Symbol rate” will not be used, only “Bit
rate” and “Samples per bit”. The symbol rate will be determined with the component
from the input M-ary signal.
Figure 3
44
TUTORIAL 4: ELECTRICAL PULSE SHAPER WITH M-ARY INPUT
The input port is of type “M-ary” and the output is of type “Electrical”. The tap file used
in this example represents the impulse root-raised cosine pulse as below. Note that
the number of taps = Shaping Waveform Duration * Symbols per bit + 1= 14 * 32 + 1
= 449. This requires knowledge of the symbols per bit. We can calculate this from the
bit rate (layout parameter) and the symbol rate (carried in the input Mary signal).
Figure 4
-0.00250402
-0.00245201
-0.00235037
...
Note: The full code, tap file and an OptiSystem project for this function
(Tutorial4SupplementaryFiles.zip) is available at the Optiwave C++ Component
Home Page. Replace the DS_SystemManager.cpp and DS_SystemManager.h
files in your project with the ones given in the zipfile. If you want to run in debug,
you must also change the location of the XML given in CppCoSimulation.cpp.
In addition change the location of the files in the OptiSystem projects to
We have created two functions in the class: ConvertToImpulses, which converts the
input M-ary signal to a sequence of electrical “impulses” (the first sample in each
symbol is the M-ary value). ApplyTapFunction, applies the impulse response to our
impulse sequence to shape the pulses.
45
TUTORIAL 4: ELECTRICAL PULSE SHAPER WITH M-ARY INPUT
Additionally we made sure this signal was in the time domain first before we defined
the amplitudes
CNDS_ElectricalSampledSignal electricalSampledSignal;
electricalSampledSignal.SetDomain(CNDS_ElectricalSampledSignal::domainTime);
ConvertToImpulses(electricalSampledSignal, vnMARYData1);
In ApplyTapFunction we use the relation that the FFT of the convolution is equal to
the product of the FFTs of the convolving function. The OptiSystem C++ project
provides built-in FFT and IFFT routines based on FFTW. The FFT function is invoked
as:
which performs a FFT on function to the resulting function_fft. Both of these must be
defined as CComplex pointers like:
finally, for normalization purposes, after the IFFT, we must divide the resulting function
by nNumberPointsInFunction.
End of Tutorial 4
46
TUTORIAL 4: ELECTRICAL PULSE SHAPER WITH M-ARY INPUT
47
TUTORIAL 4: ELECTRICAL PULSE SHAPER WITH M-ARY INPUT
48
TUTORIAL 5: BINARY CONTROLLED OPTICAL SWITCH.
Note: For this tutorial it is expected the user will copy the code provided in the
supplementary files. Here we only describe the key elements of this code.
In this tutorial we introduce the optical sampled signal class by creating a binary-
controlled optical switch. The optical signal is sent through an RC filter to simulate a
time delay in the switching. The component setup and the results of the project are
shown below
Figure 1
Figure 2
49
TUTORIAL 5: BINARY CONTROLLED OPTICAL SWITCH.
Where the top visualizer is the RC filtered value of the optical signal determined from
the binary input and the bottom visualizer RC filters the optical signal from the inverse
of the binary input
Optical signals
The optical signal classes are the most complex of all the signal classes. Those to be
accessed by the user are:
Sampled signals
CNDS_OpticalSampledSignal, header located in SignalLibrary/NDS_OpticalSampledSignal.h
Parameterized signals
CNDS_OpticalParameterizedSignal, header located in
SignalLibrary/NDS_OpticalParameterizedSignal.h
Noise bins
CNDS_OpticalNoiseBin, header located in SignalLibrary/NDS_OpticalNoiseBin.h
All other optical classes listed in this directory do not need to be accessed by the user
Domains
Similarly to the electrical signal, we can convert between the time and frequency
domain. The built in function SetDomain will apply the appropriate FFT/IFFT during
the conversion
enum enumPolarizationType
{
polarizationNone,
polarizationConstant,
polarizationArbitrary
};
50
TUTORIAL 5: BINARY CONTROLLED OPTICAL SWITCH.
COMPLEXVECTOR m_arrAmplitudeX;
COMPLEXVECTOR m_arrAmplitudeY;
The phase information is accounted for by the complex format of the amplitude. How
this is stored depends on the polarization format being used. The default format has
m_arrAmplitudeX storing the total amplitude, m_arrAmplitudeY is zero and
polarization information stored in the Stokes vector class:
CNDS_Polarization m_Polarization;
We can instead (and we will do this in the example) store the X and Y polarization
amplitudes separately on m_arrAmplitudeX and m_arrAmplitudeY respectively. The
conversion between the storage modes is obtained by the function:
SetPolarizationState(CNDS_OpticalSampledSignal::polarizationConstant);
SetPolarizationState(CNDS_OpticalSampledSignal::polarizationArbitrary);
Bandwidth
The bandwidth information is stored in the parent class (CNDS_SignalBase)
CNDS_SignalBandwidth m_Bandwidth;
which stores
double m_dLowerFrequency;
double m_dUpperFrequency;
The average between these two frequencies will be the optical signal's carrier
frequency and the difference is the bandwidth
51
TUTORIAL 5: BINARY CONTROLLED OPTICAL SWITCH.
Spatial information
In this tutorial, we only consider single mode signals, which do not contain any spatial
mode data. Accessing the transverse mode data is not needed in this tutorial and will
be discussed in Tutorial 6."
CNDS_OpticalTransverseMode m_ModeX;
CNDS_OpticalTransverseMode m_ModeY;
Note: The full code and an OptiSystem project for this function
(Tutorial5SupplementaryFiles.zip) is available at the Optiwave C++ Component
Home Page. Replace the DS_SystemManager.cpp and DS_SystemManager.h
files in your project with the ones given in the zipfile. If you want to run in debug,
you must also change the location of the XML given in CppCoSimulation.cpp.
In addition change the location of the files in the OptiSystem projects to your
particular files and directories.
Key points
1 - While CNDS_OpticalSampledSignal is the class of the optical sampled signal, it is
possible to have multiple signals on the same port. This happens because the input
signal can be the sum of multiple modulated optical signals on different carrier
frequencies and there can also be multiple transverse modes and polarizations. In
OptiSystem each different carrier frequency and transverse mode (and in some cases
polarization) will be described by a unique CNDS_OpticalSampledSignal. Therefore
when optical data is read in from the port, the function call used is
For example if we had on the input port a single polarization optical signal that was
modulated on two carrier frequencies and each frequency had two transverse modes,
vectorSignal1 would be of size 4 and would have elements:
In many cases there will only be one mode and therefore vectorSignal1[0] would be
the only element.
52
TUTORIAL 5: BINARY CONTROLLED OPTICAL SWITCH.
2 - To manipulate the amplitude data of the optical signal directly, we require that the
signals are in time domain format and the X and Y amplitudes carry each polarization
separately. Thus we call the functions
vectorSignal1[i].SetDomain(CNDS_OpticalSampledSignal::domainTime);
vectorSignal2[i].SetDomain(CNDS_OpticalSampledSignal::domainTime);
//First the domain of each input signal will be set to time domain using the function SetDomain()
vectorSignal1[i].SetPolarizationState(CNDS_OpticalSampledSignal::polarizationArbitrary);
vectorSignal2[i].SetPolarizationState(CNDS_OpticalSampledSignal::polarizationArbitrary);
//The polarization for optical signals can be represented in different ways, here we want separate arrays of X and Y f
3 - The amplitude information for the optical signal is protected so we must use the
accessors functions:
//For each sampled signal and polarization modify the amplitude depending on the binary value to emulate a switch.
for (int i = 0; i < vectorSignal1.size(); i++)
{
//Getting complex field data from current sampled signal
pEx1 = vectorSignal1[i].GetDataX();
pEy1 = vectorSignal1[i].GetDataY();
pEx2 = vectorSignal2[i].GetDataX();
pEy2 = vectorSignal2[i].GetDataY();
Note that the accessors are passing pointers so any manipulations we do on them will
modify the underlying m_arrAmplitudeX and m_arrAmplitudeY in the class.
4- The optical data is placed on the output port by the function
PutOpticalSampledSignalsVector(vectorSignal1, pOOSignal1);
PutOpticalSampledSignalsVector(vectorSignal2, pOOSignal2);
End of Tutorial 5
53
TUTORIAL 5: BINARY CONTROLLED OPTICAL SWITCH.
54
TUTORIAL 6: OPTICAL TRANSVERSE MODE CONVERTER
Note: For this tutorial it is expected the user will copy the code provided in the
supplementary files. Here we only describe the key elements of this code.
In this example we demonstrate how one can access and manipulate the transverse
mode information in the optical sampled signal. We build a transverse mode converter
where the input transverse field will be converted to a defined set of Laguerre-
Gaussian modes using a predefined overlap integral calculation class. Below we
show the case when the input mode is the [0 1] Hermite Gaussian mode. As the
figures show, for increasing number of Laguerre-Gaussian modes in the basis, the
input transverse field can be more accurately captured.
55
TUTORIAL 6: OPTICAL TRANSVERSE MODE CONVERTER
Figure 1 From top to bottom: LG (MaxL/MaxP: 2/1); LG (MaxL/MaxP: 3/3); LG (MaxL/MaxP: 6/6)
56
TUTORIAL 6: OPTICAL TRANSVERSE MODE CONVERTER
In this case we have added four parameters to the component. The Laguerre-
Gaussian mode basis will be all the modes in the range
[0...MaxLindex,0...MaxPindex]
Figure 2
Note: The full code and an OptiSystem project for this function
(Tutorial6SupplementaryFiles.zip) is available at the Optiwave C++ Component
Home Page. Replace the DS_SystemManager.cpp file in your project with the
ones given in the zipfile. If you want to run in debug, you must also change the
location of the XML given in CppCoSimulation.cpp. In addition change the
location of the files in the OptiSystem projects to your particular files and
directories.
Transverse modes
The transverse mode information is stored in the CNDS_OpticalTransverseMode
class. The data in this class is a matrix of complex elements CDS_ComplexMatrix
m_mAmplitude where the rows (x) and columns (y) represent the coordinates in the
transverse plane. The spatial representation of the basis of Laguerre-Gaussian
modes are put into the vector std::vector< CNDS_OpticalTransverseMode>
vecTranverseModes.
CNP_ChangeTransverseModes changeTransverseModes;
changeTransverseModes.Calculate(vectorSignal1, vecTranverseModes, vecTranverseModes);
This will rewrite the transverse modes of our input optical signal (vectorSignal1, which
were originally Hermite-Gaussian) into the new Laguerre-Gaussian basis given in
vecTranverseModes. Note that we have passed vecTranverseModes twice because
they represent the X and Y polarization transverse modes. In this case the two
polarizations have identical transverse modes. If you step into the
CNP_ChangeTransverseModes class, you will see that the conversion is
accomplished in a standard way using the overlap integrals between the initial
transverse mode and the new basis.
57
TUTORIAL 6: OPTICAL TRANSVERSE MODE CONVERTER
The new transverse modes are then attached to the optical signal
sampledSignalTemp.m_ModeX = vecNewTransverseModesX[j];
sampledSignalTemp.m_ModeY = vecNewTransverseModesY[j];
void gnuplot3DTopViewRealVector(DOUBLEVECTOR x, DOUBLEVECTOR y, DOUBLEVECTOR z, string title = "", string xlabel = "", string ylabel = "");
void gnuplot3DSurfaceRealVector(DOUBLEVECTOR x, DOUBLEVECTOR y, DOUBLEVECTOR z, string title = "", string xlabel = "", string ylabel = "");
In the first two functions you directly define the coordinates (x, y) and values (z) to be
plotted. For convenience, the second two functions have be written so you can plot
the transverse mode directly. The variable string type has types “abs”, “real”, “imag”
and “phase” for the part of the complex data you wish to plot. In the above code we
plot as an example
Figure 3
End of Tutorial 5
58
TUTORIAL 6: OPTICAL TRANSVERSE MODE CONVERTER
59
TUTORIAL 6: OPTICAL TRANSVERSE MODE CONVERTER
60
TUTORIAL 7: WORKING WITH OPTICAL PARAMETERIZED SIGNALS AND NOISE BINS
Note: For this tutorial it is expected the user will copy the code provided in the
supplementary files. Here we only describe the key elements of this code.
The optical parameterized signal is used for cases when it is not necessary to
consider sampled signals in a system (for example an average power analysis). This
class is much faster to calculate with than the full sampled signals. In addition, for
some optical devices, the bandwidth of the noise can be very large. Often too large
for the noise to be computationally practical using a sampled signal description. In this
case it is convenient to describe the noise in a parameterized way similar to the optical
parameterized signal
In both these cases, the power is stored in the CNDS_Polarization class:
Note: The full code and an OptiSystem project for this function
(Tutorial7SupplementaryFiles.zip) is available at the Optiwave C++ Component
Home Page. Replace the DS_SystemManager.cpp file in your project with the
ones given in the zipfile.
61
TUTORIAL 7: WORKING WITH OPTICAL PARAMETERIZED SIGNALS AND NOISE BINS
Figure 1
Note that they are both getting the signal from the same input port (pIOSignal1)
because all the various signal types are carried on the ports simultaneously
As with the sampled signals, the data is read in as vectors. Each vector element in
the parameterized signal corresponds to a different wavelength mode. However, they
cannot carry any transverse mode information.
For the noise bins, the vector has another significance. Each vector element of the
noise bin corresponds to a region of the frequency space, as shown below. In each
region, it is assumed that the noise has a constant power.
62
TUTORIAL 7: WORKING WITH OPTICAL PARAMETERIZED SIGNALS AND NOISE BINS
Figure 2
The size of this noise bin depends on the component that generated it. In this case
the “Spectral Light Source”. The parameter “Noise bins spacing” which sets this size
is shown below (note also the convert noise bins has been unchecked).
Figure 3
parameterizedSignal1[i].m_Polarization.SetPower(parameterizedSignal1[i].m_Polarization.GetPower() * 10);
// multiply parameterized signal power by factor of 10
63
TUTORIAL 7: WORKING WITH OPTICAL PARAMETERIZED SIGNALS AND NOISE BINS
The method for multiplying the noise power is similar to the parameterized signal. The
"Add" function in CNDS_OpticalSampledSignal is overloaded such that if a noise
bin is passed, it will be automatically converted to a sampled signal. The "if" statement
is used so that if this noise bin is within the bandwidth of the sampled signal, it will be
added, and then this noise-bin will be zeroed. If it is not within the sampled signal, it
is ignored
Output of signals
Both the newly created sampled signal and the remaining noise bins (those not added
to the sampled signal) are put on the output port.
PutOpticalSampledSignalsVector(sampledSignals1, pOOSignal1);
//put the new sampled signal on the output port
PutOpticalNoiseBinsVector(noiseBins1, pOOSignal1);
//put the remaining noise bins on the oputput port (the ones not within the bandwidth of the sampled signal
End of Tutorial 7
64
TUTORIAL 7: WORKING WITH OPTICAL PARAMETERIZED SIGNALS AND NOISE BINS
65
TUTORIAL 7: WORKING WITH OPTICAL PARAMETERIZED SIGNALS AND NOISE BINS
66
APPENDIX 1: OVERVIEW OF SIGNAL TYPES
This section describes how to access and set the properties of the OptiSystem signal
classes.
For all signal types, the input and output ports must first be created:
Binary signals
The binary signal holds two pieces of information: the binary sequence (stored as a
vector of longs) and the bit rate.
From the CDS_BinarySignal header file these are in the variables:
double m_dBitRate;
LONGVECTOR m_Bits;
and one can now access each element in the signal directly:
binarySignal1.m_Bits[i]
or directly:
PutBinarySignal(binarySignal1,pOOSignal1);
67
APPENDIX 1: OVERVIEW OF SIGNAL TYPES
M-ary signals
This signal type is similar to the binary except a vector of doubles is used to store the
sequence data instead of a vector of longs.
From the CDS_MarySignal header file these are in the variables:
double m_dSymbolRate;
DOUBLEVECTOR m_Symbols;
The M-ary signal holds two pieces of information: the M-ary sequence (stored as a
vector of doubles) and the symbol rate.
To access the vector of M-ary values use:
marySignal1.m_Symbols[i]
or directly,
PutMarySignal(marySignal1, pOOSignal1);
68
APPENDIX 1: OVERVIEW OF SIGNAL TYPES
Electrical signals
Electrical sampled signals
The basic class for the electrical sampled signals is
CNDS_ElectricalSampledSignal. Refer to
SignalLibrary/NDS_ElectricalSampledSignal.h for all the data and functions
available for this class. For example, the data stored in this class is:
// enum types
enum enumSignalDomain
{
domainTime,
domainFrequency
};
The complex amplitude data is stored in m_arrAmplitude. Note that the information
can be defined in the time or frequency domain. Initially, all information (from
OptiSystem in release mode or data files in debug mode) is read in the frequency
domain. To switch domains, use the commands:
electricalSampledSignal.SetDomain(CNDS_ElectricalSampledSignal::domainTime);
or,
electricalSampledSignal.SetDomain(CNDS_ElectricalSampledSignal::domainFrequency);
depending on your requirement. The SetDomain function will first check which
domain the signal is currently in. If it is already in the domain required, no further
action will be performed. If it is different, the appropriate FFT/IFFT will be applied on
m_arrAmplitude.
PutElectricalSampledSignal(electricalSampledSignal, pOOSignal1);
69
APPENDIX 1: OVERVIEW OF SIGNAL TYPES
PutElectricalSampledNoise(electricalSampledNoise, pOOSignal1);
CComplex m_ccAmplitude;
These signals are particularly useful for feedback applications where one needs to
analyze the signal one sample at a time.
PutElectricalIndividualSample(electricalIndividualSample, pOOSignal1);
70
APPENDIX 1: OVERVIEW OF SIGNAL TYPES
Optical signals
The optical ports can have multiple signals on them. This happens because the input
signal can be the sum of multiple modulated optical signals on different carrier
frequencies and there can also be multiple transverse modes and polarizations. In
OptiSystem each different carrier frequency and transverse mode (and in some cases
polarization) will be described by a unique signal. Therefore when optical data is read
in from the port, a vector of the signals is created. For the different types of optical
signals the following vectors have been defined:
Similarly to the electrical signal, we can convert between the time and frequency
domain. The built in function SetDomain will apply the appropriate FFT/IFFT during
the conversion.
Amplitudes and polarization
enum enumPolarizationType
{
polarizationNone,
polarizationConstant,
polarizationArbitrary
};
COMPLEXVECTOR m_arrAmplitudeX;
COMPLEXVECTOR m_arrAmplitudeY;
71
APPENDIX 1: OVERVIEW OF SIGNAL TYPES
The phase information is accounted for by the complex format of the amplitude. How
this is stored depends on the polarization format being used. The default format has
m_arrAmplitudeX storing the total amplitude, m_arrAmplitudeY being zero and
polarization information stored in the Stokes vector class
CNDS_Polarization m_Polarization;
// Stokes vector (not normalized)
double m_dS0;
double m_dS1;
double m_dS2;
double m_dS3;
SetPolarizationState(CNDS_OpticalSampledSignal::polarizationConstant);
SetPolarizationState(CNDS_OpticalSampledSignal::polarizationArbitrary);
Bandwidth
The bandwidth information is stored in the parent class (CNDS_SignalBase):
CNDS_SignalBandwidth m_Bandwidth;
which stores
double m_dLowerFrequency;
double m_dUpperFrequency;
The average between these two frequencies will be the optical signal's carrier
frequency and the difference is the bandwidth.
Spatial information
The transverse mode information is stored in:
CNDS_OpticalTransverseMode m_ModeX;
CNDS_OpticalTransverseMode m_ModeY;
72
APPENDIX 1: OVERVIEW OF SIGNAL TYPES
PutOpticalSampledSignalsVector(vectorSignal, pOOSignal1);
CComplex m_ccAmplitudeX;
CComplex m_ccAmplitudeY;
Which terms are non-zero depend on whether the polarization information is carried
in the Stokes parameters of in the amplitudes, similar to the optical sampled signal.
These signals are particularly useful for feedback applications where one needs to
analyze the signal one sample at a time. Also similar to the optical sampled signal,
the carrier bandwidth information is stored. However, these signals do not carry
transverse modes and so are only suitable for single mode operations.
PutOpticalIndividualSamplesVector(vectorIndividual, pOOSignal1);
73
APPENDIX 1: OVERVIEW OF SIGNAL TYPES
// common channels stores the power ratio and properties for each channel
// for extra functionality in specialized components. Not generally necessary.
CNDS_CommonChannelsData m_CommonChannels;
The user does not need to use m_CommonChannels. The power of the signal is
stored in m_Polarization:
double m_dLinewidth;
double m_dExtinctionRatio;
CNDS_SignalBandwidth m_Bandwidth
PutOpticalParameterizedSignalsVector(vectorParameterized, pOOSignal1);
74
APPENDIX 1: OVERVIEW OF SIGNAL TYPES
PutOpticalNoiseBinsVector(vectorNoiseBin, pOOSignal1);
75
APPENDIX 1: OVERVIEW OF SIGNAL TYPES
76
APPENDIX 2: DEBUGGING TIPS (RELEASE MODE)
In this section we present some built-in convenience functions for the user to debug
their programs when running their projects in release mode.
Gnuplot
One can create intermediate graphs in the C++ component with predefined
convenience functions if gnuplot is installed (please go to:
http://sourceforge.net/projects/gnuplot/files/gnuplot/ for the latest build). The
predefined function prototypes can be seen in DS_SystemManager.h.
//////////////////////////////////////////////////////////////////////////////////////////
//Convenience plotting functions using gnuplot
//In order for these to work, you must have gnuplot for windows installed on your computer
//////////////////////////////////////////////////////////////////////////////////////////
void gnuplot2D(DOUBLEVECTOR x, DOUBLEVECTOR y, string title = "", string legend = "", string xlabel = "", string ylabel = "");
void gnuplot2D(DOUBLEVECTOR x1, DOUBLEVECTOR y1, DOUBLEVECTOR x2, DOUBLEVECTOR y2, string title = "", string legend1 = "", string legend2 =
"", string xlabel = "", string ylabel = "");
void gnuplot3DTopViewRealVector(DOUBLEVECTOR x, DOUBLEVECTOR y, DOUBLEVECTOR z, string title = "", string xlabel = "", string ylabel = "");
void gnuplot3DSurfaceRealVector(DOUBLEVECTOR x, DOUBLEVECTOR y, DOUBLEVECTOR z, string title = "", string xlabel = "", string ylabel = "");
void gnuplot3DTopViewTransverseMode(CNDS_OpticalTransverseMode mode, string type = "abs", string title = "");
void gnuplot3DSurfaceTransverseMode(CNDS_OpticalTransverseMode mode, string type = "abs", string title = "");
Examples were provided in tutorials 2, 3, 4 and 6 while running in debug mode. These
can also be run in release mode however the user must ensure the working directory
is writable because the gnuplot functions create temporary files (for example)
If the user cannot write to the working directory, they should explicitly set the path for
the files for "fileName" and "scriptName".
77
APPENDIX 2: DEBUGGING TIPS (RELEASE MODE)
Information boxes
If the user wants a popup window to display a piece of information during the run, they
can use code like the example below:
The component will pause at this point until the user dismisses the popup window.
Console output
The class "Console" has been added so that the user can display information in a
console during execution of their component. For example the code below:
The class "Console" has been added so that the user can display information in a
console during execution of their component. For the code:
78
APPENDIX 2: DEBUGGING TIPS (RELEASE MODE)
will produce the console output as above, then after execution, will copy the contents
of the buffer onto Windows Notepad as follows:
79
APPENDIX 2: DEBUGGING TIPS (RELEASE MODE)
80
Optiwave
7 Capella Court
Ottawa, Ontario, K2E 7X1, Canada
Tel.: 1.613.224.4700
Fax: 1.613.224.4706
E-mail: [email protected]
URL: www.optiwave.com