Note

Click here to download the full example code

# Threshold detector probabilities of Gaussian states¶

*Author: Jake Bulmer (Xanadu Resident)*

Many quantum optics experiments use photon detectors which distinguish
between vacuum or non-vacuum events, often known as *threshold detectors*. We
sometimes describe the non-vacuum outcome as a ‘click’. Superconducting
nanowire single-photon detectors (SNSPDs)
and single-photon avalanche diodes (SPADs) are common examples of threshold detectors.

Here, we will show how we can calculate threshold detector probabilities for any Gaussian state. Let’s say we have an experiment where we create a two-mode squeezed vacuum (TMSV) state (more details on two-mode squeezing can be found here).

We can use Strawberry Fields to calculate the probability of Fock state projectors, e.g.,

```
p_fock11 = state.fock_prob([1, 1])
```

However, if we wish to see the probability of threshold detector outcomes, we must instead use a function from The Walrus library, which is installed alongside Strawberry Fields.

Because our state is Gaussian and we are using the Engine with the gaussian backend, we can get the Gaussian covariance matrix and displacement vector of our state.

```
mu = state.means()
cov = state.cov()
print(mu)
print(cov)
```

Out:

```
[0. 0. 0. 0.]
[[ 1.02006676 0.201336 0. 0. ]
[ 0.201336 1.02006676 0. 0. ]
[ 0. 0. 1.02006676 -0.201336 ]
[ 0. 0. -0.201336 1.02006676]]
```

These are then passed to the `threshold_detection_prob`

function,
which takes as arguments: the displacement vector, `mu`

, the covariance
matrix, `cov`

, and a list describing the detector outcomes. A vacuum outcome is
labelled as `0`

and a click is labelled by a `1`

. We pass in `[1, 1]`

to get
the probability that both of the two modes give a click from the threshold detectors.

```
from thewalrus import threshold_detection_prob
p_click11 = threshold_detection_prob(mu, cov, [1, 1])
print(f"single-photon coincidence probability = {p_fock11}")
print(f"click coincidence probability = {np.real_if_close(p_click11)}")
```

Out:

```
single-photon coincidence probability = 0.00983503057503257
click coincidence probability = 0.009933709152560139
```

We see that these probabilities are similar (both are close to 1%), but not the same. If we use a higher squeezing parameter, we can see that these probabilities diverge further.

```
prog = Program(2)
eng = Engine("gaussian")
with prog.context as q:
S2gate(1) | (q[0], q[1])
results = eng.run(prog)
state = results.state
p_fock11 = state.fock_prob([1, 1])
mu = state.means()
cov = state.cov()
p_click11 = threshold_detection_prob(mu, cov, [1, 1])
print(f"single-photon coincidence probability = {p_fock11}")
print(f"click coincidence probability = {p_click11.real}")
```

Out:

```
single-photon coincidence probability = 0.24359589399989143
click coincidence probability = 0.5800256583859738
```

We see that when we increase the squeezing, the click coincidence
probability increases much more than the single-photon coincidence
probability. This extra probability is due to higher-order Fock state
terms in the TMSV state. This extra probability is sometimes known as
*multiphoton contamination* because these higher-order terms mean that
our threshold detector statistics are no longer well-approximated by single-photon
projectors [1]. From this example, we can also see that multiphoton
contamination can be a more severe problem for high levels of squeezing.

Sometimes multiphoton contamination can be a problem. To see why, let’s investigate Hong-Ou-Mandel (HOM) interference [2] between photons from a TMSV state:

