"""Return the thermal equilibrium state of the system."""
out=np.sum(self.Izs,0)
out=np.sum(self.Izs,0)
returnout
# Hamiltonians
defgetHGrad(self,G,r):
# Hamiltonians
defgetHGrad(self,G,r):
"""
Return the gradient hamiltonian
Args:
G (ndarray): 3x1 vector of gradient amplitudes in T/m
G (ndarray): 3x1 or 3xN vector of gradient amplitudes in T/m
r (ndarray): 3x1 vector of spatial position in m
Returns:
H (ndarray): Gradient hamiltonian
H (ndarray): Gradient hamiltonian
"""
# TODO: Handle modulating gradients
H=self.GAMMA*G@r*self.Izs[0]
forizinself.Izs[1:]:
H+=self.GAMMA*G@r*iz
returnH
# Ensure that a single gradient value is treated the same as a vector
ifG.ndim==1:
G=G[:,np.newaxis]
Hg=[]
forginG.T:
H=self.GAMMA*g@r*self.Izs[0]
forizinself.Izs[1:]:
H+=self.GAMMA*g@r*iz
Hg.append(H)
defgetHRF(self,pulse,offset):
returnnp.asarray(Hg)
defgetHRF(self,pulse,offset):
"""
Calculate and return the RF hamiltonian
...
...
@@ -94,44 +103,46 @@ class simulator:
offset (float): Offest frequency in Hz.
Returns:
H (list of ndarray): RF hamiltonian for each pulse time point.
H (list of ndarray): RF hamiltonian for each pulse time point.
"""
ifpulseisNone:
return0
Hrf=[]
pulseAmp=np.abs(pulse)
pulsePhs=np.angle(pulse)
theta=np.arctan2(pulseAmp,-offset)# Note the negative sign before the offset here. I'm not sure why it's needed.
weff=np.sqrt(pulseAmp**2+offset**2)
forw,t,phiinnp.nditer((weff,theta,pulsePhs)):
Hrf.append(w*np.sum(self.Ixs*np.array(np.sin(t)*np.cos(phi))+self.Iys*np.array(np.sin(t)*np.sin(phi))+self.Izs*np.array(np.cos(t)),0))# require array for multiplication with list to work
# for amp,phs in np.nditer((pulseAmp,pulsePhs)):
# Hrf.append(amp*np.sum(self.Ixs*np.array(np.cos(phs)) + self.Iys*np.array(np.sin(phs)),0)) # require array for multiplication with list to work
returnHrf
# Note the negative sign before the offset here. I'm not sure why it's needed.