Index: trunk/ppStack/src/ppStackLoop.c
===================================================================
--- trunk/ppStack/src/ppStackLoop.c	(revision 19565)
+++ trunk/ppStack/src/ppStackLoop.c	(revision 19643)
@@ -179,4 +179,6 @@
 {
     assert(config);
+
+    psTimerStart("PPSTACK_TOTAL");
 
     psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
@@ -429,4 +431,5 @@
         psArray *regions = NULL, *kernels = NULL; // Regions and kernels used in subtraction
         psArray *sources = haveSources ? globalSources : indSources->data[i]; // Sources for matching
+        psTimerStart("PPSTACK_MATCH");
         if (!ppStackMatch(readout, &regions, &kernels, &matchChi2->data.F32[i],
                           sources, targetPSF, rng, config)) {
@@ -436,4 +439,19 @@
             continue;
         }
+
+        if (stats) {
+            float stampMean = psMetadataLookupF32(NULL, readout->analysis,
+                                                  PM_SUBTRACTION_ANALYSIS_STAMPS_MEAN); // Mean deviation
+            float stampRMS = psMetadataLookupF32(NULL, readout->analysis,
+                                                 PM_SUBTRACTION_ANALYSIS_STAMPS_RMS);  // RMS deviation
+            psMetadataAddF32(stats, PS_LIST_TAIL, "TIME_MATCH", PS_META_DUPLICATE_OK,
+                             "Time to match PSF", psTimerMark("PPSTACK_MATCH"));
+            psMetadataAddF32(stats, PS_LIST_TAIL, "STAMP.MEAN", PS_META_DUPLICATE_OK,
+                             "Mean deviation for stamps", stampMean);
+            psMetadataAddF32(stats, PS_LIST_TAIL, "STAMP.RMS", PS_META_DUPLICATE_OK,
+                             "RMS deviation for stamps", stampRMS);
+
+        }
+        psLogMsg("ppStack", PS_LOG_INFO, "Time to match image %d: %f sec", i, psTimerClear("PPSTACK_MATCH"));
 
         subRegions->data[i] = regions;
@@ -477,4 +495,6 @@
     ppStackThreadInit();
     ppStackThreadData *stack = ppStackThreadDataSetup(cells, imageNames, maskNames, weightNames, config);
+
+    psTimerStart("PPSTACK_INITIAL");
 
     memDump("preinitial");
@@ -640,4 +660,12 @@
     }
 
+    if (stats) {
+        psMetadataAddF32(stats, PS_LIST_TAIL, "TIME_INITIAL", 0,
+                         "Time to make initial stack", psTimerMark("PPSTACK_INITIAL"));
+    }
+    psLogMsg("ppStack", PS_LOG_INFO, "Time to make initial stack: %f sec", psTimerClear("PPSTACK_INITIAL"));
+
+    psTimerStart("PPSTACK_REJECT");
+
     // Pixel rejection
     psArray *rejected = psArrayAlloc(num);
@@ -696,4 +724,5 @@
         // Reject bad pixels
         for (int i = 0; i < num; i++) {
+            psTimerStart("PPSTACK_REJECT");
 
 #ifdef TESTING
@@ -751,4 +780,13 @@
             }
             rejected->data[i] = reject;
+
+            if (stats) {
+                psMetadataAddF32(stats, PS_LIST_TAIL, "TIME_REJECT", PS_META_DUPLICATE_OK,
+                                 "Time to perform rejection", psTimerMark("PPSTACK_REJECT"));
+                psMetadataAddS32(stats, PS_LIST_TAIL, "REJECT_PIXELS", PS_META_DUPLICATE_OK,
+                                 "Number of pixels rejected", reject ? reject->n : 0);
+            }
+            psLogMsg("ppStack", PS_LOG_INFO, "Time to perform rejection on image %d: %f sec", i,
+                     psTimerClear("PPSTACK_REJECT"));
         }
 
@@ -767,5 +805,14 @@
             return false;
         }
-    }
+
+        if (stats) {
+            psMetadataAddF32(stats, PS_LIST_TAIL, "TIME_REJECT", PS_META_DUPLICATE_OK,
+                             "Time to perform rejection", psTimerMark("PPSTACK_REJECT"));
+            psMetadataAddS32(stats, PS_LIST_TAIL, "REJECT_IMAGES", 0,
+                             "Number of images rejected completely", numRejected);
+        }
+   }
+
+    psTimerStart("PPSTACK_FINAL");
 
     memDump("reject");
@@ -828,4 +875,10 @@
 
     memDump("final");
+
+    if (stats) {
+        psMetadataAddF32(stats, PS_LIST_TAIL, "TIME_FINAL", 0,
+                         "Time to make final stack", psTimerMark("PPSTACK_FINAL"));
+    }
+    psLogMsg("ppStack", PS_LOG_INFO, "Time to make final stack: %f sec", psTimerClear("PPSTACK_FINAL"));
 
     psTrace("ppStack", 2, "Cleaning up after combination....\n");
@@ -904,4 +957,6 @@
         psTrace("ppStack", 1, "Photometering stacked image....\n");
 
+        psTimerStart("PPSTACK_PHOT");
+
         fileActivation(config, combineFiles, false);
         fileActivation(config, photFiles, true);
@@ -916,4 +971,14 @@
 
         fileActivation(config, combineFiles, true);
+
+        if (stats) {
+            pmFPAfile *photFile = psMetadataLookupPtr(NULL, config->files, "PSPHOT.INPUT"); // File
+            pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout with the sources
+            psArray *sources = psMetadataLookupPtr(NULL, photRO->analysis, "PSPHOT.SOURCES"); // Sources
+            psMetadataAddS32(stats, PS_LIST_TAIL, "NUM_SOURCES", 0, "Number of sources detected", sources->n);
+            psMetadataAddF32(stats, PS_LIST_TAIL, "TIME_PHOT", 0,
+                             "Time to do photometry", psTimerMark("PPSTACK_PHOT"));
+        }
+        psLogMsg("ppStack", PS_LOG_INFO, "Time to do photometry: %f sec", psTimerClear("PPSTACK_PHOT"));
     }
 
@@ -952,4 +1017,7 @@
     // Write out summary statistics
     if (stats) {
+        psMetadataAddF32(stats, PS_LIST_TAIL, "TIME_STACK", 0,
+                         "Time to do photometry", psTimerClear("PPSTACK_TOTAL"));
+
         const char *statsMDC = psMetadataConfigFormat(stats);
         if (!statsMDC || strlen(statsMDC) == 0) {
