Exemplo n.º 1
0
int postprocess_events(Interaction *ints, int nints, float total_e,
		       int ppflag, float coal_dist,
		       double *x, double *y, double *z, double *e, int *s, postprocCnt *postCnt)
{
  /* prost-process the events
     convert cyl to cart coords
     combine closely-spaced interactions in neighboring segments
     optionally combine closely-spaced interactions in the same segment
     Input: ints, nints, total_e
     Output: x, y, z, e
     Control: ppflag = 2 to combine interactions in the same segment
     returns final number of interactions found
  */

  double efrac, elo, dinp, dinp12, dinp13, dinp23, e1, e2, dx, dy, dz;
  int    i, j, k, found, i12, i13, i23, seg[MAX_PARS];

  /* convert cyl to cart coords */
  for (i=0; i<nints; i++) {
    cyl_to_cart(ints[i].seg, &ints[i].r, &x[i], &y[i], &z[i], &e[i]);
    seg[i] = ints[i].seg;
    s[i] = seg[i];			/* mc */
    e[i] *= total_e;
  }
  found = nints;    /* will be final number of interactions found */

  int seghit[36] = {0};

  for (i=0; i<found-1; i++) {
    seghit[seg[i]]++;
  }
  for (i=0; i<36; i++) {
    if (seghit[i] == 1) { postCnt->oneInt[i]++; }
    else if (seghit[i] == 2) { postCnt->twoInt[i]++; }
    else if (seghit[i] == 3) { postCnt->threeInt[i]++; }
    else if (seghit[i] > 3) { postCnt->manyInt[i]++; }
  }

  /* check for closely-spaced interactions in neighboring segments
     that should be combined. Needs to be done in Cartesian coords */
  for (i=0; i<found-1; i++) {
    for (j=i+1; j<found; j++) {
      if (seg[i] == seg[j]) continue;
      dx = x[i] - x[j];
      dy = y[i] - y[j];
      dz = z[i] - z[j];
      if ((dx*dx + dy*dy + dz*dz) < coal_dist*coal_dist) {
	/* FIXME - We could add a fudge factor to coal_dist if desired */
	e1 = e[i];
	e2 = e[j];
	x[i] = (e1*x[i] + e2*x[j]) / (e1+e2);
	y[i] = (e1*y[i] + e2*y[j]) / (e1+e2);
	z[i] = (e1*z[i] + e2*z[j]) / (e1+e2);
	e[i] = e1+e2;
	postCnt->combinedDiffSeg++;
	found--;
	for (k=j; k<found; k++) {
	  x[k] = x[k+1];
	  y[k] = y[k+1];
	  z[k] = z[k+1];
	  e[k] = e[k+1];
	  seg[k] = seg[k+1];
	}
      } 
    }
  }

  /* This should be postprocessing*/
 /* if (found == 2 && seg[0] == seg[1] && ((e[0]<80) || (e[1]<80) && (fabs(e[0])>1 && fabs(e[1])>1))){ 
	e1 = e[0];
	e2 = e[1];
	x[0] = (e1*x[0] + e2*x[1]) / (e1+e2);
	y[0] = (e1*y[0] + e2*y[1]) / (e1+e2);
	z[0] = (e1*z[0] + e2*z[1]) / (e1+e2);
	e[0] = e1+e2;
	found--;
 } */

  if (ppflag < 2) return found;  /* return without doing the same-segment
				    distance- or energy-based coalescence...
				    this should be the default? */

  /* now combine closely-spaced events in the same segment */
  /* FIXME - this should really be done in grid coordinates, if at all
     But that's not easy since the code above needs to be done in
     cart coords, and can change the number of interactions */

  /* this was in the original lbl code -
     I'm not sure how they got it, or if it's really a good idea */
  /* FIXME - It should at least include some dependence on number of hit segments */
  if (total_e < 140.0) {
    elo = 0.35;
  } else if (total_e < 400.0) {
    elo = 0.28;
  } else if (total_e < 900.0) {
    elo = 0.20;
  } else {
    elo = 0.15;
  }

  if (found == 3 && seg[0] == seg[1] && seg[0] == seg[2]) {
    /* 3 interactions in a one-seg event */
    /* difference in position */
    dinp12 = sqrt((x[0]-x[1])*(x[0]-x[1]) + (y[0]-y[1])*(y[0]-y[1]) + (z[0]-z[1])*(z[0]-z[1]));
    dinp13 = sqrt((x[0]-x[2])*(x[0]-x[2]) + (y[0]-y[2])*(y[0]-y[2]) + (z[0]-z[2])*(z[0]-z[2]));
    dinp23 = sqrt((x[1]-x[2])*(x[1]-x[2]) + (y[1]-y[2])*(y[1]-y[2]) + (z[1]-z[2])*(z[1]-z[2]));

    if (e[0] < elo*0.7     || e[1] < elo*0.7     || e[2] < elo*0.7    ||
	dinp12 < coal_dist || dinp13 < coal_dist || dinp23 < coal_dist) {
      /* combine 2 of the 3 interactions */
      i12 = i13 = i23 = 0;
      if (dinp12 < coal_dist && dinp12 < dinp13 && dinp12 < dinp23) {
	/* separation less than 2 mm; combine the interactions */
	i12 = 1;
      } else if (dinp13 < coal_dist && dinp13 < dinp12 && dinp13 < dinp23) {
	/* separation less than 2 mm; combine the interactions */
	i13 = 1;
      } else if (dinp23 < coal_dist && dinp23 < dinp12 && dinp23 < dinp13) {
	/* separation less than 2 mm; combine the interactions */
	i23 = 1;
      } else if (e[0] < elo*0.7 && e[0] < e[1] && e[0] < e[2]) {
	/* first interaction is too weak; combine it with the nearest other one */
	if (dinp12 < dinp13) {
	  i12 = 1;
	} else {
	  i13 = 1;
	}
      } else if (e[1] < elo*0.7 && e[1] < e[0] && e[1] < e[2]) {
	/* second interaction is too weak; combine it with the nearest other one */
	if (dinp12 < dinp23) {
	  i12 = 1;
	} else {
	  i23 = 1;
	}
      } else if (e[2] < elo*0.7 && e[2] < e[0] && e[2] < e[1]) {
	/* third interaction is too weak; combine it with the nearest other one */
	if (dinp13 < dinp23) {
	  i13 = 1;
	} else {
	  i23 = 1;
	}
      }
      /* do the coalescence */
      if (i12) {
	i=0; j=1;
      } else if (i13) {
	i=0; j=2;
      } else {
	i=1; j=2;
      }
      e1 = e[i];
      e2 = e[j];
      x[i] = (e1*x[i] + e2*x[j]) / (e1+e2);
      y[i] = (e1*y[i] + e2*y[j]) / (e1+e2);
      z[i] = (e1*z[i] + e2*z[j]) / (e1+e2);
      e[i] = e1+e2;
      found--;
      postCnt->combinedWithinSeg++;
      postCnt->combined3to2[seg[0]]++;
      for (k=j; k<found; k++) {
	x[k] = x[k+1];
	y[k] = y[k+1];
	z[k] = z[k+1];
	e[k] = e[k+1];
	seg[k] = seg[k+1];
      }

      /* see if the remaining two interactions should also be combined */
      efrac = e1/(e1+e2);
      dinp  = sqrt((x[0]-x[1])*(x[0]-x[1]) + (y[0]-y[1])*(y[0]-y[1]) + (z[0]-z[1])*(z[0]-z[1]));
      if (dinp < coal_dist || efrac > (1.0 - elo) || efrac < elo) {
	/* separation less than 2 mm, or one interaction is too weak */
	/* combine the interactions */
	e1 = e[0];
	e2 = e[1];
	x[0] = (e1*x[0] + e2*x[1]) / (e1+e2);
	y[0] = (e1*y[0] + e2*y[1]) / (e1+e2);
	z[0] = (e1*z[0] + e2*z[1]) / (e1+e2);
	e[0] = e1+e2;
	found--;
	postCnt->combinedWithinSeg++;
	postCnt->combined3to1[seg[0]]++;
	postCnt->combined3to2[seg[0]]--; /* we've combined all 3, but I incremented 3to2 counter earlier */
      }
    }

  } else {    /* more than 1 segment hit, or only 2 interactions... */

    /* loop over the hit segments */
    for (i=0; i<found-1; i++) {
      if (seg[i] == seg[i+1]) {
	/* two interactions in this segment; see if they should be combined */
	j = i+1;
	e1 = e[i];
	e2 = e[j];
	/* difference in position */
	dinp  = sqrt((x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) + (z[i]-z[j])*(z[i]-z[j]));
	/* energy fraction for first interaction */
	efrac = e1/(e1+e2);
	if (dinp < coal_dist || efrac > (1.0 - elo) || efrac < elo) {
	  /* separation less than 2 mm, or one interaction is too weak */
	  /* do the coalescence */
	  x[i] = (e1*x[i] + e2*x[j]) / (e1+e2);
	  y[i] = (e1*y[i] + e2*y[j]) / (e1+e2);
	  z[i] = (e1*z[i] + e2*z[j]) / (e1+e2);
	  e[i] = e1+e2;
	  found--;
	  postCnt->combinedWithinSeg++;
	  postCnt->combined2to1[seg[i]]++;
	  for (k=j; k<found; k++) {
	    x[k] = x[k+1];
	    y[k] = y[k+1];
	    z[k] = z[k+1];
	    e[k] = e[k+1];
	    seg[k] = seg[k+1];
	  }
	}
      } /* seg[i] == seg[i+1] */
    } /* loop over found */
  }
  return found;
} /* postprocess_event */
Exemplo n.º 2
0
float cyl_distance(struct cyl_pt pt1, struct cyl_pt pt2){
  /*yes, I'm very lazy. It's one of my best traits*/
  return cart_distance(cyl_to_cart(pt1), cyl_to_cart(pt2));
}