// append local profile to MNI space profile
void appendpf_local2std(string coordfile_std2local) {
  ifstream coordstream(coordfile_std2local);
  floatVector coord(3);
  vector<floatVector> coord_map_std2local;
  for (int i=0; i<3; i++)
    coordstream >> coord[i];
  while(coordstream.good()) {
    coord_map_std2local.push_back(coord);
    for (int i=0; i<3; i++)
      coordstream >> coord[i];
  }

  assert(coord_map_std2local.size()==conn_profile().size());
  floatVector append;
  intVector start(3);
  floatVector coef(3);
  intVector tmpCoord(3);
  int dim_profile = (conn_profile().begin()->second).size();

  auto it = conn_profile().begin();
  for (int i=0; i<conn_profile().size(); i++, it++) {
    for (int k=0; k<3; k++) {
      start[k]=(int)coord_map_std2local[i][k];
      coef[k] = coord_map_std2local[i][k]-start[k];
    }
    for (int z=0; z<2; z++) { // Note: we assume that all points are within the interiors, therefore exactly 8 neighbors
      float fracZ = (1-coef[2])*(1-z)+coef[2]*z;
      for (int y=0; y<2; y++) {
	float fracZY=fracZ * ( (1-coef[1])*(1-y)+coef[1]*y );
	for (int x=0; x<2; x++) {
	  float fracZYX=fracZY * ( (1-coef[0])*(1-x)+coef[0]*x );
	  tmpCoord[0]=start[0]+x; tmpCoord[1]=start[1]+y; tmpCoord[2]=start[2]+z;
	  if (conn_profile_local().count(tmpCoord)) {
	    for (int k=0; k<dim_profile; k++)
	      (it->second)[k] += fracZYX * conn_profile_local()[tmpCoord][k];
	  }
	}
      }
    }
  }
}
void StackedSet::smoothPositions()
{
   for (StackVec::iterator itr = m_stacks.begin(); itr != m_stacks.end();
      itr++)
   {
      const OverlayItemInternal* curItem = *itr;
      
      MC2Point average(0, 0);
      int numItems = 0;
      
      while (curItem) {
         // average will contain the sum of all items positions,
         // it will later we divided by the number of items.
         average = average +
            getPrecisionScaledScreenPosition(curItem);
         
         curItem = curItem->m_stack.getNext();
         numItems++;
      }

      // After these divisions average will actually contain the average
      // position (in precision scaled dimensions).
      average.getX() /= numItems;
      average.getY() /= numItems;

      curItem = *itr;
      
      while (curItem) {
         // Use the offset to move pixel box.
         MC2Point offset = average -
            getPrecisionScaledScreenPosition(curItem);
         curItem->getPrecisionScaledPixelBox().move(offset);
         
         // Use the offset to move the world position.
         MC2Point tmpPoint;
         MC2Coordinate tmpCoord(curItem->m_adjustedPosition);

         WFAPI::wf_float64 x;
         WFAPI::wf_float64 y;
         
         // We get the screen position for the coordinate.
         m_projection.transformf(x,y, tmpCoord);
         // We scale the screen position into precision scaled dimensions.
         tmpPoint = MC2Point(static_cast<int>(x * SCALING_CONSTANT),
                             static_cast<int>(y * SCALING_CONSTANT));
         tmpPoint += offset;

         // We have now offset the position and want to translate it
         // back to a world coordinate. Thus we need to scale it back
         // to normal screen space.
         tmpPoint.getX() /= SCALING_CONSTANT;
         tmpPoint.getY() /= SCALING_CONSTANT;
         
         // Get the corresponding world coordinate.
         m_projection.inverseTransform(tmpCoord, tmpPoint);
         
         curItem->m_adjustedPosition = tmpCoord;
         
         // Move to next item
         curItem = curItem->m_stack.getNext();
      }

   }
}