|
|
Solid-2.0 is a general quantum mechanical NMR simulation package designed
to simulate virtually any pulse sequence NMR performs on up to 10 spins.
The distribution is with 'BlochLib'
(because you need that in order to build solid), in the examples folder.
The source code interfaces directly with the BlochLib NMR library and
is greatly simplified over previous versions, that addition of additional
features is very simple...if you have any features that you would like
to see (and have a knack for C++) read the BlochLib documentation first,
then add away. If the feature is potent enough to warrant inclusion
in the main distribution please let me know and i will add it (i'll
even optimize it and extend it if possible)...if you are not so C++
savvy, then let me know the feature and i could add it...
Solid-2.0 is a major revision on the previous solid packages. It includes
an in-house scripting capabilities, easier syntax, arbitrary 2D acquisitions
and arbitrary point-to-point acquisitions, reusable pulse sections,
multiple spin sections, manipulation of spin parameters in the pulse
sequence. All in all, the entire package is much more powerful and useful.
The old version is incompatible with this version.
This documentation is highly example driven with a brief description
of each of the available function.
- To Run In Parallel
- Make sure you compile with MPI
- It runs on a master/slave model so when you run it make sure you
add one extra processor (the 'master' only gives out work and does
minimal work itself)
If you have 4 procs..simply issue this command
mpirun -np 5 solid {config file}
| The 3 Sections |
- Each input file should have these 3 sections with the basic
syntax
spins{
...
}
parameters{
powder{
...powder options...
}
...other parameters...
}
pulses{
sub1{
...pulses things....
}
...main sequence running...
...and 'fid' collection...
}
comments can be made anywhere by beginning a line with '#'
- The Spins
Section
You input file should have this section
spins{
...
}
Inside 'spins' you should obey the syntax as described for
the input string vector of the 'SolidSys.' Spin indices are
started at '0' (not 1) An example is given below
spins{
numspins 2
T 1H 0
T 13C 1
T 14N 2
C 3000 234 0.2 0
C 0 4567 0 1
D 3450 0 1
Q 1e6 0 2 0 0 0 2
J 500 0 1
}
-
The parameters
Section
Your input file should have this section
parameters{
powder{
...powder options...
}
...other parameters...
}
You can define any variable you wish here using the syntax 'A=B'
HOWEVER, there are some basic predefined variables that will be
set regardless of weather or not they are set here. It should
be noted that you can always alter these variables inside the
'pulses' section as well. These variables will be GLOBAL to any
subpulse section and any item in the pulse section
| The Global Variables |
| wr |
the rotor spinning speed
in Hz (default = 0) |
| rotor |
the rotor angle in DEGREES
(default =0 ) |
| maxtstep |
the basic time step for performing
the dyson time ordering for spinning samples. This value will
be largest dt for any integration (default 1e-6 seconds) |
| npts1D |
the number of FID points
in the first dimension (default= 1) |
| npts2D |
the number of FID points
in the seond dimension (default = 1) |
| sw |
The sweep width in Hz (default
= 20kHz) |
| Bfield |
The magnetic Field strength
in Hz (default 400 Mhz) |
| roeq |
the Initial Density matrix.
It can be anything available to HamiltonianGen in BlochLib
(default =Iz) |
| detect |
The Detection matrix. It
can be anything available to HamiltonianGen in BLochLib (default=Ip) |
| filesave |
The file name to save the
FIDs in (default=soliddata) |
| |
|
The powder subsection defines the powder average type, or the
input file of angles. It follows the syntax available to the 'powder'
class in BlochLib. Below is an example
powder{
aveType zcw
thetaStep 233
phiStep 144
gammaStep 0
}
powder{
aveType /total path to file/filename
}
The input file should have 2,3, or 4 columns and all angles
are in RADIANS
2-column file:: {phi} {theta}
3-column file:: {phi} {theta} {weight}
4-column file:: {phi} {theta} {gamma} {weight}
Below is a typical parameter input example
parameters{
powder{
aveType zcw
thetaStep 233
phiStep 144
gammaStep 0
}
wr=3000
rotor=acos(1/sqrt(3))*deg2rad
maxtstep=1e-6
npts1D=512
sw=10*wr
}
- The pulses
Section
Your input file should have this section
pulses{
sub1{
...pulses
things....
}
...main sequence running...
...and 'fid' collection...
}
This is the main driver. It performs the propagation, fid collection,
and file saving. You can alter spin system parameters here,
and change or define any variable you wish. Any variable you
set here is GLOBAL to all the sub sections. The subsections
should start with the 'sub1' and continue to 'subN.' Because
the usage of this section is highly dependant on what you are
doing, I'll simply move on to the function list, and let you
look at the examples for more information.
| The
Pulse Section Function List.... |
| ro(matrix) |
sets the current density matrix
to the input....thing can be of the syntax as HamiltonianGen
in BlochLib |
| detect(matrix) |
sets the detection matrix to
the input....thing can be of the syntax as HamiltonianGen in
BlochLib |
| amplitude(#) |
Sets the default pulse amplitude
(in Hz) the default will remain in effect until you call this
function to set it again. The input can be any valid expression
to Parser in BlochLib. |
| offset(#) |
Sets the default pulse offset
(in Hz) the default will remain in effect until you call this
function to set it again. The input can be any valid expression
to Parser in BlochLib. |
| ptop() |
Sets the type of FID to a point
to Point experiment. You must set this ANYTIME you want to use
the fid() command to collect only ONE point. It performs a trace
of the current evolved 'ro' with the detection matrix. You must
declare this BEFORE the 'fid' command is used. |
| 2D() |
If you are collecting ANY TYPE
of 2D data, you must set this flag so the data get handled properly.
You must declare this BEFORE the 'fid' command is used. |
| use(subsect) |
This tells the program to use
a subsection defined as a 'sub1'..'subN' section. It will RECALCULATE
it propagator every time it sees this function. You should use
this function (as aposed to 'reuse') if there is a variable
inside the subsection that gets updated OUTSIDE the subsection
which would cause the previously calculated propagator to be
invalid (things like changing the rotor angle, or a pulse amplitude) |
| reuse(subsect) |
This tells the program to use
a subsection defined as a 'sub1'..'subN' section. It will CALCULATE
the propagator ONLY ONCE. You should use this function when
the propagator will remain the same regardless of the time,
or any other variables. For example a C7 uses a single 2 rotor
cycle that does not change the propagator for each time incremented.
This saved you valuable computation time when used properly. |
use(subsect, repeat
use(subsect, repeat, hold)
reuse(subsect, repeat)
reuse(subsect, repeat, hold) |
Performs the same things as
the use or reuse command above, except that if the subsection
is a time periodic, then you can save computational time by
simply 'repeating' the propagator rather then recalculating
the entire thing. The parameter 'repeat' should evaluate to
a number >=0. If '0' it will NOT be applied at that time.
The hold command is useful when doing 2D type experiments (either
a ptop or a full 2D collection). The propagator will only be
applied at the FIRST point in any fid. Things like cross-polarization
(CP) fit into this category where one only CP's at the beginning
of the sequence. |
| cycler(matrix) |
This command enables you to
do 'fictitious' phase cycling. Whenever this command is implemented
the current propagated density matrix will be 'traced' with
the input matrix such that the resulting density matrix becomes
ro=trace(adjoint(cycler), ro)*cycler/trace(cycler, adjoint(cycler))
For example a z-filter (used commonly to remove unwanted X and
Y coherences would be implemented by 'cycler(Iz).' The matrix
can be of the syntax as HamiltonianGen in BlochLib. |
| fid() |
Collects an ENTIRE fid of the
length of the 'npts1D' variable, weather that be a point to
point experiment, static FIDs, or spinning FIDs. |
| fid(int) |
This is an extension that give
you the ability to specify what fid point you are collecting.
To use this for 1D FIDs you must have set the ptop flag using
'ptop().' To use this for 2D fids you must use the '2D()' flag.
For Point-To-Point 1D experiments a single complex value is
added to the data vector, for 2D data an FID of length npts1D
is computed (either in the normal static, spinning approach
or the Point To Point approach (if the ptop() command was used)). |
| alterSys(what, num) |
This allows you to alter a
parameter in the SpinSystem. The 'what' is of the syntax
D01del --> alters the dipolar coupling between 0 and 1
C1iso --> alters the isotropic shift of spin 1
C0eta --> alters the eta of spin 0
Q0del --> alters the quad coupling on spin 0
D01alpha --> changes the orientation angle of the dipole
between 0 and 1
The couplings MUST be defined in the 'spins' section before
you can alter them...num can be of any expression valid to the
Parser class in BlochLib |
savefid()
savefid(name)
savefid(name, which) |
This will save the fid AFTER
the ENTIRE powder average has been calculated. It will automatically
determine the save type. If the spectra is 1D it will save it
as a 'text' file (see below). If the data is 2D it will save
it as a matlab binary file (see below).
If 'name' is not present it will use the variable 'filesave'
as the file name.
If 'which' is present it will save a 2D fid in its 1D components
adding the number 'num' to the end of the file name to distinguish
it from the rest...this is only valid for 2D data. |
savefidtext()
savefidtext(name)
savefidtext(name, which) |
Does the same as the above
function except forces it to save the data as an ASCII file
(for both 1 and 2Ds) |
savefidmatlab()
savefidmatlab(name)
savefidmatlab(name, which) |
Does the same as the above
function except forces it to save the data as a matlab file
(for both 1 and 2Ds) |
savefidbinary()
savefidbinary(name)
savefidbinary(name, which) |
Does the same as the above
function except forces it to save the data as a binary file
(for both 1 and 2Ds) |
| show() |
This command DISPLAYS what
the simulator 'would be doing' if you do not call this function.
It dumps a LARGE variety of information to the screen and can
be useful for debugging you pulse sequences. You should set
this at the beginning of the pulses section such that everything
is displayed. It does NOT calculate anything (except the variables
and inputs) |
| {spin}:pulse(time, phase,
amp, offset) |
This produces a pulse on spin {spin} for the time {time}
in seconds, amplitude {amp} in Hz, phase {phase} in DEGREES,
and offset {offset} in Hz...some examples
a 90 pulse on proton
1H:pulse(1/15000/4, 90, 15000, 0)
uses the default offset (by 'offset(#)')
1H:pulse(1/15000/4, 90, 15000)
uses the default amplitude (by 'amplitude(#)') and offset
1H:pulse(1/15000/4, 90)
To perform multiple pulse on different spins simply use the
'|'
a 90 pulse on both carbon and 1H
amplitude(15000)
1H:pulse(1/15000/4,90) | 13C:pulse(1/15000/4,90)
if there are more then one spin type in the system, and no
pulse is specified for it at that time, a DELAY is assumed...
|
| {spin}:delay(time) |
This produces a delay (simple
evolution under the current Hamiltonian) for a time {time} in
seconds Some examples
1H:delay(0.001)
1H:pulse(1/15000/4,90) | 13C:delay(1/15000/4) |
File Formats...
- Text
For all 1D data, the output file will contain these columns
{time} {frequency} {real fid} {imag
fid} {real fft} {imag fft} {power fft}
For all 2D data, the file will contain
npts1 = {npts1D}
npts2 = {npts2D}
{matrix row index} {matrix col index} {real part} {imag part}
...
- Binary
For all 1D data, the ouput will be
npts1={npts1D}
{real val 0}{imag val 0}...{real val N}{imag val N}
the 'real val ' and 'imag val' are in binary
For all 2D data, the output will be
npts1={npts1D}
npts2={npts2D}
{real val row=0, col=0}{imag val row=0, col=0}...
{real val row0, col=npts2}{imag val row=0, col=npts2}
...
{real val row=npts1, col=0}{imag val row=npts1, col=0}...
{real val row=npts1, col=npts2}{imag val row=npts1, col=npts2}
the 'real val ' and 'imag val' are in binary
- Matlab
For both 1D and 2D data, a data matrix
(or vector) will be saved in matlab format with the name "vdat"
(so that it interfaced directly with 'solidplotter')
|
|