예제 #1
0
void SPlaneSlicer::applySliceTranslation(vtkSmartPointer<vtkMatrix4x4> vtkMat) const
{
    auto image = this->getInput< ::fwData::Image >(s_EXTENT_IN);

    ::fwData::Object::sptr index;
    switch (m_orientation)
    {
        case ::fwDataTools::helper::MedicalImageAdaptor::Orientation::X_AXIS:
            index = image->getField(::fwDataTools::fieldHelper::Image::m_sagittalSliceIndexId);
            break;
        case ::fwDataTools::helper::MedicalImageAdaptor::Orientation::Y_AXIS:
            index = image->getField(::fwDataTools::fieldHelper::Image::m_frontalSliceIndexId);
            break;
        case ::fwDataTools::helper::MedicalImageAdaptor::Orientation::Z_AXIS:
            index = image->getField(::fwDataTools::fieldHelper::Image::m_axialSliceIndexId);
            break;
    }

    const int idx = ::fwData::Integer::dynamicCast(index)->value();

    const auto& spacing = image->getSpacing();
    const auto& origin  = image->getOrigin();

    const std::uint8_t axis = static_cast<std::uint8_t>(m_orientation);

    const double trans = spacing[axis] * static_cast<double>(idx) + origin[axis];

    vtkSmartPointer<vtkMatrix4x4> transMat = vtkSmartPointer<vtkMatrix4x4>::New();
    transMat->Identity();
    transMat->SetElement(axis, 3, trans);

    vtkMatrix4x4::Multiply4x4(vtkMat, transMat, vtkMat);
}
예제 #2
0
void SPlaneSlicer::updating()
{
    this->setReslicerExtent();
    this->setReslicerAxes();

    auto image                           = this->getInput< ::fwData::Image >(s_IMAGE_IN);
    vtkSmartPointer<vtkImageData> vtkimg = vtkSmartPointer<vtkImageData>::New();

    ::fwVtkIO::toVTKImage(image, vtkimg.Get());

    m_reslicer->SetInputData(vtkimg);
    m_reslicer->Update();

    auto slice = this->getInOut< ::fwData::Image >(s_SLICE_OUT);

    ::fwVtkIO::fromVTKImage(m_reslicer->GetOutput(), slice);

    // HACK: Make output slice three-dimensional.
    // We need to do so in order to visualize it with ::visuVTKAdaptor::SImageSlice.
    // This is because the adaptor uses a vtkImageActor which doesn't handle 2d images.
    auto size = slice->getSize();
    slice->setSize({{size[0], size[1], 1}});
    auto spacing = slice->getSpacing();
    slice->setSpacing({{spacing[0], spacing[1], 0 }});
    auto origin = slice->getOrigin();
    slice->setOrigin({{origin[0], origin[1], 0}});

    auto sig = slice->signal< ::fwData::Image::ModifiedSignalType >(::fwData::Image::s_MODIFIED_SIG);

    sig->asyncEmit();
}
Module* PacketCountFilterCfg::getInstance()
{
	if (!instance)
		instance = new SystematicSampler(SYSTEMATIC_SAMPLER_COUNT_BASED,
						getInterval(), getSpacing());

	return (Module*)instance;
}
예제 #4
0
 void HorizontalListLayout::setBoxes(Layouter::LayoutedWidgets &widgets)
 {
     float x = 0;
     for(std::shared_ptr<PiH::Widget> &widget : widgets)
     {
         widget->setBoundingBox(x, getBoundingBox().y, widget->getBoundingBox().w, getBoundingBox().h);
         x += widget->getBoundingBox().w + getSpacing();
     }
 }
