Add Condition via c# (Unity)

Hi,

I would like to add SEConditions to a simulation (prior to start) through my own script, similar to how you can use the ProcessAction method on the engine already,

Is this possible? I cannot see an obvious method at the moment to achieve this,

Thanks,

To use an SECondtion, you will need to instantiate a SEPatientConfiguration object and provide it an SEPatient object as well as the SEConditions.

You can then replace the code were we load a state via sting or file in the Start method

You can pretty much just use this code block here

1 Like

Ahh perfect,

I have copied the pulse data folder to Assets/StreamingAssets, and have the following code: (I am received an error where pulse doesn’t seem to find any of my patient details age etc:

        SEPatientConfiguration cfg = new SEPatientConfiguration();
        cfg.SetDataRootDir(Application.streamingAssetsPath + "/PulseData");
        cfg.GetPatient().SerializeFromFile("./patients/Joe.json");

        if (!engine.InitializeEngine(cfg, data_mgr))
        {
            Console.WriteLine("Error Initializing Pulse!");
            return;
        }

Pulse log (First few lines):

[ERROR] : [0(s)] Unable to find substance directory : ./
[INFO] : [0(s)] Initializing engine
[INFO] : [0(s)] Human Adult Whole Body
[INFO] : [0(s)] Version : 4.1.0
[INFO] : [0(s)] GitHash : 2123f3c3
[INFO] : [0(s)] Build Time : Mon Aug 21 16:17:44 2023
[INFO] : [0(s)] Looking for files in C:/Users/USER/Desktop/Vital Medical Engine/Assets/StreamingAssets/PulseData
[INFO] : [0(s)] Configuring patient
[INFO] : [0(s)] No patient age set. Using the standard value of 44 years.
[INFO] : [0(s)] No patient height set. Using the standard value of 177 cm.
[INFO] : [0(s)] Patient ideal body weight computed and set to 72.2756 kg.
[INFO] : [0(s)] No patient weight set. Using the standard BMI value of 21.75 kg/m^2, resulting in a weight of 68.1406 kg.
[INFO] : [0(s)] No patient body fat fraction set. Using the standard value of 0.21.
[INFO] : [0(s)] Patient lean body mass computed and set to 53.8311 kg.
[INFO] : [0(s)] Patient body density computed and set to 1.05052 g/cm^3.
[INFO] : [0(s)] No patient heart rate baseline set. Using the standard value of 72 bpm.
[INFO] : [0(s)] No patient heart rate maximum set. Using a computed value of 177.2 bpm.
[INFO] : [0(s)] No patient heart rate minimum set. Using a default value of 0.001 bpm.
[INFO] : [0(s)] No patient systolic pressure baseline set. Using the standard value of 114 mmHg.
[INFO] : [0(s)] No patient diastolic pressure baseline set. Using the standard value of 73.5 mmHg.
[INFO] : [0(s)] No patient blood volume baseline set. Using a computed value of 4863.82 mL.
[INFO] : [0(s)] No patient respiration rate baseline set. Using the standard value of 12 bpm.
[INFO] : [0(s)] No patient right lung ratio set. Using the standard value of 0.525.
[INFO] : [0(s)] No patient total lung capacity set. Using a computed value of 5.78205 L.
[INFO] : [0(s)] No patient functional residual capacity set. Using a computed value of 2.16827 L.
[INFO] : [0(s)] No patient residual volume set. Using a computed value of 1.15641 L.
[INFO] : [0(s)] Patient tidal volume computed and set to 0.505929 L.
[INFO] : [0(s)] Patient vital capacity computed and set to 4.62564 L.
[INFO] : [0(s)] Patient expiratory reserve volume computed and set to 1.01186 L.
[INFO] : [0(s)] Patient inspiratory reserve volume computed and set to 3.10785 L.
[INFO] : [0(s)] Patient inspiratory capacity computed and set to 3.61378 L.
[INFO] : [0(s)] No patient alveoli surface area set. Using a computed value of 65.5986 m^2.
[INFO] : [0(s)] No patient skin surface area set. Using a computed value of 1.84221 m^2.
[INFO] : [0(s)] No patient basal metabolic rate set. Using a computed value of 1601.15 kcal/day.
[INFO] : [0(s)] Resetting Substances
[ERROR] : [0(s)] Unable to read substance C:/Users/jackb/Desktop/Vital Medical Engine/Assets/StreamingAssets/PulseData/substances/Acetoacetate.json.meta
[ERROR] : [0(s)] Unable to read substance C:/Users/jackb/Desktop/Vital Medical Engine/Assets/StreamingAssets/PulseData/substances/Albumin.json.meta

Pulse is looking for these directories under this folder

Are they in the referenced PulseData folder?

You can set exactly where Pulse can find these files via this call
cfg.SetDataRootDir("./");

You can try setting it to Application.streamingAssetsPath+"/Data/"

Yes, these have been copied over:

image

I tried renaming but it has not changed anything unfortunately, I still get pulse logs that match the above

It looks like Pulse is trying to read the meta files too
Unable to read substance C:/Users/jackb/Desktop/Vital Medical Engine/Assets/StreamingAssets/PulseData/substances/Acetoacetate.json.meta

I fixed this in the stable/integration branch, but it has not made it up to the Unity Asset yet.
This should work when I get that updated

For now, if you copy that data root directory out of the Unity project (so unity does not regenerate meta files) and get rid of the meta files, that should work.

I need to get that new build up :expressionless:

Yes I did notice that, ahh yea okay that would be great :slight_smile:

This would likely stop the substance-based issues - but how about the patient? It just doesn’t seem to pull any of the data from the patient JSON I’m telling it to serialize?

eg: No patient age set. Using the standard value of 44 years.

I would try

cfg.SetDataRootDir(Application.streamingAssetsPath + "/PulseData");
cfg.GetPatient().SerializeFromFile(Application.streamingAssetsPath + "/PulseData/patients/Joe.json");

I don’t think it’s going to find that relative path to your patient file

1 Like

No problem, Trying that gives a unity error this time - with an empty pulse log:

Code:

Can you break at the if statement?
I would inspect the cfg object, it seems like the HR or RR is not being read in properly

maybe I have also fixed this

What OS are you on? I can probably build a win64 version of the latest pretty quickly

1 Like

Success - I had a corrupted JSON patient with incorrect values for the units,

Given the patient now reads /serializes correctly - is there a quick way to check substances are okay?, I know it is trying to read the meta files at the moment, but would this actually cause any error or just a warning?

Unfortunatly, the logic for reading substance files would assume it should be able to read any file in the specified substance directory. When it could not, it would return false which then stops the initialization process of the engine.

We either need to get you an updated build of the native library or you ensure there are no meta files in the substance directory

1 Like

That makes sense, thanks a lot.

I have just tried a build on Android, with the above logic to set the data directory for pulse and read a patient from file - this however results in a 5 or so second delay and freeze whilst pulse searches the directory for files.

Is there possibly a way I can get the engine to initialize a patient file (not state, just patient) - without using the set directory/streaming assets approach?

Even just drag and dropping a patient file into the inspector would be fine. Looking at the demo pulse driver, this unfortunately only seems to work for state files?.

I apologise for the amount of queries, I do appreciate your support on this as I try to find a solution for this project!

Its possible, but we would need to add that functionality into the engine.

I would need to create a single file that contains all the initialization data contained in these files
Update Pulse to be able to source its data from this single structure rather than files on disk

You could then drag this file, along with a patient file, into the inspector and it would all get processed on the fly.

That is possible, but a hefty amount of work

hmm I see, I certainly do not want to burden you with any significant work here,

I guess an alternative would be the ability to create a saved stable state @0s from a given patient directly through the pulse API? prior to building to the target platform?

Correct
It would take several minutes on an android device to actually stabilize the engine to your patient specification. It would probably be better to create a set of states for your application.

You can create patient states by creating a simple C# consoloe program like this

public static void Run()
{
  PulseEngine pulse = new PulseEngine();
  pulse.LogToConsole(true);
  SEPatientConfiguration cfg = new SEPatientConfiguration();
  // Grab the patient and fill in some data
  SEPatient patient = cfg.GetPatient();
  patient.SetName("Bengey");
  patient.SetSex(ePatient_Sex.Male);
  patient.GetAge().SetValue(30, TimeUnit.yr);
  patient.GetWeight().SetValue(200, MassUnit.lb);
  patient.GetHeight().SetValue(74, LengthUnit.inch);
  patient.GetBodyFatFraction().SetValue(0.16);
  patient.GetSystolicArterialPressureBaseline().SetValue(120, PressureUnit.mmHg);
  patient.GetDiastolicArterialPressureBaseline().SetValue(72, PressureUnit.mmHg);
  patient.GetHeartRateBaseline().SetValue(67, FrequencyUnit.Per_min);
  patient.GetRespirationRateBaseline().SetValue(12, FrequencyUnit.Per_min);

  if (!pulse.InitializeEngine(cfg, new SEDataRequestManager()))
  {
    Console.WriteLine("Error Initializing Pulse!");
    return;
  }
  pulse.SerializeToFile("./test_results/howto/HowTo_CreatedState.json");
}
1 Like

This has worked perfectly!

Thanks so much for the support - I can imagine you have plenty of other things to deal with, so I really appreciate you taking the time to help me out,

Best!