Commit 6d550efc authored by Vladimír Ulman's avatar Vladimír Ulman
Browse files

Added rigid movement of cells with SOFA.

Since routines from Cell::SOFA_MoveImportedToReferencePosition() and
Cell::SOFA_MoveInitialToReferencePosition() could have been reused for
the rigid movements, their become wrappers to some new helper BPs
moving functions.

M    src/cell_08_G2Phase.cpp		- added support for cell movement with SOFA
M    src/cell.h						- added docs to the new functions
M    src/cellSOFA.cpp				- guess what :-)
M    ISBI2015/config-smallVOI-lowSNR.ini		- introduced new testing parameter: "disable rigid movement"
parent e4916ceb
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -223,10 +223,10 @@ export mask grid stepping = 7
; One can disable certain import by disabling/commenting respective parameter.
;
; The syntax follows that of the standard C library printf() function.
import name nucleus BP          = ../deformationsID01-05/all/ID%02u_T%03lu_nucleusOuterBoundaryPoints.txt
import name nucleoli1 BP        = ../deformationsID01-05/all/ID%02u_T%03lu_nucleoli1OuterBoundaryPoints.txt
import name nucleoli2 BP        = ../deformationsID01-05/all/ID%02u_T%03lu_nucleoli2OuterBoundaryPoints.txt
import name chromatin molecules = ../deformationsID01-05/all/ID%02u_T%03lu_chromatinPoints.txt
import name nucleus BP          = ../deformationsID01-10/ID%02u_T%03lu_nucleusOuterBoundaryPoints.txt
import name nucleoli1 BP        = ../deformationsID01-10/ID%02u_T%03lu_nucleoli1OuterBoundaryPoints.txt
import name nucleoli2 BP        = ../deformationsID01-10/ID%02u_T%03lu_nucleoli2OuterBoundaryPoints.txt
import name chromatin molecules = ../deformationsID01-10/ID%02u_T%03lu_chromatinPoints.txt

; import name nucleus BP          = ID%02u_T%03lu_nucleusOuterBoundaryPoints.txt
; import name nucleoli1 BP        = ID%02u_T%03lu_nucleoli1OuterBoundaryPoints.txt
@@ -242,10 +242,12 @@ import name chromatin molecules = ../deformationsID01-05/all/ID%02u_T%03lu_chrom
; The centre position is given in microns relative to the scene [0,0,0],
; as three (positive) real numbers separated with white space.
; The angle is given, for user convenience, in degrees.
ID01 initial position = 40.6   43		4.5
ID01 initial rotation = 45
;ID01 initial position = 40.6   43		4.5
;ID01 initial rotation = 45
ID03 initial position = 20.6 48.8 4.5
ID03 initial rotation = -90
ID04 initial position = 10.8 35.4 4.5
ID02 initial rotation = 30


;
@@ -350,7 +352,7 @@ level = 1
;
; Used in the Scheduler constructor. Should be positive natural numbers.
;init mask min label = 1
;init mask max label = 1
init mask max label = 2

;
; For non-rigid deformations, the simulator uses a coherent deformation pool
@@ -391,5 +393,13 @@ single run length = 1
; cells the same.
;
; Used in both Scheduler constructors. Should be positive natural number.
cell initial G2 life = 50
cell initial G2 life = 20

;
; If rigid movement of cells is enabled in the CMake, this parameter can
; disable it. It cannot, however, enable it if the rigid movement is disabled
; in the CMake (as the code is simply missing in the simulator binary then).
;
; Presence of the parameter with any value disables the movements,
; and vice versa.
disable rigid movement = 1
+32 −0
Original line number Diff line number Diff line
@@ -909,6 +909,38 @@ template <class MV, class PV> class Cell
			  * relative to the position found in the SOFA import files.
			  */
			 void SOFA_InitReferencePosition(void);

			 /**
			  * Helper functions, but actually these are the workhorses for
			  * rigid movements of cells under SOFA enabled in the CMake.
			  *
			  * This one works with cell boundary points.
			  *
			  * Performs rotation by \e rotAngle (in radians) around the centre
			  * at \e preRotTrans and then shifts the cell by \e postRotTrans - \e preRotTrans
			  * (both in microns).
			  *
			  * \param[in] preRotTrans
			  * \param[in] rotAngle
			  * \param[in] postRotTrans
			  */
			 void SOFA_TransformCellBPs(const i3d::Vector3d<float> preRotTrans,
										 const float rotAngle,
										 const i3d::Vector3d<float> postRotTrans);
			 /**
			  * Same as Cell::SOFA_TransformCellBPs() except that this one
			  * deals with nucleus and nuclei boundary points.
			  */
			 void SOFA_TransformNuclStarBPs(const i3d::Vector3d<float> preRotTrans,
										 const float rotAngle,
										 const i3d::Vector3d<float> postRotTrans);
			 /**
			  * Same as Cell::SOFA_TransformCellBPs() except that this one
			  * deals with chromatin points.
			  */
			 void SOFA_TransformChromatinPs(const i3d::Vector3d<float> preRotTrans,
										 const float rotAngle,
										 const i3d::Vector3d<float> postRotTrans);
			 //-------- SOFA -------- 

			 ///if the cell is comet, this represents its state
