diff --git a/IntervalsModel/plots/Distributions.Poisson_hh.pdf b/IntervalsModel/plots/Distributions.Poisson_hh.pdf
index 1ba31a7eefe870e7e4072ddd7e266fa00e022d8d..76f28596b32d2dff18b708363c1bbd952704ec3d 100644
Binary files a/IntervalsModel/plots/Distributions.Poisson_hh.pdf and b/IntervalsModel/plots/Distributions.Poisson_hh.pdf differ
diff --git a/IntervalsModel/plots/Distributions.Poisson_rest.pdf b/IntervalsModel/plots/Distributions.Poisson_rest.pdf
index 59cd700004b933f910fd4effd1523590f4e0fdda..04bcddc7c3dcc3c07b4880734b7dfed3d27c013c 100644
Binary files a/IntervalsModel/plots/Distributions.Poisson_rest.pdf and b/IntervalsModel/plots/Distributions.Poisson_rest.pdf differ
diff --git a/IntervalsModel/plots/Distributions.Poisson_ws.pdf b/IntervalsModel/plots/Distributions.Poisson_ws.pdf
index 5cd34c7f527494712afc603cc3ccf0ebeed8f2d4..8e09fe4b6c6c16b1182c5ae8cc4db8a63b00831c 100644
Binary files a/IntervalsModel/plots/Distributions.Poisson_ws.pdf and b/IntervalsModel/plots/Distributions.Poisson_ws.pdf differ
diff --git a/IntervalsModel/plots/hh.pdf b/IntervalsModel/plots/hh.pdf
index faef2d1ad0c79eae6626b480ba089d20f93ae287..fa2572fa0a1315ff43a946aadaa07b71c4ca7b8a 100644
Binary files a/IntervalsModel/plots/hh.pdf and b/IntervalsModel/plots/hh.pdf differ
diff --git a/IntervalsModel/plots/rest.pdf b/IntervalsModel/plots/rest.pdf
index 89decf0a94ea8a69fdb091e2efe540b70359061b..9f8728a9d14cf1cc15f8dce54ad848a05f4ed09a 100644
Binary files a/IntervalsModel/plots/rest.pdf and b/IntervalsModel/plots/rest.pdf differ
diff --git a/IntervalsModel/plots/ws.pdf b/IntervalsModel/plots/ws.pdf
index 243733f078430548209c9e597c56d8cbfa32fb7f..1e36f2f154e101e73e18e7d0d4b744ed260b4bce 100644
Binary files a/IntervalsModel/plots/ws.pdf and b/IntervalsModel/plots/ws.pdf differ
diff --git a/IntervalsModel/simulation_data/hh.dat b/IntervalsModel/simulation_data/hh.dat
deleted file mode 100644
index fea7ea8ac0d3dd37a0ab30ff5ce899e8d56515ce..0000000000000000000000000000000000000000
Binary files a/IntervalsModel/simulation_data/hh.dat and /dev/null differ
diff --git a/IntervalsModel/simulation_data/rest.dat b/IntervalsModel/simulation_data/rest.dat
index e43cb1058e2f3a3ba27ad57bc4518efe012f4b57..41b8f3dcb9ec866d5d1743c12a56e3d88ed46de6 100644
Binary files a/IntervalsModel/simulation_data/rest.dat and b/IntervalsModel/simulation_data/rest.dat differ
diff --git a/IntervalsModel/simulation_data/ws.dat b/IntervalsModel/simulation_data/ws.dat
index ee07dd956d8f31c12c7c6005b403b532cdc55b5b..a20eeb8fe50afeeac37ba5c0332ec3777938896b 100644
Binary files a/IntervalsModel/simulation_data/ws.dat and b/IntervalsModel/simulation_data/ws.dat differ
diff --git a/IntervalsModel/src/IntervalsModel.jl b/IntervalsModel/src/IntervalsModel.jl
index 5d730605994b10c4473c7a13e065a05eae9d483e..51275b5cda728d45e2a1abc755c7cd4231f06eb8 100644
--- a/IntervalsModel/src/IntervalsModel.jl
+++ b/IntervalsModel/src/IntervalsModel.jl
@@ -25,11 +25,11 @@ const rng = Xoroshiro128Plus()
 #consts that let give us nicer names for the indices
 const YOUNG, MIDDLE,OLD = 1,2,3
 const durmax = 144
-
+const sample_repeat = 10
 """
 Number of start times to sample for a given set of distribution parameters. 
 """
-const comparison_samples = 70
+const comparison_samples = 100
 const sparam = [60, 12]
 # Swap age brackets for numbers
 const swap_dict = OrderedDict("Y" => YOUNG, "M" => MIDDLE, "O" => OLD)
