#ABSTRACT: XPRESS for DUMMIES - Example 2 - Nested Sweeps
#PODNAME: Lab::XPRESS::Examples::Example2_Gate_IV_scan

__END__

=pod

=encoding utf-8

=head1 NAME

Lab::XPRESS::Examples::Example2_Gate_IV_scan - XPRESS for DUMMIES - Example 2 - Nested Sweeps (deprecated)

=head1 VERSION

version 3.899

=head1 Abstract

This file belongs to a deprecated legacy module stack, frozen and not under development anymore. Please port your code to the new API;
its documentation can be found on the Lab::Measurement homepage, L<https://www.labmeasurement.de/>.

This is a simple, but fully functional Lab::Measurment script, which makes use
of the XPRESS add-on.
Its purpose as a measurement script is to record a set of IV-curves at a series
of gate voltages. 
However it is also a tutorial, that introduces the XPRESS nested Sweeps
feature. 
Beginners should read Example1 first.

=head1 Introduction 

Example 1 presented a step by step tutorial in writing simple
Lab::Measurement/XPRESS script.  
In this example we show, how to extend this script, in order to get a set of
IV-curves at a series of gate voltages. 
XPRESS offers a nice feature to implement those extensions in a very simple and
mostly already familiar way. 
In the following, we will focus the new parts of our script and discuss it's
meaning. 

 #-------- 0. Import Lab::Measurement -------
 
 use Lab::Measurement::Legacy;
 
 #-------- 1. Initialize Instruments --------
 
 my $bias = Instrument(
     'Yokogawa7651',
     {
         connection_type => 'VISA_GPIB',
         gpib_address    => 3,
         gate_protect    => 0
     }
 );
 
 my $multimeter = Instrument(
     'Agilent34410A',
     {
         connection_type => 'VISA_GPIB',
         gpib_address    => 17,
         nplc =>
             10    # integration time in number of powerline cylces [10*(1/50)]
     }
 );
 
 my $gate = Instrument(
     'Yokogawa7651',
     {
         connection_type => 'VISA_GPIB',
         gpib_address    => 6,
 
         gate_protect            => 1,
         gp_min_units            => -10,
         gp_max_units            => 15,
         gp_max_units_per_second => 10e-3
     }
 );
 
 #-------- 2. Define the Sweeps -------------
 my $gate_sweep = Sweep(
     'Voltage',
     {
         mode       => 'step',
         instrument => $gate,
         points     => [ -5, 5 ],    # [starting point, target] in Volts
         stepwidth  => [0.1],
         rate       => [5e-3]
         , # [rate to approach start, sweeping rate for measurement] in Volts/s
     }
 );
 
 my $bias_sweep = Sweep(
     'Voltage',
     {
         instrument => $bias,
         points     => [ -5e-3, 5e-3 ],    # [starting point, target] in Volts
         rate       => [ 0.1, 0.5e-3 ]
         , # [rate to approach start, sweeping rate for measurement] in Volts/s
         interval => 1,    # measurement interval in s
 
         delay_before_loop => 10    # delay before Sweep begins in s
     }
 );
 
 #-------- 3. Create a DataFile -------------
 
 my $DataFile = DataFile('Gate_IV_sample1.dat');
 
 $DataFile->add_column('GateVoltage');
 $DataFile->add_column('BiasVoltage');
 $DataFile->add_column('Current');
 $DataFile->add_column('Resistance');
 
 $DataFile->add_plot(
     {
         'type'    => 'pm3d',
         'x-axis'  => 'GateVoltage',
         'y-axis'  => 'BiasVoltage',
         'cb-axis' => 'Current'
     }
 );
 
 #-------- 4. Measurement Instructions -------
 
 my $my_measurement = sub {
 
     my $sweep = shift;
 
     my $gate_voltage = $gate->get_value();
     my $bias_voltage = $bias->get_value();
     my $current      = $multimeter->get_value() * 1e-7;
     my $resistance   = ( $current != 0 ) ? $voltage / $current : '?';
 
     $sweep->LOG(
         {
             GateVoltage => $gate_voltage,
             Voltage     => $bias_voltage,
             Current     => $current,
             Resistance  => $resistance
         }
     );
 };
 
 #-------- 5. Put everything together -------
 
 $DataFile->add_measurement($my_measurement);
 
 $voltage_sweep->add_DataFile($DataFile);
 
 my $frame = Frame();
 $frame->add_master($gate_sweep);
 $frame->add_slave($bias_sweep);
 
 $frame->start();
 
 1;

=head1 The code

=head2 Instrument initialization

	#-------- 0. Import Lab::Measurement -------

	use Lab::Measurement;

	#-------- 1. Initialize Instruments --------

	my $bias = Instrument('Yokogawa7651', 
		{
		connection_type => 'VISA_GPIB',
		gpib_address => 3,
		gate_protect => 0
		});

	my $multimeter = Instrument('Agilent34410A', 
		{
		connection_type => 'VISA_GPIB',
		gpib_address => 17,
		nplc => 10					# integration time in number of powerline cylces [10*(1/50)]
		});

	my $gate = Instrument('Yokogawa7651', 
		{
		connection_type => 'VISA_GPIB',
		gpib_address => 6,

		gate_protect => 1,
		gp_min_units => -10,
		gp_max_units => 15,
		gp_max_units_per_second => 10e-3
		});

