Any implementation of population fusion models?

50 views
Skip to first unread message

HC Lim

unread,
Feb 21, 2025, 9:41:53 PMFeb 21
to dadi-user
Hi Ryan and the dadi-group,
I just want to check if such models are available or even possible. It would be the opposite of something like "PhiManip.phi_2D_to_3D_split_1". I don't know if such functions have been implemented. I have looked at different papers, including Momogliano et al 2021, but haven't seen any. The reason for wanting a fusion model instead of one with high gene flow between 2 populations is that individuals in the fused populations are no longer separable. But we can tell they were once distinct based on mitochondrial data.

Thanks,
HC

Ryan Gutenkunst

unread,
Feb 23, 2025, 12:41:39 PMFeb 23
to dadi-user
Hello HC,

Yes, you can implement a fusion model in dadi, in two steps. The first step would be to use a method like PhiManip.phi_2D_admix_2_into_1 (https://dadi.readthedocs.io/en/latest/api/dadi/PhiManip.html#dadi.PhiManip.phi_2D_admix_1_into_2) to implement the fusion event. In that function you would specify how much variation from population 2 contributes to the new fusion population. The second step would be to remove population 2, using PhiManip.remove_pop https://dadi.readthedocs.io/en/latest/api/dadi/PhiManip.html#dadi.PhiManip.remove_pop .

There are equivalent admixture functions for different numbers of populations, if your model is more complex.

Best,
Ryan

--
You received this message because you are subscribed to the Google Groups "dadi-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dadi-user+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/dadi-user/f5a7e423-e50f-4c3d-a6a7-27a82e5edd16n%40googlegroups.com.

HC Lim

unread,
Feb 26, 2025, 11:23:09 AMFeb 26
to dadi-user
Thanks Ryan! Not sure how I missed that. We will start to construct the model. With 3 time points (2 splits and 1 admixture) and migrations (not to mention size changes), the model is starting to look complex. We will run what we come up with by you if you don't mind.

Best,
HC

HC Lim

unread,
Mar 13, 2025, 2:57:37 PMMar 13
to dadi-user
Hi Ryan,
I managed to come up with a demographic model to be implemented in dadi and/or gadma  using dadi engine (https://drive.google.com/file/d/1pYNoVE_3AXQAL76qysLuvkhGCFk3kLOu/view?usp=drive_link) based on this scenario. However, when I run an optimization routine (Optimize_Functions.Optimize_Routine) borrowed from dadi_pipeline, the following error popped up. I'm wondering if it has something to do the number of times grid ("xx") is written during one of the splitting or merging events. It was given a 3D sfs, but the eventual outcome is 2D after an admixture event. Any insights will be very much appreciated!
HC

"...gadma_env/lib/python3.10/site-packages/dadi/PhiManip.py", line 197, in check_xx
    raise ValueError('Input xx argument is not monotonically increasing. '
ValueError: Input xx argument is not monotonically increasing. Have you passed in an incorrect argument?"

Ryan Gutenkunst

unread,
Mar 14, 2025, 2:24:18 PMMar 14
to dadi-user
Hello HC,

I don’t have access to the links you provided. But yes, this is almost certainly an error with how you coded the model. You can look at the API docs to see how the functions should be used: https://dadi.readthedocs.io/en/latest/api/dadi/PhiManip.html . Further up the trace it should also show you exactly which function caused the problem.

Best,
Ryan

HC Lim

unread,
Mar 14, 2025, 3:00:29 PMMar 14
to dadi-user

HC Lim

unread,
Mar 19, 2025, 10:49:29 AMMar 19
to dadi-user
Hi Ryan,
I made some progress but still ran into this error message.

raise ValueError('Dimensionality of phi and lengths of ns and xxs '
ValueError: Dimensionality of phi and lengths of ns and xxs do not all agree.

I wonder if it's caused by being given a 3D sfs but is asked to return a 2D sfs because of the admixture event. Any insights is much appreciated!

Below are the relevant codes. Basically, the history is 1 (SB) split from 2+3 (SR+SN), then 2 & 3 split, then 1 & 2 become admixed/fused and 3 continues on its own, leaving 2 final populations. While this is going on, there's symmetrical gene flow between pairs of populations.
HC

def model_func(params, ns, pts):

    # 14 parameters:
    nu_SB, nu_SRSN, nu_SR, nu_SN, nu_SBSR, T1, T2, T3, m_SB_SRSN, m_SB_SR, m_SB_SN, m_SR_SN, m_SBSR_SN, f2 = params


    xx = dadi.Numerics.default_grid(pts)
   

    phi = dadi.PhiManip.phi_1D(xx)

   
    # Phase 2: Split into two populations (SB and SR-SN); initialize 2D phi.
    phi = dadi.PhiManip.phi_1D_to_2D(xx, phi)

    phi = dadi.Integration.two_pops(phi, xx, T1, nu1=nu_SB, nu2=nu_SRSN, m12=m_SB_SRSN, m21=m_SB_SRSN)
   
    # Phase 3: At time T2, split population SRSN into two populations (SR and SN)
  
    phi = dadi.PhiManip.phi_2D_to_3D_split_2(xx, phi)
    
    phi = dadi.Integration.three_pops(phi, xx, T2, nu1=nu_SB, nu2=nu_SR, nu3=nu_SN,
                                       m12=m_SB_SR, m21=m_SB_SR,
                                       m13=m_SB_SN, m31=m_SB_SN,
                                       m23=m_SR_SN, m32=m_SR_SN)
   
    phi = dadi.PhiManip.phi_3D_admix_2_and_3_into_1(phi, f2, 0, xx, xx, xx) #only pop2 admix with 1
    
    # Phase 6: Remove population SR (population 2).
    phi = dadi.PhiManip.remove_pop(phi, xx, 2)
   
    # Phase 7: Integrate for time T3 with two populations (SB+SR and SN) with migration rate m2.
       phi = dadi.Integration.two_pops(phi, xx, T3, nu1=nu_SBSR, nu2=nu_SN, m12=m_SBSR_SN, m21=m_SBSR_SN)
   
    # Finally, generate the frequency spectrum for populations SB and SN.
    fs = dadi.Spectrum.from_phi(phi, ns, (xx, xx))
    return fs

Ryan Gutenkunst

unread,
Mar 19, 2025, 3:47:36 PMMar 19
to dadi-user
Hello HC,

The code you shared runs find on my system, if I call it like:
model_func([0.1]*14, [2,3], 5)
Is it possible you’re inputting a 1- or 3- dimensional ns list?

Best,
Ryan

HC Lim

unread,
Mar 29, 2025, 1:04:06 PMMar 29
to dadi-user
Hi Ryan,
That's correct - giving it a 2D sfs solved the problem (but run didn't converge but that's another issue). I was thinking that it needs to know how to separate the individuals during the 3-population phase. Many thanks for your help. HC
Reply all
Reply to author
Forward
0 new messages