Question on Spine Moment

Hello AnyBody community,

I am currently investigating the biomechanics of the spine and I am using AnyBody.8.0.x as well as AMMR4-Beta. The model that I am using is Plug-in-gait_MultiTrial_StandingRef with flexible thoracic model, incorporating simple muscles+ligaments+non linear disc+soft rhythm for all 3 spine region. They are driven by mocap data, reflecting ADL movements.

I am trying to programme 'NetMoment' calculation for each of the discretised vertebral level and I have been looking at the past forum posts on the topic particularly this. I am attracted to this method because all the relevant muscles in any particular intervertebral joint will be taken into account through #include MuscleList.any by the AnyForceMomentMeasure2 class and saves me from retyping all the muscles again for every level.

My question will be, if I am going to code the moment at L3/L4 level (using AnyForceMomentMeasure2), do I need to include all the segments from lower limbs (foot/talus/shank/patella/thigh/pelvis/sacrum/L5/L4/L3) or only from pelvis (sacrum/pelvis/L5/L4/L3) given there is already 'Hand of God' residual implemented at the pelvis?

Also, do I need to include the ribs if I am calculating the moment in thoracic level?

Thank you.

Kind regards,
Faizal

Hi Faizal,

I think the approach sounds correct. But it depends on what you want to include in "NetMoment". As an example, you can see how the moments for joints in the leg are calculated.

The post you referred to is an old post and I will recommend you use Object Pointers and search functions for including segments and force elements (muscles, ligaments, etc.) instead of writing muscles in a muscle list. First of all, using search function (ObjSearch, and so on), you will avoid typing the list of all the muscles. Secondly, this will also make your code a little bit more robust in case you change the body model configuration. You can search for different types of objects and then include them in a single list using arrcat.

I would suggest including the thighs so that you get the effect of psoas muscles.

Likewise, if you are using the flexible thorax, then it would make sense to include the ribs for moments in the thoracic level as some muscles attach to the ribs.

Best regards,
Dave

1 Like

Hi Dave,

Thank you for your reply.

I have coded 'NetMoment' for L3/L4 joint level as per your suggestions. It is as below.

AnyForceMomentMeasure2 NetMomentAtL3L4 = {
      AnyRefFrame &ref = Main.HumanModel.BodyModel.Trunk.Segments.L4Seg.L3L4JntNode.RotNode;
      IncludeSegments = {
        &Main.HumanModel.BodyModel.Right.Leg.Seg.Foot,
        &Main.HumanModel.BodyModel.Right.Leg.Seg.Talus,
        &Main.HumanModel.BodyModel.Right.Leg.Seg.Shank,
        &Main.HumanModel.BodyModel.Right.Leg.Seg.Patella,
        &Main.HumanModel.BodyModel.Right.Leg.Seg.Thigh,
        &Main.HumanModel.BodyModel.Left.Leg.Seg.Foot,
        &Main.HumanModel.BodyModel.Left.Leg.Seg.Talus,
        &Main.HumanModel.BodyModel.Left.Leg.Seg.Shank,
        &Main.HumanModel.BodyModel.Left.Leg.Seg.Patella,
        &Main.HumanModel.BodyModel.Left.Leg.Seg.Thigh,
        &Main.HumanModel.BodyModel.Trunk.Segments.SacrumSeg,
        &Main.HumanModel.BodyModel.Trunk.Segments.PelvisSeg,
        &Main.HumanModel.BodyModel.Trunk.Segments.L5Seg,
        &Main.HumanModel.BodyModel.Trunk.Segments.L4Seg
      };
      AnyObjectPtrArray pArrJntReactions = {
        &Main.HumanModel.BodyModel.Right.Leg.Jnt.Hip.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Right.Leg.Jnt.Knee.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Right.Leg.Jnt.Ankle.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Right.Leg.Jnt.SubTalar.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Right.Leg.Jnt.PatellaFemur.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Right.Leg.Jnt.PatellaMovement.Reaction,
        &Main.HumanModel.BodyModel.Left.Leg.Jnt.Hip.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Left.Leg.Jnt.Knee.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Left.Leg.Jnt.Ankle.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Left.Leg.Jnt.SubTalar.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Left.Leg.Jnt.PatellaFemur.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Left.Leg.Jnt.PatellaMovement.Reaction,
        &Main.HumanModel.BodyModel.Trunk.Joints.Lumbar.SacrumPelvis.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Trunk.Joints.Lumbar.L5Sacrum.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Trunk.Joints.Lumbar.L4L5.Constraints.Reaction,
        &Main.HumanModel.BodyModel.Trunk.Joints.Lumbar.L3L4.Constraints.Reaction
      };  
      IncludeForces = arrcat(
      ObjSearch("Main.HumanModel.BodyModel.*.Leg.Mus.*", "AnyMuscle"),
      ObjSearch("Main.HumanModel.BodyModel.Trunk.Muscles.*.*.*", "AnyMuscle"),
      ObjSearchRecursive("Main.HumanModel.BodyModel.Trunk.JointMuscles", "*", "AnyMuscle"),
      pArrJntReactions
      );
      AnyVec3 Mlocal = M*Main.HumanModel.BodyModel.Trunk.Segments.L4Seg.L3L4JntNode.RotNode.Axes;
    };

  AnyVar LateralBendingOnL4 = Main.Studies.InverseDynamicStudy.OncoEngLoadingAnalysis.Lumbar.NetMomentAtL3L4.Mlocal[0]; // Positive to the right lateral bending
    AnyVar AxialRotationMomentOnL4 = Main.Studies.InverseDynamicStudy.OncoEngLoadingAnalysis.Lumbar.NetMomentAtL3L4.Mlocal[1]; // Positive to the right axial turning
      AnyVar FlexionExtensionMomentOnL4 = Main.Studies.InverseDynamicStudy.OncoEngLoadingAnalysis.Lumbar.NetMomentAtL3L4.Mlocal[2]; // Positive in extension direction

