Skip to content

Commit 9fa80c9

Browse files
committed
feat: pushing a partial refactor for brain surface code
- There is still a bug that is putting the surface coordinate at the wrong place when a transform is enabled. Not clear where it's coming from
1 parent b8e5e31 commit 9fa80c9

File tree

2 files changed

+90
-61
lines changed

2 files changed

+90
-61
lines changed

Assets/Scripts/Pinpoint/Probes/ProbeManager.cs

Lines changed: 88 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public static string[] GetAllChannelAnnotationData()
112112
private const float maxRoll = 180f;
113113

114114
// Brain surface position
115-
private bool probeInBrain;
115+
private bool _probeInBrain;
116116
private Vector3 _brainSurfaceCoordT;
117117
private Vector3 _brainSurfaceWorldU;
118118
private Vector3 _brainSurfaceWorldT;
@@ -370,7 +370,7 @@ public void UpdateName()
370370
else
371371
{
372372
// Check if this probe is in the brain
373-
name = probeInBrain ? $"{_probeUIManagers[0].MaxArea}-{UUID[..8]}" : UUID[..8];
373+
name = _probeInBrain ? $"{_probeUIManagers[0].MaxArea}-{UUID[..8]}" : UUID[..8];
374374
}
375375
}
376376

@@ -734,40 +734,7 @@ public void ResizeProbePanel(int newPxHeight)
734734
UIUpdateEvent.Invoke();
735735
}
736736

737-
#region Brain surface coordinate
738-
739-
/// <summary>
740-
/// Check whether the probe is in the brain.
741-
/// If it is, calculate the brain surface coordinate by iterating up the probe until you leave the brain.
742-
/// </summary>
743-
public void UpdateSurfacePosition()
744-
{
745-
// note: the backward axis on the probe is the probe's "up" axis
746-
(Vector3 tipCoordWorld, _, _, Vector3 tipForwardWorldU) = _probeController.GetTipWorldU();
747-
748-
Vector3 surfaceIdxCoordU = FindSurfaceIdxCoordinate(BrainAtlasManager.ActiveReferenceAtlas.World2AtlasIdx(tipCoordWorld),
749-
BrainAtlasManager.ActiveReferenceAtlas.World2Atlas_Vector(-tipForwardWorldU));
750-
751-
if (float.IsNaN(surfaceIdxCoordU.x))
752-
{
753-
// not in the brain
754-
probeInBrain = false;
755-
_brainSurfaceWorldU = new Vector3(float.NaN, float.NaN, float.NaN);
756-
_brainSurfaceWorldT = new Vector3(float.NaN, float.NaN, float.NaN);
757-
_brainSurfaceCoordT = new Vector3(float.NaN, float.NaN, float.NaN);
758-
}
759-
else
760-
{
761-
// in the brain
762-
probeInBrain = true;
763-
// get the surface coordinate in un-transformed world space
764-
_brainSurfaceWorldU = BrainAtlasManager.ActiveReferenceAtlas.AtlasIdx2World(surfaceIdxCoordU);
765-
// go back into transformed space, only using the reference coordinate for the entry coordinate (not the transform coordinate)
766-
_brainSurfaceWorldT = BrainAtlasManager.WorldU2WorldT(_brainSurfaceWorldU, false);
767-
_brainSurfaceCoordT = ProbeController.Insertion.World2T(_brainSurfaceWorldU);
768-
}
769-
}
770-
737+
#region Brain surface coordinate
771738

