diff --git a/vfa_t1/CartesianReadout3D.spv b/vfa_t1/CartesianReadout3D.spv
new file mode 100644
index 0000000..ab0ac6f
--- /dev/null
+++ b/vfa_t1/CartesianReadout3D.spv
@@ -0,0 +1,541 @@
+
+
+
+
+ VariablePlugins
+
+
+ axisSBKey.keyPath
+ frequency
+ center
+ 0.0
+ editableName
+ Frequency (Hz)
+ orderedIndex
+ 0
+ pluginClass
+ SBVariableAxis
+ pluginName
+ Variable Axis
+ pluginVersion
+ 1
+ range
+ 400
+ res
+ 65
+ selectionStart
+ 0.0
+
+
+ editableName
+ Minimize TR
+ enabled
+ 1
+ pluginClass
+ SBMinimizeTRPlugin
+ pluginName
+ Minimize TR
+ pluginURL
+ http://www.SpinBench.com/
+ pluginVersion
+ 1
+
+
+ Waveforms
+
+ PulsePlugins
+
+
+ anchor
+
+ activeAnchor
+ start
+ anchorType
+ 1
+ anchoredToSBKey
+ startOfTR
+ position
+ 0.0
+
+ editableName
+ Cartesian Readout
+ fov
+ 24
+ hasPhaseEncoding
+ 1
+ hasRewinder
+ 1
+ kxCoverage
+ 1
+ kyCoverage
+ 1
+ netArea
+ 0.0
+ pluginClass
+ SBCartesianReadout
+ pluginName
+ Cartesian Readout
+ pluginVersion
+ 1
+ samplingRate
+ 250
+ x0Component
+ 1
+ x1Component
+ 0.0
+ xPostReadoutOverlap
+ 1
+ xPreReadoutOverlap
+ 1
+ xReadoutOverlap
+ 0.0
+ xRes
+ 256
+ y0Component
+ 0.0
+ y1Component
+ 0.0
+ yPostReadoutOverlap
+ 1
+ yPreReadoutOverlap
+ 1
+ yReadoutOverlap
+ 0.0
+ yRes
+ 256
+ z0Component
+ 0.0
+ z1Component
+ 1
+ zPostReadoutOverlap
+ 1
+ zPreReadoutOverlap
+ 1
+ zReadoutOverlap
+ 0.0
+
+
+ anchor
+
+ activeAnchor
+ end
+ anchorType
+ 1
+ anchoredToSBKey
+ <Cartesian Readout>.readoutStart
+ position
+ 1.0399999618530273
+
+ editableName
+ Phase Encode Gradient
+ fov
+ 24
+ pluginClass
+ SBPhaseEncodeGradient
+ pluginName
+ Phase Encode Gradient
+ pluginVersion
+ 1
+ res
+ 5
+ x0Component
+ 0.0
+ xDurationOverlap
+ 1
+ y0Component
+ 1
+ yDurationOverlap
+ 1
+ z0Component
+ 0.0
+ zDurationOverlap
+ 1
+
+
+ anchor
+
+ activeAnchor
+ start
+ anchorType
+ 1
+ anchoredToSBKey
+ <Cartesian Readout>.readoutEnd
+ position
+ 2.0639998912811279
+
+ editableName
+ Phase Encode Gradient 1
+ fov
+ 24
+ pluginClass
+ SBPhaseEncodeGradient
+ pluginName
+ Phase Encode Gradient
+ pluginVersion
+ 1
+ res
+ 5
+ x0Component
+ 0.0
+ xDurationOverlap
+ 1
+ y0Component
+ -1
+ yDurationOverlap
+ 1
+ z0Component
+ 0.0
+ zDurationOverlap
+ 1
+
+
+ SequencePlugins
+
+
+ editableName
+ Repeat
+ pluginClass
+ SBRepeatPlugin
+ pluginName
+ Repeat
+ pluginVersion
+ 1
+ repetitions
+ 256
+
+
+ editableName
+ Draw Pulses
+ maskType
+ 0
+ pluginClass
+ SBDrawPulsesPlugin
+ pluginName
+ Draw Pulses
+ pluginNames
+
+ Phase Encode Gradient
+ Phase Encode Gradient 1
+
+ pluginVersion
+ 1
+
+
+ duration
+ 1.5440000295639038
+ editableName
+ New TR
+ pluginClass
+ SBNewTRPlugin
+ pluginName
+ New TR
+ pluginVersion
+ 1
+ useGlobal
+ 1
+
+
+ editableName
+ Repeat 1
+ pluginClass
+ SBRepeatPlugin
+ pluginName
+ Repeat
+ pluginVersion
+ 1
+ repetitions
+ 5
+
+
+ editableName
+ Draw Pulses 1
+ maskType
+ 1
+ pluginClass
+ SBDrawPulsesPlugin
+ pluginName
+ Draw Pulses
+ pluginNames
+
+ Phase Encode Gradient
+ Phase Encode Gradient 1
+
+ pluginVersion
+ 1
+
+
+ editableName
+ Overlay Combinations
+ numInputs
+ 2
+ pluginClass
+ SBOverlayAllCombinationsPlugin
+ pluginName
+ Overlay Combinations
+ pluginVersion
+ 1
+
+
+ numGradAxes
+ 3
+ numOtherAxes
+ 0
+
+ absoluteTime
+ 798.7198486328125
+ activeInspector
+ 4
+ appVersion
+ 2.5.1
+ beginAtSS
+ 0
+ chronaxie
+ 0.35999999999999999
+ dFrequency
+ 0.0
+ editingMode
+ 0
+ fieldStrength
+ 3
+ freelyRotatable
+ 1
+ frequency
+ 0.0
+ gamma
+ 4258
+ gradCoilHeatingGain
+ 63
+ gradLimit
+ 4
+ gradLimitXScale
+ 1
+ gradLimitYScale
+ 1
+ gradLimitZScale
+ 1
+ inspectorWidth
+ 310
+ magnification
+ 5.3433389663696289
+ mainWindowFrame
+
+ height
+ 674
+ width
+ 1162
+ x
+ 66
+ y
+ 82
+
+ maxReadoutRate
+ 500
+ nominalGradLimitScale
+ 1
+ numRfRxChannels
+ 4
+ numRfTxChannels
+ 1
+ outputPlugins
+
+
+ displayStyle
+ Magnitude / Phase
+ editableName
+ Profile
+ magnification
+ 1
+ pluginClass
+ SBProfileViewPlugin
+ pluginName
+ Profile
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ showYValues
+ 0
+ viewBottom
+ 342
+ viewHeight
+ 253
+ viewLeft
+ 25
+ viewWidth
+ 292
+
+
+ editableName
+ Waveforms
+ gradDisplayStyle
+ XYZ Separate Plots
+ pluginClass
+ SBWaveformViewPlugin
+ pluginName
+ Waveforms
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ rfDisplayStyle
+ XY Combined Plot
+ showReadoutWindows
+ 0
+ showValues
+ 0
+ viewBottom
+ 118
+ viewHeight
+ 214
+ viewLeft
+ 25
+ viewWidth
+ 292
+
+
+ editableName
+ Time Controller
+ pluginClass
+ SBTimeControlPlugin
+ pluginName
+ Time Controller
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ viewBottom
+ 70
+ viewHeight
+ 48
+ viewLeft
+ 1
+ viewWidth
+ 340
+
+
+ editableName
+ View Scaling Controller
+ pluginClass
+ SBViewScalingPlugin
+ pluginName
+ View Scaling Controller
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ viewBottom
+ 447
+ viewHeight
+ 153
+ viewLeft
+ 0.0
+ viewWidth
+ 23
+
+
+ editableName
+ Sequencing View
+ pluginClass
+ SBSequencingViewPlugin
+ pluginName
+ Sequencing View
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ viewBottom
+ 375.5
+ viewHeight
+ 234.5
+ viewLeft
+ 349.16015625
+ viewWidth
+ 426.06640625
+
+
+ editableName
+ k-Space Trajectory
+ magnification
+ 1
+ pluginClass
+ SBTrajectoryViewPlugin
+ pluginName
+ k-Space Trajectory
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ showAllTrs
+ 1
+ showReadoutKSpace
+ 1
+ showValues
+ 1
+ viewBottom
+ 36.5
+ viewHeight
+ 328
+ viewLeft
+ 367.01953125
+ viewWidth
+ 337.21875
+ xWaveform
+ kx
+ yWaveform
+ ky
+
+
+ protonDensity
+ 1
+ readoutSampleDivisor
+ 2
+ receiverPhase
+ 0.0
+ rfLimit
+ 0.10000000000000001
+ slewMagLimitXScale
+ 0.0
+ slewMagLimitYScale
+ 0.0
+ slewMagLimitZScale
+ 0.0
+ slewRateLimit
+ 15
+ slewRateLimitXScale
+ 1
+ slewRateLimitXSlope
+ 0.0
+ slewRateLimitYScale
+ 1
+ slewRateLimitYSlope
+ 0.0
+ slewRateLimitZScale
+ 1
+ slewRateLimitZSlope
+ 0.0
+ t1
+ 800
+ t2
+ 150
+ timeWithinTr
+ 3.1198486328124999
+ tr
+ 3.1040000915527344
+ trNum
+ 255
+ waveSamplingRate
+ 50
+ xPosition
+ 0.0
+ xVelocity
+ 0.0
+ yPosition
+ 0.0
+ yVelocity
+ 0.0
+ zPosition
+ 0.0
+ zVelocity
+ 0.0
+
+
diff --git a/vfa_t1/README.md b/vfa_t1/README.md
index e69de29..8494e17 100644
--- a/vfa_t1/README.md
+++ b/vfa_t1/README.md
@@ -0,0 +1,32 @@
+## Intro
+
+The variable flip angle (VFA) implementation of [qMRLab](https://qmrlab.org) takes following as input:
+* Data
+ * `VFAData`: [vol X N] image data where N is # of FAs.
+ * `B1map`: [vol] b1 transmit field map
+ * `Mask`: [vol] binary ROI mask
+* Parameters
+ * `FA`: [1 X N] array
+ * `TR`: [1 X N] array
+
+For details you can see the interactive [`vfa_t1`](https://qmrlab.readthedocs.io/en/master/vfa_t1_batch.html) tutorial [executable online](https://qmrlab.org/jekyll/2018/12/11/T1-mapping-variable-flip-angle.html).
+
+For creating B1map, double angle method is also available in qMRLab: [`b1_dam`](https://qmrlab.readthedocs.io/en/master/b1_dam_batch.html).
+
+***
+
+## Pulse sequence implementation
+
+### Sequence components
+
+### Scan control
+
+### Reconstruction
+
+
+***
+
+
+
+
+
diff --git a/vfa_t1/SlabSelect.spv b/vfa_t1/SlabSelect.spv
new file mode 100644
index 0000000..a315f04
--- /dev/null
+++ b/vfa_t1/SlabSelect.spv
@@ -0,0 +1,376 @@
+
+
+
+
+ VariablePlugins
+
+
+ axisSBKey.keyPath
+ yPosition
+ center
+ 0.0
+ editableName
+ YPosition (mm)
+ orderedIndex
+ 0
+ pluginClass
+ SBVariableAxis
+ pluginName
+ Variable Axis
+ pluginVersion
+ 1
+ range
+ 60
+ res
+ 65
+ selectionStart
+ 0.0
+
+
+ editableName
+ Minimize TR
+ enabled
+ 1
+ pluginClass
+ SBMinimizeTRPlugin
+ pluginName
+ Minimize TR
+ pluginURL
+ http://www.SpinBench.com/
+ pluginVersion
+ 1
+
+
+ Waveforms
+
+ PulsePlugins
+
+
+ anchor
+
+ activeAnchor
+ peak
+ anchorType
+ 1
+ anchoredToSBKey
+ <Slice Select Gradient>.plateauRefocusPoint
+ position
+ 0.96694701910018921
+
+ duration
+ 1.5
+ editableName
+ Sinc RF
+ enforceRFLimit
+ 1
+ pluginClass
+ SBSincRF
+ pluginName
+ Sinc RF
+ pluginVersion
+ 1
+ rfGain_0_0
+ 1
+ rfPhase_0_0
+ 0.0
+ timeBandwidth
+ 4
+ tip
+ 20
+ window
+ 1
+
+
+ anchor
+
+ activeAnchor
+ start
+ anchorType
+ 1
+ anchoredToSBKey
+ startOfTR
+ position
+ 0.0
+
+ editableName
+ Slice Select Gradient
+ hasPrewinder
+ 0
+ hasRewinder
+ 1
+ netArea
+ 2.2892627716064453
+ plateauDuration
+ 1.5
+ plateauRefocusOffset
+ 0.75
+ pluginClass
+ SBSliceSelectGradient
+ pluginName
+ Slice Select Gradient
+ pluginVersion
+ 1
+ prewindFirstMoment
+ 0
+ rewindFirstMoment
+ 0
+ rfPulse
+ Sinc RF
+ tbw
+ 4
+ thickness
+ 5
+ x0Component
+ 0.0
+ xPlateauOverlap
+ 0.0
+ xPostPlateauOverlap
+ 1
+ xPrePlateauOverlap
+ 1
+ y0Component
+ 1
+ yPlateauOverlap
+ 0.0
+ yPostPlateauOverlap
+ 1
+ yPrePlateauOverlap
+ 1
+ z0Component
+ 0.0
+ zPlateauOverlap
+ 0.0
+ zPostPlateauOverlap
+ 1
+ zPrePlateauOverlap
+ 1
+
+
+ SequencePlugins
+
+
+ editableName
+ Draw Pulses
+ maskType
+ 0
+ pluginClass
+ SBDrawPulsesPlugin
+ pluginName
+ Draw Pulses
+ pluginNames
+
+ pluginVersion
+ 1
+
+
+ numGradAxes
+ 3
+ numOtherAxes
+ 0
+
+ absoluteTime
+ 2.822756290435791
+ activeInspector
+ 2
+ appVersion
+ 2.5.1
+ beginAtSS
+ 0
+ chronaxie
+ 0.35999999999999999
+ dFrequency
+ 0.0
+ editingMode
+ 0
+ fieldStrength
+ 3
+ freelyRotatable
+ 1
+ frequency
+ 0.0
+ gamma
+ 4258
+ gradCoilHeatingGain
+ 63
+ gradLimit
+ 2.2000000000000002
+ gradLimitXScale
+ 1
+ gradLimitYScale
+ 1
+ gradLimitZScale
+ 1
+ inspectorWidth
+ 222
+ magnification
+ 1.25
+ mainWindowFrame
+
+ height
+ 662
+ width
+ 727
+ x
+ 264
+ y
+ 91
+
+ maxReadoutRate
+ 500
+ nominalGradLimitScale
+ 1
+ numRfRxChannels
+ 4
+ numRfTxChannels
+ 1
+ outputPlugins
+
+
+ displayStyle
+ Magnitude / Phase
+ editableName
+ Profile
+ magnification
+ 1
+ pluginClass
+ SBProfileViewPlugin
+ pluginName
+ Profile
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ showYValues
+ 0
+ viewBottom
+ 335
+ viewHeight
+ 253
+ viewLeft
+ 75.57421875
+ viewWidth
+ 292
+
+
+ editableName
+ Waveforms
+ gradDisplayStyle
+ XYZ Separate Plots
+ pluginClass
+ SBWaveformViewPlugin
+ pluginName
+ Waveforms
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ rfDisplayStyle
+ XY Combined Plot
+ showReadoutWindows
+ 0
+ showValues
+ 0
+ viewBottom
+ 106
+ viewHeight
+ 214
+ viewLeft
+ 25
+ viewWidth
+ 292
+
+
+ editableName
+ Time Controller
+ pluginClass
+ SBTimeControlPlugin
+ pluginName
+ Time Controller
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ viewBottom
+ 58
+ viewHeight
+ 48
+ viewLeft
+ 1
+ viewWidth
+ 340
+
+
+ editableName
+ View Scaling Controller
+ pluginClass
+ SBViewScalingPlugin
+ pluginName
+ View Scaling Controller
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ viewBottom
+ 435
+ viewHeight
+ 153
+ viewLeft
+ 0.0
+ viewWidth
+ 23
+
+
+ protonDensity
+ 1
+ readoutSampleDivisor
+ 2
+ receiverPhase
+ 0.0
+ rfLimit
+ 0.10000000000000001
+ slewMagLimitXScale
+ 0.0
+ slewMagLimitYScale
+ 0.0
+ slewMagLimitZScale
+ 0.0
+ slewRateLimit
+ 10
+ slewRateLimitXScale
+ 1
+ slewRateLimitXSlope
+ 0.17000000000000001
+ slewRateLimitYScale
+ 1
+ slewRateLimitYSlope
+ 0.17000000000000001
+ slewRateLimitZScale
+ 1
+ slewRateLimitZSlope
+ 0.17000000000000001
+ t1
+ 800
+ t2
+ 150
+ timeWithinTr
+ 2.822756290435791
+ tr
+ 3.0004544258117676
+ trNum
+ 0
+ waveSamplingRate
+ 100
+ xPosition
+ 0.0
+ xVelocity
+ 0.0
+ yPosition
+ 0.0
+ yVelocity
+ 0.0
+ zPosition
+ -2.7808995246887207
+ zVelocity
+ 0.0
+
+
diff --git a/vfa_t1/SpoilerGradient.spv b/vfa_t1/SpoilerGradient.spv
new file mode 100644
index 0000000..44baad1
--- /dev/null
+++ b/vfa_t1/SpoilerGradient.spv
@@ -0,0 +1,323 @@
+
+
+
+
+ VariablePlugins
+
+
+ axisSBKey.keyPath
+ frequency
+ center
+ 0.0
+ editableName
+ Frequency (Hz)
+ orderedIndex
+ 0
+ pluginClass
+ SBVariableAxis
+ pluginName
+ Variable Axis
+ pluginVersion
+ 1
+ range
+ 400
+ res
+ 65
+ selectionStart
+ 0.0
+
+
+ editableName
+ Minimize TR
+ enabled
+ 1
+ pluginClass
+ SBMinimizeTRPlugin
+ pluginName
+ Minimize TR
+ pluginURL
+ http://www.SpinBench.com/
+ pluginVersion
+ 1
+
+
+ Waveforms
+
+ PulsePlugins
+
+
+ anchor
+
+ activeAnchor
+ start
+ anchorType
+ 1
+ anchoredToSBKey
+ startOfTR
+ position
+ 0.0
+
+ area
+ 10
+ editableName
+ Area Trapezoid
+ pluginClass
+ SBAreaTrapezoid
+ pluginName
+ Area Trapezoid
+ pluginVersion
+ 1
+ x0Component
+ 0.0
+ xFallOverlap
+ 1
+ xPlateauOverlap
+ 1
+ xRiseOverlap
+ 1
+ y0Component
+ 0.0
+ yFallOverlap
+ 1
+ yPlateauOverlap
+ 1
+ yRiseOverlap
+ 1
+ z0Component
+ 1
+ zFallOverlap
+ 1
+ zPlateauOverlap
+ 1
+ zRiseOverlap
+ 1
+
+
+ SequencePlugins
+
+
+ editableName
+ Draw Pulses
+ maskType
+ 0
+ pluginClass
+ SBDrawPulsesPlugin
+ pluginName
+ Draw Pulses
+ pluginNames
+
+ pluginVersion
+ 1
+
+
+ numGradAxes
+ 3
+ numOtherAxes
+ 0
+
+ absoluteTime
+ 2.7999999999999998
+ activeInspector
+ 4
+ appVersion
+ 1.3.2
+ beginAtSS
+ 0
+ chronaxie
+ 0.35999999999999999
+ dFrequency
+ 0.0
+ editingMode
+ 0
+ fieldStrength
+ 1.5
+ freelyRotatable
+ 1
+ frequency
+ 0.0
+ gamma
+ 4258
+ gradCoilHeatingGain
+ 63
+ gradLimit
+ 4
+ gradLimitXScale
+ 1
+ gradLimitYScale
+ 1
+ gradLimitZScale
+ 1
+ inspectorWidth
+ 222
+ magnification
+ 1.25
+ mainWindowFrame
+
+ height
+ 662
+ width
+ 727
+ x
+ 238
+ y
+ 115
+
+ maxReadoutRate
+ 500
+ nominalGradLimitScale
+ 1
+ numRfRxChannels
+ 4
+ numRfTxChannels
+ 1
+ outputPlugins
+
+
+ displayStyle
+ Magnitude / Phase
+ editableName
+ Profile
+ magnification
+ 1
+ pluginClass
+ SBProfileViewPlugin
+ pluginName
+ Profile
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ showYValues
+ 0
+ viewBottom
+ 330
+ viewHeight
+ 253
+ viewLeft
+ 25
+ viewWidth
+ 292
+
+
+ editableName
+ Waveforms
+ gradDisplayStyle
+ XYZ Separate Plots
+ pluginClass
+ SBWaveformViewPlugin
+ pluginName
+ Waveforms
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ rfDisplayStyle
+ XY Combined Plot
+ showReadoutWindows
+ 0
+ showValues
+ 0
+ viewBottom
+ 106
+ viewHeight
+ 214
+ viewLeft
+ 25
+ viewWidth
+ 292
+
+
+ editableName
+ Time Controller
+ pluginClass
+ SBTimeControlPlugin
+ pluginName
+ Time Controller
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ viewBottom
+ 58
+ viewHeight
+ 48
+ viewLeft
+ 1
+ viewWidth
+ 340
+
+
+ editableName
+ View Scaling Controller
+ pluginClass
+ SBViewScalingPlugin
+ pluginName
+ View Scaling Controller
+ pluginURL
+ [ Not Specified ]
+ pluginVersion
+ 1
+ viewBottom
+ 435
+ viewHeight
+ 153
+ viewLeft
+ 0.0
+ viewWidth
+ 23
+
+
+ protonDensity
+ 1
+ readoutSampleDivisor
+ 2
+ receiverPhase
+ 0.0
+ rfLimit
+ 0.10000000000000001
+ slewMagLimitXScale
+ 0.0
+ slewMagLimitYScale
+ 0.0
+ slewMagLimitZScale
+ 0.0
+ slewRateLimit
+ 15
+ slewRateLimitXScale
+ 1
+ slewRateLimitXSlope
+ 0.0
+ slewRateLimitYScale
+ 1
+ slewRateLimitYSlope
+ 0.0
+ slewRateLimitZScale
+ 1
+ slewRateLimitZSlope
+ 0.0
+ t1
+ 800
+ t2
+ 150
+ timeWithinTr
+ 2.7999999999999998
+ tr
+ 1.2836059331893921
+ trNum
+ 0
+ waveSamplingRate
+ 50
+ xPosition
+ 0.0
+ xVelocity
+ 0.0
+ yPosition
+ 0.0
+ yVelocity
+ 0.0
+ zPosition
+ 0.0
+ zVelocity
+ 0.0
+
+
diff --git a/vfa_t1/application.apd b/vfa_t1/application.apd
new file mode 100644
index 0000000..3c9d9d8
--- /dev/null
+++ b/vfa_t1/application.apd
@@ -0,0 +1,36 @@
+[Application]
+defaultName = VFA T1
+interface = lib:threeplane.ui
+continuous = 1
+sharedSlot = Real-Time
+calibrations = RealTimeShimming, Adjustments, CFtuning
+controlScript = control.js
+reconScript = recon.js
+singleJSEngine = false
+continuous = 0
+exclusiveRuns = 2
+
+[excitation]
+type = waveform
+file = SlabSelect.spv
+quadraticPhaseIncrement = 117
+
+[echodelay]
+type = delay
+duration = 3000
+
+[readout]
+type = waveform
+file = CartesianReadout3D.spv
+loopIndex = 0
+associatedRF = excitation
+
+[spoiler]
+type = waveform
+file = SpoilerGradient.spv
+
+[tiploop]
+type = loop
+maximumIndex = 2
+loopIndex = 1
+
diff --git a/vfa_t1/control.js b/vfa_t1/control.js
new file mode 100644
index 0000000..9ddd4a9
--- /dev/null
+++ b/vfa_t1/control.js
@@ -0,0 +1,228 @@
+/*
+================== qMRLab vfa_t1 pulse sequence =
+This is the controller script which is responsible for
+passing the variables between the GUI (control.ui) and
+RTHawk's sequencing engine.
+
+Waveforms exported by SpinBench and described by application.apd
+determine the initial state of the sequence. For this
+application, initial parameters are fetched from:
+
+- [excitation] SincRF + Z (SlabSelect.spv)
+- [echodelay] in us, to be exposed to GUI. (Not linked to a file)
+- [readout] 3D Cartesian Readout (CartesianReadout3D.spv)
+- [spoiler] Area Trapezoid (SpoilerGradient.spv)
+
+Author: Agah Karakuzu agahkarakuzu@gmail.com
+Created: October, 2019.
+// =================================================
+*/
+
+// Get sequence ID
+var sequenceId = rth.sequenceId();
+
+// Fetch initial parameters described in CartesianReadout3D.spv
+var xRes = SB.readout[".xRes"];
+var yRes = SB.readout[".yRes"];
+var zRes = SB.readout[".res"];
+
+rth.addCommand(new RthUpdateChangeReconstructionParameterCommand(sequenceId, "xSize", xRes));
+rth.addCommand(new RthUpdateChangeReconstructionParameterCommand(sequenceId, "ySize", yRes));
+rth.addCommand(new RthUpdateChangeReconstructionParameterCommand(sequenceId, "zSize", zRes));
+
+// Get minimum TR
+var scannerTR = new RthUpdateGetTRCommand(sequenceId, [], []);
+rth.addCommand(scannerTR);
+var minTR = scannerTR.tr();
+var startingTR = minTR;
+
+// Starting FOV also depends on CartesianReadout3D.spv
+// In SpinBench, FOV is defined in cm.
+var startingFOV = SB.readout[".fov"]; // cm
+
+// Slice thickness depends on SlabSelect.spv
+// In SpinBench, SliceThickness is defined in mm.
+var startingThickness = SB.excitation[".thickness"]; // mm
+
+rth.informationInsert(sequenceId,"mri.SliceThickness",startingThickness);
+var startingResolution = startingFOV/SB.readout[".xRes"] * 10; // mm
+var startingZResolution = startingThickness/zRes * 10; // At the beginning zFOV equaled to slice thickness of SS
+
+var startingTE = 3; //ms
+// Start of TE is anchored to the tip of sinc RF.
+var peakLocation = SB.excitation[".peak"];
+rth.informationInsert(sequenceId,"mri.EchoTime",startingTE + peakLocation);
+
+// Assume FA from SB as the smaller.
+var startingFA2 = SB.excitation[".tip"]; //20
+// FA should be in decreasing order (FA1 > FA2)
+var startingFA1 = startingFA2 - 17;
+
+
+var sliceThickness = startingThickness;
+var fieldOfView = startingFOV;
+
+//FIXME: This is temporary. Fix the order
+var flipAngle1 = startingFA2;
+var flipAngle2 = startingFA1;
+
+var echoTime = startingTE;
+var repetitionTime = startingTR;
+
+// Import display tool
+
+rth.importJS("lib:RthDisplayThreePlaneTools.js");
+var displayTools = new RthDisplayThreePlaneTools();
+
+// Change functions
+
+function changeFOV(fov){
+ if (fov
+
+ Form
+
+
+
+ 0
+ 0
+ 695
+ 581
+
+
+
+ Form
+
+
+ -
+
+
+
+
+
+
+
+
+ FOV [cm]
+
+
+
+ -
+
+
+
+
+
+
+
+
+ Slice Thickness [mm]
+
+
+
+ -
+
+
+
+
+
+
+
+
+ Flip Angle 1 [deg]
+
+
+
+ -
+
+
+
+
+
+
+
+
+ Flip Angle 2 [deg]
+
+
+
+ -
+
+
+
+
+
+
+
+
+ TR [ms]
+
+
+
+ -
+
+
+
+
+
+
+
+
+ TE [ms]
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ RthParameterInputWidget
+ QWidget
+ RthParameterInputWidget.h
+ 1
+
+
+
+
+
diff --git a/vfa_t1/recon.js b/vfa_t1/recon.js
new file mode 100644
index 0000000..f9236d1
--- /dev/null
+++ b/vfa_t1/recon.js
@@ -0,0 +1,91 @@
+/*
+================== qMRLab vfa_t1 pulse sequence =
+This script is responsible for collecting raw data
+and reconstructing images.
+
+Waveforms exported by SpinBench and described by application.apd
+determine the initial state of the sequence. For this
+application, initial parameters are fetched from:
+
+- [excitation] SincRF + Z (SlabSelect.spv)
+- [echodelay] in us, to be exposed to GUI. (Not linked to a file)
+- [readout] 3D Cartesian Readout (CartesianReadout3D.spv)
+- [spoiler] Area Trapezoid (SpoilerGradient.spv)
+
+For now, base resolution components are hardcoded to be
+256X256mm (inplane) and 5mm (slab thickness) for the
+3D readout.
+
+TODO: These parameters are to be fetched from controller.
+
+Author: Agah Karakuzu agahkarakuzu@gmail.com
+Created: October, 2019.
+// =================================================
+*/
+
+var sequenceId = rth.sequenceId();
+var instanceName = rth.instanceName();
+
+var observer = new RthReconRawObserver();
+observer.setSequenceId(sequenceId);
+observer.observeValueForKey("acquisition.samples", "samples");
+
+
+function reconBlock(input) {
+
+ this.sort = new RthReconRawToImageSort();
+
+ this.sort.setPhaseEncodes(256);
+ this.sort.setSamples(256);
+ this.sort.setSliceEncodes(5);
+
+ this.sort.setAccumulate(256*5);
+
+ this.sort.setInput(input);
+
+ this.fft = new RthReconImageFFT();
+ this.fft.setInput(this.sort.output());
+
+ this.output = function() {
+ return this.fft.output();
+ };
+}
+
+// For each `coil we need sort and FFT.
+
+var sos = new RthReconImageSumOfSquares();
+var block = [];
+
+function connectCoils(coils){
+ block = [];
+ for (var i = 0; i