I am just wondering if there are other elements that I still haven't considered (e.g. disc?).

I am not the best programmer around but I tried :sweat_smile: So, I am also just wondering if you think the code could be improved to be more concise (as I am planning to measure moments in all level in lumbar and thoracic).

Let me know. Thank you very much.

Kind regards,
Faizal

Hi Faizal,

On a quick look, it looks to be all good. Do you have shoulder-arm muscles in your model? If yes, then you should include those also. You also mentioned about disc stiffness and ligaments. One of the things you can do is to run the same model without muscles and compare the results. In the model without muscles, you can find joint moment measures in selected outputs (only for lumbar and cervical level).

The thing that worries me is that it can get cumbersome when you come to the thoracic segments, because of all the ribs. I can't really say how to make the cut and which ribs to include at each joint. There are also the abdominal layers and the diaphragm model. As you can imagine, it's not so simple and there is a chance that we miss something.

To make the code more concise, you could use the object search function also for searching for joint reactions and segments. Especially the legs could be easily condensed by using *. And all the code related to legs and including muscles could be in a shared file, so you include that for all the instances.

While using object search helps in making the code concise and more robust since you don't have to manually write down all the list, and it is resilient to changes in body model configuration, the same is also a small drawback as it will not complain if it doesn't find all the objects. So, you may miss something with these changes and you may see different results than before and it can be hard to diagnose that.

Best regards,
Dave

1 Like

Hi Dave,

Thank you for your reply and comments.

Now, I understand that I could make the code even simpler when you suggested to use ObjSearch further.

I have programmed the code for NetMoment in all the lumbar joint levels and the model has been successfully loaded and simulated.

However, when I tried to programmed NetMoment for thoracic spine, I realised that all the thoracic vertebral segments are missing the new rotated reference node (as clarified here). And when I programmed this myself, I also then realised that the location for anterior and posterior superior endplate nodes are not defined in ThoracicNode.any file for all thoracic level except for T1.

I am happy to code the anterior and posterior endplate nodes in the individual thoracic vertebrae, but I do not know the source for the information of this nodes' coordinate position. I noticed that these nodes are defined in cervical and lumbar and they are distinctive at every level.

Would you be able to point and direct me where I could gather the position of the nodes so I could programme this?

Thank you.

Kind regards,
Faizal

Hi Faizal,

That is right, the nodes and joint reaction force at the thoracic level is still missing. It's on our to-do list, and we will get to it soon. :wink:

You can see the code in the segments file and the values in the model parameters file. Generally, the idea behind is to capture the orientation of the superior endplate of a vertebra. This is done by using RotMat with 3 points. The points are picked on the source stl files (be careful to use the unscaled stl files: export the surface from a model with scaling none). Probably the most important are the anterior and posterior points, that must be on the endplate surface and on the same "planar" sort of surface of the endplate. Then, there is one on the right side that is picked but is expressed in a way to get the offset from the midpoint of the anterior and posterior endplate nodes. This helps in ensuring it has the same x coordinate as the midpoint of the anterior and posterior nodes. Then, we can use the RotMat with 3 points (the origin: midpoint of anterior and posterior endplate nodes, anterior posterior axis defined by anterior node, and the medio lateral axis defined by a vector from the origin to the difference between right and left node on the endplate.

If you would like, I would also encourage you make fork the AMMR beta repository and make a pull request with your changes. Of course, there is no pressure to do that :slight_smile:

Best regards,
Dave

1 Like