+65 −39
Original line number Diff line number Diff line
@@ -222,22 +222,45 @@ void Cell<MV, PV>::SOFA_NextImport(const size_t T)

//-----------------------------------------------------------------------------
template <class MV, class PV>
void Cell<MV, PV>::SOFA_MoveImportedToReferencePosition(void)
void Cell<MV, PV>::SOFA_TransformCellBPs(const i3d::Vector3d<float> preRotTrans,
										 const float rotAngle,
										 const i3d::Vector3d<float> postRotTrans)
{
	//cached results of "expensive" functions...
	const float ccooss=cos(rotAngle);
	const float ssiinn=sin(rotAngle);

	//iterators to sweep the lists...
	std::vector< i3d::Vector3d<float> >::iterator Fiter;
	
	//process cell BPs
	Fiter=scmCellBPList.begin();
	while (Fiter != scmCellBPList.end())
	{
	//time-savers...
	const i3d::Vector3d<float>
			preRotTrans( scmNucleusBPCentre );
		*Fiter -= preRotTrans;
		float nx=ccooss*Fiter->x - ssiinn*Fiter->y;
		float ny=ssiinn*Fiter->x + ccooss*Fiter->y;
		Fiter->x = nx + postRotTrans.x;
		Fiter->y = ny + postRotTrans.y;
		Fiter->z +=     postRotTrans.z;

	const i3d::Vector3d<float>
			postRotTrans ( SOFA_InitialPosition );
		++Fiter;
	}
	scmCellBPCentre=postRotTrans;
}

	//and cached results of "expensive" functions...
	const float ccooss=cos(SOFA_InitialRotation);
	const float ssiinn=sin(SOFA_InitialRotation);
//-----------------------------------------------------------------------------
template <class MV, class PV>
void Cell<MV, PV>::SOFA_TransformNuclStarBPs(const i3d::Vector3d<float> preRotTrans,
										 const float rotAngle,
										 const i3d::Vector3d<float> postRotTrans)
{
	//cached results of "expensive" functions...
	const float ccooss=cos(rotAngle);
	const float ssiinn=sin(rotAngle);

	//iterators to sweep the lists...
	std::vector< i3d::Vector3d<float> >::iterator Fiter;
	std::vector< Molecule >::iterator Miter;
	
	//process nucleus:
	Fiter=scmNucleusBPList.begin();
@@ -295,6 +318,20 @@ void Cell<MV, PV>::SOFA_MoveImportedToReferencePosition(void)
	scmNucleoli2BPCentre.y = ny + postRotTrans.y;
	scmNucleoli2BPCentre.z +=     postRotTrans.z;
#endif
}