772739
public (Vector3 surfaceCoordinateT, float depthT) GetSurfaceCoordinateT()
773740
{
@@ -781,42 +748,85 @@ public Vector3 GetSurfaceCoordinateWorldT()
781748

782749
public bool IsProbeInBrain()
783750
{
784-
return probeInBrain;
751+
return _probeInBrain;
785752
}
786-
753+
787754
/// <summary>
788755
/// Move probe to brain surface
789756
/// </summary>
790757
public void DropProbeToBrainSurface()
791758
{
792-
if (probeInBrain)
759+
if (_probeInBrain)
793760
{
794761
_probeController.SetProbePosition(_brainSurfaceCoordT);
795762
}
796763
else
797764
{
798-
// We need to calculate the surface coordinate ourselves
799-
var tipExtensionDirection =
800-
ManipulatorBehaviorController.IsSetToDropToSurfaceWithDepth ? _probeController.GetTipWorldU().tipUpWorldU : Vector3.up;
801-
802-
var brainSurfaceCoordinate = FindSurfaceIdxCoordinate(
803-
BrainAtlasManager.ActiveReferenceAtlas.World2AtlasIdx(_probeController.GetTipWorldU().tipCoordWorldU - tipExtensionDirection * 5),
804-
BrainAtlasManager.ActiveReferenceAtlas.World2Atlas_Vector(tipExtensionDirection));
765+
(Vector3 entryCoordAtlasIdx, _) = CalculateEntryCoordinate(!ManipulatorBehaviorController.IsSetToDropToSurfaceWithDepth);
805766

806-
if (float.IsNaN(brainSurfaceCoordinate.x))
767+
if (float.IsNaN(entryCoordAtlasIdx.x))
807768
{
808769
Debug.LogWarning("Could not find brain surface! Canceling set brain offset.");
809770
return;
810771
}
811772

812-
var brainSurfaceToTransformed =
813-
_probeController.Insertion.World2T(
814-
BrainAtlasManager.ActiveReferenceAtlas.AtlasIdx2World(brainSurfaceCoordinate));
773+
var entryCoordAtlasT = BrainAtlasManager.ActiveAtlasTransform.U2T(
774+
BrainAtlasManager.ActiveReferenceAtlas.Idx2Atlas(entryCoordAtlasIdx));
815775

816-
_probeController.SetProbePosition(brainSurfaceToTransformed);
776+
_probeController.SetProbePosition(entryCoordAtlasT);
817777
}
818778
}
819779

780+
/// <summary>
781+
/// Check whether the probe is in the brain.
782+
/// If it is, calculate the brain surface coordinate by iterating up the probe until you leave the brain.
783+
/// </summary>
784+
public void UpdateSurfacePosition()
785+
{
786+
(Vector3 entryCoordAtlasIdx, bool probeInBrain) = CalculateEntryCoordinate();
787+
_probeInBrain = probeInBrain;
788+
789+
if (!_probeInBrain)
790+
{
791+
_brainSurfaceWorldU = new Vector3(float.NaN, float.NaN, float.NaN);
792+
_brainSurfaceWorldT = new Vector3(float.NaN, float.NaN, float.NaN);
793+
_brainSurfaceCoordT = new Vector3(float.NaN, float.NaN, float.NaN);
794+
}
795+
else
796+
{
797+
// get the surface coordinate in un-transformed world space
798+
_brainSurfaceWorldU = BrainAtlasManager.ActiveReferenceAtlas.AtlasIdx2World(entryCoordAtlasIdx);
799+
// go back into transformed space, only using the reference coordinate for the entry coordinate (not the transform coordinate)
800+
_brainSurfaceWorldT = BrainAtlasManager.WorldU2WorldT(_brainSurfaceWorldU, false);
801+
802+
_brainSurfaceCoordT = BrainAtlasManager.ActiveAtlasTransform.U2T(
803+
BrainAtlasManager.ActiveReferenceAtlas.World2Atlas(_brainSurfaceWorldU, true));
804+
}
805+
}
806+
807+
/// <summary>
808+
/// Calculate the entry coordinate on the brain surface, returns coordIdx
809+
/// </summary>
810+
/// <param name="calculateOutside"></param>
811+
/// <param name="useDV"></param>
812+
/// <returns>(entryCoordAtlasIdx, probeInBrain)</returns>
813+
public (Vector3 entryCoordAtlasIdx, bool probeInBrain) CalculateEntryCoordinate(bool useDV = false)
814+
{
815+
// note: the backward axis on the probe is the probe's "up" axis
816+
(Vector3 tipCoordWorldU, _, _, Vector3 tipForwardWorldU) = _probeController.GetTipWorldU();
817+
818+
Vector3 tipAtlasIdxU = BrainAtlasManager.ActiveReferenceAtlas.World2AtlasIdx(tipCoordWorldU);
819+
Vector3 downDir = useDV ? Vector3.down : tipForwardWorldU;
820+
821+
// Check if we're in the brain
822+
bool probeInBrain = BrainAtlasManager.ActiveReferenceAtlas.GetAnnotationIdx(tipAtlasIdxU) > 0;
823+
824+
Vector3 entryCoordAtlasIdx = FindEntryIdxCoordinate(probeInBrain ? tipAtlasIdxU : tipAtlasIdxU + downDir * 5000f / BrainAtlasManager.ActiveReferenceAtlas.Resolution.x,
825+
BrainAtlasManager.ActiveReferenceAtlas.World2Atlas_Vector(downDir));
826+
827+
return (entryCoordAtlasIdx, probeInBrain);
828+
}
829+
820830
/// <summary>
821831
/// Use the annotation dataset to discover whether there is a surface coordinate by going *down* from a point searchDistance
822832
/// *above* the startPos
@@ -826,25 +836,44 @@ public void DropProbeToBrainSurface()
826836
/// to enter first to discover the surface coordinate.
827837
/// </summary>
828838
/// <param name="bottomIdxCoordU">coordinate to go down to</param>
829-
/// <param name="upVector"></param>
839+
/// <param name="downVector"></param>
830840
/// <returns></returns>
831-
public Vector3 FindSurfaceIdxCoordinate(Vector3 bottomIdxCoordU, Vector3 upVector)
841+
public Vector3 FindEntryIdxCoordinate(Vector3 bottomIdxCoordU, Vector3 downVector)
832842
{
833843
// search from 10000 um above the top idx
844+
Debug.Log(downVector);
834845
float searchDistance = 10000 / BrainAtlasManager.ActiveReferenceAtlas.Resolution.z;
835-
// We'll start at a point that is pretty far above the brain surface
836-
// note that search distance is in 25um units, so this is actually 10000 um up (i.e. the top of the probe)
837-
Vector3 topSearchIdxCoordU = bottomIdxCoordU + upVector * searchDistance;
846+
Vector3 topSearchIdxCoordU = bottomIdxCoordU - downVector * searchDistance;
838847

839848
// If by chance we are inside the brain, go farther
840849
if (BrainAtlasManager.ActiveReferenceAtlas.GetAnnotationIdx(topSearchIdxCoordU) > 0)
841-
topSearchIdxCoordU = bottomIdxCoordU + upVector * searchDistance * 2f;
850+
topSearchIdxCoordU = bottomIdxCoordU - downVector * searchDistance * 2f;
842851

843-
for (float perc = 0; perc <= 1f; perc += 0.0005f)
852+
// We're going to speed this up by doing two searches: first a fast search to get into the brain, then a slow search to accurately
853+
// get the surface coordinate
854+
float finalPerc = -1f;
855+
for (float perc = 0; perc <= 1f; perc += 0.01f)
844856
{
845857
Vector3 point = Vector3.Lerp(topSearchIdxCoordU, bottomIdxCoordU, perc);
846858
if (BrainAtlasManager.ActiveReferenceAtlas.GetAnnotationIdx(point) > 0)
847-
return point;
859+
{
860+
Debug.Log(point);
861+
finalPerc = perc;
862+
break;
863+
}
864+
}
865+
866+
if (finalPerc > -1f)
867+
{
868+
for (float perc = finalPerc; perc >= 0f; perc -= 0.0001f)
869+
{
870+
Vector3 point = Vector3.Lerp(topSearchIdxCoordU, bottomIdxCoordU, perc);
871+
if (BrainAtlasManager.ActiveReferenceAtlas.GetAnnotationIdx(point) <= 0)
872+
{
873+
Debug.Log(point);
874+
return point;
875+
}
876+
}
848877
}
849878

850879
// If you got here it means you *never* entered and then exited the brain

Assets/Scripts/Pinpoint/UI/EphysCopilot/InsertionSelectionPanelHandler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public class InsertionSelectionPanelHandler : MonoBehaviour
7171
/// </summary>
7272
public static IEnumerable<ProbeManager> TargetableProbeManagers => ProbeManager.Instances
7373
.Where(manager => !manager.IsEphysLinkControlled).Where(manager => !float.IsNaN(manager
74-
.FindSurfaceIdxCoordinate(
74+
.FindEntryIdxCoordinate(
7575
BrainAtlasManager.ActiveReferenceAtlas.World2AtlasIdx(manager.ProbeController
7676
.Insertion
7777
.PositionWorldU()),
@@ -305,7 +305,7 @@ private void ComputeMovementInsertions()
305305
};
306306

307307
// Recalculate AP and ML based on pre-depth-drive DV
308-
var brainSurfaceCoordinate = ProbeManager.FindSurfaceIdxCoordinate(
308+
var brainSurfaceCoordinate = ProbeManager.FindEntryIdxCoordinate(
309309
BrainAtlasManager.ActiveReferenceAtlas.World2AtlasIdx(
310310
ManipulatorIDToSelectedTargetProbeManager[ProbeManager.ManipulatorBehaviorController.ManipulatorID]
311311
.ProbeController.Insertion.PositionWorldU()),

0 commit comments

Comments
 (0)