Selectively inverting RF pulse

Topics related to Spinach package
Post Reply
sjlin
Posts: 5
Joined: Thu Aug 15, 2024 3:16 am

Selectively inverting RF pulse

Post by sjlin »

Dear Prof. Kuprov,

I was testing to edit a spin system with a selectively inverting RF pulse in gradient echo imaging sequence. My initial approach was by adding the shaped_pulse_af function to the grad_echo.m, then specify the targeted editing frequency and other parameters outside the sequence.
I ran into a problem starting with water only system (no chemical shift, no j-coupling, etc), where I fixed TE and varied pulse lengths of the editing pulse (Gaussian shaped, center frequencies far away from water peak). In this case, my assumption was that readout signal would occur at either real or imaginary axis depending on the direction of excitation pulse, with slight variation due to partial inversion of water tail. However, the readout signals appeared to gyrate in complex plane and the frequencies of 'gyrating' matched the editing frequencies. I am not sure what was causing this.

Please find the code below. Any comments would be greatly appreciated.

Thank you,
Shujun

Code: Select all

% Hard 90-degree pulse
rho=step(spin_system,-Hy,parameters.rho0,pi/2);

% free evolution
rho=evolution(spin_system,L,[],rho,1/parameters.evol_rate,parameters.n_step-...
                  parameters.g_step_dur*parameters.g_n_steps*parameters.evol_rate,'final');

% Soft 180 on user-specified frequency
rho=shaped_pulse_af(spin_system,L,Hx,Hy,rho,parameters.rf_frq_list{1}-parameters.offset,...
                    parameters.rf_amp_list{1},parameters.rf_dur_list,...
                    parameters.rf_phi,parameters.max_rank,'expv');

% free evolution
rho=evolution(spin_system,L,[],rho,1/parameters.evol_rate,parameters.n_step-...
                  2*parameters.g_step_dur*parameters.g_n_steps*parameters.evol_rate,'final');

% Evolution under the X gradient
rho=evolution(spin_system,L-parameters.g_amp*G{1},[],rho,parameters.g_step_dur,...
                                                         parameters.g_n_steps,'final');

% Detection under the X gradient of opposite sign
fid=evolution(spin_system,L+parameters.g_amp*G{1},parameters.coil,rho,...
                                                  parameters.g_step_dur,...
                                                2*parameters.g_n_steps,'observable');
kuprov
Posts: 201
Joined: Mon Mar 29, 2021 4:26 pm

Re: Selectively inverting RF pulse

Post by kuprov »

You are seeing the rotating frame offset - shaped_pulse_af makes off-resonance pulses at the frequency that you specify relative to the current rotating frame frequency. This is why the phase is gyrating at the frequency at which you had told the pulse to act. That function models a pulse by explicitly propagating your spin system through a sinusoidal magnetic field.

If you would like to have the more textbook behaviour, shift the rotating frame by adding some Z operator and then run a pulse by adding amplitude-modulated Lx*cos(phi)+Ly*sin(phi); the best function for that is shaped_pulse_xy.
sjlin
Posts: 5
Joined: Thu Aug 15, 2024 3:16 am

Re: Selectively inverting RF pulse

Post by sjlin »

Thanks for your input. They are very well received.

I searched Spinach documentation for adding the z-operator in order to shift the lab frame frequency with the shaped_pulse_xy function, but I am still unclear on how to achieve that. It would be really helpful if there was an example to begin with.

Thanks again for your time on this non-expert problem.

Shujun
kuprov
Posts: 201
Joined: Mon Mar 29, 2021 4:26 pm

Re: Selectively inverting RF pulse

Post by kuprov »

I have added the offset option to one of the example files - see Line 56 in the enclosed. As you can see from the figures, adding the offset in this case simply shifts the excitation pattern without accumulating a phase.
Attachments
500Hz_offset.png
500Hz_offset.png (13.67 KiB) Viewed 74732 times
zero_offset.png
zero_offset.png (13.67 KiB) Viewed 74732 times
shaped_pulse_vg.m
(1.99 KiB) Downloaded 3785 times
sjlin
Posts: 5
Joined: Thu Aug 15, 2024 3:16 am

