Giving name to populations

5 views
Skip to first unread message

João Pedro Meireles

unread,
Jun 27, 2024, 8:48:22 AM (6 days ago) Jun 27
to slim-discuss
Dear all,

My apologies for such a basic question. I have already run through the manual and I cannot make it work. How can I give a name to my populations Instead of working with p1, p2, p3...? At least name them when they are displayed in graphic or plots. 

thank you very much for your help. 

Cheers
João

Ben Haller

unread,
Jun 27, 2024, 3:45:01 PM (6 days ago) Jun 27
to João Pedro Meireles, slim-discuss
Hi João!

Well, you can do:

subpop.name = "foo";

or

subpop.setValue("name", "foo");

as two different ways to attach a name to a subpop; see the doc for the name property of Subpopulation.  But that won't define a global symbol with your name; there is presently no way to do that, to some extent for technical reasons (it's harder than it might seem).  And it won't change the name displayed in SLiMgui's built-in plots (but that's a nice idea; file a new issue in GitHub if you'd like to see it happen).  (But you could certainly use either of these styles of attached names in the legend of custom SLiMgui plots, since you have control over that in your script.)

To some extent this is a limitation of SLiM right now; but to some extent it is also a design decision, since it improves readability across SLiM models by naming subpops in a predictable and recognizable way.  If somebody could use an arbitrary symbol like "b" to represent a subpop, it would make it much harder to read/review other people's SLiM code.

Cheers,
-B.

Benjamin C. Haller
Messer Lab
Cornell University


João Pedro Meireles wrote on 6/27/24 1:48 PM:
--
SLiM forward genetic simulation: http://messerlab.org/slim/
---
You received this message because you are subscribed to the Google Groups "slim-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to slim-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/slim-discuss/380a0448-cdb3-439c-bfdc-1ca72c984ebcn%40googlegroups.com.

Ben Haller

unread,
Jul 2, 2024, 10:46:06 AM (yesterday) Jul 2
to Eirian Perkins, João Pedro Meireles, slim-discuss
Hi Eirian!

If that code is working for you, then there is a bug.  :->  That should not be allowed; you should get an error like:

ERROR (CheckLongTermBoundary): A long-term reference has been kept to an Eidos object that is not under retain-release memory management.  For example, a SLiM Individual or Subpopulation may have been placed in a global dictionary.  This is illegal; only objects that are under retain-release memory management can be kept long-term.

It isn't safe to do, and SLiM/Eidos should prevent you.  So this technique is not recommended, even if it does work for you, and it may lead to crashes or other problems.  I just tried it and got the expected error.  Off-list, please let me know what version of SLiM is allowing you to do this.  If there is a hole in the protection mechanism, it will get patched; so don't do this.

I realize that people would like to be able to do this sort of thing.  It is difficult to allow, for technical reasons under the hood.  I'm working towards redesigning things to make it possible, but it is a long road.


Cheers,
-B.

Benjamin C. Haller
Messer Lab
Cornell University


Eirian Perkins wrote on 7/2/24 10:35 AM:

Hiya Ben and João,

 

If you don’t mind me saying so, I was also quite keen to give my subpopulations names besides p1, p2, etc. My workaround was to define a global Dictionary object mapping the pN SLiM names to names of my choice:

 

defineGlobal("SLIM2POPNAMES", Dictionary());

defineGlobal("POP2SLIMNAMES", Dictionary());

 

I can set values like this

 

SLIM2POPNAMES.setValue("p0", "Te Hauturu-o-Toi");

POP2SLIMNAMES.setValue("Te Hauturu-o-Toi", "p0");

 

Then I can do things like

 

function (object)getSubpopByName(string$ name) {

    for (pop in sim.subpopulations) {

        if (pop.name == name) {

            return pop;

        }

    }

    return NULL;

}

 

function (object)getSubpopByMeaningfulName(string$ name) {

    result = getSubpopByName(POP2SLIMNAMES.getValue(name));

    if (isNULL(result)) {

        // if there is no name set, return the SLiM pNum name

        return name;

    }

    return result;

}

 

This is useful in particular if I have other functions that have actions depending on which population is sent to it

 

function (void)applyCarryingCapacity(string$ name) {

    subpop = getSubpopByName(name);

    meaningfulName = SLIM2POPNAMES.getValue(name);

    K = CARRYINGCAPACITY.getValue(meaningfulName);

    //catn("setting K for " + name + " to " + K);

    subpop.fitnessScaling = K / subpop.individualCount;

}

 

Hope this helps!

Eirian

 

Ben Haller

unread,
Jul 2, 2024, 11:53:13 AM (yesterday) Jul 2
to Eirian Perkins, João Pedro Meireles, slim-discuss
Oh, wait, I see – you're not putting the subpopulations themselves into your Dictionary, just their names.  Yes, that solution ought to work as a stopgap, sure.  :->


Cheers,
-B.

Benjamin C. Haller
Messer Lab
Cornell University


'Ben Haller' via slim-discuss wrote on 7/2/24 3:45 PM:
Reply all
Reply to author
Forward
0 new messages