diff --git a/lalpulsar/src/SuperskyMetrics.c b/lalpulsar/src/SuperskyMetrics.c
index 132ad606d9c0b867e8443dc57faf176753fbb381..f817f558bd7fef87cde86678b53c675b1415dc99 100644
--- a/lalpulsar/src/SuperskyMetrics.c
+++ b/lalpulsar/src/SuperskyMetrics.c
@@ -700,8 +700,47 @@ SuperskyMetrics *XLALComputeSuperskyMetrics(
 
 }
 
+SuperskyMetrics *XLALCopySuperskyMetrics(
+  const SuperskyMetrics *metrics
+  )
+{
+
+  // Check input
+  XLAL_CHECK_NULL( metrics != NULL, XLAL_EFAULT );
+
+  // Allocate memory for copied struct
+  SuperskyMetrics *copy_metrics = XLALCalloc( 1, sizeof( *copy_metrics ) );
+  XLAL_CHECK_NULL( copy_metrics != NULL, XLAL_ENOMEM );
+  copy_metrics->num_segments = metrics->num_segments;
+
+  // Allocate memory for copies of arrays of coherent metrics
+  copy_metrics->coh_rssky_metric = XLALCalloc( copy_metrics->num_segments, sizeof( *copy_metrics->coh_rssky_metric ) );
+  XLAL_CHECK_NULL( copy_metrics->coh_rssky_metric != NULL, XLAL_ENOMEM );
+  copy_metrics->coh_rssky_transf = XLALCalloc( copy_metrics->num_segments, sizeof( *copy_metrics->coh_rssky_transf ) );
+  XLAL_CHECK_NULL( copy_metrics->coh_rssky_transf != NULL, XLAL_ENOMEM );
+
+  // Copy coherent metrics and transform data
+  for ( size_t n = 0; n < metrics->num_segments; ++n ) {
+    GAMAT_NULL( copy_metrics->coh_rssky_metric[n], metrics->coh_rssky_metric[n]->size1, metrics->coh_rssky_metric[n]->size2 );
+    gsl_matrix_memcpy( copy_metrics->coh_rssky_metric[n], metrics->coh_rssky_metric[n] );
+    copy_metrics->coh_rssky_transf[n] = XLALCalloc( 1, sizeof( *copy_metrics->coh_rssky_transf[n] ) );
+    XLAL_CHECK_NULL( copy_metrics->coh_rssky_transf[n] != NULL, XLAL_ENOMEM );
+    memcpy( copy_metrics->coh_rssky_transf[n], metrics->coh_rssky_transf[n], sizeof( *copy_metrics->coh_rssky_transf[n] ) );
+  }
+
+  // Copy semocherent metrics and transform data
+  GAMAT_NULL( copy_metrics->semi_rssky_metric, metrics->semi_rssky_metric->size1, metrics->semi_rssky_metric->size2 );
+  gsl_matrix_memcpy( copy_metrics->semi_rssky_metric, metrics->semi_rssky_metric );
+  copy_metrics->semi_rssky_transf = XLALCalloc( 1, sizeof( *copy_metrics->semi_rssky_transf ) );
+  XLAL_CHECK_NULL( copy_metrics->semi_rssky_transf != NULL, XLAL_ENOMEM );
+  memcpy( copy_metrics->semi_rssky_transf, metrics->semi_rssky_transf, sizeof( *copy_metrics->semi_rssky_transf ) );
+
+  return copy_metrics;
+
+}
+
 void XLALDestroySuperskyMetrics(
-  SuperskyMetrics *metrics                      /// [in] Supersky metrics struct
+  SuperskyMetrics *metrics
   )
 {
   if ( metrics != NULL ) {
diff --git a/lalpulsar/src/SuperskyMetrics.h b/lalpulsar/src/SuperskyMetrics.h
index d37c3e285333b574ecd9cbfb4de0428f9162198b..89fc475b6093edf96ec7f88efec89ac576d87ba4 100644
--- a/lalpulsar/src/SuperskyMetrics.h
+++ b/lalpulsar/src/SuperskyMetrics.h
@@ -90,6 +90,13 @@ SuperskyMetrics *XLALComputeSuperskyMetrics(
   const EphemerisData *ephemerides              ///< [in] Earth/Sun ephemerides
   );
 
+///
+/// Copy a #SuperskyMetrics struct.
+///
+SuperskyMetrics *XLALCopySuperskyMetrics(
+  const SuperskyMetrics *metrics                ///< [in] Supersky metrics struct
+  );
+
 ///
 /// Destroy a #SuperskyMetrics struct.
 ///
diff --git a/lalpulsar/test/SuperskyMetricsTest.c b/lalpulsar/test/SuperskyMetricsTest.c
index f6f26039178f3a0d1c39ae42d32ae492f8e90c75..081e614c8c6eccca5e17e12d7c6484b46569563f 100644
--- a/lalpulsar/test/SuperskyMetricsTest.c
+++ b/lalpulsar/test/SuperskyMetricsTest.c
@@ -389,6 +389,23 @@ int main( void )
                      semi_phys_mismatch, 3e-2
                      ) == XLAL_SUCCESS, XLAL_EFUNC );
 
+  // Check coherent and semicoherent metrics
+  SuperskyMetrics *copy_metrics = XLALCopySuperskyMetrics( metrics );
+  XLAL_CHECK_MAIN( copy_metrics != NULL, XLAL_EFUNC );
+  for ( size_t n = 0; n < NUM_SEGS; ++n ) {
+    XLAL_CHECK_MAIN( CheckSuperskyMetrics(
+                       copy_metrics->coh_rssky_metric[n], coh_rssky_metric_refs[n],
+                       copy_metrics->coh_rssky_transf[n], &coh_rssky_transf_refs[n],
+                       coh_phys_mismatches[n], 1e-2
+                       ) == XLAL_SUCCESS, XLAL_EFUNC );
+  }
+  XLAL_CHECK_MAIN( CheckSuperskyMetrics(
+                     copy_metrics->semi_rssky_metric, semi_rssky_metric_ref,
+                     copy_metrics->semi_rssky_transf, &semi_rssky_transf_ref,
+                     semi_phys_mismatch, 3e-2
+                     ) == XLAL_SUCCESS, XLAL_EFUNC );
+
+
   // Check writing/reading SuperskyMetrics to a FITS file
 #if !defined(HAVE_LIBCFITSIO)
   fprintf( stderr, "CFITSIO library is not available; skipping FITS writing/reading test\n" );
@@ -423,6 +440,7 @@ int main( void )
   XLALDestroyEphemerisData( edat );
   XLALSegListClear( &segments );
   XLALDestroySuperskyMetrics( metrics );
+  XLALDestroySuperskyMetrics( copy_metrics );
   LALCheckMemoryLeaks();
 
   return EXIT_SUCCESS;