예제 #5
0
void tmx::Tileset::tell() {
	std::cout << "Name: " << getName() << "\n"
			  << "Source: " << getSource() << "\n"
			  << "First gID: " << getFirstGid() << "\n"
			  << "Tile Width: " << getTileWidth() << "\n"
			  << "Tile Height: " << getTileHeight() << "\n"
			  << "Spacing: " << getSpacing() << "\n"
			  << "Margin: " << getMargin() << std::endl;
}
예제 #6
0
void checkImages(cx::ImagePtr input, cx::ImagePtr expected)
{
	{
		INFO(getDim(input) << " == " << getDim(expected));
		CHECK(cx::similar(getDim(input), getDim(expected)));
	}
	{
		INFO(input->get_rMd() << "\n == \n" << expected->get_rMd());
		CHECK(cx::similar(input->get_rMd(), expected->get_rMd()));
	}
	{
		INFO(getSpacing(input) << " == " << getSpacing(expected));
		CHECK(cx::similar(getSpacing(input), getSpacing(expected)));
	}
	CHECK(input->getParentSpace() == expected->getParentSpace());
	// removed: image is not necessarily black. The size is what matters.
	//CHECK(cxtest::Utilities::getFractionOfVoxelsAboveThreshold(input->getBaseVtkImageData(), 0) == Approx(0));
}
예제 #7
0
 void VerticalListLayout::setBoxes(Layouter::LayoutedWidgets &widgets)
 {
     float x = getBoundingBox().x, y = getBoundingBox().y;
     for(std::shared_ptr<PiH::Widget> &widget : widgets)
     {
         if(m_centered)
         {
             x = getBoundingBox().x + getBoundingBox().w / 2 - widget->getBoundingBox().w / 2;
         }
         widget->setBoundingBox(x, y, widget->getBoundingBox().w, widget->getBoundingBox().h);
         y += widget->getBoundingBox().h + getSpacing();
     }
 }
예제 #8
0
파일: Font.cpp 프로젝트: davideOXC/OpenXcom
/**
 * Returns the dimensions of a particular character in the font.
 * @param c Font character.
 * @return Width and Height dimensions (X and Y are ignored).
 */
