#-------- 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
	});

#-------- 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;

=pod

=encoding utf-8

=head1 Name

Example 2 - Nested Sweeps

=head1 Abstract

	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.

.

=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!


=cut