@@ -44,7 +44,7 @@ include("plotting_functions.jl")
 Runs parameter estimation for the three scenarios, hh, ws, and rest. 
 """
 function main()
-    do_hh(400)
+    # do_hh(400)
     do_ws(400)
     do_rest(400)
     plot_all()
@@ -131,6 +131,7 @@ function do_ws(particles)
         Poisson,
     ]
     poisson_priors = filter_priors("workschool")
+    # display(poisson_priors)
     # Set parameter priors for fitting
     priors_list = [
         Factored(poisson_priors...)
diff --git a/IntervalsModel/src/hh_durations_model.jl b/IntervalsModel/src/hh_durations_model.jl
index fe80396c424e430bbef1cb03f577b171a5f36180..18f65bffb5aaa4a2a91eb0ded9ef691c6038c37a 100644
--- a/IntervalsModel/src/hh_durations_model.jl
+++ b/IntervalsModel/src/hh_durations_model.jl
@@ -13,7 +13,7 @@ function make_dat_array()
         Int.(HHYMO[!,"MNUM"]),
         Int.(HHYMO[!,"ONUM"]),
     )
-    WGHT = Weights(HHYMO[!,"WGHT_PER"]./cnst_hh.Wghttotal)
+    WGHT = Weights(HHYMO[!,"WGHT_PER"]./Wghttotal)
     AGERESP = map(r -> swap_dict[r],HHYMO[!,"AGERESP"])
     return (;
         nums,
@@ -31,10 +31,7 @@ const dat = make_dat_array() #assign a constant data array
 Calculate error between observed total contact durations in HH data and simulated total contact durations based on `dist(p[i]...)`. This one works a bit differently than the WS or rest error function, since we do not have a distribution of total durations to compare to, but rather one average total duration, and we do have the explicit samples of numbers of contacts.
 """
 function err_hh(p,dist)
-    p_matrix = zeros(3,3)
-    for i in 1:9
-        p_matrix[i] = p[i]
-    end
+    p_matrix = get_params(p)
     age_dists = [dist(p_matrix[i,j]...) for i in YOUNG:OLD, j in YOUNG:OLD]
     duration_subarray =  dat.durs #durations, these are call subarray because we used to only sample a subset
     num_contacts_subarray = dat.nums #numbers of contacts for each duration
diff --git a/IntervalsModel/src/interval_overlap_sampling.jl b/IntervalsModel/src/interval_overlap_sampling.jl
index c64d83f47cd94223ba51fa1bad083b9cfaeb5ed0..3684fc5520a1b3f14f9c42eec8b1196983ed80de 100644
--- a/IntervalsModel/src/interval_overlap_sampling.jl
+++ b/IntervalsModel/src/interval_overlap_sampling.jl
@@ -71,4 +71,4 @@ function tot_dur_sample!(sample_list,durlist)
         union!(int_list)
         sample_list[i] = mapreduce(Intervals.span,+,int_list)
     end
-end
+end
\ No newline at end of file
diff --git a/IntervalsModel/src/plotting_functions.jl b/IntervalsModel/src/plotting_functions.jl
index f03414f3d936738a01135ca86c29ede1dd3dd2b9..1e85e408c16044a3ed65de8f2a73e10c81c8861f 100644
--- a/IntervalsModel/src/plotting_functions.jl
+++ b/IntervalsModel/src/plotting_functions.jl
@@ -17,14 +17,8 @@ function plot_estimate(fname)
     end
 end
 function plot_dists(fname,dist_constructors,data)
-    function get_non_symmetric_params(p) 
-            p_matrix = [[zero(eltype(p))] for i in 1:3, j in 1:3]
-            for i in 1:9
-                p_matrix[i][1] = p[i]
-            end
-        return p_matrix
-    end
-    p_estimate_as_arrays = map(d -> get_non_symmetric_params(d.P),data)
+
+    p_estimate_as_arrays = map(d -> get_params(d.P),data)
     p_matrix = map(x -> plot(),p_estimate_as_arrays[1])
     ymo = ["Y","M","O"]
     x_range = 0.0:144.0
@@ -67,7 +61,6 @@ function plot_posteriors(fname,data)
     end   
     plot!(p_list[1]; ylabel = "No. of particles")
     plot!(p_list[4]; ylabel = "No. of particles")
-    plot!(p_list[7]; ylabel = "No. of particles")
     p = plot(p_list...; size = (800,600), seriescolor = color_palette[1])
     savefig(p,joinpath(PACKAGE_FOLDER,"plots","$fname.pdf"))
 end
