Abstract and Contents Page.
Appendix A

FORTRAN source code for Fake Data.

This routine is designed to simulated the output of the APDs at the COAST telescope under a variety of experimental conditions. The expectation value of intensity follows a Gaussian modulated sinusoid, as would be expected from a Gaussian shaped optical filter. Photon shot noise is simulated by selecting the photon counts from a Poisson distribution with the appropriate expectation value. Simple phase fluctuations can be applied to the fringes. Figure 31 shows two sweeps of example output.

c Main program for non-dispersed fake data
c Data-faking routine for COAST interferometer
c Written by Bob Tubbs, St John's College
c for Part III Physics Project, March 1998

include 'rnt.inc'

c Parameters

real pi
parameter(pi = 3.14159265358979)

c Variables

integer sample, subsample, sweep, nsweeps
integer count1, count2, direction

real spacing, position, filterwidth, intensity
real mean, amplitude, seed, initialfringeposition
real fringeposition, fringevelocity, fringeacceleration
real loggaussian, gaussian, time

character outfile*80, photonnoiseflag*8

c Function names

integer photons
real rand

c Start

status = ok

write(6,*) "Fringe spacing (samples)?"
read(5,*) spacing
write(6,*) "Initial position of fringe envelope centre",
* " (samples)?"
read(5,*) initialfringeposition
write(6,*) "Initial velocity of fringe envelope (samples/s)?"
read(5,*) fringevelocity
write(6,*) "Acceleration of fringe envelope (samples/s**2)?"
read(5,*) fringeacceleration
write(6,*) "Fractional bandwidth of filter?"
write(6,*) "(Between 1/e points)"
read(5,*) filterwidth
write(6,*) "Mean Intensity"
read(5,*) mean
write(6,*) "Maximum intensity fluctuation"
read(5,*) amplitude
write(6,*) "Number of sweeps"
read(5,*) nsweeps
write(6,*) "Output filename?"
read(5,*) outfile
write(6,*) "Add photon noise (y/n)?"
read(5,*) photonnoiseflag
if ((photonnoiseflag .eq. "y") .or.
* (photonnoiseflag .eq. "Y")) then
photonnoiseflag = "y"

c Seed psuedo-random number generator

write(6,*) "Random number seed?"
read(5,*) seed
seed = rand(seed)
endif

c Initial trolley direction

direction = 1

c Open output file

open(UNIT=9, STATUS='NEW', ERR=90, FILE=outfile)

c Output number of sweeps to file

write(9,FMT=*) nsweeps

c Start main loop

do sweep = 1, nsweeps

do sample = 1, 500

c Calculate mean light intensity for this sample

intensity = 0.0

do subsample = 1, 5

c Calculate time since first sample (seconds)
c There are 10 sweeps per second, 5000 samples
c per second, 25000 subsamples per second

time = real(sweep - 1)/10.0 + real(sample - 1)/5000.0
* + real(subsample - 3)/25000.0

c Calculate current fringe position (samples)

fringeposition = initialfringeposition + fringevelocity *
* time + fringeacceleration * (time**2) / 2.0

c Calculate current trolley position (samples)

position = 250.0 - 250.0 * real(direction) +
* (real(sample - 1) + real(subsample - 3)/5.0)
* * real(direction)

c Formula for log(Gaussian) centred at (position - fringeposition)

loggaussian = -((position - fringeposition) *
* filterwidth/spacing)**2

c Calculate Gaussian, checking for floating point underflow

if (loggaussian .gt. -30.0) then
gaussian = exp(loggaussian)
else
gaussian = 0.0
endif

c Calculate change in intensity produced by interference
c Add 1/5 of this value to the total value for the sample
c Repeated for each of the 5 subsamples to give mean value

intensity = intensity + amplitude*gaussian
* *cos(2*pi*(position - fringeposition)/spacing)/5.0

enddo

c Calculate photon counts for case with beams in phase and
c case for beams in anti-phase

if (photonnoiseflag .eq. "y") then

c Use Poisson distributed random number generator: photons()

count1 = photons(mean + intensity)
count2 = photons(mean - intensity)

else

count1 = int(mean + intensity)
count2 = int(mean - intensity)

endif

c Output photon counts to file

write(9,FMT=*) sample + (sweep - 1) * 500, count1, count2

enddo

c Reverse trolley direction

direction = - direction

c End main loop

enddo

c Close output file

close(UNIT=9, ERR=90)

stop

90 write(6,*) "Filer error"

end

 
 
c Subroutine which generates Poisson distributed
c pseudo-random numbers. Ignoring deficiencies in
c the FORTRAN random number generator and rounding
c errors, the psuedo-random numbers are perfectly
c Poisson-distributed.

integer function photons(intensity)

implicit none

c Variables

real intensity

integer i

real r, poisson, cumulative, logfactoriali, logpoisson

c Functions

real rand

c Generate psuedo-random number with rectangular distribution

r = rand(0.0)

c Initialise variables

i = 0
logfactoriali = 0.0
cumulative = 0.0
poisson = 1.0

c Check for intensity less than or equal to zero

if (intensity .gt. 0.0) then

c Main loop
c Repeated until cumulative probability is greater than r or has
c reached maximum value. Total cumulative probability may be
c minutely smaller than 1.0 due to rounding errors etc.

do while ((cumulative .lt. r) .and.
* ((real(i) .le. intensity) .or. (poisson .gt. 0.0)))

logpoisson = -intensity+real(i)*log(intensity)-logfactoriali

c Calculate probability of i photons being emmitted, checking for
c floating point underflow

if (logpoisson .gt. -30.0) then

poisson = exp(logpoisson)

else

poisson = 0.0

endif

c Calculate cumulative probability of between 0 and i photons being
c emmitted.

cumulative = cumulative + poisson

c Increment i and calculate new value of log(factorial(i))

i = i + 1

logfactoriali = logfactoriali + log(real(i))

enddo

c Number of photons required is i - 1

photons = i - 1

else

photons = 0

endif

return

end

 

Figure 31 - Example output from the Fake data routine. Two sweeps each of length 500 samples are shown. The mean intensity was 100 photons per sample. The peak fringe visibility was 0.5. The fractional bandwidth of the optical filter was 0.05.


Abstract and Contents Page.

Return to Bob's Interferometry Page.

Return to Bob's Home Page.