diff --git a/PySONIC/core/bls_lookups.json b/PySONIC/core/bls_lookups.json index 0534ed4..126efeb 100644 --- a/PySONIC/core/bls_lookups.json +++ b/PySONIC/core/bls_lookups.json @@ -1,816 +1,959 @@ { "32.0": { "-80.00": { "LJ_approx": { "x0": 1.7875580514692446e-09, "C": 14506.791031634148, "nrep": 3.911252335063797, "nattr": 0.9495868868453603 }, "Delta_eq": 1.2344323203763867e-09 }, "-71.40": { "LJ_approx": { "x0": 1.710159362626304e-09, "C": 16757.44053535206, "nrep": 3.9149844779001572, "nattr": 0.9876139143736086 }, "Delta_eq": 1.2566584760815426e-09 }, "-54.00": { "LJ_approx": { "x0": 1.588820457014353e-09, "C": 21124.28839722447, "nrep": 3.9219530533405726, "nattr": 1.0531179666960837 }, "Delta_eq": 1.302942739961778e-09 }, "-71.90": { "LJ_approx": { "x0": 1.7142977983903395e-09, "C": 16627.43538695451, "nrep": 3.9147721975981384, "nattr": 0.9855168537576823 }, "Delta_eq": 1.2553492695740507e-09 }, "-89.50": { "LJ_approx": { "x0": 1.8913883171160228e-09, "C": 12016.525797229067, "nrep": 3.9069373029335464, "nattr": 0.9021994595277029 }, "Delta_eq": 1.2107230911508513e-09 }, "-61.93": { "LJ_approx": { "x0": 1.6390264131559902e-09, "C": 19180.97634755811, "nrep": 3.9188840789597705, "nattr": 1.0250251620607604 }, "Delta_eq": 1.281743450351987e-09 }, "-53.00": { "LJ_approx": { "x0": 1.5830321174402216e-09, "C": 21361.655211483354, "nrep": 3.9223254792281588, "nattr": 1.0564645995714745 }, "Delta_eq": 1.305609024046854e-09 }, "-53.58": { "LJ_approx": { "x0": 1.5863754403940291e-09, "C": 21224.206759769622, "nrep": 3.922109852077156, "nattr": 1.0545313303221624 }, "Delta_eq": 1.3040630712174578e-09 }, "-48.87": { "LJ_approx": { "x0": 1.5603070731170595e-09, "C": 22321.280954434333, "nrep": 3.9238276518118833, "nattr": 1.0698008224359472 }, "Delta_eq": 1.3165739825437056e-09 }, "0.00": { "LJ_approx": { "x0": 1.429523524073023e-09, "C": 28748.036227122713, "nrep": 3.9338919786768276, "nattr": 1.1551044201542804 }, "Delta_eq": 1.4e-09 }, "-70.00": { "LJ_approx": { "x0": 1.698788510560293e-09, "C": 17120.631318195712, "nrep": 3.915575488491436, "nattr": 0.9934238714780391 }, "Delta_eq": 1.2603339470322538e-09 }, "-58.00": { "LJ_approx": { "x0": 1.6131662659976035e-09, "C": 20156.47605325608, "nrep": 3.9204295233162925, "nattr": 1.0393049952285334 }, "Delta_eq": 1.2922508866011204e-09 }, "-140.00": { "LJ_approx": { "x0": 3.5396589580589484e-09, "C": 1255.8321160636908, "nrep": 3.879907809497444, "nattr": 0.4190657482583384 }, "Delta_eq": 1.1019265101358682e-09 }, "-200.00": { "LJ_approx": { "x0": 5.467498689940948e-09, "C": 298.4575230665454, "nrep": 3.8382806376855165, "nattr": 0.0014805372073950717 }, "Delta_eq": 1.0050623818936587e-09 }, "-60.00": { "LJ_approx": { "x0": 1.6260780786690872e-09, "C": 19662.79538138057, "nrep": 3.9196487714944097, "nattr": 1.0321270951610706 }, "Delta_eq": 1.2869009570089227e-09 } }, "64.0": { "-80.00": { "LJ_approx": { "x0": 1.783357531675752e-09, "C": 14639.319598806138, "nrep": 3.9113027551187414, "nattr": 0.9404151935643594 }, "Delta_eq": 1.2344323203763867e-09 }, "-71.90": { "LJ_approx": { "x0": 1.7103254451796522e-09, "C": 16775.90747591089, "nrep": 3.9148582072320104, "nattr": 0.9747613204242506 }, "Delta_eq": 1.2553492695740507e-09 }, "-71.40": { "LJ_approx": { "x0": 1.7061996856525807e-09, "C": 16906.878806702443, "nrep": 3.9150725853841957, "nattr": 0.976778398349503 }, "Delta_eq": 1.2566584760815426e-09 }, "-54.00": { "LJ_approx": { "x0": 1.585264156646392e-09, "C": 21303.176047683613, "nrep": 3.92211004079812, "nattr": 1.0402641595550777 }, "Delta_eq": 1.302942739961778e-09 }, "-89.50": { "LJ_approx": { "x0": 1.886870747500225e-09, "C": 12129.260307725155, "nrep": 3.906945602966425, "nattr": 0.895598309376088 }, "Delta_eq": 1.2107230911508513e-09 }, "-61.93": { "LJ_approx": { "x0": 1.635297932833928e-09, "C": 19347.359224637305, "nrep": 3.9190113341505843, "nattr": 1.0129039638328117 }, "Delta_eq": 1.281743450351987e-09 }, "-58.00": { "LJ_approx": { "x0": 1.6095250707781465e-09, "C": 20329.27848623273, "nrep": 3.92057191136993, "nattr": 1.0267862446034561 }, "Delta_eq": 1.2922508866011204e-09 }, "-140.00": { "LJ_approx": { "x0": 3.5398097121754107e-09, "C": 1255.8690004347025, "nrep": 3.8798490490747404, "nattr": 0.4604604439108636 }, "Delta_eq": 1.1019265101358682e-09 }, "-200.00": { "LJ_approx": { "x0": 6.6005456899992844e-09, "C": 144.85407475420143, "nrep": 3.838295127819493, "nattr": 0.00992375961984237 }, "Delta_eq": 1.0050623818936587e-09 }, "-60.00": { "LJ_approx": { "x0": 1.6223930024686038e-09, "C": 19832.380892638503, "nrep": 3.9197835635468294, "nattr": 1.019801114668753 }, "Delta_eq": 1.2869009570089227e-09 } }, "50.0": { "-71.90": { "LJ_approx": { "x0": 1.7114794411958874e-09, "C": 16732.841575829825, "nrep": 3.914827883392826, "nattr": 0.9781401389550711 }, "Delta_eq": 1.2553492695740507e-09 } }, "10.0": { "0.00": { "LJ_approx": { "x0": 1.4403460578039628e-09, "C": 27932.27792195569, "nrep": 3.9334138654752686, "nattr": 1.19526523864855 }, "Delta_eq": 1.4e-09 }, "-71.90": { "LJ_approx": { "x0": 1.7286986021591825e-09, "C": 16087.514816365254, "nrep": 3.9147885683678543, "nattr": 1.012616990226475 }, "Delta_eq": 1.2553492695740507e-09 } }, "100.0": { "0.00": { "LJ_approx": { "x0": 1.4254455131143225e-09, "C": 29048.417918044444, "nrep": 3.9342659189249254, "nattr": 1.1351227816904121 }, "Delta_eq": 1.4e-09 }, "-71.90": { "LJ_approx": { "x0": 1.7087681652667724e-09, "C": 16833.83962398515, "nrep": 3.914908533680663, "nattr": 0.9697102045586926 }, "Delta_eq": 1.2553492695740507e-09 }, "-71.40": { "LJ_approx": { "x0": 1.7046480280451768e-09, "C": 16965.15489682674, "nrep": 3.9151238997284845, "nattr": 0.9716928395857687 }, "Delta_eq": 1.2566584760815426e-09 }, "-54.00": { "LJ_approx": { "x0": 1.5838767580748841e-09, "C": 21372.412565003375, "nrep": 3.922191259312523, "nattr": 1.0344167918733638 }, "Delta_eq": 1.302942739961778e-09 }, "-89.50": { "LJ_approx": { "x0": 1.8850831984948754e-09, "C": 12173.857567383837, "nrep": 3.906959887367545, "nattr": 0.8923154523792497 }, "Delta_eq": 1.2107230911508513e-09 }, "-61.93": { "LJ_approx": { "x0": 1.6338405482612552e-09, "C": 19411.96069791924, "nrep": 3.9190798895919405, "nattr": 1.0073171165886772 }, "Delta_eq": 1.281743450351987e-09 } }, "500.0": { "0.00": { "LJ_approx": { "x0": 1.4236928207491738e-09, "C": 29174.423851140436, "nrep": 3.934489087598531, "nattr": 1.1244706663694597 }, "Delta_eq": 1.4e-09 } }, "15.0": { "-71.90": { "LJ_approx": { "x0": 1.722207527516432e-09, "C": 16331.124295102756, "nrep": 3.914721476976037, "nattr": 1.0021304453280393 }, "Delta_eq": 1.2553492695740507e-09 }, "-71.40": { "LJ_approx": { "x0": 1.7180439454408102e-09, "C": 16459.15520614834, "nrep": 3.9149304238974905, "nattr": 1.0043742068193204 }, "Delta_eq": 1.2566584760815426e-09 }, "-54.00": { "LJ_approx": { "x0": 1.5959361190370466e-09, "C": 20763.823187183425, "nrep": 3.921785737782814, "nattr": 1.0737976563473925 }, "Delta_eq": 1.302942739961778e-09 }, "-89.50": { "LJ_approx": { "x0": 1.9002701433896942e-09, "C": 11795.576706463997, "nrep": 3.9070059150621814, "nattr": 0.9114123498082551 }, "Delta_eq": 1.2107230911508513e-09 }, "-61.93": { "LJ_approx": { "x0": 1.646473044478369e-09, "C": 18846.9803104403, "nrep": 3.918766624746869, "nattr": 1.044220870098494 }, "Delta_eq": 1.281743450351987e-09 } }, "70.0": { "-61.93": { "LJ_approx": { "x0": 1.6349587829329923e-09, "C": 19362.426097728276, "nrep": 3.9190260877993097, "nattr": 1.0116609492531905 }, "Delta_eq": 1.281743450351987e-09 }, "-71.90": { "LJ_approx": { "x0": 1.7099628637265945e-09, "C": 16789.420291577666, "nrep": 3.9148688185890483, "nattr": 0.9736446481917082 }, "Delta_eq": 1.2553492695740507e-09 }, "-71.40": { "LJ_approx": { "x0": 1.7058388214243274e-09, "C": 16920.455606556396, "nrep": 3.9150834388621805, "nattr": 0.9756530742858303 }, "Delta_eq": 1.2566584760815426e-09 }, "-54.00": { "LJ_approx": { "x0": 1.584940743805642e-09, "C": 21319.35643207058, "nrep": 3.9221277053335264, "nattr": 1.0389567310289958 }, "Delta_eq": 1.302942739961778e-09 }, "-89.50": { "LJ_approx": { "x0": 1.886457143504779e-09, "C": 12139.584658299475, "nrep": 3.9069481854501382, "nattr": 0.8948872453823127 }, "Delta_eq": 1.2107230911508513e-09 } }, "150.0": { "-71.90": { "LJ_approx": { "x0": 1.707781542586275e-09, "C": 16870.340248462282, "nrep": 3.914948339378328, "nattr": 0.9660711186661354 }, "Delta_eq": 1.2553492695740507e-09 }, "-71.40": { "LJ_approx": { "x0": 1.7036651779798684e-09, "C": 17001.86272239105, "nrep": 3.9151643485118117, "nattr": 0.9680342060844059 }, "Delta_eq": 1.2566584760815426e-09 }, "-54.00": { "LJ_approx": { "x0": 1.5830041112065094e-09, "C": 21415.64649760579, "nrep": 3.9222512220871013, "nattr": 1.0303387653647968 }, "Delta_eq": 1.302942739961778e-09 }, "-89.50": { "LJ_approx": { "x0": 1.883936689519767e-09, "C": 12202.390459945682, "nrep": 3.906974649816042, "nattr": 0.8898102498996743 }, "Delta_eq": 1.2107230911508513e-09 }, "-61.93": { "LJ_approx": { "x0": 1.6329212539031057e-09, "C": 19452.44141782297, "nrep": 3.9191317215599946, "nattr": 1.0033715654432673 }, "Delta_eq": 1.281743450351987e-09 } }, "16.0": { "-71.90": { "LJ_approx": { "x0": 1.721337196662225e-09, "C": 16363.738563915058, "nrep": 3.9147202446411637, "nattr": 1.0005179992350384 }, "Delta_eq": 1.2553492695740507e-09 }, "-71.40": { "LJ_approx": { "x0": 1.717176984027311e-09, "C": 16491.97282711717, "nrep": 3.9149293522242252, "nattr": 1.0027563589061772 }, "Delta_eq": 1.2566584760815426e-09 }, "-54.00": { "LJ_approx": { "x0": 1.5951507107307484e-09, "C": 20803.713978702526, "nrep": 3.921796023871708, "nattr": 1.0717457519944718 }, "Delta_eq": 1.302942739961778e-09 }, "-89.50": { "LJ_approx": { "x0": 1.899300769652515e-09, "C": 11819.650350288994, "nrep": 3.906993085458305, "nattr": 0.9105930969008011 }, "Delta_eq": 1.2107230911508513e-09 }, "-61.93": { "LJ_approx": { "x0": 1.6456524054221337e-09, "C": 18883.851022856303, "nrep": 3.918771854603072, "nattr": 1.042336408142498 }, "Delta_eq": 1.281743450351987e-09 }, "-58.00": { "LJ_approx": { "x0": 1.6196423302303851e-09, "C": 19847.346684716063, "nrep": 3.920294617611314, "nattr": 1.0573210567487794 }, "Delta_eq": 1.2922508866011204e-09 }, "-140.00": { "LJ_approx": { "x0": 3.536300349187651e-09, "C": 1259.968827699725, "nrep": 3.8800144975132485, "nattr": 0.35722933384459793 }, "Delta_eq": 1.1019265101358682e-09 }, "-200.00": { "LJ_approx": { "x0": 4.448077576688761e-09, "C": 658.9502615105886, "nrep": 3.8382596040618573, "nattr": -0.0007412836249291593 }, "Delta_eq": 1.0050623818936587e-09 }, "-60.00": { "LJ_approx": { "x0": 1.6326306076113028e-09, "C": 19359.641562109642, "nrep": 3.9195252093199606, "nattr": 1.0498037816897123 }, "Delta_eq": 1.2869009570089227e-09 } }, "40.0": { "-71.90": { "LJ_approx": { "x0": 1.7127556130633909e-09, "C": 16685.139617894773, "nrep": 3.9147997833590855, "nattr": 0.9816110605284186 }, "Delta_eq": 1.2553492695740507e-09 }, "-140.00": { "LJ_approx": { "x0": 3.5400899114625196e-09, "C": 1255.3328685760946, "nrep": 3.8798858604365565, "nattr": 0.4340973480775988 }, "Delta_eq": 1.1019265101358682e-09 } }, "30.0": { "-71.90": { "LJ_approx": { "x0": 1.7147994934556977e-09, "C": 16608.65261608246, "nrep": 3.914764637335829, "nattr": 0.9867268079339511 }, "Delta_eq": 1.2553492695740507e-09 } }, "25.4": { "-71.90": { "LJ_approx": { "x0": 1.7162265501918752e-09, "C": 16555.217050637588, "nrep": 3.9147464050871856, "nattr": 0.9900398844251959 }, "Delta_eq": 1.2553492695740507e-09 }, "-61.93": { "LJ_approx": { "x0": 1.6408385667642563e-09, "C": 19099.831853142834, "nrep": 3.9188405082474103, "nattr": 1.0301853851264013 }, "Delta_eq": 1.281743450351987e-09 } }, "40.3": { "-71.90": { "LJ_approx": { "x0": 1.7127058661258177e-09, "C": 16686.9995037205, "nrep": 3.914800799246736, "nattr": 0.981479342025535 }, "Delta_eq": 1.2553492695740507e-09 }, "-61.93": { "LJ_approx": { "x0": 1.637531858311385e-09, "C": 19247.790954282773, "nrep": 3.918928365198691, "nattr": 1.020450016688262 }, "Delta_eq": 1.281743450351987e-09 } }, "45.0": { "-71.90": { "LJ_approx": { "x0": 1.712051746586677e-09, "C": 16711.456749369456, "nrep": 3.914814642254888, "nattr": 0.979726839958776 }, "Delta_eq": 1.2553492695740507e-09 } }, "20.0": { "-71.90": { "LJ_approx": { "x0": 1.7186388439609698e-09, "C": 16464.85454836168, "nrep": 3.9147266088229755, "nattr": 0.9952322612710219 }, "Delta_eq": 1.2553492695740507e-09 }, "-140.00": { "LJ_approx": { "x0": 3.5381843063817075e-09, "C": 1257.5756585425543, "nrep": 3.8799713679048966, "nattr": 0.38013951841061877 }, "Delta_eq": 1.1019265101358682e-09 } }, "60.0": { "-71.90": { "LJ_approx": { "x0": 1.710603828012074e-09, "C": 16765.5278159216, "nrep": 3.9148503824940146, "nattr": 0.9756024890579372 }, "Delta_eq": 1.2553492695740507e-09 } }, "34.0": { "-71.90": { "LJ_approx": { "x0": 1.7138494069983225e-09, "C": 16644.21766668786, "nrep": 3.9147795488410644, "nattr": 0.9844103642751335 }, "Delta_eq": 1.2553492695740507e-09 } }, "22.6": { "-71.90": { "LJ_approx": { "x0": 1.717347083819261e-09, "C": 16513.244775760173, "nrep": 3.914735582752492, "nattr": 0.9925083846044295 }, "Delta_eq": 1.2553492695740507e-09 }, "-54.00": { "LJ_approx": { "x0": 1.5915583742563881e-09, "C": 20985.87279990122, "nrep": 3.9218681449692334, "nattr": 1.06169568520175 }, "Delta_eq": 1.302942739961778e-09 } }, "45.3": { "-71.90": { "LJ_approx": { "x0": 1.7120143529753677e-09, "C": 16712.8535932463, "nrep": 3.9148154954695285, "nattr": 0.9796234512533043 }, "Delta_eq": 1.2553492695740507e-09 } }, "31.0": { "0.00": { "LJ_approx": { "x0": 1.429704934686545e-09, "C": 28734.55271989346, "nrep": 3.9338783401809607, "nattr": 1.155904475115303 }, "Delta_eq": 1.4e-09 }, "-71.90": { "LJ_approx": { "x0": 1.714533452342314e-09, "C": 16618.61152256, "nrep": 3.9147686086169227, "nattr": 0.9860860917336786 }, "Delta_eq": 1.2553492695740507e-09 } }, "31.1": { "-71.90": { "LJ_approx": { "x0": 1.714515996985078e-09, "C": 16619.26565583038, "nrep": 3.914768856863524, "nattr": 0.986044873313721 }, "Delta_eq": 1.2553492695740507e-09 } }, "45.2": { "-71.90": { "LJ_approx": { "x0": 1.7120203335936594e-09, "C": 16712.630620283762, "nrep": 3.914815347514677, "nattr": 0.9796407085930723 }, "Delta_eq": 1.2553492695740507e-09 } }, "28.0": { "-140.00": { "LJ_approx": { "x0": 3.539662733628618e-09, "C": 1255.7594429416959, "nrep": 3.8799232005747073, "nattr": 0.4091144934965918 }, "Delta_eq": 1.1019265101358682e-09 } }, "52.0": { "-140.00": { "LJ_approx": { "x0": 3.540099825001411e-09, "C": 1255.4092689381769, "nrep": 3.8798640679267495, "nattr": 0.44958440372614994 }, "Delta_eq": 1.1019265101358682e-09 } }, "48.0": { "-140.00": { "LJ_approx": { "x0": 3.540113162797765e-09, "C": 1255.365483546012, "nrep": 3.8798702909870157, "nattr": 0.4451084636623491 }, "Delta_eq": 1.1019265101358682e-09 } }, "25.0": { "-140.00": { "LJ_approx": { "x0": 3.5394591974100957e-09, "C": 1255.9739311868518, "nrep": 3.8799379083844014, "nattr": 0.3998616563003167 }, "Delta_eq": 1.1019265101358682e-09 } }, "24.0": { "-140.00": { "LJ_approx": { "x0": 3.539294542800419e-09, "C": 1256.1755733964683, "nrep": 3.8799434079572483, "nattr": 0.3965246264708772 }, "Delta_eq": 1.1019265101358682e-09 } }, "26.0": { "-71.90": { "LJ_approx": { "x0": 1.716013742853656e-09, "C": 16563.186031095847, "nrep": 3.914748825378261, "nattr": 0.9895571841402089 }, "Delta_eq": 1.2553492695740507e-09 } + }, + "47.8": { + "-71.90": { + "LJ_approx": { + "x0": 1.7117134574481139e-09, + "C": 16724.09882321637, + "nrep": 3.914822340960349, + "nattr": 0.9787950821308133 + }, + "Delta_eq": 1.2553492695740507e-09 + } + }, + "45.9": { + "-71.90": { + "LJ_approx": { + "x0": 1.711942249735064e-09, + "C": 16715.54886943138, + "nrep": 3.9148171027544123, + "nattr": 0.9794265342377567 + }, + "Delta_eq": 1.2553492695740507e-09 + } + }, + "30.3": { + "-71.90": { + "LJ_approx": { + "x0": 1.7147276912050609e-09, + "C": 16611.3405217478, + "nrep": 3.9147656933151262, + "nattr": 0.9865543051062363 + }, + "Delta_eq": 1.2553492695740507e-09 + } + }, + "43.4": { + "-71.90": { + "LJ_approx": { + "x0": 1.7122593582582404e-09, + "C": 16703.696731600092, + "nrep": 3.914810082243474, + "nattr": 0.9802910111364295 + }, + "Delta_eq": 1.2553492695740507e-09 + } + }, + "59.7": { + "-71.90": { + "LJ_approx": { + "x0": 1.710624810423359e-09, + "C": 16764.744721099407, + "nrep": 3.914849818351629, + "nattr": 0.9756645210872293 + }, + "Delta_eq": 1.2553492695740507e-09 + } + }, + "31.6": { + "-71.90": { + "LJ_approx": { + "x0": 1.7144029387800298e-09, + "C": 16623.497279426527, + "nrep": 3.914770610799719, + "nattr": 0.9857697612214258 + }, + "Delta_eq": 1.2553492695740507e-09 + } + }, + "36.3": { + "-71.90": { + "LJ_approx": { + "x0": 1.7133999698436411e-09, + "C": 16661.0351629387, + "nrep": 3.9147874692503435, + "nattr": 0.9832772435848539 + }, + "Delta_eq": 1.2553492695740507e-09 + } + }, + "55.7": { + "-71.90": { + "LJ_approx": { + "x0": 1.710943143434582e-09, + "C": 16752.866849028967, + "nrep": 3.914841318636611, + "nattr": 0.9766031714646571 + }, + "Delta_eq": 1.2553492695740507e-09 + } + }, + "48.5": { + "-71.90": { + "LJ_approx": { + "x0": 1.7116397026523852e-09, + "C": 16726.853954116246, + "nrep": 3.9148240832062964, + "nattr": 0.9785886152529253 + }, + "Delta_eq": 1.2553492695740507e-09 + } + }, + "42.2": { + "-71.90": { + "LJ_approx": { + "x0": 1.712423436257706e-09, + "C": 16697.560003586437, + "nrep": 3.9148066437354734, + "nattr": 0.980728415714794 + }, + "Delta_eq": 1.2553492695740507e-09 + } + }, + "27.9": { + "-71.90": { + "LJ_approx": { + "x0": 1.7154107379662085e-09, + "C": 16585.76539172651, + "nrep": 3.914756263081378, + "nattr": 0.9881670164800336 + }, + "Delta_eq": 1.2553492695740507e-09 + } + }, + "36.8": { + "-71.90": { + "LJ_approx": { + "x0": 1.7133062675842822e-09, + "C": 16664.541652779935, + "nrep": 3.9147891722285952, + "nattr": 0.9830389492355903 + }, + "Delta_eq": 1.2553492695740507e-09 + } + }, + "24.3": { + "-71.90": { + "LJ_approx": { + "x0": 1.7166571039691342e-09, + "C": 16539.090593408535, + "nrep": 3.91474189560473, + "nattr": 0.9910014451873015 + }, + "Delta_eq": 1.2553492695740507e-09 + } } } \ No newline at end of file diff --git a/README.md b/README.md index bc5ebe0..4df17c7 100644 --- a/README.md +++ b/README.md @@ -1,211 +1,213 @@ # Description `PySONIC` is a Python implementation of the **multi-Scale Optimized Neuronal Intramembrane Cavitation (SONIC) model [1]**, a computationally efficient and interpretable model of neuronal intramembrane cavitation. It allows to simulate the responses of various neuron types to ultrasonic (and electrical) stimuli. ## Content of repository ### Models The package contains four model classes: - `Model` defines the generic interface of a model, including mandatory attributes and methods for simulating it. - `BilayerSonophore` defines the underlying **biomechanical model of intramembrane cavitation**. - `PointNeuron` defines an abstract generic interface to **conductance-based point-neuron electrical models**. It is inherited by classes defining the different neuron types with specific membrane dynamics. - `NeuronalBilayerSonophore` defines the **full electromechanical model for any given neuron type**. To do so, it inherits from `BilayerSonophore` and receives a specific `PointNeuron` object at initialization. All model classes contain a `simulate` method to simulate the underlying model's behavior for a given set of stimulation and physiological parameters. The `NeuronalBilayerSonophore.simulate` method contains an additional `method` argument defining whether to perform a detailed (`full`), coarse-grained (`sonic`) or hybrid (`hybrid`) integration of the differential system. ### Simulators Numerical integration routines are implemented outside the models, in separate `Simulator` classes: - `PeriodicSimulator` integrates a differential system periodically until a stable periodic behavior is detected. - `PWSimulator` integrates a differential system given a specific temporal stimulation pattern (pulse repetition frequency, stimulus duty cycle and post-stimulus offset), using different derivative functions for "ON" (with stimulus) and "OFF" (without stimulus) periods - `HybridSimulator` inherits from both `PeriodicSimulator`and `PWSimulator`. It integrates a differential system using a hybrid scheme inside each "ON" or "OFF" period: 1. The full ODE system is integrated for a few cycles with a dense time granularity until a periodic stabilization detection 2. The profiles of all variables over the last cycle are resampled to a far lower (i.e. sparse) sampling rate 3. A subset of the ODE system is integrated with a sparse time granularity, while the remaining variables are periodically expanded from their last cycle profile, until the end of the period or that of an predefined update interval. 4. The process is repeated from step 1 ### Neurons Several conductance-based point-neuron models are implemented that inherit from the `PointNeuron` generic interface: - `CorticalRS`: cortical regular spiking (`RS`) neuron - `CorticalFS`: cortical fast spiking (`FS`) neuron - `CorticalLTS`: cortical low-threshold spiking (`LTS`) neuron - `CorticalIB`: cortical intrinsically bursting (`IB`) neuron - `ThalamicRE`: thalamic reticular (`RE`) neuron - `ThalamoCortical`: thalamo-cortical (`TC`) neuron - `OstukaSTN`: subthalamic nucleus (`STN`) neuron - `FrankenhaeuserHuxley`: Xenopus myelinated fiber node (`FH`) ### Other modules - `batches`: a generic interface to run simulation batches with or without multiprocessing - `parsers`: command line parsing utilities - `plt`: graphing utilities - `postpro`: post-processing utilities (mostly signal features detection) - `constants`: algorithmic constants used across modules and classes - `utils`: generic utilities # Requirements - Python 3.6+ - Package dependencies (numpy, scipy, ...) are installed automatically upon installation of the package. # Installation - Open a terminal. +- Install [git-lfs](https://github.com/git-lfs/git-lfs/wiki/Installation) if not already done + - Activate a Python3 environment if needed, e.g. on the tnesrv5 machine: ```source /opt/apps/anaconda3/bin activate``` - Check that the appropriate version of pip is activated: ```pip --version``` - Clone the repository and install the python package: ```git clone https://c4science.ch/diffusion/4670/pysonic.git``` ```cd pysonic``` ```pip install -e .``` # Usage ## Python scripts You can easily run simulations of any implemented point-neuron model under both electrical and ultrasonic stimuli, and visualize the simulation results, in just a few lines of code: ```python import logging import matplotlib.pyplot as plt from PySONIC.core import PulsedProtocol, NeuronalBilayerSonophore, ElectricDrive, AcousticDrive from PySONIC.neurons import getPointNeuron from PySONIC.utils import logger from PySONIC.plt import GroupedTimeSeries logger.setLevel(logging.INFO) # Point-neuron model and corresponding neuronal bilayer sonophore model pneuron = getPointNeuron('RS') a = 32e-9 # sonophore radius (m) nbls = NeuronalBilayerSonophore(a, pneuron) # Electric and ultrasonic drives ELdrive = ElectricDrive(10.) # mA/m2 USdrive = AcousticDrive( 500e3, # Hz 100e3) # Pa # Pulsing protocol tstim = 250e-3 # s toffset = 50e-3 # s PRF = 100. # Hz DC = 0.5 # - pp = PulsedProtocol(tstim, toffset, PRF, DC) # Run simulation upon electrical stimulation, and plot results data, meta = pneuron.simulate(ELdrive, pp) fig1 = GroupedTimeSeries([(data, meta)]).render() # Run simulation upon ultrasonic stimulation, and plot results data, meta = nbls.simulate(USdrive, pp) fig2 = GroupedTimeSeries([(data, meta)]).render() plt.show() ``` ## From the command line ### Running simulations and batches You can easily run simulations of all 3 model types using the dedicated command line scripts. To do so, open a terminal in the `scripts` directory. - Use `run_mech.py` for simulations of the **mechanical model** upon **ultrasonic stimulation**. For instance, for a 32 nm radius bilayer sonophore sonicated at 500 kHz and 100 kPa: ```python run_mech.py -a 32 -f 500 -A 100 -p Z``` - Use `run_estim.py` for simulations of **point-neuron models** upon **intracellular electrical stimulation**. For instance, a regular-spiking (RS) neuron injected with 10 mA/m2 intracellular current for 30 ms: ```python run_estim.py -n RS -A 10 --tstim 30 -p Vm``` - Use `run_astim.py` for simulations of **point-neuron models** upon **ultrasonic stimulation**. For instance, for a coarse-grained simulation of a 32 nm radius bilayer sonophore within a regular-spiking (RS) neuron membrane, sonicated at 500 kHz and 100 kPa for 150 ms: ```python run_astim.py -n RS -a 32 -f 500 -A 100 --tstim 150 --method sonic -p Qm``` Additionally, you can run batches of simulations by specifying more than one value for any given stimulation parameter (e.g. `-A 100 200` for sonication with 100 and 200 kPa respectively). These batches can be parallelized using multiprocessing to optimize performance, with the extra argument `--mpi`. ### Saving and visualizing results By default, simulation results are neither shown, nor saved. To view results directly upon simulation completion, you can use the `-p [xxx]` option, where `[xxx]` can be `all` (to plot all resulting variables) or a given variable name (e.g. `Z` for membrane deflection, `Vm` for membrane potential, `Qm` for membrane charge density). To save simulation results in binary `.pkl` files, you can use the `-s` option. You will be prompted to choose an output directory, unless you also specify it with the `-o ` option. Output files are automatically named from model and simulation parameters to avoid ambiguity. When running simulation batches, it is highly advised to specify the `-s` option in order to save results of each simulation. You can then visualize results at a later stage. To visualize results, use the `plot_timeseries.py` script. You will be prompted to select the output files containing the simulation(s) results. By default, separate figures will be created for each simulation, showing the time profiles of all resulting variables. Here again, you can choose to show only a subset of variables using the `-p [xxx]` option. Moreover, if you select a subset of variables, you can visualize resulting profiles across simulations in comparative figures wih the `--compare` option. Several more options are available. To view them, type in: ```python -h``` # Extend the package ## Add other neuron types You can easily add other neuron types into the package, providing their ion channel populations and underlying voltage-gated dynamics equations are known. To add a new point-neuron model, follow this procedure: 1. Create a new file, and save it in the `neurons` sub-folder, with an explicit name (e.g. `my_neuron.py`). 2. Copy-paste the content of the `template.py` file (also located in the `neurons` sub-folder) into your file. 3. In your file, change the **class name** from `TemplateNeuron` to something more explicit (e.g. `MyNeuron`), and change the **neuron name** accordingly (e.g. `myneuron`). This name is a keyword used to refer to the model from outside the class. 4. Modify/add **biophysical parameters** of your model (resting parameters, reversal potentials, channel conductances, ionic concentrations, temperatures, diffusion constants, etc...) as class attributes. If some parameters are not fixed and must be computed, assign them to the class inside a `__new__` method, taking the class (`cls`) as sole attribute. 5. Specify a **dictionary of names:descriptions of your different differential states** (i.e. all the differential variables of your model, except for the membrane potential). 6. Modify/add **gating states kinetics** (`alphax` and `betax` methods) that define the voltage-dependent activation and inactivation rates of the different ion channnels gates of your model. Those methods take the membrane potential `Vm` as input and return a rate in `s-1`. Alternatively, your can use steady-state open-probabilties (`xinf`) and adaptation time constants (`taux`) methods. 7. Modify the `derStates` method that defines the **derivatives of your different state variables**. These derivatives are defined inside a dictionary, where each state key is paired to a lambda function that takes the membrane potential `Vm` and a states vector `x` as inputs, and returns the associated state derivative (in `/s`). 8. Modify the `steadyStates` method that defines the **steady-state values of your different state variables**. These steady-states are defined inside a dictionary, where each state key is paired to a lambda function that takes the membrane potential `Vm` as only input, and returns the associated steady-state value (in ``). If some steady-states depend on the values of other-steady states, you can proceed as follows: - define all independent steady-states functions in a dictionary called `lambda_dict` - add dependent steady-state functions to the dictionary, calling `lambda_dict[k](Vm)` for each state `k` whose value is required. 9. Modify/add **membrane currents** (`iXX` methods) of your model. Those methods take relevant gating states and the membrane potential `Vm` as inputs, and must return a current density in `mA/m2`. **You also need to modify the docstring accordingly, as this information is used by the package**. 10. Modify the `currents` method that defines the **membrane currents of your model**. These currents are defined inside a dictionary, where each current key is paired to a lambda function that takes the membrane potential `Vm` and a states vector `x` as inputs, and returns the associated current (in `mA/m2`). **The `derStates`, `steadyStates` and `currents` methods are automatically parsed by the package to adapt neuron models to US stimulation. Hence, make sure to**: - **keep them as class methods** - **check that all calls to functions that depend solely on `Vm` appear directly in the methods' lambda expressions and are not hidden inside nested function calls.** 11. Add the neuron class to the package, by importing it in the `__init__.py` file of the `neurons` sub-folder: ```python from .my_neuron import MyNeuron ``` 12. Verify your point-neuron model by running simulations under various electrical stimuli and comparing the output to the neurons's expected behavior. Implement required corrections if any. 13. Pre-compute lookup tables required to run coarse-grained simulations of the neuron model upon ultrasonic stimulation. To do so, go to the `scripts` directory and run the `run_lookups.py` script with the neuron's name as command line argument, e.g.: ```python run_lookups.py -n myneuron --mpi``` If possible, use the `--mpi` argument to enable multiprocessing, as lookups pre-computation greatly benefits from parallelization. That's it! You can now run simulations of your point-neuron model upon ultrasonic stimulation. # Authors Code written and maintained by Theo Lemaire (theo.lemaire@epfl.ch). # License & citation This project is licensed under the MIT License - see the LICENSE file for details. If PySONIC contributes to a project that leads to a scientific publication, please acknowledge this fact by citing [Lemaire, T., Neufeld, E., Kuster, N., and Micera, S. (2019). Understanding ultrasound neuromodulation using a computationally efficient and interpretable model of intramembrane cavitation. J. Neural Eng.](https://iopscience.iop.org/article/10.1088/1741-2552/ab1685) DOI: 10.1088/1741-2552/ab1685 # References [1] Lemaire, T., Neufeld, E., Kuster, N., and Micera, S. (2019). Understanding ultrasound neuromodulation using a computationally efficient and interpretable model of intramembrane cavitation. J. Neural Eng. diff --git a/setup.py b/setup.py index 1eb2003..6faadf6 100644 --- a/setup.py +++ b/setup.py @@ -1,53 +1,53 @@ # -*- coding: utf-8 -*- # @Author: Theo Lemaire # @Email: theo.lemaire@epfl.ch # @Date: 2017-06-13 09:40:02 # @Last Modified by: Theo Lemaire -# @Last Modified time: 2020-02-01 16:13:33 +# @Last Modified time: 2020-02-12 14:08:03 import os from setuptools import setup def readme(): with open('README.md', encoding="utf8") as f: return f.read() def getFiles(path): return [f'{path}/{x}' for x in os.listdir(path)] setup( name='PySONIC', version='1.0', description='Python implementation of the **multi-Scale Optimized Neuronal Intramembrane \ Cavitation** (SONIC) model to compute individual neural responses to acoustic \ stimuli, as predicted by the *intramembrane cavitation* hypothesis.', long_description=readme(), url='https://iopscience.iop.org/article/10.1088/1741-2552/ab1685', classifiers=[ 'Development Status :: 4 - Beta', 'Intended Audience :: Science/Research', 'Programming Language :: Python :: 3', 'Topic :: Scientific/Engineering :: Physics' ], keywords=('SONIC NICE acoustic ultrasound ultrasonic neuromodulation neurostimulation excitation\ computational model intramembrane cavitation'), author='Théo Lemaire', author_email='theo.lemaire@epfl.ch', license='MIT', packages=['PySONIC'], scripts=getFiles('scripts') + getFiles('tests'), install_requires=[ 'numpy>=1.10', 'scipy>=0.17', 'matplotlib>=2' 'pandas>=0.22.0', 'colorlog>=3.0.1', 'tqdm>=4.3', 'lockfile>=0.1.2', 'multiprocess>=0.70', 'pushbullet.py>=0.11.0' ], zip_safe=False )