Re: Selectively inverting RF pulse

Post by sjlin »

This is really helpful!

With the script and your earlier suggestion, I can now simulate the way I wanted with the editing frequency and direction using an additional 'phi' term, thanks! I have one more question about an error I received when running imaging.m.

Inside the gradient echo imaging sequence, I added the z operator

Code: Select all

% % Make pulse operators
Lp=operator(spin_system,'L+','1H');
Lx=kron(speye(prod(parameters.npts)),(Lp+Lp')/2);
Lzp=operator(spin_system,'Lz','1H');
Lz=kron(speye(prod(parameters.npts)),Lzp);

% Initial state
rho=state(spin_system,'Lz','1H');
Outside the sequence, I have the parameters defined for the spin system as followed:

Code: Select all

parameters.rho0_ph={ones(100,1)*(1)};
parameters.rho0_st={state(spin_system,{'Lz'},{1})}; 
parameters.coil_ph={ones(100,1)};
parameters.coil_st={state(spin_system,'L+','1H','cheap')};

% Sample geometry
parameters.dims=.1; % dimension of sample, unit: m
parameters.npts=100;
parameters.deriv={'period',3};

% % Relaxation superoperators
[R1Op,R2Op]=rlx_t1_t2(spin_system);

% Relaxation phantom
parameters.rlx_ph={ones(100,1);
                   ones(100,1)};
parameters.rlx_op={R1Op,R2Op};

% Set up acquisition
parameters.spins={'1H'};
parameters.coil=state(spin_system,'L+','1H','cheap');
parameters.decouple={};
parameters.offset=0;
parameters.axis_units='Hz';
parameters.g_amp=5e-3; % T/m
parameters.g_step_dur=2e-5; % s 
parameters.g_n_steps=100;
parameters.zerofill=2*parameters.g_n_steps+1;
parameters.sweep=2000; % rate of readout step
parameters.npoints=parameters.zerofill;
parameters.evol_rate=5000; % rate of evolution step
Here is the error message after running my script. I tried to change parameters.npts, but it did not help. I was wondering where I should change to match the dimension of Louisvillian and sequence parameters.

Code: Select all

Error using shaped_pulse_xy>grumble
control operators must have the same size as drift.

Error in shaped_pulse_xy (line 65)
grumble(drift,controls,amplitudes,slice_durs,rho,method);

Error in sjl_RF_test2 (line 54)
parameters.rho0=shaped_pulse_xy(spin_system,L,...

Error in imaging (line 175)
answer=pulse_sequence(spin_system,parameters,H,R,K,G,F);

Error in sjl_shaped_pulse_xy (line 123)
fid(:,I)=imaging(spin_system,@sjl_RF_test2,parameters);
Thank you for your patience on this thread from a newbie.

Shujun
kuprov
Posts: 201
Joined: Mon Mar 29, 2021 4:26 pm

Re: Selectively inverting RF pulse

Post by kuprov »

Some operator somewhere has not been replicated to all voxels. Set a break point before Line 54 in sjl_RF_test2 and check the dimensions manually.

When you do imaging simulations, there is always a kron call like this:

Code: Select all

Lz=kron(speye(prod(parameters.npts)),Lzp);
that tells Spinach "replicate this spin operator to all voxels". It makes a block-diagonal matrix (one block per voxel) with each block containing the operator. If you have a dimension mismatch error, that means that some operator somewhere has been received from Spinach kernel with an operator() call, but not replicated.
sjlin
Posts: 5
Joined: Thu Aug 15, 2024 3:16 am

Re: Selectively inverting RF pulse

Post by sjlin »

I accidentally overwrote the detection state - 'parameters.coil' - that caused the dimension mismatch. Thanks for the explanation, it works now :D
kuprov
Posts: 201
Joined: Mon Mar 29, 2021 4:26 pm

Re: Selectively inverting RF pulse

Post by kuprov »

:)
Post Reply