# Running ALPACA from Python Console

**URL:** <https://discourse.slicer.org/t/running-alpaca-from-python-console/35538>\
**Category:** Support\
**Created:** [April 16, 2024, 4:39pm UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538 "2024-04-16T16:39:45Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![evaherbst](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/evaherbst/32/65595_2.png) [@evaherbst](https://discourse.slicer.org/u/evaherbst)\
**Post date:** [April 16, 2024, 4:39pm UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/1 "2024-04-16T16:39:46Z")

</div>

Hello, I am trying to run ALPACA from the Python console.

I am accessing the logic with:

> import ALPACA  
> AlpacaLogic = ALPACA.ALPACALogic()  
> Then I define my paths and directories as inputs for ALPACA batch mode.  
> I set skipScaling to False

When I try to run:  
AlpacaLogic.process(sourceModelPath, sourceLandmarkPath, targetModelDirectory, outputDirectory, skipScaling)

i get the error:

> Traceback (most recent call last):  
> File “”, line 10, in   
> File “C:/Users/eherbst/AppData/Local/slicer.org/Slicer 5.6.2/slicer.org/Extensions-32448/SlicerMorph/lib/Slicer-5.6/qt-scripted-modules/ALPACA.py”, line 3085, in process  
> “InputVolume”: inputVolume.GetID(),  
> AttributeError: ‘str’ object has no attribute ‘GetID’

I see in the ALPACA.py code that running Alpaca also requires the ProjectionFactor and Parameters, but if I do not define them as inputs, does it just use the defaults?

hank you,  
Eva

---

<div class="post-metadata">

**Author:** ![smrolfe](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/smrolfe/32/3659_2.png) [@smrolfe](https://discourse.slicer.org/u/smrolfe)\
**Post date:** [April 16, 2024, 10:21pm UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/2 "2024-04-16T22:21:35Z")

</div>

AlpacaLogic.process is a test utility and doesn’t run the method from the command line. The batch mode tab of the module is intended to handle bundled jobs, maybe if you could describe your use case for running this from the command line I can help find a solution?

---

<div class="post-metadata">

**Author:** ![chz31](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chz31/32/77363_2.png) [@chz31](https://discourse.slicer.org/u/chz31)\
**Post date:** [April 17, 2024, 2:25am UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/3 "2024-04-17T02:25:57Z")

</div>

I agree with Sara that the best way is probably just to run the batch mode in the UI.

If you want to run the batch mode in Python, you can use the function `runLandmarkMultiprocess()` in the `ALPACALogic`. There is a parameter `self.parameterDictionary` that would have all the required parameters. So far, the default parameters work for most of my cases.You can also check the function `onApplyLandmarkMulti()` to see how the batch mode runs using the `runLandmarkMultiprocess` function.

---

<div class="post-metadata">

**Author:** ![evaherbst](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/evaherbst/32/65595_2.png) [@evaherbst](https://discourse.slicer.org/u/evaherbst)\
**Post date:** [April 17, 2024, 7:16am UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/4 "2024-04-17T07:16:00Z")

</div>

Thank you Sara and Chi!

My use case is that I process a lot of scans (segmentation → landmark transfer via Alpaca → cropping based on landmarks) and since the segmentation and cropping is automated, it would be nice to also automate the Alpaca step to run everything together without manual input.

I will try the runLandmarkMultiprocess function.

Thanks again!  
Eva

---

<div class="post-metadata">

**Author:** ![evaherbst](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/evaherbst/32/65595_2.png) [@evaherbst](https://discourse.slicer.org/u/evaherbst)\
**Post date:** [April 19, 2024, 4:42pm UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/5 "2024-04-19T16:42:10Z")

</div>

Hi all,

Thanks for your help!  
I got it working with the following function:

> def runAlpaca(scapulaModelOutputDir, sourceModelPath, sourceLandmarkPath, landmarkOutputDirectory):  
> import ALPACA  
> AlpacaLogic = ALPACA.ALPACALogic()  
> targetModelDirectory = scapulaModelOutputDir  
> scalingOption= True  
> projectionFactor = 0.01  
> useJSONFormat = True  
> parameters = { #from Alpaca defaults  
> “projectionFactor”: 0.01,  
> “pointDensity”: 1.00,  
> “normalSearchRadius”: 2,  
> “FPFHNeighbors”: 100,  
> “FPFHSearchRadius”: 5.00,  
> “distanceThreshold”: 3.00,  
> “maxRANSAC”: 1000000,  
> “ICPDistanceThreshold”: 1.50,  
> “alpha”: 2.0,  
> “beta”: 2.0,  
> “CPDIterations”: 100,  
> “CPDTolerance”: 0.001,  
> “Acceleration”: False,  
> “BCPDFolder”: “T:/Slicer/bcpd-master/bcpd-master/win”  
> }  
> AlpacaLogic.runLandmarkMultiprocess(sourceModelPath, sourceLandmarkPath, targetModelDirectory, landmarkOutputDirectory, scalingOption, projectionFactor, useJSONFormat, parameters)

I copied all of the default parameters from the GUI, since I couldn’t figure out how to retrieve them from the command line.  
Maybe there is a more elegant solution that would update based on user inputs in the GUI, or the plugin’s defaults (in case they ever change).

Also, for projection factor, the default in the GUI is 1.0, but I saw that the code divides this by 100, so I did the same when hard coding the defaults (since it looks like the division happens and then the value is updated in the parameter list).

Setting it directly to 1.0 in the parameter list gave a bad landmark transfer so it looks like this scaling is very important.

Thanks again!  
Eva

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [April 19, 2024, 7:17pm UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/6 "2024-04-19T19:17:59Z")

</div>

I am glad this worked.

However, what is the purpose of running ALPACA in this way? If you are going to use fixed parameters, I think batch mode will be easier. I thought maybe you are trying to do a parameter sweep (i.e., try many samples with different sets of parameters).

---

<div class="post-metadata">

**Author:** ![evaherbst](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/evaherbst/32/65595_2.png) [@evaherbst](https://discourse.slicer.org/u/evaherbst)\
**Post date:** [April 22, 2024, 8:01am UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/7 "2024-04-22T08:01:08Z")

</div>

I want to batch process a lot of scans, and am using Alpaca to transfer landmarks to then fit an ROI to each bone and then analyse it. The steps before and after Alpaca are all run from python so it helps to run everything together in an automated way.

---

<div class="post-metadata">

**Author:** ![evaherbst](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/evaherbst/32/65595_2.png) [@evaherbst](https://discourse.slicer.org/u/evaherbst)\
**Post date:** [October 1, 2024, 4:46pm UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/8 "2024-10-01T16:46:56Z")

</div>

Hello again,

I just tried running this after not using it for a while.

I am testing it with a single source model for now, which previously worked.

I previously specified the specific .ply and the mrk.json files in the code as the source model path and source landmark path, not just the directories (similar to how those individual files can be selected in the MALPACA GUI)

However, doing that now gives me an error that mrk.json file that it should be a directory:

> NotADirectoryError: [WinError 267] The directory name is invalid:\>  
> ‘P:…/source\_landmarks/lm\_2NHJX1.mrk.json’

When I replace the specific files with directories, that prevents the above error about the directory but the results remain empty (medianEstimates and individualEstimates folders are created but empty)

My inputs look like this now (previously the first two were pointing to specific files.  
sourceModelPath = …/source\_scapula\_model"  
sourceLandmarkPath = “…/source\_landmarks”  
targetModelPath = “…/scapula\_model\_output”  
targetLandmarkPath = “…/landmark\_output”

Do you have any recommendations how to fix this issue to enable batch running Alpaca/Malpaca like I did before?

I checked the Alpaca logic on github but didnt see find changes that could explain this new error.

Thank you,  
Eva

---

<div class="post-metadata">

**Author:** ![chz31](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chz31/32/77363_2.png) [@chz31](https://discourse.slicer.org/u/chz31)\
**Post date:** [October 1, 2024, 5:19pm UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/9 "2024-10-01T17:19:18Z")

</div>

I haven’t tried MALPACA from scripting for a while. I think the batch mode in `runLandmarkMultiProcess` should simply iterate through `sourceModelList` from the source directory, then run `pairwiseAlignment` for each source model to generate a predicted lm array for each source, and then use np.median() to output the median:

> <https://github.com/SlicerMorph/SlicerMorph/blob/259a0f496551d0e1c5a6851e4233946d672c1391/ALPACA/ALPACA.py#L1540C1-L1553C26>

Are there any other error printed out? If you have time to add `print(array)` after line 1548, will it print out the landmark array?

---

<div class="post-metadata">

**Author:** ![evaherbst](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/evaherbst/32/65595_2.png) [@evaherbst](https://discourse.slicer.org/u/evaherbst)\
**Post date:** [October 3, 2024, 12:39pm UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/10 "2024-10-03T12:39:37Z")

</div>

Thank you Chi, we will test this.  
I also thought it shouldn’t be a problem to have a single landmark source.  
I didn’t get any errors when specifying the overall folder paths for the source models and source landmarks which is strange.  
The output landmark folders are created but empty.

We will try with the print(array) statement.

Thank you,  
Eva

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [October 3, 2024, 5:58pm UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/11 "2024-10-03T17:58:49Z")

</div>

> [@evaherbst](#):
>
> I also thought it shouldn’t be a problem to have a single landmark source.

MALPACA is for multiple templates (multiple sources). If you have a single source, use ALPACA (single-template option).

If you are using MALPACA logic, then it is normal it is expecting a directory of inputs, as opposed to a single source file.

---

<div class="post-metadata">

**Author:** ![chz31](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chz31/32/77363_2.png) [@chz31](https://discourse.slicer.org/u/chz31)\
**Post date:** [October 3, 2024, 6:37pm UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/12 "2024-10-03T18:37:37Z")

</div>

If you run MALPACA by scripting using multi-template option by putting a single file in the folder, it should simply iterate through that single file in the folder and export the median equivalent to the output that the single template. Hopefully it can be printed out.

When you specify “single template” in the batch mode, it should simply read that particular template file in the folder and run `pairwiseAlignment` and export the predictions of that template: :[SlicerMorph/ALPACA/ALPACA.py at 259a0f496551d0e1c5a6851e4233946d672c1391 · SlicerMorph/SlicerMorph · GitHub](https://github.com/SlicerMorph/SlicerMorph/blob/259a0f496551d0e1c5a6851e4233946d672c1391/ALPACA/ALPACA.py#L1381C1-L1387C14)

Then it will pass that single file to `runLandmarkMultiProcess` to do batch mode for a single template when the boolean function detects the sourceModelPath points to a particular file:

> <https://github.com/SlicerMorph/SlicerMorph/blob/259a0f496551d0e1c5a6851e4233946d672c1391/ALPACA/ALPACA.py#L1556C1-L1568C36>

I’ll also see if I can try it over the weekend. I’m surprised that there’s no output there. If you run batch mode in ALPACA GUI, will it output things normally?

---

<div class="post-metadata">

**Author:** ![evaherbst](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/evaherbst/32/65595_2.png) [@evaherbst](https://discourse.slicer.org/u/evaherbst)\
**Post date:** [October 6, 2024, 8:00am UTC](https://discourse.slicer.org/t/running-alpaca-from-python-console/35538/13 "2024-10-06T08:00:01Z")

</div>

Thank you Murat and Chi!

We want to use MALPACA in the future but were testing with a single template for now, which worked in the past.

I think I might have found the error.

The landmarks and meshes were recreated after my initial tests by another member in my group and had slightly different names from each other. Apologies for my oversight in not catching this.  
This would also explain why alpaca worked in the gui since there was just one template and it wouldn’t need to match in that case.

We will double check it tomorrow.

Thank you,  
Eva