In this first part of this script, we are doing more or less the same as in Example 1. Import the Lab::Measurement library, 
then initialize the instruments we need. Now what's new is, that we initialize here a third instrument,
the gate, which is again a Yokogawa7651. No big deal, so far. New is, that we are using the gate protection mode this time.
It's turned on by C<<gate_protect => 1>>. With C<<gp_min_units => -10>> and C<<gp_max_units => 15>> we define the lower and upper limits, which we do not
want to be exceeded by the source instrument. So if the Yokogawa is in voltage sourcing mode (which we expect to be for now), 
the output Voltage will be limited to values between -10V and 15V. If it would be in current mode, it would not be limited at all, because 15A might be a little bit to much for this device :)
With C<<gp_max_units_per_second => 10e-3>> we define the highest possible sweep rate, so it will sweep no faster than 10mV per second. 

=head2 Sweep Objects

	#-------- 2. Define the Sweeps -------------
	my $gate_sweep = Sweep('Voltage', 
		{
		mode => 'step',
		instrument => $gate,
		points => [-5, 5],	# [starting point, target] in Volts
		stepwidth => [0.1],
		rate => [5e-3],			# [rate to approach start, sweeping rate for measurement] in Volts/s
		});

	my $bias_sweep = Sweep('Voltage', 
		{
		instrument => $bias,
		points => [-5e-3, 5e-3],	# [starting point, target] in Volts
		rate => [0.1, 0.5e-3],		# [rate to approach start, sweeping rate for measurement] in Volts/s
		interval => 1, 				# measurement interval in s

		delay_before_loop => 10 	# delay before Sweep begins in s
		});

In this experiment, we want to measure the current through our sample, depending on two parameters: the source-drain voltage and the gate voltage.
Of course, that means we need instead of only one sweep, now two sweeps. And as you see, we created a second sweep, which we called $gate_sweep.
Unlike $source_sweep, this one is in mode 'step'. This means, that instead of sweeping and measuring simultaniously, the instrument will sweep, stop, make a new 
data value, sweep to the next step ... and so on. And in our case it will be: go to the next step, make an IV-curve and so on. Therefore we have to define the parameter stepwidth,
while the rates parameter defines the rate, which is used to approach the steps.

=head2 The DataFile

	#-------- 3. Create a DataFile -------------

	my $DataFile = DataFile('Gate_IV_sample1.dat');

	$DataFile->add_column('GateVoltage');
	$DataFile->add_column('BiasVoltage');
	$DataFile->add_column('Current');
	$DataFile->add_column('Resistance');


	$DataFile->add_plot({
		'type'	  => 'pm3d'

		'x-axis'  => 'GateVoltage',
		'y-axis'  => 'BiasVoltage',
		'cb-axis' => 'Current'
		});

Almost nothing new here, besides: plot-type is now pm3d. This creates a color coded 2D plot. Therefore we have to specify a third axis, the cb-axis, which defines the values, which will be presented color-coded
in the plot later on.

=head2 4. The measurement instructions

#-------- 4. Measurement Instructions -------

	my $my_measurement = sub {

		my $sweep = shift;

		my $gate_voltage = $gate->get_value();
		my $bias_voltage = $bias->get_value();
		my $current = $multimeter->get_value()*1e-7;
		my $resistance = ($current != 0) ? $voltage/$current : '?';

		$sweep->LOG({
			GateVoltage => $gate_voltage,
			Voltage => $bias_voltage,
			Current => $current,
			Resistance => $resistance
			});
	};

Again, almost nothing new here. But its getting really interesting in the next paragraph, so stay with us!

=head2 5. Putting everything in place

Ok now we are finally, at the heart of this lesson! That's where most of the logic takes place, so we will do it step by step.

	#-------- 5. Put everything together -------

	$DataFile->add_measurement($my_measurement);

	$voltage_sweep->add_DataFile($DataFile);

We still remember the first two lines. But why is the DataFile only connected to the voltage sweep, and not to the gate sweep? 
Thats because the voltage sweep is the one, during which the actual measurements take place. 
But to define which sweep acts first, and which one is controlled by the other one, we introduce a new object. The Frame:

	my $frame = Frame();

You can assign masters and slaves in a frame, just like this:

	$frame->add_master($gate_sweep);
	$frame->add_slave($bias_sweep);

The master, has to be a sweep-object, which is in mode 'step' or 'list', here $gate_sweep. Each frame can have only one master.
For the slave, you have more freedom. You can put as many slaves as you want into the frame, just by calling add_slave multiple times.
It's possible to assign sweep objects of any type as a slave. It's even possible to put your own individual, handwritten code, into the frame as a slave, which will be called
each time the master makes a new step. We will show you how to do this in one of the next examples. And you can use another frame as a slave.
This way, one can reach an unlimited degree of nesting sweeps, and create experiments, that last years!

Last but not least, as always, you have to start the whole thing. But this time we start the frame instead of one particular sweep:

	$frame->start();

Otherwise the script won't do anything. 
And that's it!

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2021 by the Lab::Measurement team; in detail:

  Copyright 2017       Simon Reinhardt
            2018       Andreas K. Huettel, Simon Reinhardt


This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