diff --git a/IntervalsModel/src/rest_durations_model.jl b/IntervalsModel/src/rest_durations_model.jl
index 53678dfeca5afda3b305a757e2574d7f7b19ce7b..37ce4e9b2ea0f82bd8462757d34c293b60df2073 100644
--- a/IntervalsModel/src/rest_durations_model.jl
+++ b/IntervalsModel/src/rest_durations_model.jl
@@ -12,15 +12,9 @@ const kerneldensity_data_rest = (
 Calculate error between observed contact durations in rest data and simulated contact durations based on `dist(p[i]...)`.
 """
 function err_rest(p,dist)
-    #we get the vector p as a 9 element vector from KissABC, but more convenient as a 3x3 matrix
-    p_matrix = zeros(3,3)
-    for i in 1:9
-        p_matrix[i] = p[i]
-    end
+    #we get the vector p as a 6n element vector from KissABC, but more convenient as a 3x3 matrix of tuples
+    p_matrix = get_params(p)
 
-    #sample a matrix of neighourhood sizes for distributions in rest_distributions
-    #this is actually not correct? neighbourhood sizes should be symmetric!
-    neighourhoods = rand.(rng,rest_distributions)
     
     #create a matrix of distributions of type dist, from the parameters in p_matrix
     age_dists = [dist(p_matrix[i,j]...) for i in YOUNG:OLD, j in YOUNG:OLD]
@@ -29,24 +23,30 @@ function err_rest(p,dist)
     sample_list = zeros(comparison_samples)
     errsum = 0
 
-    for age_sample in YOUNG:OLD
-        for age_j in YOUNG:OLD #for a given age_sample loop over possible contact ages
-            if neighourhoods[age_sample,age_j] > 0
-                #get durations from our candidate distribtions for each of the contacts in neighbourhood
-                durs = trunc.(Int,rand(rng,age_dists[age_sample,age_j],neighourhoods[age_sample,age_j])) .% durmax
-                
-                #this MODIFIES sample_list to contain samples from the distribution of total_durations, given intervals of length dur.
-                tot_dur_sample!(sample_list,durs)
-                
-                #compute a kernel density from the list of samples
-                kde_est = kde(sample_list)
+    for _ in 1:sample_repeat
+
+        #sample a matrix of neighourhood sizes for distributions in rest_distributions
+        #this is actually not correct? neighbourhood sizes should be symmetric!
+        neighourhoods = rand.(rng,rest_distributions)
+        for age_sample in YOUNG:OLD
+            for age_j in YOUNG:OLD #for a given age_sample loop over possible contact ages
+                if neighourhoods[age_sample,age_j] > 0
+                    #get durations from our candidate distribtions for each of the contacts in neighbourhood
+                    durs = trunc.(Int,rand(rng,age_dists[age_sample,age_j],neighourhoods[age_sample,age_j])) .% durmax
+                    
+                    #this MODIFIES sample_list to contain samples from the distribution of total_durations, given intervals of length dur.
+                    tot_dur_sample!(sample_list,durs)
+                    
+                    #compute a kernel density from the list of samples
+                    kde_est = kde(sample_list)
 
-                #compute L1 distance between observed distribution of total durations from survey, and observed distribution from simulation
-                errsum += mapreduce(+,0:1:durmax) do i
-                    return abs(pdf(kde_est,i) - pdf(kerneldensity_data_ws[age_sample],i))
+                    #compute L1 distance between observed distribution of total durations from survey, and observed distribution from simulation
+                    errsum += mapreduce(+,0:1:durmax) do i
+                        return abs(pdf(kde_est,i) - pdf(kerneldensity_data_ws[age_sample],i))
+                    end
                 end
             end
         end
     end
-    return errsum
+    return errsum./sample_repeat
 end
\ No newline at end of file
diff --git a/IntervalsModel/src/utils.jl b/IntervalsModel/src/utils.jl
index a02d85dad890a3a0ebc7df138be723d79477c2c5..843730bebff44c5998352a409af181342b354cce 100644
--- a/IntervalsModel/src/utils.jl
+++ b/IntervalsModel/src/utils.jl
@@ -24,6 +24,14 @@ function as_symmetric_matrix(l)
     ]
 end
 
+"""
+    Turn a symmetric 3x3 matrix, l, into a vector of length 6, probably a nicer way to do this exists but meh.
+"""
+function symmetric_matrix_as_vector(A) 
+    return [A[1,1],A[1,2],A[1,3],A[2,2],A[2,3],A[3,3]]
+end
+
+
 """
 Load rest data from `network-data/Timeuse/Rest/RData`.
 """
@@ -82,13 +90,14 @@ function filter_priors(location_key)
     end
 
     priors_probs = filter(row-> row["location"] == location_key, eachrow(priors)) |>
-                    df -> map(r -> (r[:index_out],r[:index_in]) => convert(Vector,r[string.(0:143)]),df) |>
+                    df -> map(r -> (r[:index_out],r[:index_in]) => convert(Vector,r[string.(0:94)]),df) |> #this is pretty inflexible to changing support unfortunately
                     Dict |>
                     df -> Dict(map(v -> v => Categorical(df[v]), collect(keys(df))))
 
     output_array = Array{eltype(values(priors_probs)),2}(undef,(3,3))
     for (key,value) in priors_probs
         output_array[key...] = value
+        output_array[reverse(key)...] = value #corny way to get symmetry assuming key is a 2-tuple
     end
-    return output_array
+    return symmetric_matrix_as_vector(output_array)
 end
\ No newline at end of file
diff --git a/IntervalsModel/src/ws_durations_model.jl b/IntervalsModel/src/ws_durations_model.jl
index 91aadca465abdd4cec66f14883598903cf57c5ff..1f6b81362225b1fe273c68f866be217736cea58e 100644
--- a/IntervalsModel/src/ws_durations_model.jl
+++ b/IntervalsModel/src/ws_durations_model.jl
@@ -16,10 +16,8 @@ Calculate error between observed contact durations in workschool data and simula
 """
 function err_ws(p,dist)
     #we get the vector p as a 9 element vector from KissABC, but more convenient as a 3x3 matrix
-    p_matrix = zeros(3,3) 
-    for i in 1:9
-        p_matrix[i] = p[i] #this will fill p_matrix with the elements of p in column-major order
-    end
+
+    p_matrix = get_params(p)
 
     #create a matrix of distributions of type dist, from the parameters in p_matrix
     age_dists = [dist(p_matrix[i,j]...) for i in YOUNG:OLD, j in YOUNG:OLD] 
@@ -27,28 +25,29 @@ function err_ws(p,dist)
     #initialize the list of samples and the total error
     sample_list = zeros(comparison_samples)
     errsum = 0
-
-    for age_sample in YOUNG:OLD
-        #Sample neighbourhood sizes. Note that this includes the weekend/weekday coinflip, implemented in CovidAlertVaccinationModel.  
-        neighourhoods = CovidAlertVaccinationModel.ws_sample(age_sample)
-
-        for age_j in YOUNG:OLD #for a given age_sample loop over possible contact ages        
-            if neighourhoods[age_j] > 0
-                #get durations from our candidate distribtions for each of the contacts in neighbourhood
-                durs = trunc.(Int,rand(rng,age_dists[age_sample,age_j],neighourhoods[age_j])) .% durmax
-
-                #this MODIFIES sample_list to contain samples from the distribution of total_durations, given intervals of length dur.
-                tot_dur_sample!(sample_list,durs)
-
-                #compute a kernel density from the list of samples
-                kde_est = kde(sample_list)
-                
-                #compute L1 distance between observed distribution of total durations from survey, and observed distribution from simulation
-                errsum += mapreduce(+,0:1:durmax) do i
-                    return abs(pdf(kde_est,i) - pdf(kerneldensity_data_ws[age_sample],i))
+    for _ in 1:sample_repeat
+        for age_sample in YOUNG:OLD
+            #Sample neighbourhood sizes. Note that this includes the weekend/weekday coinflip, implemented in CovidAlertVaccinationModel.  
+            neighourhoods = CovidAlertVaccinationModel.ws_sample(age_sample)
+
+            for age_j in YOUNG:OLD #for a given age_sample loop over possible contact ages        
+                if neighourhoods[age_j] > 0
+                    #get durations from our candidate distribtions for each of the contacts in neighbourhood
+                    durs = trunc.(Int,rand(rng,age_dists[age_sample,age_j],neighourhoods[age_j])) .% durmax
+
+                    #this MODIFIES sample_list to contain samples from the distribution of total_durations, given intervals of length dur.
+                    tot_dur_sample!(sample_list,durs)
+
+                    #compute a kernel density from the list of samples
+                    kde_est = kde(sample_list)
+                    
+                    #compute L1 distance between observed distribution of total durations from survey, and observed distribution from simulation
+                    errsum += mapreduce(+,0:1:durmax) do i
+                        return abs(pdf(kde_est,i) - pdf(kerneldensity_data_ws[age_sample],i))
+                    end
                 end
             end
         end
     end
-    return errsum
+    return errsum./sample_repeat
 end