コード例 #1
0
void ShortAxisFitting::setThetaDelta(ShortAxisOptimizationInput* input, const alglib::real_1d_array& x) {
	Cmiss_field_module_id field_module = (input->field_module);
	std::vector<Cmiss_node_id>& cmiss_nodes(*(input->cmiss_nodes));
	Cmiss_field_id coordinate = (input->coordinates_rc);
	Cmiss_field_cache_id cache = (input->cache);
	double* initialSegmentLengths = input->initialSegmentLengths;
	int* saxNodes = input->saxNodes;
	int numberOfModelFrames = input->numberOfModelFrames;
	int NUMBER_OF_SEGMENTS = input->NUMBER_OF_SEGMENTS;
	int NUMBER_OF_SAX_NODES = input->NUMBER_OF_SAX_NODES;
	double** result = input->result; //This is expected to be preallocated for heap efficiency
	int* endoNodeIds = input->endoNodesIds;
	const int NUMBER_OF_ENDO_NODES = 48; //Ignore the apex
	int ctr = 0;
	double coord[3];
	int frame = input->frame;
	Point3D centroids[4];
	centroids[0] = input->centroids[0];
	centroids[1] = input->centroids[1];
	centroids[2] = input->centroids[2];
	centroids[3] = input->centroids[3];


	//First 12 endo nodes saxcentroid 0, next 12 1...

	//Set the theta variation in x to the mesh
	{
		Cmiss_field_module_begin_change(field_module);
		{
			double time = ((double) frame) / ((double) numberOfModelFrames);
			if (frame == (numberOfModelFrames - 1))
			{
				time = 1.0;
			}
			Cmiss_field_cache_set_time(cache, time);


			for (int nc = 0; nc < NUMBER_OF_ENDO_NODES; nc++)
			{
				ctr = nc/12;
				double deltaTheta = ((int)(x[ctr]*100000))/100000.0;
				Cmiss_field_cache_set_node(cache, cmiss_nodes[endoNodeIds[nc] - 1]);
				Cmiss_field_evaluate_real(coordinate, cache, 3, coord);
				Point3D start(coord);
				start = start + centroids[nc/12];
				double nTheta = atan2(start.z, start.x) + deltaTheta;
				double dist = sqrt(start.x * start.x + start.z * start.z);
				coord[0] = dist * cos(nTheta) - centroids[nc/12].x;
				coord[2] = dist * sin(nTheta) - centroids[nc/12].z;

				Cmiss_field_assign_real(coordinate, cache, 3, coord);
			}
		}
		Cmiss_field_module_end_change(field_module);
	}

}
コード例 #2
0
void ShortAxisFitting::getSegmentLengths(ShortAxisOptimizationInput* input) {
	int ctr = 0;
	double* lengthArray = *(input->result);
	double* initialSegmentLengths = input->initialSegmentLengths;
	double coord[3];
	Cmiss_field_id coordinates_rc = input->coordinates_rc;
	Cmiss_field_cache_id cache = input->cache;
	std::vector<Cmiss_node_id>& cmiss_nodes(*input->cmiss_nodes);
	double** segmentNodes = input->segmentNodes;
	int frame = input->frame;
	//for (int frame = 0; frame < input->numberOfModelFrames; frame++)
	{
		double time = ((double) frame) / ((double) input->numberOfModelFrames);
		if (frame == (input->numberOfModelFrames - 1))
		{
			time = 1.0;
		}
		Cmiss_field_cache_set_time(cache, time);
		for (int seg = 0; seg < input->NUMBER_OF_SEGMENTS; seg++)
		{
			Cmiss_field_cache_set_node(cache, cmiss_nodes[segmentNodes[seg][0]]);
			Cmiss_field_evaluate_real(coordinates_rc, cache, 3, coord);
			Point3D start(coord);
			Cmiss_field_cache_set_node(cache, cmiss_nodes[segmentNodes[seg][1]]);
			Cmiss_field_evaluate_real(coordinates_rc, cache, 3, coord);
			Point3D end(coord);
			lengthArray[ctr++] = start.distance(end);
		}
	}
	ctr = 0;
	double error = 0;
	if (initialSegmentLengths != NULL)
	{
		//for (int frame = 0; frame < input->numberOfModelFrames; frame++)
		{
			for (int seg = 0; seg < input->NUMBER_OF_SEGMENTS; seg++)
			{
				error += fabs(initialSegmentLengths[ctr] - lengthArray[ctr]);
				ctr++;
			}
		}
	}
	input->segmentMatchError = error;
}
コード例 #3
0
ファイル: element_tool.cpp プロジェクト: A1kmm/libzinc
static void Element_tool_interactive_event_handler(void *device_id,
	struct Interactive_event *event,void *element_tool_void,
	struct Graphics_buffer *graphics_buffer)
