from__future__importannotationsimportdolfinfromtypingimportNamedTupleimportnumpyasnptry:importufl_legacyasuflexceptImportError:importufldefecg_recovery(*,v:dolfin.Function,mesh:dolfin.Mesh,sigma_b:dolfin.Constant,dx:dolfin.Measure|None=None,point:np.ndarray|None=None,r:dolfin.Function|None=None,):ifdxisNone:# breakpoint()dx=dolfin.dx(domain=mesh,metadata={"quadrature_degree":4})ifrisNone:r=dolfin.SpatialCoordinate(mesh)-dolfin.Constant(point)r3=ufl.sqrt((r**2))**3# https://carp.medunigraz.at/knowledge-base/tissue-scale-ep.htmlreturn(1/(4*ufl.pi*sigma_b))*dolfin.assemble((ufl.inner(ufl.grad(v),r)/r3)*dx)def_check_attr(attr:np.ndarray|None):ifattrisNone:raiseAttributeError(f"Missing attribute {attr}")# Taken from https://en.wikipedia.org/wiki/Electrocardiography
[docs]classLeads12(NamedTuple):RA:np.ndarrayLA:np.ndarrayLL:np.ndarrayRL:np.ndarray|None=None# Do we really need this?V1:np.ndarray|None=NoneV2:np.ndarray|None=NoneV3:np.ndarray|None=NoneV4:np.ndarray|None=NoneV5:np.ndarray|None=NoneV6:np.ndarray|None=None@propertydefI(self)->np.ndarray:"""Voltage between the (positive) left arm (LA) electrode and right arm (RA) electrode"""returnself.LA-self.RA@propertydefII(self)->np.ndarray:"""Voltage between the (positive) left leg (LL) electrode and the right arm (RA) electrode """returnself.LL-self.RA@propertydefIII(self)->np.ndarray:"""Voltage between the (positive) left leg (LL) electrode and the left arm (LA) electrode """returnself.LL-self.LA@propertydefVw(self)->np.ndarray:"""Wilson's central terminal"""return(1/3)*(self.RA+self.LA+self.LL)@propertydefaVR(self)->np.ndarray:"""Lead augmented vector right (aVR) has the positive electrode on the right arm. The negative pole is a combination of the left arm electrode and the left leg electrode """return(3/2)*(self.RA-self.Vw)@propertydefaVL(self)->np.ndarray:"""Lead augmented vector left (aVL) has the positive electrode on the left arm. The negative pole is a combination of the right arm electrode and the left leg electrode """return(3/2)*(self.LA-self.Vw)@propertydefaVF(self)->np.ndarray:"""Lead augmented vector foot (aVF) has the positive electrode on the left leg. The negative pole is a combination of the right arm electrode and the left arm electrode """return(3/2)*(self.LL-self.Vw)@propertydefV1_(self)->np.ndarray:_check_attr(self.V1)returnself.V1-self.Vw@propertydefV2_(self)->np.ndarray:_check_attr(self.V2)returnself.V2-self.Vw@propertydefV3_(self)->np.ndarray:_check_attr(self.V3)returnself.V3-self.Vw@propertydefV4_(self)->np.ndarray:_check_attr(self.V4)returnself.V4-self.Vw@propertydefV5_(self)->np.ndarray:_check_attr(self.V5)returnself.V5-self.Vw@propertydefV6_(self)->np.ndarray:_check_attr(self.V6)returnself.V6-self.Vw