SDL_Rect Font::getCharSize(wchar_t c)
{
	SDL_Rect size = { 0, 0, 0, 0 };
	if (c != 1 && !isLinebreak(c) && !isSpace(c))
	{
		FontImage *image = &_images[_chars[c].first];
		size.w = _chars[c].second.w + image->spacing;
		size.h = _chars[c].second.h + image->spacing;
	}
	else
	{
		if (_monospace)
			size.w = getWidth() + getSpacing();
		else if (isNonBreakableSpace(c))
			size.w = getWidth() / 4;
		else
			size.w = getWidth() / 2;
		size.h = getHeight() + getSpacing();
	}
	// In case anyone mixes them up
	size.x = size.w;
	size.y = size.h;
	return size;
}
예제 #9
0
//========================================================================
//   
// NAME  GFXFont::wrapStr
//
// DESCRIPTION
//       modifies *str so that it will word wrap within the
//       specified width.  Carriage returns are removed
//       and replaced with spaces or spaces are removed and
//       replaced by carriage returns.    
//       
// ARGUMENTS 
//       str   - String to be modified
//       width - wrapping width in pixels
// RETURNS 
//       
// NOTES 
//       Tabs are not supported.
//       
//========================================================================
void GFXFont::wrapStr(char *str, Int32 width)
{
   Int32 spaceLen; // length of a space character
   Int32 lineLen;  // length of current line
   Int32 wordLen;  // length of current word
   char *lastSpace;
      
   spaceLen = getWidth(' ') + getSpacing();

   lineLen = 0;
   lastSpace = NULL;
   while (*str)
   {
      // convert spaces
      if (isspace(*str))
      {
         lineLen += spaceLen;
         *str = ' ';
         lastSpace = str;
         str++;
      }
      else 
      {
         wordLen = getWordWidth((void *)str);
         if ((lineLen + wordLen) > width)
         {
            if (lastSpace)
            {
               *lastSpace = '\n';
               lastSpace = NULL;
               lineLen = 0;
            }  
         }
         lineLen += wordLen;
         while (*str && (! isspace(*str)) )
            str++;
      }           
   }
}
예제 #10
0
RRect RLineCache::flush(class IRichCompositor* compositor)
{
	RRect line_rect;

	// no element yet, need not flush!
	element_list_t* line = getCachedElements();
	if ( line->size() == 0 )
		return line_rect;

	// line mark
	std::vector<element_list_t::iterator> line_marks;
	std::vector<short> line_widths;

	RRect zone = compositor->getMetricsState()->zone;
	bool wrapline = m_rWrapLine;

	// line width auto growth
	if ( zone.size.w == 0 )
		wrapline = false;
	
	RMetricsState* mstate = compositor->getMetricsState();

	RPos pen;
	RRect temp_linerect;
	short base_line_pos_y = 0;
	element_list_t::iterator inner_start_it = line->begin();
	line_marks.push_back(line->begin()); // push first line start
	for ( element_list_t::iterator it = line->begin(); it != line->end(); it++ )
	{
		RMetrics* metrics = (*it)->getMetrics();

		// prev composit event
		(*it)->onCachedCompositBegin(this, pen);

		// calculate baseline offset
		short baseline_correct = 0;
		if ( (*it)->needBaselineCorrect() )
		{
			baseline_correct = m_rBaselinePos;
		}

		// first element
		if ( pen.x == 0 )
		{
			pen.x -= metrics->rect.min_x();
		}
		
		// set position
		(*it)->setLocalPositionX(pen.x);
		(*it)->setLocalPositionY(pen.y + baseline_correct);

		RRect rect = metrics->rect;
		rect.pos.x += pen.x;
		rect.pos.y += baseline_correct;
		temp_linerect.extend(rect);

		// process wrapline
		element_list_t::iterator next_it = it + 1;
		if ( next_it == line->end() ||	// last element
			(*next_it)->isNewlineBefore() || // line-break before next element
			(*it)->isNewlineFollow() ||	// line-break after this element
			( wrapline && pen.x != 0		// wrap line
			&& pen.x + metrics->advance.x + (*next_it)->getMetrics()->rect.pos.x + (*next_it)->getMetrics()->rect.size.w + getPadding()*2 > zone.size.w 
			&& (*next_it)->canLinewrap() ) )
		{
			// correct out of bound correct
			short y2correct = -temp_linerect.max_y();

			for ( element_list_t::iterator inner_it = inner_start_it; inner_it != next_it; inner_it++ )
			{
				RPos pos = (*inner_it)->getLocalPosition();
				(*inner_it)->setLocalPositionY(pos.y + y2correct);
				(*inner_it)->setLocalPositionX(pos.x /*+ x2correct*/);
			}

			temp_linerect.pos.y = pen.y;
			line_rect.extend(temp_linerect);

			pen.y -= (temp_linerect.size.h + getSpacing());
			pen.x = 0;

			// push next line start
			line_marks.push_back(next_it);
			line_widths.push_back(temp_linerect.size.w);

			inner_start_it = next_it;
			temp_linerect = RRect();
		}
		else
		{
			pen.x += metrics->advance.x;
		}
		
		// post composit event
		(*it)->onCachedCompositEnd(this, pen);
	}

	short align_correct_x = 0;
	size_t line_mark_idx = 0;
	if ( getHAlign() == e_align_left )
		line_rect.size.w += getPadding() * 2;
	else
		line_rect.size.w = RMAX(zone.size.w, line_rect.size.w + getPadding() * 2); // auto rect
	for ( element_list_t::iterator it = line->begin(); it != line->end(); it++ )
	{
		// prev composit event
		(*it)->onCachedCompositBegin(this, pen);

		if ( it == line_marks[line_mark_idx] )
		{
			short lwidth = line_widths[line_mark_idx];

			// x correct
			switch ( getHAlign() )
			{
			case e_align_left:
				align_correct_x = getPadding();
				break;
			case e_align_center:
				align_correct_x = ( line_rect.size.w - lwidth ) / 2;
				break;
			case e_align_right:
				align_correct_x = line_rect.size.w - lwidth - getPadding();
				break;
			}

			line_mark_idx++; // until next line
		}

		RPos pos = (*it)->getLocalPosition();
		(*it)->setLocalPositionX(mstate->pen_x + pos.x + align_correct_x);
		(*it)->setLocalPositionY(mstate->pen_y + pos.y);

		// post composit event
		(*it)->onCachedCompositEnd(this, pen);
	}

	line_rect.pos.y = mstate->pen_y;

	// advance pen position
	mstate->pen_y -= (line_rect.size.h + getSpacing());
	mstate->pen_x = 0;
	
	clear();

	return line_rect;
}
예제 #11
0
RRect RHTMLTableCache::flush(class IRichCompositor* compositor)
{
	RRect table_rect;

	if ( m_rCached.empty())
	{
		return table_rect;
	}

	// table content size
	std::vector<short> row_heights;
	std::vector<short> col_widths;
	std::vector<bool> width_set;
	short max_row_width = 0;
	short max_row_height = 0;
	for ( element_list_t::iterator it = m_rCached.begin(); it != m_rCached.end(); it++ )
	{
		REleHTMLRow* row = dynamic_cast<REleHTMLRow*>(*it);
		if ( !row )
		{
			CCLog("[CCRich] Table cache can only accept 'REleHTMLRow' element!");
			continue;
		}

		short current_row_height = 0;
		std::vector<class REleHTMLCell*>& cells = row->getCells();
		for ( size_t i = 0; i < cells.size(); i++ )
		{
			CCAssert(i <= col_widths.size(), "");
			if ( i == col_widths.size() )
			{
				col_widths.push_back(cells[i]->getMetrics()->rect.size.w + getPadding() * 2);
				width_set.push_back(cells[i]->isWidthSet());
			}
			else
			{
				if (width_set[i])
				{
					if (cells[i]->isWidthSet())
					{
						col_widths[i] = RMAX(col_widths[i], cells[i]->getMetrics()->rect.size.w + getPadding() * 2);
					}
					else
					{
						// do nothing
					}
				}
				else
				{
					if (cells[i]->isWidthSet())
					{
						col_widths[i] = cells[i]->getMetrics()->rect.size.w + getPadding() * 2;
						width_set[i] = true;
					}
					else
					{
						// do nothing use the first row default width
						//col_widths[i] = RMIN(col_widths[i], cells[i]->getMetrics()->rect.size.w + getPadding() * 2);
					}
				}
			}

			current_row_height = RMAX(current_row_height, cells[i]->getMetrics()->rect.size.h);
		}

		current_row_height += getPadding() * 2;
		row_heights.push_back(current_row_height);

		table_rect.size.h += current_row_height;
	}

	// max width
	for ( size_t i = 0; i < col_widths.size(); i++ )
	{
		table_rect.size.w += col_widths[i];
	}

	// set content metrics
	short spacing = getSpacing();
	short pen_x = 0;
	short pen_y = -m_rTable->m_rBorder;
	size_t row_idx = 0;
	for ( element_list_t::iterator it = m_rCached.begin(); it != m_rCached.end(); it++ )
	{
		REleHTMLRow* row = dynamic_cast<REleHTMLRow*>(*it);
		if ( !row )
		{
			CCLog("[CCRich] Table cache can only accept 'REleHTMLRow' element!");
			continue;
		}

		pen_x = m_rTable->m_rBorder;

		// set row metrics
		row->setLocalPositionX(pen_x);
		row->setLocalPositionY(pen_y);
		RMetrics* row_metrics = row->getMetrics();
		row_metrics->rect.size.h = row_heights[row_idx];
		row_metrics->rect.size.w = table_rect.size.w + spacing * (col_widths.size() - 1);

		// process cells in row
		short cell_pen_x = 0;
		std::vector<class REleHTMLCell*>& cells = row->getCells();
		for ( size_t i = 0; i < cells.size(); i++ )
		{
			cells[i]->setLocalPositionX(cell_pen_x);
			cells[i]->setLocalPositionY(0);
			RMetrics* cell_metrics = cells[i]->getMetrics();
			cell_metrics->rect.size.w = col_widths[i];
			cell_metrics->rect.size.h = row_heights[row_idx];

			recompositCell(cells[i]);

			cell_pen_x += col_widths[i];
			cell_pen_x += spacing;
		}

		pen_y -= row_heights[row_idx];
		pen_y -= spacing;
        row_idx++;
	}

	table_rect.size.h += m_rTable->m_rBorder * 2 + spacing * (row_heights.size() - 1);
	table_rect.size.w += m_rTable->m_rBorder * 2 + spacing * (col_widths.size() - 1);

	m_rCached.clear();

	return table_rect;
}
예제 #12
0
파일: FieldPlane.cpp 프로젝트: LMY/yEMcalc
bool FieldPlane::accumulate(FieldPlane fp) {
	return  getCenter() == fp.getCenter() && getSpacing() == fp.getSpacing() ? accumulateSquare(fp.get()) : false;
}
예제 #13
0
파일: FieldPlane.cpp 프로젝트: LMY/yEMcalc
bool FieldPlane::sum(FieldPlane fp) {
	return getCenter() == fp.getCenter() && getSpacing() == fp.getSpacing() ? sum(fp.get()) : false;
}
예제 #14
0
int main(int argc, char* argv[])
{
	/*!
	 * \page Vector_5_md_vl_sym_crs Vector 5 molecular dynamic with symmetric Verlet list crossing scheme
	 *
	 * ## Simulation ## {#md_e5_sym_sim_crs}
	 *
	 * The simulation is equal to the simulation explained in the example molecular dynamic
	 *
	 * \see \ref md_e5_sym
	 *
	 * The difference is that we create a symmetric Verlet-list for crossing scheme instead of a normal one
	 * \snippet Vector/5_molecular_dynamic_sym_crs/main.cpp sim verlet
	 *
	 * The rest of the code remain unchanged
	 *
	 * \snippet Vector/5_molecular_dynamic_sym_crs/main.cpp simulation
	 *
	 */

	//! \cond [simulation] \endcond

	double dt = 0.00025;
	double sigma = 0.1;
	double r_cut = 3.0*sigma;
	double r_gskin = 1.3*r_cut;
	double sigma12 = pow(sigma,12);
	double sigma6 = pow(sigma,6);

	openfpm::vector<double> x;
	openfpm::vector<openfpm::vector<double>> y;

	openfpm_init(&argc,&argv);
	Vcluster & v_cl = create_vcluster();

	// we will use it do place particles on a 10x10x10 Grid like
	size_t sz[3] = {10,10,10};

	// domain
	Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});

	// Boundary conditions
	size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};

	// ghost, big enough to contain the interaction radius
	Ghost<3,float> ghost(r_gskin);
	ghost.setLow(0,0.0);
	ghost.setLow(1,0.0);
	ghost.setLow(2,0.0);

	vector_dist<3,double, aggregate<double[3],double[3]> > vd(0,box,bc,ghost,BIND_DEC_TO_GHOST);

	size_t k = 0;
	size_t start = vd.accum();

	auto it = vd.getGridIterator(sz);

	while (it.isNext())
	{
		vd.add();

		auto key = it.get();

		vd.getLastPos()[0] = key.get(0) * it.getSpacing(0);
		vd.getLastPos()[1] = key.get(1) * it.getSpacing(1);
		vd.getLastPos()[2] = key.get(2) * it.getSpacing(2);

		vd.template getLastProp<velocity>()[0] = 0.0;
		vd.template getLastProp<velocity>()[1] = 0.0;
		vd.template getLastProp<velocity>()[2] = 0.0;

		vd.template getLastProp<force>()[0] = 0.0;
		vd.template getLastProp<force>()[1] = 0.0;
		vd.template getLastProp<force>()[2] = 0.0;

		k++;
		++it;
	}

	vd.map();
	vd.ghost_get<>();

	timer tsim;
	tsim.start();

	//! \cond [sim verlet] \endcond

	// Get the Cell list structure
	auto NN = vd.getVerletCrs(r_gskin);;

	//! \cond [sim verlet] \endcond

	// calculate forces
	calc_forces(vd,NN,sigma12,sigma6,r_cut);
	unsigned long int f = 0;

	int cnt = 0;
	double max_disp = 0.0;

	// MD time stepping
	for (size_t i = 0; i < 10000 ; i++)
	{
		// Get the iterator
		auto it3 = vd.getDomainIterator();

		double max_displ = 0.0;

		// integrate velicity and space based on the calculated forces (Step1)
		while (it3.isNext())
		{
			auto p = it3.get();

			// here we calculate v(tn + 0.5)
			vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
			vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
			vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];

			Point<3,double> disp({vd.template getProp<velocity>(p)[0]*dt,vd.template getProp<velocity>(p)[1]*dt,vd.template getProp<velocity>(p)[2]*dt});

			// here we calculate x(tn + 1)
			vd.getPos(p)[0] += disp.get(0);
			vd.getPos(p)[1] += disp.get(1);
			vd.getPos(p)[2] += disp.get(2);

			if (disp.norm() > max_displ)
				max_displ = disp.norm();

			++it3;
		}

		if (max_disp < max_displ)
			max_disp = max_displ;

		// Because we moved the particles in space we have to map them and re-sync the ghost
		if (cnt % 10 == 0)
		{
			vd.map();
			vd.template ghost_get<>();
			// Get the Cell list structure
			vd.updateVerlet(NN,r_gskin,VL_CRS_SYMMETRIC);
		}
		else
		{
			vd.template ghost_get<>(SKIP_LABELLING);
		}

		cnt++;

		// calculate forces or a(tn + 1) Step 2
		calc_forces(vd,NN,sigma12,sigma6,r_cut);

		// Integrate the velocity Step 3
		auto it4 = vd.getDomainIterator();

		while (it4.isNext())
		{
			auto p = it4.get();

			// here we calculate v(tn + 1)
			vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
			vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
			vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];

			++it4;
		}

		// After every iteration collect some statistic about the confoguration
		if (i % 100 == 0)
		{
			// We write the particle position for visualization (Without ghost)
			vd.deleteGhost();
			vd.write("particles_",f);

			// we resync the ghost
			vd.ghost_get<>();


			// We calculate the energy
			double energy = calc_energy(vd,NN,sigma12,sigma6,r_cut);
			auto & vcl = create_vcluster();
			vcl.sum(energy);
			vcl.max(max_disp);
			vcl.execute();

			// we save the energy calculated at time step i c contain the time-step y contain the energy
			x.add(i);
			y.add({energy});

			// We also print on terminal the value of the energy
			// only one processor (master) write on terminal
			if (vcl.getProcessUnitID() == 0)
				std::cout << "Energy: " << energy << "   " << max_disp << "   " << std::endl;

			max_disp = 0.0;

			f++;
		}
	}

	tsim.stop();
	std::cout << "Time: " << tsim.getwct()  << std::endl;

	//! \cond [simulation] \endcond

	// Google charts options, it store the options to draw the X Y graph
	GCoptions options;

	// Title of the graph
	options.title = std::string("Energy with time");

	// Y axis name
	options.yAxis = std::string("Energy");

	// X axis name
	options.xAxis = std::string("iteration");

	// width of the line
	options.lineWidth = 1.0;

	// Object that draw the X Y graph
	GoogleChart cg;

	// Add the graph
	// The graph that it produce is in svg format that can be opened on browser
	cg.AddLinesGraph(x,y,options);

	// Write into html format
	cg.write("gc_plot2_out.html");

	//! \cond [google chart] \endcond

	/*!
	 * \page Vector_5_md_vl_sym_crs Vector 5 molecular dynamic with symmetric Verlet list crossing scheme
	 *
	 * ## Finalize ## {#finalize_v_e5_md_sym_crs}
	 *
	 *  At the very end of the program we have always to de-initialize the library
	 *
	 * \snippet Vector/5_molecular_dynamic_sym_crs/main.cpp finalize
	 *
	 */

	//! \cond [finalize] \endcond

	openfpm_finalize();

	//! \cond [finalize] \endcond

	/*!
	 * \page Vector_5_md_vl_sym_crs Vector 5 molecular dynamic with symmetric Verlet list crossing scheme
	 *
	 * ## Full code ## {#full_code_v_e5_md_sym_crs}
	 *
	 * \include Vector/5_molecular_dynamic_sym_crs/main.cpp
	 *
	 */
}
예제 #15
0
int main(int argc, char* argv[])
{
    /*!
     *
     * \page Vector_4_comp_reo Vector 4 computational reordering and cache friendliness
     *
     * ## Initialization ##
     *
     * The initialization is the same as the molecular dynamic example. The differences are in the
     * parameters. We will use a bigger system, with more particles. The delta time for integration
     * is chosen in order to keep the system stable.
     *
     * \see \ref e3_md_init
     *
     * \snippet Vector/4_reorder/main_comp_ord.cpp vect create
     *
     */

    //! \cond [vect create] \endcond

    double dt = 0.0001;
    float r_cut = 0.03;
    double sigma = r_cut/3.0;
    double sigma12 = pow(sigma,12);
    double sigma6 = pow(sigma,6);

    openfpm::vector<double> x;
    openfpm::vector<openfpm::vector<double>> y;

    openfpm_init(&argc,&argv);
    Vcluster & v_cl = create_vcluster();

    // we will use it do place particles on a 40x40x40 Grid like
    size_t sz[3] = {40,40,40};

    // domain
    Box<3,float> box({0.0,0.0,0.0}, {1.0,1.0,1.0});

    // Boundary conditions
    size_t bc[3]= {PERIODIC,PERIODIC,PERIODIC};

    // ghost, big enough to contain the interaction radius
    Ghost<3,float> ghost(r_cut);

    vector_dist<3,double, aggregate<double[3],double[3]> > vd(0,box,bc,ghost);

    //! \cond [vect create] \endcond

    /*!
     * \page Vector_4_comp_reo Vector 4 computational reordering and cache friendliness
     *
     * ## Particles on a grid like position ##
     *
     * Here we place the particles on a grid like manner
     *
     * \see \ref e3_md_gl
     *
     * \snippet Vector/4_reorder/main_comp_ord.cpp vect grid
     *
     */

    //! \cond [vect grid] \endcond

    auto it = vd.getGridIterator(sz);

    while (it.isNext())
    {
        vd.add();

        auto key = it.get();

        vd.getLastPos()[0] = key.get(0) * it.getSpacing(0);
        vd.getLastPos()[1] = key.get(1) * it.getSpacing(1);
        vd.getLastPos()[2] = key.get(2) * it.getSpacing(2);

        vd.template getLastProp<velocity>()[0] = 0.0;
        vd.template getLastProp<velocity>()[1] = 0.0;
        vd.template getLastProp<velocity>()[2] = 0.0;

        vd.template getLastProp<force>()[0] = 0.0;
        vd.template getLastProp<force>()[1] = 0.0;
        vd.template getLastProp<force>()[2] = 0.0;

        ++it;
    }

    //! \cond [vect grid] \endcond

    /*!
     *
     * \page Vector_4_comp_reo Vector 4 computational reordering and cache friendliness
     *
     * ## Molecular dynamic steps ##
     *
     * Here we do 30000 MD steps using verlet integrator the cycle is the same as the
     * molecular dynamic example. with the following changes.
     *
     * ### Cell lists ###
     *
     * Instead of getting the normal cell list we get an hilbert curve cell-list. Such cell list has a
     * function called **getIterator** used inside the function **calc_forces** and **calc_energy**
     * that iterate across all the particles but in a smart-way. In practice
     * given an r-cut a cell-list is constructed with the provided spacing. Suppose to have a cell-list
     * \f$ m \times n \f$, an hilbert curve \f$ 2^k \times 2^k \f$ is contructed with \f$ k = ceil(log_2(max(m,n))) \f$.
     * Cell-lists are explored according to this Hilbert curve, If a cell does not exist is simply skipped.
     *
     *
     * \verbatim
    +------+------+------+------+     Example of Hilbert curve running on a 3 x 3 Cell
    |      |      |      |      |     An hilbert curve of k = ceil(log_2(3)) = 4
    |  X+---->X   |  X +---> X  |
    |  ^   |  +   |  ^   |   +  |
    ***|******|******|****---|--+      *******
    *  +   |  v   |  +   *   v  |      *     *
    *  7   |  8+---->9   *   X  |      *     *  = Domain
    *  ^   |      |      *   +  |      *     *
    *--|-----------------*---|--+      *******
    *  +   |      |      *   v  |
    *  4<----+5   |   6<---+ X  |
    *      |  ^   |   +  *      |
    *---------|-------|--*------+
    *      |  +   |   v  *      |
    *  1+---->2   |   3+---> X  |
    *      |      |      *      |
    **********************------+

     this mean that we will iterate the following cells

     1,2,5,4,7,8,9,6,3

     Suppose now that the particles are ordered like described




    Particles   id      Cell
                 0         1
                 1         7
                 2         8
    			 3		   1
    			 4		   9
    			 5		   9
    			 6		   6
    			 7		   7
    			 8		   3
    			 9		   2
    			10		   4
    			11		   3


    The iterator of the cell-list will explore the particles in the following way

    Cell     1  2 5 4  7  8  9  6 3
       	   |   | | | |   | |   | | |
        	0,3,9,,10,1,7,2,4,5,6,8


     * \endverbatim
     *
     * We cannot explain here what is a cache, but in practice is a fast memory in the CPU able
     * to store chunks of memory. The cache in general is much smaller than RAM, but the big advantage
     * is its speed. Retrieve data from the cache is much faster than RAM. Unfortunately the factors
     *  that determine what is on cache and what is not are multiples: Type of cache, algorithm ... .
     * Qualitatively all caches will tend to load chunks of data that you read multiple-time, or chunks
     *  of data that probably you will read based on pattern analysis. A small example is a linear memory copy where
     * you read consecutively memory and you write on consecutive memory.
     * Modern CPU recognize such pattern and decide to load on cache the consecutive memory before
     *  you actually require it.
     *
     *
     * Iterating the vector in the way described above has the advantage that when we do computation on particles
     * and its neighborhood with the sequence described above it will happen that:
     *
     * * If to process a particle A we read some neighborhood particles to process the next particle A+1
     *   we will probably read most of the previous particles.
     *
     *
     * In order to show in practice what happen we first show the graph when we do not reorder
     *
     * \htmlinclude Vector/4_reorder/no_reorder.html
     *
     * The measure has oscillation but we see an asymptotic behavior from 0.04 in the initial condition to
     * 0.124 . Below we show what happen when we use iterator from the Cell list hilbert
     *
     * \htmlinclude Vector/4_reorder/comp_reord.html
     *
     * In cases where particles does not move or move very slowly consider to use data-reordering, because it can
     * give **8-10% speedup**
     *
     * \see \ref e4_reo
     *
     *  ## Timers ##
     *
     *  In order to collect the time of the force calculation we insert two timers around the function
     *  calc_force. The overall performance is instead calculated with another timer around the time stepping
     *
     * \snippet Vector/4_reorder/main_data_ord.cpp timer start
     * \snippet Vector/4_reorder/main_data_ord.cpp timer stop
     *
     * \see \ref e3_md_vi
     *
     *
     */

    //! \cond [md steps] \endcond

    // Get the Cell list structure
    auto NN = vd.getCellList_hilb(r_cut);

    // calculate forces
    calc_forces(vd,NN,sigma12,sigma6);
    unsigned long int f = 0;

    timer time2;
    time2.start();

#ifndef TEST_RUN
    size_t Nstep = 30000;
#else
    size_t Nstep = 300;
#endif

    // MD time stepping
    for (size_t i = 0; i < Nstep ; i++)
    {
        // Get the iterator
        auto it3 = vd.getDomainIterator();

        // integrate velicity and space based on the calculated forces (Step1)
        while (it3.isNext())
        {
            auto p = it3.get();

            // here we calculate v(tn + 0.5)
            vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
            vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
            vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];

            // here we calculate x(tn + 1)
            vd.getPos(p)[0] += vd.template getProp<velocity>(p)[0]*dt;
            vd.getPos(p)[1] += vd.template getProp<velocity>(p)[1]*dt;
            vd.getPos(p)[2] += vd.template getProp<velocity>(p)[2]*dt;

            ++it3;
        }

        // Because we mooved the particles in space we have to map them and re-sync the ghost
        vd.map();
        vd.template ghost_get<>();

        timer time;
        if (i % 10 == 0)
            time.start();

        // calculate forces or a(tn + 1) Step 2
        calc_forces(vd,NN,sigma12,sigma6);

        if (i % 10 == 0)
        {
            time.stop();
            x.add(i);
            y.add({time.getwct()});
        }

        // Integrate the velocity Step 3
        auto it4 = vd.getDomainIterator();

        while (it4.isNext())
        {
            auto p = it4.get();

            // here we calculate v(tn + 1)
            vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
            vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
            vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];

            ++it4;
        }

        // After every iteration collect some statistic about the confoguration
        if (i % 100 == 0)
        {
            // We write the particle position for visualization (Without ghost)
            vd.deleteGhost();
            vd.write("particles_",f);

            // we resync the ghost
            vd.ghost_get<>();

            // We calculate the energy
            double energy = calc_energy(vd,NN,sigma12,sigma6);
            auto & vcl = create_vcluster();
            vcl.sum(energy);
            vcl.execute();

            // We also print on terminal the value of the energy
            // only one processor (master) write on terminal
            if (vcl.getProcessUnitID() == 0)
                std::cout << std::endl << "Energy: " << energy << std::endl;

            f++;
        }
    }

    time2.stop();
    std::cout << "Performance: " << time2.getwct() << std::endl;

    //! \cond [md steps] \endcond

    /*!
     * \page Vector_4_comp_reo Vector 4 computational reordering and cache friendliness
     *
     * ## Plotting graphs ##
     *
     * After we terminate the MD steps our vector x contains at which iteration we benchmark the force
     * calculation time, while y contains the measured time at that time-step. We can produce a graph X Y
     *
     * \note The graph produced is an svg graph that can be view with a browser. From the browser we can
     *       also easily save the graph into pure svg format
     *
     * \snippet Vector/4_reorder/main_comp_ord.cpp google chart
     *
     */

    //! \cond [google chart] \endcond

    // Google charts options, it store the options to draw the X Y graph
    GCoptions options;

    // Title of the graph
    options.title = std::string("Force calculation time");

    // Y axis name
    options.yAxis = std::string("Time");

    // X axis name
    options.xAxis = std::string("iteration");

    // width of the line
    options.lineWidth = 1.0;

    // Object that draw the X Y graph
    GoogleChart cg;

    // Add the graph
    // The graph that it produce is in svg format that can be opened on browser
    cg.AddLinesGraph(x,y,options);

    // Write into html format
    cg.write("gc_plot2_out.html");

    //! \cond [google chart] \endcond

    /*!
     *
     * \page Vector_4_comp_reo Vector 4 computational reordering and cache friendliness
     *
     * ## Finalize ##
     *
     *  At the very end of the program we have always to de-initialize the library
     *
     * \snippet Vector/4_reorder/main_comp_ord.cpp finalize
     *
     */

    //! \cond [finalize] \endcond

    openfpm_finalize();

    //! \cond [finalize] \endcond

    /*!
     *
     * \page Vector_4_comp_reo Vector 4 computational reordering and cache friendliness
     *
     * # Full code #
     *
     * \include Vector/4_reorder/main_comp_ord.cpp
     *
     */
}