/*******************************************************************************
LAST MODIFIED  18 November 2005

DESCRIPTION :
Input handler for input from devices. <device_id> is a unique address enabling
the editor to handle input from more than one device at a time. The <event>
describes the type of event, button numbers and key modifiers, and the volume
of space affected by the interaction. Main events are button press, movement and
release.
==============================================================================*/
{
	enum Interactive_event_type event_type;
	FE_value time, xi[MAXIMUM_ELEMENT_XI_DIMENSIONS];
	int clear_selection, element_dimension, i, input_modifier,
		number_of_xi_points, shift_pressed;
	int number_in_xi[MAXIMUM_ELEMENT_XI_DIMENSIONS];
	struct FE_element *picked_element;
	struct FE_element_shape *element_shape;
	struct Element_tool *element_tool;
	struct Interaction_volume *interaction_volume,*temp_interaction_volume;
	struct LIST(Scene_picked_object) *scene_picked_object_list;
	struct Scene *scene;
	struct Cmiss_rendition *rendition = NULL;
	FE_value_triple *xi_points;

	ENTER(Element_tool_interactive_event_handler);
	if (device_id&&event&&(element_tool=
		(struct Element_tool *)element_tool_void))
	{
		Cmiss_region_begin_hierarchical_change(element_tool->region);
		interaction_volume=Interactive_event_get_interaction_volume(event);
		scene=Interactive_event_get_scene(event);
		if (scene != 0)
		{
			event_type=Interactive_event_get_type(event);
			input_modifier=Interactive_event_get_input_modifier(event);
			shift_pressed=(INTERACTIVE_EVENT_MODIFIER_SHIFT & input_modifier);
			switch (event_type)
			{
			case INTERACTIVE_EVENT_BUTTON_PRESS:
				{
					/* interaction only works with first mouse button */
					if (1==Interactive_event_get_button_number(event))
					{
						scene_picked_object_list=
							Scene_pick_objects(scene,interaction_volume,graphics_buffer);
						if (scene_picked_object_list != 0)
						{
							element_tool->picked_element_was_unselected=1;
							if (0 != (picked_element=Scene_picked_object_list_get_nearest_element(
								scene_picked_object_list,(struct Cmiss_region *)NULL,
								element_tool->select_elements_enabled,
								element_tool->select_faces_enabled,
								element_tool->select_lines_enabled,
								(struct Scene_picked_object **)NULL,
								&rendition,	(struct Cmiss_graphic **)NULL)))
							{
								/* Open command_field of picked_element in browser */
								if (element_tool->command_field)
								{
									if (element_tool->time_keeper)
									{
										time = Time_keeper_get_time(element_tool->time_keeper);
									}
									else
									{
										time = 0;
									}
									/* since we don't really have fields constant over an
									element, evaluate at its centre */
									element_dimension =
										get_FE_element_dimension(picked_element);
									for (i = 0; i < element_dimension; i++)
									{
										number_in_xi[i] = 1;
									}
									get_FE_element_shape(picked_element, &element_shape);
									if (FE_element_shape_get_xi_points_cell_centres(
										element_shape, number_in_xi,
										&number_of_xi_points, &xi_points))
									{
										/*???debug*/printf("element_tool: xi =");
										for (i = 0; i < element_dimension; i++)
										{
											xi[i] = xi_points[0][i];
											/*???debug*/printf(" %g",xi[i]);
										}
										/*???debug*/printf("\n");
										Cmiss_field_module_id field_module = Cmiss_field_get_field_module(element_tool->command_field);
										Cmiss_field_cache_id field_cache = Cmiss_field_module_create_cache(field_module);
										Cmiss_field_cache_set_time(field_cache, time);
										Cmiss_field_cache_set_mesh_location(field_cache, picked_element, element_dimension, xi);
										char *command_string = Cmiss_field_evaluate_string(element_tool->command_field, field_cache);
										if (command_string)
										{
											Execute_command_execute_string(element_tool->execute_command, command_string);
											DEALLOCATE(command_string);
										}
										Cmiss_field_cache_destroy(&field_cache);
										Cmiss_field_module_destroy(&field_module);
										DEALLOCATE(xi_points);
									}
								}
								Cmiss_field_group_id group = Cmiss_rendition_get_selection_group(rendition);
								if (group)
								{
									Cmiss_region_id temp_region = Cmiss_rendition_get_region(rendition);
									Cmiss_field_module_id field_module = Cmiss_region_get_field_module(temp_region);
									int dimension = Cmiss_element_get_dimension(picked_element);
									Cmiss_mesh_id master_mesh = Cmiss_field_module_find_mesh_by_dimension(field_module, dimension);
									Cmiss_field_element_group_id element_group = Cmiss_field_group_get_element_group(group, master_mesh);
									Cmiss_mesh_destroy(&master_mesh);
									if (element_group)
									{
										Cmiss_mesh_group_id mesh_group = Cmiss_field_element_group_get_mesh(element_group);
										element_tool->picked_element_was_unselected =
											!Cmiss_mesh_contains_element(Cmiss_mesh_group_base_cast(mesh_group), picked_element);
										Cmiss_mesh_group_destroy(&mesh_group);
										Cmiss_field_element_group_destroy(&element_group);
									}
									Cmiss_field_group_destroy(&group);
									Cmiss_field_module_destroy(&field_module);
								}
							}
							REACCESS(FE_element)(&(element_tool->last_picked_element),
								picked_element);
							/*(if ((clear_selection = !shift_pressed)
								&&((!picked_element)||
								(element_tool->picked_element_was_unselected)))*/
							clear_selection = !shift_pressed;
							if (clear_selection)
							{
								if (element_tool->region)
								{
									Cmiss_rendition *root_rendition =
										Cmiss_region_get_rendition_internal(element_tool->region);
									Cmiss_field_group_id root_group =
										Cmiss_rendition_get_selection_group(root_rendition);
									if (root_group)
									{
										Cmiss_field_group_clear_region_tree_element(root_group);
										Cmiss_field_group_destroy(&root_group);
									}
									Cmiss_rendition_destroy(&root_rendition);
								}
							}
							if (picked_element)
							{
								REACCESS(Cmiss_rendition)(&(element_tool->rendition),
									rendition);
								Cmiss_region *sub_region = NULL;
								Cmiss_field_group_id sub_group = NULL;
								Cmiss_mesh_group_id mesh_group = 0;
								if (element_tool->rendition)
								{
									sub_region = Cmiss_rendition_get_region(element_tool->rendition);
									sub_group = Cmiss_rendition_get_or_create_selection_group(element_tool->rendition);
									if (sub_group)
									{
										int dimension = Cmiss_element_get_dimension(picked_element);
										Cmiss_field_module_id field_module = Cmiss_region_get_field_module(sub_region);
										Cmiss_mesh_id temp_mesh =
											Cmiss_field_module_find_mesh_by_dimension(field_module, dimension);
										Cmiss_field_element_group_id element_group = Cmiss_field_group_get_element_group(sub_group, temp_mesh);
										if (!element_group)
											element_group = Cmiss_field_group_create_element_group(sub_group, temp_mesh);
										mesh_group = Cmiss_field_element_group_get_mesh(element_group);
										Cmiss_field_element_group_destroy(&element_group);
										Cmiss_mesh_destroy(&temp_mesh);
										Cmiss_field_module_destroy(&field_module);
									}
								}
								if (mesh_group)
								{
									Cmiss_mesh_group_add_element(mesh_group, picked_element);
									Cmiss_mesh_group_destroy(&mesh_group);
								}
								if (sub_group)
								{
									Cmiss_field_group_destroy(&sub_group);
								}
							}
							DESTROY(LIST(Scene_picked_object))(&(scene_picked_object_list));
						}
						element_tool->motion_detected=0;
						REACCESS(Interaction_volume)(
							&(element_tool->last_interaction_volume),interaction_volume);
					}
				} break;
			case INTERACTIVE_EVENT_MOTION_NOTIFY:
			case INTERACTIVE_EVENT_BUTTON_RELEASE:
				{
					if (element_tool->last_interaction_volume&&
						((INTERACTIVE_EVENT_MOTION_NOTIFY==event_type) ||
						(1==Interactive_event_get_button_number(event))))
					{
						if (INTERACTIVE_EVENT_MOTION_NOTIFY==event_type)
						{
							element_tool->motion_detected=1;
						}
						if (element_tool->last_picked_element)
						{
							/* unselect last_picked_element if not just added */
							if ((INTERACTIVE_EVENT_BUTTON_RELEASE==event_type)&&
								shift_pressed&&(!(element_tool->picked_element_was_unselected)))
							{
								struct LIST(FE_element) *temp_element_list = CREATE(LIST(FE_element))();
								ADD_OBJECT_TO_LIST(FE_element)(element_tool->last_picked_element, temp_element_list);
								Cmiss_rendition_remove_selection_from_element_list_of_dimension(element_tool->rendition,
									temp_element_list, Cmiss_element_get_dimension(element_tool->last_picked_element));
								DESTROY(LIST(FE_element))(&temp_element_list);
							}
						}
						else if (element_tool->motion_detected)
						{
							/* rubber band select */
							temp_interaction_volume=
								create_Interaction_volume_bounding_box(
								element_tool->last_interaction_volume,interaction_volume);
							if (temp_interaction_volume != 0)
							{
								if (INTERACTIVE_EVENT_MOTION_NOTIFY==event_type)
								{
									if (!element_tool->rubber_band)
									{
										/* create rubber_band object and put in scene */
										element_tool->rubber_band=CREATE(GT_object)(
											"element_tool_rubber_band",g_POLYLINE,
											element_tool->rubber_band_material);
										ACCESS(GT_object)(element_tool->rubber_band);
									}
									Interaction_volume_make_polyline_extents(
										temp_interaction_volume,element_tool->rubber_band);
								}
								else
								{
#if defined (USE_SCENE_OBJECT)
									Scene_remove_graphics_object(scene,element_tool->rubber_band);
#endif
									DEACCESS(GT_object)(&(element_tool->rubber_band));
								}
								if (INTERACTIVE_EVENT_BUTTON_RELEASE==event_type)
								{
									scene_picked_object_list=
										Scene_pick_objects(scene,temp_interaction_volume,
										graphics_buffer);
									if (scene_picked_object_list != 0)
									{
										Region_element_map *element_map =
											(Region_element_map *)Scene_picked_object_list_get_picked_region_sorted_elements(
											scene_picked_object_list,
											element_tool->select_elements_enabled,
											element_tool->select_faces_enabled,
											element_tool->select_lines_enabled);
										if (element_map)
										{
											Cmiss_region *sub_region = NULL;
											Cmiss_field_group_id sub_group = NULL;
											Cmiss_rendition *region_rendition = NULL;
											Cmiss_mesh_group_id mesh_group[MAXIMUM_ELEMENT_XI_DIMENSIONS];
											int iter = 0;
											for (iter = 0; iter < MAXIMUM_ELEMENT_XI_DIMENSIONS; iter++)
											{
												mesh_group[iter] = 0;
											}
											Region_element_map::iterator pos;
											for (pos = element_map->begin(); pos != element_map->end(); ++pos)
											{
												if (pos->first != sub_region)
												{
													if (sub_group)
													{
														Cmiss_field_group_destroy(&sub_group);
													}
													for (iter = 0; iter < MAXIMUM_ELEMENT_XI_DIMENSIONS; iter++)
													{
														if (mesh_group[iter])
														{
															Cmiss_mesh_group_destroy(&(mesh_group[iter]));
														}
													}
													if (region_rendition)
													{
														Cmiss_rendition_destroy(&region_rendition);
													}
													sub_region = pos->first;
													if (sub_region)
													{
														region_rendition= Cmiss_region_get_rendition_internal(sub_region);
														sub_group = Cmiss_rendition_get_or_create_selection_group(region_rendition);
													}
												}
												if (sub_region && sub_group)
												{
													Cmiss_field_module_id field_module = Cmiss_region_get_field_module(sub_region);
													int dimension = Cmiss_element_get_dimension(pos->second);
													if (dimension <= MAXIMUM_ELEMENT_XI_DIMENSIONS)
													{
														if (!mesh_group[dimension - 1])
														{
															Cmiss_mesh_id temp_mesh =
																Cmiss_field_module_find_mesh_by_dimension(field_module, dimension);
															Cmiss_field_element_group_id element_group =
																Cmiss_field_group_get_element_group(sub_group, temp_mesh);
															if (!element_group)
															{
																element_group = Cmiss_field_group_create_element_group(sub_group, temp_mesh);
															}
															mesh_group[dimension - 1] = Cmiss_field_element_group_get_mesh(element_group);
															Cmiss_field_element_group_destroy(&element_group);
															Cmiss_mesh_destroy(&temp_mesh);
														}
														Cmiss_mesh_group_add_element(mesh_group[dimension - 1], pos->second);
													}
													Cmiss_field_module_destroy(&field_module);
												}
											}
											if (sub_group)
											{
												Cmiss_field_group_destroy(&sub_group);
											}
											for (iter = 0; iter < MAXIMUM_ELEMENT_XI_DIMENSIONS; iter++)
											{
												if (mesh_group[iter])
												{
													Cmiss_mesh_group_destroy(&(mesh_group[iter]));
												}
											}
											if (region_rendition)
											{
												Cmiss_rendition_destroy(&region_rendition);
											}
											delete element_map;
										}
										DESTROY(LIST(Scene_picked_object))(
											&(scene_picked_object_list));
									}
								}
								DESTROY(Interaction_volume)(&temp_interaction_volume);
							}
						}
						if (INTERACTIVE_EVENT_BUTTON_RELEASE==event_type)
						{
							Element_tool_reset((void *)element_tool);
						}
					}
				} break;
			default:
				{
					display_message(ERROR_MESSAGE,
						"Element_tool_interactive_event_handler.  Unknown event type");
				} break;
			}
コード例 #4
0
ファイル: StrainMeasures.cpp プロジェクト: ABI-Software/ICMA
void StrainMeasures::embedStrainOnElements(std::string fieldname, std::vector<std::string>& strain) {

	const unsigned int num_strains = numberOfModelFrames_;
	double times[1024];
	for (unsigned int j = 0; j < num_strains; j++) {
		times[j] = static_cast<double>(j) / (num_strains - 1.0);
	}
	Cmiss_time_sequence_id time_sequence = Cmiss_field_module_get_matching_time_sequence(field_module, num_strains, times);

	Cmiss_field_module_begin_change(field_module);

	//Create Node template
	Cmiss_nodeset_id nodeset = Cmiss_field_module_find_nodeset_by_name(field_module, "cmiss_nodes");
	Cmiss_node_template_id nodeTemplate = Cmiss_nodeset_create_node_template(nodeset);
	//Create the field
	Cmiss_field_id strainField = Cmiss_field_module_create_field(field_module, fieldname.c_str(), "finite number_of_components 1 component_names value");
	if (!strainField) {
		std::cout << "Unable to create field " << fieldname << std::endl;
		return;
	}

	Cmiss_node_template_define_field(nodeTemplate, strainField);
	Cmiss_node_template_define_time_sequence(nodeTemplate, strainField, time_sequence);

	//Create Element template
	Cmiss_mesh_id mesh = Cmiss_field_module_find_mesh_by_dimension(field_module, 3);
	Cmiss_element_template_id element_template = Cmiss_mesh_create_element_template(mesh);
	Cmiss_element_template_set_shape_type(element_template, CMISS_ELEMENT_SHAPE_CUBE);
	Cmiss_element_template_set_number_of_nodes(element_template, 1);
	Cmiss_element_basis_id constant_basis = Cmiss_field_module_create_element_basis(field_module, 3, CMISS_BASIS_FUNCTION_CONSTANT);
	const int local_node_index = 1;
	Cmiss_element_template_define_field_simple_nodal(element_template, strainField, -1, constant_basis, 1, &local_node_index);
	Cmiss_element_basis_destroy(&constant_basis);

	//Map strains to elements

	std::map<int, int> elemStrainMap; //Cmiss element no is mapped to strain array number
	//APLAX
	elemStrainMap[3] = elemStrainMap[10] = 1; //Array id base 0
	elemStrainMap[15] = elemStrainMap[22] = 18; //Average of strain ids 2 and 8
	elemStrainMap[27] = elemStrainMap[34] = 12;
	elemStrainMap[39] = elemStrainMap[46] = 17;
	elemStrainMap[40] = elemStrainMap[45] = 17;
	elemStrainMap[28] = elemStrainMap[33] = 10;
	elemStrainMap[16] = elemStrainMap[21] = 19; //Average of strain ids 11 and 5
	elemStrainMap[4] = elemStrainMap[9] = 4;

	//TCH
	elemStrainMap[11] = elemStrainMap[12] = 2; //Array id base 0
	elemStrainMap[23] = elemStrainMap[24] = 20; //Average of strain ids 3 and 9
	elemStrainMap[35] = elemStrainMap[36] = 8;
	elemStrainMap[47] = elemStrainMap[48] = 16;
	elemStrainMap[41] = elemStrainMap[42] = 16;
	elemStrainMap[17] = elemStrainMap[18] = 11;
	elemStrainMap[29] = elemStrainMap[30] = 21; //Average of strain ids 12 and 6
	elemStrainMap[5] = elemStrainMap[6] = 5;

	//FCH
	elemStrainMap[1] = elemStrainMap[2] = 3; //Array id base 0
	elemStrainMap[13] = elemStrainMap[14] = 22; //Average of 10 and 4
	elemStrainMap[25] = elemStrainMap[26] = 4;
	elemStrainMap[37] = elemStrainMap[38] = 23; //Average of strains 14 and 15
	elemStrainMap[43] = elemStrainMap[44] = 24; //Average of strains 16 and 13
	elemStrainMap[31] = elemStrainMap[32] = 6;
	elemStrainMap[19] = elemStrainMap[20] = 25; //Average of strains 7 and 1
	elemStrainMap[7] = elemStrainMap[8] = 0;

	std::vector<std::string> allStrain = strain;

	//Add the additional strains 18 - 23
	std::string s2 = strain[1];
	std::string s8 = strain[7];

	std::string s11 = strain[10];
	std::string s5 = strain[5];

	std::string s9 = strain[8];
	std::string s3 = strain[2];

	std::string s12 = strain[11];
	std::string s6 = strain[6];

	std::string s10 = strain[9];
	std::string s4 = strain[3];

	std::string s14 = strain[13];
	std::string s15 = strain[14];

	std::string s16 = strain[15];
	std::string s13 = strain[12];

	std::string s1 = strain[0];
	std::string s7 = strain[6];

	std::vector<std::string> compute;
	compute.push_back(s2);
	compute.push_back(s8);

	compute.push_back(s11);
	compute.push_back(s5);

	compute.push_back(s9);
	compute.push_back(s3);

	compute.push_back(s12);
	compute.push_back(s6);

	compute.push_back(s10);
	compute.push_back(s4);

	compute.push_back(s14);
	compute.push_back(s15);

	compute.push_back(s16);
	compute.push_back(s13);

	compute.push_back(s7);
	compute.push_back(s1);

	for (int cptc = 0; cptc < 16; cptc += 2) {
		std::vector<std::string> strain1;
		std::vector<std::string> strain2;
		std::ostringstream ss;
		boost::split(strain1, compute[cptc], boost::is_any_of(","));
		boost::split(strain2, compute[cptc + 1], boost::is_any_of(","));
		for (unsigned int j = 0; j < num_strains - 1; j++) {
			double value1 = atof(strain1[j].c_str());
			double value2 = atof(strain2[j].c_str());
			ss << (value1 + value2) * 0.5 << ",";
		}
		ss << "0.0";
		allStrain.push_back(ss.str());
	}

	for (unsigned int i = 0; i < num_elements; i++) {
		Cmiss_node_id temporaryNode = Cmiss_nodeset_create_node(nodeset, extraNodeStartID++, nodeTemplate);
		Cmiss_element_template_set_node(element_template, 1, temporaryNode); //Link node with the element
		Cmiss_element_merge(elements[i], element_template);
		Cmiss_field_cache_set_node(fieldCache, temporaryNode);
		std::vector<std::string> strains;
		boost::split(strains, allStrain[elemStrainMap[i + 1]], boost::is_any_of(","));
		for (unsigned int j = 0; j < num_strains; j++) {
			double value = atof(strains[j].c_str());
			double time = times[j];
			Cmiss_field_cache_set_time(fieldCache, time);
			Cmiss_field_assign_real(strainField,fieldCache,1,&value);
		}
		Cmiss_node_destroy(&temporaryNode);
	}

	Cmiss_field_module_end_change(field_module);
	Cmiss_field_destroy(&strainField);
	Cmiss_element_template_destroy(&element_template);
	Cmiss_node_template_destroy(&nodeTemplate);
	Cmiss_nodeset_destroy(&nodeset);
	//Calling the following leads to the error ERROR: DESTROY(FE_time_sequence).  Positive access_count
	//Cmiss_time_sequence_destroy(&time_sequence);

}
コード例 #5
0
ファイル: StrainMeasures.cpp プロジェクト: ABI-Software/ICMA
std::vector<std::string> StrainMeasures::getSixteenSegmentTorsions(double wall_xi) {

	//The measure of change due to helix rotation between the walls
	//Setup segments
	const double base_start = 1.0;
	const double mid_start = 0.7;
	const double apex_start = 0.5;
	const double apex_end = 0.001;
	const double wall_epi = 1.0;
	if (wall_xi == 1.0)
		wall_xi = 0.99;
	std::vector<WallSegment> segments;
	//APLAX
	const double apexAngle = 0.0;
	//Base
	WallSegment seg1(3, 7); //Segment 2
	seg1.setXIA(apexAngle, 0.5 * (base_start + mid_start), wall_xi);
	seg1.setXIB(apexAngle, 0.5 * (base_start + mid_start), wall_epi);

	WallSegment seg2(5, 1); //Segment 5
	seg2.setXIA(apexAngle, 0.5 * (base_start + mid_start), wall_xi);
	seg2.setXIB(apexAngle, 0.5 * (base_start + mid_start), wall_epi);

	//Mid
	WallSegment seg3(7, 11); //Segment 8
	seg3.setXIA(apexAngle, 0.5 * (mid_start + apex_start), wall_xi);
	seg3.setXIB(apexAngle, 0.5 * (mid_start + apex_start), wall_epi);

	WallSegment seg4(5, 9); //Segment 11
	seg4.setXIA(apexAngle, 0.5 * (mid_start + apex_start), wall_xi);
	seg4.setXIB(apexAngle, 0.5 * (mid_start + apex_start), wall_epi);

	//Apex

	WallSegment seg5(12, 16); //Segment 13
	seg5.setXIA(0.8, 0.5 * (apex_start + apex_end), wall_xi);
	seg5.setXIB(0.8, 0.5 * (apex_start + apex_end), wall_epi);

	WallSegment seg6(9, 13); //Segment 15
	seg6.setXIA(0.1, 0.5 * (apex_start + apex_end), wall_xi);
	seg6.setXIB(0.1, 0.5 * (apex_start + apex_end), wall_epi);

	//TCH
	const double tchAngle = 2.5 / 3.0;
	//Base
	WallSegment tseg1(4, 8); //Segment 3
	tseg1.setXIA(tchAngle, 0.5 * (base_start + mid_start), wall_xi);
	tseg1.setXIB(tchAngle, 0.5 * (base_start + mid_start), wall_epi);

	WallSegment tseg2(6, 2); //Segment 6
	tseg2.setXIA(tchAngle, 0.5 * (base_start + mid_start), wall_xi);
	tseg2.setXIB(tchAngle, 0.5 * (base_start + mid_start), wall_epi);

	//Mid
	WallSegment tseg3(8, 12); //Segment 9
	tseg3.setXIA(tchAngle, 0.5 * (mid_start + apex_start), wall_xi);
	tseg3.setXIB(tchAngle, 0.5 * (mid_start + apex_start), wall_epi);

	WallSegment tseg4(6, 10); //Segment 12
	tseg4.setXIA(tchAngle, 0.5 * (mid_start + apex_start), wall_xi);
	tseg4.setXIB(tchAngle, 0.5 * (mid_start + apex_start), wall_epi);

	//Apex
	WallSegment tseg5(12, 16); //Segment 14
	tseg5.setXIA(tchAngle, 0.5 * (apex_start + apex_end), wall_xi);
	tseg5.setXIB(tchAngle, 0.5 * (apex_start + apex_end), wall_epi);

	WallSegment tseg6(10, 14); //Segment 16
	tseg6.setXIA(tchAngle, 0.5 * (apex_start + apex_end), wall_xi);
	tseg6.setXIB(tchAngle, 0.5 * (apex_start + apex_end), wall_epi);

	//FCH
	const double fchAngle = 1.0 / 3.0;
	//Base
	WallSegment fseg1(1, 5); //Segment 4
	fseg1.setXIA(fchAngle, 0.5 * (base_start + mid_start), wall_xi);
	fseg1.setXIB(fchAngle, 0.5 * (base_start + mid_start), wall_epi);

	WallSegment fseg2(7, 3); //Segment 1
	fseg2.setXIA(fchAngle, 0.5 * (base_start + mid_start), wall_xi);
	fseg2.setXIB(fchAngle, 0.5 * (base_start + mid_start), wall_epi);

	//Mid
	WallSegment fseg3(5, 9); //Segment 10
	fseg3.setXIA(fchAngle, 0.5 * (mid_start + apex_start), wall_xi);
	fseg3.setXIB(fchAngle, 0.5 * (mid_start + apex_start), wall_epi);

	WallSegment fseg4(7, 11); //Segment 7
	fseg4.setXIA(fchAngle, 0.5 * (mid_start + apex_start), wall_xi);
	fseg4.setXIB(fchAngle, 0.5 * (mid_start + apex_start), wall_epi);

	//Apex
	WallSegment fseg5(9, 13); //Segment 14+15
	fseg5.setXIA(fchAngle, apex_start, wall_xi);
	fseg5.setXIB(fchAngle, apex_end, wall_epi);

	WallSegment fseg6(11, 15); //Segment 13+16
	fseg6.setXIA(fchAngle, apex_start, wall_xi);
	fseg6.setXIB(fchAngle, apex_end, wall_epi);

	segments.clear();

	segments.push_back(fseg2); //1
	segments.push_back(seg1); //2
	segments.push_back(tseg1); //3
	segments.push_back(fseg1); //4
	segments.push_back(seg2); //5
	segments.push_back(tseg2); //6
	segments.push_back(fseg4); //7
	segments.push_back(seg3); //8
	segments.push_back(tseg3); //9
	segments.push_back(fseg3); //10
	segments.push_back(seg4); //11
	segments.push_back(tseg4); //12
	segments.push_back(seg5); //13
	segments.push_back(tseg5); //14
	segments.push_back(seg6); //15
	segments.push_back(tseg6); //16

	//Setup the active strain segments
	int aplaxStrainIds[] = { 1, 7, 12, 14, 10, 4 };
	int tchStrainIds[] = { 2, 8, 13, 15, 11, 5 };
	int fchStrainIds[] = { 0, 6, 9, 3 };
	int activeStrainSegments[16];
	unsigned int totalActiveSegments = 0;
	memset(activeStrainSegments, 0, sizeof(int) * 16);
	for (int i = 0; i < 6; i++)
		activeStrainSegments[aplaxStrainIds[i]] = 1;
	totalActiveSegments += 6;
	for (int i = 0; i < 6; i++)
		activeStrainSegments[tchStrainIds[i]] = 1;
	totalActiveSegments += 6;
	for (int i = 0; i < 4; i++)
		activeStrainSegments[fchStrainIds[i]] = 1;
	totalActiveSegments += 4;

	//Compute the strain for each segment over time
	unsigned int samples = numberOfModelFrames_;
	double* length = new double[samples];
	double* nstrain = new double[numberOfModelFrames_];
	double* avgstrain = new double[numberOfModelFrames_];
	double temp_array[3], temp_array1[3];
	unsigned int numSegments = segments.size();

	memset(avgstrain, 0, numberOfModelFrames_ * sizeof(double));
	std::vector<std::string> strains;
	std::stringstream ss;
	//Setup the header
	for (unsigned int i = 0; i < numSegments; i++) {
		WallSegment& seg = segments[i];
		for (unsigned int dt = 0; dt < samples; dt++) {
			double time = ((double) dt) / (samples - 1.0);

			Cmiss_field_cache_set_time(fieldCache, time);
			temp_array1[0] = temp_array1[1] = temp_array1[2] = 0.0;
			//Since cmiss id starts at 1 subtract 1 from seg.elementid?
			Cmiss_field_cache_set_mesh_location(fieldCache, elements[seg.elementida - 1], 3, seg.xia);
			Cmiss_field_evaluate_real(coordianteField, fieldCache, 3, temp_array);
			Cmiss_field_cache_set_mesh_location(fieldCache, elements[seg.elementida - 1], 3, seg.xib);
			Cmiss_field_evaluate_real(coordianteField, fieldCache, 3, temp_array1);

			length[dt] = fabs(temp_array1[2]);
		}

		ss << " 0.0";
		avgstrain[0] = 0.0;
		for (unsigned int dt = 1; dt < samples - 1; dt++) {
			nstrain[dt] = length[dt] - length[0];

			ss << "," << nstrain[dt];
			avgstrain[dt] += nstrain[dt] * activeStrainSegments[i];
		}
		ss << "," << nstrain[0];
		avgstrain[numberOfModelFrames_ - 1] += nstrain[0] * activeStrainSegments[i];
		strains.push_back(ss.str());
		//Clear the buffer
		ss.str("");
	}

	ss << avgstrain[0];
	for (unsigned int dt = 1; dt < numberOfModelFrames_; dt++) {
		ss << "," << avgstrain[dt] / totalActiveSegments;
	}
	strains.push_back(ss.str());

	delete[] length;
	delete[] nstrain;
	delete[] avgstrain;
	return strains;
}
コード例 #6
0
ファイル: StrainMeasures.cpp プロジェクト: ABI-Software/ICMA
std::vector<std::string> StrainMeasures::getLinearDistortion(double* wall_xi, unsigned int cnt, double power) {
	unsigned int xdiscret = 25;
	unsigned int ydiscret = 25;
	//Create points of interest array
	double **pointsOfInterest_x = new double*[xdiscret + 1];
	double **pointsOfInterest_y = new double*[xdiscret + 1];
	for (unsigned int i = 0; i <= xdiscret; i++) {
		pointsOfInterest_x[i] = new double[ydiscret + 1];
		pointsOfInterest_y[i] = new double[ydiscret + 1];
	}
	double delx = 1.0 / xdiscret;
	double dely = 1.0 / ydiscret;

	for (unsigned int xd = 0; xd <= xdiscret; xd++) {
		double xinc = xd * delx;
		if (xinc == 0.0)
			xinc = 0.001;
		if (xinc == 1.0)
			xinc = 0.99;
		for (unsigned int yd = 0; yd <= ydiscret; yd++) {
			double yinc = yd * dely;
			if (yinc == 0.0)
				yinc = 0.001;
			if (yinc == 1.0)
				yinc = 0.99;
			pointsOfInterest_x[xd][yd] = xinc;
			pointsOfInterest_y[xd][yd] = yinc;
		}
	}

	Cmiss_field_id principleStarinsField = Cmiss_field_module_find_field_by_name(field_module, "principal_strains");
	double temp_array[3];
	double coordinates[3];
	long nan_count = 0;

	std::vector<std::string> results;

	std::vector<LevelSet*>* coordSets = new std::vector<LevelSet*>();
	std::vector<LevelSet*>* deformSets = new std::vector<LevelSet*>();
	for (unsigned int ls = 0; ls < cnt; ls++) {
		coordSets->clear();
		deformSets->clear();
		for (unsigned int mt = 0; mt < numberOfModelFrames_; mt++) {
			double time = ((double) mt) / (numberOfModelFrames_ - 1.0);
			LevelSet* myCoordLevelSet = new LevelSet(num_elements, xdiscret + 1, ydiscret + 1);
			LevelSet* myDeformLevelSet = new LevelSet(num_elements, xdiscret + 1, ydiscret + 1, 1);

			Cmiss_field_cache_set_time(fieldCache, time);
			nan_count = 0;
			for (unsigned int xd = 0; xd <= xdiscret; xd++) {
				for (unsigned int yd = 0; yd <= ydiscret; yd++) {
					for (unsigned int elementId = 0; elementId < num_elements; elementId++) {
						coordinates[0] = pointsOfInterest_x[xd][yd];
						coordinates[1] = pointsOfInterest_y[xd][yd];
						coordinates[2] = wall_xi[ls];
						//std::cout<<coordinates[0]<<" "<<coordinates[1]<<" "<<coordinates[2]<<std::endl;
						temp_array[0] = temp_array[1] = temp_array[2] = 0.0;

						Cmiss_field_cache_set_mesh_location(fieldCache, elements[elementId], 3, coordinates);
						Cmiss_field_evaluate_real(principleStarinsField, fieldCache, 3, temp_array);
						double result = getLocalDeformation(temp_array, &nan_count);
						myDeformLevelSet->setData(elementId, xd, yd, &result, 1);

						Cmiss_field_evaluate_real(coordianteField, fieldCache, 3, temp_array);
						myCoordLevelSet->setData(elementId, xd, yd, temp_array, 3);
					}
				}
			}
			coordSets->push_back(myCoordLevelSet);
			deformSets->push_back(myDeformLevelSet);
		}
		std::stringstream ss;
		unsigned int numpoints = coordSets->size();
		for (unsigned int i = 0; i < numpoints; i++) {
			LevelSet* myCoordLevelSet = coordSets->at(i);
			LevelSet* myDeformLevelSet = deformSets->at(i);
			ss << myDeformLevelSet->getLPSum(0, power) / myCoordLevelSet->getArea();
			if (i < (numpoints - 1))
				ss << ",";
			delete myCoordLevelSet;
			delete myDeformLevelSet;
		}
		results.push_back(ss.str());
	}
	//Clean up
	delete deformSets;
	delete coordSets;

	for (unsigned int i = 0; i <= xdiscret; i++) {
		delete[] pointsOfInterest_x[i];
		delete[] pointsOfInterest_y[i];
	}

	delete[] pointsOfInterest_x;
	delete[] pointsOfInterest_y;

	Cmiss_field_destroy(&principleStarinsField);
	return results;
}
コード例 #7
0
ファイル: StrainMeasures.cpp プロジェクト: ABI-Software/ICMA
std::vector<std::string> StrainMeasures::getSegmentStrains(std::string fieldName) {
	std::vector<std::string> strains(19);
	Cmiss_field_id field = Cmiss_field_module_find_field_by_name(field_module, fieldName.c_str());

	//Compute strains
	unsigned int numSegments = mySegments->size();
	double temp_array1[3];
	double temp_array2[3];
//#define printcoord
#ifdef printcoord
#include "MeshTopology.h"

	std::vector<Cmiss_node_id> myNodes(100);
	Cmiss_nodeset_id nodeset = Cmiss_field_module_find_nodeset_by_name(field_module, "cmiss_nodes");
	Cmiss_node_iterator_id nodeIterator = Cmiss_nodeset_create_node_iterator(nodeset);
	Cmiss_node_id node = Cmiss_node_iterator_next(nodeIterator);
	if (node != 0) {
		double temp_array[3];

		while (node) {
			int node_id = Cmiss_node_get_identifier(node);
			myNodes[node_id - 1] = node;
			node = Cmiss_node_iterator_next(nodeIterator);
		}
	}
	Cmiss_nodeset_destroy(&nodeset);
	Cmiss_node_iterator_destroy(&nodeIterator);

	std::vector<int> Nodes(27);

	Nodes[8] = aplaxNodes8;
	Nodes[7] = aplaxNodes7;
	Nodes[6] = aplaxNodes6;
	Nodes[5] = aplaxNodes5;
	Nodes[4] = aplaxNodes4;
	Nodes[3] = aplaxNodes3;
	Nodes[2] = aplaxNodes2;
	Nodes[1] = aplaxNodes1;
	Nodes[0] = aplaxNodes0;

	Nodes[9] = tchNodes0;
	Nodes[10] = tchNodes1;
	Nodes[11] = tchNodes2;
	Nodes[12] = tchNodes3;
	Nodes[13] = tchNodes4;
	Nodes[14] = tchNodes5;
	Nodes[15] = tchNodes6;
	Nodes[16] = tchNodes7;
	Nodes[17] = tchNodes8;

	Nodes[18] = fchNodes0;
	Nodes[19] = fchNodes1;
	Nodes[20] = fchNodes2;
	Nodes[21] = fchNodes3;
	Nodes[22] = fchNodes4;
	Nodes[23] = fchNodes5;
	Nodes[24] = fchNodes6;
	Nodes[25] = fchNodes7;
	Nodes[26] = fchNodes8;

#endif
	std::vector<std::vector<double> > aplaxLengths;
	std::vector<std::vector<double> > tchLengths;
	std::vector<std::vector<double> > fchLengths;
	double denomj = (numberOfModelFrames_ - 1.0);
	for (int i = 0; i < numberOfModelFrames_; i++) {
		std::vector<double> cLengths;
		double time = ((double) i) / denomj;
		Cmiss_field_cache_set_time(fieldCache, time);
#ifdef printcoord
		std::cout<<"Frame "<<i<<"\t"<<time<<"\t"<<mySegments->at(0).xia[2]<<std::endl;
#endif
		for (int j = 0; j < numSegments; j++) {
			WallSegment& seg = mySegments->at(j);
			//The the lengths
			temp_array1[0] = temp_array1[1] = temp_array1[2] = 0.0;
			temp_array2[0] = temp_array2[1] = temp_array2[2] = 0.0;
			//Since cmiss id starts at 1 subtract 1 from seg.elemeid?
			//Note that accessing some computed field (those that involve gradients), with multiple versions leads to gradient set to 0 warning
			Cmiss_field_cache_set_mesh_location(fieldCache, elements[seg.elementida - 1], 3, seg.xia);
			Cmiss_field_evaluate_real(field, fieldCache, 3, temp_array1);
			Cmiss_field_cache_set_mesh_location(fieldCache, elements[seg.elementidb - 1], 3, seg.xib);
			Cmiss_field_evaluate_real(field, fieldCache, 3, temp_array2);
			Point3D p1(temp_array1);
			Point3D p2(temp_array2);
			double dist = p1.distance(p2);
#ifdef printcoord
			{
				int nodeCtr = (j / 8) * 9 + j % 8;
				Cmiss_field_cache_set_node(fieldCache, myNodes[Nodes[nodeCtr]]);
				temp_array1[0] = temp_array1[1] = temp_array1[2] = 0.0;
				Cmiss_field_evaluate_real(field, fieldCache, 3, temp_array1);
				Point3D p3(temp_array1);
				Cmiss_field_cache_set_node(fieldCache, myNodes[Nodes[nodeCtr + 1]]);
				temp_array1[0] = temp_array1[1] = temp_array1[2] = 0.0;
				Cmiss_field_evaluate_real(field, fieldCache, 3, temp_array1);
				Point3D p4(temp_array1);
				std::cout << p1 << "\t" << p2 << " = " << dist << "\t:\t Value at " << Nodes[nodeCtr] + 1 << "\t" << p3 << "\t" << p1.distance(p3) << "\t" << Nodes[nodeCtr + 1] + 1
						<< "\t" << p4 << "\t" << p2.distance(p4) << "\t distance \t " << p3.distance(p4) << std::endl;
			}
#endif
			cLengths.push_back(dist);
		}

		for (int segc = 0; segc < numSegments / 8; segc++) {
			int offset = segc * 8;
			std::vector<double> sLengths;

			sLengths.push_back(cLengths[0 + offset] + (1 / 3.0 - 1 / 4.0) * 4 * cLengths[1 + offset]);
			sLengths.push_back((1.0 - (1 / 3.0 - 1 / 4.0)) * 4 * cLengths[1 + offset] + (2 / 3.0 - 1 / 2.0) * 4 * cLengths[2 + offset]);
			sLengths.push_back((1.0 - (2 / 3.0 - 1 / 2.0)) * 4 * cLengths[2 + offset] + cLengths[3 + offset]);
			sLengths.push_back(cLengths[4 + offset] + (1.0 - (2 / 3.0 - 1 / 2.0)) * 4 * cLengths[5 + offset]);
			sLengths.push_back((2 / 3.0 - 1 / 2.0) * 4 * cLengths[5 + offset] + (1.0 - (1 / 3.0 - 1 / 4.0)) * 4 * cLengths[6 + offset]);
			sLengths.push_back((1 / 3.0 - 1 / 4.0) * 4 * cLengths[6 + offset] + cLengths[7 + offset]);

			if (segc == 0)
				aplaxLengths.push_back(sLengths);
			else if (segc == 1)
				tchLengths.push_back(sLengths);
			else
				fchLengths.push_back(sLengths);
		}
	}
	std::vector<double> avgStrains(numberOfModelFrames_, 0.0);

	for (int segc = 0; segc < numSegments / 8; segc++) {
		std::vector<std::vector<double> > dstrains;
		std::vector<std::vector<double> > distances;
		if (segc == 0)
			distances = aplaxLengths;
		else if (segc == 1)
			distances = tchLengths;
		else if (segc == 2)
			distances = fchLengths;

		std::vector<double>& initStrain = distances[0];
		for (int frame = 1; frame < numberOfModelFrames_; frame++) { //Compute Strains
			std::vector<double>& curStrainLengths = distances[frame];
			std::vector<double> curStrain;
			double c = 0;
			unsigned int ulimit = initStrain.size();
			for (int j = 0; j < ulimit; j++) {
				c = 100.0 * (curStrainLengths[j] - initStrain[j]) / initStrain[j];
				curStrain.push_back(c);
			}
			dstrains.push_back(curStrain);
		}

		std::vector<std::string> strainSeries;

		for (int j = 0; j < initStrain.size(); j++) {
			std::ostringstream ss;
			ss << 0.0; //For init step

			int denom = numberOfModelFrames_ - 1;
			double maxStrain = dstrains[denom - 1][j];
			//Note that frame goes from 1 to heart.numberOfModelFrames_ when computing strain
			//so shift down by 1
			for (int i = 0; i < denom; i++) { //Compute Strains
											  //Drift compensate
				double stc = dstrains[i][j] - (i + 1) * maxStrain / denom;
				ss << "," << stc;
				avgStrains[i] += stc;
			}
			strainSeries.push_back(ss.str());
		}
		if (segc == 0) {
			strains[2 - 1] = strainSeries[5];
			strains[8 - 1] = strainSeries[4];
			strains[17 - 1] = strainSeries[3];
			strains[18 - 1] = strainSeries[2];
			strains[11 - 1] = strainSeries[1];
			strains[5 - 1] = strainSeries[0];
		} else if (segc == 2) {
			strains[3 - 1] = strainSeries[0];
			strains[9 - 1] = strainSeries[1];
			strains[14 - 1] = strainSeries[2];
			strains[16 - 1] = strainSeries[3];
			strains[12 - 1] = strainSeries[4];
			strains[6 - 1] = strainSeries[5];
		} else if (segc == 1) {
			strains[4 - 1] = strainSeries[0];
			strains[10 - 1] = strainSeries[1];
			strains[15 - 1] = strainSeries[2];
			strains[13 - 1] = strainSeries[3];
			strains[7 - 1] = strainSeries[4];
			strains[1 - 1] = strainSeries[5];
		}
	}
#ifdef printcoord
	std::cout << "Linear 3D " << fieldName << std::endl;
	for (int i = 1; i < 100; i++)
		Cmiss_node_destroy(&myNodes[i]);

#endif
	//Add the average strain
	//Num strain segments depends on the number of active segments (6 strain segments per view, which has 8 active segments)
	double denom = (numSegments / 8) * 6;

	std::ostringstream ss;
	ss << 0.0; //For init step
	for (int i = 0; i < numberOfModelFrames_ - 1; i++) { //Compute the Average
		ss << "," << avgStrains[i] / denom;
	}
	strains[18] = ss.str();

	//Check if model PGS should be calculated
	if (computeModelPGS) {
		double max = fabs(avgStrains[0]);
		int idx = 0;
		for (int i = 1; i < numberOfModelFrames_ - 1; i++) {
			if (fabs(avgStrains[i]) > max) {
				max = fabs(avgStrains[i]);
				idx = i;
			}
		}
		modelPGS = avgStrains[idx] / denom;
		computeModelPGS = false; //set it so that it is not computed in subsequent calls
	}

	Cmiss_field_destroy(&field);

	return strains;
}
コード例 #8
0
ファイル: StrainMeasures.cpp プロジェクト: ABI-Software/ICMA
std::vector<std::string> StrainMeasures::getRadialStrains(double wall_xi, ViewTypeEnum type) {

	std::vector<std::string> strains(18, "");
	std::vector<double> avgStrains(numberOfModelFrames_, 0.0);
	std::ostringstream strain;
	//Note with respect to the model apex base is x-axis
	//choose y-z as xy
	//Compute the XI values for the circles

	const int allelemIds[][6][3] = { { { 47, 0, 0 }, { 46, 15, 31 }, { 14, 30, 46 }, { 45, 0, 0 }, { 48, 13, 29 }, { 16, 32, 48 } }, { { 43, 0, 0 }, { 42, 11, 27 }, { 14, 30, 46 },
			{ 41, 0, 0 }, { 44, 9, 25 }, { 12, 28, 44 } }, { { 39, 0, 0 }, { 38, 7, 23 }, { 14, 30, 46 }, { 37, 0, 0 }, { 40, 5, 21 }, { 8, 24, 40 } } };

	const double elemStarts[][3] = { { 0, 0, 0 }, { 0.5, 0, 0 }, { 0.0, 0, 0 }, { 0, 0, 0 }, { 0.5, 0, 0 }, { 0, 0, 0 } };

	const double elemEnds[][3] = { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 0.5 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 0.5 } };

	double discretization = 0.02;

	int typedepth = 0;
	if (type == SAXAPEX)
		typedepth = 2;
	else if (type == SAXMID)
		typedepth = 1;

	double depth = 0.0; //Get the central cross section

	std::vector<std::vector<double*> > eCPTS;
	std::vector<std::vector<int> > eELEM;

	for (int elemDepth = 0; elemDepth < 6; elemDepth++) {
		std::vector<double*> cpts;
		std::vector<int> cel;
		for (int eid = 0; eid < 3; eid++) {
			if (allelemIds[typedepth][elemDepth][eid] > 0) {
				int elemID = allelemIds[typedepth][elemDepth][eid] - 1;
				for (double xs = elemStarts[elemDepth][eid]; xs < elemEnds[elemDepth][eid]; xs += discretization) {
					Point3D xiCoord(xs, depth, wall_xi);
					cpts.push_back(xiCoord.ToArray());
					cel.push_back(elemID);
				}
			}
		}
		eCPTS.push_back(cpts);
		eELEM.push_back(cel);
	}
	unsigned int nStrains = eCPTS.size();
	for (int ns = 0; ns < nStrains; ns++) {
		std::vector<double*>& cpts = eCPTS[ns];
		std::vector<int>& cel = eELEM[ns];
		unsigned int npts = cpts.size();
		std::vector<double> circums;
		for (int frame = 0; frame < numberOfModelFrames_; frame++) {
			double time = ((double) frame) / (numberOfModelFrames_ - 1.0);
			Cmiss_field_cache_set_time(fieldCache, time);
			//Compute the circle coordinates
			std::vector<Point3D> pts;
			double coord[3];
			for (int j = 0; j < npts; j++) {
				Cmiss_field_cache_set_mesh_location(fieldCache, elements[cel[j]], 3, cpts[j]);
				Cmiss_field_evaluate_real(coordianteField, fieldCache, 3, coord);
				coord[1] = 0.0;
				pts.push_back(Point3D(coord[0], coord[1], coord[2]));
			}
			double distance = 0;
			for (int j = 1; j < npts; j++) {
				distance += pts[j - 1].distance(pts[j]);
			}
			circums.push_back(distance);
		}
		//Free mem
		for (int j = 0; j < npts; j++) {
			delete[] cpts[j];
		}

		double initValue = circums[0];

		strain.str("");
		for (int frame = 0; frame < numberOfModelFrames_; frame++) {
			double stv = (circums[frame] - initValue) / initValue;
			strain << stv << ",";
			avgStrains[frame] += stv;
		}

		std::string lvstr = strain.str();
		strains[ns] = (lvstr.substr(0, lvstr.length() - 1));
	}

	//Push the average strain
	strain.str("");
	for (int frame = 0; frame < numberOfModelFrames_; frame++) {
		strain << avgStrains[frame] / numberOfModelFrames_ << ",";
	}

	std::string lvstr = strain.str();
	strains[17] = (lvstr.substr(0, lvstr.length() - 1)); //Location of average strain

	return strains;
}
コード例 #9
0
ファイル: StrainMeasures.cpp プロジェクト: ABI-Software/ICMA
std::string StrainMeasures::getCircumferentialStrain(double wall_xi, ViewTypeEnum type) {
	std::ostringstream strain;
	//Note with respect to the model apex base is x-axis
	//choose y-z as xy
	//Compute the XI values for the circles
	// xi   x(1 inc),height(1 dec),y(=xi)
	const int elemIds[][12] = { { 14, 30, 46, 15, 31, 47, 16, 32, 48, 13, 29, 45 }, { 10, 26, 42, 11, 27, 13, 12, 28, 44, 9, 25, 41 },
			{ 6, 22, 38, 7, 23, 39, 8, 24, 40, 5, 21, 37 }, { 2, 18, 34, 3, 19, 35, 4, 20, 36, 1, 17, 33 } };
	double discretization = 0.02;

	int elemDepth = 2;
	double depth = 0.0;
	switch (type) {
	case SAXAPEX: {
		elemDepth = 2;
		depth = 0.5;
		break;
	}
	case SAXMID: {
		elemDepth = 1;
		depth = 0.5;
		break;
	}
	case SAXBASE: {
		elemDepth = 0;
		depth = 0.01;
		break;
	}
	}

	std::vector<double*> cpts;
	std::vector<int> cel;
	for (int eid = 0; eid < 12; eid++) {
		int elemID = elemIds[elemDepth][eid] - 1;
		for (double xs = 0.0; xs < 1.0; xs += discretization) {
			Point3D xiCoord(xs, depth, wall_xi);
			cpts.push_back(xiCoord.ToArray());
			cel.push_back(elemID);
		}
	}
	unsigned int npts = cpts.size();
	std::vector<double> circums;
	for (int frame = 0; frame < numberOfModelFrames_; frame++) {
		double time = ((double) frame) / (numberOfModelFrames_ - 1.0);
		Cmiss_field_cache_set_time(fieldCache, time);
		//Compute the circle coordinates
		std::vector<Point3D> pts;
		double coord[3];
		for (int j = 0; j < npts; j++) {
			Cmiss_field_cache_set_mesh_location(fieldCache, elements[cel[j]], 3, cpts[j]);
			Cmiss_field_evaluate_real(coordianteField, fieldCache, 3, coord);
			coord[1] = 0.0;
			pts.push_back(Point3D(coord[0], coord[1], coord[2]));
		}
		LVChamberCircle circle(pts);

		circums.push_back(circle.getCircumference());
	}
	//Free mem
	for (int j = 0; j < npts; j++) {
		delete[] cpts[j];
	}

	double initValue = circums[0];

	for (int frame = 0; frame < numberOfModelFrames_; frame++) {
		strain << (circums[frame] - initValue) / initValue << ",";
	}

	std::string lvstr = strain.str();
	//Remove the last "," seperator
	return lvstr.substr(0, lvstr.length() - 1);
}
コード例 #10
0
ファイル: StrainMeasures.cpp プロジェクト: ABI-Software/ICMA
std::string StrainMeasures::getLVVolume(double xi) {

	//Compute the LV circles
	std::vector<std::vector<Point3D> > circleXI;
	std::vector<std::vector<int> > circleElem;

	std::ostringstream lvVolume;
	//Note with respect to the model apex base is x-axis
	//choose y-z as xy
	//Compute the XI values for the circles
	// xi   x(1 inc),height(1 dec),y(=xi)
	const int elemIds[][12] = { { 14, 30, 46, 15, 31, 47, 16, 32, 48, 13, 29, 45 }, { 10, 26, 42, 11, 27, 13, 12, 28, 44, 9, 25, 41 },
			{ 6, 22, 38, 7, 23, 39, 8, 24, 40, 5, 21, 37 }, { 2, 18, 34, 3, 19, 35, 4, 20, 36, 1, 17, 33 } };
	double discretization = 0.05;

	for (int elemDepth = 0; elemDepth < 4; elemDepth++) {

		for (double depth = 1.0; depth >= discretization; depth -= discretization) {
			std::vector<Point3D> cpts;
			std::vector<int> cel;
			for (int eid = 0; eid < 12; eid++) {
				int elemID = elemIds[elemDepth][eid] - 1;
				for (double xs = 0.0; xs < 1.0; xs += discretization) {
					cpts.push_back(Point3D(xs, depth, xi));
					cel.push_back(elemID);
				}
			}
			circleXI.push_back(cpts);
			circleElem.push_back(cel);
		}
	}

	unsigned int numCircles = circleXI.size();
	double minVolume = -1.0; //Compute Ejection fraction
	double endVolume = 0.0;  //as using smallest and end volume
	for (int frame = 0; frame < numberOfModelFrames_; frame++) {
		double time = ((double) frame) / (numberOfModelFrames_ - 1.0);
		std::vector<LVChamberCircle> circles;
		Cmiss_field_cache_set_time(fieldCache, time);
		//Compute the circles
		for (int i = 0; i < numCircles; i++) {
			std::vector<Point3D>& circlexi = circleXI[i];
			std::vector<int>& cel = circleElem[i];
			std::vector<Point3D> cpts;
			unsigned int npts = circlexi.size();
			double coord[3];
			for (int j = 0; j < npts; j++) {
				double* xcoord = circlexi[j].ToArray();
				Cmiss_field_cache_set_mesh_location(fieldCache, elements[cel[j]], 3, xcoord);
				Cmiss_field_evaluate_real(coordianteField, fieldCache, 3, coord);
				cpts.push_back(Point3D(coord[0], coord[1], coord[2]));
				delete[] xcoord;
			}
			circles.push_back(LVChamberCircle(cpts));
		}
		//Compute the volume for the existing circles
		double volume = 0.0;
		numCircles = circles.size();
		for (int i = 0; i < numCircles - 1; i++) {
			volume += circles[i].getVolume(circles[i + 1]);
		}
		if (minVolume < 0.0 || volume < minVolume) {
			minVolume = volume;
		}
		endVolume = volume;
		lvVolume << volume << ",";
	}

	if (xi < 0.001) {
		ejectionFraction = (endVolume - minVolume) / endVolume;
	}

	std::string lvstr = lvVolume.str();
	//Remove the last "," seperator
	return lvstr.substr(0, lvstr.length() - 1);
}
コード例 #11
0
void ShortAxisFitting::optimize(const alglib::real_1d_array& x, double& func, void* ptr) {
	struct ShortAxisOptimizationInput* input = static_cast<struct ShortAxisOptimizationInput*>(ptr);
	Cmiss_field_module_id field_module = (input->field_module);
	std::vector<Cmiss_node_id>& cmiss_nodes(*(input->cmiss_nodes));
	std::vector<double>& targetDeltas(*(input->targetDeltas));
	Cmiss_field_id coordinate = (input->coordinates_rc);
	Cmiss_field_cache_id cache = (input->cache);
	double* initialSegmentLengths = input->initialSegmentLengths;
	int* saxNodes = input->saxNodes;
	int numberOfModelFrames = input->numberOfModelFrames;
	int NUMBER_OF_SEGMENTS = input->NUMBER_OF_SEGMENTS;
	int NUMBER_OF_SAX_NODES = input->NUMBER_OF_SAX_NODES;
	double** result = input->result; //This is expected to be preallocated for heap efficiency
	int* endoNodeIds = input->endoNodesIds;
	const int NUMBER_OF_ENDO_NODES = 48; //Ignore the apex
	int ctr = 0;
	double coord[3];
	int frame = input->frame;
	std::vector<Point3D>& resetCoord(input->initEndoCoordinates->at(frame));
	std::vector<Point3D>& initFrame(*input->initFrame);

	setThetaDelta(input, x);

	//Compute the theta error
	double thetaError = 0.0;
	//for (int frame = 0; frame < numberOfModelFrames; frame++)
	{
		double time = ((double) frame) / ((double) numberOfModelFrames);
		if (frame == (numberOfModelFrames - 1))
		{
			time = 1.0;
		}
		Cmiss_field_cache_set_time(cache, time);
		std::vector<Point3D> sax;
		Point3D sax_centroid(0, 0, 0);
		for (int seg = 0; seg < NUMBER_OF_SAX_NODES; seg++)
		{
			Cmiss_field_cache_set_node(cache, cmiss_nodes[saxNodes[seg]]);
			Cmiss_field_evaluate_real(coordinate, cache, 3, coord);
			Point3D start(coord);
			sax.push_back(start);
			sax_centroid += start;
		}
		sax_centroid = sax_centroid * (1.0 / NUMBER_OF_SAX_NODES);
		double avg = 0.0;
		for (int seg = 0; seg < NUMBER_OF_SAX_NODES; seg++)
		{
			Vector3D trans = sax[seg] - sax_centroid;
			double denom = trans.x- initFrame[seg].x;
			double nuem  = trans.z- initFrame[seg].z;
			double ltheta = atan2(nuem, denom);
			if(fabs(denom)<1.0e-6 && fabs(nuem)<1.0e-6){
					ltheta = 0.0;
			}
			avg += ltheta;
		}
		avg /=NUMBER_OF_SAX_NODES;
		thetaError +=fabs(avg-targetDeltas[frame]);
		input->thetaError = avg;
	}


	//Compute the segment error
	getSegmentLengths(input);
	double segmentMatchError = input->segmentMatchError;
	func = segmentMatchError + thetaError;
	if(segmentMatchError>2.0)
		func = 1.0e+30;
	input->totalError = func;
	//Reset coordinates to original
	{
		Cmiss_field_module_begin_change(field_module);

		{
			double time = ((double) frame) / ((double) numberOfModelFrames);
			if (frame == (numberOfModelFrames - 1))
			{
				time = 1.0;
			}
			Cmiss_field_cache_set_time(cache, time);
			for (int nc = 0; nc < NUMBER_OF_ENDO_NODES; nc++)
			{
				coord[0] = resetCoord[nc].x;
				coord[1] = resetCoord[nc].y;
				coord[2] = resetCoord[nc].z;
				Cmiss_field_cache_set_node(cache, cmiss_nodes[endoNodeIds[nc] - 1]);
				Cmiss_field_assign_real(coordinate, cache, 3, coord);
			}
		}
		Cmiss_field_module_end_change(field_module);
	}
}
コード例 #12
0
ShortAxisFitting::ShortAxisFitting(std::vector<std::string> mesh, std::vector<std::vector<Point3D> > markers) :
		inputMesh(mesh), saxMarkers(markers) {
	numberOfModelFrames_ = mesh.size();
	cmiss_nodes.resize(98);
	//Load the mesh
	//Initialise cmgui and get context
	context_ = Cmiss_context_create("saxfit");
	//This required for using the cmiss_context_execute_command
	Cmiss_context_enable_user_interface(context_, NULL);

	/**< Handle to the context */
	Cmiss_region_id root_region = Cmiss_context_get_default_region(context_);

	std::string region_name = "heart";
	// Create a heart region

	Cmiss_region_id heart_region = Cmiss_region_create_child(root_region, region_name.c_str());

	// Read in the heart model spaced over the number of model frames
	for (unsigned int i = 0; i < numberOfModelFrames_ - 1; i++)
	{
		double time = static_cast<double>(i) / numberOfModelFrames_;
		Cmiss_stream_information_id stream_information = Cmiss_region_create_stream_information(root_region);
		Cmiss_stream_information_region_id stream_information_region = Cmiss_stream_information_cast_region(stream_information);
		Cmiss_stream_resource_id stream_resource = Cmiss_stream_information_create_resource_memory_buffer(stream_information, mesh[i].c_str(), mesh[i].length());
		Cmiss_stream_information_region_set_resource_attribute_real(stream_information_region, stream_resource, CMISS_STREAM_INFORMATION_REGION_ATTRIBUTE_TIME, time);

		Cmiss_region_read(root_region, stream_information);

		Cmiss_stream_resource_destroy(&stream_resource);
		Cmiss_stream_information_destroy(&stream_information);
		Cmiss_stream_information_region_destroy(&stream_information_region);
	}

	// Wrap the end point add another set of nodes at time 1.0
	{
		Cmiss_stream_information_id stream_information = Cmiss_region_create_stream_information(root_region);
		Cmiss_stream_information_region_id stream_information_region = Cmiss_stream_information_cast_region(stream_information);
		Cmiss_stream_resource_id stream_resource = Cmiss_stream_information_create_resource_memory_buffer(stream_information, mesh[0].c_str(), mesh[0].length());
		int r = Cmiss_stream_information_region_set_resource_attribute_real(stream_information_region, stream_resource, CMISS_STREAM_INFORMATION_REGION_ATTRIBUTE_TIME, 1.0);

		Cmiss_region_read(root_region, stream_information);

		Cmiss_stream_resource_destroy(&stream_resource);
		Cmiss_stream_information_destroy(&stream_information);
		Cmiss_stream_information_region_destroy(&stream_information_region);
	}

	//Cmiss_region_id heart_region = Cmiss_region_find_child_by_name(root_region, region_name.c_str());
	//Get the field module of the heart region
	field_module_ = Cmiss_region_get_field_module(heart_region);

	if (field_module_ != 0)
	{
		Cmiss_field_module_begin_change(field_module_);

		// 'coordinates' is an assumed field in
		// a rc coordinate system.
		coordinates_rc_ = Cmiss_field_module_find_field_by_name(field_module_, "coordinates");
		//Create the cache
		cache = Cmiss_field_module_create_cache(field_module_);

		Cmiss_field_module_end_change(field_module_);
		//Get node handles
		Cmiss_nodeset_id nodeset = Cmiss_field_module_find_nodeset_by_name(field_module_, "cmiss_nodes");
		Cmiss_node_iterator_id nodeIterator = Cmiss_nodeset_create_node_iterator(nodeset);

		Cmiss_node_id node = Cmiss_node_iterator_next(nodeIterator);
		if (node != 0)
		{
			while (node)
			{
				int node_id = Cmiss_node_get_identifier(node);
				cmiss_nodes[node_id - 1] = node;
				node = Cmiss_node_iterator_next(nodeIterator);
			}
		}
		Cmiss_nodeset_destroy(&nodeset);
		Cmiss_node_iterator_destroy(&nodeIterator);

		int endo[] =
		{ 55, 57, 71, 73, 66, 67, 69, 60, 61, 63, 52, 53, 54, 56, 70, 72, 64, 65, 68, 58, 59, 62, 50, 51, 77, 84, 85, 81, 82, 83, 78, 79, 80, 74, 75, 76, 89, 96, 97, 93, 94, 95,
			90, 91, 92, 86, 87, 88, 98 };
		memcpy(endoNodeIds, endo, sizeof(int) * 49);

		//int sax[] =	{ 73, 74, 75, 76, 83, 84, 80, 81, 82, 77, 78, 79 };
		//int sax[] =		{ 79, 78, 77, 82, 81, 80, 84, 83, 76, 75, 74, 73 };
		int sax[] =	{ 80, 81, 82, 77, 78, 79, 73, 74, 75, 76, 83, 84 };

		memcpy(saxNodes, sax, sizeof(int) * NUMBER_OF_SAX_NODES);

		segmentNodes = new double*[24];
		for (int i = 0; i < 24; i++)
		{
			segmentNodes[i] = new double[2];
		}
		//Store the initial endo coordinates

		const int NUMBER_OF_ENDO_NODES = 48; //Skip apex
		double coord[3];
		for(int frame = 0;frame<numberOfModelFrames_;frame++){
			std::vector<Point3D> frameCoords;
			Cmiss_field_module_begin_change(field_module_);
			{
				double time = ((double) frame) / ((double) numberOfModelFrames_);
				if (frame == (numberOfModelFrames_ - 1))
				{
					time = 1.0;
				}
				Cmiss_field_cache_set_time(cache, time);
				for (int nc = 0; nc < NUMBER_OF_ENDO_NODES; nc++)
				{
					Cmiss_field_cache_set_node(cache, cmiss_nodes[endoNodeIds[nc] - 1]);
					Cmiss_field_evaluate_real(coordinates_rc_, cache, 3, coord);
					Point3D start(coord);
					frameCoords.push_back(start);
				}
				initEndoCoordinates.push_back(frameCoords);
			}
			Cmiss_field_module_end_change(field_module_);
		}



		//Set the segment node ids
		segmentNodes[0][0] = aplaxNodes0;
		segmentNodes[0][1] = aplaxNodes1;
		segmentNodes[1][0] = aplaxNodes1;
		segmentNodes[1][1] = aplaxNodes2;
		segmentNodes[2][0] = aplaxNodes2;
		segmentNodes[2][1] = aplaxNodes3;
		segmentNodes[3][0] = aplaxNodes3;
		segmentNodes[3][1] = aplaxNodes4;
		segmentNodes[4][0] = aplaxNodes4;
		segmentNodes[4][1] = aplaxNodes5;
		segmentNodes[5][0] = aplaxNodes5;
		segmentNodes[5][1] = aplaxNodes6;
		segmentNodes[6][0] = aplaxNodes6;
		segmentNodes[6][1] = aplaxNodes7;
		segmentNodes[7][0] = aplaxNodes7;
		segmentNodes[7][1] = aplaxNodes8;
		segmentNodes[8][0] = tchNodes0;
		segmentNodes[8][1] = tchNodes1;
		segmentNodes[9][0] = tchNodes1;
		segmentNodes[9][1] = tchNodes2;
		segmentNodes[10][0] = tchNodes2;
		segmentNodes[10][1] = tchNodes3;
		segmentNodes[11][0] = tchNodes3;
		segmentNodes[11][1] = tchNodes4;
		segmentNodes[12][0] = tchNodes4;
		segmentNodes[12][1] = tchNodes5;
		segmentNodes[13][0] = tchNodes5;
		segmentNodes[13][1] = tchNodes6;
		segmentNodes[14][0] = tchNodes6;
		segmentNodes[14][1] = tchNodes7;
		segmentNodes[15][0] = tchNodes7;
		segmentNodes[15][1] = tchNodes8;
		segmentNodes[16][0] = fchNodes0;
		segmentNodes[16][1] = fchNodes1;
		segmentNodes[17][0] = fchNodes1;
		segmentNodes[17][1] = fchNodes2;
		segmentNodes[18][0] = fchNodes2;
		segmentNodes[18][1] = fchNodes3;
		segmentNodes[19][0] = fchNodes3;
		segmentNodes[19][1] = fchNodes4;
		segmentNodes[20][0] = fchNodes4;
		segmentNodes[20][1] = fchNodes5;
		segmentNodes[21][0] = fchNodes5;
		segmentNodes[21][1] = fchNodes6;
		segmentNodes[22][0] = fchNodes6;
		segmentNodes[22][1] = fchNodes7;
		segmentNodes[23][0] = fchNodes7;
		segmentNodes[23][1] = fchNodes8;

		//Compute the segment lengths
		initialSegmentLengths = new double[NUMBER_OF_SEGMENTS * numberOfModelFrames_];

		ShortAxisOptimizationInput input;
		input.NUMBER_OF_SEGMENTS = NUMBER_OF_SEGMENTS;
		input.cache = cache;
		input.cmiss_nodes = &cmiss_nodes;
		input.coordinates_rc = coordinates_rc_;
		input.result = &initialSegmentLengths;
		input.numberOfModelFrames = numberOfModelFrames_;
		input.initialSegmentLengths = NULL;
		input.segmentNodes = segmentNodes;

		getSegmentLengths(&input);
		//Compute the average rotation that of the sax markers
		std::vector<Point3D>& iptCoord(saxMarkers[0]);
		unsigned int numSaxMarkers = iptCoord.size();
		Point3D saxCentroid(0, 0, 0);
		for (int i = 0; i < numSaxMarkers; i++)
		{
			saxCentroid += iptCoord[i];
		}
		saxCentroid = saxCentroid*(-1.0/numSaxMarkers);
		initFrame = iptCoord;
		for (int i = 0; i < numSaxMarkers; i++)
		{
			initFrame[i]+=saxCentroid;
		}

		for(int frame = 0;frame<numberOfModelFrames_;frame++){
			std::vector<Point3D>& ipCoord(saxMarkers[frame]);
			unsigned int numSaxMarkers = ipCoord.size();
			Point3D saxcentroid(0, 0, 0);
			for (int i = 0; i < numSaxMarkers; i++)
			{
				saxcentroid += ipCoord[i];
			}
			saxcentroid = saxcentroid*(-1.0/numSaxMarkers);
			std::vector<Point3D> currentFrame(ipCoord);
			for (int i = 0; i < numSaxMarkers; i++)
			{
				currentFrame[i]+=saxcentroid;
			}
			double avgAngle = 0.0;
			for (int i = 0; i < numSaxMarkers; i++)
			{
				avgAngle += (atan2(currentFrame[i].z-initFrame[i].z,currentFrame[i].x-initFrame[i].x));
			}
			avgAngle /=numSaxMarkers;
			targetDeltas.push_back(avgAngle);
			std::cout<<frame<<"\t"<<avgAngle*180/M_PI<<std::endl;
		}
		//The initFrame markers should correspond to the initFrame of the mesh as that is what is used in the comparisons
		initFrame.clear();

		Point3D sax_centroid(0, 0, 0);
		for (int seg = 0; seg < NUMBER_OF_SAX_NODES; seg++)
		{
			Cmiss_field_cache_set_node(cache, cmiss_nodes[saxNodes[seg]]);
			Cmiss_field_evaluate_real(coordinates_rc_, cache, 3, coord);
			Point3D start(coord);
			initFrame.push_back(start);
			sax_centroid += start;
		}
		sax_centroid = sax_centroid * (-1.0 / NUMBER_OF_SAX_NODES);
		for (int seg = 0; seg < NUMBER_OF_SAX_NODES; seg++)
		{
			initFrame[seg] += sax_centroid;
		}

	}
	else
	{
		std::cout << "--- No field module for heart region!!! (Short Axis Fitting)";
		std::cout << "No field module " << std::endl;
		throw -1;
	}

	Cmiss_region_destroy(&heart_region);
	Cmiss_region_destroy(&root_region);
}
コード例 #13
0
void ShortAxisFitting::fit() {
	//Compute the segment lengths
	double *tempSpace = new double[NUMBER_OF_SEGMENTS * numberOfModelFrames_];
	memcpy(tempSpace, initialSegmentLengths, sizeof(double) * NUMBER_OF_SEGMENTS * numberOfModelFrames_);

	ShortAxisOptimizationInput* input = new struct ShortAxisOptimizationInput;
	input->numberOfModelFrames = numberOfModelFrames_;
	input->NUMBER_OF_SEGMENTS = NUMBER_OF_SEGMENTS;
	input->NUMBER_OF_SAX_NODES = NUMBER_OF_SAX_NODES;
	input->field_module = field_module_;
	input->coordinates_rc = coordinates_rc_;
	input->cache = cache;
	input->cmiss_nodes = &cmiss_nodes;
	input->targetDeltas = &targetDeltas;
	input->endoNodesIds = endoNodeIds;
	input->segmentNodes = segmentNodes;
	input->saxNodes = saxNodes;
	input->initialSegmentLengths = initialSegmentLengths;
	input->result = &tempSpace;
	input->segmentMatchError = 0.0;
	input->initFrame = &initFrame;
	input->initEndoCoordinates = &initEndoCoordinates;

	int nodegroups[][12] = {
	   {aplaxNodes0,aplaxNodes8,tchNodes0,tchNodes8,fchNodes0,fchNodes8,aplaxtchNode00,aplaxtchNode88,fchaplaxNode00,fchaplaxNode88,fchtchNode08,fchtchNode80},
	   {aplaxNodes1,aplaxNodes7,tchNodes1,tchNodes7,fchNodes1,fchNodes7,aplaxtchNode11,aplaxtchNode77,fchaplaxNode11,fchaplaxNode77,fchtchNode17,fchtchNode71},
	   {aplaxNodes2,aplaxNodes6,tchNodes2,tchNodes6,fchNodes2,fchNodes6,aplaxtchNode22,aplaxtchNode66,fchaplaxNode22,fchaplaxNode66,fchtchNode26,fchtchNode62},
	   {aplaxNodes3,aplaxNodes5,tchNodes3,tchNodes5,fchNodes3,fchNodes5,aplaxtchNode33,aplaxtchNode55,fchaplaxNode33,fchaplaxNode55,fchtchNode35,fchtchNode53}
	};

	// These variables define stopping conditions for the optimizer.
	//
	// We use very simple condition - |g|<=epsg
	//
	//Note that we do not want decimal accuracy, also the minimization problem never seems
	//to reduce the error to zero, rather the order is in 10000.00
	double epsg = 0.10;
	double epsf = 0;
	double epsx = 0;
	double epso = 0.0010;
	double epsi = 0.0010;

	alglib::real_1d_array x;
	alglib::real_1d_array bndl;
	alglib::real_1d_array bndu;

	//Create the initial and boundary vectors
	int parameters = 4;
	double* tempValues = new double[parameters];

	for (int i = 0; i < parameters; i++)
	{
		tempValues[i] = -0.25;
	}
	bndl.setcontent(parameters, tempValues);
	for (int i = 0; i < parameters; i++)
	{
		tempValues[i] = +0.25;
	}
	bndu.setcontent(parameters, tempValues);

	alglib::minbleicstate state;
	alglib::minbleicreport rep;

	alglib::ae_int_t maxits = 0;

	//
	// This variable contains differentiation step
	//
	double diffstep = 1.0e-4;

	for (int frame = 0; frame < numberOfModelFrames_; frame++)
	{
		input->frame = frame;
		clock_t begin = clock();


		tempValues[0] = 0.0;
		tempValues[2] = targetDeltas[frame];
		tempValues[1] = -targetDeltas[frame]/2;
		tempValues[3] = -targetDeltas[frame]/2;

		x.setcontent(parameters,tempValues);
		//Compute the centroids
		{
			double coord[3];
			double time = ((double) frame) / ((double) numberOfModelFrames_);
			if (frame == (numberOfModelFrames_ - 1))
			{
				time = 1.0;
			}
			Cmiss_field_cache_set_time(cache, time);
			//Compute the centroids
			Point3D centroids[4];
			for(int sc=0;sc<4;sc++){
				for(int nc = 0;nc<12;nc++){
					Cmiss_field_cache_set_node(cache, cmiss_nodes[nodegroups[sc][nc]]);
					Cmiss_field_evaluate_real(coordinates_rc_, cache, 3, coord);
					Point3D start(coord);
					centroids[sc] += start;
				}
				input->centroids[sc] = centroids[sc]*(-1.0/12);
			}

		}


		//
		// Now we are ready to actually optimize something:
		// * first we create optimizer
		// * we add boundary constraints
		// * we tune stopping conditions
		// * and, finally, optimize and obtain results...
		//
		try
		{
			alglib::minbleiccreatef(x, diffstep, state);
			alglib::minbleicsetbc(state, bndl, bndu);
			alglib::minbleicsetinnercond(state, epsg, epsf, epsx);
			alglib::minbleicsetoutercond(state, epso, epsi);
			alglib::minbleicoptimize(state, optimize, NULL, input);
			alglib::minbleicresults(state, x, rep);
			setThetaDelta(input, x);

			{
				double coord[3];
				{
					double time = ((double) frame) / ((double) numberOfModelFrames_);
					if (frame == (numberOfModelFrames_ - 1))
					{
						time = 1.0;
					}
					Cmiss_field_cache_set_time(cache, time);
					std::vector<Point3D> sax;
					Point3D sax_centroid(0, 0, 0);
					for (int seg = 0; seg < NUMBER_OF_SAX_NODES; seg++)
					{
						Cmiss_field_cache_set_node(cache, cmiss_nodes[saxNodes[seg]]);
						Cmiss_field_evaluate_real(coordinates_rc_, cache, 3, coord);
						Point3D start(coord);
						sax.push_back(start);
						sax_centroid += start;
					}
					sax_centroid = sax_centroid * (1.0 / NUMBER_OF_SAX_NODES);
					double avg = 0.0;
					for (int seg = 0; seg < NUMBER_OF_SAX_NODES; seg++)
					{
						Vector3D trans = sax[seg] - sax_centroid;
						double denom = trans.x- initFrame[seg].x;
						double nuem  = trans.z- initFrame[seg].z;
						double ltheta = atan2(nuem, denom);
						if(fabs(denom)<1.0e-6 && fabs(nuem)<1.0e-6){
							ltheta = 0.0;
						}
						avg+=ltheta;
					}
					avg/=NUMBER_OF_SAX_NODES;
					std::cout << "Frame " << frame << "\t" << x.tostring(5)<<"\t Result "<<avg*180/M_PI<<"\t Target "<<targetDeltas[frame]*180/M_PI<< std::endl;
				}

			}

		} catch (alglib::ap_error& err)
		{
			std::cout << err.msg << std::endl;
		}

		clock_t end = clock();
		double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
		std::cout << "Optimization took " << elapsed_secs << std::endl;
		std::cout <<"Total Error "<< input->totalError << "\t segment error " << input->segmentMatchError << "\t thetaError " << input->thetaError << std::endl;
		std::cout<<"*******************************************************************"<<std::endl;
	}
	delete[] tempSpace;
	throw -1;
}
コード例 #14
0
ファイル: fieldcache.hpp プロジェクト: A1kmm/libzinc
	int setTime(double time)
	{
		return Cmiss_field_cache_set_time(id, time);
	}