Conversation
aabrown100-git
left a comment
There was a problem hiding this comment.
@javijv4 great job thanks for doing this! Sorry for the delay in reviewing, but I left some comments throughout.
My only major comment is to better explain the modifications to Bayer, and relatedly if we can validate the implementations for both Bayer and Doste by comparing to lifex or other codes. I think both of these aspects will be useful to future lab members, especially when writing about these methods in their papers.
|
As discussed with @javijv4, I've found that computing gradients at nodes (where Laplace solutions are stored) and then interpolating point data to cell data gives smoother basis vectors than the current method of first interpolating Laplace solutions to cells then computing gradients. I've also noticed that for some course meshes, 500 LS iterations doesn't quite converge (increased to max 2000 in my branch). See https://github.com/dseyler/sv-fibergen.git where these changes have been implemented as well as optional command line inputs. |
|
@dseyler thank you! It looks great. @aabrown100-git I will
Does that sound good? |
|
@javijv4 Sounds good to all points. For point 3, for the documentation is that the |
|
@aabrown100-git For the VALIDATION.MD, I was thinking of restricting it to show that the code is doing what it is supposed to. |
|
@javijv4 |
|
@javijv4 Sorry for the late review ! This Python code probably does not belong in the svMultiPhysics repository but should be part of SimVascular like the Purkinje fiber generation code is. |
| Created on 2025/11/21 20:38:14 | ||
|
|
||
| @author: Javiera Jilberto Vallejos | ||
| ''' |
There was a problem hiding this comment.
@javijv4 No need for date and author, also add license header.
There was a problem hiding this comment.
Is a license header necessary? Other Python files in the repo do not have a license header
There was a problem hiding this comment.
@aabrown100-git I think any code in the repository needs a license.
There was a problem hiding this comment.
@ktbolt Is this the header I should add?
# SPDX-FileCopyrightText: Copyright (c) Stanford University, The Regents of the University of California, and others.
# SPDX-License-Identifier: BSD-3-Clause
| x: array-like of shape (N, 3) | ||
| Returns: | ||
| np.ndarray of shape (N, 3) with row-wise normalized vectors. | ||
| """ |
There was a problem hiding this comment.
@javijv4 Be sure to follow a consistent docstring format like Google.
|
@ktbolt thanks! I will work on the revisions. Regarding where to host the code, from what I found, I think the Purkinje code in the SimVascular repository is a SimVascular plugin. These, for now at least, are stand-alone Python codes. I discussed where to put this code with @aabrown100-git, and the utilities folder in svMultiPhysics seemed like a good place, since it already has two other folders that also contain stand-alone Python code. I can definitely move it somewhere else if you think there are better places to put it, though! |
|
@javijv4 The core of the Purkinje Plugin is its Python code, it can be imported as a package and run in a Python script, the plugin just provides an interface to it. This functionality will be made available in the new SimVascular implementation in Slicer 3D as a plugin and Python package. It seems that this fiber generation code should be made available to SimVascular users as a Python package that can be imported, something that could later be used to create a Slicer 3D plugin. This will require a bit more work to generalize the code but it is better to do this now than later. |
|
@ktbolt sounds good! How should I proceed with this then? The Purkinje plugin repository is an individual repo, so I am not sure how to go about creating one. Also, this pull request will need to be closed, right? I have a separate GitHub repository (https://github.com/javijv4/sv-fibergen) where I initially had all these codes, and where I've been working on the revisions, so it would be easy to just transfer that to a SimVascular repository. |
|
@javijv4 I think it will be ok to just leave the code where it is and we can figure out where to put it in future, not sure how the new Slicer SimVascular code will be organized. The important thing is to implement a general Python package that can be imported, does not assume a solver or certain face names. @aabrown100-git What do you think ? |
|
@ktbolt @javijv4 I think implementing it as a Python package is a good idea! From what I can tell, FibGen.py is basically a Python package already. Do we just need a few changes to make it more user friendly? @javijv4 If we want to remove the template .xml files, you can write Python code to generate the desired xml file and include this in FibGen.py. A few prompts to the AI should get it done. @ktbolt what do you mean the package should not assume a solver? |
|
@javijv4 @aabrown100-git I think FibGen.py needs to be more general
I had thought that the code could work on the output of any solver but maybe that is not important. |
|
@ktbolt, sounds good, I can refactor the code to make it more general and use classes. This is the structure I am thinking of, I think it makes sense for the code to be able to read the solutions from any other solver, which is possible with this structure. But I would like to keep the option to run the solver because, in practice, when running these codes for several patients, it is so much easier to have all the steps in one file. About the first point, what do you mean by generic face names? The way I have it set up is that the user indicates the name of the surfaces in a dictionary in the main Python file, which is passed to the function that runs the Laplace problem that uses tit to point to the right files in the solver_*.xml files. I was trying to maintain the original code as much as possible, but since I will be adding classes, I can revise the input reading to be more straightforward as well. @aabrown100-git sounds good, I will do that. |
|
@javijv4 In Maybe |
|
Yeah, the strings are used to identify a particular heart surface. "epi" = epicardium, "mv" = mitral valve, "tv" = tricuspid valve. I will use more descriptive names and look into using an Enum class. Thanks! |
|
Hey all, Ok, I finished the updates and implemented the new code using classes. The code now consists of 5 scripts.
@aabrown100-git, I think this implementation will make it easier to add new fiber-generation methods, for example, in the atria. It will be required to add the new surfaces to I added a DOCUMENTATION.md that explains in detail the methods used and the modifications to the original Bayer code. Lastly, I added a VALIDATION.md file to show the final results of the code and the correlation between the scalar-interpolated fiber angles and those obtained using the fiber generation code. Scripts to generate these results are provided in
The README.md provides a brief description and points to these other documents for more information. Let me know what you think and if there are any issues! |
…he septum to the LV
|
@ktbolt done! @aabrown100-git and @dseyler, I modified the basis definition to ensure consistent alpha and beta angle definitions across methods and chambers, and modified Doste to assign 2/3 of the septum to the LV. |
|
@ktbolt question: right now, the scripts are set up so the user can run the examples without installing the scripts as a package. I have everything set up so the packages can be installed as a package with |
|
@javijv4 I don't think the user will need to install the scripts as a package. It would be good to be able to import the modules in
Note that the naming convention for modules is all lowercase with underscores so |
|
@ktbolt, @aabrown100-git done!
|
aabrown100-git
left a comment
There was a problem hiding this comment.
@javijv4 This all looks good to me now, thanks for all your good work on this!



Current situation
Resolves #479
Release Notes
Code of Conduct & Contributing Guidelines