I guess there's a plan for how pygwinc will eventually look, but I thought I'd ask this now rather than later in development.
Is there a reason you avoid using objects to represent the various aspects of the noise budget (the noise calculations, interferometers, plotting tools, etc.)? This seems to me to be the clearest way to define an API for others to write their own noise budgets. Right now some of the code seems to resemble MATLAB GWINC in its structure, which, while making it easy to change parameters and noises that are already supported, makes it difficult to add new noise sources or change the way existing noise sources are calculated.
I would really like to be able to subclass a base interferometer noise model, add the noises that I want to calculate, maybe change a few things (e.g. a different interferometer configuration's quantum noise calculation) but otherwise use everything else (including e.g. plotting tools) as-is. As an example, an in-air experiment wouldn't care to plot residual gas noise - right now as far as I can tell I'd have to either remove this with a monkey hack or open up my copy of gwinc.py and hard-code it. The latter is probably what most people would do, leading to the prospect that unofficial implementations start getting spread around (I've seen this happen with GWINC!).
Maybe another cool thing to do would be to have stuff like the squeezer as "mixins" to the base interferometer class, which then provides tools to e.g. calculate filter cavity parameters, instead of having these calculations -- which might be confusing for those modelling completely different setups -- available whether you need them or not. With a mixin it would even be possible for someone to implement their own squeezer model, itself perhaps a subclass of the base squeezer model, to model different squeezer designs.
I guess all of this depends on the intended use case!
Designs
Child items ...
Show closed items
Linked items 0
Link issues together to show that they're related or that one is blocking others.
Learn more.
The first use case we've been targeting is to accurately reproduce the reference noise curves for A+, Voyager, and CE. To do that we need to reconcile the differences between the various matgwinc implementations that currently generate those curves. I think starting with the matlab-esque architecture has been helpful for that short-term goal.
However, pygwinc's architecture can certainly evolve in the future if there's a well motivated proposal.
Hey, Sean. Thank you very much for the comments and the very good points.
An object-based architecture would pretty clearly be better and more useful in all the ways you describe. We intend to move to a model like that over time, and would very much appreciate your input into how it evolves. But we've been playing a bit of a long game here.
There has been a lot of resistance to re-writing gwinc in python, with concern that doing so would fracture the development and maintenance effort. So the major concern initially has been to legitimize the project by starting with a rote copy of the code that we could easily validate against the existing matlab code. Once we've shown that the output is acceptably similar to what matlab produces, and we've gained some level of "certification" by the existing gwinc maintainers and users, then we could start slowing transforming the code into a more generally useful structure.
So for the moment we're focusing on validation with the existing matlab code. And we still have a bit more work to do to port over updated calculations. In the mean time we've been doing a fair bit of cleanup around the edges.
We welcome suggestions like this on where the architecture should go ultimately. Maybe we gather ideas into the wiki and start to outline a roadmap.
Thanks for the clarification. It's good to hear this will eventually be on the roadmap, but I understand the drive to make it first agree with MATLAB GWINC.
Gathering ideas together sounds good. I think there is going to be a fair bit of overlap in terms of bundled utilities (e.g. plotting, constants, I/O, etc.) between pygwinc, Finesse 3, and other Python tools like my LISO port (and maybe even e.g. Lee's vector fitting tool). All of them produce the same types of data, and it'd be useful to have the ability to combine the data they produce together programmatically. This is probably something just to keep in mind for now, since these tools are all at an early stage of development, but my dream is for all of these tools to one day work together so you can quickly hack out a control loop model or add together noises from different tools!
Sean, what you want is I am aiming for with my tool "Phasor" https://github.com/mccullerlp/phasor which can do combined optical/electrical/mechanical with closed loops and arbitrary shaped noise sources, with tagging of these sources so that output spectral densities are split into budgets.
While GWINC deserves some of this modularity for developer sanity, as a codebase it is really to have the minimal flexibility/parameterset to define an interferometer. Essentially so that users can make "official" curves with the lowest possibility of being wrong.
It would be better if GWINCs various noise calculations could be interfaced-with and exported in a sane way so that more powerful broad-spectrum integration tools can capture the official noise computations easily. This makes it so that fracture does not occur in this codebase, but rather in the developmental codebases of more advanced (and fragile) tools.
I don't see why pygwinc can't serve two functions: to spit out an official Advanced LIGO (or A+, or whatever) noise budget by default, but allow its calculations and parameters to be overridden. Such overrides (probably via subclassing) would be made from within the user's own projects, not pushed back into pygwinc, which, as we seem to agree, should just provide the standard calculations and utilities.
On the other hand, if you are suggesting that pygwinc should not even include the specific Advanced LIGO configuration, then I would probably agree with that. Then pygwinc would become two projects: gwinclib to provide the calculations and something else (let's call it ligogwinc) to plot the official LIGO budget.
I'm not advocating for pygwinc to contain all of the suggested plotting/data/export toolbox code (it's clear that other projects would also want to use such a library), but rather just to be compatible with it. The toolbox code could be its own project (that I would be happy to help work on).
Does Phasor already contain the data handling/plotting functionality I mentioned? If so, could you point me towards where in the source it is defined? Otherwise, I have a basic version of such a toolbox split across two projects that I could merge together if there is interest.
Ok, so the purpose of gwinc is somewhat up to preference. My worry about the GWINC code given its need to remain a "reference" fundamental noise calculator is simply that adding more and more noise sources with the flexibility to adjust all of them can really increase complexity even with good object-oriented design. On the other hand, the core function of GWINC to create a "noises" dictionary is incredibly simple and essentially all of the flexibility needed is encapsulated in a user creating a piece of code like:
and if you look inside gwinc.py much of the complexity currently existing is because various users wanted special cases (notably folded arms...). I think the best compromise is that each of those function calls should actually be a more configurable and granular class that users can modify. Users can then make merge requests that continue fragmenting those nominal-computation base classes to create an API that is modular in the correct way, while preserving the output of the nominal computations (since apriori we don't know how to split of the computations for every future use-case).
The configuration system can then use registration hooks and a dispatch mechanism to assemble the noise curves. I am doing this now in my upgrade to the quantum noise calculation (not yet finished)
which now removes the need for the various quantum noise schemes with optional "chaining" of filter cavities, instead one can configure a custom sequence
and this kind of dispatch is totally possible for other systems, and the typenames could be dispatched.
I think there is no need for a separate libgwinc and gwinc-plotter since the noise budget is such simple code. I think that as the code is cleaned up it will start to look modular in the right ways to use well as a library. I just think if we start wanting GWINC to be capable of loopology or things that Finesse/Optickle are better at then the underlying structure of the code becomes vastly more coupled, requiring linear solvers and a lot of bookkeeping.
as for phasor, it has an ACnoise output but it is returned in a dictionary keyed with all of the noise sources. An example output for a filter-cavity length noise study is
where you can see noise from VCOs and the NPRO powering the squeezer, as well as the suspension thermal noise which is just coming from johnson noise of the lossy springs defining the suspensions. All of it is hierarchically defined (unlike GWINC). You can see how the NPRO is created with a perfect laser, modulators and shaped noise from:
To clarify, I didn't intend for gwinc to be used within any loops - indeed there are better tools for that. I am just suggesting a way we can retain some of the positive features of MATLAB in the Python solution. One of the useful aspects of MATLAB - that I've seen many people use it for - is the ability to quickly combine together data from different tools to make a plot. You can copy and paste curves from separate plots to create a new plot. This is not possible in Matplotlib as far as I know. However, we can provide such functionality (arguably in a better form) by allowing the underlying data objects to be combined and then saved/plotted/whatever. As long as the metadata is carried along with the data, it will work quite nicely with data from multiple sources.
Regarding the system you suggest: that looks reasonable, though I must admit I still prefer encouraging people to subclass to build their own models rather than submitting their calculations to core gwinc. It could work if your configuration file approach extends to the core calculations themselves, such that one could e.g. use a different quantum noise model entirely. If not, then this may be facilitated by providing not only hooks like you propose to implement, but also filter callbacks for the data each built-in calculation produces.
I'm not sure relying on pull requests to add core functionality will work so well. Most people only reluctantly use version control, or may be reluctant to polish their code enough to be included in the standard gwinc release. It seems to me that it would be better for gwinc to encourage unofficial extension by whoever wants to do so, and discourage them from changing core gwinc code in any way (enforced by distributing via package manager rather than svn checkout or zip file). If we encouraged users by way of example to first subclass an abstract base class containing all the standard calculations, then any changes the user would make would be clearly unofficial.