```
from strawberryfields.ops import BSgate
def HOM_probs(r):
prog = Program(2)
eng = Engine("gaussian")
with prog.context as q:
S2gate(r) | (q[0], q[1])
BSgate(0.25 * np.pi) | (q[0], q[1])
results = eng.run(prog)
state = results.state
p_fock = state.fock_prob([1, 1])
mu = state.means()
cov = state.cov()
p_click = threshold_detection_prob(mu, cov, [1, 1])
return p_fock, p_click
r = 0.1
p_fock, p_click = HOM_probs(r)
print(f"squeezing: r = {r}")
print(f"single-photon coincidence probability = {np.round(p_fock,14)}")
print(f"threshold detector coincidence probability = {np.round(p_click.real, 14)}")
r = 1
p_fock, p_click = HOM_probs(r)
print()
print(f"squeezing: r = {r}")
print(f"single-photon coincidence probability = {np.round(p_fock,14)}")
print(f"threshold detector coincidence probability = {np.round(p_click.real, 14)}")
```

Out:

```
squeezing: r = 0.1
single-photon coincidence probability = 0.0
threshold detector coincidence probability = 2.479294099e-05
squeezing: r = 1
single-photon coincidence probability = 0.0
threshold detector coincidence probability = 0.12386579428626
```

In ideal HOM interference, if we send two photons onto a 50/50 beamsplitter (a BSgate with \(\theta=\pi/4\) ), we should never see two photons at the output. To understand what is happening here, we should consider that TMSV creates correlated pairs of photons across its two modes. The HOM interference occurs perfectly when we have single-photon projectors, independent of what our squeezing parameter is. This is because we know exactly how many photons must have arrived at the beamsplitter. However, when we have threshold detectors, we cannot perfectly count the photons, so we cannot distinguish terms in the TMSV state. This leads to multiphoton contamination which degrades our interference. HOM interference underpins many important photonic protocols, e.g., Bell state measurement, and so degradation in the interference visibility can lead to poor fidelity of operations.

## Displaced Gaussian States¶

In the examples considered so far, we have only explored states which
contain no displacement. However, the `threshold_detection_prob`

function is compatible with displaced Gaussian states.

```
from strawberryfields.ops import Dgate
prog = Program(3)
eng = Engine("gaussian")
alpha = 1
r = 1
with prog.context as q:
S2gate(r) | (q[0], q[1])
Dgate(alpha) | q[2]
BSgate(0.25 * np.pi) | (q[1], q[2])
results = eng.run(prog)
state = results.state
p_fock = state.fock_prob([1, 1, 1])
mu = state.means()
cov = state.cov()
print(mu)
print(cov)
p_click = threshold_detection_prob(mu, cov, [1, 1, 1])
print(f"single-photon coincidence probability = {np.round(p_fock,14)}")
print(f"threshold detector coincidence probability = {np.round(p_click.real, 14)}")
```

Out:

```
[ 0. -1.41421356 1.41421356 0. 0. 0. ]
[[ 3.76219569 2.56457759 2.56457759 0. 0. 0. ]
[ 2.56457759 2.38109785 1.38109785 0. 0. 0. ]
[ 2.56457759 1.38109785 2.38109785 0. 0. 0. ]
[ 0. 0. 0. 3.76219569 -2.56457759 -2.56457759]
[ 0. 0. 0. -2.56457759 2.38109785 1.38109785]
[ 0. 0. 0. -2.56457759 1.38109785 2.38109785]]
single-photon coincidence probability = 0.0
threshold detector coincidence probability = 0.20933477023044
```

Here we see a similar phenomenon but between the 3-mode coincidence measurements where we interfere one mode of the TMSV with a coherent state. When we have threshold detectors, this coincidence is not completely suppressed.

## References¶

- 1
A. Christ & C. Silberhorn (2012). “Limits on the deterministic creation of pure single-photon states using parametric down-conversion”. Phys. Rev. A 85, 023829. doi:10.1103/PhysRevA.85.023829

- 2
C. K. Hong; Z. Y. Ou & L. Mandel (1987). “Measurement of subpicosecond time intervals between two photons by interference”. Phys. Rev. Lett. 59 (18): 2044–2046. doi:10.1103/PhysRevLett.59.2044

**Total running time of the script:** ( 0 minutes 13.886 seconds)

## Contents

## Downloads

## Related tutorials