Solid-2.0 Documentation---
 

 
 
home
Sections
-Spins
-Parameters
-Pulses
---Function List---
-file formats
Examples
-Static
---basic
---2D
---alterSys
---decouple
-Mas
---basic
---2D
---ptop
-C7s
---basic
---2D
---explicit
---rotor
---transfer
-Quadrupoles
---central Trans
 
 


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{
    # if desired use a pulse section via
        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
    #this defined the nucleous
    #T {label} {spin}

        T 1H 0 #the first spin is a proton
        T 13C 1 #the second spin is 13C
        T 14N 2 # a quadrupole spin

    #interactions are defined as below
    # frequencies are defined in Hz (not rad/sec)
    #a CSA
    #C {iso} {del} {eta} {spin} {alpha} {beta} {gamma}

        C 3000 234 0.2 0 #a csa on the first spin
        C 0 4567 0 1 #a csa on the second spin

    #A Dipole
    #D {del} {spin1} {spin2} {alpha} {beta} {gamma}

        D 3450 0 1 # a dipole between spin 1 and 2

    #a qudrupole
    #Q {Q} {eta} {spin} {alpha} {beta} {gamma} {order}

        Q 1e6 0 2 0 0 0 2

    # scalar coupling
    #J {J} {spin1} {spin2}

        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

    # the internal zcw powder average
    powder{
        aveType zcw
        thetaStep 233
        phiStep 144
        gammaStep 0
    }


    # using an input file
    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{
    # the internal zcw powder average
        powder{
            aveType zcw
            thetaStep 233
            phiStep 144
            gammaStep 0
        }
        wr=3000
        rotor=acos(1/sqrt(3))*deg2rad #magic angle
        maxtstep=1e-6
        npts1D=512
        sw=10*wr
    }


  • The pulses Section

    Your input file should have this section

    pulses{
    # if desired use a pulse section via
        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')


 
all material copywrite ©2002 LBL
Contact: Bo Blanton