Beispiel #1
0
int main(void)
{
	unsigned long i,j;
	float cmp,*data1,*data2,*ans;

	data1=vector(1,N);
	data2=vector(1,N);
	ans=vector(1,N2);
	for (i=1;i<=N;i++) {
		if ((i > N/2-N/8) && (i < N/2+N/8))
			data1[i]=1.0;
		else
			data1[i]=0.0;
		data2[i]=data1[i];
	}
	correl(data1,data2,N,ans);
	/* Calculate directly */
	printf("%3s %14s %18s\n","n","CORREL","direct calc.");
	for (i=0;i<=16;i++) {
		cmp=0.0;
		for (j=1;j<=N;j++)
			cmp += data1[((i+j-1) % N)+1]*data2[j];
		printf("%3ld %15.6f %15.6f\n",i,ans[i+1],cmp);
	}
	free_vector(ans,1,N2);
	free_vector(data2,1,N);
	free_vector(data1,1,N);
	return 0;
}
Beispiel #2
0
void cross_corr(int n,real f[],real g[],real corr[])
{
  int i,j;
  
  if (acf.bFour)
    correl(f-1,g-1,n,corr-1);
  else {
    for(i=0; (i<n); i++) {
      for(j=i; (j<n); j++) 
	corr[j-i] += f[i]*g[j];
      corr[i] /= (real)(n-i);
    }
  }
}
Beispiel #3
0
static void low_do_four_core(int nfour,int nframes,real c1[],real cfour[],
			     int nCos,gmx_bool bPadding)
{
  int  i=0;
  real aver,*ans;

  aver = 0.0;
  switch (nCos) {
  case enNorm:  
    for(i=0; (i<nframes); i++) {
      aver+=c1[i];
      cfour[i]=c1[i];
    }
    break;
  case enCos:
    for(i=0; (i<nframes); i++) 
      cfour[i]=cos(c1[i]);
    break;
  case enSin:
    for(i=0; (i<nframes); i++) 
      cfour[i]=sin(c1[i]);
    break;
  default:
    gmx_fatal(FARGS,"nCos = %d, %s %d",nCos,__FILE__,__LINE__);
  }
  for(   ; (i<nfour); i++)
    cfour[i]= 0.0;
  
  if (bPadding) {
    aver /= nframes;
    /* printf("aver = %g\n",aver); */
    for(i=0; (i<nframes); i++)
      cfour[i] -= aver;
  }
    
  snew(ans,2*nfour);
  correl(cfour-1,cfour-1,nfour,ans-1);
  
  if (bPadding)  
    for (i=0; (i<nfour); i++)
      cfour[i] = ans[i]+sqr(aver);
  else
    for (i=0; (i<nfour); i++)
      cfour[i] = ans[i];
      
  sfree(ans);
}
Beispiel #4
0
/*FGROUP ALItools
  delta=0 -> autocor fun
  delta=1 -> -1,0,1
*/
void croscor1(int input1,int input2,int cordist,int delta,int dir){
 SSM0CHAN *in1,*in2,*in;
 w32 corfun[2*delta+1];
 int i;
 if(dir == 0)cordist=-cordist;
 for(i=0;i<(2*delta+1);i++)corfun[i]=0;
 in1=INPUTS[input1];
 in=INPUTS[input2];
 while(in1 != NULL){
  in2=in;
  while((in2 != NULL) && (in1->ssmid != in2->ssmid))in2=in2->next;
  if(in2 != NULL){
   correl(in1->bctime,in2->bctime,in1->size,in2->size,cordist,delta,corfun);
   in=in2;
  }
  in1=in1->next;
 }
 printf("Croscor: %i %i \n",input1,input2);
 for(i=0;i<2*delta+1;i++)printf("<%i> <%i> ",i-delta+cordist,corfun[i] );
 //for(i=0;i<2*delta+1;i++)printf("%i ",corfun[i] );
 printf("<input %i %i> <end>\n",input1,input2);
}
int get_tau(float y1[],float y2[],double tstart1,double tstart2,int npts,
double laglen,double sr,double *tau,float *ccc,float *cccp)
/*
      This function cross-correlates time series.  
      It is assumed that the time series are float arrays in y1 and y2.
      The additional array z is created to hold the cross-correlation series.
 
      y1,y2:       data series to be cross-correlated
      tstart1,2    start times (epoch seconds) of data series
      npts:        length of the two series
      sr:          sampling rate of the two series (not a whole number)
      laglen:      maximum amount (seconds) of offset for cross-correlation
                       laglen << npts/sr (laglen ~ 0.2 npts/sr is typical)
      tau:         signal time diff. (epoch seconds) of second - first
                   (This closely reflects the origin time difference.)
      ccc:         cross-correlation coefficient (-1 <= ccc <= 1)
      cccp:        relative amplitude of second event over first event

      return value:0 -- no error
                   1 -- real sample rate too far from integer value
                   2 -- number of requested lags is larger than length of series
                   3 -- divisor = 0.0 in computing refined tau
*/ 
{
  int         iret,len,isr,lags,kmax,i;
  float       *z;
  float       dummy,amean1,amean2,stdev1,stdev2,del,tmax,rmax;
  float       ym,y0,yp,a,b,c,tpeak,tshift;
  float       tol=0.01;
/*tol is the tolerance to allow the real sampling rate to deviate from an
  integer value; for instance for tol = 0.01, 99.99 and 100.01 are
  acceptable and are taken to be nominally 100.  This value is set here
  to 0.01, and will produce only up to 1/10 of a millisecond error in 1 sec.*/

/*Check if sample rate is nearly integer.  Some tolerance must be allowed 
  because sample rates given by CSS3.0 data may not be exactly whole 
  numbers.*/
  isr = nint(sr);
  if (fabs(isr - sr) > tol) return 1;

/*Get mean and stdev estimate and remove mean.*/
  stats(y1,npts,2,&amean1,&stdev1,&dummy,&dummy);
  for (i=0;i<npts;i++) y1[i] = y1[i] - amean1;
  stats(y2,npts,2,&amean2,&stdev2,&dummy,&dummy);
  for (i=0;i<npts;i++) y2[i] = y2[i] - amean2;

  lags = nint(laglen*sr);
  if (lags > npts) return 2;
  len = 2*lags + 1;
  z = malloc(len*sizeof(float));
  del = 1.0/sr;

/*Get cross-correlation in time domain and normalize by standard deviations.
  Normalize by stn. dev. squared of the first event to get an estimate
  of the amplitude of the second event relative to that of the first.  The
  log10 of this estimate would estimate the magnitude difference.*/

  iret = correl(y1,y2,z,npts,lags,&rmax,&kmax);

  *ccc  = rmax/(stdev1*stdev2);
  *cccp = rmax/(stdev1*stdev1);

/*Occasional cases may arise where this leads to |CCF| > 1, so reset it 
  to +/-1 if greater.  Such cases arise when the interpolated peak of the 
  cross-correlation function goes above +1 or below -1.*/
  if (*ccc >  1.0) *ccc =  1.0;
  if (*ccc < -1.0) *ccc = -1.0;

/*Compute the delay.  A positive tmax means the 2nd signal is delayed
  wrt 1st by that amount.*/
  tmax=kmax*del;
/*Pick out 3 points around maximum and compute best-fit parabola.*/
  ym = z[kmax+lags-1];
  y0 = z[kmax+lags];
  yp = z[kmax+lags+1];
  a = ( ym/2 + yp/2 - y0)/pow((double) del,(double)2);
  b = (-ym/2 + yp/2)/del;
  c = y0;
/*Peak is at relative time where derivative = 0.*/
  if (a == 0.0) 
  {
    free(z);
    return 3;
  }
  tpeak = -b/(2*a);
/*Get total time shift.*/
  tshift = tmax + tpeak;
/*Compute absolute time shift between signals.  If the 2nd is later than the 
  1st, the shift is positive.*/
  *tau = tstart2 - tstart1 + tshift;

  free(z);
  return 0;
}
Beispiel #6
0
Fluxrec *cross_corr_nr(float *flux1, float *flux2, int npoints, float dx)
{
  int i;                    /* Looping variable */
  int no_error=1;           /* Flag set to 0 on error */
  float *y1=NULL;           /* Light curve 1 fluxes */
  float *y2=NULL;           /* Light curve 2 fluxes */
  float *corrout=NULL;      /* Float output from correlation */
  float *yptr1,*yptr2;      /* Pointers to navigate y1, y2, and corrout */
  float *fptr1,*fptr2;      /* Pointers to navigate flux1 and flux2 */
  Fluxrec *xcorr=NULL;      /* Cross-correlation curve */
  Fluxrec *xptr;            /* Pointer to navigate xcorr */

  /*
   * Allocate memory for the float versions of the light curves
   */

  if(!(y1 = new_array(npoints,1))) {
    fprintf(stderr,"ERROR: cross_corr_nr\n");
    return NULL;
  }

  if(!(y2 = new_array(npoints,1)))
    no_error = 0;

  /*
   * Transfer data into y1 and y2.  We need to do this because the
   *  correl routine modifies the arrays passed to i.
   */

  if(no_error) {
    for(i=0,fptr1=flux1,fptr2=flux2,yptr1=y1,yptr2=y2; i<npoints;
	i++,fptr1++,fptr2++,yptr1++,yptr2++) {
      *yptr1 = *fptr1;
      *yptr2 = *fptr2;
    }
  }

  /*
   * Allocate memory for the output from the cross-correlation
   */

  if(no_error)
    if(!(corrout = new_array(npoints,2)))
      no_error = 0;

  /*
   * Call the correlation function.
   * NB: The -1 after y1, y2, and corrout is necessary because of the
   *  Numerical Recipes fortran convention.
   */

  if(no_error)
    correl(y1-1,y2-1,(unsigned long) npoints,corrout-1);

  /*
   * Allocate memory for output Fluxrec array
   */

  if(no_error)
    if(!(xcorr = new_fluxrec(npoints)))
      no_error = 0;

  /*
   * Fill array.  
   * *** NB: The output from correl is the cross-correlation curve with
   *         the positive values going from 0 to (npoints/2-1) and
   *         the negative values going from npoints to npoints/2.
   *         We want the array to be in the "correct" order with the most
   *         negative value at position 0 and monotonically increasing from
   *         there.  Therefore fill the array accordingly.
   */

  if(no_error) {
    for(i=0,yptr1=corrout,xptr=xcorr; i<npoints/2; i++,yptr1++,xptr++) {
      yptr2 = yptr1 + npoints/2;
      xptr->day = (i-npoints/2)*dx;
      xptr->flux = *yptr2;
      (xptr+npoints/2)->day = i*dx;
      (xptr+npoints/2)->flux = *yptr1;
    }
  }

  /*
   * Clean up and exit
   */

  y1 = del_array(y1);
  y2 = del_array(y2);
  corrout = del_array(corrout);

  if(no_error)
    return xcorr;
  else {
    fprintf(stderr,"ERROR: cross_corr_nr.\n");
    return NULL;
  }
}
Beispiel #7
0
main (int argc, char *argv[])
{
  struct em_file inputdata1;
  struct em_file inputdata2;
  struct em_file inputdata3;
  struct em_file inputdata4;
  struct em_file outputdata;

  fftw_real *Vol_tmpl_sort, *Volume, *e3, *PointCorr, *sqconv;
  fftw_complex *C3, *PointVolume, *PointSq;
  rfftwnd_plan p3, pi3, r3, ri3;
  fftw_real scale;

  struct tm *zeit;
  struct tm start;
  char name[200];
  int Rx_max, Ry_max, Rz_max;
  int Rx_min, Ry_min, Rz_min;
  int Vx_min, Vy_min, Vz_min;
  int Vx_max, Vy_max, Vz_max;
  float Phi, Psi, Theta, winkel_lauf;
  float *Rot_tmpl, *Vol_tmpl;
  int i, j, k, tmpx, tmpy, tmpz,lauf_pe, ksub;
  int ijk;
  int lauf, n;
  float max, eps;
  time_t lt;
  float Ctmp, Ctmpim, Dtmp, Dtmpim;
  int dim_fft;
  int sub[3],range[3],range_sub[3],subc[3],offset[3],dimarray[3];
  int FullVolume_dims[3];
  int nr[3];
  int area[3];
  
/* MPI Variablen */
  int winkel_max, winkel_min;
  int winkel_max_pe, winkel_min_pe;
  int winkel_step_pe;
  int Phi_max, Psi_max, Theta_max;
  int Phi_min, Psi_min, Theta_min;
  int Phi_step, Psi_step, Theta_step;
  int Theta_winkel_start, Psi_winkel_start, Phi_winkel_start;
  int Theta_winkel_nr, Psi_winkel_nr, Phi_winkel_nr;
  int Theta_winkel_end, Psi_winkel_end, Phi_winkel_end;
  int Theta_steps, Psi_steps, Phi_steps;
  float Theta_winkel_rest_nr, Psi_winkel_rest_nr, Phi_winkel_rest_nr;
  int in_max;
  float rms_wedge, tempccf;
  float *Ergebnis, *conv;
  float cycles;
  int cycle;
  
/* MPI Variablen Ende*/

  if (argc < 15)
    {
      printf ("\n\n");
      printf (" 'OSCAR' is an Optimized SCanning AlgoRithm for \n");
      printf (" local correlation.\n");
      printf (" All files in EM-V-int4 format !!!\n\n");
      printf (" Input: Volume to be searched, Template mask for local \n ");
      printf ("   correlation, pointspread function and angular search \n");
      printf ("   range. \n");
      printf (" Output: locally normalized X-Correlation Function Out.ccf.norm, \n");
      printf ("   non-normalized X-Correlation Function Out.ccf, and Out.ang \n");
      printf ("   with the corresponding angles.\n\n");
      printf (" usage: oscar Volume Template Out ...\n");
      printf ("         ... Phi_min Phi_max Phi_step Psi_min Psi_max Psi_step The_min The_max The_step\n");
      printf ("    ... Poinspread-function mask-file dim_of_fft\n\n");
      printf (" with Message Passing Interface (MPI)\n");
      printf (" the total number of angles must be modulo\n");
      printf (" of used processors!\n\n");
      printf (" Linux:   	1.'lamboot' to start MPI\n");
      printf ("		2.'mpirun -np 2 oscar Volume Templ Out 30 180 30 30 180 30 30 180 30 Poinspread-function mask-file 256'\n\n");
      printf (" In this version asymmetric masks can be used ! \n");
      printf (" last revision  ,  11.11.03, Friedrich Foerster");
      printf (" \n\n");
      exit (1);
    }

  MPI_Init (&argc, &argv);
  MPI_Comm_size (MPI_COMM_WORLD, &mysize);
  MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
  /* Dimensionen auslesen */
  // Dimension of fft
  dim_fft = atoi (argv[15]);
  nr[0]=1;
  nr[1]=1;
  nr[2]=1;
  area[0]=dim_fft;
  area[1]=dim_fft;
  area[2]=dim_fft;
  read_em_header(argv[1], &inputdata1); /* Searchvolume */
  read_em (argv[2], &inputdata2); /* Template */
  FullVolume_dims[0]=inputdata1.dims[0];
  FullVolume_dims[1]=inputdata1.dims[1];
  FullVolume_dims[2]=inputdata1.dims[2];
  Rx_min = 1;
  Ry_min = 1;
  Rz_min = 1;
  Rx_max = (inputdata2.dims[0]);
  Ry_max = (inputdata2.dims[1]);
  Rz_max = (inputdata2.dims[2]);
  Vx_min = 1;
  Vy_min = 1;
  Vz_min = 1;
  Vx_max = dim_fft;
  Vy_max = dim_fft;
  Vz_max = dim_fft;
  p3 = rfftw3d_create_plan (Vx_max, Vy_max, Vz_max, FFTW_REAL_TO_COMPLEX,
			    FFTW_MEASURE | FFTW_IN_PLACE);	/*FFTW_ESTIMATE FFTW_MEASURE */
  pi3 = rfftw3d_create_plan (Vx_max, Vy_max, Vz_max, FFTW_COMPLEX_TO_REAL,
			     FFTW_MEASURE | FFTW_IN_PLACE);
  r3 = rfftw3d_create_plan (Rx_max, Rx_max, Rx_max, FFTW_REAL_TO_COMPLEX,
  		    FFTW_MEASURE | FFTW_IN_PLACE);	/*FFTW_ESTIMATE FFTW_MEASURE */
  ri3 = rfftw3d_create_plan (Rx_max, Rx_max, Rx_max, FFTW_COMPLEX_TO_REAL,
  		     FFTW_MEASURE | FFTW_IN_PLACE);
  if (myrank == 0)
    {
      printf("Plans for FFTW created \n");fflush(stdout);
    }
  Volume = (fftw_real *) calloc (Vx_max * Vx_max * 2 * (Vx_max / 2 + 1),sizeof (fftw_real) );
  Rot_tmpl = (float *) malloc (sizeof (float) * Rx_max * Ry_max * Rz_max);
  Vol_tmpl = (float *) malloc (sizeof (float) * Vx_max * Vy_max * Vz_max);
  conv = (float *) malloc (sizeof (float) * Vx_max * Vy_max * Vz_max);
  sqconv = (fftw_real *) calloc(Vz_max * Vy_max * 2 * (Vx_max / 2 + 1), sizeof (fftw_real));
  if (!
      (inputdata1.floatdata =
       (float *) malloc (sizeof (float) * Vx_max * Vy_max * Vz_max)))
    {
      printf ("Memory allocation  failure in inputdata1.floatdata!!!");
      fflush (stdout);
      exit (1);
    }
  if (!
      (outputdata.floatdata =
       (float *) malloc (sizeof (float) * Vx_max * Vy_max * Vz_max)))
    {
      printf ("Memory allocation  failure in outputdata.floatdata!!!");
      fflush (stdout);
      exit (1);
    }
  
  if (!
      (Vol_tmpl_sort = (fftw_real *) calloc (Vz_max*Vy_max*2*(Vx_max / 2 + 1), sizeof (fftw_real) )))
    {
      printf ("Memory allocation  failure in Volume_tmpl_sort!!!");
      printf ("Nx = %i, Ny = %i, Nz = %i, bytes = %i \n",2 *(Vx_max / 2 + 1),Vy_max, Vz_max, sizeof (fftw_real));
      fflush (stdout);
      exit (1);
    }
  Ergebnis = (float *) calloc (Vz_max * Vy_max * Vx_max, sizeof (float));
   /* Winkelraum */
  Phi_min = atof (argv[4]);
  Phi_max = atof (argv[5]);
  Phi_step = atof (argv[6]);
  Psi_min = atof (argv[7]);
  Psi_max = atof (argv[8]);
  Psi_step = atof (argv[9]);
  Theta_min = atof (argv[10]);
  Theta_max = atof (argv[11]);
  Theta_step = atof (argv[12]);
  /* Pointspread Function*/
  read_em (argv[13], &inputdata3);
  /* mask function */
  read_em (argv[14], &inputdata4);
  Phi_steps = (Phi_max - Phi_min) / Phi_step + 1;
  Psi_steps = (Psi_max - Psi_min) / Psi_step + 1;
  Theta_steps = (Theta_max - Theta_min) / Theta_step + 1;
  winkel_max = Phi_steps * Psi_steps * Theta_steps;
  winkel_min = 0;
  range[0]=dim_fft-1;
  range[1]=dim_fft-1;
  range[2]=dim_fft-1;
  range_sub[0]=range[0]-Rx_max;
  range_sub[1]=range[1]-Rx_max;
  range_sub[2]=range[2]-Rx_max;
  sub[0]=1;
  sub[1]=1;
  sub[2]=1;
  cycles=(int)(FullVolume_dims[2]/(dim_fft-Rx_max)+0.5);
  cycles=(int)(FullVolume_dims[1]/(dim_fft-Rx_max)+0.5)*cycles;
  cycles=(int)(FullVolume_dims[0]/(dim_fft-Rx_max)+0.5)*cycles;
  cycle=0;
  if (myrank == 0)
    {
      printf ("\n oscar starts to run ... ");tack (&start);fflush (stdout);
      /* prepare Output */
      strcpy (name, argv[3]);
      strcat (name, ".ccf");
      printf ("\nCreate outputfile: %s ... \n", name);fflush(stdout);
      create_em (name, FullVolume_dims);
      strcpy (name, argv[3]);
      strcat (name, ".ang");
      printf ("Create outputfile: %s ... \n", name);fflush(stdout);
      create_em (name, FullVolume_dims);
      strcpy (name, argv[3]);
      strcat (name, ".ccf.norm");
      printf ("Create outputfile: %s ... \n", name);fflush(stdout);
      create_em (name, FullVolume_dims);
    }
  for (sub[2]=1; sub[2] < FullVolume_dims[2]-Rz_max;sub[2]=sub[2]+dim_fft-Rz_max)
    {		  
    if (myrank == 0)
	{
	tack (&start);
	printf ("%f%%..", (float) (cycle / cycles * 100));
	fflush (stdout);
	}

      for (sub[1]=1; sub[1] < FullVolume_dims[1]-Ry_max;sub[1]=sub[1]+dim_fft-Ry_max)
        {
	  for (sub[0]=1; sub[0] < FullVolume_dims[0]-Rx_max;sub[0]=sub[0]+dim_fft-Rx_max)
	    {
	      cycle=cycle+1;
	      subc[0]=sub[0];
	      subc[1]=sub[1];
	      subc[2]=sub[2]; 
	      if (sub[2] + range[2] > FullVolume_dims[2]) subc[2]=FullVolume_dims[2]-range[2];  /* we are at the corner ?!*/
	      if (sub[1] + range[1] > FullVolume_dims[1]) subc[1]=FullVolume_dims[1]-range[1];  /* we are at the corner ?!*/
	      if (sub[0] + range[0] > FullVolume_dims[0]) subc[0]=FullVolume_dims[0]-range[0];  /* we are at the corner ?!*/
	      read_em_subregion (argv[1], &inputdata1,subc,range);
	      read_em_subregion (argv[1], &outputdata,subc,range);
	      /* Umsortieren der Daten */
	      lauf = 0;
	      for (k = 0; k < Vz_max; k++)
		{
		  for (j = 0; j < Vy_max; j++)
		    {
		      for (i = 0; i < Vx_max; i++)
			{
			  /* square - needed for normalization */
			  sqconv[i + 2 * (Vx_max / 2 + 1) * (j + Vy_max * k)] = inputdata1.floatdata[lauf]*inputdata1.floatdata[lauf];
			  Volume[i + 2 * (Vx_max / 2 + 1) * (j + Vy_max * k)] = inputdata1.floatdata[lauf];
			  inputdata1.floatdata[lauf] = -1.0; /* kleine Zahl wg Max-Op , hier kommen die CCFs rein*/
			  outputdata.floatdata[lauf] = -1.0; /* hier kommen die Winkel rein*/
			  lauf++;
			}
		    }
		}
	      rfftwnd_one_real_to_complex (p3, &Volume[0], NULL); /* einmalige fft von Suchvolumen */
	      rfftwnd_one_real_to_complex (p3, &sqconv[0], NULL); /* FFT of square*/
	      winkel_step_pe = (int) winkel_max / mysize;
	      winkel_min_pe = myrank * winkel_step_pe;
	      winkel_max_pe = winkel_min_pe + winkel_step_pe;
	      Theta_winkel_nr = (int) winkel_min_pe / (Psi_steps * Phi_steps);
	      Theta_winkel_rest_nr = winkel_min_pe - Theta_winkel_nr * (Psi_steps * Phi_steps);
	      Psi_winkel_nr = (int) Theta_winkel_rest_nr / (Phi_steps);
	      Psi_winkel_rest_nr = Theta_winkel_rest_nr - Psi_winkel_nr * (Phi_steps);
	      Phi_winkel_nr = (int) Psi_winkel_rest_nr;
	      Theta = Theta_winkel_nr * Theta_step + Theta_min;
	      Phi = Phi_winkel_nr * Phi_step + Phi_min - Phi_step;
	      Psi = Psi_winkel_nr * Psi_step + Psi_min;
	      eps = 0.001;
	      n = 0;
	      //Friedrich -> Zaehlung der voxels 
	      n = countvoxel(inputdata4.dims[0], inputdata4.floatdata, eps);
	      eps = 0.001;
	      for (winkel_lauf = winkel_min_pe; winkel_lauf < winkel_max_pe;winkel_lauf++)
		{
		  if (Phi < Phi_max)
		    Phi = Phi + Phi_step;
		  else
		    {
		      Phi = Phi_min;
		      Psi = Psi + Psi_step;
		    }
		  if (Psi > Psi_max)
		    {
		      Psi = Psi_min;
		      Theta = Theta + Theta_step;
		    }
		  tom_rotate3d (&Rot_tmpl[0], &inputdata2.floatdata[0], Phi, Psi, Theta, Rx_max, Ry_max, Rz_max);
		  /*calculate Ref variance */
		  rms_wedge = energizer (Rx_min, Rx_max, n, &Rot_tmpl[0], &inputdata3.floatdata[0], &inputdata4.floatdata[0], r3, ri3); 
		  pastes (&Rot_tmpl[0], &Vol_tmpl[0], 1, 1, 1, Rx_max, Ry_max, Rz_max, Vx_max);
		  scale = 1.0 / ((double)Vx_max * (double)Vy_max * (double)Vz_max * ((double) rms_wedge) );
		  //printf("hippo1: scale = %.10f \n",scale);
		  sort4fftw(&Vol_tmpl_sort[0],&Vol_tmpl[0],Vx_max, Vy_max, Vz_max);
		  rfftwnd_one_real_to_complex (p3, &Vol_tmpl_sort[0], NULL);
		  PointVolume = (fftw_complex *) & Volume[0];
		  C3 = (fftw_complex *) & Vol_tmpl_sort[0];
		  /* Correlation */
		  correl(&PointVolume[0], &C3[0], Vx_max, Vy_max, Vz_max, scale);
		  /* back to real space */
		  rfftwnd_one_complex_to_real (pi3, &C3[0], NULL);
		  PointCorr = (fftw_real *) & C3[0];
		  /* Umsortieren der Daten */
		  sortback4fftw( &PointCorr[0], &Ergebnis[0], Vx_max, Vy_max, Vz_max);
		  // crossen 
		  cross(&Ergebnis[0], Vx_max);
		  /* 3rd: divide */
		  lauf = 0;
		  for (k = 0 ; k < Vz_max  ; k++)
		    {
		      for (j = 0; j < Vy_max; j++)
			{
			  for (i = 0; i < Vx_max; i++)
			    {
			      if (inputdata1.floatdata[lauf] < Ergebnis[lauf] )
				{
				  inputdata1.floatdata[lauf] = Ergebnis[lauf];
				  outputdata.floatdata[lauf] = (int) winkel_lauf;
				}
			      lauf++;
			    }
			}
		    }
		}				/* Ende winkel_lauf */
	      //FF
	      MPI_Barrier (MPI_COMM_WORLD);
	      /* Ergebnisse einsammeln (myrank 0)*/
	      if (myrank == 0)
		{
		  for (lauf_pe = 1; lauf_pe < mysize; lauf_pe++)
		    {
		      MPI_Recv (&Ergebnis[0], Vx_max * Vy_max * Vz_max, MPI_FLOAT, lauf_pe,
				99, MPI_COMM_WORLD, &status);
		      MPI_Recv (&conv[0], Vx_max * Vy_max * Vz_max, MPI_FLOAT,
				lauf_pe, 98, MPI_COMM_WORLD, &status);
		      /* use conv as temporary memory for angles  */
		      for (lauf = 0; lauf < Vx_max * Vy_max * Vz_max; lauf++)
			{
			  if (inputdata1.floatdata[lauf] < Ergebnis[lauf])
			    {
			      inputdata1.floatdata[lauf] = Ergebnis[lauf];
			      outputdata.floatdata[lauf] = conv[lauf];
			    }
			}
		    }
		  /*Ergebnisse eingesammelt */
		  
		}
	      // myrank > 0: Ergebnisse senden
	      else
		{
		  MPI_Send (inputdata1.floatdata, Vx_max * Vy_max * Vz_max, MPI_FLOAT, 0,
			    99, MPI_COMM_WORLD);
		  MPI_Send (outputdata.floatdata, Vx_max * Vy_max * Vz_max, MPI_FLOAT, 0,
			    98, MPI_COMM_WORLD);
		}
	      MPI_Barrier (MPI_COMM_WORLD);
	      // nicht normalisiertes Volumen und Winkel rausschreiben
	      subc[0]=subc[0]+Rx_max/2;
	      subc[1]=subc[1]+Rx_max/2;
	      subc[2]=subc[2]+Rx_max/2;
	      if (myrank==0)
		{
		  offset[0]=Rx_max/2;
		  offset[1]=Rx_max/2;
		  offset[2]=Rx_max/2;
		  dimarray[0]=dim_fft;
		  dimarray[1]=dim_fft;
		  dimarray[2]=dim_fft;
		  strcpy (name, argv[3]);
		  strcat (name, ".ccf");
		  write_em_subsubregion (name, &inputdata1,subc,range_sub,offset,dimarray); 
		  strcpy (name, argv[3]);
		  strcat (name, ".ang");
		  write_em_subsubregion (name, &outputdata,subc,range_sub,offset,dimarray);
		  /* ------------------- normalization - here only PE 0 ---------- */
		  pastes (&inputdata4.floatdata[0], &Vol_tmpl[0], 1, 1, 1, Rx_max, Ry_max, Rz_max, Vx_max); /* paste mask into zero volume*/
		  /* 1st local mean */
		  sort4fftw(&Vol_tmpl_sort[0], &Vol_tmpl[0], Vx_max, Vy_max, Vz_max);
		  rfftwnd_one_real_to_complex (p3, &Vol_tmpl_sort[0], NULL);
		  C3 = (fftw_complex *) & Vol_tmpl_sort[0];
		  /* Convolution of volume and mask */
		  scale = 1.0 / ((double)Vx_max * (double)Vy_max * (double)Vz_max );
		  convolve( &PointVolume[0], &C3[0], Vx_max, Vy_max, Vz_max, scale);
		  rfftwnd_one_complex_to_real (pi3, &C3[0], NULL);
		  PointCorr = (fftw_real *) & C3[0];
		  /* Umsortieren der Daten */
		  sortback4fftw( &PointCorr[0], &conv[0], Vx_max, Vy_max, Vz_max);
		  /* 2nd : convolution of square and resorting*/
		  pastes (&inputdata4.floatdata[0], &Vol_tmpl[0], 1, 1, 1, Rx_max, Ry_max, Rz_max, Vx_max); /* paste mask into zero volume*/
		  sort4fftw( &Vol_tmpl_sort[0], &Vol_tmpl[0], Vx_max, Vy_max, Vz_max);
		  rfftwnd_one_real_to_complex (p3, &Vol_tmpl_sort[0], NULL);
		  C3 = (fftw_complex *) & Vol_tmpl_sort[0];
		  PointSq = (fftw_complex *) & sqconv[0];// set pointer to FFT of square
		  convolve( &PointSq[0], &C3[0], Vx_max, Vy_max, Vz_max, scale);
		  rfftwnd_one_complex_to_real (pi3, &C3[0], NULL);
		  PointCorr = (fftw_real *) &C3[0];
		  //FF
		  lauf = 0;
		  for (k = 0; k < Vz_max; k++)
		    {
		      for (j = 0; j < Vy_max; j++)
			{
			  for (i = 0; i < Vx_max; i++)
			    {
			      conv[lauf] = sqrt(PointCorr[i + 2 * (Vx_max / 2 + 1) * (j + Vy_max * k)] - conv[lauf]*conv[lauf]/((float) n) ) ;/*local variance*/
			      lauf++;
			    }
			}
		    }
		  cross(&conv[0], Vx_max);
		  /* perform division */
		  for (lauf = 0; k < Vz_max*Vy_max*Vz_max; lauf++)
		    {
		      if (conv[lauf] > eps)
			{
			  inputdata1[lauf].floatdata = inputdata1[lauf].floatdata/conv[lauf];
			}
		      else
			{
			  inputdata1[lauf].floatdata = 0;
			}
		    }
		  strcpy (name, argv[3]);
		  strcat (name, ".ccf.norm");
		  write_em_subsubregion (name, &inputdata1,subc,range_sub,offset,dimarray);
		}
	      MPI_Barrier (MPI_COMM_WORLD);
	    }
	} /* these are the new brackets from the subregion_read , SN */
    }
  free(Ergebnis);
  free(inputdata1.floatdata);  
  free(inputdata2.floatdata);
  free(inputdata3.floatdata);
  free(inputdata4.floatdata);
  rfftwnd_destroy_plan(p3);
  rfftwnd_destroy_plan(pi3);
  rfftwnd_destroy_plan(r3);
  rfftwnd_destroy_plan(ri3);
  free(Volume);
  free(sqconv);
  free(conv);
  free(Rot_tmpl);
  free(Vol_tmpl_sort);
  free(outputdata.floatdata);
  if (myrank==0)
    {
      printf ("oscar finished. ");
      tack (&start); fflush(stdout);
    }
  MPI_Finalize();

  /* end main */
}