Пример #1
0
VecDoub PressureTable::DensityFromP(VecDoub_I vec) {
  double Press = vec[0]*P_scale;
  double rho;
  VecDoub vec_out(1, 0.0);

  int nPress = GetDimension1();
  double P_min = GetCoordinate1(0);
  double P_max = GetCoordinate1(nPress-1);

  if (Press <= P_max) {
    if (Press >= P_min) {
      rho = Lookup(Press,Z_newton,Zv_newton,C_newton,"rho0");
    } else {
      double rho_min = Lookup(P_min,Z_newton,Zv_newton,C_newton,"rho0");
      rho = rho_min*Press/P_min;
    }
  } else {
    double rho_max = Lookup(P_max,Z_newton,Zv_newton,C_newton,"rho0");
    rho = rho_max*Press/P_max;
  }

  vec_out[0] = rho-rho_newton;
  if (verbose_newton) {
    cout << "( " << Press << " ) => ( " 
         << rho << " vs " << rho_newton << " )"
         << endl;
  }
  return vec_out;
}
Пример #2
0
VecDoub PressureTable::YcAndDensityFromCPT(VecDoub_I vec) {
  double eps = 1.0e-4;
  double C = vec[0];
  double Press = vec[1]*P_scale;
  double Yc;
  double rho;
  VecDoub vec_out(2, 0.0);

  double Yc_eq  = Lookup(Press,Z_newton,Zv_newton,1.0,"PROG");
  Yc = C*Yc_eq;
  // Define Yc to find the solution C=0 when Yc_eq = 0 (necessary for Z=0 or 1, Sz = 1)
  if (Yc_eq == 0.0) {
    Yc = Yc_newton + C;
  } else if (Yc_eq < eps) {
  //                                 or when Yc_eq < eps
    Yc = Yc_newton*C;
  }

  double RoM = Lookup(Press, Z_newton,Zv_newton,C, "RoM");
  rho = Press/(RoM*T_newton);

  vec_out[0] = Yc-Yc_newton;
  vec_out[1] = rho-rho_newton;
  if (verbose_newton) {
    cout << "( " << C << " , " << Press << " ) => ( "
         << vec_out[0] << " , " << vec_out[1] << " )"
         << endl;
    cout << "Yc : " << Yc << " vs " << Yc_newton << endl;
    cout << "rho : " << rho << " vs " << rho_newton << endl;
  }
  return vec_out;
}
Пример #3
0
VecDoub PressureTable::DensityFromPT(VecDoub_I vec) {
  double Press = vec[0]*P_scale;
  double rho;
  VecDoub vec_out(1, 0.0);

  double RoM = Lookup(Press, Z_newton,Zv_newton,C_newton, "RoM");
  rho = Press/(RoM*T_newton);

  vec_out[0] = rho-rho_newton;
  if (verbose_newton) {
    cout << "( " << Press << " ) => ( "
         << rho << " vs " << rho_newton << " )"
         << endl;
  }
  return vec_out;
}
Пример #4
0
VecDoub PressureTable::YcAndDensityFromCP(VecDoub_I vec) {
  double eps = 1.0e-4;
  double C = vec[0];
  double Press = vec[1]*P_scale;
  double Yc;
  double rho;
  VecDoub vec_out(2, 0.0);

  double Yc_eq  = Lookup(Press,Z_newton,Zv_newton,1.0,"PROG");
  Yc = C*Yc_eq;
  // Define Yc to find the solution C=0 when Yc_eq = 0 (necessary for Z=0 or 1, Sz = 1)
  if (Yc_eq == 0.0) {
    Yc = Yc_newton + C;
  } else if (Yc_eq < eps) {
  //                                 or when Yc_eq < eps
    Yc = Yc_newton*C;
  }

  int nPress = GetDimension1();
  double P_min = GetCoordinate1(0);
  double P_max = GetCoordinate1(nPress-1);

  if (Press <= P_max) {
    if (Press >= P_min) {
      rho = Lookup(Press,Z_newton,Zv_newton,C,"rho0");
    } else {
      double rho_min = Lookup(P_min,Z_newton,Zv_newton,C,"rho0");
      rho = rho_min*Press/P_min;
    }
  } else {
    double rho_max = Lookup(P_max,Z_newton,Zv_newton,C,"rho0");
    rho = rho_max*Press/P_max;
  }


  vec_out[0] = Yc-Yc_newton;
  vec_out[1] = rho-rho_newton;
  if (verbose_newton) {
    cout << "( " << C << " , " << Press << " ) => ( "
         << vec_out[0] << " , " << vec_out[1] << " )"
         << endl;
    cout << "Yc : " << Yc << " vs " << Yc_newton << endl;
    cout << "rho : " << rho << " vs " << rho_newton << endl;
  }
  return vec_out;
}
Пример #5
0
VecDoub PressureTable::YcAndDensityFromCP_new(VecDoub_I vec) {
  double eps = 1.0e-4;
  double C = vec[0];
  double Press = vec[1]*P_scale;
  double Yc;
  double rho;
  VecDoub vec_out(2, 0.0);

  double Yc_eq  = Lookup(Press,Z_newton,Zv_newton,1.0,"PROG");
  Yc = C*Yc_eq;
  // Define Yc to find the solution C=0 when Yc_eq = 0 (necessary for Z=0 or 1, Sz = 1)
  if (Yc_eq == 0.0) {
    Yc = Yc_newton + C;
  } else if (Yc_eq < eps) {
  //                                 or when Yc_eq < eps
    Yc = Yc_newton*C;
  }

  double RoM, T0, E0, GAMMA0, AGAMMA;
  LookupSelectedCoeff(RoM, T0, E0, GAMMA0, AGAMMA, Press, Z_newton,Zv_newton,C);
  double Temp;
  if (AGAMMA == 0.0)
    Temp = T0 + (GAMMA0 - 1.0) / RoM * (E_newton - E0);
  else
    Temp = T0 + (GAMMA0 - 1.0) / AGAMMA * (exp(AGAMMA * (E_newton - E0) / RoM) - 1.0);

  rho = Press/(RoM*Temp);

  vec_out[0] = Yc-Yc_newton;
  vec_out[1] = rho-rho_newton;
  if (verbose_newton) {
    cout << "( " << C << " , " << Press << " ) => ( "
         << vec_out[0] << " , " << vec_out[1] << " )"
         << endl;
    cout << "Yc : " << Yc << " vs " << Yc_newton << endl;
    cout << "rho : " << rho << " vs " << rho_newton << endl;
  }
  return vec_out;
}
Пример #6
0
VecDoub PressureTable::DensityFromP_new(VecDoub_I vec) {
  double Press = vec[0]*P_scale;
  double rho;
  VecDoub vec_out(1, 0.0);

  double RoM, T0, E0, GAMMA0, AGAMMA;
  LookupSelectedCoeff(RoM, T0, E0, GAMMA0, AGAMMA, Press, Z_newton,Zv_newton,C_newton);
  double Temp;
  if (AGAMMA == 0.0)
    Temp = T0 + (GAMMA0 - 1.0) / RoM * (E_newton - E0);
  else
    Temp = T0 + (GAMMA0 - 1.0) / AGAMMA * (exp(AGAMMA * (E_newton - E0) / RoM) - 1.0);

  rho = Press/(RoM*Temp);

  vec_out[0] = rho-rho_newton;
  if (verbose_newton) {
    cout << "( " << Press << " ) => ( "
         << rho << " vs " << rho_newton << " )"
         << endl;
  }
  return vec_out;
}
Пример #7
0
// moving average on vector nPoints a,(b,(c)) of given sensor, thread safe
// container: unique class object
// xma:      average type
// pv:       use xma to smooth position or velocity
// nPoints:  window length, longer window equals smoother results, but slower end-point convergence
//              estimate: nPoints = freq *  w_time; [s = 1/s * s]
// initEndEff:  user set start point
void moving_average(DataContainer* container, int sensor_in)
{
  // xma average type
  int xma = container->getInt(1);
  int pv = container->getInt(2);
  int nPoints = container->getInt(3);
  // tell container in getVec which flag to strike
  int accessor;
  // to smooth vector entries
  int a = 0;
  int b = 0;
  int c = 0;
  // interactive marker menu 1:notchecked 2:checked
  double ui_validjumps = 1;
  // iteration counter
  int count = 1;
  // invalid iteration counter
  int invalidCount = 0;
  // time between last saved window-entry
  double t_delta = 0.;
  // smoothed entries
  double x = 0.;
  double y = 0.;
  double z = 0.;
  // velocity is calculated by the last two smoothed entries divided by their t_delta
  // Suffix _delta indicates incremental steps.
  double v_x = 0.;
  double v_y = 0.;
  double v_z = 0.;
  double x_delta = 0.;
  double y_delta = 0.;
  double z_delta = 0.;
  double v_x_delta = 0.;
  double v_y_delta = 0.;
  double v_z_delta = 0.;
  // EMA adjusting factor
  double alpha;
  // XMA weights
  std::vector<double> weights;
  // temporary for setVec, p:3,4,5 v:6,7,8
  std::vector<double> vec_out(9, 0);
  // first t_delta will therefore be huge
  vec_out[0] = ros::Time::now().toNSec();
  // info on how many points were involved
  vec_out[2] = nPoints;
  // temporary vector for getVec
  std::vector<double> tmp(6, 0);
  // intital end-effector position
  std::vector<double> initEndEff(6, 0);
  // window holds past nPoints, w[length-1] is the oldest entry
  std::vector<std::vector<double> > w;
  // timespan before rechecking Flag
  struct timespec req, rem;
  req.tv_sec = 0;
  req.tv_nsec = 30000000;  // 33Hz

  if (sensor_in == 15)
  {  // 3D point
    accessor = 1;
    a = 3;
    b = 4;
    c = 5;
    initEndEff[0] = ros::Time::now().toNSec();
    initEndEff[1] = sensor_in;
    initEndEff[2] = nPoints;
    initEndEff[3] = container->getInt(5);
    initEndEff[4] = container->getInt(6);
    initEndEff[5] = container->getInt(7);
    for (int i = 0; i < nPoints; ++i)
    {
      w.push_back(initEndEff);
    }
    vec_out[1] = 16;
  }
  else
  {
    ROS_ERROR(NNAME": xma for Sensor_in %d not set up.", sensor_in);
    return;
  }

  // calculate weights
  weights.resize(nPoints, 1. / nPoints);  // SMA
  if (xma == 1)
  {  // LMA
    double sum = 0.;
    for (int i = 1; i <= nPoints; ++i)
    {
      weights[nPoints - i] = 1. / nPoints * i;
      sum += 1. / nPoints * i;
    }
    // normalize, division gets superfluous
    for (int i = 0; i < nPoints; ++i)
      weights[i] /= sum;
  }
  else if (xma == 2)
  {  // EMA
    // choose alpha (0;1), close to 1: aggressive response
    // 0: stay on init value
    // 1: output the input
    alpha = nPoints/100;
  }

  while (!ros::isShuttingDown() && container->getInt(14) == 0)
  {
    // do until valid vector
    bool valid = false;
    while (!valid)
    {
      if (container->checkVecFlag(accessor, sensor_in) == 1)
      {
        container->getVec(accessor, sensor_in, tmp);

        if (validPoint(container, tmp, w[0]))
        {
          valid = true;
          w.insert(w.begin(), 1, tmp);
          w.pop_back();
          container->setInt(12, 0);
          invalidCount = 0;
        }
        else if (invalidCount > 90)
        {
          container->setInt(12, 1);
          invalidCount = 0;
        }
        else
        {
          invalidCount++;
        }
      }
      else
      {
        nanosleep(&req, &rem);
        if (ros::isShuttingDown()) {
          return;
        }
      }
    }

    if (xma < 2)
    {  // SMA LMA
      x = 0.;
      y = 0.;
      z = 0.;
      for (int i = 0; i < nPoints; ++i)
      {
        x += w[i][a] * weights[i];
        y += w[i][b] * weights[i];
        z += w[i][c] * weights[i];
      }
    }
    else
    {  // EMA
      x = alpha * w[0][a] + (1. - alpha) * vec_out[3];
      y = alpha * w[0][b] + (1. - alpha) * vec_out[4];
      z = alpha * w[0][c] + (1. - alpha) * vec_out[5];
    }

    // calculate deltas and (velocity @EXPERIMENTAL), change!
    if (accessor == 1)
      t_delta = (w[0][0] - vec_out[0]);  // kinect uses secs
    else
      t_delta = (w[0][0] - vec_out[0]) * 1e-9;  // android nsces to secs

    if (pv > 0)
    {
      x_delta = x - vec_out[3];
      y_delta = y - vec_out[4];
      z_delta = z - vec_out[5];
      if (pv > 1)
      {
        v_x = x_delta / t_delta;
        v_y = y_delta / t_delta;
        v_z = z_delta / t_delta;
        if (pv > 2 && count > 0)
        {
          v_x_delta = (v_x - vec_out[6]);
          v_y_delta = (v_y - vec_out[7]);
          v_z_delta = (v_z - vec_out[8]);
        }
      }
    }

    // refresh outgoing vector
    vec_out[0] = w[0][0];
    if (pv == 0)
    {
      vec_out[3] = x;
      vec_out[4] = y;
      vec_out[5] = z;
    }
    else if (pv == 1)
    {
      vec_out[3] = x_delta;
      vec_out[4] = y_delta;
      vec_out[5] = z_delta;
    }
    else if (pv == 2)
    {
      vec_out[3] = v_x;
      vec_out[4] = v_y;
      vec_out[5] = v_z;
    }
    else if (pv == 3 && count > 0)
    {
      vec_out[3] = v_x_delta;
      vec_out[4] = v_y_delta;
      vec_out[5] = v_z_delta;
    }
    container->setVec(vec_out);

    // hold on to data for next loop
    if (pv > 0)
    {
      vec_out[3] = x;
      vec_out[4] = y;
      vec_out[5] = z;
      if (pv > 2)
      {
        vec_out[6] = v_x;
        vec_out[7] = v_y;
        vec_out[8] = v_z;
      }
    }
    count++;
  }
}
int complement_match (Representation* X_rep, Representation* Y_rep,
		      Map * map, int map_max,
		      int * map_ctr, int * map_best, int best_max, int parent_map){
			
    Penalty_parametrization penalty_params; /* for SW */
    double **x    = X_rep->full;
    int * x_type  = X_rep->full_type;
    int NX        = X_rep->N_full;
    double **y    = Y_rep->full;
    int * y_type  = Y_rep->full_type;
    int NY        = Y_rep->N_full;
    
    double F_effective = 0.0;
    double F_current;
    double q[4] = {0.0}, q_init[4] = {0.0};
    double **x_rotated = NULL;
    double **tr_x_rotated = NULL;
    double **R;
    double z_scr = 0.0, *z_best;
    double avg, avg_sq, stdev;
    double alpha = options.alpha;
    double rmsd, best_rmsd[TOP_RMSD];
    double **best_quat;
    double cutoff_rmsd = 3.0; /* <<<<<<<<<<<<<<<<< hardcoded */
    int *x_type_fudg, *y_type_fudg;
    int *anchor_x, *anchor_y, no_anchors;
    int no_top_rmsd = TOP_RMSD, chunk;
    int x_ctr, y_ctr, top_ctr;
    int **best_triple_x;
    int **best_triple_y;
    int x_triple[3], y_triple[3];
    int retval, done = 0;
    int best_ctr;
    int i, j;
    int t;
    int smaller;
    int my_map_ctr;
    int stored_new;
    int * x2y, map_unstable;
    //time_t  time_now, time_start;
    
    int cull_by_dna (Representation * X_rep, int *set_of_directions_x,
		 Representation * Y_rep, int *set_of_directions_y,
		     int set_size, Map *map, double cutoff_rmsd);
    int distance_of_nearest_approach (Representation * X_rep, int *set_of_directions_x,
				      Representation * Y_rep, int *set_of_directions_y,
				      int set_size,  double * rmsd_ptr);
    int same_hand_triple (Representation * X_rep, int *set_of_directions_x,
			  Representation * Y_rep, int *set_of_directions_y, int set_size);
    
    int find_map (Penalty_parametrization * params, Representation *X_rep,  Representation *Y_rep,
		  double ** R, double alpha, double * F_effective,  Map *map, 
		  int *anchor_x, int * anchor_y, int anchor_size );
    int find_next_triple (double **X, double **Y, 
			  int *x_type, int *y_type, int NX, int NY,
			  int *x_triple, int *y_triple);
    int gradient_descent (int first_call, double alpha,
			  double **x, int * x_type, int NX,
			  double **y, int * y_type, int NY,
			  double *q_best, double *F_best_ptr) ;
    int map_quality_metrics (Representation *X_rep, Representation *Y_rep,
			     double ** tr_x_rotated, Map * map, int *reasonable_angle_ct);
    int monte_carlo (double alpha,
		 double **x, int * x_type, int NX,
		 double **y, int * y_type, int NY,
		 double  *q_best, double *F_best_ptr);
    int opt_quat (double ** x, int NX, int *set_of_directions_x,
		  double ** y, int NY, int *set_of_directions_y,
		  int set_size, double * q, double * rmsd);
    int qmap (double *x0, double *x1, double *y0, double *y1, double * quat);
    int store_sorted (Map * map, int NX, int NY, int *map_best, int map_max,
		      double * z_best, int best_ctr,
		      double z_scr, int  my_map_ctr, int *stored);
    
	    
    
    map_best[0] = -1; /* it is the end-of-array flag */
    if ( *map_ctr >= map_max ) {
	fprintf (stderr, "Map array undersized.\n");
	exit (1);
    }

    smaller = (NX <= NY) ? NX : NY;
 
    /***********************/
    /* memory allocation   */
    /***********************/
    if ( ! (R=dmatrix(3,3) ) ) return 1; /* compiler is bugging me otherwise */
    if ( ! (x_rotated    = dmatrix (NX,3)) ) return 1;
    if ( ! (tr_x_rotated = dmatrix (NX,3)) ) return 1;
    if ( ! (best_quat    = dmatrix (no_top_rmsd,4)) ) return 1;
    if ( ! (best_triple_x    = intmatrix (no_top_rmsd,3)) ) return 1;
    if ( ! (best_triple_y    = intmatrix (no_top_rmsd,3)) ) return 1;
    if ( ! (z_best = emalloc(NX*NY*sizeof(double) )) ) return 1;
    if ( ! (x_type_fudg = emalloc(NX*sizeof(int) )) ) return 1;
    if ( ! (y_type_fudg = emalloc(NY*sizeof(int) )) ) return 1;
    if ( ! (anchor_x = emalloc(NX*sizeof(int) )) ) return 1;
    if ( ! (anchor_y = emalloc(NY*sizeof(int) )) ) return 1;

    penalty_params.custom_gap_penalty_x = NULL;
    penalty_params.custom_gap_penalty_y = NULL;
    //if ( ! (penalty_params.custom_gap_penalty_x = emalloc(NX*sizeof(double) )) ) return 1; 
    //if ( ! (penalty_params.custom_gap_penalty_y = emalloc(NY*sizeof(double) )) ) return 1; 
    /***********************/
    
    /***********************/
    /* expected quantities */
    /***********************/
    avg = avg_sq = stdev = 0.0;
    //if (options.postprocess) {
    if (0) {
	if (F_moments (x, x_type, NX, y, y_type, NY, alpha, &avg, &avg_sq, &stdev)) return 1;
    }
    /***********************/
    

    /***********************/
    /* initialization      */
    /***********************/
    best_ctr   = 0;
    penalty_params.gap_opening   = options.gap_open;
    penalty_params.gap_extension = options.gap_extend;
    penalty_params.endgap        = options.endgap;
    penalty_params.endgap_special_treatment = options.use_endgap;
    /***********************/

    /***************************************/
    /* find reasonble triples of SSEs      */
    /* that correspond in type             */
    /*  and can be mapped onto each other  */
    /***************************************/
    for (top_ctr=0; top_ctr<no_top_rmsd; top_ctr++) {
	best_rmsd[top_ctr] = BAD_RMSD+1;
	best_triple_x[top_ctr][0] = -1;
    }
	
    for (x_ctr=0; x_ctr < NX-2 && !done; x_ctr++) {
	
	for (y_ctr=0; y_ctr < NY-2 && !done; y_ctr++) {

	    if ( y_type[y_ctr] != x_type[x_ctr] ) continue;
	    
	    x_triple[0] = x_ctr;
	    y_triple[0] = y_ctr;
	    
	    if (find_next_triple (x, y,  x_type, y_type,
				  NX, NY,  x_triple, y_triple) ){
		continue;
	    }

	    if ( x_triple[1] < 0 ||  x_triple[2] < 0 ) continue;
	    if ( y_triple[1] < 0 ||  y_triple[2] < 0 ) continue;

	    /* do these three have  kind-of similar layout in space?*/
	    /* is handedness the same? */
	    if ( ! same_hand_triple ( X_rep, x_triple, Y_rep, y_triple, 3)) continue;
	    
	    /* are distances comparab;e? */
	    if (distance_of_nearest_approach ( X_rep, x_triple,
					       Y_rep, y_triple, 3, &rmsd)) continue;
	    if ( rmsd > cutoff_rmsd) continue;
	    
	    /* find q_init that maps the two triples as well as possible*/
	    if ( opt_quat ( x,  NX, x_triple, y, NY, y_triple, 3, q_init, &rmsd)) continue;


	    for (top_ctr=0; top_ctr<no_top_rmsd; top_ctr++) {
		
		if (  rmsd <= best_rmsd[top_ctr] ) {
			    
		    chunk = no_top_rmsd - top_ctr -1;

		    if (chunk) {
			memmove (best_rmsd+top_ctr+1, best_rmsd+top_ctr, chunk*sizeof(double)); 
			memmove (best_quat[top_ctr+1],
				 best_quat[top_ctr], chunk*4*sizeof(double)); 
			memmove (best_triple_x[top_ctr+1],
				 best_triple_x[top_ctr], chunk*3*sizeof(int)); 
			memmove (best_triple_y[top_ctr+1],
				 best_triple_y[top_ctr], chunk*3*sizeof(int)); 
		    }
		    best_rmsd[top_ctr] = rmsd;
		    memcpy (best_quat[top_ctr], q_init, 4*sizeof(double)); 
		    memcpy (best_triple_x[top_ctr], x_triple, 3*sizeof(int)); 
		    memcpy (best_triple_y[top_ctr], y_triple, 3*sizeof(int)); 
		    break;
		}
	    }
	    
	}
    }

# if 0
    for (top_ctr=0; top_ctr<no_top_rmsd; top_ctr++) {
	if ( best_rmsd[top_ctr] > BAD_RMSD ) break;
	printf (" %3d %8.3lf   ", top_ctr,  best_rmsd[top_ctr]);
	vec_out ( best_quat[top_ctr], 4, "quat: ");
	for (t=0; t<3; t++ ) {
	    printf ("\t %3d  %3d \n", best_triple_x[top_ctr][t]+1, best_triple_y[top_ctr][t]+1 );
	}
    }
    exit (1);
# endif

    /*********************************************/
    /*   main loop                               */
    /*********************************************/
    for (top_ctr=0; top_ctr<no_top_rmsd; top_ctr++) {
	
	if ( best_rmsd[top_ctr] > BAD_RMSD ) break;

	quat_to_R (best_quat[top_ctr], R);
	rotate (x_rotated, NX, R, x);


	F_current = F( y, y_type, NY, x_rotated, x_type, NX, alpha);

# if 0	
	printf ("\n***********************************\n");
	printf (" %3d %8.3lf  %8.3lf   ", top_ctr,  best_rmsd[top_ctr], F_current);
	vec_out ( best_quat[top_ctr], 4, "quat: ");
	for (t=0; t<3; t++ ) {
	    printf ("\t %3d  %3d \n", best_triple_x[top_ctr][t]+1, best_triple_y[top_ctr][t]+1 );
	}
# endif
	/* find map which uses the 2 triples as anchors */
	no_anchors = 3;
	find_map (&penalty_params, X_rep, Y_rep, R, alpha, &F_effective, map + (*map_ctr),
		   best_triple_x[top_ctr], best_triple_y[top_ctr], no_anchors);

	x2y = ( map + (*map_ctr) ) ->x2y;
	map_unstable  = 0;
	for (t=0; t<3; t++ ) {
	    if ( x2y[best_triple_x[top_ctr][t]] != best_triple_y[top_ctr][t] ) {
		map_unstable = 1;
	    }
	}
	if ( map_unstable) continue;
	
	/* dna here is not DNA but "distance of nearest approach" */
	cull_by_dna ( X_rep, best_triple_x[top_ctr], 
		      Y_rep, best_triple_y[top_ctr],  3,  map + (*map_ctr), cutoff_rmsd );
	
	//printf ("map after culling by dna:\n");
	//print_map (stdout, map+ (*map_ctr), NULL, NULL,  NULL, NULL, 1);

	/* monte that optimizes the aligned vectors only */
	for (i=0; i<NX; i++) {
	     x_type_fudg[i] = JACKFRUIT;
	}
	for (j=0; j<NY; j++) {
	     y_type_fudg[j] = JACKFRUIT*2;
	}

	no_anchors = 0;

	for (i=0; i<NX; i++) {
	     j = (map+(*map_ctr))->x2y[i];
	     if (j < 0 ) continue;
	     x_type_fudg[i] = x_type[i];
	     y_type_fudg[j] = y_type[j];
	     anchor_x[no_anchors] = i;
	     anchor_y[no_anchors] = j;
	     no_anchors ++;
	}


	if ( opt_quat ( x,  NX, anchor_x, y, NY, anchor_y, no_anchors, q, &rmsd)) continue;
	
	retval = monte_carlo ( alpha,  x, x_type_fudg, NX,
			       y,  y_type_fudg, NY, q, &F_current);
	if (retval) return retval;

	
	if (options.postprocess) {
	    z_scr = stdev ? (F_current - avg)/stdev : 0.0;
	} else {
	    z_scr =  0.0;
	}
	quat_to_R (q, R);
	/* store_image() is waste of time, but perhaps not critical */
	store_image (X_rep, Y_rep, R,  alpha, map + (*map_ctr));
	map_assigned_score ( X_rep, map + (*map_ctr));

	//printf ("map  %2d  assigned score:   %8.3lf      z_score: %8.3lf \n\n",
	//	*map_ctr+1, (map + (*map_ctr)) -> assigned_score, z_scr);


        /*   store the map that passed all the filters down to here*/
	my_map_ctr = *map_ctr;


	map[my_map_ctr].F       = F_current;
	map[my_map_ctr].avg     = avg;
	map[my_map_ctr].avg_sq  = avg_sq;
	map[my_map_ctr].z_score = z_scr;
	memcpy ( map[my_map_ctr].q, q, 4*sizeof(double) );
		
	/* recalculate the assigned score*/

	
	//if (top_ctr==24) exit (1);

	/************************/
	/* store sorted         */
	/************************/
	/* find the place for the new z-score */
	store_sorted (map, NX, NY, map_best, map_max,
		      z_best, best_ctr, -map[my_map_ctr].assigned_score, my_map_ctr, &stored_new);

	if ( stored_new ) { /* we want to keep this map */
	    (*map_ctr) ++;
	    best_ctr++;
	} /* otherwise this map space is reusable */
	    

	/* is this pretty much as good as it can get ? */
	if ( fabs (map[my_map_ctr].assigned_score - smaller)
	     < options.tol )  done = 1;


    }
    map_best[best_ctr] = -1;
  
    
    /******************************************************/
    /* look for the sub-map of a couple of best hits      */
    /******************************************************/
    /* initialization:*/
    
    map_consistence ( NX, NY, NULL, NULL, NULL, NULL, NULL); 
    
    best_ctr = 0;
    while (  map_best[best_ctr] >  -1 ) {
	best_ctr ++;
    }

    //exit (1);
    
    if (best_ctr) {
	int nr_maps = (best_ctr<options.number_maps_cpl)?
	    best_ctr : options.number_maps_cpl;
	int best_i;
	int consistent;
	double z;
	double total_assigned_score, score, best_score = -100;
	double gap_score;

	for (i=0; i<nr_maps; i++) { /* look for the complement */
	    best_i =  map_best[i];
	    
	    /*intialize the (list of) submatch map(s) */
	    if ( !map[best_i].submatch_best) {
		/* for now look for a single map only */
		/* TODO - would it be worth any to look at more maps?*/ 
		int map_max = 1;
		map[best_i].submatch_best = emalloc (map_max*sizeof(int) );
		if (! map[best_i].submatch_best) return 1;
	    }
	    map[best_i].submatch_best[0]    = -1;
	    map[best_i].score_with_children =  0;
	    map[best_i].compl_z_score       =  0;
	    
	    for (j=0; j<best_ctr; j++) {

		if (i==j) continue;
		
		map_complementarity ( map+best_i, map + map_best[j], &z);
			
		map_consistence ( NX, NY, map+best_i, map + map_best[j],
				  &total_assigned_score, &gap_score, NULL);
		consistent = ( (map+best_i)->assigned_score < total_assigned_score
			       && (map + map_best[j])->assigned_score
			       < total_assigned_score);
		if ( consistent ) {
		    score = total_assigned_score;
		    if (  score > best_score ) {
			best_score = score;
			map[best_i].submatch_best[0] = map_best[j];
			map[best_i].score_with_children = total_assigned_score;
			map[best_i].compl_z_score = z;
		    }
		}
	    }

	}
    }
    
    /**********************/
    /* garbage collection */
    gradient_descent (1, 0.0,  NULL, NULL, 0,
			       NULL, NULL, 0, NULL, NULL);
    free_dmatrix (R);
    free_dmatrix (x_rotated);
    free_dmatrix (tr_x_rotated);
    free_dmatrix (best_quat);
    free_imatrix (best_triple_x);
    free_imatrix (best_triple_y);
    free (z_best);
    free (x_type_fudg);
    free (y_type_fudg);
    free (anchor_x);
    free (anchor_y);
     
    if (penalty_params.custom_gap_penalty_x) free (penalty_params.custom_gap_penalty_x);
    if (penalty_params.custom_gap_penalty_y) free (penalty_params.custom_gap_penalty_y);
    /*********************/
    
    return 0;
}