Software … powerful tools for your research & development!

Making Plots With a Variation of Operation or System Parameters

Dr. Rüdiger Paschotta

The powerful script language, which is supported by most of our software products, allows our users to generate all sorts of plots – not just some predefined ones. Here, I would like to give some useful hints for beginners, which could also be of interest for those considering to start with our software. You will see that a lot can be achieved quite easily with a few lines of script code. I hope you will have fun!

The given examples will all refer to our RP Fiber Power software; very similar things are possible in our resonator design software RP Resonator, for example, or in the coating design software RP Coating.

Simple Plots not Affecting a System

Let us begin with simpler kinds of plots, where the operation and system parameters are not changed. As an example, consider a fiber amplifier model with our software RP Fiber Power where we want to plot the distribution of pump and signal power within the fiber for a certain amplifier configuration and some set of input powers and wavelengths. For that purpose, we can use a command like the following:

f: P(signal, x) / mW,
   color = blue, width = 3, "signal power"

Generally, the “f:” command can be used to generate a plot based on a mathematical expression which depends on the variable <$x$>. For some number of <$x$> values within the range of the horizontal coordinate axis, that expression is evaluated, and the results are used as <$y$> coordinates of the plotted curve. For obtaining the <$y$> value, I have divided the obtained power by mW (a predefined constant, the value of which is 0.001), assuming that the vertical axis values are understood as milliwatts. In our example, three additional options have been used, which modify the color and width of the curve and produce a text label, helping the user to distinguish different curves.

In our example case, we used the predefined function P(), having two arguments: the used “optical channel” and the position in the fiber, where 0 refers to the left end. In the software documentation, one can find numerous other functions with which one can access various calculated quantities. In many cases, the required calculation is triggered by the function call; in other cases, the calculations have already been done, and the function only retrieves their results.

Changing an Operation Parameter in a Plot

It is quite common that one makes plots where a certain operation parameter is varied along the <$x$> axis. For example, we might want to plot the signal output power as a function of the applied pump power. In such a case, three different things have to be done for each <$x$> value:

  • A system parameter (in our case, the pump power) has to be set according to the <$x$> value.
  • The state of the system has to be recalculated.
  • A certain output value (here: the signal output power) has to be retrieved and used as the <$y$> coordinate.

In RP Fiber Power, we can achieve all that (and make the coordinate system) with the following commands:

x: 0, 500
"pump power (mW)", @x
y: 0, 300
"signal power (mW)", @y

f: (set_P_in(pump, x * mW); P_out(signal)) / mW,
   color = blue, width = 3

For performing the above-mentioned tasks, a so-called composite expression is used with the “f:” command; it consists of two expressions separated by a semicolon and enclosed in parentheses. (Instead of the parentheses, one could use “begin” and “end”.) Some details:

  • The first used function call modifies the input power of a certain optical channel (here: the pump channel). The multiplication with mW converts the coordinate value into a power in fundamental units (watts).
  • The second function retrieves the output power for a certain channel. When that is called, the system state is automatically recalculated, as the software has recognized that the system state has become invalid due to the modification of an input power.

The result of the composite expression is the result of the last expression, i.e., the signal output power.

There are numerous other functions for modifying other operation parameters. For example, one could modify the signal wavelength:

f: (set_lambda(signal, x * nm); P_out(signal)) / mW,
   color = blue, width = 3, "signal power"

Changing a System Parameter

We can use essentially the same techniques as above to obtain plots where certain system parameters are changed. For example, we might change the length of the active fiber used in a fiber amplifier. The plot may then be generated with the following code:

f: (set_L(x); P_out(signal)) / mW,
   color = blue, width = 3, "signal power"

Restoring Values After a Plot

If we do nothing more than shown above, we might encounter a problem: when the plot is finished, the varied operation or system parameter of the last point in the plot – corresponding to the highest <$x$> value – remains valid. This may affect further plots, for example as parts of further diagrams. Therefore, it is often desirable to restore the original state when a plot is finished.

In the previous example case, let us assume that the fiber length was originally defined by the variable L. This means that after the plot we want to set the fiber length to that value again. The most clear and convenient way is to use the “finish” option of the “f:” command:

f: (set_L(x); P_out(signal)) / mW,
   color = blue, width = 3, "signal power",
   finish set_L(L)

One might think that instead one could work with the following, where the length is restored with a separate command:

f: (set_L(x); P_out(signal)) / mW,
   color = blue, width = 3, "signal power"
call set_L(L)

That would fail, however, for a subtle reason: diagrams and contained plots etc. are not immediately generated when the corresponding commands are read, but only later on after successful reading of the whole script. (The reasoning behind that is that you do not want to wait for possibly time-consuming plot only in order to learn thereafter that a syntax error further down in the script should have been corrected first.) For that reason, the following would happen:

  • The details for the plot (as defined with the “f:”) command are stored for later use.
  • The fiber length is set.
  • Later on, the plot is made – after rather than before setting the fiber length!

That problem can be avoided by using the “!” command (instead of “calc”), which stores an expression for later evaluation when the plot is made:

f: (set_L(x); P_out(signal)) / mW,
   color = blue, width = 3, "signal power"
! set_L(L)

The better solution, however, is using the “finish” option as shown above because then the restoration action becomes part of the plotting command. This makes it less likely that you will erroneously copy the plotting command for use somewhere else in the script while forgetting that the restoration action should also be copied.

