pyGSTi 0.9.12__cp38-cp38-win_amd64.whl → 0.9.13__cp38-cp38-win_amd64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (225) hide show
  1. pyGSTi-0.9.13.dist-info/METADATA +185 -0
  2. {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/RECORD +211 -220
  3. {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/WHEEL +1 -1
  4. pygsti/_version.py +2 -2
  5. pygsti/algorithms/contract.py +1 -1
  6. pygsti/algorithms/core.py +62 -35
  7. pygsti/algorithms/fiducialpairreduction.py +95 -110
  8. pygsti/algorithms/fiducialselection.py +17 -8
  9. pygsti/algorithms/gaugeopt.py +2 -2
  10. pygsti/algorithms/germselection.py +87 -77
  11. pygsti/algorithms/mirroring.py +0 -388
  12. pygsti/algorithms/randomcircuit.py +165 -1333
  13. pygsti/algorithms/rbfit.py +0 -234
  14. pygsti/baseobjs/basis.py +94 -396
  15. pygsti/baseobjs/errorgenbasis.py +0 -132
  16. pygsti/baseobjs/errorgenspace.py +0 -10
  17. pygsti/baseobjs/label.py +52 -168
  18. pygsti/baseobjs/opcalc/fastopcalc.cp38-win_amd64.pyd +0 -0
  19. pygsti/baseobjs/opcalc/fastopcalc.pyx +2 -2
  20. pygsti/baseobjs/polynomial.py +13 -595
  21. pygsti/baseobjs/protectedarray.py +72 -132
  22. pygsti/baseobjs/statespace.py +1 -0
  23. pygsti/circuits/__init__.py +1 -1
  24. pygsti/circuits/circuit.py +753 -504
  25. pygsti/circuits/circuitconstruction.py +0 -4
  26. pygsti/circuits/circuitlist.py +47 -5
  27. pygsti/circuits/circuitparser/__init__.py +8 -8
  28. pygsti/circuits/circuitparser/fastcircuitparser.cp38-win_amd64.pyd +0 -0
  29. pygsti/circuits/circuitstructure.py +3 -3
  30. pygsti/circuits/cloudcircuitconstruction.py +27 -14
  31. pygsti/data/datacomparator.py +4 -9
  32. pygsti/data/dataset.py +51 -46
  33. pygsti/data/hypothesistest.py +0 -7
  34. pygsti/drivers/bootstrap.py +0 -49
  35. pygsti/drivers/longsequence.py +46 -10
  36. pygsti/evotypes/basereps_cython.cp38-win_amd64.pyd +0 -0
  37. pygsti/evotypes/chp/opreps.py +0 -61
  38. pygsti/evotypes/chp/statereps.py +0 -32
  39. pygsti/evotypes/densitymx/effectcreps.cpp +9 -10
  40. pygsti/evotypes/densitymx/effectreps.cp38-win_amd64.pyd +0 -0
  41. pygsti/evotypes/densitymx/effectreps.pyx +1 -1
  42. pygsti/evotypes/densitymx/opreps.cp38-win_amd64.pyd +0 -0
  43. pygsti/evotypes/densitymx/opreps.pyx +2 -2
  44. pygsti/evotypes/densitymx/statereps.cp38-win_amd64.pyd +0 -0
  45. pygsti/evotypes/densitymx/statereps.pyx +1 -1
  46. pygsti/evotypes/densitymx_slow/effectreps.py +7 -23
  47. pygsti/evotypes/densitymx_slow/opreps.py +16 -23
  48. pygsti/evotypes/densitymx_slow/statereps.py +10 -3
  49. pygsti/evotypes/evotype.py +39 -2
  50. pygsti/evotypes/stabilizer/effectreps.cp38-win_amd64.pyd +0 -0
  51. pygsti/evotypes/stabilizer/effectreps.pyx +0 -4
  52. pygsti/evotypes/stabilizer/opreps.cp38-win_amd64.pyd +0 -0
  53. pygsti/evotypes/stabilizer/opreps.pyx +0 -4
  54. pygsti/evotypes/stabilizer/statereps.cp38-win_amd64.pyd +0 -0
  55. pygsti/evotypes/stabilizer/statereps.pyx +1 -5
  56. pygsti/evotypes/stabilizer/termreps.cp38-win_amd64.pyd +0 -0
  57. pygsti/evotypes/stabilizer/termreps.pyx +0 -7
  58. pygsti/evotypes/stabilizer_slow/effectreps.py +0 -22
  59. pygsti/evotypes/stabilizer_slow/opreps.py +0 -4
  60. pygsti/evotypes/stabilizer_slow/statereps.py +0 -4
  61. pygsti/evotypes/statevec/effectreps.cp38-win_amd64.pyd +0 -0
  62. pygsti/evotypes/statevec/effectreps.pyx +1 -1
  63. pygsti/evotypes/statevec/opreps.cp38-win_amd64.pyd +0 -0
  64. pygsti/evotypes/statevec/opreps.pyx +2 -2
  65. pygsti/evotypes/statevec/statereps.cp38-win_amd64.pyd +0 -0
  66. pygsti/evotypes/statevec/statereps.pyx +1 -1
  67. pygsti/evotypes/statevec/termreps.cp38-win_amd64.pyd +0 -0
  68. pygsti/evotypes/statevec/termreps.pyx +0 -7
  69. pygsti/evotypes/statevec_slow/effectreps.py +0 -3
  70. pygsti/evotypes/statevec_slow/opreps.py +0 -5
  71. pygsti/extras/__init__.py +0 -1
  72. pygsti/extras/drift/signal.py +1 -1
  73. pygsti/extras/drift/stabilityanalyzer.py +3 -1
  74. pygsti/extras/interpygate/__init__.py +12 -0
  75. pygsti/extras/interpygate/core.py +0 -36
  76. pygsti/extras/interpygate/process_tomography.py +44 -10
  77. pygsti/extras/rpe/rpeconstruction.py +0 -2
  78. pygsti/forwardsims/__init__.py +1 -0
  79. pygsti/forwardsims/forwardsim.py +50 -93
  80. pygsti/forwardsims/mapforwardsim.py +78 -20
  81. pygsti/forwardsims/mapforwardsim_calc_densitymx.cp38-win_amd64.pyd +0 -0
  82. pygsti/forwardsims/mapforwardsim_calc_densitymx.pyx +65 -66
  83. pygsti/forwardsims/mapforwardsim_calc_generic.py +91 -13
  84. pygsti/forwardsims/matrixforwardsim.py +72 -17
  85. pygsti/forwardsims/termforwardsim.py +9 -111
  86. pygsti/forwardsims/termforwardsim_calc_stabilizer.cp38-win_amd64.pyd +0 -0
  87. pygsti/forwardsims/termforwardsim_calc_statevec.cp38-win_amd64.pyd +0 -0
  88. pygsti/forwardsims/termforwardsim_calc_statevec.pyx +0 -651
  89. pygsti/forwardsims/torchfwdsim.py +265 -0
  90. pygsti/forwardsims/weakforwardsim.py +2 -2
  91. pygsti/io/__init__.py +1 -2
  92. pygsti/io/mongodb.py +0 -2
  93. pygsti/io/stdinput.py +6 -22
  94. pygsti/layouts/copalayout.py +10 -12
  95. pygsti/layouts/distlayout.py +0 -40
  96. pygsti/layouts/maplayout.py +103 -25
  97. pygsti/layouts/matrixlayout.py +99 -60
  98. pygsti/layouts/prefixtable.py +1534 -52
  99. pygsti/layouts/termlayout.py +1 -1
  100. pygsti/modelmembers/instruments/instrument.py +3 -3
  101. pygsti/modelmembers/instruments/tpinstrument.py +2 -2
  102. pygsti/modelmembers/modelmember.py +0 -17
  103. pygsti/modelmembers/operations/__init__.py +3 -4
  104. pygsti/modelmembers/operations/affineshiftop.py +206 -0
  105. pygsti/modelmembers/operations/composederrorgen.py +1 -1
  106. pygsti/modelmembers/operations/composedop.py +1 -24
  107. pygsti/modelmembers/operations/denseop.py +5 -5
  108. pygsti/modelmembers/operations/eigpdenseop.py +2 -2
  109. pygsti/modelmembers/operations/embeddederrorgen.py +1 -1
  110. pygsti/modelmembers/operations/embeddedop.py +0 -1
  111. pygsti/modelmembers/operations/experrorgenop.py +5 -2
  112. pygsti/modelmembers/operations/fullarbitraryop.py +1 -0
  113. pygsti/modelmembers/operations/fullcptpop.py +2 -2
  114. pygsti/modelmembers/operations/fulltpop.py +28 -6
  115. pygsti/modelmembers/operations/fullunitaryop.py +5 -4
  116. pygsti/modelmembers/operations/lindbladcoefficients.py +93 -78
  117. pygsti/modelmembers/operations/lindbladerrorgen.py +268 -441
  118. pygsti/modelmembers/operations/linearop.py +7 -27
  119. pygsti/modelmembers/operations/opfactory.py +1 -1
  120. pygsti/modelmembers/operations/repeatedop.py +1 -24
  121. pygsti/modelmembers/operations/staticstdop.py +1 -1
  122. pygsti/modelmembers/povms/__init__.py +3 -3
  123. pygsti/modelmembers/povms/basepovm.py +7 -36
  124. pygsti/modelmembers/povms/complementeffect.py +4 -9
  125. pygsti/modelmembers/povms/composedeffect.py +0 -320
  126. pygsti/modelmembers/povms/computationaleffect.py +1 -1
  127. pygsti/modelmembers/povms/computationalpovm.py +3 -1
  128. pygsti/modelmembers/povms/effect.py +3 -5
  129. pygsti/modelmembers/povms/marginalizedpovm.py +3 -81
  130. pygsti/modelmembers/povms/tppovm.py +74 -2
  131. pygsti/modelmembers/states/__init__.py +2 -5
  132. pygsti/modelmembers/states/composedstate.py +0 -317
  133. pygsti/modelmembers/states/computationalstate.py +3 -3
  134. pygsti/modelmembers/states/cptpstate.py +4 -4
  135. pygsti/modelmembers/states/densestate.py +10 -8
  136. pygsti/modelmembers/states/fullpurestate.py +0 -24
  137. pygsti/modelmembers/states/purestate.py +1 -1
  138. pygsti/modelmembers/states/state.py +5 -6
  139. pygsti/modelmembers/states/tpstate.py +28 -10
  140. pygsti/modelmembers/term.py +3 -6
  141. pygsti/modelmembers/torchable.py +50 -0
  142. pygsti/modelpacks/_modelpack.py +1 -1
  143. pygsti/modelpacks/smq1Q_ZN.py +3 -1
  144. pygsti/modelpacks/smq2Q_XXYYII.py +2 -1
  145. pygsti/modelpacks/smq2Q_XY.py +3 -3
  146. pygsti/modelpacks/smq2Q_XYI.py +2 -2
  147. pygsti/modelpacks/smq2Q_XYICNOT.py +3 -3
  148. pygsti/modelpacks/smq2Q_XYICPHASE.py +3 -3
  149. pygsti/modelpacks/smq2Q_XYXX.py +1 -1
  150. pygsti/modelpacks/smq2Q_XYZICNOT.py +3 -3
  151. pygsti/modelpacks/smq2Q_XYZZ.py +1 -1
  152. pygsti/modelpacks/stdtarget.py +0 -121
  153. pygsti/models/cloudnoisemodel.py +1 -2
  154. pygsti/models/explicitcalc.py +3 -3
  155. pygsti/models/explicitmodel.py +3 -13
  156. pygsti/models/fogistore.py +5 -3
  157. pygsti/models/localnoisemodel.py +1 -2
  158. pygsti/models/memberdict.py +0 -12
  159. pygsti/models/model.py +801 -68
  160. pygsti/models/modelconstruction.py +4 -4
  161. pygsti/models/modelnoise.py +2 -2
  162. pygsti/models/modelparaminterposer.py +1 -1
  163. pygsti/models/oplessmodel.py +1 -1
  164. pygsti/models/qutrit.py +15 -14
  165. pygsti/objectivefns/objectivefns.py +75 -140
  166. pygsti/objectivefns/wildcardbudget.py +2 -7
  167. pygsti/optimize/__init__.py +1 -0
  168. pygsti/optimize/arraysinterface.py +28 -0
  169. pygsti/optimize/customcg.py +0 -12
  170. pygsti/optimize/customlm.py +129 -323
  171. pygsti/optimize/customsolve.py +2 -2
  172. pygsti/optimize/optimize.py +0 -84
  173. pygsti/optimize/simplerlm.py +841 -0
  174. pygsti/optimize/wildcardopt.py +19 -598
  175. pygsti/protocols/confidenceregionfactory.py +28 -14
  176. pygsti/protocols/estimate.py +31 -14
  177. pygsti/protocols/gst.py +238 -142
  178. pygsti/protocols/modeltest.py +19 -12
  179. pygsti/protocols/protocol.py +9 -37
  180. pygsti/protocols/rb.py +450 -79
  181. pygsti/protocols/treenode.py +8 -2
  182. pygsti/protocols/vb.py +108 -206
  183. pygsti/protocols/vbdataframe.py +1 -1
  184. pygsti/report/factory.py +0 -15
  185. pygsti/report/fogidiagram.py +1 -17
  186. pygsti/report/modelfunction.py +12 -3
  187. pygsti/report/mpl_colormaps.py +1 -1
  188. pygsti/report/plothelpers.py +11 -3
  189. pygsti/report/report.py +16 -0
  190. pygsti/report/reportables.py +41 -37
  191. pygsti/report/templates/offline/pygsti_dashboard.css +6 -0
  192. pygsti/report/templates/offline/pygsti_dashboard.js +12 -0
  193. pygsti/report/workspace.py +2 -14
  194. pygsti/report/workspaceplots.py +328 -505
  195. pygsti/tools/basistools.py +9 -36
  196. pygsti/tools/edesigntools.py +124 -96
  197. pygsti/tools/fastcalc.cp38-win_amd64.pyd +0 -0
  198. pygsti/tools/fastcalc.pyx +35 -81
  199. pygsti/tools/internalgates.py +151 -15
  200. pygsti/tools/jamiolkowski.py +5 -5
  201. pygsti/tools/lindbladtools.py +19 -11
  202. pygsti/tools/listtools.py +0 -114
  203. pygsti/tools/matrixmod2.py +1 -1
  204. pygsti/tools/matrixtools.py +173 -339
  205. pygsti/tools/nameddict.py +1 -1
  206. pygsti/tools/optools.py +154 -88
  207. pygsti/tools/pdftools.py +0 -25
  208. pygsti/tools/rbtheory.py +3 -320
  209. pygsti/tools/slicetools.py +64 -12
  210. pyGSTi-0.9.12.dist-info/METADATA +0 -157
  211. pygsti/algorithms/directx.py +0 -711
  212. pygsti/evotypes/qibo/__init__.py +0 -33
  213. pygsti/evotypes/qibo/effectreps.py +0 -78
  214. pygsti/evotypes/qibo/opreps.py +0 -376
  215. pygsti/evotypes/qibo/povmreps.py +0 -98
  216. pygsti/evotypes/qibo/statereps.py +0 -174
  217. pygsti/extras/rb/__init__.py +0 -13
  218. pygsti/extras/rb/benchmarker.py +0 -957
  219. pygsti/extras/rb/dataset.py +0 -378
  220. pygsti/extras/rb/io.py +0 -814
  221. pygsti/extras/rb/simulate.py +0 -1020
  222. pygsti/io/legacyio.py +0 -385
  223. pygsti/modelmembers/povms/denseeffect.py +0 -142
  224. {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/LICENSE +0 -0
  225. {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/top_level.txt +0 -0
@@ -13,6 +13,7 @@ ModelTest Protocol objects
13
13
  import collections as _collections
14
14
  import warnings as _warnings
15
15
  import pathlib as _pathlib
16
+ from typing import Optional
16
17
  from pygsti.baseobjs.profiler import DummyProfiler as _DummyProfiler
17
18
  from pygsti.objectivefns.objectivefns import ModelDatasetCircuitsStore as _ModelDatasetCircuitStore
18
19
  from pygsti.protocols.estimate import Estimate as _Estimate
@@ -23,6 +24,7 @@ from pygsti.objectivefns import objectivefns as _objfns
23
24
  from pygsti.circuits import Circuit
24
25
  from pygsti.circuits.circuitlist import CircuitList as _CircuitList
25
26
  from pygsti.baseobjs.resourceallocation import ResourceAllocation as _ResourceAllocation
27
+ from pygsti.forwardsims import ForwardSimulator
26
28
 
27
29
 
28
30
  class ModelTest(_proto.Protocol):
@@ -98,6 +100,7 @@ class ModelTest(_proto.Protocol):
98
100
  set_trivial_gauge_group=True, verbosity=2, name=None):
99
101
 
100
102
  from .gst import GSTBadFitOptions as _GSTBadFitOptions
103
+ from .gst import GSTGaugeOptSuite as _GSTGaugeOptSuite
101
104
 
102
105
  if set_trivial_gauge_group:
103
106
  model_to_test = model_to_test.copy()
@@ -107,7 +110,7 @@ class ModelTest(_proto.Protocol):
107
110
  super().__init__(name)
108
111
  self.model_to_test = model_to_test
109
112
  self.target_model = target_model
110
- self.gaugeopt_suite = gaugeopt_suite
113
+ self.gaugeopt_suite = _GSTGaugeOptSuite.cast(gaugeopt_suite)
111
114
  self.badfit_options = _GSTBadFitOptions.cast(badfit_options)
112
115
  self.verbosity = verbosity
113
116
 
@@ -125,13 +128,8 @@ class ModelTest(_proto.Protocol):
125
128
  self.circuit_weights = None
126
129
  self.unreliable_ops = ('Gcnot', 'Gcphase', 'Gms', 'Gcn', 'Gcx', 'Gcz')
127
130
 
128
- #def run_using_germs_and_fiducials(self, model, dataset, target_model, prep_fiducials,
129
- # meas_fiducials, germs, maxLengths):
130
- # from .gst import StandardGSTDesign as _StandardGSTDesign
131
- # design = _StandardGSTDesign(target_model, prep_fiducials, meas_fiducials, germs, maxLengths)
132
- # return self.run(_proto.ProtocolData(design, dataset))
133
-
134
- def run(self, data, memlimit=None, comm=None, checkpoint=None, checkpoint_path=None, disable_checkpointing= False):
131
+ def run(self, data, memlimit=None, comm=None, checkpoint=None, checkpoint_path=None, disable_checkpointing=False,
132
+ simulator: Optional[ForwardSimulator.Castable]=None):
135
133
  """
136
134
  Run this protocol on `data`.
137
135
 
@@ -164,12 +162,19 @@ class ModelTest(_proto.Protocol):
164
162
  to disk during the course of this protocol. It is strongly recommended
165
163
  that this be kept set to False without good reason to disable the checkpoints.
166
164
 
165
+ simulator : ForwardSimulator.Castable or None
166
+ Ignored if None. If not None, then we call
167
+ fwdsim = ForwardSimulator.cast(simulator),
168
+ and we set the .sim attribute of every Model we encounter to fwdsim.
169
+
167
170
  Returns
168
171
  -------
169
172
  ModelEstimateResults
170
173
  """
171
174
  the_model = self.model_to_test
172
-
175
+ if simulator is not None:
176
+ the_model.sim = simulator
177
+
173
178
  target_model = self.target_model # can be None; target model isn't necessary
174
179
 
175
180
  #Create profiler
@@ -267,11 +272,13 @@ class ModelTest(_proto.Protocol):
267
272
  models.update({('iteration %d estimate' % k): the_model for k in range(len(bulk_circuit_lists))})
268
273
  # TODO: come up with better key names? and must we have iteration_estimates?
269
274
  if target_model is not None:
275
+ if simulator is not None:
276
+ target_model.sim = simulator
270
277
  models['target'] = target_model
271
278
  ret.add_estimate(_Estimate(ret, models, parameters, extra_parameters=extra_parameters), estimate_key=self.name)
272
279
 
273
- #Add some better handling for when gauge optimization is turned off (current code path isn't working.
274
- if self.gaugeopt_suite is not None:
280
+ #Add some better handling for when gauge optimization is turned off (current code path isn't working.)
281
+ if not self.gaugeopt_suite.is_empty():
275
282
  ret= _add_gaugeopt_and_badfit(ret, self.name, target_model, self.gaugeopt_suite,
276
283
  self.unreliable_ops, self.badfit_options,
277
284
  None, resource_alloc, printer)
@@ -282,8 +289,8 @@ class ModelTest(_proto.Protocol):
282
289
  #and add a key for this to the goparameters dict (this is what the report
283
290
  #generation looks at to determine the names of the gauge optimized models).
284
291
  #Set the value to None as a placeholder.
285
- from .gst import GSTGaugeOptSuite
286
292
  ret.estimates[self.name].goparameters['trivial_gauge_opt']= None
293
+
287
294
  return ret
288
295
 
289
296
 
@@ -1311,11 +1311,17 @@ class CombinedExperimentDesign(ExperimentDesign): # for multiple designs on the
1311
1311
 
1312
1312
  if all_circuits is None:
1313
1313
  all_circuits = []
1314
- if not interleave:
1314
+ if interleave:
1315
+ subdesign_circuit_lists = [sub_design.all_circuits_needing_data for sub_design in sub_designs.values()]
1316
+ #zip_longest is like zip, but if the iterables are of different lengths it returns a specified fill value
1317
+ #(default None) in place of the missing elements once an iterable has been exhausted.
1318
+ for circuits in _itertools.zip_longest(*subdesign_circuit_lists):
1319
+ for circuit in circuits:
1320
+ if circuit is not None:
1321
+ all_circuits.append(circuit)
1322
+ else:
1315
1323
  for des in sub_designs.values():
1316
1324
  all_circuits.extend(des.all_circuits_needing_data)
1317
- else:
1318
- raise NotImplementedError("Interleaving not implemented yet")
1319
1325
  _lt.remove_duplicates_in_place(all_circuits) # Maybe don't always do this?
1320
1326
 
1321
1327
  if qubit_labels is None and len(sub_designs) > 0:
@@ -1458,12 +1464,6 @@ class SimultaneousExperimentDesign(ExperimentDesign):
1458
1464
  else:
1459
1465
  raise ValueError("Cannot convert a %s to a %s!" % (str(type(edesign)), str(cls)))
1460
1466
 
1461
- #@classmethod
1462
- #def from_tensored_circuits(cls, circuits, template_edesign, qubit_labels_per_edesign):
1463
- # pass #Useful??? - need to break each circuit into different parts
1464
- # based on qubits, then copy (?) template edesign and just replace itself
1465
- # all_circuits_needing_data member?
1466
-
1467
1467
  def __init__(self, edesigns, tensored_circuits=None, qubit_labels=None):
1468
1468
  """
1469
1469
  Create a new SimultaneousExperimentDesign object.
@@ -1953,9 +1953,6 @@ class ProtocolData(_TreeNode, _MongoSerializable):
1953
1953
  """
1954
1954
  return isinstance(self.dataset, (_data.MultiDataSet, dict))
1955
1955
 
1956
- #def underlying_tree_paths(self):
1957
- # return self.edesign.get_tree_paths()
1958
-
1959
1956
  def prune_tree(self, paths, paths_are_sorted=False):
1960
1957
  """
1961
1958
  Prune the tree rooted here to include only the given paths, discarding all else.
@@ -2545,23 +2542,6 @@ class ProtocolResultsDir(_TreeNode, _MongoSerializable):
2545
2542
 
2546
2543
  2. Child :class:`ProtocolResultsDir` objects, obtained by indexing this
2547
2544
  object directly using the name of the sub-directory.
2548
-
2549
- Parameters
2550
- ----------
2551
- data : ProtocolData
2552
- The data from which *all* the Results objects in this
2553
- ProtocolResultsDir are derived.
2554
-
2555
- protocol_results : ProtocolResults, optional
2556
- An initial (single) results object to add. The name of the
2557
- results object is used as its key within the `.for_protocol`
2558
- dictionary. If None, then an empty results directory is created.
2559
-
2560
- children : dict, optional
2561
- A dictionary of the :class:`ProtocolResultsDir` objects that are
2562
- sub-directories beneath this one. If None, then children are
2563
- automatically created based upon the tree given by `data`. (To
2564
- avoid creating any children, you can pass an empty dict here.)
2565
2545
  """
2566
2546
  collection_name = "pygsti_results_directories"
2567
2547
 
@@ -2681,14 +2661,6 @@ class ProtocolResultsDir(_TreeNode, _MongoSerializable):
2681
2661
  """
2682
2662
  Create a new ProtocolResultsDir object.
2683
2663
 
2684
- This container object holds two things:
2685
-
2686
- 1. A `.for_protocol` dictionary of :class:`ProtocolResults` corresponding
2687
- to different protocols (keys are protocol names).
2688
-
2689
- 2. Child :class:`ProtocolResultsDir` objects, obtained by indexing this
2690
- object directly using the name of the sub-directory.
2691
-
2692
2664
  Parameters
2693
2665
  ----------
2694
2666
  data : ProtocolData