Adds ability to forward noises from sub-budgets into higher level budget
This adds the ability to extract noises and calibrations from a list of sub-budgets and forward them to an upper level budget, as was done in !128 (closed). However, @christopher.wipf suggested a different implementation. That suggestion was not general enough though (it only worked for a single sub-budget and not a list of sub-budgets). Here I loop through his suggestion and further generalize it to work with dicts as well as lists. We'll need this by hook or by crook for the new quantum calculations.
Examples of this forwarding are given in the unit test test_forward_noises
in test/budgets/test_budgets.py They use the budgets H1NoRefsForwardNoises
and H1dictNoRefsForwardNoises
defined in the H1 intereferometer in that directory.
As a simple example using the exact same API as in !128 (closed) and used in all of the new quantum code,
class Quantum(nb.Budget):
noises = [
(Shot, Sensing),
RadiationPressure,
]
class MainBudget(nb.Budget):
noises = [
Thermal,
]
noises_forward = [
Quantum,
]
Defined like this the main budget will have shot noise, radiation pressure, and thermal noise even though the two quantum noises are grouped in their own sub-budget. If MainBudget
had been defined with Quantum
in the list of noises with Thermal
instead, the main budget would only have the total quantum and thermal noises, and the quantum noise would be further broken up into a quantum sub-budget with shot noise and radiation pressure noise.
An alternative approach, which would need to be modified to support dicts directly and which I don't like as much, was implemented in the commit 15ac555e and is almost exactly Chris' suggestion. Instead of the above which very slightly modifies the nb.Budget
init, the same behavior is produced without modifying nb.Budget
with
def forward_noises(subbudgets):
noises_frwd = []
for budget in subbudgets:
if not isinstance(budget, (tuple, list)):
budget = (budget,)
b = budget[0]
cals = tuple(budget[1:])
cals += tuple(b.calibrations)
noises_frwd.extend([
n + cals if isinstance(n, (tuple, list))
else (n,) + cals for n in b.noises
])
return noises_frwd
class MainBudget(Budget):
noises = [
Thermal,
]
noises += forward_noises([
Quantum,
])