//-----------------------------------------------------------------------------
template <class MV, class PV>
void Cell<MV, PV>::SOFA_TransformChromatinPs(const i3d::Vector3d<float> preRotTrans,
										 const float rotAngle,
										 const i3d::Vector3d<float> postRotTrans)
{
	//cached results of "expensive" functions...
	const float ccooss=cos(rotAngle);
	const float ssiinn=sin(rotAngle);

	//iterator...
	std::vector< Molecule >::iterator Miter;

	//process chromatin:
	Miter=chrDotList.begin();
@@ -313,37 +350,26 @@ void Cell<MV, PV>::SOFA_MoveImportedToReferencePosition(void)

//-----------------------------------------------------------------------------
template <class MV, class PV>
void Cell<MV, PV>::SOFA_MoveInitialToReferencePosition(void)
{
	//time-savers...
	const i3d::Vector3d<float>
			preRotTrans( scmCellBPCentre );

	const i3d::Vector3d<float>
			postRotTrans ( SOFA_InitialPosition );

	//and cached results of "expensive" functions...
	const float ccooss=cos(SOFA_InitialRotation);
	const float ssiinn=sin(SOFA_InitialRotation);

	//iterators to sweep the lists...
	std::vector< i3d::Vector3d<float> >::iterator Fiter;
	
	//process cell BPs
	Fiter=scmCellBPList.begin();
	while (Fiter != scmCellBPList.end())
void Cell<MV, PV>::SOFA_MoveImportedToReferencePosition(void)
{
		*Fiter -= preRotTrans;
		float nx=ccooss*Fiter->x - ssiinn*Fiter->y;
		float ny=ssiinn*Fiter->x + ccooss*Fiter->y;
		Fiter->x = nx + postRotTrans.x;
		Fiter->y = ny + postRotTrans.y;
		Fiter->z +=     postRotTrans.z;

		++Fiter;
	SOFA_TransformChromatinPs(scmNucleusBPCentre,
				SOFA_InitialRotation,SOFA_InitialPosition);

	SOFA_TransformNuclStarBPs(scmNucleusBPCentre,
				SOFA_InitialRotation,SOFA_InitialPosition);
	//
	//note1: Chromatin must be transformed first as transforming Nucl* points also modifies
	//their centre scmNucleusBPCentre...
	//
	//note2: parameters are handed intentionally by value (copies are made)
}

	scmCellBPCentre=postRotTrans;
//-----------------------------------------------------------------------------
template <class MV, class PV>
void Cell<MV, PV>::SOFA_MoveInitialToReferencePosition(void)
{
	SOFA_TransformCellBPs(scmCellBPCentre,
				SOFA_InitialRotation,SOFA_InitialPosition);
}

//-----------------------------------------------------------------------------
+67 −1
Original line number Diff line number Diff line
@@ -47,6 +47,12 @@ void Cell<MV, PV>::DoG2Phase(const size_t noFrames)

	// ---------- actions a phase needs to do before the frame generating cycle ----------
	//prepare the activity plan to spread the phase duties over the given number of frames

#else //after SOFA

	//accumulated translation and rotation
	i3d::Vector3d<float> slsTranslation(0.f);
	float slsRotation=0.f;
#endif //after SOFA

	//the main cycle
@@ -100,11 +106,71 @@ void Cell<MV, PV>::DoG2Phase(const size_t noFrames)
		MoveBPListAndCentre(scmNucleoli2BPList,scmNucleoli2BPCentre,FF);
#endif
#else //after SOFA
		//read the current cell shape, driven now by the SOFA:
		//read the comming cell shape, driven now by the SOFA:
		SOFA_NextImport(timePoint+1);
		scmCellBPList=scmNucleusBPList;
		scmCellOuterBPNumber=scmNucleusOuterBPNumber;
		scmCellBPCentre=scmNucleusBPCentre;

#ifdef GTGEN_WITH_RIGIDMOTION
		if ( !configIni["testing"].present("disable rigid movement") )
		{
			//try to move the cell...
			i3d::Vector3d<float> sugTranslation;	//suggested transl.
			float sugRotation;							//suggested rotation

			int tries=0;									//attempts counter
			bool collision=true;							//suggested configuration flag

			//while not many unsuccessful attempts...
			while ((collision) && (tries < 500))
			{
				SuggestBrownianVector(sugTranslation,
						i3d::Vector3d<float>(cellMagnitudeOfMovementPerFrame,
													cellMagnitudeOfMovementPerFrame,
													0.f) //cellMagnitudeOfMovementPerFrame/3.f)
											);
				//sugRotation=GetRandomGauss(0.f,0.23f);
				sugRotation=GetRandomGauss(0.3*scmLastRotationAngle,0.23f * (1.f + float(tries)/500.0));
				++tries;

				//check the new suggestion...
				collision=ScmNewCellPositionCollide(SOFA_InitialPosition,
																slsRotation+sugRotation,
																slsTranslation+sugTranslation);
			}
			if (!collision)
			{
				//accept the new position
				REPORT("translating by " << sugTranslation
							<< " microns and rotating by "
							<< sugRotation*180.f/3.14159f
							<< " degrees after " << tries << " tries");

				//remember the linking transformation
				slsRotation+=sugRotation;
				slsTranslation+=sugTranslation;

				//remember the last movement
				scmLastTranslationVector=sugTranslation;
				scmLastRotationAngle=sugRotation;

				//and commit it to the cell representation
				SOFA_TransformCellBPs(SOFA_InitialPosition,
								slsRotation,SOFA_InitialPosition+slsTranslation);
				SOFA_TransformNuclStarBPs(SOFA_InitialPosition,
								slsRotation,SOFA_InitialPosition+slsTranslation);
				SOFA_TransformChromatinPs(SOFA_InitialPosition,
								slsRotation,SOFA_InitialPosition+slsTranslation);
			}
			else
				//if unsuccessful in suggesting, try also the current position
				if (ScmNewCellPositionCollide(i3d::Vector3d<float>(0.f)))
					throw ERROR_REPORT("Unable to find non-colliding movement.");
		}
		else
		REPORT("TESTING MODE: rigid cell movement is disabled");
#endif
#endif //after SOFA