@@ -113,43 +113,43 @@ def create_processor_spec(pcircuit, qubit_labels, gates=['Gcnot','Gh']):
113113
114114 return pspec
115115
116- def build_model (error_rates , pspec ):
117- """
118- Creates a *spatially homogeneous* error model from
119- the given error rates dictionary. Could easily be generalized to
120- spatially inhomogeneous errors. Works only for a
121- gate set of only Gh and Gcnot.
122- """
123- ######TODO: GENERALIZE TO OTHER MODELS########
124- oneQ_gate_names = ['Gh' , ]
125- twoQ_gate_names = ['Gcnot' , ]
126- gate_dictionary = dict ()
116+ # def build_model(error_rates, pspec):
117+ # """
118+ # Creates a *spatially homogeneous* error model from
119+ # the given error rates dictionary. Could easily be generalized to
120+ # spatially inhomogeneous errors. Works only for a
121+ # gate set of only Gh and Gcnot.
122+ # """
123+ # ######TODO: GENERALIZE TO OTHER MODELS########
124+ # oneQ_gate_names = ['Gh', ]
125+ # twoQ_gate_names = ['Gcnot', ]
126+ # gate_dictionary = dict()
127127
128128
129- def create_gate_object (erates , num_qubits , gate_name ):
130- state_space = QubitSpace (num_qubits )
131- lindblad_errorgen = LindbladErrorgen .from_elementary_errorgens (erates ,
132- state_space = state_space ,
133- evotype = 'stabilizer' )
134- perfect_gate = StaticCliffordOp (pspec .gate_unitaries [gate_name ], evotype = 'stabilizer' )
135- exp_errorgen = ExpErrorgenOp (lindblad_errorgen )
136- gate_mm = ComposedOp ([perfect_gate , exp_errorgen ])
137- return gate_mm
129+ # def create_gate_object(erates, num_qubits, gate_name):
130+ # state_space = QubitSpace(num_qubits)
131+ # lindblad_errorgen = LindbladErrorgen.from_elementary_errorgens(erates,
132+ # state_space=state_space,
133+ # evotype='stabilizer')
134+ # perfect_gate = StaticCliffordOp(pspec.gate_unitaries[gate_name], evotype='stabilizer')
135+ # exp_errorgen = ExpErrorgenOp(lindblad_errorgen)
136+ # gate_mm = ComposedOp([perfect_gate, exp_errorgen])
137+ # return gate_mm
138138
139- for i , gate_name in enumerate (oneQ_gate_names ):
140- for j , q in enumerate (pspec .qubit_labels ):
141- label = pygsti .baseobjs .label .Label (gate_name , q )
142- gate_dictionary [label ] = create_gate_object (error_rates [gate_name ], 1 , gate_name )
143-
144- for i , gate_name in enumerate (twoQ_gate_names ):
145- for j , qs in enumerate (pspec .availability [gate_name ]):
146- label = pygsti .baseobjs .label .Label (gate_name , qs )
147- gate_dictionary [label ] = create_gate_object (error_rates [gate_name ], 2 , gate_name )
139+ # for i, gate_name in enumerate(oneQ_gate_names):
140+ # for j, q in enumerate(pspec.qubit_labels):
141+ # label = pygsti.baseobjs.label.Label(gate_name, q)
142+ # gate_dictionary[label] = create_gate_object(error_rates[gate_name], 1, gate_name)
143+
144+ # for i, gate_name in enumerate(twoQ_gate_names):
145+ # for j, qs in enumerate(pspec.availability[gate_name]):
146+ # label = pygsti.baseobjs.label.Label(gate_name, qs)
147+ # gate_dictionary[label] = create_gate_object(error_rates[gate_name], 2, gate_name)
148148
149- prep_layers = None
150- povm_layers = None
151- model = LocalNoiseModel (pspec , gate_dictionary , prep_layers , povm_layers , evotype = 'stabilizer' )
152- return model
149+ # prep_layers = None
150+ # povm_layers = None
151+ # model = LocalNoiseModel(pspec, gate_dictionary, prep_layers, povm_layers, evotype='stabilizer')
152+ # return model
153153
154154import numpy as np
155155import stim
@@ -264,7 +264,7 @@ def create_processor_spec(pcircuit, qubit_labels, gates=['Gcnot','Gh']):
264264 # Find all the CNOT gates used in the circuit, using brute force string comprehension
265265 cleaned_pcstr = pyg_cstr .replace (']' , '' ).replace ('[' , '' ).split ('@' )[0 ]
266266 connections = [(int (s .split (':' )[1 ]), int (s .split (':' )[2 ])) for s in cleaned_pcstr .split ('G' ) if len (s .split (':' )) > 2 ]
267- availability = {'Gcnot' :connections }
267+ availability = {'Gcnot' :connections , 'Gcphase' : connections }
268268 pspec = pygsti .processors .QubitProcessorSpec (len (qubit_labels ), gates , qubit_labels = qubit_labels ,
269269 availability = availability )
270270
@@ -338,7 +338,7 @@ def parse_pauli_product(prod, current_qubit_mapping):
338338 return (pauli_string , qubits )
339339
340340
341- def stim_to_pygsti_circuit (circuit , qubit_labels , qubit_relabelling_dict = None , show_qubit_mappings = False , include_observables = False , include_idles = False ):
341+ def stim_to_pygsti_circuit (circuit , qubit_labels , qubit_relabelling_dict = None , show_qubit_mappings = False , include_observables = False , separate_observables = False , include_idles = False ):
342342
343343 if qubit_relabelling_dict is None :
344344 qubit_relabelling_dict = {q :q for q in qubit_labels }
@@ -347,6 +347,7 @@ def stim_to_pygsti_circuit(circuit, qubit_labels, qubit_relabelling_dict=None, s
347347
348348 measurements = []
349349 detectors = []
350+ observable_detectors = []
350351
351352 def convert_1q_layer (gatename , stim_layer_string , current_qubit_mapping ):
352353 gate_dict = {'H' :'Gh' ,
@@ -437,19 +438,35 @@ def update_qubit_mapping(line, current_qubit_mapping, qubit_labels):
437438 targ = len (measurements )- 1 * rel_meas
438439 det .append (targ )
439440 detectors .append (det )
441+ # elif 'OBSERVABLE_INCLUDE' in line.split('(')[0]:
442+ # if not include_observables:
443+ # pass
444+ # else:
445+ # #TODO PROPERLY EXTRACT THE LABEL OF THE OBSERVABLE
446+ # #print(line)
447+ # det = []
448+ # for arg in line.split(' ')[1:]:
449+ # #get the ref number, it's negative, index into measurements
450+ # if 'rec' in arg:
451+ # rel_meas = int(re.findall(r'\[-(\d+)\]', arg)[0])
452+ # targ = len(measurements)-1*rel_meas
453+ # det.append(targ)
454+ # detectors.append(det)
440455 elif 'OBSERVABLE_INCLUDE' in line .split ('(' )[0 ]:
441- if not include_observables :
442- pass
443- else :
444- #print(line)
445- det = []
446- for arg in line .split (' ' )[1 :]:
447- #get the ref number, it's negative, index into measurements
448- if 'rec' in arg :
449- rel_meas = int (re .findall (r'\[-(\d+)\]' , arg )[0 ])
450- targ = len (measurements )- 1 * rel_meas
451- det .append (targ )
452- detectors .append (det )
456+ if include_observables :
457+ # Extract the integer j from OBSERVABLE_INCLUDE(j)
458+ match = re .search (r'OBSERVABLE_INCLUDE\((\d+)\)' , line )
459+ if match :
460+ j = int (match .group (1 ))
461+ if len (observable_detectors ) <= j :
462+ observable_detectors .append ([])
463+ # Extract measurement references from the line
464+ for arg in line .split (' ' )[1 :]:
465+ if 'rec' in arg :
466+ rel_meas = int (re .findall (r'\[-(\d+)\]' , arg )[0 ])
467+ targ = len (measurements ) - 1 * rel_meas
468+ observable_detectors [j ].append (targ )
469+
453470 elif 'TICK' in line .split (' ' ) or 'QUBIT_COORDS' or 'SHIFT_COORDS' in line .split (' ' ):
454471 pass
455472 else :
@@ -458,5 +475,11 @@ def update_qubit_mapping(line, current_qubit_mapping, qubit_labels):
458475 pyg_c = pygsti .circuits .Circuit ('' .join (gate_layers )+ '@(' + ',' .join ([str (q ) for q in range (1 + max (current_qubit_mapping .values ()))]) + ')' , editable = True )
459476 pyg_c .delete_idle_layers_inplace ()
460477 pyg_c .done_editing ()
478+
479+ if not separate_observables :
480+ detectors .extend (observable_detectors )
481+
482+ return pyg_c , current_qubit_mapping , measurements , detectors
461483
462- return pyg_c , current_qubit_mapping , measurements , detectors
484+ else :
485+ return pyg_c , current_qubit_mapping , measurements , detectors , observable_detectors
0 commit comments