By the way, there is also the “init” option which calls an expression before making the plot.

Making Multiple Plots with a Single Command

It is often convenient to produce multiple plots with a single command, where a certain parameter is different for each plot. For example, you may want to plot the signal output power of a fiber amplifier as a function of the signal wavelength, and this for different values of the pump power. This could be done with the following code:

f: (set_lambda(signal, x * nm); P_out(signal)) / mW,
   color = blue, width = 3,
   init set_P_in(pump, P),
   for P := 100 mW to 500 mW step 50 mW,
   finish set_P_in(pump, P_p_in)
! set_lambda(signal, lambda_s)

Here, I have done the restoration of the original signal wavelength with a separate “!” , so that it is done only once after the whole plotting rather than after each single plot (which would actually also not have caused a problem).

Cases Where the x Coordinate is Not an Input Value

In all the discussed example cases, the <$x$> values were input values. In some cases, however, you want to use some calculated values as <$x$> values. For example, you may want to plot the signal output power of the fiber amplifier is a function of the absorbed pump power rather than the injected pump power.

The problem is that there is no predefined function telling the system something like “put in as much pump power as needed to get a certain amount of pump power absorbed”. It is actually possible to define such a function, but there is a much simpler way to solve our problem: using a parametric plot. Here, some input parameter (the injected pump power) runs through a certain range, and we get both the <$x$> and <$y$> values calculated from that parameter:

k: P_in := 0 to 800 mW step 1 mW,
   { x = } (set_P_in(pump, P_in); (P_in - P_out(pump)) / mW),
   { y = } P_out(signal) / mW,
   color = blue, width = 3,
   finish set_P_in(pump, P_p_in)

The “k:” command for parametric plots obtains

  • a variable and a range of values it must run through,
  • an expression for calculating the <$x$> coordinate value,
  • an expression for calculating the <$y$> coordinate value, and
  • additional options as needed.

In our example, the <$x$> value is the injected pump power minus the residual pump power at the fiber end – this is the absorbed pump power. (If the fiber has parasitic losses, the power absorbed by those is included.)

Keeping Certain Values Constant

In some cases, you want to automatically have some operation parameter adjusted such that a certain condition is maintained. For example, you may want to have as much as pump power as required for obtaining a certain signal output power.

SetPumpFor(P_s_out) := 
  zero((set_P_in(pump, P_p_in); P_out(signal) - P_s_out),
       P_p_in in [0, 1], xtol = 1 uW);

P_s_out_w := 10 mW
show "P_p_in: ",
   P_p_in := SetPumpFor(P_s_out_w):d3:"W"

You see that I have defined a function which adjusts the pump power such that the obtained signal output power minus the wanted signal output power is zero. The “zero” function is a very convenient and efficient tool for numerical root finding. As its result, it delivers the value required for achieving the set goal.

Once you have a function like SetPumpFor(), you can also use it in a plot:

f: (set_P_in(signal, x * mW);
   step = 30, color = red, width = 3, "residual pump power",
   finish set_P_in(signal, P_signal_in)

Here, the signal input power is very along the <$x$> axis. For each value, the pump power is calculated such that the required signal output power is achieved. What is plotted is the residual pump power, i.e., the output power of the pump channel.

Final Remarks

You have seen that it is not too difficult to generate all sorts of plots with a bit of script code. Initially, you may find it a little tricky to get this code developed. However, there are various ways to get the required solution:

  • The script language is well documented in the manual and the online help system. Admittedly, it may take you too much time to construct a solution that way.
  • Our software is delivered with plenty of demo files, where such techniques are applied. Often, just by reading that code you will understand straightaway how it works. Then you can copy pieces of code from there and adapt them to your needs.
  • In RP Fiber Power, you can start using the interactive forms rather than writing script code. When you execute the calculations, the software will generate a script based on your form inputs. You can take that script as a starting point for further refinements. So you get most of your script written automatically and only at some specialties.
  • Of course, you can make use of the technical support. Tell me what you want to plot, and I will insert the required code into the script which you sent me, or send you some isolated snippets of code which you can paste into your script.

Also be aware that such a script language gives you an enormous flexibility. With it, you can do even a lot of things which I (the software developer) never had in mind. Therefore, it is absolutely worthwhile to spend a little time for learning how that works.

See also the article of 2015-10-31, which discusses our expression engine in more detail. Also, the article of 2013-10-02 gives you some internal insight; it tells you how expression are stored and handled internally, if you are curious how such things work.

This article is a posting of the RP Photonics Software News, authored by Dr. Rüdiger Paschotta. You may link to this page, because its location is permanent.

Note that you can also receive the articles in the form of a newsletter or with an RSS feed.

Questions and Comments from Users

Here you can submit questions and comments. As far as they get accepted by the author, they will appear above this paragraph together with the author’s answer. The author will decide on acceptance based on certain criteria. Essentially, the issue must be of sufficiently broad interest.

Please do not enter personal data here; we would otherwise delete it soon. (See also our privacy declaration.) If you wish to receive personal feedback or consultancy from the author, please contact him, e.g. via e-mail.

Spam check:

By submitting the information, you give your consent to the potential publication of your inputs on our website according to our rules. (If you later retract your consent, we will delete those inputs.) As your inputs are first reviewed by the author, they may be published with some delay.


Connect and share this with your network:

Follow our specific LinkedIn pages for more insights and updates: