diff --git a/README.md b/README.md
index 1b780f37bec2d25cdc618e5a781fbc2512776139..bb04aa78fa18890846e377ab7bf34db91e3ff6a9 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ description is loaded, the noise budget can be calculated and plotted:
 >>> freq = np.logspace(1, 3, 1000)
 >>> Budget = gwinc.load_budget('aLIGO')
 >>> ifo = gwinc.precompIFO(freq, Budget.ifo)
->>> traces = Budget(freq, ifo=ifo).calc_trace()
+>>> traces = Budget(freq, ifo=ifo).run()
 >>> fig = gwinc.plot_noise(freq, traces)
 >>> fig.show()
 ```
diff --git a/gwinc/__init__.py b/gwinc/__init__.py
index 18ca39b109251662e0b6f08d299e5b9206bb0bed..3347d489b628bd714fda268127e032d11db8031b 100644
--- a/gwinc/__init__.py
+++ b/gwinc/__init__.py
@@ -113,7 +113,7 @@ def gwinc(freq, ifo, source=None, plot=False, PRfixed=True):
     # from just ifo description, without having to specify full budget
     Budget = load_budget('aLIGO')
     ifo = precompIFO(freq, ifo, PRfixed)
-    traces = Budget(freq, ifo=ifo).calc_trace()
+    traces = Budget(freq, ifo=ifo).run()
     plot_style = getattr(Budget, 'plot_style', {})
 
     # construct matgwinc-compatible noises structure
diff --git a/gwinc/__main__.py b/gwinc/__main__.py
index d1c8194308dad366934c57bf63a1edb48c422f8c..d6b220f38d919c0f1f76e288dbf1c11ca3b746a2 100644
--- a/gwinc/__main__.py
+++ b/gwinc/__main__.py
@@ -179,10 +179,7 @@ def main():
             logging.info("precomputing ifo...")
             ifo = precompIFO(freq, ifo)
         logging.info("calculating budget...")
-        budget = Budget(freq=freq, ifo=ifo)
-        budget.load()
-        budget.update()
-        traces = budget.calc_trace()
+        traces = Budget(freq=freq, ifo=ifo).run()
 
     # logging.info('recycling factor: {: >0.3f}'.format(ifo.gwinc.prfactor))
     # logging.info('BS power:         {: >0.3f} W'.format(ifo.gwinc.pbs))
diff --git a/gwinc/nb.py b/gwinc/nb.py
index 9434ef13388a5e49a6543c002cb1d7d46120ede4..18c09a4dbfb6332e2b1dcf6f8aad5ccd7e9b2abd 100644
--- a/gwinc/nb.py
+++ b/gwinc/nb.py
@@ -32,7 +32,7 @@ class BudgetItem:
         return None
 
     def update(self, **kwargs):
-        """Overload method for updating data needed to calculate final PSD.
+        """Overload method for updating data.
 
         By default any keyword arguments provided are written directly
         as attribute variables (as with __init__).
@@ -42,7 +42,7 @@ class BudgetItem:
             setattr(self, key, val)
 
     def calc(self):
-        """Overload method for calculation of final PSD.
+        """Overload method for final PSD calculation.
 
         Should return an array of power-referenced values evaluated at
         all evaluation frequencies (self.freq).
@@ -152,6 +152,17 @@ class Noise(BudgetItem):
             data = None
         return data, self.style
 
+    def run(self, **kwargs):
+        """Convenience method to load, update, and return calc traces.
+
+        Equivalent of load(), update(), calc_traces() run in sequence.
+        Keyword arguments are passed to update().
+
+        """
+        self.load()
+        self.update(**kwargs)
+        return self.calc_trace()
+
 
 class Budget(Noise):
     """GWINC Budget class