int TestConnProbe::outputState(double timed){
   //Grab weights of probe and test for the value of .625/1.5, or .4166666
   HyPerConn* conn = getTargetHyPerConn();
   int numPreExt = conn->preSynapticLayer()->getNumExtended();
   int syw = conn->yPatchStride();                   // stride in patch

   for(int kPre = 0; kPre < numPreExt; kPre++){
      PVPatch * weights = conn->getWeights(kPre, 0);
      int nk  = conn->fPatchSize() * weights->nx;

      pvwdata_t * data = conn->get_wData(0,kPre);
      int ny  = weights->ny;
      for (int y = 0; y < ny; y++) {
         pvwdata_t * dataYStart = data + y * syw;
         for(int k = 0; k < nk; k++){
            if(fabs(timed - 0) < (parent->getDeltaTime()/2)){
               if(fabs(dataYStart[k] - 1) > .01){
                  std::cout << "dataYStart[k]: " << dataYStart[k] << "\n";
               }
               assert(fabs(dataYStart[k] - 1) <= .01);
            }
            else if(fabs(timed - 1) < (parent->getDeltaTime()/2)){
               if(fabs(dataYStart[k] - 1.375) > .01){
                  std::cout << "dataYStart[k]: " << dataYStart[k] << "\n";
               }
               assert(fabs(dataYStart[k] - 1.375) <= .01);
            }

         }
      }
   }
   return PV_SUCCESS;

}
int MomentumTestConnProbe::outputState(double timed){
   //Grab weights of probe and test for the value of .625/1.5, or .4166666
   HyPerConn* conn = getTargetHyPerConn();
   int numPreExt = conn->preSynapticLayer()->getNumExtended();
   int syw = conn->yPatchStride();                   // stride in patch

   for(int kPre = 0; kPre < numPreExt; kPre++){
      PVPatch * weights = conn->getWeights(kPre, 0);
      int nk  = conn->fPatchSize() * weights->nx;

      pvwdata_t * data = conn->get_wData(0,kPre);
      int ny  = weights->ny;
      pvdata_t wCorrect;
      for (int y = 0; y < ny; y++) {
         pvwdata_t * dataYStart = data + y * syw;
         for(int k = 0; k < nk; k++){
            pvdata_t wObserved = dataYStart[k];
            if(timed < 3){
               wCorrect = 0;
            }
            else{
               wCorrect = .376471;
               for(int i = 0; i < (timed-3); i++){
                  wCorrect += .376471 * exp(-(2*(i+1)));
               }
            }
            assert(fabs(wObserved - wCorrect) <= 1e-4);
         }
      }
   }
   return PV_SUCCESS;

}
/**
 * @timef
 * NOTES:
 *    - kPost, kxPost, kyPost are indices in the restricted post-synaptic layer.
 *
 */
int PostConnProbe::outputState(double timef)
{
   int k, kxPre, kyPre;
   HyPerConn * c = getTargetHyPerConn();
   PVPatch  * w;
   PVPatch *** wPost = c->convertPreSynapticWeights(timef);

   // TODO - WARNING: currently only works if nfPre==0

   const PVLayer * lPre = c->preSynapticLayer()->clayer;
   const PVLayer * lPost = c->postSynapticLayer()->clayer;

   const int nxPre = lPre->loc.nx;
   const int nyPre = lPre->loc.ny;
   const int nfPre = lPre->loc.nf;
   const PVHalo * haloPre = &lPre->loc.halo;

   const int nxPost = lPost->loc.nx;
   const int nyPost = lPost->loc.ny;
   const int nfPost = lPost->loc.nf;
   const PVHalo * haloPost = &lPost->loc.halo;

   // calc kPost if needed
   if (kPost < 0) {
      kPost = kIndex(kxPost, kyPost, kfPost, nxPost, nyPost, nfPost);
   }
   else {
      kxPost = kxPos(kPost, nxPost, nyPost, nfPost);
      kyPost = kyPos(kPost, nxPost, nyPost, nfPost);
      kfPost = featureIndex(kPost, nxPost, nyPost, nfPost);
   }

   c->preSynapticPatchHead(kxPost, kyPost, kfPost, &kxPre, &kyPre);

   const int kxPreEx = kxPre + haloPre->lt;
   const int kyPreEx = kyPre + haloPre->up;

   const int kxPostEx = kxPost + haloPost->lt;
   const int kyPostEx = kyPost + haloPost->up;
   const int kPostEx = kIndex(kxPostEx, kyPostEx, kfPost, nxPost+haloPost->lt+haloPost->rt, nyPost+haloPost->dn+haloPost->up, nfPost);

   const bool postFired = lPost->activity->data[kPostEx] > 0.0;

   w = wPost[getArborID()][kPost];
   pvwdata_t * wPostData = c->getWPostData(getArborID(),kPost);

   const int nw = w->nx * w->ny * nfPost; //w->nf;

   if (wPrev == NULL) {
      wPrev = (pvwdata_t *) calloc(nw, sizeof(pvwdata_t));
      for (k = 0; k < nw; k++) {
         wPrev[k] = wPostData[k]; // This is broken if the patch is shrunken
      }
   }
   if (wActiv == NULL) {
      wActiv = (pvwdata_t *) calloc(nw, sizeof(pvwdata_t));
   }

   k = 0;
   for (int ky = 0; ky < w->ny; ky++) {
      for (int kx = 0; kx < w->nx; kx++) {
         int kPre = kIndex(kx+kxPreEx, ky+kyPreEx, 0, nxPre+haloPre->lt+haloPre->rt, nyPre+haloPre->dn+haloPre->up, nfPre);
         wActiv[k++] = lPre->activity->data[kPre];
      }
   }

   bool changed = false;
   for (k = 0; k < nw; k++) {
      if (wPrev[k] != wPostData[k] || wActiv[k] != 0.0) {
         changed = true;
         break;
      }
   }
   FILE * fp = getStream()->fp;
   if (stdpVars && (postFired || changed)) {
      if (postFired) fprintf(fp, "*");
      else fprintf(fp, " ");
      fprintf(fp, "t=%.1f w%d(%d,%d,%d) prePatchHead(%d,%d): ", timef, kPost, kxPost,
            kyPost, kfPost, kxPre, kyPre);
      if (image) fprintf(fp, "tag==%d ", image->tag());
      fprintf(fp, "\n");
   }
   if (stdpVars && changed) {
      text_write_patch_extra(fp, w, wPostData, wPrev, wActiv, getTargetHyPerConn());
      fflush(fp);
   }

   for (k = 0; k < nw; k++) {
      wPrev[k] = wPostData[k];
   }

   if (outputIndices) {
      fprintf(fp, "w%d(%d,%d,%d) prePatchHead(%d,%d): ", kPost, kxPost, kyPost, kfPost, kxPre, kyPre);
      if(!stdpVars){
        fprintf(fp,"\n");
      }
      const PVLayer * lPre = c->preSynapticLayer()->clayer;
      write_patch_indices(fp, w, &lPre->loc, kxPre, kyPre, 0);
      fflush(fp);
   }

   return 0;
}