From b4aac15bf9e696c442f8d4c972f329d16ff97f7f Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Fri, 1 May 2020 15:41:25 +0530 Subject: [PATCH 1/3] New python bindings using pybind11 (#410) * not a bug. * Turned scripts recieved from harsha into a test case. open #402. * Renamed wrapper.Neutral to __Wrapper__. With new API, this functionality can be built in. * closes #401 * Fixed another bug: -DWTIH_BOOST=ON could not override GSL after WITH_GSL was cached by cmake. Ie, if once built with default options, there was no way to use BOOST without cleaning up the old build completely. * check is made if solver has space while reading/writing SBML files,small change to port the code to py3 * Squashed commit of the following: commit b313f8d72537b6d8218857d0f0ef81268bc05f81 Author: Dilawar Singh Date: Sun Apr 12 19:03:24 2020 +0530 moved __init__.py and moose.py to pybind folder. commit 77afafd49dc6e99b1c00c060b00181d1190e1c7b Author: Dilawar Singh Date: Sun Apr 12 18:03:28 2020 +0530 Use not gui backend. commit 6ad911c73c5f9d01846c5869263c12ee82e1bdf8 Author: Dilawar Singh Date: Sun Apr 12 13:23:33 2020 +0530 Variable and Cinfo need not be exposed. commit 5fec8497593a9d77b5ed5832336747c6cd8fb33c Author: Dilawar Singh Date: Sun Apr 12 12:27:13 2020 +0530 Create moose element from vec and field. commit ab3d85dc0f023a4cda2a9cf7ecfae97d860567b2 Author: Dilawar Singh Date: Sun Apr 12 11:21:21 2020 +0530 Added support for ["string", double] valueFinfoItem. commit 9c967c02abd565c90d452d200f778e1d2ed78349 Author: Anushree Narjala Date: Sun Apr 12 10:03:17 2020 +0530 seed is an int and can't be empty. commit cc7ea95512692e3cd3a4fd0aefbe573094901e38 Author: Dilawar Singh Date: Sat Apr 11 15:46:11 2020 +0530 This is a really good commit. `.num` is supported now. commit 2185c653125c6285cb4378fd5189107bebd5f4d2 Author: Dilawar Singh Date: Sat Apr 11 12:28:39 2020 +0530 Added doxygen target. commit 32c3fc70d44762fdbabe37edc3cd6c5cd20502db Author: Dilawar Singh Date: Fri Apr 10 13:09:09 2020 +0530 Finfo is also vectorised. commit d71612488026c12b01fb816cf0eb4c14fc356af8 Author: Dilawar Singh Date: Fri Apr 10 12:03:53 2020 +0530 Negative indexing is allowed. Fixes one more moose-examples neuroml/LIF/twoLIFxml_firing.py commit a2d6a384ff15bc6d8a2605d503ee90b7366ef71b Author: Dilawar Singh Date: Thu Apr 9 21:07:04 2020 +0530 Use old PyRun code. Pybind11 does not have subterpreter support. commit 2587c0db0dc25cf21b85b24f774b90b1cff9b011 Author: Dilawar Singh Date: Thu Apr 9 13:58:16 2020 +0530 Added a test for testing pyrun. commit f3a4925805d206531cb71a82fa72b1c24e63a548 Author: Dilawar Singh Date: Thu Apr 9 11:25:11 2020 +0530 when `-DWITH_BOOST=ON` is passed to cmake, it now overrides `WITH_GSL` option. Also fixes build failure. commit 2127c3abc4870fd4b7e4d17ebecc5aa579dfa873 Author: Dilawar Singh Date: Thu Apr 9 11:15:01 2020 +0530 Fixes https://gitlab.com/dilawar/moose-core/-/issues/7 commit 31f2b8f6f1e91b5d8946559fe1352368587fad3f Author: Dilawar Singh Date: Wed Apr 8 23:16:37 2020 +0530 If Function is not valid_, return quietly. commit b91a0eff9c018e67e8ea399b640efedd171f9d29 Author: Dilawar Singh Date: Wed Apr 8 22:25:06 2020 +0530 All tests are passing now. commit 0ce71acd9db6cfeb5313a76b32e880a813eab15e Author: Dilawar Singh Date: Wed Apr 8 20:13:39 2020 +0530 genesis and kkit are reverted back to master. commit 6535c465bbd5b007f925bc5e781f2d8b23a19309 Author: Dilawar Singh Date: Wed Apr 8 19:03:13 2020 +0530 isA is working just fine. commit bf118f40d19c9e4cece04bef2a1bb504c7c33475 Author: Dilawar Singh Date: Wed Apr 8 14:18:23 2020 +0530 We can now assign moose.vec to a field which takes Id. refactoring. int -> double, bool -> (int, double) coercing is allowed. Fixed script /home1/dilawars/Work.HG/GITLAB/moose-examples/snippets/interpol2d.py in https://gitlab.com/dilawar/moose-examples/-/issues/1 commit fb57aaffd537f2d627d12b900ee339296b07528c Author: Dilawar Singh Date: Wed Apr 8 13:21:19 2020 +0530 overloading template function is not so straight-forward when typecasting can happen by itslf e.g. int and unsigned int. commit 22aeb43a3fb0ef13a2066c5d29eb1bb9f7fe6ee3 Author: Dilawar Singh Date: Wed Apr 8 09:52:57 2020 +0530 moose.element return single ObjId and not vec as I mistakenly assumed. commit ea81f1c109b062009cd8a43220a677dd3184f8e8 Author: Dilawar Singh Date: Tue Apr 7 21:45:13 2020 +0530 Vectorize function later. commit 462465177e75b551482782d30dd77c84880605dd Author: Dilawar Singh Date: Tue Apr 7 20:48:47 2020 +0530 name, path, and parent of moose.vec are not vectorised. commit 6126a6402ee22664fdbb62aff8f60fa07a99e6c4 Author: Dilawar Singh Date: Tue Apr 7 19:20:28 2020 +0530 snippets/savemodel.py is causing problem now. commit 15eae1dbcd4cfd1ba4140e1c054d4827ac7b033e Author: Dilawar Singh Date: Tue Apr 7 18:08:37 2020 +0530 vec values are returned as numpy array. commit cc89202ad7325aa9d9bca82e542481611d65e1bf Author: Dilawar Singh Date: Tue Apr 7 16:55:00 2020 +0530 Default parameters in connect is now working. First argument is not needed if it is a class member function. commit 8092a8ef91c7e44bad2173a8cd20be5e3a504a75 Author: Dilawar Singh Date: Tue Apr 7 16:19:16 2020 +0530 If a Shell function retuns Id, wrap it in a MooseVec. The current API has this behaviour. commit 8ca430c97ad13370a4253ce5b73f8abbbc12f4b3 Author: Dilawar Singh Date: Tue Apr 7 13:54:52 2020 +0530 TODO: Id should be wrapped as moose.vec commit d6552e6293bf7d36b196e47fcd936d06eae8c7cc Author: Dilawar Singh Date: Tue Apr 7 12:05:31 2020 +0530 Passes snippets/synapse.py https://gitlab.com/dilawar/moose-examples/-/issues/1 commit 3ea0a660ec5a5f57fb625b6ffd5aff275152be1f Author: Dilawar Singh Date: Tue Apr 7 11:23:27 2020 +0530 Support more return types. commit 0862930b42e8d6b751985fe71c91139c038e888c Author: Dilawar Singh Date: Tue Apr 7 10:44:35 2020 +0530 MooseVec can now handle fieldElement as well. commit 1d40e74de77b4390fd3f612afc60881d8b2a81b4 Author: Dilawar Singh Date: Mon Apr 6 21:03:58 2020 +0530 Needs some major overhaul of API. commit 3116b0596e6aba2c5bf7f409fa2fe10efe11af25 Author: Dilawar Singh Date: Mon Apr 6 15:04:32 2020 +0530 Removed melement. commit 8baffdcbbb122b7f1e08090d7daee33940645211 Author: Dilawar Singh Date: Mon Apr 6 15:00:59 2020 +0530 Support more fieldType. Fixes one more failing script in moose examples. commit b3a3e844e42260a054ec2956d7dea4d9a53bcf79 Author: Dilawar Singh Date: Mon Apr 6 14:01:28 2020 +0530 Time to run examples now. commit 731fc47fe5d0850e038d981c4c3cf411e4a39611 Author: Dilawar Singh Date: Mon Apr 6 13:44:38 2020 +0530 type checking has been moved to C++ code. its bit tricky here and not as readable as it should be. May be I can leave this at the python level. commit 790efdf6ca12b3b99cc04454d7d10b911ade11be Author: Dilawar Singh Date: Mon Apr 6 13:24:30 2020 +0530 Some more progress. Getting a bit more faster than the current API. commit 4e246219bde8ebc1f67ab02aea0da3fa3336167f Author: Dilawar Singh Date: Mon Apr 6 13:17:18 2020 +0530 Overloaded funtions. commit bc95f4da354773cf55bc82fe475887d2c13ef284 Author: Dilawar Singh Date: Mon Apr 6 12:25:23 2020 +0530 Enabled helper functions. commit aeecc41854581d49788eb982ed32c0af288641f5 Author: Dilawar Singh Date: Mon Apr 6 00:17:06 2020 +0530 beat the old api in microbenchmarks as well. commit 6e88eff9812bcb8e62614773fafd37d84c087c57 Author: Dilawar Singh Date: Sun Apr 5 23:56:00 2020 +0530 minor tweaks. commit 1dd93908797be948939870ca21604e6b642a5c5c Author: Dilawar Singh Date: Sun Apr 5 23:46:37 2020 +0530 moose.create is fast but moose.delete is bit slow. commit 0eda1b7af7230ed3e11de2dda923fd3bba7b6aab Author: Dilawar Singh Date: Sun Apr 5 22:39:37 2020 +0530 forward declaration and compile fixes. commit a3bdd698844760b4d9fb7fef6ab90293e2d308c1 Author: Dilawar Singh Date: Sun Apr 5 20:05:43 2020 +0530 Added benchmark file. commit e294eeaddb04ff58371aba260cc9aed062bec812 Author: Dilawar Singh Date: Sun Apr 5 19:55:01 2020 +0530 added micro benchmarks. commit 5979dc481e8705116ffc84ce92722224a55b8d39 Author: Dilawar Singh Date: Sat Apr 4 23:25:28 2020 +0530 Added documentations. commit 56c12f45a9c729f7d44934dad90fb9838a8f3adf Author: Dilawar Singh Date: Sat Apr 4 22:21:40 2020 +0530 All tests are passing.. needs to add some tests.. commit f039fad969aa5535cfe768174d1f82fa45a71a76 Author: Dilawar Singh Date: Sat Apr 4 21:58:28 2020 +0530 _cmoose to _moose. commit 9543258a6c23b47c5dbe34c9cb96a980094625b9 Author: Dilawar Singh Date: Sat Apr 4 19:57:21 2020 +0530 Needs to fix some more API issues. commit 4d6c1479f5bafcb41402b82d80e9fefd5e072d03 Author: Dilawar Singh Date: Sat Apr 4 17:49:15 2020 +0530 Added version 2.5 commit f0efd214f0d7ef35fb67e53f7905105444803eb4 Author: Dilawar Singh Date: Sat Apr 4 17:41:41 2020 +0530 Removed a broken test and renamed one. The namedvars tests is moved to fixme (not supported). commit cd3dc5a963a731f58fa46b11065572647485eb26 Author: Dilawar Singh Date: Sat Apr 4 12:11:59 2020 +0530 Needs final touch. commit 5262dc4132b7d9cca149c8b56b0601755799b4e8 Author: Dilawar Singh Date: Sat Apr 4 12:03:56 2020 +0530 Added one more missing attribute. commit 77576436515d7e596e69355089477997a4416c9c Author: Dilawar Singh Date: Sat Apr 4 11:25:53 2020 +0530 test commit [skip ci] commit cb8a9702cd171cb77279c287095c6c9ec470f9b7 Author: Dilawar Singh Date: Sat Apr 4 10:28:06 2020 +0530 old test is back. commit 06e3357521563b1b7f59ab173f68f20844318e93 Author: Dilawar Singh Date: Sat Apr 4 10:24:53 2020 +0530 Fixed the issue with isinstance(x, moose.CubeMesh). Now it is working fine. commit 685ab75f751ff109b9616d7ace29582dd12e320e Author: Dilawar Singh Date: Sat Apr 4 07:26:24 2020 +0530 One more test is passing. commit 6188e0949f3f68433646aab703bd94bf93ec60ce Author: Dilawar Singh Date: Sat Apr 4 07:25:25 2020 +0530 Restored old values in the test. commit 349f8ea0971c242343f993eec2086bd510f94825 Author: Dilawar Singh Date: Sat Apr 4 05:55:15 2020 +0530 fixes to one more tests. commit c90986a62b5b7b345900bd1490a41f15b29f9b43 Author: Dilawar Singh Date: Sat Apr 4 05:42:22 2020 +0530 Now do a local testing. commit e6a6575c6f76a855df1ae39bef5c745d751e93d6 Author: Dilawar Singh Date: Sat Apr 4 05:37:26 2020 +0530 numerical assertion of oscillatory tests are hard. commit 5af49e95958f1cea41fac70be4286c50d1546d46 Author: Dilawar Singh Date: Sat Apr 4 05:26:34 2020 +0530 Almost all tests are passing. commit d7f03bd59d107d31ee4a02294cb9f06d20310674 Author: Dilawar Singh Date: Sat Apr 4 04:54:44 2020 +0530 remove 'value' attribute from the ObjId, it was conflicting with MString 'value'. commit ce79591383a999163c23dc476bb41085b55ce58b Author: Dilawar Singh Date: Sat Apr 4 04:43:36 2020 +0530 Needs to fix doc. commit 113dddc0302e0dca9a57bae8ceff55f5dcac930b Author: Dilawar Singh Date: Sat Apr 4 04:36:02 2020 +0530 more tests are passing. all test_Xreacs are passing now. commit 29ff41c80facd4fdd0ebb9c8cc36e26780724e2c Author: Dilawar Singh Date: Sat Apr 4 04:31:33 2020 +0530 Use ObjId instread of Id in buildMeshJunction. commit 33e9591505ed027f97bdb02da8840164ecc0bfab Author: Dilawar Singh Date: Sat Apr 4 04:27:38 2020 +0530 Passing ObjId as Id is creating trouble. commit 537779e28d2d20645db6abaf374250196c63c009 Author: Dilawar Singh Date: Sat Apr 4 03:59:30 2020 +0530 one more test passes. commit 650309ab7fb75b2470f483a21119017a5c9e1f9a Author: Dilawar Singh Date: Sat Apr 4 03:05:28 2020 +0530 delete works. commit b13e05176e46b8027c3620f19dac93b959558685 Author: Dilawar Singh Date: Sat Apr 4 02:13:31 2020 +0530 Some more tests [skip ci] commit e518d35e6402a05042d4ed5727a824df262b2e57 Author: Dilawar Singh Date: Sat Apr 4 01:42:15 2020 +0530 One more test is passed. commit c783578d1466b2a80c14045e7c8aee3467bc82b2 Author: Dilawar Singh Date: Sat Apr 4 01:37:24 2020 +0530 isinstance support is added. commit 2a28f9a974170b26767d9efe33902ec0dce60882 Author: Dilawar Singh Date: Fri Apr 3 22:15:46 2020 +0530 Added tests to normalizepath. commit 4c2086af6efcf0dd2d9c9791e2ee7fa605008791 Author: Dilawar Singh Date: Fri Apr 3 22:08:30 2020 +0530 Global random number generator is moved from basecode to randnum. commit 6a2b7b7a3eed2f1765b61bda6c70ed1e12cde1e3 Author: Dilawar Singh Date: Fri Apr 3 20:09:21 2020 +0530 Couple of seg-faults to take care of. commit 8a90db29454324f5b4df0c118d3ecc92b128196d Author: Dilawar Singh Date: Fri Apr 3 18:27:52 2020 +0530 Fixed one more test. commit 1798a1ed5a3a1a04c647a10f3b6ff9601edb52ea Author: Dilawar Singh Date: Fri Apr 3 14:18:47 2020 +0530 Need to fix rdesignuer now. commit 0be10c0e660b7ed56da5b5fa0cce33bcecb3f024 Author: Dilawar Singh Date: Fri Apr 3 12:59:16 2020 +0530 Finfo can also return .vec. commit 226d61633c75f5d60fbffaef76b2ac85bce5af4f Author: Dilawar Singh Date: Fri Apr 3 12:35:32 2020 +0530 Function is also fixed. commit b68a97bac95a347cad2081ea8ec7432e13ecbcc8 Author: Dilawar Singh Date: Fri Apr 3 12:22:29 2020 +0530 SynapseTest is also passing. commit 8f2a0391608619a4f9382cf46ef9c019c855a81b Author: Dilawar Singh Date: Fri Apr 3 11:38:20 2020 +0530 Fixes all the c++ tests commit 173b9d24f86589ed11efad6b118aa3762eaa533e Author: Dilawar Singh Date: Fri Apr 3 11:28:47 2020 +0530 ObjId.vec create a vec on the fly. commit e71fea0dd8048c12d17e0389f1a535fc09dcb795 Author: Dilawar Singh Date: Thu Apr 2 22:39:02 2020 +0530 Same problem on OSX. One more test is failing. commit 47e25f95a956c9c8e8e98a8a68b6af1f6639990b Author: Dilawar Singh Date: Thu Apr 2 22:08:41 2020 +0530 Some more fixes. moose.element is not honoring dataIndex. commit 9de507af215719c8128622db4eb25485286cf2cb Author: Dilawar Singh Date: Thu Apr 2 20:17:29 2020 +0530 bebug vec and connection list. commit d7f0a26b91db7b63b6c744a32a125f059b5fbffb Author: Dilawar Singh Date: Thu Apr 2 19:22:00 2020 +0530 Refactoring. commit 22214101d29666f5c3dc7df0506428a8db4bab11 Author: Dilawar Singh Date: Thu Apr 2 16:17:48 2020 +0530 Added .clang-format file. commit 7a8437d51ddbc2193509c601e5ca9da1b3ffe765 Author: Dilawar Singh Date: Thu Apr 2 12:44:32 2020 +0530 more progress. Lets have lunch first now. commit 0ed893302d45c8fd344ef13967d667aad25a08cc Author: Dilawar Singh Date: Thu Apr 2 12:25:44 2020 +0530 Fix Xreacs later. commit 04d4d2fd25ef118bd7fe86fc54e1ac3183d20a97 Author: Dilawar Singh Date: Thu Apr 2 11:52:19 2020 +0530 Refactoring. If Finfo* is passed, no need to pass rttitype and fname. We can get these values from Finfo. commit 77cc0b1ff48252a200d6d16522a88caca285660a Author: Dilawar Singh Date: Wed Apr 1 21:21:06 2020 +0530 refacorted codebase... commit 52cfdf7acd9f3c88e16785834879b8f7226e6e34 Author: Dilawar Singh Date: Wed Apr 1 21:06:13 2020 +0530 Added extra header for Finfo ... commit b16dd1c236079418431fe58d2bbefcd599d643de Author: Dilawar Singh Date: Wed Apr 1 19:58:56 2020 +0530 Needs to implement LookupFinfo set. commit 8199fc05672410899c41f2219a266532b234df4b Author: Dilawar Singh Date: Wed Apr 1 18:48:25 2020 +0530 Disable pybind11. commit 5c25dad5a5ccbdcd5bcfc48764e6b9ed5aab6de5 Author: Dilawar Singh Date: Wed Apr 1 18:48:02 2020 +0530 One more tests seem to pass. commit 40a45595ea8df4d3c0e50270e487643523270547 Author: Dilawar Singh Date: Wed Apr 1 18:22:52 2020 +0530 Some more fixes. commit dd9b50e9db13bb23bf0b40479f5b8793c6db2c41 Author: Dilawar Singh Date: Wed Apr 1 17:59:50 2020 +0530 Perfect. One more test passes. commit fec019b7d532fc5085750f4edf5e776d64e20d56 Author: Dilawar Singh Date: Wed Apr 1 15:41:22 2020 +0530 Refactoring and some more generic programming. commit 9eb230876541311d6d7f4e57ca703f2ddce594e8 Author: Dilawar Singh Date: Tue Mar 31 20:48:57 2020 +0530 small fixes. Changes in API requires .id . commit 7de32283c4aad0c0a4c9f1bc60af307b9d516712 Author: Dilawar Singh Date: Tue Mar 31 19:13:51 2020 +0530 Minor tweak to a test. commit c541b91df07aba448217f6773b9b5a5d7f001feb Author: Dilawar Singh Date: Tue Mar 31 19:08:36 2020 +0530 One more test passed. commit 5cc3d3b91404b817ac2018c68f1104f2104f8e0e Merge: ce579acf5 1abb6f1f6 Author: Dilawar Singh Date: Tue Mar 31 18:59:23 2020 +0530 Merge branch 'pybind11_shell' into temp commit ce579acf5aee3711bf5c2d7028f298e4a0e0541d Author: Dilawar Singh Date: Tue Mar 31 18:58:59 2020 +0530 renmaed. commit 16bbc3e8593199292c15d9b5d404f128784e44a4 Author: Dilawar Singh Date: Tue Mar 31 18:20:55 2020 +0530 phew. I made a boo boo before. commit 1abb6f1f6a978825e951feadcac8299c69ea2150 Merge: 24df86a66 fa06c38a9 Author: Dilawar Singh Date: Tue Mar 31 02:24:30 2020 +0530 Merge branch 'pybind11_shell' of gitlab.com:dilawar/moose-core into pybind11_shell commit fa06c38a942858cc6c2b6bafd5588ce47f1bc3a4 Author: Dilawar Singh Date: Tue Mar 31 02:14:22 2020 +0530 Id and ObjId are not playing well together... commit 48832b10703dab66e27df023fcba35a174bb1b48 Author: Dilawar Singh Date: Tue Mar 31 01:30:34 2020 +0530 test_synchan is a good example; possible we should return moose.vec there. commit 8667c139c234e0aedce35a99afcbe97308b6ca22 Author: Dilawar Singh Date: Tue Mar 31 01:28:02 2020 +0530 temp commit. commit 24df86a66a637cc87ec613b20f50de1c54568b87 Author: Dilawar Singh Date: Mon Mar 30 23:39:46 2020 +0530 Temp commit. Exposing only Id. commit 448b8b5b7f3ab9691c80956114b37d0db0aaeb02 Author: Dilawar Singh Date: Mon Mar 30 23:14:51 2020 +0530 more tests are passing... commit d1b4990d29f79d3cec4f281963c22bb3ca491974 Author: Dilawar Singh Date: Mon Mar 30 20:35:39 2020 +0530 Need to find a solution.. commit 6b5082b6aa638e7820b6ea55952f246afa871d99 Author: Dilawar Singh Date: Mon Mar 30 19:05:44 2020 +0530 Refactoring and have a working moose.vec API. commit 98d8d3440cb3dfc14f88af93b7e355f8802852d4 Author: Dilawar Singh Date: Mon Mar 30 18:05:07 2020 +0530 [skip ci] needs tweaking in the API. commit 0f7929c23eeb1c567f772b8d4bc3b94642111248 Author: Dilawar Singh Date: Mon Mar 30 14:40:37 2020 +0530 Support vec. But first need a nap. commit 93d6e8350593abdc9a123b5786b36d1fa5044760 Author: Dilawar Singh Date: Mon Mar 30 13:33:05 2020 +0530 refactoring. commit fd0301584377ef24439fd32d34b4494c8d29fe2b Author: Dilawar Singh Date: Mon Mar 30 13:17:31 2020 +0530 random works. commit fc345474889c9ea7f8d95ac4b82c0c2f8d90fbaa Author: Dilawar Singh Date: Mon Mar 30 11:49:00 2020 +0530 Need to polish the API. commit 6af0f2c15f548e02ffeb899842c4700932985f9f Author: Dilawar Singh Date: Mon Mar 30 11:00:03 2020 +0530 Lets move to DestFinfo. commit 476d7009ee2eafb82598de820d15fcf2f142ca29 Author: Dilawar Singh Date: Mon Mar 30 07:53:31 2020 +0530 Return type. commit 778208aaf1bd4c19db1c78063b9fa2700d2e115a Merge: dab5af452 dd65791b9 Author: Dilawar Singh Date: Mon Mar 30 07:42:04 2020 +0530 Merge branch 'pybind11_shell' of gitlab.com:dilawar/moose-core into pybind11_shell commit dd65791b93a6403915453344602b3b986c5ab2e5 Author: Dilawar Singh Date: Mon Mar 30 06:54:42 2020 +0530 Updated [skip ci] commit 76ec2a1d26abfe6a269faad2b261e710477f3241 Author: Dilawar Singh Date: Sun Mar 29 23:00:02 2020 +0530 [skip ci] some more changes. commit c4d7bc61a129337bf1af4f952de9a58ed83306b0 Author: Dilawar Singh Date: Sun Mar 29 22:24:57 2020 +0530 We go both API integrated. commit f0ac78508e5b36d2c0066867f6f90b2267e3f29b Author: Dilawar Singh Date: Sun Mar 29 21:48:18 2020 +0530 LookupField is a function. commit aee928ebe5a85d115a8fd0dae986f57f272c264a Author: Dilawar Singh Date: Sun Mar 29 21:11:48 2020 +0530 Do the rest tomorrow. commit e118e12bf4f8e56e008efd1dca05b90ba325bf0c Author: Dilawar Singh Date: Sun Mar 29 20:45:21 2020 +0530 Retuning binding to std::function which return the Finfo value. commit dab5af452a2809dac788f3a71ea5499122c7e51b Author: Dilawar Singh Date: Sun Mar 29 18:01:12 2020 +0530 isA is method. Time to make it a subscriptable dictionary. commit c7a7b2458a78ee758657b461726b76bc6f23cda7 Author: Dilawar Singh Date: Sun Mar 29 15:34:42 2020 +0530 Lets handle LookupField::set and get. commit a06e47874645bb640fae73ca31bb6ed350223b64 Author: Dilawar Singh Date: Sun Mar 29 01:13:46 2020 +0530 Deal with it tomorrow. commit bb1cae5c84df2546a1be13a333ffe47d92fda694 Author: Dilawar Singh Date: Sun Mar 29 00:28:22 2020 +0530 Getting there. [skip ci] commit 5cccf8bb038fefd4da93917d0fcbd0dbfc761056 Author: Dilawar Singh Date: Sat Mar 28 22:33:21 2020 +0530 Some refactoring. Back to same functionality [skip ci]. commit a979de6c5ce96dff087f356fa6e471e43feb8b98 Author: Dilawar Singh Date: Sat Mar 28 20:46:01 2020 +0530 Updated a bit more .. commit b43c6174a5e57054b42bdbb98ee82e7f179af6bd Author: Dilawar Singh Date: Sat Mar 28 19:47:58 2020 +0530 New API works fantastic. commit 0deb2912def2c038db84e00d5b0ca4e31b87bb10 Author: Dilawar Singh Date: Sat Mar 28 19:40:19 2020 +0530 Incremental change. Dynamic attributes. commit 7f2539c785cb752356081eec2f2da8e5b41643c1 Author: Dilawar Singh Date: Sat Mar 28 19:31:31 2020 +0530 Subclassing _ObjId now. commit 0f64cd08d8e6ee8cb4c42d2734d2e5caf043a6e9 Author: Dilawar Singh Date: Sat Mar 28 18:12:57 2020 +0530 Dynamic attributes are needed now. commit eff08b2cf4317363e2d26048b1494a2daa43996f Author: Dilawar Singh Date: Sat Mar 28 16:16:13 2020 +0530 All test passes. Needs to work on the API now. commit 8791df7af67ac5963b8a40a2673b6e37bb184322 Author: Dilawar Singh Date: Sat Mar 28 15:40:35 2020 +0530 Blazingly fast. commit 070f735b1294403b714389972d38f37d7abbb594 Author: Dilawar Singh Date: Sat Mar 28 14:06:47 2020 +0530 Perfect. The base API works now. Not time to do a profiling. commit 07a134809a7ab34dd9a49efa689bc24e9a7e8c5d Author: Dilawar Singh Date: Sat Mar 28 00:28:22 2020 +0530 This is for tomorow. commit 72f7b62fa6391929eadafee78249dcd9603a2fbb Author: Dilawar Singh Date: Fri Mar 27 21:43:33 2020 +0530 Work from home. commit 4ea29e92ab0663300eac7e54958d6cc85f3c1d49 Author: Dilawar Singh Date: Fri Mar 27 20:32:19 2020 +0530 May be later. commit eff6f902c41ba559f7a2e37dcb3daa8c1ddec506 Author: Dilawar Singh Date: Fri Mar 27 17:57:40 2020 +0530 Not sure about the testKsolve.cpp tests. commit bef104c153c3cd7ab388d20b8db2da3b5edcce10 Author: Dilawar Singh Date: Fri Mar 27 17:11:34 2020 +0530 Do testing with master branch. commit 0078af17f61700db2097a685c8ba4581d37a9593 Author: Dilawar Singh Date: Fri Mar 27 14:45:40 2020 +0530 get can not overloaded pretty well. Use different name for getting different value. It is verbose now but we can override later. commit 915e10f95adb30e66075d65125cbbe5fe0206cc2 Merge: 911bd03c8 bf2d609a2 Author: Dilawar Singh Date: Fri Mar 27 13:56:46 2020 +0530 Merge branch 'pybind11_shell' of gitlab.com:dilawar/moose-core into pybind11_shell commit bf2d609a2daefe28eb321c2c076d5168f01e1dac Author: Dilawar Singh Date: Fri Mar 27 14:11:18 2020 +0530 add test function. commit 911bd03c8d9095c883248574826782eeb5cfc7f7 Author: Dilawar Singh Date: Fri Mar 27 13:56:12 2020 +0530 local changes. commit cc7144fb0be01c20386c21c320691a17438abae7 Author: Dilawar Singh Date: Fri Mar 27 13:50:40 2020 +0530 Move to gulgula. commit d41e7ebbf4160722c20419972a468b8abc2f0602 Author: Dilawar Singh Date: Fri Mar 27 04:18:44 2020 +0530 Allmost there. commit d913cebbc20b5f1795cc6bc87e49f7ba682f1b8e Author: Dilawar Singh Date: Fri Mar 27 01:50:18 2020 +0530 addMsg -> connect . commit 8793d3386f85f4805f49ff06912bbfe3a643a34a Author: Dilawar Singh Date: Fri Mar 27 01:10:24 2020 +0530 get/set are on ObjId . commit d99115c2b2e67a042643471897c60a23e2421daa Author: Dilawar Singh Date: Fri Mar 27 00:47:20 2020 +0530 Ok. Vector and numpy are working. commit 2f3bc04011d0e80499bbbffae4dc548a8c875f67 Author: Dilawar Singh Date: Thu Mar 26 23:02:03 2020 +0530 move to bebinca for fast compilation. commit a94fec91645a4942a926c04193a110ae9bbd485b Author: Dilawar Singh Date: Thu Mar 26 18:29:50 2020 +0530 children and parent is not working. commit 756ec3a24fa355615ca039e9e9a59f8a60e67f51 Author: Dilawar Singh Date: Wed Mar 25 14:53:17 2020 +0530 Some more fixes. It will be too much debugging to get it right. commit 77451f169582a234ecd3377d353ed5361ea9fec1 Author: Dilawar Singh Date: Tue Mar 24 15:07:09 2020 +0530 All the learning experience is over. Pybind11 is great. commit 6edda7ab96ae86c65b1f52d3cee4771a435dfaf6 Author: Dilawar Singh Date: Tue Mar 24 00:55:13 2020 +0530 Add a bit more fields. commit e32c468ca4ff9d493bc43ee19edf8b5f27b330d1 Author: Dilawar Singh Date: Mon Mar 23 23:30:19 2020 +0530 I can complete this API tomorrow. commit 7aaddf75179282d3f07914dbec34994c067d22cd Author: Dilawar Singh Date: Mon Mar 23 22:54:35 2020 +0530 added more functions [skip ci] commit 7f1b7090e94fbb9732a6bafa4f0d0123de794301 Author: Dilawar Singh Date: Mon Mar 23 16:38:34 2020 +0530 disable build for now on gitlab ci commit ae2739d70bced3c2952b937d9147e06a64b31a59 Author: Dilawar Singh Date: Mon Mar 23 15:05:22 2020 +0530 pybind11 module is named _cmoose and it different from _moose. commit 0c336848e7a95922d1111fbeec16edb37aafb768 Author: Dilawar Singh Date: Mon Mar 23 14:45:32 2020 +0530 I got wildcardFind to function. commit 65b307c12fcef3ae2e2b05c17511af038cbcaba5 Author: Dilawar Singh Date: Mon Mar 23 13:33:22 2020 +0530 Fixed the bug I caused by using smart pointer. I am so silly... commit fe596e353b39f8232d35a10fe022c0654d2d3669 Merge: d5d29bb38 f4070daf1 Author: Dilawar Singh Date: Mon Mar 23 12:45:01 2020 +0530 Merge branch 'issue_397' of gitlab.com:dilawar/moose-core into pybind11 commit d5d29bb38ceeae7d62bacd23ccad641b9be6543c Author: Dilawar Singh Date: Sun Mar 22 23:12:58 2020 +0530 Time to support / in path. commit 270ea8cf33cee04e1919d24d40d3ac3213d8b90f Author: Dilawar Singh Date: Sun Mar 22 22:50:21 2020 +0530 empty element() commit a1eed3ad0d5211de4c0b1fbbca6913e5172a394d Author: Dilawar Singh Date: Sun Mar 22 22:39:55 2020 +0530 temp commit. commit a70b5fe9b5e916c5a9e5bfc8e63d396b202d6243 Author: Dilawar Singh Date: Sun Mar 22 15:44:56 2020 +0530 Great. Lets try cython as well. commit 038490f009e58cdf149918664c65db5e9b0bd84b Author: Dilawar Singh Date: Sun Mar 22 15:44:27 2020 +0530 Try cython now. commit 8bbf9002f173085a920a24c45fd4d1b8e2ad82f2 Author: Dilawar Singh Date: Sun Mar 22 13:43:02 2020 +0530 _moose goes to python/moose directory. commit 014bde2b82fa479fda5c6801c817fbd79d9f93c5 Merge: 8f6089910 ad58dc5cd Author: Dilawar Singh Date: Sun Mar 22 13:18:20 2020 +0530 Merge branch 'issue_397' into pybind11 commit f4070daf1b015b377e4fdc25ec3cd8bfe8bade74 Merge: ad58dc5cd 5e660e998 Author: Dilawar Singh Date: Sat Mar 21 22:21:16 2020 +0530 Merge branch 'refactoring' into issue_397 commit 5e660e9982644f33679b822b8404d95a4cba3376 Author: dilawars Date: Sat Mar 21 21:24:21 2020 +0530 include cmath in Pool.cpp as well. Failed compilation with gcc5.3 commit ad58dc5cd8b7ec47cd88f9eb95c41aed621e1c84 Author: dilawars Date: Sat Mar 21 21:24:21 2020 +0530 include cmath in Pool.cpp as well. Failed compilation with gcc5.3 commit c4d55aa61b423114b1a4277062c3d6a85eaaf324 Author: Dilawar Singh Date: Sat Mar 21 15:45:16 2020 +0530 Minor cleanup in macros and loggers. numCores now use thread library to determine number of available threads. commit f8dcb12e3778aae27d476c7a92f2bc97bc613663 Author: Dilawar Singh Date: Sat Mar 21 15:32:02 2020 +0530 NUMPY is essential dependency; therefore numpy code is no longer included conditionally. USE_NUMPY is implied and have been removed from cmake. commit 9ef658e7b78d192987e2617660b2226b0c0b9023 Author: Dilawar Singh Date: Sat Mar 21 15:15:43 2020 +0530 Fix to https://github.com/BhallaLab/moose-core/issues/397 commit 8f60899108fba4898d536916ccec726effad774c Author: Dilawar Singh Date: Tue Mar 17 18:27:54 2020 +0530 Perfecto. Create works. commit aa95a0c99cb1d73fd15d018e0fc0430844458756 Author: Dilawar Singh Date: Sun Mar 15 22:10:07 2020 +0530 pybind11 bindings. commit da9d1d930ed317ab298b0a81357a4b9f7f4a4f95 Merge: 0e85a57b3 36c002688 Author: Dilawar Singh Date: Sun Mar 15 15:40:06 2020 +0530 Merge commit '36c0026886c70e39c505f8715e65a7c3cf1e6ade' as 'external/pybind11' commit 36c0026886c70e39c505f8715e65a7c3cf1e6ade Author: Dilawar Singh Date: Sun Mar 15 15:40:06 2020 +0530 Squashed 'external/pybind11/' content from commit 4f72ef846 git-subtree-dir: external/pybind11 git-subtree-split: 4f72ef846fe8453596230ac285eeaa0ce3278bb4 * Minor fixes to pybind11. * Fix #409 When `moose.Function('abc')` is created, set expression to "0". Expression is not empty by default. This is to mimic the old behaviour. Note that at this point, derivative is not defined and is `nan` (old behaviour: derivative is 0.0). * Ready for a draft PR and initial disucssion. * Return numpy array instead of vector. Probably not the most memory efficient way for returning vector but since most pyMOOSE scripts assume that returned data is numpy array, we return the numpy array. TODO: benchmarking. * Fixed: moose.le can caused segfault when used on moose.vec This also fixes script mgblock.py https://github.com/BhallaLab/moose-examples/pull/71 * Fixed: moose.le can caused segfault when used on moose.vec This also fixes script mgblock.py https://github.com/BhallaLab/moose-examples/pull/71 * removed mkdoc.py from pybind11. * Fixed a pylint error as well python2/python3 compatibility * wildcard -> reacSystemPath Stoic::path is depreacted bcause it collides with Neutral::path. * Fixed another set. * Travis fix: Install pytest on OSX as well. * fix gitlab pipeline install pytest * isinstance is replace to isA added to this, validation.py: error msg is sent back, writeKkit.py: while writting genesis file if any object is not written then errorlog is send/printed which is usefull durning command line * fix test py_run. Relax the matching to 90% using difflib (from 95%). * grenerate documentation on the fly. * Work in progress: __doc__ string from cWork in progress: __doc__ string from cWork in progress: __doc__ string from cWork in progress: __doc__ string from c++ * Keeping the C++ type and Python's type name same. * Cleanup * pydoc support moved moose.py content to __init__.py. This way pydoc works great also fixed travis build. * moose.doc is working now. _moose.generateDoc is the underlying function. Needs to cleanup documentation a bit now. Fixed regression. * update to docs Disabled C++ signature in Python documentations. Added docstring to __init__.py * more docstring are added [skip ci] * Added datetime and other string to version_info. * All functions have docstring. * loadmodel docstring is added. * temp commit. * showmsg is ported to c++. * added more docstring and moved some functions to public api. * Merged hrani changes and mine from new bindings. removed 'basestring' * # This is a combination of 2 commits. # This is the 1st commit message: python2 support. Added python2 support as well. It will be easy to remove later. _moose.element is a good way to convert string/objid/id to melement. # This is the commit message #2: writeKkit * python2 support. Added python2 support as well. It will be easy to remove later. _moose.element is a good way to convert string/objid/id to melement. writeKkit python2 support. Added python2 support as well. It will be easy to remove later. python2 support. Added python2 support as well. It will be easy to remove later. _moose.element is a good way to convert string/objid/id to melement. writeKkit python2 support. Added python2 support as well. It will be easy to remove later. * basestring -> str * fixes to `pip install` Added missing folders. * Fixed pylint error. * moose.getField accepts two argument instead of 3. Updated rmogul.py file. * fix: compiles with clang++ typeid(X) when X is an incomplete type is not supported by C++ standard. Suprisingly this was compiling fine with gcc but not with clang++. version is set to 3.2.0.dev$(today) * travis fixes: OSX PyRun tests compares last 50 lines rather than whole text. This way we can ignore lines with different timestamp. * builds on osx locally. * tests passes with 3.8 as well. * On OSX, stream does not flush properly? Using difflib to test the ratio between got and expected string. * flush the streams before calling tests... * Don't run the trvais/osx Not sure why but only on travis+OSX, pyrun test does not pass. It fails because whole buffer is not dumped to the tty. * Fixes to pyrun tests. * Time to post the API. * listmsg has been moved to C++. * docstring to writeNML2 * Fixed typo in docstring. Ready to be reviewed. * showfield and showfields are both supported. `moose.showfield` is an alias for `moose.showfields`. * Added back moose.ce Co-authored-by: Dilawar Singh Co-authored-by: HarshaRani Co-authored-by: Anushree Narjala --- .ci/travis_prepare_osx.sh | 1 + .clang-format | 49 + .gitlab-ci.yml | 8 +- CMakeLists.txt | 182 +- CheckCXXCompiler.cmake | 7 +- MANIFEST.in | 2 + basecode/CMakeLists.txt | 7 +- basecode/Cinfo.cpp | 787 ++-- basecode/Cinfo.h | 627 +-- basecode/Conv.h | 53 +- basecode/DestFinfo.cpp | 60 +- basecode/DestFinfo.h | 41 +- basecode/EpFunc.h | 2 + basecode/Finfo.cpp | 99 +- basecode/Finfo.h | 43 +- basecode/Id.cpp | 124 +- basecode/Id.h | 72 +- basecode/LookupValueFinfo.h | 228 +- basecode/ObjId.h | 10 +- basecode/consts.cpp | 25 - basecode/global.cpp | 44 +- basecode/global.h | 53 +- basecode/header.h | 41 +- basecode/testAsync.cpp | 3289 ++++++++------- basecode/testGlobals.cpp | 20 + biophysics/Compartment.cpp | 2 +- biophysics/HHChannel.cpp | 526 ++- biophysics/HHChannel.h | 330 +- biophysics/HHChannelBase.cpp | 544 ++- biophysics/HHGate.cpp | 837 ++-- biophysics/HHGate.h | 413 +- biophysics/Neuron.cpp | 5 +- biophysics/RandSpike.cpp | 2 +- biophysics/ReadCell.cpp | 8 +- biophysics/ReadSwc.cpp | 2 +- biophysics/testBiophysics.cpp | 1480 ++++--- builtins/Function.cpp | 38 +- builtins/Function.h | 2 +- builtins/HDF5DataWriter.cpp | 4 +- builtins/HDF5WriterBase.cpp | 42 +- builtins/HDF5WriterBase.h | 6 +- builtins/Interpol2D.cpp | 4 +- builtins/MooseParser.cpp | 44 +- builtins/MooseParser.h | 11 +- builtins/MooseSocketInfo.h | 2 +- builtins/Mstring.cpp | 71 +- builtins/Mstring.h | 52 +- builtins/NSDFWriter.cpp | 16 +- builtins/SocketStreamer.cpp | 28 +- builtins/SocketStreamer.h | 14 +- builtins/Streamer.cpp | 52 +- builtins/Streamer.h | 16 +- builtins/StreamerBase.cpp | 4 +- builtins/Table.cpp | 8 +- builtins/Table.h | 2 +- builtins/TableBase.cpp | 14 +- builtins/TableBase.h | 5 +- builtins/testBuiltins.cpp | 2 + builtins/testNSDF.cpp | 2 +- devel/CMakeLists.txt | 6 + devel/Doxyfile.in | 2280 +++++++++++ {tests/py_moose => devel/fixme}/test_docs.py | 3 +- .../fixme}/test_function_namedvars.py | 0 .../py_moose => devel/fixme}/test_wrapper.py | 0 device/PulseGen.cpp | 318 +- device/PulseGen.h | 49 +- diffusion/Dsolve.cpp | 4 +- diffusion/Dsolve.h | 2 +- external/CMakeLists.txt | 2 + external/fmt/CMakeLists.txt | 4 + external/fmt/include/fmt/chrono.h | 1119 +++++ external/fmt/include/fmt/color.h | 568 +++ external/fmt/include/fmt/compile.h | 595 +++ external/fmt/include/fmt/core.h | 1789 ++++++++ external/fmt/include/fmt/format-inl.h | 1403 +++++++ external/fmt/include/fmt/format.h | 3648 +++++++++++++++++ external/fmt/include/fmt/locale.h | 78 + external/fmt/include/fmt/os.h | 392 ++ external/fmt/include/fmt/ostream.h | 143 + external/fmt/include/fmt/posix.h | 2 + external/fmt/include/fmt/printf.h | 721 ++++ external/fmt/include/fmt/ranges.h | 387 ++ external/fmt/src/format.cc | 176 + external/fmt/src/os.cc | 316 ++ external/pybind11/.appveyor.yml | 70 + external/pybind11/.gitignore | 38 + external/pybind11/.gitmodules | 3 + external/pybind11/.readthedocs.yml | 3 + external/pybind11/.travis.yml | 306 ++ external/pybind11/CMakeLists.txt | 157 + external/pybind11/CONTRIBUTING.md | 49 + external/pybind11/ISSUE_TEMPLATE.md | 17 + external/pybind11/LICENSE | 29 + external/pybind11/MANIFEST.in | 2 + external/pybind11/README.md | 129 + external/pybind11/include/pybind11/attr.h | 493 +++ .../pybind11/include/pybind11/buffer_info.h | 114 + external/pybind11/include/pybind11/cast.h | 2179 ++++++++++ external/pybind11/include/pybind11/chrono.h | 184 + external/pybind11/include/pybind11/common.h | 2 + external/pybind11/include/pybind11/complex.h | 65 + .../pybind11/include/pybind11/detail/class.h | 639 +++ .../pybind11/include/pybind11/detail/common.h | 820 ++++ .../pybind11/include/pybind11/detail/descr.h | 100 + .../pybind11/include/pybind11/detail/init.h | 335 ++ .../include/pybind11/detail/internals.h | 349 ++ .../pybind11/include/pybind11/detail/typeid.h | 55 + external/pybind11/include/pybind11/eigen.h | 607 +++ external/pybind11/include/pybind11/embed.h | 202 + external/pybind11/include/pybind11/eval.h | 117 + .../pybind11/include/pybind11/functional.h | 101 + external/pybind11/include/pybind11/iostream.h | 209 + external/pybind11/include/pybind11/numpy.h | 1642 ++++++++ .../pybind11/include/pybind11/operators.h | 168 + external/pybind11/include/pybind11/options.h | 65 + external/pybind11/include/pybind11/pybind11.h | 2183 ++++++++++ external/pybind11/include/pybind11/pytypes.h | 1484 +++++++ external/pybind11/include/pybind11/stl.h | 386 ++ external/pybind11/include/pybind11/stl_bind.h | 656 +++ external/pybind11/pybind11/__init__.py | 12 + external/pybind11/pybind11/__main__.py | 36 + external/pybind11/pybind11/_version.py | 2 + external/pybind11/setup.cfg | 12 + external/pybind11/setup.py | 122 + external/pybind11/tools/FindCatch.cmake | 57 + external/pybind11/tools/FindEigen3.cmake | 81 + .../pybind11/tools/FindPythonLibsNew.cmake | 202 + external/pybind11/tools/check-style.sh | 70 + external/pybind11/tools/libsize.py | 38 + .../pybind11/tools/pybind11Config.cmake.in | 104 + external/pybind11/tools/pybind11Tools.cmake | 227 + hsolve/Cell.cpp | 267 +- hsolve/ZombieCompartment.cpp | 3 +- kinetics/Reac.cpp | 150 +- ksolve/Gsolve.cpp | 2 +- ksolve/GssaVoxelPools.cpp | 3 +- ksolve/SteadyStateBoost.cpp | 811 ++-- ksolve/SteadyStateGsl.cpp | 3 +- ksolve/Stoich.cpp | 2136 +++++----- ksolve/Stoich.h | 211 +- ksolve/VoxelPools.h | 2 +- mesh/ChemCompt.h | 676 ++- mesh/CylMesh.cpp | 4 +- mesh/NeuroNode.cpp | 4 +- mpi/proc.cpp | 222 - mpi/proc1.cpp | 228 -- mpi/proc2.cpp | 179 - mpi/proc3.cpp | 109 - mpi/proc4.cpp | 109 - mpi/proc5.cpp | 181 - msg/SparseMsg.cpp | 1 + msg/SparseMsg.h | 2 +- pybind11/CMakeLists.txt | 84 + pybind11/Finfo.cpp | 392 ++ pybind11/Finfo.h | 133 + pybind11/MooseVec.cpp | 250 ++ pybind11/MooseVec.h | 177 + pybind11/PyRun.cpp | 347 ++ pybind11/PyRun.h | 88 + pybind11/helper.cpp | 615 +++ pybind11/helper.h | 230 ++ pybind11/pymoose.cpp | 449 ++ pybind11/pymoose.h | 48 + pymoose/__init__.py | 23 + {python/moose => pymoose}/moose.py | 0 pymoose/moosemodule.cpp | 4 +- pymoose/vec.cpp | 868 ++-- python/moose/SBML/readSBML.py | 25 +- python/moose/SBML/validation.py | 4 +- python/moose/SBML/writeSBML.py | 2 +- python/moose/__init__.py | 890 +++- .../chemUtil/add_Delete_ChemicalSolver.py | 8 +- python/moose/chemUtil/chemConnectUtil.py | 35 +- python/moose/fixXreacs.py | 39 +- python/moose/model_utils.py | 245 +- python/moose/moose_legacy.py | 391 ++ python/moose/neuroml/ChannelML.py | 16 +- python/moose/neuroml/MorphML.py | 4 +- python/moose/{moose_test.py => tests.py} | 4 +- python/moose/utils.py | 638 +-- python/moose/wrapper.py | 212 - python/rdesigneur/moogul.py | 2 +- python/rdesigneur/rdesigneur.py | 10 +- randnum/CMakeLists.txt | 2 +- randnum/RNG.cpp | 1 - randnum/RNG.h | 1 + randnum/randnum.cpp | 52 + randnum/randnum.h | 80 + randnum/test_normal_dist.cpp | 12 +- scheduling/CMakeLists.txt | 14 +- setup.py | 3 +- shell/LoadModels.cpp | 2 +- shell/Neutral.cpp | 796 ++-- shell/Neutral.h | 93 +- shell/SaveModels.cpp | 2 +- shell/Shell.cpp | 1014 ++--- shell/Shell.h | 7 +- shell/ShellCopy.cpp | 285 +- shell/Wildcard.cpp | 17 +- shell/Wildcard.h | 14 +- shell/testShell.cpp | 3331 ++++++++------- ...aupnerBrunel2012CaPlasticitySynHandler.cpp | 3 + synapse/RollingMatrix.cpp | 46 +- synapse/RollingMatrix.h | 22 +- synapse/SeqSynHandler.cpp | 13 +- synapse/SimpleSynHandler.cpp | 156 +- tests/CMakeLists.txt | 114 + tests/benchmarks/load_module.py | 0 tests/benchmarks/micro_benchmark.sh | 15 + tests/{py_moose => core}/OSC_diff_vols.g | 0 tests/{py_moose => core}/benchmark.py | 0 tests/{py_moose => core}/chan_proto.py | 0 tests/{py_moose => core}/models.py | 0 tests/{py_moose => core}/param_chan.py | 0 tests/{py_moose => core}/params.py | 0 tests/{py_moose => core}/run_mumble.sh | 0 tests/{py_moose => core}/soma.p | 0 tests/{py_moose => core}/streamer.py | 0 ...GraupnerBrunel2012_STDPfromCaPlasticity.py | 1 + tests/{py_moose => core}/test_Xchan1.py | 129 +- tests/{py_moose => core}/test_Xdiff1.py | 0 tests/{py_moose => core}/test_Xenz1.py | 0 tests/{py_moose => core}/test_Xreacs2.py | 14 + tests/{py_moose => core}/test_Xreacs3.py | 2 +- tests/{py_moose => core}/test_Xreacs4.py | 2 +- tests/{py_moose => core}/test_Xreacs4a.py | 2 +- tests/{py_moose => core}/test_Xreacs5.py | 2 +- tests/{py_moose => core}/test_Xreacs5a.py | 2 +- tests/{py_moose => core}/test_Xreacs6.py | 4 +- tests/{py_moose => core}/test_Xreacs7.py | 0 tests/{py_moose => core}/test_Xreacs8.py | 2 +- .../test_accessing_existing_paths.py | 0 tests/core/test_api.py | 221 + .../test_connectionLists.py | 7 +- .../test_cylinder_diffusion_gsolve+dsolve.py | 0 tests/{py_moose => core}/test_difshells.py | 3 +- tests/core/test_doctests.py | 41 + .../{py_moose => core}/test_dose_response.py | 0 tests/core/test_expr_parser.py | 353 ++ tests/{py_moose => core}/test_function.py | 1 + tests/core/test_function_change_expr.py | 99 + .../test_function_chemsys.py | 0 .../test_function_controls_reac_rate.py | 7 +- tests/core/test_function_example.py | 97 + .../test_gsolve_parallel.py | 0 .../test_hsolve_externalCalcium.py | 0 tests/{py_moose => core}/test_kkit.py | 12 +- tests/{py_moose => core}/test_ksolve.py | 0 .../test_ksolve_parallel.py | 20 +- tests/core/test_metaclass.py | 38 + tests/core/test_moose_attribs.py | 196 + tests/{py_moose => core}/test_moose_paths.py | 8 +- .../test_negative_value_flag.py | 5 +- tests/core/test_pyrun.py | 380 ++ tests/{py_moose => core}/test_random_gen.sh | 0 tests/{py_moose => core}/test_random_num.py | 0 tests/{py_moose => core}/test_rdesigneur.py | 2 +- .../test_rdesigneur_random_syn_input.py | 0 .../test_steady_state_solver.py | 0 tests/{py_moose => core}/test_streamer.py | 0 .../test_pymoose_2.py => core/test_suit1.py} | 23 +- .../{py_moose => core}/test_switch_solvers.py | 0 tests/core/test_synapse.py | 113 + tests/{py_moose => core}/test_synchan.py | 23 +- .../test_table_streaming_support.py | 6 +- tests/core/test_vec.py | 35 + tests/data/reaction.g | 76 + tests/profiling/profile.py | 23 + tests/py_moose/test_expr_parser.py | 349 -- tests/py_moose/test_moose_attribs.py | 65 - tests/py_moose/test_pymoose_1.py | 242 -- tests/py_moose/test_vec.py | 10 - .../Na_Chan_Migliore2018_.py | 0 .../chem/CICRspineDend.g | 0 .../chem/CICRwithConcChan.g | 0 .../chem/chanPhosph3compt.g | 0 .../chem/chanPhosphByCaMKII.g | 0 .../chem/psd52.g | 0 .../chem/psd53_old.g | 0 .../test_1_minimalModel.py | 2 +- .../test_20_currentPulse.py | 1 + .../test_21_vclamp.py | 0 .../test_30_squid_currentPulse.py | 0 .../test_32_squid_axon_propgn.py | 0 .../test_41_ballAndStick.py | 0 .../test_51_periodic_syn_input.py | 0 .../test_6_chem_osc.py | 0 .../test_72_CICR.py | 0 .../test_74_travelling_osc.py | 0 .../test_76_func_func_control_reac_rates.py | 0 .../test_rdes_with_func_proto.py | 0 tests/support/test_kkit.py | 32 + tests/support/test_neuroml2.py | 2 +- tests/support/test_sbml.py | 37 +- utility/CMakeLists.txt | 8 + utility/numutil.cpp | 4 +- utility/strutil.cpp | 238 +- utility/strutil.h | 171 +- utility/test_util.cpp | 34 + utility/testing_macros.hpp | 16 +- 300 files changed, 46180 insertions(+), 13999 deletions(-) create mode 100644 .clang-format delete mode 100644 basecode/consts.cpp create mode 100644 basecode/testGlobals.cpp create mode 100644 devel/Doxyfile.in rename {tests/py_moose => devel/fixme}/test_docs.py (90%) rename {tests/py_moose => devel/fixme}/test_function_namedvars.py (100%) rename {tests/py_moose => devel/fixme}/test_wrapper.py (100%) create mode 100644 external/CMakeLists.txt create mode 100644 external/fmt/CMakeLists.txt create mode 100644 external/fmt/include/fmt/chrono.h create mode 100644 external/fmt/include/fmt/color.h create mode 100644 external/fmt/include/fmt/compile.h create mode 100644 external/fmt/include/fmt/core.h create mode 100644 external/fmt/include/fmt/format-inl.h create mode 100644 external/fmt/include/fmt/format.h create mode 100644 external/fmt/include/fmt/locale.h create mode 100644 external/fmt/include/fmt/os.h create mode 100644 external/fmt/include/fmt/ostream.h create mode 100644 external/fmt/include/fmt/posix.h create mode 100644 external/fmt/include/fmt/printf.h create mode 100644 external/fmt/include/fmt/ranges.h create mode 100644 external/fmt/src/format.cc create mode 100644 external/fmt/src/os.cc create mode 100644 external/pybind11/.appveyor.yml create mode 100644 external/pybind11/.gitignore create mode 100644 external/pybind11/.gitmodules create mode 100644 external/pybind11/.readthedocs.yml create mode 100644 external/pybind11/.travis.yml create mode 100644 external/pybind11/CMakeLists.txt create mode 100644 external/pybind11/CONTRIBUTING.md create mode 100644 external/pybind11/ISSUE_TEMPLATE.md create mode 100644 external/pybind11/LICENSE create mode 100644 external/pybind11/MANIFEST.in create mode 100644 external/pybind11/README.md create mode 100644 external/pybind11/include/pybind11/attr.h create mode 100644 external/pybind11/include/pybind11/buffer_info.h create mode 100644 external/pybind11/include/pybind11/cast.h create mode 100644 external/pybind11/include/pybind11/chrono.h create mode 100644 external/pybind11/include/pybind11/common.h create mode 100644 external/pybind11/include/pybind11/complex.h create mode 100644 external/pybind11/include/pybind11/detail/class.h create mode 100644 external/pybind11/include/pybind11/detail/common.h create mode 100644 external/pybind11/include/pybind11/detail/descr.h create mode 100644 external/pybind11/include/pybind11/detail/init.h create mode 100644 external/pybind11/include/pybind11/detail/internals.h create mode 100644 external/pybind11/include/pybind11/detail/typeid.h create mode 100644 external/pybind11/include/pybind11/eigen.h create mode 100644 external/pybind11/include/pybind11/embed.h create mode 100644 external/pybind11/include/pybind11/eval.h create mode 100644 external/pybind11/include/pybind11/functional.h create mode 100644 external/pybind11/include/pybind11/iostream.h create mode 100644 external/pybind11/include/pybind11/numpy.h create mode 100644 external/pybind11/include/pybind11/operators.h create mode 100644 external/pybind11/include/pybind11/options.h create mode 100644 external/pybind11/include/pybind11/pybind11.h create mode 100644 external/pybind11/include/pybind11/pytypes.h create mode 100644 external/pybind11/include/pybind11/stl.h create mode 100644 external/pybind11/include/pybind11/stl_bind.h create mode 100644 external/pybind11/pybind11/__init__.py create mode 100644 external/pybind11/pybind11/__main__.py create mode 100644 external/pybind11/pybind11/_version.py create mode 100644 external/pybind11/setup.cfg create mode 100644 external/pybind11/setup.py create mode 100644 external/pybind11/tools/FindCatch.cmake create mode 100644 external/pybind11/tools/FindEigen3.cmake create mode 100644 external/pybind11/tools/FindPythonLibsNew.cmake create mode 100755 external/pybind11/tools/check-style.sh create mode 100644 external/pybind11/tools/libsize.py create mode 100644 external/pybind11/tools/pybind11Config.cmake.in create mode 100644 external/pybind11/tools/pybind11Tools.cmake delete mode 100644 mpi/proc.cpp delete mode 100644 mpi/proc1.cpp delete mode 100644 mpi/proc2.cpp delete mode 100644 mpi/proc3.cpp delete mode 100644 mpi/proc4.cpp delete mode 100644 mpi/proc5.cpp create mode 100644 pybind11/CMakeLists.txt create mode 100644 pybind11/Finfo.cpp create mode 100644 pybind11/Finfo.h create mode 100644 pybind11/MooseVec.cpp create mode 100644 pybind11/MooseVec.h create mode 100644 pybind11/PyRun.cpp create mode 100644 pybind11/PyRun.h create mode 100644 pybind11/helper.cpp create mode 100644 pybind11/helper.h create mode 100644 pybind11/pymoose.cpp create mode 100644 pybind11/pymoose.h create mode 100644 pymoose/__init__.py rename {python/moose => pymoose}/moose.py (100%) create mode 100644 python/moose/moose_legacy.py rename python/moose/{moose_test.py => tests.py} (98%) delete mode 100644 python/moose/wrapper.py create mode 100644 randnum/randnum.cpp create mode 100644 randnum/randnum.h create mode 100644 tests/CMakeLists.txt create mode 100644 tests/benchmarks/load_module.py create mode 100755 tests/benchmarks/micro_benchmark.sh rename tests/{py_moose => core}/OSC_diff_vols.g (100%) rename tests/{py_moose => core}/benchmark.py (100%) rename tests/{py_moose => core}/chan_proto.py (100%) rename tests/{py_moose => core}/models.py (100%) rename tests/{py_moose => core}/param_chan.py (100%) rename tests/{py_moose => core}/params.py (100%) rename tests/{py_moose => core}/run_mumble.sh (100%) rename tests/{py_moose => core}/soma.p (100%) rename tests/{py_moose => core}/streamer.py (100%) rename tests/{py_moose => core}/test_GraupnerBrunel2012_STDPfromCaPlasticity.py (99%) rename tests/{py_moose => core}/test_Xchan1.py (55%) rename tests/{py_moose => core}/test_Xdiff1.py (100%) rename tests/{py_moose => core}/test_Xenz1.py (100%) rename tests/{py_moose => core}/test_Xreacs2.py (84%) rename tests/{py_moose => core}/test_Xreacs3.py (99%) rename tests/{py_moose => core}/test_Xreacs4.py (99%) rename tests/{py_moose => core}/test_Xreacs4a.py (99%) rename tests/{py_moose => core}/test_Xreacs5.py (99%) rename tests/{py_moose => core}/test_Xreacs5a.py (99%) rename tests/{py_moose => core}/test_Xreacs6.py (98%) rename tests/{py_moose => core}/test_Xreacs7.py (100%) rename tests/{py_moose => core}/test_Xreacs8.py (99%) rename tests/{py_moose => core}/test_accessing_existing_paths.py (100%) create mode 100644 tests/core/test_api.py rename tests/{py_moose => core}/test_connectionLists.py (98%) rename tests/{py_moose => core}/test_cylinder_diffusion_gsolve+dsolve.py (100%) rename tests/{py_moose => core}/test_difshells.py (98%) create mode 100644 tests/core/test_doctests.py rename tests/{py_moose => core}/test_dose_response.py (100%) create mode 100644 tests/core/test_expr_parser.py rename tests/{py_moose => core}/test_function.py (99%) create mode 100644 tests/core/test_function_change_expr.py rename tests/{py_moose => core}/test_function_chemsys.py (100%) rename tests/{py_moose => core}/test_function_controls_reac_rate.py (94%) create mode 100644 tests/core/test_function_example.py rename tests/{py_moose => core}/test_gsolve_parallel.py (100%) rename tests/{py_moose => core}/test_hsolve_externalCalcium.py (100%) rename tests/{py_moose => core}/test_kkit.py (74%) rename tests/{py_moose => core}/test_ksolve.py (100%) rename tests/{py_moose => core}/test_ksolve_parallel.py (86%) create mode 100644 tests/core/test_metaclass.py create mode 100644 tests/core/test_moose_attribs.py rename tests/{py_moose => core}/test_moose_paths.py (80%) rename tests/{py_moose => core}/test_negative_value_flag.py (93%) create mode 100644 tests/core/test_pyrun.py rename tests/{py_moose => core}/test_random_gen.sh (100%) rename tests/{py_moose => core}/test_random_num.py (100%) rename tests/{py_moose => core}/test_rdesigneur.py (96%) rename tests/{py_moose => core}/test_rdesigneur_random_syn_input.py (100%) rename tests/{py_moose => core}/test_steady_state_solver.py (100%) rename tests/{py_moose => core}/test_streamer.py (100%) rename tests/{py_moose/test_pymoose_2.py => core/test_suit1.py} (58%) rename tests/{py_moose => core}/test_switch_solvers.py (100%) create mode 100644 tests/core/test_synapse.py rename tests/{py_moose => core}/test_synchan.py (76%) rename tests/{py_moose => core}/test_table_streaming_support.py (97%) create mode 100644 tests/core/test_vec.py create mode 100644 tests/data/reaction.g create mode 100644 tests/profiling/profile.py delete mode 100644 tests/py_moose/test_expr_parser.py delete mode 100644 tests/py_moose/test_moose_attribs.py delete mode 100644 tests/py_moose/test_pymoose_1.py delete mode 100644 tests/py_moose/test_vec.py rename tests/{py_rdesigneur => rdesigneur}/Na_Chan_Migliore2018_.py (100%) rename tests/{py_rdesigneur => rdesigneur}/chem/CICRspineDend.g (100%) rename tests/{py_rdesigneur => rdesigneur}/chem/CICRwithConcChan.g (100%) rename tests/{py_rdesigneur => rdesigneur}/chem/chanPhosph3compt.g (100%) rename tests/{py_rdesigneur => rdesigneur}/chem/chanPhosphByCaMKII.g (100%) rename tests/{py_rdesigneur => rdesigneur}/chem/psd52.g (100%) rename tests/{py_rdesigneur => rdesigneur}/chem/psd53_old.g (100%) rename tests/{py_rdesigneur => rdesigneur}/test_1_minimalModel.py (97%) rename tests/{py_rdesigneur => rdesigneur}/test_20_currentPulse.py (95%) rename tests/{py_rdesigneur => rdesigneur}/test_21_vclamp.py (100%) rename tests/{py_rdesigneur => rdesigneur}/test_30_squid_currentPulse.py (100%) rename tests/{py_rdesigneur => rdesigneur}/test_32_squid_axon_propgn.py (100%) rename tests/{py_rdesigneur => rdesigneur}/test_41_ballAndStick.py (100%) rename tests/{py_rdesigneur => rdesigneur}/test_51_periodic_syn_input.py (100%) rename tests/{py_rdesigneur => rdesigneur}/test_6_chem_osc.py (100%) rename tests/{py_rdesigneur => rdesigneur}/test_72_CICR.py (100%) rename tests/{py_rdesigneur => rdesigneur}/test_74_travelling_osc.py (100%) rename tests/{py_rdesigneur => rdesigneur}/test_76_func_func_control_reac_rates.py (100%) rename tests/{py_rdesigneur => rdesigneur}/test_rdes_with_func_proto.py (100%) create mode 100644 tests/support/test_kkit.py create mode 100644 utility/test_util.cpp diff --git a/.ci/travis_prepare_osx.sh b/.ci/travis_prepare_osx.sh index d706e68bb9..1f51344452 100755 --- a/.ci/travis_prepare_osx.sh +++ b/.ci/travis_prepare_osx.sh @@ -45,3 +45,4 @@ $PYTHON3 -m pip install matplotlib --user --upgrade $PYTHON3 -m pip install pyNeuroML libNeuroML --user $PYTHON3 -m pip install scipy --user $PYTHON3 -m pip install pylint --user +$PYTHON3 -m pip install pytest --user diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000..5e9fd52108 --- /dev/null +++ b/.clang-format @@ -0,0 +1,49 @@ +--- +AccessModifierOffset: -4 +SortIncludes: false +ConstructorInitializerIndentWidth: 4 +AlignEscapedNewlinesLeft: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakTemplateDeclarations: true +AlwaysBreakBeforeMultilineStrings: true +BreakBeforeBinaryOperators: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BinPackParameters: true +ColumnLimit: 80 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +DerivePointerBinding: true +ExperimentalAutoDetectBinPacking: false +IndentCaseLabels: true +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCSpaceBeforeProtocolList: false +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 60 +PenaltyBreakString: 1000 +PenaltyBreakFirstLessLess: 120 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerBindsToType: true +SpacesBeforeTrailingComments: 2 +Cpp11BracedListStyle: true +Standard: Auto +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +BreakBeforeBraces: Stroustrup +IndentFunctionDeclarationAfterType: true +SpacesInParentheses: false +SpacesInAngles: false +SpaceInEmptyParentheses: false +SpacesInCStyleCastParentheses: false +SpaceAfterControlStatementKeyword: false +SpaceBeforeAssignmentOperators: true +ContinuationIndentWidth: 4 +Standard : C++11 +... + diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 26e6d1cf43..57aab96469 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,6 +17,12 @@ build: - python3 -m pip install python-libsbml --user --upgrade - python3 -m pip install pyneuroml --user --upgrade - python3 -m pip install sympy scipy --user --upgrade + - python3 -m pip install pytest --user --upgrade - python3 setup.py build test - python3 setup.py install --user - - python3 -c "import moose; moose.test()" + - python3 -c "import moose.tests; moose.tests.test()" + + except: + - pybind11 + - devel + diff --git a/CMakeLists.txt b/CMakeLists.txt index d373ed2609..d3ce946992 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8 FATAL_ERROR) +cmake_minimum_required(VERSION 3.2.3 FATAL_ERROR) # Project to build MOOSE's python module. project(PyMOOSE) @@ -18,11 +18,7 @@ if(NOT PYTHONINTERP_FOUND) find_package(PythonInterp 2.7) endif() -# Disable rpath on OSX. -if(APPLE) - set(CMAKE_MACOSX_RPATH OFF) -endif() - +set(CMAKE_MACOSX_RPATH OFF) # NOTE: version should be changed in setup.py file. # If moose version is not given, use setup.py file to get the default version. @@ -55,19 +51,20 @@ if( CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE ) endif() ################################ CMAKE OPTIONS ################################## -option(WITH_NSDF "Enable NSDF support. Requires hdf5" OFF ) - option(DEBUG "Build with debug support" OFF) option(GPROF "Build for profiling using gprof" OFF) option(ENABLE_UNIT_TESTS "Enable unit tests (DEBUG should also be ON)" OFF) option(WITH_MPI "Enable Openmpi support" OFF) + option(WITH_BOOST "Enable boost. Prefer boost over stl" OFF) option(WITH_BOOST_ODE "Use boost library ode2 library instead of GSL" OFF) option(WITH_GSL "Use gsl-library. Alternative is WITH_BOOST" ON) -option(PARALLELIZED_CLOCK "High level parallelization of moose::Clock (alpha)" OFF ) -option(USE_PRIVATE_RNG "Stochastic Objects use their private RNG" ON) + option(WITH_ASAN "Use AddressSanitizer in DEBUG mode." OFF) +option(WITH_NSDF "Enable NSDF support. Requires hdf5" OFF ) + +option(WITH_LEGACY_BINDING "Use legacy python-bindings" OFF) ############################ BUILD CONFIGURATION ################################# @@ -102,10 +99,8 @@ if(WITH_ASAN AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=address") endif() -if(WITH_GSL) - set(WITH_BOOST OFF) - set(WITH_BOOST_ODE OFF) -elseif(WITH_BOOST) +# Override default GSL solvers when BOOST is enabled. +if(WITH_BOOST OR WITH_BOOST_ODE) set(WITH_BOOST_ODE ON) set(WITH_GSL OFF) endif() @@ -114,19 +109,16 @@ endif() link_directories(${CMAKE_BINARY_DIR}) add_library(libmoose SHARED basecode/main.cpp) +set_target_properties(libmoose PROPERTIES PREFIX "") add_executable(moose.bin basecode/main.cpp) ################################### SETUP BUILD ################################ -# default include paths. -include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ) -set_target_properties(libmoose PROPERTIES COMPILE_DEFINITIONS "MOOSE_LIB") -set_target_properties(libmoose PROPERTIES PREFIX "") -## Variable to collect all static libraries. +# Variable to collect all static libraries. set(STATIC_LIBRARIES "" ) # Collect all shared libraries here. -set(SYSTEM_SHARED_LIBS ${LibXML2_LIBRARIES}) +set(SYSTEM_SHARED_LIBS "") # BOOST ode library performs better than GSL and ideally should be made default. # Unfortunately Boost does not have a very good matrix library; it has ublas @@ -231,7 +223,7 @@ add_subdirectory(device) add_subdirectory(kinetics) add_subdirectory(synapse) add_subdirectory(intfire) -add_subdirectory(external/libsoda) +add_subdirectory(external) # development related. add_subdirectory(devel) @@ -271,7 +263,7 @@ endif( ) # especially section 'Mac OS X and the RPATH' # Switching is OFF since all libraries are statically linked in module. if(APPLE) - set_target_properties( libmoose PROPERTIES MACOSX_RPATH OFF) + set_target_properties(libmoose PROPERTIES MACOSX_RPATH OFF) endif(APPLE) # MAC linker does not understand many of gnu-ld options. @@ -304,12 +296,16 @@ if( WITH_BOOST ) target_link_libraries( moose.bin ${Boost_LIBRARIES} ) endif( WITH_BOOST ) - ######################### BUILD PYMOOSE ######################################## +if(NOT WITH_LEGACY_BINDING) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/pybind11) + add_subdirectory(pybind11) +else() + message(STATUS "Building legacy python binding.") + add_subdirectory(pymoose) +endif() -# This target is built by pymoose/CMakeLists.txt file. -add_subdirectory(pymoose) # always override debian default installation directory. It will be installed in # site-packages instead of dist-packages. @@ -338,9 +334,6 @@ endif() install(TARGETS moose.bin DESTINATION bin CONFIGURATIONS Debug) install(TARGETS libmoose DESTINATION lib CONFIGURATIONS Debug) -# NOTE: Install macro for _moose (pymoose) has been moved to -# pymoose/CMakeLists.txt file. - # Print message to start build process if(${CMAKE_BUILD_TOOL} MATCHES "make") message( @@ -353,123 +346,8 @@ endif() ############################ CTEST ###################################### -include( CTest ) -set(CTEST_NIGHTLY_START_TIME "05:30:00 UTC") -set(CTEST_SUBMIT_URL "http://my.cdash.org/submit.php?project=moose") - -if(DEBUG OR "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - # Run this test in debug mode. In Release mode, this does not do anything. - set(MOOSE_BIN_LOCATION $) - message(STATUS "Executable moose.bin will be at ${MOOSE_BIN_LOCATION}" ) - - add_test(NAME moose.bin-raw-run COMMAND moose.bin -u -q) -endif() - -# Core tests. -set(PYMOOSE_TEST_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/py_moose) -file(GLOB PY_TEST_SCRIPTS "${PYMOOSE_TEST_DIRECTORY}/test_*.py" ) -foreach(_test_script ${PY_TEST_SCRIPTS} ) - get_filename_component(_name_we ${_test_script} NAME_WE) - set(_test_name "core_${_name_we}") - add_test(NAME ${_test_name} - COMMAND ${PYTHON_EXECUTABLE} ${_test_script} - WORKING_DIRECTORY ${PYMOOSE_TEST_DIRECTORY}) - set_tests_properties(${_test_name} - PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/python" - ) -endforeach() - -# Tests for supported formats such as neuroml, sbml etc. -set(SUPPORT_TEST_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/support) -file(GLOB PY_TEST_SCRIPTS "${SUPPORT_TEST_DIRECTORY}/test_*.py" ) -foreach(_test_script ${PY_TEST_SCRIPTS} ) - get_filename_component(_name_we ${_test_script} NAME_WE) - set(_test_name "support_${_name_we}") - add_test(NAME ${_test_name} - COMMAND ${PYTHON_EXECUTABLE} ${_test_script} - WORKING_DIRECTORY ${SUPPORT_TEST_DIRECTORY}) - set_tests_properties(${_test_name} - PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/python" - ) -endforeach() - -# rdesigneur tests. These tests require matplotlib. -set(RDES_TEST_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/py_rdesigneur) -file(GLOB RDES_TEST_SCRIPTS "${RDES_TEST_DIRECTORY}/test_*.py" ) -foreach(_test_script ${RDES_TEST_SCRIPTS}) - get_filename_component(_name_we ${_test_script} NAME_WE) - set(_test_name "rdes_${_name_we}") - add_test(NAME ${_test_name} - COMMAND ${PYTHON_EXECUTABLE} ${_test_script} - WORKING_DIRECTORY ${RDES_TEST_DIRECTORY} - ) - set_tests_properties(${_test_name} PROPERTIES - ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/python;MOOSE_NUM_THREADS=4" - ) -endforeach() - -# FIXME TESTS. These should not run by default. We need to fix them. -set(PYMOOSE_FIXME_TEST_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/devel/fixme) -file(GLOB PY_FIXME_TEST_SCRIPTS "${PYMOOSE_FIXME_TEST_DIRECTORY}/*.py" ) -foreach( _test_script ${PY_FIXME_TEST_SCRIPTS} ) - get_filename_component( _name_we ${_test_script} NAME_WE) - set(_test_name "alpha_${_name_we}") - add_test( NAME ${_test_name} - COMMAND ${PYTHON_EXECUTABLE} ${_test_script} - CONFIGURATIONS alpha - WORKING_DIRECTORY ${PYMOOSE_ALPHA_TEST_DIRECTORY} - ) - set_tests_properties( ${_test_name} - PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/python" - ) -endforeach( ) - -# Regression and github issues. These should not run by default. -set(PYMOOSE_ISSUES_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/devel/issues) -file(GLOB PY_ISSUES_SCRIPTS "${PYMOOSE_ISSUES_DIRECTORY}/*.py" ) -foreach(_test_script ${PY_ISSUES_SCRIPTS}) - get_filename_component( _test_name ${_test_script} NAME_WE) - add_test(NAME ${_test_name} - COMMAND ${PYTHON_EXECUTABLE} ${_test_script} - CONFIGURATIONS Devel - WORKING_DIRECTORY ${PYMOOSE_ISSUES_DIRECTORY} - ) - set_tests_properties(${_test_name} - PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/python" - ) -endforeach() - -################################# COVERAGE ################################### - -add_custom_target(coverage) -set(PYTEST_TEST_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests) -file(GLOB_RECURSE PYTEST_TEST_SCRIPTS ${PYTEST_TEST_DIRECTORY}/test_*.py) - -foreach(_test_script ${PYTEST_TEST_SCRIPTS}) - get_filename_component(_name_we ${_test_script} NAME_WE) - set(_test_name "pytest_${_name_we}") - # message(STATUS "Adding test ${_test_name}") - add_custom_target(${_test_name} - # We collect coverage data but do not show report during each test. - # We show report at the end of all tests. Set `--cov-report=` - COMMAND ${PYTHON_EXECUTABLE} -m pytest - --cov=moose --cov=rdesigneur --cov-append --cov-report= - ${_test_script} - DEPENDS _moose - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Executing ${_test_script} using pytest" - VERBATIM) - add_dependencies(coverage ${_test_name}) -endforeach() - -# Generate report at the end. -add_custom_command(TARGET coverage POST_BUILD - COMMAND ${PYTHON_EXECUTABLE} -m coverage report - COMMAND ${PYTHON_EXECUTABLE} -m coverage html - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Genearting coverage report" - VERBATIM) - +include(CTest) +add_subdirectory(tests) ########################### RELEASE ######################################### set(PYMOOSE_SDIST_FILE ${CMAKE_BINARY_DIR}/pymoose-${VERSION_MOOSE}.tar.gz) @@ -519,3 +397,17 @@ foreach(_py_script ${PY_SCRIPTS}) add_dependencies(pylint ${TGT_NAME} ) endforeach( ) +######################## DOCS ############################################### +find_package(Doxygen) +if(DOXYGEN_FOUND) + set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/devel/Doxyfile.in) + set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) + configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY) + add_custom_target(doc + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation using Doxygen." + VERBATIM) +else() + message(STATUS "Doxygen needs to be installed to generate API docs") +endif() diff --git a/CheckCXXCompiler.cmake b/CheckCXXCompiler.cmake index 5b1e75961c..f6661fa179 100644 --- a/CheckCXXCompiler.cmake +++ b/CheckCXXCompiler.cmake @@ -1,5 +1,5 @@ # Compiler check. -# Must support c++11 +# Must support c++14 # If python2 is supported then we can not use c++17. if(COMPILER_IS_TESTED) return() @@ -20,12 +20,11 @@ add_definitions(-Wall ) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - # gcc-4.9.0 has regex supports though moose will compile with 4.8.x; - # won't work. if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9") message(FATAL_ERROR "Insufficient gcc version. Minimum requried 4.9") endif() add_definitions( -Wno-unused-local-typedefs ) + add_definitions( -fmax-errors=5 ) elseif(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")) add_definitions( -Wno-unused-local-typedef ) endif() @@ -50,7 +49,7 @@ if(COMPILER_SUPPORTS_CXX11) endif(APPLE) else(COMPILER_SUPPORTS_CXX11) message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} is too old. \n" - "Please use a compiler which has c++11 support." + "Please use a compiler which has full c++11 support." ) endif(COMPILER_SUPPORTS_CXX11) diff --git a/MANIFEST.in b/MANIFEST.in index c0378e2a24..d71333ee95 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -34,3 +34,5 @@ recursive-include signeur * recursive-include synapse * recursive-include tests * recursive-include utility * +recursive-include pybind11 * +recursive-include devel * diff --git a/basecode/CMakeLists.txt b/basecode/CMakeLists.txt index c166bfd267..e65f4176b0 100644 --- a/basecode/CMakeLists.txt +++ b/basecode/CMakeLists.txt @@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 2.8) include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake ) add_library(basecode - consts.cpp Element.cpp DataElement.cpp GlobalDataElement.cpp @@ -26,3 +25,9 @@ add_library(basecode doubleEq.cpp testAsync.cpp ) + +add_executable(test_globals testGlobals.cpp global.cpp) + +enable_testing() +add_test(NAME cpp_test_globals COMMAND $) + diff --git a/basecode/Cinfo.cpp b/basecode/Cinfo.cpp index cbbe2eb242..c4217337d1 100644 --- a/basecode/Cinfo.cpp +++ b/basecode/Cinfo.cpp @@ -1,76 +1,86 @@ /********************************************************************** -** This program is part of 'MOOSE', the -** Messaging Object Oriented Simulation Environment, -** also known as GENESIS 3 base code. -** copyright (C) 2003-2013 Upinder S. Bhalla. and NCBS -** It is made available under the terms of the -** GNU Lesser General Public License version 2.1 -** See the file COPYING.LIB for the full notice. -**********************************************************************/ + * This program is part of 'MOOSE', the + * Messaging Object Oriented Simulation Environment, + * also known as GENESIS 3 base code. + * copyright (C) 2003-2013 Upinder S. Bhalla. and NCBS + * It is made available under the terms of the + * GNU Lesser General Public License version 2.1 + * See the file COPYING.LIB for the full notice. + **********************************************************************/ + #include "header.h" +#include "Finfo.h" #include "../shell/Shell.h" #include "Dinfo.h" +#include + // Static declaration. unsigned int Cinfo::numCoreOpFunc_ = 0; -Cinfo::Cinfo( const string& name, - const Cinfo* baseCinfo, - Finfo** finfoArray, - unsigned int nFinfos, - DinfoBase* d, - const string* doc, - unsigned int numDoc, - bool banCreation -) - : name_( name ), baseCinfo_( baseCinfo ), dinfo_( d ), - numBindIndex_( 0 ), banCreation_( banCreation ) -{ - if ( cinfoMap().find( name ) != cinfoMap().end() ) { - cout << "Warning: Duplicate Cinfo name " << name << endl; - } - init( finfoArray, nFinfos ); - cinfoMap()[ name ] = this; - doc_.clear(); - -#if VERBOSITY > 2 - cerr << setw(VERBOSITY) << "Doing initCinfo for " << name << " with numDoc = " << numDoc << endl; -#endif /* ----- not DEBUG ----- */ - if ( doc && numDoc ) { - for ( unsigned int i = 0; i < numDoc - 1; i += 2 ) { - const string argName = doc[i]; - const string argVal = doc[i+1]; - // cout << "in initCinfo for " << name << ", doc[" << i << "] = " << doc[i] << ", " << doc[i+1] << endl; - // doc_[ doc[i] ] = doc[i+i]; - doc_[ argName ] = argVal; - } - } +Cinfo::Cinfo(const string& name, const Cinfo* baseCinfo, Finfo** finfoArray, + unsigned int nFinfos, DinfoBase* d, const string* doc, + unsigned int numDoc, bool banCreation) + : name_(name), + baseCinfo_(baseCinfo), + dinfo_(d), + numBindIndex_(0), + banCreation_(banCreation) +{ + if(cinfoMap().find(name) != cinfoMap().end()) { + cout << "Warning: Duplicate Cinfo name " << name << endl; + } + init(finfoArray, nFinfos); + cinfoMap()[name] = this; + doc_.clear(); + if(doc && numDoc) { + for(unsigned int i = 0; i < numDoc - 1; i += 2) { + const string argName = doc[i]; + const string argVal = doc[i + 1]; + // cout << "in initCinfo for " << name << ", doc[" << i << "] = " << + // doc[i] << ", " << doc[i+1] << endl; + // doc_[ doc[i] ] = doc[i+i]; + doc_[argName] = argVal; + } + } } Cinfo::Cinfo() - : name_( "dummy" ), baseCinfo_( 0 ), dinfo_( 0 ), - numBindIndex_( 0 ), banCreation_( false ) -{;} + : name_("dummy"), + baseCinfo_(0), + dinfo_(0), + numBindIndex_(0), + banCreation_(false) +{ + ; +} -Cinfo::Cinfo( const Cinfo& other ) - : name_( "dummy" ), baseCinfo_( 0 ), dinfo_( 0 ), - numBindIndex_( 0 ), banCreation_( false ) -{;} +Cinfo::Cinfo(const Cinfo& other) + : name_("dummy"), + baseCinfo_(0), + dinfo_(0), + numBindIndex_(0), + banCreation_(false) +{ + ; +} /* const Cinfo& Cinfo::operator=( const Cinfo& other ) { - name_ = other.name_; - baseCinfo_ = other.baseCinfo_; - dinfo_ = 0; - numBindIndex_ = other.numBindIndex_; - doc_ = doc_; - finfoMap_ = other + name_ = other.name_; + baseCinfo_ = other.baseCinfo_; + dinfo_ = 0; + numBindIndex_ = other.numBindIndex_; + doc_ = doc_; + finfoMap_ = other } */ Cinfo::~Cinfo() -{;} // The dinfos are statically allocated, we don't free them. +{ + ; +} // The dinfos are statically allocated, we don't free them. //////////////////////////////////////////////////////////////////// // Initialization funcs @@ -79,169 +89,208 @@ Cinfo::~Cinfo() /** * init: initializes the Cinfo. Must be called just once */ -void Cinfo::init( Finfo** finfoArray, unsigned int nFinfos ) -{ - if ( baseCinfo_ ) { - // Copy over base Finfos. - numBindIndex_ = baseCinfo_->numBindIndex_; - finfoMap_ = baseCinfo_->finfoMap_; - funcs_ = baseCinfo_->funcs_; - postCreationFinfos_ = baseCinfo_->postCreationFinfos_; - } - for ( unsigned int i = 0; i < nFinfos; i++ ) { - registerFinfo( finfoArray[i] ); - } +void Cinfo::init(Finfo** finfoArray, unsigned int nFinfos) +{ + if(baseCinfo_) { + // Copy over base Finfos. + numBindIndex_ = baseCinfo_->numBindIndex_; + finfoMap_ = baseCinfo_->finfoMap_; + funcs_ = baseCinfo_->funcs_; + postCreationFinfos_ = baseCinfo_->postCreationFinfos_; + } + for(unsigned int i = 0; i < nFinfos; i++) { + registerFinfo(finfoArray[i]); + } } -FuncId Cinfo::registerOpFunc( const OpFunc* f ) +FuncId Cinfo::registerOpFunc(const OpFunc* f) { - FuncId ret = funcs_.size(); - funcs_.push_back( f ); - return ret; + FuncId ret = funcs_.size(); + funcs_.push_back(f); + return ret; } -void Cinfo::overrideFunc( FuncId fid, const OpFunc* f ) +void Cinfo::overrideFunc(FuncId fid, const OpFunc* f) { - assert ( funcs_.size() > fid ); - funcs_[ fid ] = f; + assert(funcs_.size() > fid); + funcs_[fid] = f; } BindIndex Cinfo::registerBindIndex() { - return numBindIndex_++; + return numBindIndex_++; } -void Cinfo::registerFinfo( Finfo* f ) +void Cinfo::registerFinfo(Finfo* f) { - finfoMap_[ f->name() ] = f; - f->registerFinfo( this ); - if ( dynamic_cast< DestFinfo* >( f ) ) { - destFinfos_.push_back( f ); - } - else if ( dynamic_cast< SrcFinfo* >( f ) ) { - srcFinfos_.push_back( f ); - } - else if ( dynamic_cast< ValueFinfoBase* >( f ) ) { - valueFinfos_.push_back( f ); - } - else if ( dynamic_cast< LookupValueFinfoBase* >( f ) ) { - lookupFinfos_.push_back( f ); - } - else if ( dynamic_cast< SharedFinfo* >( f ) ) { - sharedFinfos_.push_back( f ); - } - else if ( dynamic_cast< FieldElementFinfoBase* >( f ) ) { - fieldElementFinfos_.push_back( f ); - } + finfoMap_[f->name()] = f; + f->registerFinfo(this); + if(dynamic_cast(f)) { + destFinfos_.push_back(f); + } + else if(dynamic_cast(f)) { + srcFinfos_.push_back(f); + } + else if(dynamic_cast(f)) { + valueFinfos_.push_back(f); + } + else if(dynamic_cast(f)) { + lookupFinfos_.push_back(f); + } + else if(dynamic_cast(f)) { + sharedFinfos_.push_back(f); + } + else if(dynamic_cast(f)) { + fieldElementFinfos_.push_back(f); + } } -void Cinfo::registerPostCreationFinfo( const Finfo* f ) +/* --------------------------------------------------------------------------*/ +/** + * @Synopsis Finfo derived class, using `dynamic_cast` figure out. + * + * @Param f const Finfo* + * + * @Returns String representing the polymorphic type of Finfo. + */ +/* ----------------------------------------------------------------------------*/ +string Cinfo::getFinfoType(const Finfo* f) const { - postCreationFinfos_.push_back( f ); + if(dynamic_cast(f)) { + return "DestFinfo"; + } + else if(dynamic_cast(f)) { + return "SrcFinfo"; + } + else if(dynamic_cast(f)) { + return "ValueFinfo"; + } + else if(dynamic_cast(f)) { + return "LookupValueFinfo"; + } + else if(dynamic_cast(f)) { + return "SharedFinfo"; + } + else if(dynamic_cast(f)) { + return "FieldElementFinfo"; + } + return ""; } -void Cinfo::postCreationFunc( Id newId, Element* newElm ) const +void Cinfo::registerPostCreationFinfo(const Finfo* f) { - for ( vector< const Finfo* >::const_iterator i = - postCreationFinfos_.begin(); - i != postCreationFinfos_.end(); ++i ) - (*i)->postCreationFunc( newId, newElm ); + postCreationFinfos_.push_back(f); } -void buildFinfoElement( Id parent, vector< Finfo* >& f, const string& name ) +void Cinfo::postCreationFunc(Id newId, Element* newElm) const { - if ( f.size() > 0 ) { - char* data = reinterpret_cast< char* >( &f[0] ); - Id id = Id::nextId(); - Element* e = new GlobalDataElement( - id, Finfo::initCinfo(), name, f.size() ); - Finfo::initCinfo()->dinfo()->assignData( e->data( 0 ), f.size(), data, f.size()); - Shell::adopt( parent, id, 0 ); - } + for(vector::const_iterator i = postCreationFinfos_.begin(); + i != postCreationFinfos_.end(); ++i) + (*i)->postCreationFunc(newId, newElm); +} + +void buildFinfoElement(Id parent, vector& f, const string& name) +{ + if(f.size() > 0) { + char* data = reinterpret_cast(&f[0]); + Id id = Id::nextId(); + Element* e = + new GlobalDataElement(id, Finfo::initCinfo(), name, f.size()); + Finfo::initCinfo()->dinfo()->assignData(e->data(0), f.size(), data, + f.size()); + Shell::adopt(parent, id, 0); + } } // Static function called by init() -void Cinfo::makeCinfoElements( Id parent ) -{ - static Dinfo< Cinfo > dummy; - vector< unsigned int > dims( 1, 0 ); - - vector< Id > cinfoElements; - for ( map< string, Cinfo* >::iterator i = cinfoMap().begin(); - i != cinfoMap().end(); ++i ) { - Id id = Id::nextId(); - char* data = reinterpret_cast< char* >( i->second ); - Element* e = new GlobalDataElement( - id, Cinfo::initCinfo(), i->first ); - Cinfo::initCinfo()->dinfo()->assignData( e->data( 0 ), 1, data, 1 ); - // Cinfo* temp = reinterpret_cast< Cinfo* >( e->data( 0 ) ); - - Shell::adopt( parent, id, 0 ); - cinfoElements.push_back( id ); - // cout << "Cinfo::makeCinfoElements: parent= " << parent << ", Id = " << id << ", name = " << i->first << endl; - } - vector< Id >::iterator j = cinfoElements.begin(); - for ( map< string, Cinfo* >::iterator i = cinfoMap().begin(); - i != cinfoMap().end(); ++i ) { - buildFinfoElement( *j, i->second->srcFinfos_, "srcFinfo" ); - buildFinfoElement( *j, i->second->destFinfos_, "destFinfo" ); - buildFinfoElement( *j, i->second->valueFinfos_, "valueFinfo" ); - buildFinfoElement( *j, i->second->lookupFinfos_, "lookupFinfo" ); - buildFinfoElement( *j, i->second->sharedFinfos_, "sharedFinfo" ); - buildFinfoElement( *j, i->second->fieldElementFinfos_, "fieldElementFinfo" ); - j++; - } +void Cinfo::makeCinfoElements(Id parent) +{ + static Dinfo dummy; + vector dims(1, 0); + + vector cinfoElements; + for(map::iterator i = cinfoMap().begin(); + i != cinfoMap().end(); ++i) { + Id id = Id::nextId(); + char* data = reinterpret_cast(i->second); + Element* e = new GlobalDataElement(id, Cinfo::initCinfo(), i->first); + Cinfo::initCinfo()->dinfo()->assignData(e->data(0), 1, data, 1); + // Cinfo* temp = reinterpret_cast< Cinfo* >( e->data( 0 ) ); + + Shell::adopt(parent, id, 0); + cinfoElements.push_back(id); + // cout << "Cinfo::makeCinfoElements: parent= " << parent << ", Id = " + // << id << ", name = " << i->first << endl; + } + vector::iterator j = cinfoElements.begin(); + for(map::iterator i = cinfoMap().begin(); + i != cinfoMap().end(); ++i) { + buildFinfoElement(*j, i->second->srcFinfos_, "srcFinfo"); + buildFinfoElement(*j, i->second->destFinfos_, "destFinfo"); + buildFinfoElement(*j, i->second->valueFinfos_, "valueFinfo"); + buildFinfoElement(*j, i->second->lookupFinfos_, "lookupFinfo"); + buildFinfoElement(*j, i->second->sharedFinfos_, "sharedFinfo"); + buildFinfoElement(*j, i->second->fieldElementFinfos_, + "fieldElementFinfo"); + j++; + } } ////////////////////////////////////////////////////////////////////// // Look up operations. ////////////////////////////////////////////////////////////////////// -const Cinfo* Cinfo::find( const string& name ) +const Cinfo* Cinfo::find(const string& name) { - map::iterator i = cinfoMap().find(name); - if ( i != cinfoMap().end() ) - return i->second; - return 0; + map::iterator i = cinfoMap().find(name); + if(i != cinfoMap().end()) + return i->second; + return 0; } const Cinfo* Cinfo::baseCinfo() const { - return baseCinfo_; + return baseCinfo_; } /** * Looks up Finfo from name. */ -const Finfo* Cinfo::findFinfo( const string& name ) const +const Finfo* Cinfo::findFinfo(const string& name) const +{ + auto i = finfoMap_.find(name); + if(i != finfoMap_.end()) + return i->second; + return 0; +} + +const FinfoWrapper Cinfo::findFinfoWrapper(const string& name) const { - map< string, Finfo*>::const_iterator i = finfoMap_.find( name ); - if ( i != finfoMap_.end() ) - return i->second; - return 0; + return FinfoWrapper(findFinfo(name)); } bool Cinfo::banCreation() const { - return banCreation_; + return banCreation_; } /** * looks up OpFunc by FuncId */ -const OpFunc* Cinfo::getOpFunc( FuncId fid ) const { - if ( fid < funcs_.size () ) - return funcs_[ fid ]; - return 0; +const OpFunc* Cinfo::getOpFunc(FuncId fid) const +{ + if(fid < funcs_.size()) + return funcs_[fid]; + return 0; } /* FuncId Cinfo::getOpFuncId( const string& funcName ) const { - map< string, FuncId >::const_iterator i = opFuncNames_.find( funcName ); - if ( i != opFuncNames_.end() ) { - return i->second; - } - return 0; + map< string, FuncId >::const_iterator i = opFuncNames_.find( funcName ); + if ( i != opFuncNames_.end() ) { + return i->second; + } + return 0; } */ @@ -251,46 +300,46 @@ FuncId Cinfo::getOpFuncId( const string& funcName ) const { const std::string& Cinfo::name() const { - return name_; + return name_; } unsigned int Cinfo::numBindIndex() const { - return numBindIndex_; + return numBindIndex_; } -const map< string, Finfo* >& Cinfo::finfoMap() const +const map& Cinfo::finfoMap() const { - return finfoMap_; + return finfoMap_; } const DinfoBase* Cinfo::dinfo() const { - return dinfo_; + return dinfo_; } -bool Cinfo::isA( const string& ancestor ) const +bool Cinfo::isA(const string& ancestor) const { - if ( ancestor == "Neutral" ) return 1; - const Cinfo* base = this; - while( base && base != Neutral::initCinfo() ) { - if ( ancestor == base->name_ ) - return 1; - base = base->baseCinfo_; - } - return 0; + if(ancestor == "Neutral") + return true; + const Cinfo* base = this; + while(base && base != Neutral::initCinfo()) { + if(ancestor == base->name_) + return true; + base = base->baseCinfo_; + } + return false; } void Cinfo::reportFids() const { - for ( map< string, Finfo*>::const_iterator i = finfoMap_.begin(); - i != finfoMap_.end(); ++i ) { - const DestFinfo* df = dynamic_cast< const DestFinfo* >( - i->second ); - if ( df ) { - cout << df->getFid() << " " << df->name() << endl; - } - } + for(map::const_iterator i = finfoMap_.begin(); + i != finfoMap_.end(); ++i) { + const DestFinfo* df = dynamic_cast(i->second); + if(df) { + cout << df->getFid() << " " << df->name() << endl; + } + } } //////////////////////////////////////////////////////////////////////// @@ -298,17 +347,15 @@ void Cinfo::reportFids() const //////////////////////////////////////////////////////////////////////// map& Cinfo::cinfoMap() { - static map lookup_; - return lookup_; + static map lookup_; + return lookup_; } - - /* map< OpFunc, FuncId >& Cinfo::funcMap() { - static map< OpFunc, FuncId > lookup_; - return lookup_; + static map< OpFunc, FuncId > lookup_; + return lookup_; } */ @@ -318,74 +365,58 @@ map< OpFunc, FuncId >& Cinfo::funcMap() const Cinfo* Cinfo::initCinfo() { - ////////////////////////////////////////////////////////////// - // Field Definitions - ////////////////////////////////////////////////////////////// - static ReadOnlyValueFinfo< Cinfo, string > docs( - "docs", - "Documentation", - &Cinfo::getDocs - ); - - static ReadOnlyValueFinfo< Cinfo, string > baseClass( - "baseClass", - "Name of base class", - &Cinfo::getBaseClass - ); - - static string doc[] = - { - "Name", "Cinfo", - "Author", "Upi Bhalla", - "Description", "Class information object." - }; + ////////////////////////////////////////////////////////////// + // Field Definitions + ////////////////////////////////////////////////////////////// + static ReadOnlyValueFinfo docs("docs", "Documentation", + &Cinfo::getDocs); + + static ReadOnlyValueFinfo baseClass( + "baseClass", "Name of base class", &Cinfo::getBaseClass); + + static string doc[] = {"Name", "Cinfo", + "Author", "Upi Bhalla", + "Description", "Class information object."}; - static Finfo* cinfoFinfos[] = { - &docs, // ReadOnlyValue - &baseClass, // ReadOnlyValue - }; + static Finfo* cinfoFinfos[] = { + &docs, // ReadOnlyValue + &baseClass, // ReadOnlyValue + }; - static Dinfo< Cinfo > dinfo; - static Cinfo cinfoCinfo ( - "Cinfo", - Neutral::initCinfo(), - cinfoFinfos, - sizeof( cinfoFinfos ) / sizeof ( Finfo* ), - &dinfo, - doc, - sizeof(doc)/sizeof(string) - ); + static Dinfo dinfo; + static Cinfo cinfoCinfo("Cinfo", Neutral::initCinfo(), cinfoFinfos, + sizeof(cinfoFinfos) / sizeof(Finfo*), &dinfo, doc, + sizeof(doc) / sizeof(string)); - return &cinfoCinfo; + return &cinfoCinfo; } static const Cinfo* cinfoCinfo = Cinfo::initCinfo(); - /////////////////////////////////////////////////////////////////// // Field functions /////////////////////////////////////////////////////////////////// string Cinfo::getDocs() const { ostringstream doc; - for (map ::const_iterator ii = doc_.begin(); ii != doc_.end(); ++ii){ - doc << '\n' << ii->first << ":\t\t" << ii->second << endl; + for(auto ii = doc_.cbegin(); ii != doc_.cend(); ++ii) { + doc << endl + << std::setw(15) << std::left << ii->first << ": " << ii->second; } - return doc.str(); + return doc.str(); } - -static DestFinfo dummy( - "dummy", - "This Finfo is a dummy. If you are reading this you have used an invalid index", -0 ); +static DestFinfo dummy("dummy", + "This Finfo is a dummy. If you are reading this you " + "have used an invalid index", + 0); string Cinfo::getBaseClass() const { - if ( baseCinfo_ ) - return baseCinfo_->name(); - else - return "none"; + if(baseCinfo_) + return baseCinfo_->name(); + else + return "none"; } //////////////////////////////////////////////////////////////////// @@ -395,184 +426,185 @@ string Cinfo::getBaseClass() const // the indices of the new finfos, but I shouldn't be looking them up // by index anyway. //////////////////////////////////////////////////////////////////// -Finfo* Cinfo::getSrcFinfo( unsigned int i ) const -{ - if ( i >= getNumSrcFinfo() ) - return 0; - if ( baseCinfo_ ) { - if ( i >= baseCinfo_->getNumSrcFinfo() ) - return srcFinfos_[ i - baseCinfo_->getNumSrcFinfo() ]; - else - return baseCinfo_->getSrcFinfo( i ); - //return const_cast< Cinfo* >( baseCinfo_ )->getSrcFinfo( i ); - } +Finfo* Cinfo::getSrcFinfo(unsigned int i) const +{ + if(i >= getNumSrcFinfo()) + return 0; + if(baseCinfo_) { + if(i >= baseCinfo_->getNumSrcFinfo()) + return srcFinfos_[i - baseCinfo_->getNumSrcFinfo()]; + else + return baseCinfo_->getSrcFinfo(i); + // return const_cast< Cinfo* >( baseCinfo_ )->getSrcFinfo( i ); + } - return srcFinfos_[i]; + return srcFinfos_[i]; } unsigned int Cinfo::getNumSrcFinfo() const { - if ( baseCinfo_ ) - return srcFinfos_.size() + baseCinfo_->getNumSrcFinfo(); - else - return srcFinfos_.size(); + if(baseCinfo_) + return srcFinfos_.size() + baseCinfo_->getNumSrcFinfo(); + else + return srcFinfos_.size(); } //////////////////////////////////////////////////////////////////// -Finfo* Cinfo::getDestFinfo( unsigned int i ) const -{ - if ( i >= getNumDestFinfo() ) - return &dummy; - if ( baseCinfo_ ) { - if ( i >= baseCinfo_->getNumDestFinfo() ) - return destFinfos_[ i - baseCinfo_->getNumDestFinfo() ]; - else - return const_cast< Cinfo* >( baseCinfo_ )->getDestFinfo( i ); - } +Finfo* Cinfo::getDestFinfo(unsigned int i) const +{ + if(i >= getNumDestFinfo()) + return &dummy; + if(baseCinfo_) { + if(i >= baseCinfo_->getNumDestFinfo()) + return destFinfos_[i - baseCinfo_->getNumDestFinfo()]; + else + return const_cast(baseCinfo_)->getDestFinfo(i); + } - return destFinfos_[i]; + return destFinfos_[i]; } unsigned int Cinfo::getNumDestFinfo() const { - if ( baseCinfo_ ) - return destFinfos_.size() + baseCinfo_->getNumDestFinfo(); - else - return destFinfos_.size(); + if(baseCinfo_) + return destFinfos_.size() + baseCinfo_->getNumDestFinfo(); + else + return destFinfos_.size(); } //////////////////////////////////////////////////////////////////// -Finfo* Cinfo::getValueFinfo( unsigned int i ) const -{ - if ( i >= getNumValueFinfo() ) - return &dummy; - if ( baseCinfo_ ) { - if ( i >= baseCinfo_->getNumValueFinfo() ) - return valueFinfos_[ i - baseCinfo_->getNumValueFinfo() ]; - else - return const_cast< Cinfo* >(baseCinfo_)->getValueFinfo( i ); - } +Finfo* Cinfo::getValueFinfo(unsigned int i) const +{ + if(i >= getNumValueFinfo()) + return &dummy; + if(baseCinfo_) { + if(i >= baseCinfo_->getNumValueFinfo()) + return valueFinfos_[i - baseCinfo_->getNumValueFinfo()]; + else + return const_cast(baseCinfo_)->getValueFinfo(i); + } - return valueFinfos_[i]; + return valueFinfos_[i]; } unsigned int Cinfo::getNumValueFinfo() const { - if ( baseCinfo_ ) - return valueFinfos_.size() + baseCinfo_->getNumValueFinfo(); - else - return valueFinfos_.size(); + if(baseCinfo_) + return valueFinfos_.size() + baseCinfo_->getNumValueFinfo(); + else + return valueFinfos_.size(); } - //////////////////////////////////////////////////////////////////// -Finfo* Cinfo::getLookupFinfo( unsigned int i ) const -{ - if ( i >= getNumLookupFinfo() ) - return &dummy; - if ( baseCinfo_ ) { - if ( i >= baseCinfo_->getNumLookupFinfo() ) - return lookupFinfos_[ i - baseCinfo_->getNumLookupFinfo() ]; - else - return const_cast< Cinfo* >(baseCinfo_)->getLookupFinfo( i ); - } +Finfo* Cinfo::getLookupFinfo(unsigned int i) const +{ + if(i >= getNumLookupFinfo()) + return &dummy; + if(baseCinfo_) { + if(i >= baseCinfo_->getNumLookupFinfo()) + return lookupFinfos_[i - baseCinfo_->getNumLookupFinfo()]; + else + return const_cast(baseCinfo_)->getLookupFinfo(i); + } - return lookupFinfos_[i]; + return lookupFinfos_[i]; } unsigned int Cinfo::getNumLookupFinfo() const { - if ( baseCinfo_ ) - return lookupFinfos_.size() + baseCinfo_->getNumLookupFinfo(); - else - return lookupFinfos_.size(); + if(baseCinfo_) + return lookupFinfos_.size() + baseCinfo_->getNumLookupFinfo(); + else + return lookupFinfos_.size(); } //////////////////////////////////////////////////////////////////// -Finfo* Cinfo::getSharedFinfo( unsigned int i ) -{ - if ( i >= getNumSharedFinfo() ) - return &dummy; - if ( baseCinfo_ ) { - if ( i >= baseCinfo_->getNumSharedFinfo() ) - return sharedFinfos_[ i - baseCinfo_->getNumSharedFinfo() ]; - else - return const_cast< Cinfo* >( baseCinfo_ )->getSharedFinfo( i ); - } +Finfo* Cinfo::getSharedFinfo(unsigned int i) +{ + if(i >= getNumSharedFinfo()) + return &dummy; + if(baseCinfo_) { + if(i >= baseCinfo_->getNumSharedFinfo()) + return sharedFinfos_[i - baseCinfo_->getNumSharedFinfo()]; + else + return const_cast(baseCinfo_)->getSharedFinfo(i); + } - return sharedFinfos_[i]; + return sharedFinfos_[i]; } unsigned int Cinfo::getNumSharedFinfo() const { - if ( baseCinfo_ ) - return sharedFinfos_.size() + baseCinfo_->getNumSharedFinfo(); - else - return sharedFinfos_.size(); + if(baseCinfo_) + return sharedFinfos_.size() + baseCinfo_->getNumSharedFinfo(); + else + return sharedFinfos_.size(); } //////////////////////////////////////////////////////////////////// -Finfo* Cinfo::getFieldElementFinfo( unsigned int i ) const -{ - if ( i >= getNumFieldElementFinfo() ) - return &dummy; - if ( baseCinfo_ ) { - if ( i >= baseCinfo_->getNumFieldElementFinfo() ) - return fieldElementFinfos_[ i - baseCinfo_->getNumFieldElementFinfo() ]; - else - return const_cast< Cinfo* >( baseCinfo_ )->getFieldElementFinfo( i ); - } +Finfo* Cinfo::getFieldElementFinfo(unsigned int i) const +{ + if(i >= getNumFieldElementFinfo()) + return &dummy; + if(baseCinfo_) { + if(i >= baseCinfo_->getNumFieldElementFinfo()) + return fieldElementFinfos_[i - + baseCinfo_->getNumFieldElementFinfo()]; + else + return const_cast(baseCinfo_)->getFieldElementFinfo(i); + } - return fieldElementFinfos_[i]; + return fieldElementFinfos_[i]; } unsigned int Cinfo::getNumFieldElementFinfo() const { - if ( baseCinfo_ ) - return fieldElementFinfos_.size() + baseCinfo_->getNumFieldElementFinfo(); - else - return fieldElementFinfos_.size(); + if(baseCinfo_) + return fieldElementFinfos_.size() + + baseCinfo_->getNumFieldElementFinfo(); + else + return fieldElementFinfos_.size(); } //////////////////////////////////////////////////////////////////// -void Cinfo::setNumFinfo( unsigned int val ) // Dummy function +void Cinfo::setNumFinfo(unsigned int val) // Dummy function { - ; + ; } //////////////////////////////////////////////////////////////////// -const string& Cinfo::srcFinfoName( BindIndex bid ) const -{ - static const string err = ""; - for ( vector< Finfo* >::const_iterator i = srcFinfos_.begin(); - i != srcFinfos_.end(); ++i ) { - const SrcFinfo* sf = dynamic_cast< const SrcFinfo* >( *i ); - assert( sf ); - if ( sf->getBindIndex() == bid ) { - return sf->name(); - } - } - if ( baseCinfo_ ) - return baseCinfo_->srcFinfoName( bid ); - cout << "Error: Cinfo::srcFinfoName( " << bid << " ): not found\n"; - return err; -} - -const string& Cinfo::destFinfoName( FuncId fid ) const -{ - static const string err = ""; - for ( vector< Finfo* >::const_iterator i = destFinfos_.begin(); - i != destFinfos_.end(); ++i ) { - const DestFinfo* df = dynamic_cast< const DestFinfo* >( *i ); - assert( df ); - if ( df->getFid() == fid ) { - return df->name(); - } - } - if ( baseCinfo_ ) - return baseCinfo_->destFinfoName( fid ); - cout << "Error: Cinfo::destFinfoName( " << fid << " ): not found\n"; - return err; +const string& Cinfo::srcFinfoName(BindIndex bid) const +{ + static const string err = ""; + for(vector::const_iterator i = srcFinfos_.begin(); + i != srcFinfos_.end(); ++i) { + const SrcFinfo* sf = dynamic_cast(*i); + assert(sf); + if(sf->getBindIndex() == bid) { + return sf->name(); + } + } + if(baseCinfo_) + return baseCinfo_->srcFinfoName(bid); + cout << "Error: Cinfo::srcFinfoName( " << bid << " ): not found\n"; + return err; +} + +const string& Cinfo::destFinfoName(FuncId fid) const +{ + static const string err = ""; + for(vector::const_iterator i = destFinfos_.begin(); + i != destFinfos_.end(); ++i) { + const DestFinfo* df = dynamic_cast(*i); + assert(df); + if(df->getFid() == fid) { + return df->name(); + } + } + if(baseCinfo_) + return baseCinfo_->destFinfoName(fid); + cout << "Error: Cinfo::destFinfoName( " << fid << " ): not found\n"; + return err; } //////////////////////////////////////////////////////////////////// @@ -580,19 +612,16 @@ const string& Cinfo::destFinfoName( FuncId fid ) const // Static function. Should be called soonest after static initialization. void Cinfo::rebuildOpIndex() { - numCoreOpFunc_ = OpFunc::rebuildOpIndex(); - unsigned int num = 0; - for ( map< string, Cinfo* >::iterator - i = cinfoMap().begin(); i != cinfoMap().end(); ++i ) - { - vector< const OpFunc* >& vec = i->second->funcs_; - for( vector< const OpFunc* >::iterator - j = vec.begin(); j != vec.end(); ++j ) - { - OpFunc* of = const_cast< OpFunc* >( *j ); - num += of->setIndex( num ); - } - } - // cout << "on node " << Shell::myNode() << ": oldNumOpFunc = " << numCoreOpFunc_ << ", new = " << num << endl; - numCoreOpFunc_ = num; + numCoreOpFunc_ = OpFunc::rebuildOpIndex(); + unsigned int num = 0; + for(map::iterator i = cinfoMap().begin(); + i != cinfoMap().end(); ++i) { + vector& vec = i->second->funcs_; + for(vector::iterator j = vec.begin(); j != vec.end(); + ++j) { + OpFunc* of = const_cast(*j); + num += of->setIndex(num); + } + } + numCoreOpFunc_ = num; } diff --git a/basecode/Cinfo.h b/basecode/Cinfo.h index 020be60b2b..e7660b75cc 100644 --- a/basecode/Cinfo.h +++ b/basecode/Cinfo.h @@ -11,322 +11,323 @@ #define _CINFO_H class DinfoBase; +class Finfo; +class OpFunc; +class FinfoWrapper; /** * Class to manage class information for all the other classes. */ -class Cinfo -{ - public: - /** - * The Cinfo intializer is used for static initialization - * of all the MOOSE Cinfos. Each MOOSE class must set up - * a function to build its Cinfo. This function must be - * called statically in the MOOSE class .cpp file. - * Note how it takes the base *Cinfo as an argument. This - * lets us call the base Cinfo initializer when making - * each Cinfo class, thus ensuring the correct static - * initialization sequence, despite the somewhat loose - * semantics for this sequence in most C++ compilers. - */ - Cinfo( const std::string& name, - const Cinfo* baseCinfo, // Base class - Finfo** finfoArray, // Field information array - unsigned int nFinfos, - DinfoBase* d, // A handle to lots of utility functions for the Data class. - const string* doc = 0, - unsigned int numDoc = 0, - bool banCreation = false - ); - - /** - * This initializer is used only as a dummy, to keep Dinfo happy - */ - Cinfo(); - - /** - * This is also a dummy initializer for Dinfo. - */ - Cinfo( const Cinfo& other ); - - ~Cinfo(); -////////////////////////////////////////////////////////////////////////// - /** - * Initializes the Cinfo. Must be called exactly once for - * each Cinfo. - */ - void init( Finfo** finfoArray, unsigned int nFinfos ); - - /** - * registerFinfo: - * Puts Finfo information into Cinfo, and updates fields on - * Finfo as necessary. - */ - void registerFinfo( Finfo* f ); - - /** - * Registers the OpFunc, assigns it a FuncId and returns the - * FuncId. - */ - FuncId registerOpFunc( const OpFunc* f ); - - /** - * Used in derived classes, to replace the original OpFunc with - * the new one. - */ - void overrideFunc( FuncId fid, const OpFunc* f ); - - /** - * Returns the next free value for BindIndex, and keeps track - * of the total number set up. - */ - BindIndex registerBindIndex(); - - /** - * Handles any operations that must be done after an Element - * is created. Scans through all Finfos as they are the ones to - * manage such requests. Examples are to create FieldElements. - */ - void postCreationFunc( Id newId, Element* newElm ) const; - - /** - * Registers a finfo as needing post-creation work - */ - void registerPostCreationFinfo( const Finfo* f ); - - /** - * True if this class should never be instantiated in MOOSE. - * This may happen if it is a pure virtual class, or if - * this Cinfo is for a FieldElement which cannot be created - * in isolation but only as a child of another class. - */ - bool banCreation() const; -////////////////////////////////////////////////////////////////////////// - - const OpFunc* getOpFunc( FuncId fid ) const; - // FuncId getOpFuncId( const string& funcName ) const; - - /** - * Return the name of the Cinfo - */ - const std::string& name() const; - - /** - * Finds the Cinfo with the specified name. - */ - static const Cinfo* find( const std::string& name ); - - /* - * Returns base Cinfo class. The Neutral returns 0. - */ - const Cinfo* baseCinfo() const; - - /** - * Finds Finfo by name in the list for this class, - * ignoring any element-specific fields. - * Returns 0 on failure. - */ - const Finfo* findFinfo( const string& name) const; - - /** - * Finds the funcId by name. Returns 0 on failure. - const FuncId findFuncId( const string& name) const; - */ - - /** - * Number of SrcMsgs in total. Each has a unique number to - * bind to an entry in the msgBinding vector in the Element. - */ - unsigned int numBindIndex() const; - - /** - * Returns the map between name and field info - */ - const map< string, Finfo* >& finfoMap() const; - - /** - * Returns the Dinfo, which manages creation and destruction - * of the data, and knows about its size. - */ - const DinfoBase* dinfo() const; - - /** - * Returns true if the current Cinfo is derived from - * the ancestor - */ - bool isA( const string& ancestor ) const; - - /** - * Utility function for debugging - */ - void reportFids() const; - - ///////////////////////////////////////////////////////////////// - // Functions here for the MOOSE Cinfo inspection class - ///////////////////////////////////////////////////////////////// - - /** - * Return the documentation string - */ - string getDocs() const; - - /** - * Return the name of the base class - */ - string getBaseClass() const; - - - /** - * Return the specified SrcFinfo - */ - Finfo* getSrcFinfo( unsigned int i ) const; - - /** - * Return number of SrcFinfos - */ - unsigned int getNumSrcFinfo() const; - - /** - * Return the specified DestFinfo - */ - Finfo* getDestFinfo( unsigned int i ) const; - - /** - * Return number of DestFinfo - */ - unsigned int getNumDestFinfo() const; - - /** - * Return the specified ValueFinfo - */ - Finfo* getValueFinfo( unsigned int i ) const; - - /** - * Return number of ValueFinfo - */ - unsigned int getNumValueFinfo() const; - - /** - * Return the specified LookupFinfo - */ - Finfo* getLookupFinfo( unsigned int i ) const; - /** - * Return number of LookupFinfo - */ - unsigned int getNumLookupFinfo() const; - - /** - * Return the specified SharedFinfo - */ - Finfo* getSharedFinfo( unsigned int i ); - - /** - * Return number of SharedFinfos - */ - unsigned int getNumSharedFinfo() const; - - /** - * Return the specified FieldElementFinfo - */ - Finfo* getFieldElementFinfo( unsigned int i ) const; - - /** - * Return number of FieldElementFinfos - */ - unsigned int getNumFieldElementFinfo() const; - - /** - * Dummy function. We never allow this assignment. - */ - void setNumFinfo( unsigned int v ); - - /** - * Returns the name of the SrcFinfo having the specified - * BindIndex, on this Cinfo. - * Returns "" on failure. - */ - const string& srcFinfoName( BindIndex bid ) const; - - /** - * Returns the name of the DestFinfo having the specified - * FuncId, on this Cinfo. - * Returns "" on failure. - */ - const string& destFinfoName( FuncId fid ) const; - - - - /** - * Utility function used at init to create the inspection - * Elements for each of the Cinfos. - */ - static void makeCinfoElements( Id parent ); - - /** - * Ensures that the Func Ids are always in a fixed order, - * regardless of the sequence of static initialization of - * Cinfos. - */ - static void rebuildOpIndex(); - - /** - * Initializer for the MOOSE fields for Cinfo - */ - static const Cinfo* initCinfo(); - - private: - string name_; - - // const std::string author_; - // const std::string description_; - const Cinfo* baseCinfo_; - const DinfoBase* dinfo_; - - BindIndex numBindIndex_; - std::map< std::string, std::string > doc_; - - bool banCreation_; - - /** - * This looks up Finfos by name. - */ - map< string, Finfo* > finfoMap_; - - /// Keep track of all SrcFinfos - vector< Finfo* > srcFinfos_; - - /// Keep track of all DestFinfos - vector< Finfo* > destFinfos_; - - /// Keep track of all ValueFinfos - vector< Finfo* > valueFinfos_; - - /// Keep track of all LookupFinfos - vector< Finfo* > lookupFinfos_; - - /// Keep track of all SharedFinfos - vector< Finfo* > sharedFinfos_; - - /// Keep track of all FieldElementFinfos - vector< Finfo* > fieldElementFinfos_; - - /** - * These are special Finfos which have to be invoked - * after the Element is created, and their postCreationFuncs - * called. They are typically things like FieldElementFinfos. - */ - vector< const Finfo* > postCreationFinfos_; - vector< const OpFunc* > funcs_; - - // Useful to know in case we have transient OpFuncs made and - //destroyed. - static unsigned int numCoreOpFunc_; -// map< string, FuncId > opFuncNames_; - - static map< string, Cinfo* >& cinfoMap(); - - // Many opfuncs share same FuncId - // static map< OpFunc*, FuncId >& funcMap(); +class Cinfo { +public: + /** + * The Cinfo intializer is used for static initialization + * of all the MOOSE Cinfos. Each MOOSE class must set up + * a function to build its Cinfo. This function must be + * called statically in the MOOSE class .cpp file. + * Note how it takes the base *Cinfo as an argument. This + * lets us call the base Cinfo initializer when making + * each Cinfo class, thus ensuring the correct static + * initialization sequence, despite the somewhat loose + * semantics for this sequence in most C++ compilers. + */ + Cinfo(const std::string& name, const Cinfo* baseCinfo, // Base class + Finfo** finfoArray, // Field information array + unsigned int nFinfos, DinfoBase* d, // A handle to lots of utility + // functions for the Data class. + const std::string* doc = 0, unsigned int numDoc = 0, + bool banCreation = false); + + /** + * This initializer is used only as a dummy, to keep Dinfo happy + */ + Cinfo(); + + /** + * This is also a dummy initializer for Dinfo. + */ + Cinfo(const Cinfo& other); + + ~Cinfo(); + + /** + * Initializes the Cinfo. Must be called exactly once for + * each Cinfo. + */ + void init(Finfo** finfoArray, unsigned int nFinfos); + + /** + * registerFinfo: + * Puts Finfo information into Cinfo, and updates fields on + * Finfo as necessary. + */ + void registerFinfo(Finfo* f); + + /** + * Registers the OpFunc, assigns it a FuncId and returns the + * FuncId. + */ + FuncId registerOpFunc(const OpFunc* f); + + /** + * Used in derived classes, to replace the original OpFunc with + * the new one. + */ + void overrideFunc(FuncId fid, const OpFunc* f); + + /** + * Returns the next free value for BindIndex, and keeps track + * of the total number set up. + */ + BindIndex registerBindIndex(); + + /** + * Handles any operations that must be done after an Element + * is created. Scans through all Finfos as they are the ones to + * manage such requests. Examples are to create FieldElements. + */ + void postCreationFunc(Id newId, Element* newElm) const; + + /** + * Registers a finfo as needing post-creation work + */ + void registerPostCreationFinfo(const Finfo* f); + + /** + * True if this class should never be instantiated in MOOSE. + * This may happen if it is a pure virtual class, or if + * this Cinfo is for a FieldElement which cannot be created + * in isolation but only as a child of another class. + */ + bool banCreation() const; + ////////////////////////////////////////////////////////////////////////// + + const OpFunc* getOpFunc(FuncId fid) const; + // FuncId getOpFuncId( const string& funcName ) const; + + /** + * Return the name of the Cinfo + */ + const std::string& name() const; + + /** + * Returns the type of Finfo. + */ + string getFinfoType(const Finfo* finfo) const; + + /** + * Finds the Cinfo with the specified name. + */ + static const Cinfo* find(const std::string& name); + + /* + * Returns base Cinfo class. The Neutral returns 0. + */ + const Cinfo* baseCinfo() const; + + /** + * Finds Finfo by name in the list for this class, + * ignoring any element-specific fields. + * Returns 0 on failure. + */ + const Finfo* findFinfo(const string& name) const; + + // This if for python binding. + const FinfoWrapper findFinfoWrapper(const string& name) const; + + /** + * Finds the funcId by name. Returns 0 on failure. + const FuncId findFuncId( const string& name) const; + */ + + /** + * Number of SrcMsgs in total. Each has a unique number to + * bind to an entry in the msgBinding vector in the Element. + */ + unsigned int numBindIndex() const; + + /** + * Returns the map between name and field info + */ + const map& finfoMap() const; + + /** + * Returns the Dinfo, which manages creation and destruction + * of the data, and knows about its size. + */ + const DinfoBase* dinfo() const; + + /** + * Returns true if the current Cinfo is derived from + * the ancestor + */ + bool isA(const string& ancestor) const; + + /** + * Utility function for debugging + */ + void reportFids() const; + + ///////////////////////////////////////////////////////////////// + // Functions here for the MOOSE Cinfo inspection class + ///////////////////////////////////////////////////////////////// + + /** + * Return the documentation string + */ + string getDocs() const; + + /** + * Return the name of the base class + */ + string getBaseClass() const; + + /** + * Return the specified SrcFinfo + */ + Finfo* getSrcFinfo(unsigned int i) const; + + /** + * Return number of SrcFinfos + */ + unsigned int getNumSrcFinfo() const; + + /** + * Return the specified DestFinfo + */ + Finfo* getDestFinfo(unsigned int i) const; + + /** + * Return number of DestFinfo + */ + unsigned int getNumDestFinfo() const; + + /** + * Return the specified ValueFinfo + */ + Finfo* getValueFinfo(unsigned int i) const; + + /** + * Return number of ValueFinfo + */ + unsigned int getNumValueFinfo() const; + + /** + * Return the specified LookupFinfo + */ + Finfo* getLookupFinfo(unsigned int i) const; + + /** + * Return number of LookupFinfo + */ + unsigned int getNumLookupFinfo() const; + + /** + * Return the specified SharedFinfo + */ + Finfo* getSharedFinfo(unsigned int i); + + /** + * Return number of SharedFinfos + */ + unsigned int getNumSharedFinfo() const; + + /** + * Return the specified FieldElementFinfo + */ + Finfo* getFieldElementFinfo(unsigned int i) const; + + /** + * Return number of FieldElementFinfos + */ + unsigned int getNumFieldElementFinfo() const; + + /** + * Dummy function. We never allow this assignment. + */ + void setNumFinfo(unsigned int v); + + /** + * Returns the name of the SrcFinfo having the specified + * BindIndex, on this Cinfo. + * Returns "" on failure. + */ + const string& srcFinfoName(BindIndex bid) const; + + /** + * Returns the name of the DestFinfo having the specified + * FuncId, on this Cinfo. + * Returns "" on failure. + */ + const string& destFinfoName(FuncId fid) const; + + /** + * Utility function used at init to create the inspection + * Elements for each of the Cinfos. + */ + static void makeCinfoElements(Id parent); + + /** + * Ensures that the Func Ids are always in a fixed order, + * regardless of the sequence of static initialization of + * Cinfos. + */ + static void rebuildOpIndex(); + + /** + * Initializer for the MOOSE fields for Cinfo + */ + static const Cinfo* initCinfo(); + +private: + string name_; + + // const std::string author_; + // const std::string description_; + const Cinfo* baseCinfo_; + const DinfoBase* dinfo_; + + BindIndex numBindIndex_; + std::map doc_; + + bool banCreation_; + + /** + * This looks up Finfos by name. + */ + map finfoMap_; + + /// Keep track of all SrcFinfos + vector srcFinfos_; + + /// Keep track of all DestFinfos + vector destFinfos_; + + /// Keep track of all ValueFinfos + vector valueFinfos_; + + /// Keep track of all LookupFinfos + vector lookupFinfos_; + + /// Keep track of all SharedFinfos + vector sharedFinfos_; + + /// Keep track of all FieldElementFinfos + vector fieldElementFinfos_; + + /** + * These are special Finfos which have to be invoked + * after the Element is created, and their postCreationFuncs + * called. They are typically things like FieldElementFinfos. + */ + vector postCreationFinfos_; + vector funcs_; + + // Useful to know in case we have transient OpFuncs made and + // destroyed. + static unsigned int numCoreOpFunc_; + + static map& cinfoMap(); }; -#endif // _CINFO_H +#endif // _CINFO_H diff --git a/basecode/Conv.h b/basecode/Conv.h index e19fccabc3..0baf86a498 100644 --- a/basecode/Conv.h +++ b/basecode/Conv.h @@ -88,6 +88,8 @@ template< class T > class Conv return "short"; if ( typeid( T ) == typeid( long ) ) return "long"; + if ( typeid( T ) == typeid( size_t ) ) + return "size_t"; if ( typeid( T ) == typeid( unsigned int ) ) return "unsigned int"; if ( typeid( T ) == typeid( unsigned long ) ) @@ -100,7 +102,56 @@ template< class T > class Conv return "Id"; if ( typeid( T ) == typeid( ObjId ) ) return "ObjId"; - return typeid( T ).name(); // this is not portable but may be more useful than "bad" + if ( typeid( T ) == typeid( vector) ) + return "vector"; + if ( typeid( T ) == typeid( vector*) ) + return "vector*"; + if ( typeid( T ) == typeid( vector) ) + return "vector"; + if ( typeid( T ) == typeid( vector*) ) + return "vector*"; +#if 0 + // typeid of incomplete type Neutral (after forward declarting it) + // is not supported by c++ standard. Though following compiles with + // gcc (but not with clang). + if ( typeid( T ) == typeid( Neutral ) ) + return "Neutral"; + if ( typeid( T ) == typeid( vector ) ) + return "vector"; + if ( typeid( T ) == typeid( vector*) ) + return "vector*"; +#endif + if ( typeid( T ) == typeid( vector) ) + return "vector"; + if ( typeid( T ) == typeid( vector) ) + return "vector"; + if ( typeid( T ) == typeid( vector*) ) + return "vector*"; + if ( typeid( T ) == typeid( vector) ) + return "vector"; + if ( typeid( T ) == typeid( vector*) ) + return "vector*"; + if ( typeid( T ) == typeid( vector) ) + return "vector"; + if ( typeid( T ) == typeid( vector*) ) + return "vector*"; + if ( typeid( T ) == typeid( vector>) ) + return "vector>"; + if ( typeid( T ) == typeid( vector>*) ) + return "vector>*"; + if ( typeid( T ) == typeid( vector>) ) + return "vector>"; + if ( typeid( T ) == typeid( vector>*) ) + return "vector>*"; + if ( typeid( T ) == typeid( vector>) ) + return "vector>"; + if ( typeid( T ) == typeid( vector>*) ) + return "vector>*"; + if ( typeid( T ) == typeid( vector>) ) + return "vector>"; + if ( typeid( T ) == typeid( vector>*) ) + return "vector>*"; + return typeid(T).name(); // this is not portable but may be more useful than "bad" } private: diff --git a/basecode/DestFinfo.cpp b/basecode/DestFinfo.cpp index b8a497e0dc..86ef7e692e 100644 --- a/basecode/DestFinfo.cpp +++ b/basecode/DestFinfo.cpp @@ -10,58 +10,58 @@ #include #include "header.h" -DestFinfo::~DestFinfo() { - delete func_; +DestFinfo::~DestFinfo() +{ + delete func_; } -DestFinfo::DestFinfo( const string& name, const string& doc, - OpFunc* func ) - : Finfo( name, doc ), func_( func ) +DestFinfo::DestFinfo(const string& name, const string& doc, OpFunc* func) + : Finfo(name, doc), func_(func) { - ; + ; } -void DestFinfo::registerFinfo( Cinfo* c ) +void DestFinfo::registerFinfo(Cinfo* c) { - if ( c->baseCinfo() ) { - const Finfo* bf = c->baseCinfo()->findFinfo( name() ); - if ( bf ) { - const DestFinfo* df = dynamic_cast< const DestFinfo* >( bf ); - assert( df ); - fid_ = df->fid_; - c->overrideFunc( fid_, func_ ); - return; - } - } - fid_ = c->registerOpFunc( func_ ); -// cout << c->name() << "." << name() << ": " << fid_ << endl; + if(c->baseCinfo()) { + const Finfo* bf = c->baseCinfo()->findFinfo(name()); + if(bf) { + const DestFinfo* df = dynamic_cast(bf); + assert(df); + fid_ = df->fid_; + c->overrideFunc(fid_, func_); + return; + } + } + fid_ = c->registerOpFunc(func_); + // cout << c->name() << "." << name() << ": " << fid_ << endl; } const OpFunc* DestFinfo::getOpFunc() const { - return func_; + return func_; } FuncId DestFinfo::getFid() const { - return fid_; + return fid_; } -bool DestFinfo::strSet( - const Eref& tgt, const string& field, const string& arg ) const +bool DestFinfo::strSet(const Eref& tgt, const string& field, + const string& arg) const { - assert( 0 ); - return false; + assert(0); + return false; } -bool DestFinfo::strGet( - const Eref& tgt, const string& field, string& returnValue ) const +bool DestFinfo::strGet(const Eref& tgt, const string& field, + string& returnValue) const { - assert( 0 ); - return false; + assert(0); + return false; } string DestFinfo::rttiType() const { - return func_->rttiType(); + return func_->rttiType(); } diff --git a/basecode/DestFinfo.h b/basecode/DestFinfo.h index c013a6b25d..70562c3599 100644 --- a/basecode/DestFinfo.h +++ b/basecode/DestFinfo.h @@ -9,35 +9,32 @@ #ifndef _DEST_FINFO_H #define _DEST_FINFO_H - /* * DestFinfo manages function requests. All messages terminate on * the functions stored in DestFinfos. No templates here, as all the * type-specific work is done by the OpFunc. -*/ -class DestFinfo: public Finfo -{ - public: - ~DestFinfo(); - DestFinfo( const string& name, const string& doc,OpFunc* func ); - void registerFinfo( Cinfo* c ); - bool strSet( const Eref& tgt, const string& field, - const string& arg ) const; - bool strGet( const Eref& tgt, const string& field, - string& returnValue ) const; + */ +class DestFinfo : public Finfo { +public: + ~DestFinfo(); + DestFinfo(const string& name, const string& doc, OpFunc* func); + void registerFinfo(Cinfo* c); + bool strSet(const Eref& tgt, const string& field, const string& arg) const; + bool strGet(const Eref& tgt, const string& field, + string& returnValue) const; - const OpFunc* getOpFunc() const; - FuncId getFid() const; + const OpFunc* getOpFunc() const; + FuncId getFid() const; - /////////////////////////////////////////////////////////////// - // Override the default virtual function for the rtti info - /////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////// + // Override the default virtual function for the rtti info + /////////////////////////////////////////////////////////////// - string rttiType() const; + string rttiType() const; - private: - OpFunc* func_; - FuncId fid_; +private: + OpFunc* func_; + FuncId fid_; }; -#endif // _DEST_FINFO_H +#endif // _DEST_FINFO_H diff --git a/basecode/EpFunc.h b/basecode/EpFunc.h index 3fcb1e0715..e413905ac7 100644 --- a/basecode/EpFunc.h +++ b/basecode/EpFunc.h @@ -10,6 +10,8 @@ #ifndef _EPFUNC_H #define _EPFUNC_H +class Neutral; + /** * Utility function to return a pointer of the desired type from the * Eref data. Mainly here because it lets us specialize for Neutrals, diff --git a/basecode/Finfo.cpp b/basecode/Finfo.cpp index 741af4a94a..478abfaad3 100644 --- a/basecode/Finfo.cpp +++ b/basecode/Finfo.cpp @@ -10,8 +10,7 @@ #include #include "header.h" -Finfo::Finfo( const string& name, const string& doc ) - : name_( name ), doc_( doc ) +Finfo::Finfo(const string& name, const string& doc) : name_(name), doc_(doc) { ; } @@ -22,53 +21,33 @@ Finfo::Finfo( const string& name, const string& doc ) const Cinfo* Finfo::initCinfo() { - static ReadOnlyValueFinfo< FinfoWrapper, string > fieldName( - "fieldName", - "Name of field handled by Finfo", - &FinfoWrapper::getName - ); - - static ReadOnlyValueFinfo< FinfoWrapper, string > docs( - "docs", - "Documentation for Finfo", - &FinfoWrapper::docs - ); - - static ReadOnlyValueFinfo< FinfoWrapper, string > type( - "type", - "RTTI type info for this Finfo", - &FinfoWrapper::type - ); - - static ReadOnlyValueFinfo< FinfoWrapper, vector< string > > src( - "src", - "Subsidiary SrcFinfos. Useful for SharedFinfos", - &FinfoWrapper::src - ); - static ReadOnlyValueFinfo< FinfoWrapper, vector< string > > dest( - "dest", - "Subsidiary DestFinfos. Useful for SharedFinfos", - &FinfoWrapper::dest - ); - - - static Finfo* finfoFinfos[] = - { - &fieldName, // ReadOnlyValue - &docs, // ReadOnlyValue - &type, // ReadOnlyValue - &src, // ReadOnlyValue - &dest, // ReadOnlyValue + static ReadOnlyValueFinfo fieldName( + "fieldName", "Name of field handled by Finfo", &FinfoWrapper::getName); + + static ReadOnlyValueFinfo docs( + "docs", "Documentation for Finfo", &FinfoWrapper::docs); + + static ReadOnlyValueFinfo type( + "type", "RTTI type info for this Finfo", &FinfoWrapper::type); + + static ReadOnlyValueFinfo> src( + "src", "Subsidiary SrcFinfos. Useful for SharedFinfos", + &FinfoWrapper::src); + static ReadOnlyValueFinfo> dest( + "dest", "Subsidiary DestFinfos. Useful for SharedFinfos", + &FinfoWrapper::dest); + + static Finfo* finfoFinfos[] = { + &fieldName, // ReadOnlyValue + &docs, // ReadOnlyValue + &type, // ReadOnlyValue + &src, // ReadOnlyValue + &dest, // ReadOnlyValue }; - static Dinfo< Finfo* > dinfo; - static Cinfo finfoCinfo ( - "Finfo", - Neutral::initCinfo(), - finfoFinfos, - sizeof( finfoFinfos ) / sizeof( Finfo* ), - &dinfo - ); + static Dinfo dinfo; + static Cinfo finfoCinfo("Finfo", Neutral::initCinfo(), finfoFinfos, + sizeof(finfoFinfos) / sizeof(Finfo*), &dinfo); return &finfoCinfo; } @@ -77,59 +56,57 @@ static const Cinfo* finfoCinfo = Finfo::initCinfo(); //////////////////////////////////////////////////////////////// -const string& Finfo::name( ) const +const string& Finfo::name() const { return name_; } -const string& Finfo::docs( ) const +const string& Finfo::docs() const { return doc_; } //////////////////////////////////////////////////////////////// // Needed to access as a MOOSE field. Note that the Finfo is stored as a ptr -string FinfoWrapper::getName( ) const +string FinfoWrapper::getName() const { return f_->name(); } -string FinfoWrapper::docs( ) const +string FinfoWrapper::docs() const { return f_->docs(); } - -string FinfoWrapper::type( ) const +string FinfoWrapper::type() const { return f_->rttiType(); } -vector< string > FinfoWrapper::src( ) const +vector FinfoWrapper::src() const { return f_->innerSrc(); } -vector< string > FinfoWrapper::dest( ) const +vector FinfoWrapper::dest() const { return f_->innerDest(); } - // Default virtual functions. string Finfo::rttiType() const { - return typeid( *this ).name(); + return typeid(*this).name(); } -vector< string > Finfo::innerSrc() const +vector Finfo::innerSrc() const { - static vector< string > ret; + static vector ret; return ret; } -vector< string > Finfo::innerDest() const +vector Finfo::innerDest() const { - static vector< string > ret; + static vector ret; return ret; } diff --git a/basecode/Finfo.h b/basecode/Finfo.h index 75852acde4..982da863dd 100644 --- a/basecode/Finfo.h +++ b/basecode/Finfo.h @@ -9,10 +9,9 @@ #ifndef _FINFO_H #define _FINFO_H -class Finfo -{ +class Finfo { public: - Finfo( const string& name, const string& doc ); + Finfo(const string& name, const string& doc); virtual ~Finfo() { ; @@ -35,23 +34,23 @@ class Finfo /** * Assign function Ids, bindIndex and so on. */ - virtual void registerFinfo( Cinfo* c ) = 0; + virtual void registerFinfo(Cinfo* c) = 0; /** * Function to set this field using a string argument. * Returns true on success. * Normally called only from SetGet::strSet. */ - virtual bool strSet( const Eref& tgt, const string& field, - const string& arg ) const = 0; + virtual bool strSet(const Eref& tgt, const string& field, + const string& arg) const = 0; /** * Function to return value of field into a string argument. * Returns true on success. * Normally called only from SetGet::strGet. */ - virtual bool strGet( const Eref& tgt, const string& field, - string& returnValue ) const = 0; + virtual bool strGet(const Eref& tgt, const string& field, + string& returnValue) const = 0; /** * This function is called on each new Element after @@ -60,7 +59,7 @@ class Finfo * as soon as the parent is made. * Used in FieldElementFinfo.h */ - virtual void postCreationFunc( Id newId, Element* newElm ) const + virtual void postCreationFunc(Id newId, Element* newElm) const { ; } @@ -78,7 +77,7 @@ class Finfo * Is called only from msg src, so most Finfos return 0. * SrcFinfo and SharedFinfo will need to implement this. */ - virtual bool checkTarget( const Finfo* target) const + virtual bool checkTarget(const Finfo* target) const { return 0; } @@ -89,7 +88,7 @@ class Finfo * Returns 1 on success. * Defaults to 0 because many Finfo combinations won't work. */ - virtual bool addMsg( const Finfo* target, ObjId mid, Element* src ) const + virtual bool addMsg(const Finfo* target, ObjId mid, Element* src) const { return 0; } @@ -130,12 +129,12 @@ class Finfo /** * Returns subsidiary SrcFinfos */ - virtual vector< string > innerSrc() const; + virtual vector innerSrc() const; /** * Returns subsidiary DestFinfos */ - virtual vector< string > innerDest() const; + virtual vector innerDest() const; /** * Returns the Class Info for this Finfo @@ -148,33 +147,31 @@ class Finfo }; // Wrapper to handle the access functions to the Finfo objects. -class FinfoWrapper -{ +class FinfoWrapper { public: - FinfoWrapper( const Finfo* other ) - : f_( other ) + FinfoWrapper(const Finfo* other) : f_(other) { ; } - string getName( ) const; - string docs( ) const; - string type( ) const; + string getName() const; + string docs() const; + string type() const; /** * Returns the list of subsidiary SrcFinfos. * Used in Shared Finfos, empty otherwise. Goes via * internal virtual function. */ - vector< string > src( ) const; + vector src() const; /** * Returns the list of subsidiary destFinfos. * Used in SharedFinfos and ValueFinfos, empty otherwise. Goes via * internal virtual function. */ - vector< string > dest( ) const; + vector dest() const; private: const Finfo* f_; }; -#endif // _FINFO_H +#endif // _FINFO_H diff --git a/basecode/Id.cpp b/basecode/Id.cpp index 5cdd445945..15078eb989 100644 --- a/basecode/Id.cpp +++ b/basecode/Id.cpp @@ -16,27 +16,25 @@ ////////////////////////////////////////////////////////////// Id::Id() -// : id_( 0 ), index_( 0 ) - : id_( 0 ) + // : id_( 0 ), index_( 0 ) + : id_(0) { ; } -Id::Id( unsigned int id ) - : id_( id ) +Id::Id(unsigned int id) : id_(id) { ; } -Id::Id( const string& path, const string& separator ) +Id::Id(const string& path) { - Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); - assert( shell ); - id_ = shell->doFind( path ).id.id_; + Shell* shell = reinterpret_cast(Id().eref().data()); + assert(shell); + id_ = shell->doFind(path).id.id_; } -Id::Id( const ObjId& oi ) - : id_( oi.id.id_ ) +Id::Id(const ObjId& oi) : id_(oi.id.id_) { ; } @@ -46,19 +44,19 @@ Id::Id( const ObjId& oi ) * out of the existing range, but it would be nice to have a heuristic * on how outrageous the incoming value is. */ -Id Id::str2Id( const std::string& s ) +Id Id::str2Id(const std::string& s) { // unsigned int val = atoi( s.c_str() ); - return Id( s ); + return Id(s); } ////////////////////////////////////////////////////////////// // Element array static access function. Private. ////////////////////////////////////////////////////////////// -vector< Element* >& Id::elements() +vector& Id::elements() { - static vector< Element* > e; + static vector e; return e; } @@ -67,31 +65,29 @@ vector< Element* >& Id::elements() ////////////////////////////////////////////////////////////// // static func to convert id into a string. -string Id::id2str( Id id ) +string Id::id2str(Id id) { return id.path(); } // Function to convert it into its fully separated path. -string Id::path( const string& separator) const +string Id::path() const { - string ret = Neutral::path( eref() ); + string ret = Neutral::path(eref()); // FIXME: Monday 09 March 2020 12:30:27 PM IST, Dilawar Singh - // This beaks the path comparison. Getting x.path from x returned in a + // This beaks the path comparison. Getting x.path from x returned in a // list by moose.wildcardFind() and getting path from here doesn't math // when this is enabled. // If we want to remove [0] then it should be done globally and not just // here. - // Trim off trailing [] - assert( ret.length() > 0 ); - while ( ret.back() == ']' ) - { - size_t pos = ret.find_last_of( '[' ); - if ( pos != string::npos && pos > 0 ) - { - ret = ret.substr( 0, pos ); + // Trim off trailing [] + assert(ret.length() > 0); + while (ret.back() == ']') { + size_t pos = ret.find_last_of('['); + if (pos != string::npos && pos > 0) { + ret = ret.substr(0, pos); } } @@ -111,26 +107,26 @@ string Id::path( const string& separator) const * deprecated Element* Id::operator()() const { - return elements()[ id_ ]; + return elements()[ id_ ]; } */ /// Synonym for Id::operator()() Element* Id::element() const { - return elements()[ id_ ]; + return elements()[id_]; } /* unsigned int Id::index() const { - return index_; + return index_; } */ Eref Id::eref() const { - return Eref( elements()[ id_ ], 0 ); + return Eref(elements()[id_], 0); // return Eref( elements()[ id_ ], index_ ); } @@ -140,8 +136,8 @@ Id Id::nextId() // Should really look up 'available' list. // Should really put the returned value onto the 'reserved' list // so they don't go dangling. - Id ret( elements().size() ); - elements().push_back( 0 ); + Id ret(elements().size()); + elements().push_back(0); return ret; } @@ -151,53 +147,49 @@ unsigned int Id::numIds() return elements().size(); } -void Id::bindIdToElement( Element* e ) +void Id::bindIdToElement(Element* e) { - if ( elements().size() <= id_ ) - { - if ( elements().size() % 1000 == 0 ) - { - elements().reserve( elements().size() + 1000 ); + if (elements().size() <= id_) { + if (elements().size() % 1000 == 0) { + elements().reserve(elements().size() + 1000); } - elements().resize( id_ + 1, 0 ); + elements().resize(id_ + 1, 0); } - assert( elements()[ id_ ] == 0 ); + assert(elements()[id_] == 0); /* if ( elements()[ id_ ] != 0 ) - cout << "Warning: assigning Element to existing id " << id_ << "\n"; - */ - elements()[ id_ ] = e; + cout << "Warning: assigning Element to existing id " << id_ << "\n"; + */ + elements()[id_] = e; // cout << "Id::bindIdToElement '" << e->getName() << "' = " << id_ << endl; } /* Id Id::create( Element* e ) { - Id ret( elements().size() ); - elements().push_back( e ); - return ret; + Id ret( elements().size() ); + elements().push_back( e ); + return ret; } */ void Id::destroy() const { - if ( elements()[ id_ ] ) - { - // cout << "Id::destroy '" << elements()[ id_ ]->getName() << "' = " << id_ << endl; - delete elements()[ id_ ]; - elements()[ id_ ] = 0; + if (elements()[id_]) { + // cout << "Id::destroy '" << elements()[ id_ ]->getName() << "' = " << + // id_ << endl; + delete elements()[id_]; + elements()[id_] = 0; // Put id_ on 'available' list - } - else - { + } else { cout << "Warning: Id::destroy: " << id_ << " already zeroed\n"; } } void Id::zeroOut() const { - assert ( id_ < elements().size() ); - elements()[ id_ ] = 0; + assert(id_ < elements().size()); + elements()[id_] = 0; } unsigned int Id::value() const @@ -207,11 +199,9 @@ unsigned int Id::value() const void Id::clearAllElements() { - for ( vector< Element* >::iterator - i = elements().begin(); i != elements().end(); ++i ) - { - if ( *i ) - { + for (vector::iterator i = elements().begin(); + i != elements().end(); ++i) { + if (*i) { (*i)->clearAllMsgs(); delete *i; } @@ -222,19 +212,19 @@ void Id::clearAllElements() // Id utility ////////////////////////////////////////////////////////////// -ostream& operator <<( ostream& s, const Id& i ) +ostream& operator<<(ostream& s, const Id& i) { s << i.id_; /* if ( i.index_ == 0 ) - s << i.id_; + s << i.id_; else - s << i.id_ << "[" << i.index_ << "]"; + s << i.id_ << "[" << i.index_ << "]"; */ return s; } -istream& operator >>( istream& s, Id& i ) +istream& operator>>(istream& s, Id& i) { s >> i.id_; return s; @@ -242,8 +232,8 @@ istream& operator >>( istream& s, Id& i ) /* Id::Id( unsigned int id, unsigned int index ) - : id_( id ), index_( index ) + : id_( id ), index_( index ) { - ; + ; } */ diff --git a/basecode/Id.h b/basecode/Id.h index 1b877e0b38..bcc4a837c4 100644 --- a/basecode/Id.h +++ b/basecode/Id.h @@ -10,12 +10,15 @@ #ifndef _ID_H #define _ID_H +class ObjId; +class Element; +class Eref; + /** * This class manages id lookups for elements. Ids provide a uniform * handle for every object, independent of which node they are located on. */ -class Id -{ +class Id { public: ////////////////////////////////////////////////////////////// // Id creation @@ -28,22 +31,24 @@ class Id /** * Creates an id with the specified Element number */ - Id( unsigned int id ); + Id(unsigned int id); /** * Returns an id found by traversing the specified path */ - Id( const std::string& path, const std::string& separator = "/" ); + Id(const std::string& path); /** * Downconverts an OjbId to an Id */ - Id( const ObjId& oi ); + Id(const ObjId& oi); /** * Destroys an Id. Doesn't do anything much. */ - ~Id() {} + ~Id() + { + } /** * Reserves an id for assigning to an Element. Each time it is @@ -52,7 +57,6 @@ class Id */ static Id nextId(); - /** * Returns the number of Ids in use. */ @@ -61,7 +65,7 @@ class Id /** * The specified element is placed into current id. */ - void bindIdToElement( Element* e ); + void bindIdToElement(Element* e); /** * Cleanly deletes the associated Element, and zeroes out @@ -76,8 +80,7 @@ class Id /** * Returns the full pathname of the object on the id. */ - std::string path( const std::string& separator = "/" ) const; - + std::string path() const; /** * Returns the Element pointed to by the id @@ -98,7 +101,7 @@ class Id */ Element* element() const; -// unsigned int index() const; + // unsigned int index() const; /** * Returns the Eref to the element plus index @@ -109,39 +112,40 @@ class Id * Returns an id whose value is string-converted from the * specified string. */ - static Id str2Id( const std::string& s ); + static Id str2Id(const std::string& s); /** * Returns a string holding the ascii value of the id_ . */ - static std::string id2str( Id id ); + static std::string id2str(Id id); unsigned int value() const; ////////////////////////////////////////////////////////////// // Comparisons between ids ////////////////////////////////////////////////////////////// - bool operator==( const Id& other ) const + bool operator==(const Id& other) const { // return id_ == other.id_ && index_ == other.index_; return id_ == other.id_; } - bool operator!=( const Id& other ) const + bool operator!=(const Id& other) const { // return id_ != other.id_ || index_ != other.index_; return id_ != other.id_; } - bool operator<( const Id& other ) const + bool operator<(const Id& other) const { // return ( id_ < other.id_ ) || // ( id_ == other.id_ && index_ < other.index_ ); - return ( id_ < other.id_ ); + return (id_ < other.id_); } // The follwoing two functions check if the Id is associated with - // an existing element. Needed for handling objects that have been destroyed. + // an existing element. Needed for handling objects that have been + // destroyed. static bool isValid(Id id) { return (id.id_ < elements().size()) && (elements()[id.id_] != 0); @@ -164,29 +168,27 @@ class Id void zeroOut() const; ////////////////////////////////////////////////////////////// - friend ostream& operator <<( ostream& s, const Id& i ); - friend istream& operator >>( istream& s, Id& i ); + friend ostream& operator<<(ostream& s, const Id& i); + friend istream& operator>>(istream& s, Id& i); private: // static void setManager( Manager* m ); - unsigned int id_; // Unique identifier for Element* -// unsigned int index_; // Index of array entry within element. - static vector< Element* >& elements(); + unsigned int id_; // Unique identifier for Element* + // unsigned int index_; // Index of array entry within element. + static vector& elements(); }; -// User defined hash function. +// User defined hash function. // See https://en.cppreference.com/w/cpp/utility/hash for more details. -namespace std -{ - template <> - struct hash +namespace std { +template <> +struct hash { +public: + size_t operator()(const Id& x) const { - public : - size_t operator()(const Id &x ) const - { - return std::hash()( x.value() ); - } - }; + return std::hash()(x.value()); + } +}; } -#endif // _ID_H +#endif // _ID_H diff --git a/basecode/LookupValueFinfo.h b/basecode/LookupValueFinfo.h index 12b2403e04..89cd9d184a 100644 --- a/basecode/LookupValueFinfo.h +++ b/basecode/LookupValueFinfo.h @@ -13,15 +13,18 @@ * This class is here just as a organizational feature. Lets us do some * inspection using dynamic_casts. */ -class LookupValueFinfoBase: public Finfo -{ - public: - ~LookupValueFinfoBase() - {;} - - LookupValueFinfoBase( const string& name, const string& doc ) - : Finfo( name, doc ) - {;} +class LookupValueFinfoBase : public Finfo { +public: + ~LookupValueFinfoBase() + { + ; + } + + LookupValueFinfoBase(const string& name, const string& doc) + : Finfo(name, doc) + { + ; + } }; /** @@ -31,110 +34,111 @@ class LookupValueFinfoBase: public Finfo * L is the lookup class * F is the field class. */ -template < class T, class L, class F > class LookupValueFinfo: public LookupValueFinfoBase -{ - public: - ~LookupValueFinfo() { - delete set_; - delete get_; - } - - LookupValueFinfo( const string& name, const string& doc, - void ( T::*setFunc )( L, F ), - F ( T::*getFunc )( L ) const ) - : LookupValueFinfoBase( name, doc ) - { - string setname = "set" + name; - setname[3] = std::toupper( setname[3] ); - set_ = new DestFinfo( - setname, - "Assigns field value.", - new OpFunc2< T, L, F >( setFunc ) ); - - string getname = "get" + name; - getname[3] = std::toupper( getname[3] ); - get_ = new DestFinfo( - getname, - "Requests field value. The requesting Element must " - "provide a handler for the returned value.", - new GetOpFunc1< T, L, F >( getFunc ) ); - } - - - void registerFinfo( Cinfo* c ) { - c->registerFinfo( set_ ); - c->registerFinfo( get_ ); - } - - bool strSet( const Eref& tgt, const string& field, - const string& arg ) const { - string fieldPart = field.substr( 0, field.find( "[" ) ); - string indexPart = field.substr( field.find( "[" ) + 1, field.find( "]" ) ); - return LookupField< L, F >::innerStrSet( - tgt.objId(), fieldPart, indexPart, arg ); - } - - bool strGet( const Eref& tgt, const string& field, - string& returnValue ) const { - string fieldPart = field.substr( 0, field.find( "[" ) ); - string indexPart = field.substr( field.find( "[" ) + 1, field.find( "]" ) ); - return LookupField< L, F >::innerStrGet( tgt.objId(), - fieldPart, indexPart, returnValue ); - } - - string rttiType() const { - return Conv::rttiType() + "," + Conv::rttiType(); - } - - private: - DestFinfo* set_; - DestFinfo* get_; +template +class LookupValueFinfo : public LookupValueFinfoBase { +public: + ~LookupValueFinfo() + { + delete set_; + delete get_; + } + + LookupValueFinfo(const string& name, const string& doc, + void (T::*setFunc)(L, F), F (T::*getFunc)(L) const) + : LookupValueFinfoBase(name, doc) + { + string setname = "set" + name; + setname[3] = std::toupper(setname[3]); + set_ = new DestFinfo(setname, "Assigns field value.", + new OpFunc2(setFunc)); + + string getname = "get" + name; + getname[3] = std::toupper(getname[3]); + get_ = + new DestFinfo(getname, + "Requests field value. The requesting Element must " + "provide a handler for the returned value.", + new GetOpFunc1(getFunc)); + } + + void registerFinfo(Cinfo* c) + { + c->registerFinfo(set_); + c->registerFinfo(get_); + } + + bool strSet(const Eref& tgt, const string& field, const string& arg) const + { + string fieldPart = field.substr(0, field.find("[")); + string indexPart = field.substr(field.find("[") + 1, field.find("]")); + return LookupField::innerStrSet(tgt.objId(), fieldPart, indexPart, + arg); + } + + bool strGet(const Eref& tgt, const string& field, string& returnValue) const + { + string fieldPart = field.substr(0, field.find("[")); + string indexPart = field.substr(field.find("[") + 1, field.find("]")); + return LookupField::innerStrGet(tgt.objId(), fieldPart, indexPart, + returnValue); + } + + string rttiType() const + { + return Conv::rttiType() + "," + Conv::rttiType(); + } + +private: + DestFinfo* set_; + DestFinfo* get_; }; -template < class T, class L, class F > class ReadOnlyLookupValueFinfo: public LookupValueFinfoBase -{ - public: - ~ReadOnlyLookupValueFinfo() { - delete get_; - } - - ReadOnlyLookupValueFinfo( const string& name, const string& doc, - F ( T::*getFunc )( L ) const ) - : LookupValueFinfoBase( name, doc ) - { - string getname = "get" + name; - getname[3] = std::toupper( getname[3] ); - get_ = new DestFinfo( - getname, - "Requests field value. The requesting Element must " - "provide a handler for the returned value.", - new GetOpFunc1< T, L, F >( getFunc ) ); - } - - - void registerFinfo( Cinfo* c ) { - c->registerFinfo( get_ ); - } - - bool strSet( const Eref& tgt, const string& field, - const string& arg ) const { - return 0; - } - - bool strGet( const Eref& tgt, const string& field, - string& returnValue ) const { - string fieldPart = field.substr( 0, field.find( "[" ) ); - string indexPart = field.substr( field.find( "[" ) + 1, field.find( "]" ) ); - return LookupField< L, F >::innerStrGet( tgt.objId(), - fieldPart, indexPart, returnValue ); - } - - string rttiType() const { - return Conv::rttiType() + "," + Conv::rttiType(); - } - - private: - DestFinfo* get_; +template +class ReadOnlyLookupValueFinfo : public LookupValueFinfoBase { +public: + ~ReadOnlyLookupValueFinfo() + { + delete get_; + } + + ReadOnlyLookupValueFinfo(const string& name, const string& doc, + F (T::*getFunc)(L) const) + : LookupValueFinfoBase(name, doc) + { + string getname = "get" + name; + getname[3] = std::toupper(getname[3]); + get_ = + new DestFinfo(getname, + "Requests field value. The requesting Element must " + "provide a handler for the returned value.", + new GetOpFunc1(getFunc)); + } + + void registerFinfo(Cinfo* c) + { + c->registerFinfo(get_); + } + + bool strSet(const Eref& tgt, const string& field, const string& arg) const + { + return 0; + } + + bool strGet(const Eref& tgt, const string& field, string& returnValue) const + { + string fieldPart = field.substr(0, field.find("[")); + string indexPart = field.substr(field.find("[") + 1, field.find("]")); + return LookupField::innerStrGet(tgt.objId(), fieldPart, indexPart, + returnValue); + } + + string rttiType() const + { + return Conv::rttiType() + "," + Conv::rttiType(); + } + +private: + DestFinfo* get_; }; -#endif // _LOOKUP_VALUE_FINFO_H +#endif // _LOOKUP_VALUE_FINFO_H diff --git a/basecode/ObjId.h b/basecode/ObjId.h index ab91204c23..c487f86c8d 100644 --- a/basecode/ObjId.h +++ b/basecode/ObjId.h @@ -10,8 +10,6 @@ #ifndef _OBJ_ID_H #define _OBJ_ID_H -#include "Id.h" - /** * This class manages lookups for specific data entries in elements, * in a node-independent manner. @@ -38,12 +36,18 @@ class ObjId /** * Creates a ObjId using specified Id and DataIndex */ - ObjId( Id i, unsigned int d, unsigned int f = 0 ) + ObjId( Id i, unsigned int d, unsigned int f) : id( i ), dataIndex( d ), fieldIndex( f ) { ; } + ObjId( Id i, unsigned int d) + : id( i ), dataIndex( d ), fieldIndex(0) + { + ; + } + ObjId( Id i ) : id( i ), dataIndex( 0 ), fieldIndex( 0 ) { diff --git a/basecode/consts.cpp b/basecode/consts.cpp deleted file mode 100644 index 30e1b50e30..0000000000 --- a/basecode/consts.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/********************************************************************** -** This program is part of 'MOOSE', the -** Messaging Object Oriented Simulation Environment. -** Copyright (C) 2003-2010 Upinder S. Bhalla. and NCBS -** It is made available under the terms of the -** GNU Lesser General Public License version 2.1 -** See the file COPYING.LIB for the full notice. -**********************************************************************/ - -#include "header.h" - -const double PI = 3.141592653589793; - -// There is experimental error in the last sig fig here. -const double NA = 6.0221415e23; - -const double FaradayConst = 96485.3415; // s A / mol - -const double GasConst = 8.3144621; // R, units are J/(K.mol) - -/// Used by ObjId and Eref -const unsigned int ALLDATA = ~0U; - -/// Used by ObjId and Eref -const unsigned int BADINDEX = ~1U; diff --git a/basecode/global.cpp b/basecode/global.cpp index 6cca169009..a8ebfb7cad 100644 --- a/basecode/global.cpp +++ b/basecode/global.cpp @@ -32,25 +32,16 @@ unsigned int totalTests = 0; stringstream errorSS; -bool isRNGInitialized = false; - clock_t simClock = clock(); -extern int checkPath(const string& path); -extern string joinPath(string pathA, string pathB); -extern string fixPath(string path); -extern string dumpStats(int); - namespace moose { -unsigned long __rng_seed__ = 0; map> solverProfMap = {{"Ksolve", {0.0, 0}}, {"HSolve", {0.0, 0}} }; -moose::RNG rng; /* Check if path is OK */ int checkPath(const string& path) @@ -87,29 +78,6 @@ string fixPath(string path) return path; } -/** - * @brief Set the global seed or all rngs. - * - * @param x - */ -void mtseed(unsigned int x) -{ - moose::__rng_seed__ = x; - moose::rng.setSeed(x); - isRNGInitialized = true; -} - -/* Generate a random number */ -double mtrand(void) -{ - return moose::rng.uniform(); -} - -double mtrand(double a, double b) -{ - return (b - a) * mtrand() + a; -} - // MOOSE suffixes [0] to all elements to path. Remove [0] with null // character whenever possible. For n > 0, [n] should not be touched. Its // the user job to take the pain and write the correct path. @@ -251,6 +219,7 @@ string moosePathToColumnName(const string& path, char delim, size_t maxParents) return colname; } + /* Return formatted string * Precision is upto 17 decimal points. */ @@ -261,15 +230,6 @@ string toString(double x) return string(buffer); } -int getGlobalSeed() -{ - return __rng_seed__; -} - -void setGlobalSeed(int seed) -{ - __rng_seed__ = seed; -} void addSolverProf(const string& name, double time, size_t steps) { @@ -283,4 +243,6 @@ void printSolverProfMap() cout << '\t' << v.first << ": " << v.second[0] << " sec (" << v.second[1] << ")" << endl; } + + } diff --git a/basecode/global.h b/basecode/global.h index 992b562baa..5d0d2feed0 100644 --- a/basecode/global.h +++ b/basecode/global.h @@ -16,7 +16,6 @@ #include #include -#include "../randnum/RNG.h" /* Use inbuilt rng */ #include "../utility/print_function.hpp" using namespace std; @@ -56,17 +55,8 @@ extern unsigned int totalTests; namespace moose { -extern moose::RNG rng; - extern map> solverProfMap; -/** - * @brief A global seed for all RNGs in moose. When moose.seed( x ) is called, - * this variable is set. Other's RNGs (except muparser) uses this seed to - * initialize them. By default it is initialized by random_device (see - * global.cpp). - */ -extern unsigned long __rng_seed__; /** * @brief Fix a path. For testing purpose. @@ -100,31 +90,7 @@ int checkPath(const string& path); */ string joinPath(string pathA, string pathB); -/** - * @brief Seed seed for RNG. - * - * @param seed - */ -void mtseed(unsigned int seed); - -/** - * @brief Generate a random double between 0 and 1 - * - * @return A random number between 0 and 1. - */ -double mtrand(void); -/* --------------------------------------------------------------------------*/ -/** - * @Synopsis Overloaded function. Random number between a and b - * - * @Param a lower limit. - * @Param b Upper limit. - * - * @Returns - */ -/* ----------------------------------------------------------------------------*/ -double mtrand(double a, double b); /** * @brief Create a POSIX compatible path from a given string. @@ -145,6 +111,7 @@ string createMOOSEPath(const string& path); */ string toString(double x); + /** * @brief Create directory, recursively. */ @@ -200,24 +167,7 @@ string moosePathToUserPath(string path); string moosePathToColumnName(const string& path, char delim = '.', size_t maxParents = 1); -/* --------------------------------------------------------------------------*/ -/** - * @Synopsis Get the global seed set by call of moose.seed( X ) - * - * @Returns seed (int). - */ -/* ----------------------------------------------------------------------------*/ -int getGlobalSeed(); -/* --------------------------------------------------------------------------*/ -/** - * @Synopsis Set the seed for all random generator. When seed of a RNG is - * not set, this seed it used. It is set to -1 by default. - * - * @Param seed - */ -/* ----------------------------------------------------------------------------*/ -void setGlobalSeed(int seed); /* --------------------------------------------------------------------------*/ /** @@ -230,6 +180,7 @@ void setGlobalSeed(int seed); /* ----------------------------------------------------------------------------*/ void addSolverProf(const string& name, double time, size_t steps = 1); void printSolverProfMap(); + } #endif /* ----- #ifndef __MOOSE_GLOBAL_INC_ ----- */ diff --git a/basecode/header.h b/basecode/header.h index 97a8bdf450..0a059991b2 100644 --- a/basecode/header.h +++ b/basecode/header.h @@ -25,6 +25,12 @@ using namespace std; +constexpr double PI = 3.141592653589793; +constexpr double NA = 6.0221415e23; +constexpr double FaradayConst = 96485.3415; // s A / mol +constexpr double GasConst = 8.3144621; // R, units are J/(K.mol) + +typedef unsigned short BindIndex; /** * Looks up and uniquely identifies functions, on a per-Cinfo basis. @@ -37,42 +43,20 @@ typedef unsigned int FuncId; */ typedef unsigned int DataId; -/** - * Identifies data entry on an Element. This is a global index, - * in that it does not refer to the array on any given node, but uniquely - * identifies the entry over the entire multinode simulation. - */ -extern const unsigned int ALLDATA; // Defined in consts.cpp +/// Used by ObjId and Eref +const unsigned int ALLDATA = ~0U; -/// Identifies bad DataIndex or FieldIndex in ObjId. -extern const unsigned int BADINDEX; // Defined in consts.cpp - -/** - * Index into Element::vector< vector< MsgFuncBinding > > msgBinding_; - */ -typedef unsigned short BindIndex; - -extern const double PI; // Defined in consts.cpp -extern const double NA; // Defined in consts.cpp -extern const double FaradayConst; // Defined in consts.cpp -extern const double GasConst; // Defined in consts.cpp - -class Element; -class Eref; -class OpFunc; -class Cinfo; -class SetGet; -class FuncBarrier; -class ObjId; -class SrcFinfo; +/// Used by ObjId and Eref +const unsigned int BADINDEX = ~1U; #include "doubleEq.h" #include "Id.h" #include "ObjId.h" +#include "Cinfo.h" + #include "Finfo.h" #include "DestFinfo.h" #include "ProcInfo.h" -#include "Cinfo.h" #include "MsgFuncBinding.h" #include "../msg/Msg.h" #include "Dinfo.h" @@ -86,7 +70,6 @@ class SrcFinfo; #include "SrcFinfo.h" extern DestFinfo* receiveGet(); -class Neutral; #include "OpFuncBase.h" #include "HopFunc.h" #include "SetGet.h" diff --git a/basecode/testAsync.cpp b/basecode/testAsync.cpp index 3ba2b25057..aaa8f0d109 100644 --- a/basecode/testAsync.cpp +++ b/basecode/testAsync.cpp @@ -30,7 +30,7 @@ #include "../scheduling/Clock.h" #include "../builtins/Arith.h" #include "../biophysics/IntFire.h" -#include "../randnum/RNG.h" +#include "../randnum/randnum.h" #include @@ -38,942 +38,941 @@ int _seed_ = 0; void showFields() { - const Cinfo* nc = Neutral::initCinfo(); - Id i1 = Id::nextId(); - Element* ret = new GlobalDataElement( i1, nc, "test1", 1 ); - assert( ret ); - // i1.eref().element()->showFields(); - cout << "." << flush; - - delete i1.element(); + const Cinfo* nc = Neutral::initCinfo(); + Id i1 = Id::nextId(); + Element* ret = new GlobalDataElement(i1, nc, "test1", 1); + assert(ret); + // i1.eref().element()->showFields(); + cout << "." << flush; + + delete i1.element(); } void testSendMsg() { - const Cinfo* ac = Arith::initCinfo(); - unsigned int size = 100; - - const DestFinfo* df = dynamic_cast< const DestFinfo* >( - ac->findFinfo( "setOutputValue" ) ); - assert( df != 0 ); - FuncId fid = df->getFid(); - - Id i1 = Id::nextId(); - Id i2 = Id::nextId(); - Element* ret = new GlobalDataElement( i1, ac, "test1", size ); - // bool ret = nc->create( i1, "test1", size ); - assert( ret ); - // ret = nc->create( i2, "test2", size ); - ret = new GlobalDataElement( i2, ac, "test2", size ); - assert( ret ); - - Eref e1 = i1.eref(); - Eref e2 = i2.eref(); - - Msg* m = new OneToOneMsg( e1, e2, 0 ); - vector< vector< Eref > > ver; - m->targets( ver ); - assert( ver.size() == size ); - assert( ver[0].size() == 1 ); - assert( ver[0][0].element() == e2.element() ); - assert( ver[0][0].dataIndex() == e2.dataIndex() ); - assert( ver[55].size() == 1 ); - assert( ver[55][0].element() == e2.element() ); - assert( ver[55][0].dataIndex() == 55 ); - - SrcFinfo1 s( "test", "" ); - s.setBindIndex( 0 ); - e1.element()->addMsgAndFunc( m->mid(), fid, s.getBindIndex() ); - // e1.element()->digestMessages(); - const vector< MsgDigest >& md = e1.element()->msgDigest( 0 ); - assert( md.size() == 1 ); - assert( md[0].targets.size() == 1 ); - assert( md[0].targets[0].element() == e2.element() ); - assert( md[0].targets[0].dataIndex() == e2.dataIndex() ); - - for ( unsigned int i = 0; i < size; ++i ) { - double x = i + i * i; - s.send( Eref( e1.element(), i ), x ); - } - - for ( unsigned int i = 0; i < size; ++i ) { - double temp = i + i * i; - double val = reinterpret_cast< Arith* >(e2.element()->data( i ) )->getOutput(); - assert( doubleEq( val, temp ) ); - } - cout << "." << flush; - - delete i1.element(); - delete i2.element(); + const Cinfo* ac = Arith::initCinfo(); + unsigned int size = 100; + + const DestFinfo* df = + dynamic_cast(ac->findFinfo("setOutputValue")); + assert(df != 0); + FuncId fid = df->getFid(); + + Id i1 = Id::nextId(); + Id i2 = Id::nextId(); + Element* ret = new GlobalDataElement(i1, ac, "test1", size); + // bool ret = nc->create( i1, "test1", size ); + assert(ret); + // ret = nc->create( i2, "test2", size ); + ret = new GlobalDataElement(i2, ac, "test2", size); + assert(ret); + + Eref e1 = i1.eref(); + Eref e2 = i2.eref(); + + Msg* m = new OneToOneMsg(e1, e2, 0); + vector> ver; + m->targets(ver); + assert(ver.size() == size); + assert(ver[0].size() == 1); + assert(ver[0][0].element() == e2.element()); + assert(ver[0][0].dataIndex() == e2.dataIndex()); + assert(ver[55].size() == 1); + assert(ver[55][0].element() == e2.element()); + assert(ver[55][0].dataIndex() == 55); + + SrcFinfo1 s("test", ""); + s.setBindIndex(0); + e1.element()->addMsgAndFunc(m->mid(), fid, s.getBindIndex()); + // e1.element()->digestMessages(); + const vector& md = e1.element()->msgDigest(0); + assert(md.size() == 1); + assert(md[0].targets.size() == 1); + assert(md[0].targets[0].element() == e2.element()); + assert(md[0].targets[0].dataIndex() == e2.dataIndex()); + + for(unsigned int i = 0; i < size; ++i) { + double x = i + i * i; + s.send(Eref(e1.element(), i), x); + } + + for(unsigned int i = 0; i < size; ++i) { + double temp = i + i * i; + double val = + reinterpret_cast(e2.element()->data(i))->getOutput(); + assert(doubleEq(val, temp)); + } + cout << "." << flush; + + delete i1.element(); + delete i2.element(); } // This used to use parent/child msg, but that has other implications // as it causes deletion of elements. void testCreateMsg() { - const Cinfo* ac = Arith::initCinfo(); - unsigned int size = 100; - Id i1 = Id::nextId(); - Id i2 = Id::nextId(); - Element* temp = new GlobalDataElement( i1, ac, "test1", size ); - // bool ret = nc->create( i1, "test1", size ); - assert( temp ); - temp = new GlobalDataElement( i2, ac, "test2", size ); - assert( temp ); - - Eref e1 = i1.eref(); - Eref e2 = i2.eref(); - - OneToOneMsg *m = new OneToOneMsg( e1, e2, 0 ); - assert( m ); - const Finfo* f1 = ac->findFinfo( "output" ); - assert( f1 ); - const Finfo* f2 = ac->findFinfo( "arg1" ); - assert( f2 ); - bool ret = f1->addMsg( f2, m->mid(), e1.element() ); - - assert( ret ); - // e1.element()->digestMessages(); - - for ( unsigned int i = 0; i < size; ++i ) { - const SrcFinfo1< double >* sf = dynamic_cast< const SrcFinfo1< double >* >( f1 ); - assert( sf != 0 ); - sf->send( Eref( e1.element(), i ), double( i ) ); - double val = reinterpret_cast< Arith* >(e2.element()->data( i ) )->getArg1(); - assert( doubleEq( val, i ) ); - } - - /* - for ( unsigned int i = 0; i < size; ++i ) - cout << i << " " << reinterpret_cast< Neutral* >(e2.element()->data( i ))->getName() << endl; + const Cinfo* ac = Arith::initCinfo(); + unsigned int size = 100; + Id i1 = Id::nextId(); + Id i2 = Id::nextId(); + Element* temp = new GlobalDataElement(i1, ac, "test1", size); + // bool ret = nc->create( i1, "test1", size ); + assert(temp); + temp = new GlobalDataElement(i2, ac, "test2", size); + assert(temp); + + Eref e1 = i1.eref(); + Eref e2 = i2.eref(); + + OneToOneMsg* m = new OneToOneMsg(e1, e2, 0); + assert(m); + const Finfo* f1 = ac->findFinfo("output"); + assert(f1); + const Finfo* f2 = ac->findFinfo("arg1"); + assert(f2); + bool ret = f1->addMsg(f2, m->mid(), e1.element()); + + assert(ret); + // e1.element()->digestMessages(); + + for(unsigned int i = 0; i < size; ++i) { + const SrcFinfo1* sf = + dynamic_cast*>(f1); + assert(sf != 0); + sf->send(Eref(e1.element(), i), double(i)); + double val = reinterpret_cast(e2.element()->data(i))->getArg1(); + assert(doubleEq(val, i)); + } + + /* + for ( unsigned int i = 0; i < size; ++i ) + cout << i << " " << reinterpret_cast< Neutral* >(e2.element()->data( + i ))->getName() << endl; */ - cout << "." << flush; - delete i1.element(); - delete i2.element(); + cout << "." << flush; + delete i1.element(); + delete i2.element(); } void testSetGet() { - const Cinfo* ac = Arith::initCinfo(); - unsigned int size = 100; - - string arg; - Id i2 = Id::nextId(); - Element* ret = new GlobalDataElement( i2, ac, "test2", size ); - assert( ret ); - ProcInfo p; - - for ( unsigned int i = 0; i < size; ++i ) { - ObjId oid( i2, i ); - double x = i * 3.14; - bool ret = Field< double >::set( oid, "outputValue", x ); - assert( ret ); - double val = reinterpret_cast< Arith* >(oid.data())->getOutput(); - assert( doubleEq( val, x ) ); - } - - for ( unsigned int i = 0; i < size; ++i ) { - ObjId oid( i2, i ); - double x = i * 3.14; - double ret = Field< double >::get( oid, "outputValue" ); - ProcInfo p; - assert( doubleEq( ret, x ) ); - } - - cout << "." << flush; - delete i2.element(); + const Cinfo* ac = Arith::initCinfo(); + unsigned int size = 100; + + string arg; + Id i2 = Id::nextId(); + Element* ret = new GlobalDataElement(i2, ac, "test2", size); + assert(ret); + ProcInfo p; + + for(unsigned int i = 0; i < size; ++i) { + ObjId oid(i2, i); + double x = i * 3.14; + bool ret = Field::set(oid, "outputValue", x); + assert(ret); + double val = reinterpret_cast(oid.data())->getOutput(); + assert(doubleEq(val, x)); + } + + for(unsigned int i = 0; i < size; ++i) { + ObjId oid(i2, i); + double x = i * 3.14; + double ret = Field::get(oid, "outputValue"); + ProcInfo p; + assert(doubleEq(ret, x)); + } + + cout << "." << flush; + delete i2.element(); } void testStrSet() { - const Cinfo* ac = Arith::initCinfo(); - unsigned int size = 100; - - string arg; - Id i2 = Id::nextId(); - Element* ret = new GlobalDataElement( i2, ac, "test2", size ); - assert( ret ); - ProcInfo p; - - Shell::adopt( Id(), i2, 0 ); - - assert( ret->getName() == "test2" ); - bool ok = SetGet::strSet( ObjId( i2, 0 ), "name", "NewImprovedTest" ); - assert( ok ); - assert( ret->getName() == "NewImprovedTest" ); - - for ( unsigned int i = 0; i < size; ++i ) { - double x = sqrt((double) i ); - // Eref dest( e2.element(), i ); - ObjId dest( i2, i ); - stringstream ss; - ss << setw( 10 ) << x; - ok = SetGet::strSet( dest, "outputValue", ss.str() ); - assert( ok ); - // SetGet1< double >::set( dest, "setOutputValue", x ); - } - - for ( unsigned int i = 0; i < size; ++i ) { - double temp = sqrt((double) i ); - double val = reinterpret_cast< Arith* >( - Eref( i2.element(), i ).data() )->getOutput(); - assert( fabs( val - temp ) < 1e-5 ); - // DoubleEq won't work here because string is truncated. - } - - cout << "." << flush; - - delete i2.element(); + const Cinfo* ac = Arith::initCinfo(); + unsigned int size = 100; + + string arg; + Id i2 = Id::nextId(); + Element* ret = new GlobalDataElement(i2, ac, "test2", size); + assert(ret); + ProcInfo p; + + Shell::adopt(Id(), i2, 0); + + assert(ret->getName() == "test2"); + bool ok = SetGet::strSet(ObjId(i2, 0), "name", "NewImprovedTest"); + assert(ok); + assert(ret->getName() == "NewImprovedTest"); + + for(unsigned int i = 0; i < size; ++i) { + double x = sqrt((double)i); + // Eref dest( e2.element(), i ); + ObjId dest(i2, i); + stringstream ss; + ss << setw(10) << x; + ok = SetGet::strSet(dest, "outputValue", ss.str()); + assert(ok); + // SetGet1< double >::set( dest, "setOutputValue", x ); + } + + for(unsigned int i = 0; i < size; ++i) { + double temp = sqrt((double)i); + double val = + reinterpret_cast(Eref(i2.element(), i).data())->getOutput(); + assert(fabs(val - temp) < 1e-5); + // DoubleEq won't work here because string is truncated. + } + + cout << "." << flush; + + delete i2.element(); } void testGet() { - const Cinfo* ac = Arith::initCinfo(); - unsigned int size = 100; - string arg; - Id i2 = Id::nextId(); - - Element* ret = new GlobalDataElement( i2, ac, "test2", size ); - assert( ret ); - ProcInfo p; - - ObjId oid( i2, 0 ); - - string val = Field< string >::get( oid, "name" ); - assert( val == "test2" ); - ret->setName( "HupTwoThree" ); - val = Field< string >::get( oid, "name" ); - assert( val == "HupTwoThree" ); - - for ( unsigned int i = 0; i < size; ++i ) { - double temp = i * 3; - reinterpret_cast< Arith* >(oid.element()->data( i ))->setOutput( temp ); - } - - for ( unsigned int i = 0; i < size; ++i ) { - // Eref dest( e2.element(), i ); - ObjId dest( i2, i ); - - double val = Field< double >::get( dest, "outputValue" ); - double temp = i * 3; - assert( doubleEq( val, temp ) ); - } - - cout << "." << flush; - delete i2.element(); + const Cinfo* ac = Arith::initCinfo(); + unsigned int size = 100; + string arg; + Id i2 = Id::nextId(); + + Element* ret = new GlobalDataElement(i2, ac, "test2", size); + assert(ret); + ProcInfo p; + + ObjId oid(i2, 0); + + string val = Field::get(oid, "name"); + assert(val == "test2"); + ret->setName("HupTwoThree"); + val = Field::get(oid, "name"); + assert(val == "HupTwoThree"); + + for(unsigned int i = 0; i < size; ++i) { + double temp = i * 3; + reinterpret_cast(oid.element()->data(i))->setOutput(temp); + } + + for(unsigned int i = 0; i < size; ++i) { + // Eref dest( e2.element(), i ); + ObjId dest(i2, i); + + double val = Field::get(dest, "outputValue"); + double temp = i * 3; + assert(doubleEq(val, temp)); + } + + cout << "." << flush; + delete i2.element(); } void testStrGet() { - const Cinfo* ac = Arith::initCinfo(); - unsigned int size = 100; - string arg; - Id i2 = Id::nextId(); - - Element* ret = new GlobalDataElement( i2, ac, "test2", size ); - assert( ret ); - ProcInfo p; - - ObjId oid( i2, 0 ); - - string val; - bool ok = SetGet::strGet( oid, "name", val ); - assert( ok ); - assert( val == "test2" ); - ret->setName( "HupTwoThree" ); - ok = SetGet::strGet( oid, "name", val ); - assert( ok ); - assert( val == "HupTwoThree" ); - - for ( unsigned int i = 0; i < size; ++i ) { - double temp = i * 3; - reinterpret_cast< Arith* >( ObjId( i2, i ).data() )->setOutput( temp ); - } - - for ( unsigned int i = 0; i < size; ++i ) { - // Eref dest( e2.element(), i ); - ObjId dest( i2, i ); - ok = SetGet::strGet( dest, "outputValue", val ); - assert( ok ); - double conv = atof( val.c_str() ); - double temp = i * 3; - assert( fabs( conv - temp ) < 1e-5 ); - // DoubleEq won't work here because string is truncated. - } - - cout << "." << flush; - delete i2.element(); + const Cinfo* ac = Arith::initCinfo(); + unsigned int size = 100; + string arg; + Id i2 = Id::nextId(); + + Element* ret = new GlobalDataElement(i2, ac, "test2", size); + assert(ret); + ProcInfo p; + + ObjId oid(i2, 0); + + string val; + bool ok = SetGet::strGet(oid, "name", val); + assert(ok); + assert(val == "test2"); + ret->setName("HupTwoThree"); + ok = SetGet::strGet(oid, "name", val); + assert(ok); + assert(val == "HupTwoThree"); + + for(unsigned int i = 0; i < size; ++i) { + double temp = i * 3; + reinterpret_cast(ObjId(i2, i).data())->setOutput(temp); + } + + for(unsigned int i = 0; i < size; ++i) { + // Eref dest( e2.element(), i ); + ObjId dest(i2, i); + ok = SetGet::strGet(dest, "outputValue", val); + assert(ok); + double conv = atof(val.c_str()); + double temp = i * 3; + assert(fabs(conv - temp) < 1e-5); + // DoubleEq won't work here because string is truncated. + } + + cout << "." << flush; + delete i2.element(); } - void testSetGetDouble() { - const Cinfo* ic = IntFire::initCinfo(); - unsigned int size = 100; - - string arg; - Id i2 = Id::nextId(); - // Id i3( i2.value() + 1 ); - Element* ret = new GlobalDataElement( i2, ic, "test2", size ); - assert( ret ); - ProcInfo p; - - for ( unsigned int i = 0; i < size; ++i ) { - // Eref e2( i2(), i ); - ObjId oid( i2, i ); - double temp = i; - bool ret = Field< double >::set( oid, "Vm", temp ); - assert( ret ); - assert( - doubleEq ( reinterpret_cast< IntFire* >(oid.data())->getVm() , temp ) ); - } - - for ( unsigned int i = 0; i < size; ++i ) { - ObjId oid( i2, i ); - double temp = i; - double ret = Field< double >::get( oid, "Vm" ); - assert( doubleEq( temp, ret ) ); - } - - cout << "." << flush; - delete i2.element(); - // delete i3.element(); + const Cinfo* ic = IntFire::initCinfo(); + unsigned int size = 100; + + string arg; + Id i2 = Id::nextId(); + // Id i3( i2.value() + 1 ); + Element* ret = new GlobalDataElement(i2, ic, "test2", size); + assert(ret); + ProcInfo p; + + for(unsigned int i = 0; i < size; ++i) { + // Eref e2( i2(), i ); + ObjId oid(i2, i); + double temp = i; + bool ret = Field::set(oid, "Vm", temp); + assert(ret); + assert(doubleEq(reinterpret_cast(oid.data())->getVm(), temp)); + } + + for(unsigned int i = 0; i < size; ++i) { + ObjId oid(i2, i); + double temp = i; + double ret = Field::get(oid, "Vm"); + assert(doubleEq(temp, ret)); + } + + cout << "." << flush; + delete i2.element(); + // delete i3.element(); } void testSetGetSynapse() { - const Cinfo* ssh = SimpleSynHandler::initCinfo(); - unsigned int size = 100; - - string arg; - Id handler = Id::nextId(); - Element* temp = new GlobalDataElement( handler, ssh, "test2", size ); - assert( temp ); - vector< unsigned int > ns( size ); - vector< vector< double > > delay( size ); - for ( unsigned int i = 0; i < size; ++i ) { - ns[i] = i; - for ( unsigned int j = 0; j < i; ++j ) { - double temp = i * 1000 + j; - delay[i].push_back( temp ); - } - } - - bool ret = Field< unsigned int >::setVec( handler, "numSynapse", ns ); - assert( ret ); - assert( temp->numData() == size ); - Id syns( handler.value() + 1 ); - for ( unsigned int i = 0; i < size; ++i ) { - ret = Field< double >:: - setVec( ObjId( syns, i ), "delay", delay[i] ); - if ( i > 0 ) - assert( ret ); - } - - for ( unsigned int i = 0; i < size; ++i ) { - assert( syns.element()->numField( i ) == i ); - SimpleSynHandler* s = - reinterpret_cast< SimpleSynHandler* >( temp->data( i ) ); - assert( s->getNumSynapses() == i ); - for ( unsigned int j = 0; j < i; ++j ) { - // ObjId oid( syns, i, j ); - ObjId oid( syns, i, j ); - double x = i * 1000 + j ; - double d = Field< double >::get( oid, "delay" ); - double d2 = s->getSynapse( j )->getDelay(); - assert( doubleEq( d, x ) ); - assert( doubleEq( d2, x ) ); - } - } - delete syns.element(); - delete temp; - cout << "." << flush; + const Cinfo* ssh = SimpleSynHandler::initCinfo(); + unsigned int size = 100; + + string arg; + Id handler = Id::nextId(); + Element* temp = new GlobalDataElement(handler, ssh, "test2", size); + assert(temp); + vector ns(size); + vector> delay(size); + for(unsigned int i = 0; i < size; ++i) { + ns[i] = i; + for(unsigned int j = 0; j < i; ++j) { + double temp = i * 1000 + j; + delay[i].push_back(temp); + } + } + + bool ret = Field::setVec(handler, "numSynapse", ns); + assert(ret); + assert(temp->numData() == size); + Id syns(handler.value() + 1); + for(unsigned int i = 0; i < size; ++i) { + ret = Field::setVec(ObjId(syns, i), "delay", delay[i]); + if(i > 0) + assert(ret); + } + + for(unsigned int i = 0; i < size; ++i) { + assert(syns.element()->numField(i) == i); + SimpleSynHandler* s = + reinterpret_cast(temp->data(i)); + assert(s->getNumSynapses() == i); + for(unsigned int j = 0; j < i; ++j) { + // ObjId oid( syns, i, j ); + ObjId oid(syns, i, j); + double x = i * 1000 + j; + double d = Field::get(oid, "delay"); + double d2 = s->getSynapse(j)->getDelay(); + assert(doubleEq(d, x)); + assert(doubleEq(d2, x)); + } + } + delete syns.element(); + delete temp; + cout << "." << flush; } void testSetGetVec() { - const Cinfo* sc = SimpleSynHandler::initCinfo(); - unsigned int size = 100; - - string arg; - Id i2 = Id::nextId(); - Element* temp = new GlobalDataElement( i2, sc, "test2", size ); - assert( temp ); - - vector< unsigned int > numSyn( size, 0 ); - for ( unsigned int i = 0; i < size; ++i ) - numSyn[i] = i; - - Eref e2( i2.element(), 0 ); - // Here we test setting a 1-D vector - bool ret = Field< unsigned int >::setVec( i2, "numSynapse", numSyn ); - assert( ret ); - - for ( unsigned int i = 0; i < size; ++i ) { - SimpleSynHandler* ssh = reinterpret_cast< SimpleSynHandler* >( i2.element()->data( i ) ); - assert( ssh->getNumSynapses() == i ); - } - - vector< unsigned int > getSyn; - - Field< unsigned int >::getVec( i2, "numSynapse", getSyn ); - assert (getSyn.size() == size ); - for ( unsigned int i = 0; i < size; ++i ) - assert( getSyn[i] == i ); - - Id synapse( i2.value() + 1 ); - delete synapse.element(); - delete temp; - cout << "." << flush; + const Cinfo* sc = SimpleSynHandler::initCinfo(); + unsigned int size = 100; + + string arg; + Id i2 = Id::nextId(); + Element* temp = new GlobalDataElement(i2, sc, "test2", size); + assert(temp); + + vector numSyn(size, 0); + for(unsigned int i = 0; i < size; ++i) + numSyn[i] = i; + + Eref e2(i2.element(), 0); + // Here we test setting a 1-D vector + bool ret = Field::setVec(i2, "numSynapse", numSyn); + assert(ret); + + for(unsigned int i = 0; i < size; ++i) { + SimpleSynHandler* ssh = + reinterpret_cast(i2.element()->data(i)); + assert(ssh->getNumSynapses() == i); + } + + vector getSyn; + + Field::getVec(i2, "numSynapse", getSyn); + assert(getSyn.size() == size); + for(unsigned int i = 0; i < size; ++i) + assert(getSyn[i] == i); + + Id synapse(i2.value() + 1); + delete synapse.element(); + delete temp; + cout << "." << flush; } void testSendSpike() { - static const double WEIGHT = -1.0; - static const double TAU = 1.0; - static const double DT = 0.1; - const Cinfo* ic = IntFire::initCinfo(); - const Cinfo* sc = Synapse::initCinfo(); - unsigned int size = 100; - - string arg; - Id i2 = Id::nextId(); - Element* temp = new GlobalDataElement( i2, ic, "test2", size ); - assert( temp ); - Id i3 = Id::nextId(); - Element* temp2 = new GlobalDataElement( i3, sc, "syns", size ); - assert( temp2 ); - Eref e2 = i2.eref(); - for ( unsigned int i = 0; i < size; ++i ) { - ObjId oid( i3, i ); - bool ret = Field< unsigned int >::set( oid, "numSynapses", i ); - assert( ret ); - } - - Id synId( i3.value() + 1 ); - ObjId target( synId , 1 ); - - reinterpret_cast< Synapse* >(target.data())->setWeight( WEIGHT ); - reinterpret_cast< Synapse* >(target.data())->setDelay( 0.01 ); - SingleMsg *m = new SingleMsg( e2, target.eref(), 0 ); - const Finfo* f1 = ic->findFinfo( "spikeOut" ); - const Finfo* f2 = sc->findFinfo( "addSpike" ); - bool ret = f1->addMsg( f2, m->mid(), synId.element() ); - assert( ret ); - - reinterpret_cast< IntFire* >(e2.data())->setVm( 1.0 ); - // ret = SetGet1< double >::set( e2, "Vm", 1.0 ); - ProcInfo p; - p.dt = DT; - reinterpret_cast< IntFire* >(e2.data())->process( e2, &p ); - // At this stage we have sent the spike, so e2.data::Vm should be -1e-7. - double Vm = reinterpret_cast< IntFire* >(e2.data())->getVm(); - assert( doubleEq( Vm, -1e-7 ) ); - ObjId targetCell( i2, 1 ); - reinterpret_cast< IntFire* >(targetCell.data())->setTau( TAU ); - - reinterpret_cast< IntFire* >(targetCell.data())->process( targetCell.eref(), &p ); - Vm = Field< double >::get( targetCell, "Vm" ); - assert( doubleEq( Vm , WEIGHT * ( 1.0 - DT / TAU ) ) ); - delete i2.element(); - delete i3.element(); - delete synId.element(); - cout << "." << flush; + static const double WEIGHT = -1.0; + static const double TAU = 1.0; + static const double DT = 0.1; + const Cinfo* ic = IntFire::initCinfo(); + const Cinfo* sc = Synapse::initCinfo(); + unsigned int size = 100; + + string arg; + Id i2 = Id::nextId(); + Element* temp = new GlobalDataElement(i2, ic, "test2", size); + assert(temp); + Id i3 = Id::nextId(); + Element* temp2 = new GlobalDataElement(i3, sc, "syns", size); + assert(temp2); + Eref e2 = i2.eref(); + for(unsigned int i = 0; i < size; ++i) { + ObjId oid(i3, i); + bool ret = Field::set(oid, "numSynapses", i); + assert(ret); + } + + Id synId(i3.value() + 1); + ObjId target(synId, 1); + + reinterpret_cast(target.data())->setWeight(WEIGHT); + reinterpret_cast(target.data())->setDelay(0.01); + SingleMsg* m = new SingleMsg(e2, target.eref(), 0); + const Finfo* f1 = ic->findFinfo("spikeOut"); + const Finfo* f2 = sc->findFinfo("addSpike"); + bool ret = f1->addMsg(f2, m->mid(), synId.element()); + assert(ret); + + reinterpret_cast(e2.data())->setVm(1.0); + // ret = SetGet1< double >::set( e2, "Vm", 1.0 ); + ProcInfo p; + p.dt = DT; + reinterpret_cast(e2.data())->process(e2, &p); + // At this stage we have sent the spike, so e2.data::Vm should be -1e-7. + double Vm = reinterpret_cast(e2.data())->getVm(); + assert(doubleEq(Vm, -1e-7)); + ObjId targetCell(i2, 1); + reinterpret_cast(targetCell.data())->setTau(TAU); + + reinterpret_cast(targetCell.data()) + ->process(targetCell.eref(), &p); + Vm = Field::get(targetCell, "Vm"); + assert(doubleEq(Vm, WEIGHT * (1.0 - DT / TAU))); + delete i2.element(); + delete i3.element(); + delete synId.element(); + cout << "." << flush; } -void printSparseMatrix( const SparseMatrix< unsigned int >& m) +void printSparseMatrix(const SparseMatrix& m) { - unsigned int nRows = m.nRows(); - unsigned int nCols = m.nColumns(); - - for ( unsigned int i = 0; i < nRows; ++i ) { - cout << "[ "; - for ( unsigned int j = 0; j < nCols; ++j ) { - cout << m.get( i, j ) << " "; - } - cout << "]\n"; - } - const unsigned int *n; - const unsigned int *c; - for ( unsigned int i = 0; i < nRows; ++i ) { - unsigned int num = m.getRow( i, &n, &c ); - for ( unsigned int j = 0; j < num; ++j ) - cout << n[j] << " "; - } - cout << endl; - - for ( unsigned int i = 0; i < nRows; ++i ) { - unsigned int num = m.getRow( i, &n, &c ); - for ( unsigned int j = 0; j < num; ++j ) - cout << c[j] << " "; - } - cout << endl; - cout << endl; + unsigned int nRows = m.nRows(); + unsigned int nCols = m.nColumns(); + + for(unsigned int i = 0; i < nRows; ++i) { + cout << "[ "; + for(unsigned int j = 0; j < nCols; ++j) { + cout << m.get(i, j) << " "; + } + cout << "]\n"; + } + const unsigned int* n; + const unsigned int* c; + for(unsigned int i = 0; i < nRows; ++i) { + unsigned int num = m.getRow(i, &n, &c); + for(unsigned int j = 0; j < num; ++j) + cout << n[j] << " "; + } + cout << endl; + + for(unsigned int i = 0; i < nRows; ++i) { + unsigned int num = m.getRow(i, &n, &c); + for(unsigned int j = 0; j < num; ++j) + cout << c[j] << " "; + } + cout << endl; + cout << endl; } void testSparseMatrix() { - static unsigned int preN[] = { 1, 2, 3, 4, 5, 6, 7 }; - static unsigned int postN[] = { 1, 3, 4, 5, 6, 2, 7 }; - static unsigned int preColIndex[] = { 0, 4, 0, 1, 2, 3, 4 }; - static unsigned int postColIndex[] = { 0, 1, 1, 1, 2, 0, 2 }; - - static unsigned int dropN[] = { 1, 6, 2, 7 }; - static unsigned int dropColIndex[] = { 0, 1, 0, 1 }; - - SparseMatrix< unsigned int > m( 3, 5 ); - unsigned int nRows = m.nRows(); - unsigned int nCols = m.nColumns(); - - m.set( 0, 0, 1 ); - m.set( 0, 4, 2 ); - m.set( 1, 0, 3 ); - m.set( 1, 1, 4 ); - m.set( 1, 2, 5 ); - m.set( 2, 3, 6 ); - m.set( 2, 4, 7 ); - - const unsigned int *n; - const unsigned int *c; - unsigned int k = 0; - for ( unsigned int i = 0; i < nRows; ++i ) { - unsigned int num = m.getRow( i, &n, &c ); - for ( unsigned int j = 0; j < num; ++j ) { - assert( n[j] == preN[ k ] ); - assert( c[j] == preColIndex[ k ] ); - k++; - } - } - assert( k == 7 ); - - // printSparseMatrix( m ); - - m.transpose(); - assert( m.nRows() == nCols ); - assert( m.nColumns() == nRows ); - - k = 0; - for ( unsigned int i = 0; i < nCols; ++i ) { - unsigned int num = m.getRow( i, &n, &c ); - for ( unsigned int j = 0; j < num; ++j ) { - assert( n[j] == postN[ k ] ); - assert( c[j] == postColIndex[ k ] ); - k++; - } - } - assert( k == 7 ); - - // Drop column 1. - vector< unsigned int > keepCols( 2 ); - keepCols[0] = 0; - keepCols[1] = 2; - // cout << endl; m.print(); - m.reorderColumns( keepCols ); - // cout << endl; m.print(); - assert( m.nRows() == nCols ); - assert( m.nColumns() == 2 ); - - k = 0; - for ( unsigned int i = 0; i < nCols; ++i ) { - unsigned int num = m.getRow( i, &n, &c ); - for ( unsigned int j = 0; j < num; ++j ) { - assert( n[j] == dropN[ k ] ); - assert( c[j] == dropColIndex[ k ] ); - k++; - } - } - assert( k == 4 ); - - cout << "." << flush; + static unsigned int preN[] = {1, 2, 3, 4, 5, 6, 7}; + static unsigned int postN[] = {1, 3, 4, 5, 6, 2, 7}; + static unsigned int preColIndex[] = {0, 4, 0, 1, 2, 3, 4}; + static unsigned int postColIndex[] = {0, 1, 1, 1, 2, 0, 2}; + + static unsigned int dropN[] = {1, 6, 2, 7}; + static unsigned int dropColIndex[] = {0, 1, 0, 1}; + + SparseMatrix m(3, 5); + unsigned int nRows = m.nRows(); + unsigned int nCols = m.nColumns(); + + m.set(0, 0, 1); + m.set(0, 4, 2); + m.set(1, 0, 3); + m.set(1, 1, 4); + m.set(1, 2, 5); + m.set(2, 3, 6); + m.set(2, 4, 7); + + const unsigned int* n; + const unsigned int* c; + unsigned int k = 0; + for(unsigned int i = 0; i < nRows; ++i) { + unsigned int num = m.getRow(i, &n, &c); + for(unsigned int j = 0; j < num; ++j) { + assert(n[j] == preN[k]); + assert(c[j] == preColIndex[k]); + k++; + } + } + assert(k == 7); + + // printSparseMatrix( m ); + + m.transpose(); + assert(m.nRows() == nCols); + assert(m.nColumns() == nRows); + + k = 0; + for(unsigned int i = 0; i < nCols; ++i) { + unsigned int num = m.getRow(i, &n, &c); + for(unsigned int j = 0; j < num; ++j) { + assert(n[j] == postN[k]); + assert(c[j] == postColIndex[k]); + k++; + } + } + assert(k == 7); + + // Drop column 1. + vector keepCols(2); + keepCols[0] = 0; + keepCols[1] = 2; + // cout << endl; m.print(); + m.reorderColumns(keepCols); + // cout << endl; m.print(); + assert(m.nRows() == nCols); + assert(m.nColumns() == 2); + + k = 0; + for(unsigned int i = 0; i < nCols; ++i) { + unsigned int num = m.getRow(i, &n, &c); + for(unsigned int j = 0; j < num; ++j) { + assert(n[j] == dropN[k]); + assert(c[j] == dropColIndex[k]); + k++; + } + } + assert(k == 4); + + cout << "." << flush; } void testSparseMatrix2() { - // Here zeroes mean no entry, not an entry of zero. - // Rows 0 to 4 are totally empty - static unsigned int row5[] = { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0 }; - static unsigned int row6[] = { 0, 0, 3, 4, 0, 0, 0, 0, 0, 0 }; - static unsigned int row7[] = { 0, 0, 0, 0, 5, 0, 0, 0, 0, 6 }; - static unsigned int row8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - static unsigned int row9[] = { 0, 0, 7, 0, 0, 0, 0, 8, 0, 0 }; - - vector< vector < unsigned int > > m( 10 ); - for ( unsigned int i = 0; i < 10; ++i ) - m[i].resize( 10, 0 ); - - for ( unsigned int i = 0; i < 10; ++i ) m[5][i] = row5[i]; - for ( unsigned int i = 0; i < 10; ++i ) m[6][i] = row6[i]; - for ( unsigned int i = 0; i < 10; ++i ) m[7][i] = row7[i]; - for ( unsigned int i = 0; i < 10; ++i ) m[8][i] = row8[i]; - for ( unsigned int i = 0; i < 10; ++i ) m[9][i] = row9[i]; - - SparseMatrix< unsigned int > n( 10, 10 ); - for ( unsigned int i = 0; i < 10; ++i ) - for ( unsigned int j = 0; j < 10; ++j ) - if ( m[i][j] != 0 ) - n.set( i, j, m[i][j] ); - - n.transpose(); - for ( unsigned int i = 0; i < 10; ++i ) - for ( unsigned int j = 0; j < 10; ++j ) - assert (n.get( j, i ) == m[i][j] ); - n.transpose(); - for ( unsigned int i = 0; i < 10; ++i ) - for ( unsigned int j = 0; j < 10; ++j ) - assert (n.get( i, j ) == m[i][j] ); - - /////////////////////////////////////////////////////////////// - // Drop columns 2 and 7. - /////////////////////////////////////////////////////////////// - static unsigned int init[] = {0, 1, 3, 4, 5, 6, 8, 9}; - vector< unsigned int > keepCols( - init, init + sizeof( init ) / sizeof( unsigned int ) ); - n.reorderColumns( keepCols ); - for ( unsigned int i = 0; i < 10; ++i ) { - for ( unsigned int j = 0; j < 8; ++j ) { - unsigned int k = keepCols[j]; - assert (n.get( i, j ) == m[i][k] ); - } - } - n.clear(); - n.setSize( 1, 100 ); - for ( unsigned int i = 0; i < 100; ++i ) - n.set( 0, i, 10 * i ); - n.transpose(); - for ( unsigned int i = 0; i < 100; ++i ) - assert( n.get( i, 0 ) == 10 * i ); - n.transpose(); - for ( unsigned int i = 0; i < 100; ++i ) - assert( n.get( 0, i ) == 10 * i ); - - /* - n.printInternal(); - cout << "before transpose\n"; - n.print(); - n.transpose(); - cout << "after transpose\n"; - n.print(); - n.transpose(); - cout << "after transpose back\n"; - n.print(); - */ - - cout << "." << flush; + // Here zeroes mean no entry, not an entry of zero. + // Rows 0 to 4 are totally empty + static unsigned int row5[] = {1, 0, 2, 0, 0, 0, 0, 0, 0, 0}; + static unsigned int row6[] = {0, 0, 3, 4, 0, 0, 0, 0, 0, 0}; + static unsigned int row7[] = {0, 0, 0, 0, 5, 0, 0, 0, 0, 6}; + static unsigned int row8[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + static unsigned int row9[] = {0, 0, 7, 0, 0, 0, 0, 8, 0, 0}; + + vector> m(10); + for(unsigned int i = 0; i < 10; ++i) + m[i].resize(10, 0); + + for(unsigned int i = 0; i < 10; ++i) + m[5][i] = row5[i]; + for(unsigned int i = 0; i < 10; ++i) + m[6][i] = row6[i]; + for(unsigned int i = 0; i < 10; ++i) + m[7][i] = row7[i]; + for(unsigned int i = 0; i < 10; ++i) + m[8][i] = row8[i]; + for(unsigned int i = 0; i < 10; ++i) + m[9][i] = row9[i]; + + SparseMatrix n(10, 10); + for(unsigned int i = 0; i < 10; ++i) + for(unsigned int j = 0; j < 10; ++j) + if(m[i][j] != 0) + n.set(i, j, m[i][j]); + + n.transpose(); + for(unsigned int i = 0; i < 10; ++i) + for(unsigned int j = 0; j < 10; ++j) + assert(n.get(j, i) == m[i][j]); + n.transpose(); + for(unsigned int i = 0; i < 10; ++i) + for(unsigned int j = 0; j < 10; ++j) + assert(n.get(i, j) == m[i][j]); + + /////////////////////////////////////////////////////////////// + // Drop columns 2 and 7. + /////////////////////////////////////////////////////////////// + static unsigned int init[] = {0, 1, 3, 4, 5, 6, 8, 9}; + vector keepCols(init, + init + sizeof(init) / sizeof(unsigned int)); + n.reorderColumns(keepCols); + for(unsigned int i = 0; i < 10; ++i) { + for(unsigned int j = 0; j < 8; ++j) { + unsigned int k = keepCols[j]; + assert(n.get(i, j) == m[i][k]); + } + } + n.clear(); + n.setSize(1, 100); + for(unsigned int i = 0; i < 100; ++i) + n.set(0, i, 10 * i); + n.transpose(); + for(unsigned int i = 0; i < 100; ++i) + assert(n.get(i, 0) == 10 * i); + n.transpose(); + for(unsigned int i = 0; i < 100; ++i) + assert(n.get(0, i) == 10 * i); + + /* + n.printInternal(); + cout << "before transpose\n"; + n.print(); + n.transpose(); + cout << "after transpose\n"; + n.print(); + n.transpose(); + cout << "after transpose back\n"; + n.print(); + */ + + cout << "." << flush; } void testSparseMatrixReorder() { - SparseMatrix< int > n( 2, 1 ); - n.set( 0, 0, -1 ); - n.set( 1, 0, 1 ); - vector< unsigned int > colOrder( 1, 0 ); // Keep the original as is - n.reorderColumns( colOrder ); // This case failed in an earlier version - assert( n.get( 0, 0 ) == -1 ); - assert( n.get( 1, 0 ) == 1 ); - - unsigned int nrows = 4; - unsigned int ncolumns = 5; - - ////////////////////////////////////////////////////////////// - // Test a reordering - ////////////////////////////////////////////////////////////// - n.setSize( nrows, ncolumns ); - for ( unsigned int i = 0; i < nrows; ++i ) { - for ( unsigned int j = 0; j < ncolumns; ++j ) { - int x = i * 10 + j; - n.set( i, j, x ); - } - } - colOrder.resize( ncolumns ); - colOrder[0] = 3; - colOrder[1] = 2; - colOrder[2] = 0; - colOrder[3] = 4; - colOrder[4] = 1; - n.reorderColumns( colOrder ); - assert( n.nRows() == nrows ); - assert( n.nColumns() == ncolumns ); - for ( unsigned int i = 0; i < nrows; ++i ) { - for ( unsigned int j = 0; j < ncolumns; ++j ) { - int x = i * 10 + colOrder[j]; - assert( n.get( i, j ) == x ); - } - } - - ////////////////////////////////////////////////////////////// - // Test reordering + eliminating some columns - ////////////////////////////////////////////////////////////// - // Put back in original config - for ( unsigned int i = 0; i < nrows; ++i ) { - for ( unsigned int j = 0; j < ncolumns; ++j ) { - unsigned int x = i * 10 + j; - n.set( i, j, x ); - } - } - colOrder.resize( 2 ); - colOrder[0] = 3; - colOrder[1] = 2; - n.reorderColumns( colOrder ); - assert( n.nRows() == nrows ); - assert( n.nColumns() == 2 ); - for ( unsigned int i = 0; i < nrows; ++i ) { - assert( n.get( i, 0 ) == static_cast< int >( i * 10 + 3 ) ); - assert( n.get( i, 1 ) == static_cast< int >( i * 10 + 2 ) ); - } - cout << "." << flush; + SparseMatrix n(2, 1); + n.set(0, 0, -1); + n.set(1, 0, 1); + vector colOrder(1, 0); // Keep the original as is + n.reorderColumns(colOrder); // This case failed in an earlier version + assert(n.get(0, 0) == -1); + assert(n.get(1, 0) == 1); + + unsigned int nrows = 4; + unsigned int ncolumns = 5; + + ////////////////////////////////////////////////////////////// + // Test a reordering + ////////////////////////////////////////////////////////////// + n.setSize(nrows, ncolumns); + for(unsigned int i = 0; i < nrows; ++i) { + for(unsigned int j = 0; j < ncolumns; ++j) { + int x = i * 10 + j; + n.set(i, j, x); + } + } + colOrder.resize(ncolumns); + colOrder[0] = 3; + colOrder[1] = 2; + colOrder[2] = 0; + colOrder[3] = 4; + colOrder[4] = 1; + n.reorderColumns(colOrder); + assert(n.nRows() == nrows); + assert(n.nColumns() == ncolumns); + for(unsigned int i = 0; i < nrows; ++i) { + for(unsigned int j = 0; j < ncolumns; ++j) { + int x = i * 10 + colOrder[j]; + assert(n.get(i, j) == x); + } + } + + ////////////////////////////////////////////////////////////// + // Test reordering + eliminating some columns + ////////////////////////////////////////////////////////////// + // Put back in original config + for(unsigned int i = 0; i < nrows; ++i) { + for(unsigned int j = 0; j < ncolumns; ++j) { + unsigned int x = i * 10 + j; + n.set(i, j, x); + } + } + colOrder.resize(2); + colOrder[0] = 3; + colOrder[1] = 2; + n.reorderColumns(colOrder); + assert(n.nRows() == nrows); + assert(n.nColumns() == 2); + for(unsigned int i = 0; i < nrows; ++i) { + assert(n.get(i, 0) == static_cast(i * 10 + 3)); + assert(n.get(i, 1) == static_cast(i * 10 + 2)); + } + cout << "." << flush; } void testSparseMatrixFill() { - SparseMatrix< int > n; - unsigned int nrow = 5; - unsigned int ncol = 7; - vector< unsigned int > row; - vector< unsigned int > col; - vector< int > val; - unsigned int num = 0; - for ( unsigned int i = 0; i < nrow; ++i ) { - for ( unsigned int j = 0; j < ncol; ++j ) { - if ( j == 0 || i + j == 6 || ( j - i) == 2 ) { - row.push_back( i ); - col.push_back( j ); - val.push_back( 100 + i * 10 + j ); - ++num; - } - } - } - n.tripletFill( row, col, val ); - // n.print(); - assert( n.nRows() == nrow ); - assert( n.nColumns() == ncol ); - assert( n.nEntries() == num ); - for ( unsigned int i = 0; i < nrow; ++i ) { - for ( unsigned int j = 0; j < ncol; ++j ) { - int val = n.get( i, j ); - if ( j == 0 || i + j == 6 || ( j - i) == 2 ) - assert( static_cast< unsigned int >( val ) == 100 + i * 10 + j ); - else - assert( val == 0 ); - } - } - cout << "." << flush; + SparseMatrix n; + unsigned int nrow = 5; + unsigned int ncol = 7; + vector row; + vector col; + vector val; + unsigned int num = 0; + for(unsigned int i = 0; i < nrow; ++i) { + for(unsigned int j = 0; j < ncol; ++j) { + if(j == 0 || i + j == 6 || (j - i) == 2) { + row.push_back(i); + col.push_back(j); + val.push_back(100 + i * 10 + j); + ++num; + } + } + } + n.tripletFill(row, col, val); + // n.print(); + assert(n.nRows() == nrow); + assert(n.nColumns() == ncol); + assert(n.nEntries() == num); + for(unsigned int i = 0; i < nrow; ++i) { + for(unsigned int j = 0; j < ncol; ++j) { + int val = n.get(i, j); + if(j == 0 || i + j == 6 || (j - i) == 2) + assert(static_cast(val) == 100 + i * 10 + j); + else + assert(val == 0); + } + } + cout << "." << flush; } -void printGrid( Element* e, const string& field, double min, double max ) +void printGrid(Element* e, const string& field, double min, double max) { - static string icon = " .oO@"; - unsigned int yside = sqrt( double ( e->numData() ) ); - unsigned int xside = e->numData() / yside; - if ( e->numData() % yside > 0 ) - xside++; - - for ( unsigned int i = 0; i < e->numData(); ++i ) { - if ( ( i % xside ) == 0 ) - cout << endl; - Eref er( e, i ); - ObjId oid( e->id(), i ); - double Vm = Field< double >::get( oid, field ); - int shape = 5.0 * ( Vm - min ) / ( max - min ); - if ( shape > 4 ) - shape = 4; - if ( shape < 0 ) - shape = 0; - cout << icon[ shape ]; - } - cout << endl; + static string icon = " .oO@"; + unsigned int yside = sqrt(double(e->numData())); + unsigned int xside = e->numData() / yside; + if(e->numData() % yside > 0) + xside++; + + for(unsigned int i = 0; i < e->numData(); ++i) { + if((i % xside) == 0) + cout << endl; + Eref er(e, i); + ObjId oid(e->id(), i); + double Vm = Field::get(oid, field); + int shape = 5.0 * (Vm - min) / (max - min); + if(shape > 4) + shape = 4; + if(shape < 0) + shape = 0; + cout << icon[shape]; + } + cout << endl; } void testSparseMsg() { - // static const unsigned int NUMSYN = 104576; - static const double thresh = 0.2; - static const double Vmax = 1.0; - static const double refractoryPeriod = 0.4; - static const double weightMax = 0.02; - static const double delayMax = 4; - static const double timestep = 0.2; - static const double connectionProbability = 0.1; - static const unsigned int runsteps = 5; - const Cinfo* ic = IntFire::initCinfo(); - const Cinfo* sshc = SimpleSynHandler::initCinfo(); - const Cinfo* sc = Synapse::initCinfo(); - const Finfo* procFinfo = sshc->findFinfo( "process" ); - assert( procFinfo ); - const DestFinfo* df = dynamic_cast< const DestFinfo* >( procFinfo ); - assert( df ); - // const Cinfo* sc = Synapse::initCinfo(); - unsigned int size = 1024; - - string arg; - - // The default value, but better to be explicit. - moose::setGlobalSeed( 5489UL ); - - Id sshid = Id::nextId(); - Element* t2 = new GlobalDataElement( sshid, sshc, "test2", size ); - assert( t2 ); - Id syns( sshid.value() + 1 ); - Id cells = Id::nextId(); - Element* t3 = new GlobalDataElement( cells, ic, "intFire", size ); - assert( t3 ); - - SparseMsg* sm = new SparseMsg( t3, syns.element(), 0 ); - assert( sm ); - const Finfo* f1 = ic->findFinfo( "spikeOut" ); - const Finfo* f2 = sc->findFinfo( "addSpike" ); - assert( f1 && f2 ); - f1->addMsg( f2, sm->mid(), t3 ); - sm->randomConnect( connectionProbability ); - - vector< double > temp( size, 0.0 ); - for ( unsigned int i = 0; i < size; ++i ) - temp[i] = moose::mtrand() * Vmax; - - bool ret = Field< double >::setVec( cells, "Vm", temp ); - assert( ret ); - temp.clear(); - temp.resize( size, thresh ); - ret = Field< double >::setVec( cells, "thresh", temp ); - assert( ret ); - temp.clear(); - temp.resize( size, refractoryPeriod ); - ret = Field< double >::setVec( cells, "refractoryPeriod", temp ); - assert( ret ); - - unsigned int fieldSize = 5000; - vector< double > weight( size * fieldSize, 0.0 ); - vector< double > delay( size * fieldSize, 0.0 ); - for ( unsigned int i = 0; i < size; ++i ) { - ObjId id( sshid, i ); - unsigned int numSyn = - Field< unsigned int >::get( id, "numSynapse" ); - unsigned int k = i * fieldSize; - for ( unsigned int j = 0; j < numSyn; ++j ) { - weight[ k + j ] = moose::mtrand() * weightMax; - delay[ k + j ] = moose::mtrand() * delayMax; - } - } - ret = Field< double >::setVec( syns, "weight", weight ); - assert( ret ); - ret = Field< double >::setVec( syns, "delay", delay ); - assert( ret ); - - // printGrid( cells(), "Vm", 0, thresh ); - - ProcInfo p; - p.dt = timestep; - for ( unsigned int i = 0; i < runsteps; ++i ) { - p.currTime += p.dt; - SetGet1< ProcInfo* >::setRepeat( sshid, "process", &p ); - SetGet1< ProcInfo* >::setRepeat( cells, "process", &p ); - // cells()->process( &p, df->getFid() ); - } - - delete t2; - delete t3; - cout << "." << flush; + // static const unsigned int NUMSYN = 104576; + static const double thresh = 0.2; + static const double Vmax = 1.0; + static const double refractoryPeriod = 0.4; + static const double weightMax = 0.02; + static const double delayMax = 4; + static const double timestep = 0.2; + static const double connectionProbability = 0.1; + static const unsigned int runsteps = 5; + const Cinfo* ic = IntFire::initCinfo(); + const Cinfo* sshc = SimpleSynHandler::initCinfo(); + const Cinfo* sc = Synapse::initCinfo(); + const Finfo* procFinfo = sshc->findFinfo("process"); + assert(procFinfo); + const DestFinfo* df = dynamic_cast(procFinfo); + assert(df); + // const Cinfo* sc = Synapse::initCinfo(); + unsigned int size = 1024; + + string arg; + + // The default value, but better to be explicit. + moose::setGlobalSeed(5489UL); + + Id sshid = Id::nextId(); + Element* t2 = new GlobalDataElement(sshid, sshc, "test2", size); + assert(t2); + Id syns(sshid.value() + 1); + Id cells = Id::nextId(); + Element* t3 = new GlobalDataElement(cells, ic, "intFire", size); + assert(t3); + + SparseMsg* sm = new SparseMsg(t3, syns.element(), 0); + assert(sm); + const Finfo* f1 = ic->findFinfo("spikeOut"); + const Finfo* f2 = sc->findFinfo("addSpike"); + assert(f1 && f2); + f1->addMsg(f2, sm->mid(), t3); + sm->randomConnect(connectionProbability); + + vector temp(size, 0.0); + for(unsigned int i = 0; i < size; ++i) + temp[i] = moose::mtrand() * Vmax; + + bool ret = Field::setVec(cells, "Vm", temp); + assert(ret); + temp.clear(); + temp.resize(size, thresh); + ret = Field::setVec(cells, "thresh", temp); + assert(ret); + temp.clear(); + temp.resize(size, refractoryPeriod); + ret = Field::setVec(cells, "refractoryPeriod", temp); + assert(ret); + + unsigned int fieldSize = 5000; + vector weight(size * fieldSize, 0.0); + vector delay(size * fieldSize, 0.0); + for(unsigned int i = 0; i < size; ++i) { + ObjId id(sshid, i); + unsigned int numSyn = Field::get(id, "numSynapse"); + unsigned int k = i * fieldSize; + for(unsigned int j = 0; j < numSyn; ++j) { + weight[k + j] = moose::mtrand() * weightMax; + delay[k + j] = moose::mtrand() * delayMax; + } + } + ret = Field::setVec(syns, "weight", weight); + assert(ret); + ret = Field::setVec(syns, "delay", delay); + assert(ret); + + // printGrid( cells(), "Vm", 0, thresh ); + + ProcInfo p; + p.dt = timestep; + for(unsigned int i = 0; i < runsteps; ++i) { + p.currTime += p.dt; + SetGet1::setRepeat(sshid, "process", &p); + SetGet1::setRepeat(cells, "process", &p); + // cells()->process( &p, df->getFid() ); + } + + delete t2; + delete t3; + cout << "." << flush; } void test2ArgSetVec() { - const Cinfo* ac = Arith::initCinfo(); - unsigned int size = 100; - - string arg; - Id i2 = Id::nextId(); - Element* ret = new GlobalDataElement( i2, ac, "test2", size ); - assert( ret ); - - vector< double > arg1( size ); - vector< double > arg2( size ); - for ( unsigned int i = 0; i < size; ++i ) { - arg1[i] = i; - arg2[i] = 100 * ( 100 - i ); - } - - SetGet2< double, double >::setVec( i2, "arg1x2", arg1, arg2 ); - - for ( unsigned int i = 0; i < size; ++i ) { - ObjId oid( i2, i ); - double x = i * 100 * ( 100 - i ); - double val = reinterpret_cast< Arith* >(oid.data())->getOutput(); - assert( doubleEq( val, x ) ); - } - cout << "." << flush; - delete i2.element(); + const Cinfo* ac = Arith::initCinfo(); + unsigned int size = 100; + + string arg; + Id i2 = Id::nextId(); + Element* ret = new GlobalDataElement(i2, ac, "test2", size); + assert(ret); + + vector arg1(size); + vector arg2(size); + for(unsigned int i = 0; i < size; ++i) { + arg1[i] = i; + arg2[i] = 100 * (100 - i); + } + + SetGet2::setVec(i2, "arg1x2", arg1, arg2); + + for(unsigned int i = 0; i < size; ++i) { + ObjId oid(i2, i); + double x = i * 100 * (100 - i); + double val = reinterpret_cast(oid.data())->getOutput(); + assert(doubleEq(val, x)); + } + cout << "." << flush; + delete i2.element(); } - class TestId { - public : - void setId( Id id ) { - id_ = id; - } - Id getId() const { - return id_; - } - static const Cinfo* initCinfo(); - private : - Id id_ ; +public: + void setId(Id id) + { + id_ = id; + } + Id getId() const + { + return id_; + } + static const Cinfo* initCinfo(); + +private: + Id id_; }; // Here we test setRepeat using an Id field. This test is added // because of a memory leak problem that cropped up much later. const Cinfo* TestId::initCinfo() { - static ValueFinfo< TestId, Id > id( - "id", - "test", - &TestId::setId, - &TestId::getId - ); - static Finfo* testIdFinfos[] = {&id}; - static Cinfo testIdCinfo( - "TestIdRepeatAssignment", - Neutral::initCinfo(), - testIdFinfos, - sizeof( testIdFinfos )/ sizeof( Finfo* ), - new Dinfo< TestId >() - ); - return &testIdCinfo; + static ValueFinfo id("id", "test", &TestId::setId, + &TestId::getId); + static Finfo* testIdFinfos[] = {&id}; + static Cinfo testIdCinfo( + "TestIdRepeatAssignment", Neutral::initCinfo(), testIdFinfos, + sizeof(testIdFinfos) / sizeof(Finfo*), new Dinfo()); + return &testIdCinfo; } void testSetRepeat() { - const Cinfo* sc = SimpleSynHandler::initCinfo(); - unsigned int size = 100; - - string arg; - Id cell = Id::nextId(); - Element* temp = new GlobalDataElement( cell, sc, "cell", size ); - assert( temp ); - vector< unsigned int > numSyn( size, 0 ); - for ( unsigned int i = 0; i < size; ++i ) - numSyn[i] = i; - - // Here we test setting a 1-D vector - bool ret = Field< unsigned int >::setVec( cell, "numSynapse", numSyn); - assert( ret ); - - Id synapse( cell.value() + 1 ); - // Here we test setting a 2-D array with different dims on each axis. - for ( unsigned int i = 0; i < size; ++i ) { - ret = Field< double >:: - setRepeat( ObjId( synapse, i ), "delay", 123.0 ); - assert( ret ); - } - for ( unsigned int i = 0; i < size; ++i ) { - vector< double > delay; - Field< double >::getVec( ObjId( synapse, i ), "delay", delay ); - assert( delay.size() == i ); - for ( unsigned int j = 0; j < i; ++j ) { - assert( doubleEq( delay[j], 123.0 ) ); - } - } - - delete synapse.element(); - delete temp; - cout << "." << flush; + const Cinfo* sc = SimpleSynHandler::initCinfo(); + unsigned int size = 100; + + string arg; + Id cell = Id::nextId(); + Element* temp = new GlobalDataElement(cell, sc, "cell", size); + assert(temp); + vector numSyn(size, 0); + for(unsigned int i = 0; i < size; ++i) + numSyn[i] = i; + + // Here we test setting a 1-D vector + bool ret = Field::setVec(cell, "numSynapse", numSyn); + assert(ret); + + Id synapse(cell.value() + 1); + // Here we test setting a 2-D array with different dims on each axis. + for(unsigned int i = 0; i < size; ++i) { + ret = Field::setRepeat(ObjId(synapse, i), "delay", 123.0); + assert(ret); + } + for(unsigned int i = 0; i < size; ++i) { + vector delay; + Field::getVec(ObjId(synapse, i), "delay", delay); + assert(delay.size() == i); + for(unsigned int j = 0; j < i; ++j) { + assert(doubleEq(delay[j], 123.0)); + } + } + + delete synapse.element(); + delete temp; + cout << "." << flush; } /** @@ -983,864 +982,862 @@ void testSetRepeat() * All this is tallied for validating the unit test. */ -static SrcFinfo0 s0( "s0", ""); -class Test -{ - public: - Test() - : numAcks_( 0 ) - {;} - - void process( const Eref& e, ProcPtr p ) - {;} - - void handleS0() { - numAcks_++; - } - - void handleS1( const Eref& e, string s ) { - s_ = s + s_; - s0.send( e ); - } - - void handleS2( const Eref& e, int i1, int i2 ) { - i1_ += 10 * i1; - i2_ += 10 * i2; - s0.send( e ); - } - - static Finfo* sharedVec[ 6 ]; - - static const Cinfo* initCinfo() - { - static SharedFinfo shared( "shared", "", - sharedVec, sizeof( sharedVec ) / sizeof( const Finfo * ) ); - static Finfo * testFinfos[] = { - &shared, - }; - - static Dinfo< Test > dinfo; - static Cinfo testCinfo( - "Test", - 0, - testFinfos, - sizeof( testFinfos ) / sizeof( Finfo* ), - &dinfo - ); - - return &testCinfo; - } - - string s_; - int i1_; - int i2_; - int numAcks_; +static SrcFinfo0 s0("s0", ""); +class Test { +public: + Test() : numAcks_(0) + { + ; + } + + void process(const Eref& e, ProcPtr p) + { + ; + } + + void handleS0() + { + numAcks_++; + } + + void handleS1(const Eref& e, string s) + { + s_ = s + s_; + s0.send(e); + } + + void handleS2(const Eref& e, int i1, int i2) + { + i1_ += 10 * i1; + i2_ += 10 * i2; + s0.send(e); + } + + static Finfo* sharedVec[6]; + + static const Cinfo* initCinfo() + { + static SharedFinfo shared("shared", "", sharedVec, + sizeof(sharedVec) / sizeof(const Finfo*)); + static Finfo* testFinfos[] = { + &shared, + }; + + static Dinfo dinfo; + static Cinfo testCinfo("Test", 0, testFinfos, + sizeof(testFinfos) / sizeof(Finfo*), &dinfo); + + return &testCinfo; + } + + string s_; + int i1_; + int i2_; + int numAcks_; }; Finfo* Test::sharedVec[6]; void testSharedMsg() { - static SrcFinfo1< string > s1( "s1", "" ); - static SrcFinfo2< int, int > s2( "s2", "" ); - static DestFinfo d0( "d0", "", - new OpFunc0< Test >( & Test::handleS0 ) ); - static DestFinfo d1( "d1", "", - new EpFunc1< Test, string >( &Test::handleS1 ) ); - static DestFinfo d2( "d2", "", - new EpFunc2< Test, int, int >( &Test::handleS2 ) ); - - Test::sharedVec[0] = &s0; - Test::sharedVec[1] = &d0; - Test::sharedVec[2] = &s1; - Test::sharedVec[3] = &d1; - Test::sharedVec[4] = &s2; - Test::sharedVec[5] = &d2; - - Id t1 = Id::nextId(); - Id t2 = Id::nextId(); - // bool ret = Test::initCinfo()->create( t1, "test1", 1 ); - - Element* temp = new GlobalDataElement( t1, Test::initCinfo(), "test1", 1 ); - assert( temp ); - temp = new GlobalDataElement( t2, Test::initCinfo(), "test2", 1 ); - // ret = Test::initCinfo()->create( t2, "test2", 1 ); - assert( temp ); - - // Assign initial values - Test* tdata1 = reinterpret_cast< Test* >( t1.eref().data() ); - tdata1->s_ = "tdata1"; - tdata1->i1_ = 1; - tdata1->i2_ = 2; - - Test* tdata2 = reinterpret_cast< Test* >( t2.eref().data() ); - tdata2->s_ = "TDATA2"; - tdata2->i1_ = 5; - tdata2->i2_ = 6; - - // Set up message. The actual routine is in Shell.cpp, but here we - // do it independently. - - const Finfo* shareFinfo = Test::initCinfo()->findFinfo( "shared" ); - assert( shareFinfo != 0 ); - Msg* m = new OneToOneMsg( t1.eref(), t2.eref(), 0 ); - assert( m != 0 ); - bool ret = shareFinfo->addMsg( shareFinfo, m->mid(), t1.element() ); - assert( ret ); - - // t1.element()->digestMessages(); - // t2.element()->digestMessages(); - // Display stuff. Need to figure out how to unit test this. - // t1()->showMsg(); - // t2()->showMsg(); - - // Send messages - ProcInfo p; - string arg1 = " hello "; - s1.send( t1.eref(), arg1 ); - s2.send( t1.eref(), 100, 200 ); - - string arg2 = " goodbye "; - s1.send( t2.eref(), arg2 ); - s2.send( t2.eref(), 500, 600 ); - - /* - cout << "data1: s=" << tdata1->s_ << - ", i1=" << tdata1->i1_ << ", i2=" << tdata1->i2_ << - ", numAcks=" << tdata1->numAcks_ << endl; - cout << "data2: s=" << tdata2->s_ << - ", i1=" << tdata2->i1_ << ", i2=" << tdata2->i2_ << - ", numAcks=" << tdata2->numAcks_ << endl; - */ - // Check results - - assert( tdata1->s_ == " goodbye tdata1" ); - assert( tdata2->s_ == " hello TDATA2" ); - assert( tdata1->i1_ == 5001 ); - assert( tdata1->i2_ == 6002 ); - assert( tdata2->i1_ == 1005 ); - assert( tdata2->i2_ == 2006 ); - assert( tdata1->numAcks_ == 2 ); - assert( tdata2->numAcks_ == 2 ); - - t1.destroy(); - t2.destroy(); - - cout << "." << flush; + static SrcFinfo1 s1("s1", ""); + static SrcFinfo2 s2("s2", ""); + static DestFinfo d0("d0", "", new OpFunc0(&Test::handleS0)); + static DestFinfo d1("d1", "", new EpFunc1(&Test::handleS1)); + static DestFinfo d2("d2", "", new EpFunc2(&Test::handleS2)); + + Test::sharedVec[0] = &s0; + Test::sharedVec[1] = &d0; + Test::sharedVec[2] = &s1; + Test::sharedVec[3] = &d1; + Test::sharedVec[4] = &s2; + Test::sharedVec[5] = &d2; + + Id t1 = Id::nextId(); + Id t2 = Id::nextId(); + // bool ret = Test::initCinfo()->create( t1, "test1", 1 ); + + Element* temp = new GlobalDataElement(t1, Test::initCinfo(), "test1", 1); + assert(temp); + temp = new GlobalDataElement(t2, Test::initCinfo(), "test2", 1); + // ret = Test::initCinfo()->create( t2, "test2", 1 ); + assert(temp); + + // Assign initial values + Test* tdata1 = reinterpret_cast(t1.eref().data()); + tdata1->s_ = "tdata1"; + tdata1->i1_ = 1; + tdata1->i2_ = 2; + + Test* tdata2 = reinterpret_cast(t2.eref().data()); + tdata2->s_ = "TDATA2"; + tdata2->i1_ = 5; + tdata2->i2_ = 6; + + // Set up message. The actual routine is in Shell.cpp, but here we + // do it independently. + + const Finfo* shareFinfo = Test::initCinfo()->findFinfo("shared"); + assert(shareFinfo != 0); + Msg* m = new OneToOneMsg(t1.eref(), t2.eref(), 0); + assert(m != 0); + bool ret = shareFinfo->addMsg(shareFinfo, m->mid(), t1.element()); + assert(ret); + + // t1.element()->digestMessages(); + // t2.element()->digestMessages(); + // Display stuff. Need to figure out how to unit test this. + // t1()->showMsg(); + // t2()->showMsg(); + + // Send messages + ProcInfo p; + string arg1 = " hello "; + s1.send(t1.eref(), arg1); + s2.send(t1.eref(), 100, 200); + + string arg2 = " goodbye "; + s1.send(t2.eref(), arg2); + s2.send(t2.eref(), 500, 600); + + /* + cout << "data1: s=" << tdata1->s_ << + ", i1=" << tdata1->i1_ << ", i2=" << tdata1->i2_ << + ", numAcks=" << tdata1->numAcks_ << endl; + cout << "data2: s=" << tdata2->s_ << + ", i1=" << tdata2->i1_ << ", i2=" << tdata2->i2_ << + ", numAcks=" << tdata2->numAcks_ << endl; + */ + // Check results + + assert(tdata1->s_ == " goodbye tdata1"); + assert(tdata2->s_ == " hello TDATA2"); + assert(tdata1->i1_ == 5001); + assert(tdata1->i2_ == 6002); + assert(tdata2->i1_ == 1005); + assert(tdata2->i2_ == 2006); + assert(tdata1->numAcks_ == 2); + assert(tdata2->numAcks_ == 2); + + t1.destroy(); + t2.destroy(); + + cout << "." << flush; } void testConvVector() { - vector< unsigned int > intVec; - for ( unsigned int i = 0; i < 5; ++i ) - intVec.push_back( i * i ); - - double buf[500]; - double* tempBuf = buf; - - Conv< vector< unsigned int > > intConv; - assert( intConv.size( intVec ) == 1 + intVec.size() ); - intConv.val2buf( intVec, &tempBuf ); - assert( tempBuf == buf + 6 ); - assert( buf[0] == intVec.size() ); - assert( static_cast< unsigned int >( buf[1] ) == intVec[0] ); - assert( static_cast< unsigned int >( buf[2] ) == intVec[1] ); - assert( static_cast< unsigned int >( buf[3] ) == intVec[2] ); - assert( static_cast< unsigned int >( buf[4] ) == intVec[3] ); - assert( static_cast< unsigned int >( buf[5] ) == intVec[4] ); - - tempBuf = buf; - const vector< unsigned int >& testIntVec = intConv.buf2val( &tempBuf ); - - assert( intVec.size() == testIntVec.size() ); - for ( unsigned int i = 0; i < intVec.size(); ++i ) { - assert( intVec[ i ] == testIntVec[i] ); - } - - vector< string > strVec; - strVec.push_back( "one" ); - strVec.push_back( "two" ); - strVec.push_back( "three and more and more and more" ); - strVec.push_back( "four and yet more" ); - - tempBuf = buf; - Conv< vector< string > >::val2buf( strVec, &tempBuf ); - unsigned int sz = Conv< vector< string > >::size( strVec ); - assert( sz == 1 + 2 + ( strVec[2].length() + 8) /8 + ( strVec[3].length() + 8 )/8 ); - assert( buf[0] == 4 ); - assert( strcmp( reinterpret_cast< char* >( buf + 1 ), "one" ) == 0 ); - - tempBuf = buf; - const vector< string >& tgtStr = - Conv< vector< string > >::buf2val( &tempBuf ); - assert( tgtStr.size() == 4 ); - for ( unsigned int i = 0; i < 4; ++i ) - assert( tgtStr[i] == strVec[i] ); - - cout << "." << flush; + vector intVec; + for(unsigned int i = 0; i < 5; ++i) + intVec.push_back(i * i); + + double buf[500]; + double* tempBuf = buf; + + Conv> intConv; + assert(intConv.size(intVec) == 1 + intVec.size()); + intConv.val2buf(intVec, &tempBuf); + assert(tempBuf == buf + 6); + assert(buf[0] == intVec.size()); + assert(static_cast(buf[1]) == intVec[0]); + assert(static_cast(buf[2]) == intVec[1]); + assert(static_cast(buf[3]) == intVec[2]); + assert(static_cast(buf[4]) == intVec[3]); + assert(static_cast(buf[5]) == intVec[4]); + + tempBuf = buf; + const vector& testIntVec = intConv.buf2val(&tempBuf); + + assert(intVec.size() == testIntVec.size()); + for(unsigned int i = 0; i < intVec.size(); ++i) { + assert(intVec[i] == testIntVec[i]); + } + + vector strVec; + strVec.push_back("one"); + strVec.push_back("two"); + strVec.push_back("three and more and more and more"); + strVec.push_back("four and yet more"); + + tempBuf = buf; + Conv>::val2buf(strVec, &tempBuf); + unsigned int sz = Conv>::size(strVec); + assert(sz == + 1 + 2 + (strVec[2].length() + 8) / 8 + (strVec[3].length() + 8) / 8); + assert(buf[0] == 4); + assert(strcmp(reinterpret_cast(buf + 1), "one") == 0); + + tempBuf = buf; + const vector& tgtStr = Conv>::buf2val(&tempBuf); + assert(tgtStr.size() == 4); + for(unsigned int i = 0; i < 4; ++i) + assert(tgtStr[i] == strVec[i]); + + cout << "." << flush; } void testConvVectorOfVectors() { - short *row0 = 0; - short row1[] = { 1 }; - short row2[] = { 2, 3 }; - short row3[] = { 4, 5, 6 }; - short row4[] = { 7, 8, 9, 10 }; - short row5[] = { 11, 12, 13, 14, 15 }; - - vector< vector < short > > vec( 6 ); - vec[0].insert( vec[0].end(), row0, row0 + 0 ); - vec[1].insert( vec[1].end(), row1, row1 + 1 ); - vec[2].insert( vec[2].end(), row2, row2 + 2 ); - vec[3].insert( vec[3].end(), row3, row3 + 3 ); - vec[4].insert( vec[4].end(), row4, row4 + 4 ); - vec[5].insert( vec[5].end(), row5, row5 + 5 ); - - double expected[] = { - 6, // Number of sub-vectors - 0, // No entries on first sub-vec - 1, 1, - 2, 2,3, - 3, 4,5,6, - 4, 7,8,9,10, - 5, 11,12,13,14,15 - }; - - double origBuf[500]; - double* buf = origBuf; - - Conv< vector< vector< short > > > conv; - - assert( conv.size( vec ) == 1 + 6 + 0 + 1 + 2 + 3 + 4 + 5 ); // 21 - conv.val2buf( vec, &buf ); - assert( buf == 22 + origBuf ); - for ( unsigned int i = 0; i < 22; ++i ) - assert( doubleEq( origBuf[i], expected[i] ) ); - - double* buf2 = origBuf; - const vector< vector< short > >& rc = conv.buf2val( &buf2 ); - - assert( rc.size() == 6 ); - for ( unsigned int i = 0; i < 6; ++i ) { - assert( rc[i].size() == i ); - for ( unsigned int j = 0; j < i; ++j ) - assert( rc[i][j] == vec[i][j] ); - } - - cout << "." << flush; + short* row0 = 0; + short row1[] = {1}; + short row2[] = {2, 3}; + short row3[] = {4, 5, 6}; + short row4[] = {7, 8, 9, 10}; + short row5[] = {11, 12, 13, 14, 15}; + + vector> vec(6); + vec[0].insert(vec[0].end(), row0, row0 + 0); + vec[1].insert(vec[1].end(), row1, row1 + 1); + vec[2].insert(vec[2].end(), row2, row2 + 2); + vec[3].insert(vec[3].end(), row3, row3 + 3); + vec[4].insert(vec[4].end(), row4, row4 + 4); + vec[5].insert(vec[5].end(), row5, row5 + 5); + + double expected[] = {6, // Number of sub-vectors + 0, // No entries on first sub-vec + 1, 1, 2, 2, 3, 3, 4, 5, 6, 4, + 7, 8, 9, 10, 5, 11, 12, 13, 14, 15}; + + double origBuf[500]; + double* buf = origBuf; + + Conv>> conv; + + assert(conv.size(vec) == 1 + 6 + 0 + 1 + 2 + 3 + 4 + 5); // 21 + conv.val2buf(vec, &buf); + assert(buf == 22 + origBuf); + for(unsigned int i = 0; i < 22; ++i) + assert(doubleEq(origBuf[i], expected[i])); + + double* buf2 = origBuf; + const vector>& rc = conv.buf2val(&buf2); + + assert(rc.size() == 6); + for(unsigned int i = 0; i < 6; ++i) { + assert(rc[i].size() == i); + for(unsigned int j = 0; j < i; ++j) + assert(rc[i][j] == vec[i][j]); + } + + cout << "." << flush; } void testMsgField() { - const Cinfo* ac = Arith::initCinfo(); - unsigned int size = 10; - - const DestFinfo* df = dynamic_cast< const DestFinfo* >( - ac->findFinfo( "setOutputValue" ) ); - assert( df != 0 ); - FuncId fid = df->getFid(); - - Id i1 = Id::nextId(); - Id i2 = Id::nextId(); - Element* ret = new GlobalDataElement( i1, ac, "test1", size ); - assert( ret ); - ret = new GlobalDataElement( i2, ac, "test2", size ); - assert( ret ); - - Eref e1 = i1.eref(); - - Msg* m = new SingleMsg( Eref( i1.element(), 5 ), Eref( i2.element(), 3 ), 0 ); - ProcInfo p; - - assert( m->mid().element()->getName() == "singleMsg" ); - - SingleMsg* sm = reinterpret_cast< SingleMsg* >( m->mid().data() ); - assert( sm ); - assert ( sm == m ); - assert( sm->getI1() == 5 ); - assert( sm->getI2() == 3 ); - - SrcFinfo1 s( "test", "" ); - s.setBindIndex( 0 ); - e1.element()->addMsgAndFunc( m->mid(), fid, s.getBindIndex() ); - - for ( unsigned int i = 0; i < size; ++i ) { - double x = i * 42; - s.send( Eref( e1.element(), i ), x ); - } - - // Check that regular msgs go through. - Eref tgt3( i2.element(), 3 ); - Eref tgt8( i2.element(), 8 ); - double val = reinterpret_cast< Arith* >( tgt3.data() )->getOutput(); - assert( doubleEq( val, 5 * 42 ) ); - val = reinterpret_cast< Arith* >( tgt8.data() )->getOutput(); - assert( doubleEq( val, 0 ) ); - - // Now change I1 and I2, rerun, and check. - sm->setI1( 9 ); - sm->setI2( 8 ); - for ( unsigned int i = 0; i < size; ++i ) { - double x = i * 1000; - s.send( Eref( e1.element(), i ), x ); - } - val = reinterpret_cast< Arith* >( tgt3.data() )->getOutput(); - assert( doubleEq( val, 5 * 42 ) ); - val = reinterpret_cast< Arith* >( tgt8.data() )->getOutput(); - assert( doubleEq( val, 9000 ) ); - - cout << "." << flush; - - delete i1.element(); - delete i2.element(); + const Cinfo* ac = Arith::initCinfo(); + unsigned int size = 10; + + const DestFinfo* df = + dynamic_cast(ac->findFinfo("setOutputValue")); + assert(df != 0); + FuncId fid = df->getFid(); + + Id i1 = Id::nextId(); + Id i2 = Id::nextId(); + Element* ret = new GlobalDataElement(i1, ac, "test1", size); + assert(ret); + ret = new GlobalDataElement(i2, ac, "test2", size); + assert(ret); + + Eref e1 = i1.eref(); + + Msg* m = new SingleMsg(Eref(i1.element(), 5), Eref(i2.element(), 3), 0); + ProcInfo p; + + assert(m->mid().element()->getName() == "singleMsg"); + + SingleMsg* sm = reinterpret_cast(m->mid().data()); + assert(sm); + assert(sm == m); + assert(sm->getI1() == 5); + assert(sm->getI2() == 3); + + SrcFinfo1 s("test", ""); + s.setBindIndex(0); + e1.element()->addMsgAndFunc(m->mid(), fid, s.getBindIndex()); + + for(unsigned int i = 0; i < size; ++i) { + double x = i * 42; + s.send(Eref(e1.element(), i), x); + } + + // Check that regular msgs go through. + Eref tgt3(i2.element(), 3); + Eref tgt8(i2.element(), 8); + double val = reinterpret_cast(tgt3.data())->getOutput(); + assert(doubleEq(val, 5 * 42)); + val = reinterpret_cast(tgt8.data())->getOutput(); + assert(doubleEq(val, 0)); + + // Now change I1 and I2, rerun, and check. + sm->setI1(9); + sm->setI2(8); + for(unsigned int i = 0; i < size; ++i) { + double x = i * 1000; + s.send(Eref(e1.element(), i), x); + } + val = reinterpret_cast(tgt3.data())->getOutput(); + assert(doubleEq(val, 5 * 42)); + val = reinterpret_cast(tgt8.data())->getOutput(); + assert(doubleEq(val, 9000)); + + cout << "." << flush; + + delete i1.element(); + delete i2.element(); } void testSetGetExtField() { - const Cinfo* nc = Neutral::initCinfo(); - const Cinfo* rc = Arith::initCinfo(); - unsigned int size = 100; - - string arg; - Id i1 = Id::nextId(); - Id i2( i1.value() + 1 ); - Id i3( i2.value() + 1 ); - Id i4( i3.value() + 1 ); - Element* e1 = new GlobalDataElement( i1, nc, "test", size ); - assert( e1 ); - Shell::adopt( Id(), i1, 0 ); - Element* e2 = new GlobalDataElement( i2, rc, "x", size ); - assert( e2 ); - Shell::adopt( i1, i2, 0 ); - Element* e3 = new GlobalDataElement( i3, rc, "y", size ); - assert( e3 ); - Shell::adopt( i1, i3, 0 ); - Element* e4 = new GlobalDataElement( i4, rc, "z", size ); - assert( e4 ); - Shell::adopt( i1, i4, 0 ); - bool ret; - - vector< double > vec; - for ( unsigned int i = 0; i < size; ++i ) { - ObjId a( i1, i ); - ObjId b( i1, size - i - 1); - // Eref a( e1, i ); - // Eref b( e1, size - i - 1 ); - double temp = i; - ret = Field< double >::set( a, "x", temp ); - assert( ret ); - double temp2 = temp * temp; - ret = Field< double >::set( b, "y", temp2 ); - assert( ret ); - vec.push_back( temp2 - temp ); - } - - ret = Field< double >::setVec( i1, "z", vec ); - assert( ret ); - - for ( unsigned int i = 0; i < size; ++i ) { - /* - Eref a( e2, i ); - Eref b( e3, size - i - 1 ); - Eref c( e4, i ); - */ - ObjId a( i2, i ); - ObjId b( i3, size - i - 1 ); - ObjId c( i4, i ); - double temp = i; - double temp2 = temp * temp; - - double v = reinterpret_cast< Arith* >(a.data() )->getOutput(); - assert( doubleEq( v, temp ) ); - - v = reinterpret_cast< Arith* >(b.data() )->getOutput(); - assert( doubleEq( v, temp2 ) ); - - v = reinterpret_cast< Arith* >( c.data() )->getOutput(); - assert( doubleEq( v, temp2 - temp ) ); - } - - for ( unsigned int i = 0; i < size; ++i ) { - // Eref a( e1, i ); - // Eref b( e1, size - i - 1 ); - ObjId a( i1, i ); - ObjId b( i1, size - i - 1 ); - - double temp = i; - double temp2 = temp * temp; - double ret = Field< double >::get( a, "x" ); - assert( doubleEq( temp, ret ) ); - - ret = Field< double >::get( b, "y" ); - assert( doubleEq( temp2, ret ) ); - - ret = Field< double >::get( a, "z" ); - assert( doubleEq( temp2 - temp, ret ) ); - // cout << i << " " << ret << " temp2 = " << temp2 << endl; - } - - cout << "." << flush; - - /* - * This works, but I want to avoid calling the Shell specific ops here - * - * Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); - * s->doDelete( i1 ); - */ - i4.destroy(); - i3.destroy(); - i2.destroy(); - i1.destroy(); + const Cinfo* nc = Neutral::initCinfo(); + const Cinfo* rc = Arith::initCinfo(); + unsigned int size = 100; + + string arg; + Id i1 = Id::nextId(); + Id i2(i1.value() + 1); + Id i3(i2.value() + 1); + Id i4(i3.value() + 1); + Element* e1 = new GlobalDataElement(i1, nc, "test", size); + assert(e1); + Shell::adopt(Id(), i1, 0); + Element* e2 = new GlobalDataElement(i2, rc, "x", size); + assert(e2); + Shell::adopt(i1, i2, 0); + Element* e3 = new GlobalDataElement(i3, rc, "y", size); + assert(e3); + Shell::adopt(i1, i3, 0); + Element* e4 = new GlobalDataElement(i4, rc, "z", size); + assert(e4); + Shell::adopt(i1, i4, 0); + bool ret; + + vector vec; + for(unsigned int i = 0; i < size; ++i) { + ObjId a(i1, i); + ObjId b(i1, size - i - 1); + // Eref a( e1, i ); + // Eref b( e1, size - i - 1 ); + double temp = i; + ret = Field::set(a, "x", temp); + assert(ret); + double temp2 = temp * temp; + ret = Field::set(b, "y", temp2); + assert(ret); + vec.push_back(temp2 - temp); + } + + ret = Field::setVec(i1, "z", vec); + assert(ret); + + for(unsigned int i = 0; i < size; ++i) { + /* + Eref a( e2, i ); + Eref b( e3, size - i - 1 ); + Eref c( e4, i ); + */ + ObjId a(i2, i); + ObjId b(i3, size - i - 1); + ObjId c(i4, i); + double temp = i; + double temp2 = temp * temp; + + double v = reinterpret_cast(a.data())->getOutput(); + assert(doubleEq(v, temp)); + + v = reinterpret_cast(b.data())->getOutput(); + assert(doubleEq(v, temp2)); + + v = reinterpret_cast(c.data())->getOutput(); + assert(doubleEq(v, temp2 - temp)); + } + + for(unsigned int i = 0; i < size; ++i) { + // Eref a( e1, i ); + // Eref b( e1, size - i - 1 ); + ObjId a(i1, i); + ObjId b(i1, size - i - 1); + + double temp = i; + double temp2 = temp * temp; + double ret = Field::get(a, "x"); + assert(doubleEq(temp, ret)); + + ret = Field::get(b, "y"); + assert(doubleEq(temp2, ret)); + + ret = Field::get(a, "z"); + assert(doubleEq(temp2 - temp, ret)); + // cout << i << " " << ret << " temp2 = " << temp2 << endl; + } + + cout << "." << flush; + + /* + * This works, but I want to avoid calling the Shell specific ops here + * + * Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); + * s->doDelete( i1 ); + */ + i4.destroy(); + i3.destroy(); + i2.destroy(); + i1.destroy(); } void testLookupSetGet() { - const Cinfo* ac = Arith::initCinfo(); - unsigned int size = 100; - string arg; - Id i2 = Id::nextId(); + const Cinfo* ac = Arith::initCinfo(); + unsigned int size = 100; + string arg; + Id i2 = Id::nextId(); - Element* elm = new GlobalDataElement( i2, ac, "test2", size ); - assert( elm ); - ObjId obj( i2, 0 ); + Element* elm = new GlobalDataElement(i2, ac, "test2", size); + assert(elm); + ObjId obj(i2, 0); - Arith* arith = reinterpret_cast< Arith* >(obj.data() ); - for ( unsigned int i = 0; i < 4; ++i ) - arith->setIdentifiedArg( i, 0 ); - for ( unsigned int i = 0; i < 4; ++i ) - assert( doubleEq( 0, arith->getIdentifiedArg( i ) ) ); + Arith* arith = reinterpret_cast(obj.data()); + for(unsigned int i = 0; i < 4; ++i) + arith->setIdentifiedArg(i, 0); + for(unsigned int i = 0; i < 4; ++i) + assert(doubleEq(0, arith->getIdentifiedArg(i))); - LookupField< unsigned int, double >::set( obj, "anyValue", 0, 100 ); - LookupField< unsigned int, double >::set( obj, "anyValue", 1, 101 ); - LookupField< unsigned int, double >::set( obj, "anyValue", 2, 102 ); - LookupField< unsigned int, double >::set( obj, "anyValue", 3, 103 ); + LookupField::set(obj, "anyValue", 0, 100); + LookupField::set(obj, "anyValue", 1, 101); + LookupField::set(obj, "anyValue", 2, 102); + LookupField::set(obj, "anyValue", 3, 103); - assert( doubleEq( arith->getOutput(), 100 ) ); - assert( doubleEq( arith->getArg1(), 101 ) ); - assert( doubleEq( arith->getIdentifiedArg( 2 ), 102 ) ); - assert( doubleEq( arith->getIdentifiedArg( 3 ), 103 ) ); + assert(doubleEq(arith->getOutput(), 100)); + assert(doubleEq(arith->getArg1(), 101)); + assert(doubleEq(arith->getIdentifiedArg(2), 102)); + assert(doubleEq(arith->getIdentifiedArg(3), 103)); - for ( unsigned int i = 0; i < 4; ++i ) - arith->setIdentifiedArg( i, 17 * i + 3 ); + for(unsigned int i = 0; i < 4; ++i) + arith->setIdentifiedArg(i, 17 * i + 3); - double ret = LookupField< unsigned int, double >::get( - obj, "anyValue", 0 ); - assert( doubleEq( ret, 3 ) ); + double ret = LookupField::get(obj, "anyValue", 0); + assert(doubleEq(ret, 3)); - ret = LookupField< unsigned int, double >::get( obj, "anyValue", 1 ); - assert( doubleEq( ret, 20 ) ); + ret = LookupField::get(obj, "anyValue", 1); + assert(doubleEq(ret, 20)); - ret = LookupField< unsigned int, double >::get( obj, "anyValue", 2 ); - assert( doubleEq( ret, 37 ) ); + ret = LookupField::get(obj, "anyValue", 2); + assert(doubleEq(ret, 37)); - ret = LookupField< unsigned int, double >::get( obj, "anyValue", 3 ); - assert( doubleEq( ret, 54 ) ); + ret = LookupField::get(obj, "anyValue", 3); + assert(doubleEq(ret, 54)); - cout << "." << flush; - i2.destroy(); + cout << "." << flush; + i2.destroy(); } void testIsA() { - const Cinfo* n = Neutral::initCinfo(); - const Cinfo* a = Arith::initCinfo(); - assert( a->isA( "Arith" ) ); - assert( a->isA( "Neutral" ) ); - assert( !a->isA( "Fish" ) ); - assert( !a->isA( "Synapse" ) ); - assert( !n->isA( "Arith" ) ); - assert( n->isA( "Neutral" ) ); - cout << "." << flush; + const Cinfo* n = Neutral::initCinfo(); + const Cinfo* a = Arith::initCinfo(); + assert(a->isA("Arith")); + assert(a->isA("Neutral")); + assert(!a->isA("Fish")); + assert(!a->isA("Synapse")); + assert(!n->isA("Arith")); + assert(n->isA("Neutral")); + cout << "." << flush; } void testFinfoFields() { - const FinfoWrapper vmFinfo = IntFire::initCinfo()->findFinfo( "Vm" ); - const FinfoWrapper synFinfo = SimpleSynHandler::initCinfo()->findFinfo( "synapse" ); - const FinfoWrapper procFinfo = IntFire::initCinfo()->findFinfo( "proc" ); - const FinfoWrapper processFinfo = IntFire::initCinfo()->findFinfo( "process" ); - const FinfoWrapper reinitFinfo = IntFire::initCinfo()->findFinfo( "reinit" ); - const FinfoWrapper spikeFinfo = IntFire::initCinfo()->findFinfo( "spikeOut" ); - const FinfoWrapper classNameFinfo = Neutral::initCinfo()->findFinfo( "className" ); - - assert( vmFinfo.getName() == "Vm" ); - assert( vmFinfo.docs() == "Membrane potential" ); - assert( vmFinfo.src().size() == 0 ); - assert( vmFinfo.dest().size() == 2 ); - assert( vmFinfo.dest()[0] == "setVm" ); - assert( vmFinfo.dest()[1] == "getVm" ); - assert( vmFinfo.type() == "double" ); - - assert( synFinfo.getName() == "synapse" ); - assert( synFinfo.docs() == "Sets up field Elements for synapse" ); - assert( synFinfo.src().size() == 0 ); - assert( synFinfo.dest().size() == 0 ); - // cout << synFinfo->type() << endl; - assert( synFinfo.type() == typeid(Synapse).name() ); - - assert( procFinfo.getName() == "proc" ); - assert( procFinfo.docs() == "Shared message for process and reinit" ); - assert( procFinfo.src().size() == 0 ); - assert( procFinfo.dest().size() == 2 ); - assert( procFinfo.dest()[0] == "process" ); - assert( procFinfo.dest()[1] == "reinit" ); - // cout << "proc " << procFinfo.type() << endl; - assert( procFinfo.type() == "void" ); - - assert( processFinfo.getName() == "process" ); - assert( processFinfo.docs() == "Handles process call" ); - assert( processFinfo.src().size() == 0 ); - assert( processFinfo.dest().size() == 0 ); - // cout << "process " << processFinfo.type() << endl; - assert( processFinfo.type() == "const ProcInfo*" ); - - assert( reinitFinfo.getName() == "reinit" ); - assert( reinitFinfo.docs() == "Handles reinit call" ); - assert( reinitFinfo.src().size() == 0 ); - assert( reinitFinfo.dest().size() == 0 ); - // cout << "reinit " << reinitFinfo.type() << endl; - assert( reinitFinfo.type() == "const ProcInfo*" ); - - assert( spikeFinfo.getName() == "spikeOut" ); - assert( spikeFinfo.docs() == "Sends out spike events. The argument is the timestamp of the spike. " ); - assert( spikeFinfo.src().size() == 0 ); - assert( spikeFinfo.dest().size() == 0 ); - // cout << spikeFinfo->type() << endl; - assert( spikeFinfo.type() == "double" ); - - assert( classNameFinfo.getName() == "className" ); - assert( classNameFinfo.type() == "string" ); - - cout << "." << flush; + const FinfoWrapper vmFinfo = IntFire::initCinfo()->findFinfo("Vm"); + const FinfoWrapper synFinfo = + SimpleSynHandler::initCinfo()->findFinfo("synapse"); + const FinfoWrapper procFinfo = IntFire::initCinfo()->findFinfo("proc"); + const FinfoWrapper processFinfo = + IntFire::initCinfo()->findFinfo("process"); + const FinfoWrapper reinitFinfo = IntFire::initCinfo()->findFinfo("reinit"); + const FinfoWrapper spikeFinfo = IntFire::initCinfo()->findFinfo("spikeOut"); + const FinfoWrapper classNameFinfo = + Neutral::initCinfo()->findFinfo("className"); + + assert(vmFinfo.getName() == "Vm"); + assert(vmFinfo.docs() == "Membrane potential"); + assert(vmFinfo.src().size() == 0); + assert(vmFinfo.dest().size() == 2); + assert(vmFinfo.dest()[0] == "setVm"); + assert(vmFinfo.dest()[1] == "getVm"); + assert(vmFinfo.type() == "double"); + + assert(synFinfo.getName() == "synapse"); + assert(synFinfo.docs() == "Sets up field Elements for synapse"); + assert(synFinfo.src().size() == 0); + assert(synFinfo.dest().size() == 0); + // cout << synFinfo->type() << endl; + assert(synFinfo.type() == typeid(Synapse).name()); + + assert(procFinfo.getName() == "proc"); + assert(procFinfo.docs() == "Shared message for process and reinit"); + assert(procFinfo.src().size() == 0); + assert(procFinfo.dest().size() == 2); + assert(procFinfo.dest()[0] == "process"); + assert(procFinfo.dest()[1] == "reinit"); + // cout << "proc " << procFinfo.type() << endl; + assert(procFinfo.type() == "void"); + + assert(processFinfo.getName() == "process"); + assert(processFinfo.docs() == "Handles process call"); + assert(processFinfo.src().size() == 0); + assert(processFinfo.dest().size() == 0); + // cout << "process " << processFinfo.type() << endl; + assert(processFinfo.type() == "const ProcInfo*"); + + assert(reinitFinfo.getName() == "reinit"); + assert(reinitFinfo.docs() == "Handles reinit call"); + assert(reinitFinfo.src().size() == 0); + assert(reinitFinfo.dest().size() == 0); + // cout << "reinit " << reinitFinfo.type() << endl; + assert(reinitFinfo.type() == "const ProcInfo*"); + + assert(spikeFinfo.getName() == "spikeOut"); + assert( + spikeFinfo.docs() == + "Sends out spike events. The argument is the timestamp of the spike. "); + assert(spikeFinfo.src().size() == 0); + assert(spikeFinfo.dest().size() == 0); + // cout << spikeFinfo->type() << endl; + assert(spikeFinfo.type() == "double"); + + assert(classNameFinfo.getName() == "className"); + assert(classNameFinfo.type() == "string"); + + cout << "." << flush; } void testCinfoFields() { - assert( IntFire::initCinfo()->getDocs() == "" ); - assert( SimpleSynHandler::initCinfo()->getBaseClass() == "SynHandlerBase" ); - - // We have a little bit of a hack here to cast away - // constness, due to the way the FieldElementFinfos - // are set up. - Cinfo *neutralCinfo = const_cast< Cinfo* >( Neutral::initCinfo() ); - assert( neutralCinfo->getNumSrcFinfo() == 1 ); - - Cinfo *cinfo = const_cast< Cinfo* >( IntFire::initCinfo() ); - unsigned int nsf = neutralCinfo->getNumSrcFinfo(); - assert( nsf == 1 ); - assert( cinfo->getNumSrcFinfo() == 1 + nsf ); - assert( cinfo->getSrcFinfo( 0 + nsf ) == cinfo->findFinfo( "spikeOut" ) ); - - unsigned int ndf = neutralCinfo->getNumDestFinfo(); - assert( ndf == 29 ); - unsigned int sdf = IntFire::initCinfo()->getNumDestFinfo(); - assert( sdf == 40 ); - - /* - assert( cinfo->getDestFinfo( 0+ndf )->name() == "setNumSynapses" ); - assert( cinfo->getDestFinfo( 1+ndf )->name() == "getNumSynapses" ); - assert( cinfo->getDestFinfo( 2+ndf )->name() == "setNumSynapse" ); - assert( cinfo->getDestFinfo( 3+ndf )->name() == "getNumSynapse" ); - */ - - assert( cinfo->getDestFinfo( 0+ndf ) == cinfo->findFinfo( "setVm" ) ); - assert( cinfo->getDestFinfo( 1+ndf ) == cinfo->findFinfo( "getVm" ) ); - assert( cinfo->getDestFinfo( 2+ndf ) == cinfo->findFinfo( "setTau" ) ); - assert( cinfo->getDestFinfo( 3+ndf ) == cinfo->findFinfo( "getTau" ) ); - - assert( cinfo->getDestFinfo( 4+ndf ) == cinfo->findFinfo( "setThresh" ) ); - assert( cinfo->getDestFinfo( 5+ndf ) == cinfo->findFinfo( "getThresh" ) ); - assert( cinfo->getDestFinfo( 6+ndf ) == cinfo->findFinfo( "setRefractoryPeriod" ) ); - assert( cinfo->getDestFinfo( 7+ndf ) == cinfo->findFinfo( "getRefractoryPeriod" ) ); - assert( cinfo->getDestFinfo( 8+ndf ) == cinfo->findFinfo( "activation" ) ); - assert( cinfo->getDestFinfo( 9+ndf ) == cinfo->findFinfo( "process" ) ); - assert( cinfo->getDestFinfo( 10+ndf ) == cinfo->findFinfo( "reinit" ) ); - - - unsigned int nvf = neutralCinfo->getNumValueFinfo(); - assert( nvf == 19 ); - assert( cinfo->getNumValueFinfo() == 4 + nvf ); - assert( cinfo->getValueFinfo( 0 + nvf ) == cinfo->findFinfo( "Vm" ) ); - assert( cinfo->getValueFinfo( 1 + nvf ) == cinfo->findFinfo( "tau" ) ); - assert( cinfo->getValueFinfo( 2 + nvf ) == cinfo->findFinfo( "thresh" ) ); - assert( cinfo->getValueFinfo( 3 + nvf ) == cinfo->findFinfo( "refractoryPeriod" ) ); - - unsigned int nlf = neutralCinfo->getNumLookupFinfo(); - assert( nlf == 4 ); // Neutral inserts a lookup field for neighbors - assert( cinfo->getNumLookupFinfo() == 0 + nlf ); - assert( cinfo->getLookupFinfo( 0 + nlf )->name() == "dummy"); - - unsigned int nshf = neutralCinfo->getNumSharedFinfo(); - assert( nshf == 0 ); - assert( cinfo->getNumSharedFinfo() == 1 + nshf ); - assert( cinfo->getSharedFinfo( 0 + nshf ) == cinfo->findFinfo( "proc" ) ); - - cout << "." << flush; + assert(IntFire::initCinfo()->getDocs() == ""); + assert(SimpleSynHandler::initCinfo()->getBaseClass() == "SynHandlerBase"); + + // We have a little bit of a hack here to cast away + // constness, due to the way the FieldElementFinfos + // are set up. + Cinfo* neutralCinfo = const_cast(Neutral::initCinfo()); + assert(neutralCinfo->getNumSrcFinfo() == 1); + + Cinfo* cinfo = const_cast(IntFire::initCinfo()); + unsigned int nsf = neutralCinfo->getNumSrcFinfo(); + assert(nsf == 1); + assert(cinfo->getNumSrcFinfo() == 1 + nsf); + assert(cinfo->getSrcFinfo(0 + nsf) == cinfo->findFinfo("spikeOut")); + + unsigned int ndf = neutralCinfo->getNumDestFinfo(); + assert(ndf == 29); + unsigned int sdf = IntFire::initCinfo()->getNumDestFinfo(); + assert(sdf == 40); + + /* + assert( cinfo->getDestFinfo( 0+ndf )->name() == "setNumSynapses" ); + assert( cinfo->getDestFinfo( 1+ndf )->name() == "getNumSynapses" ); + assert( cinfo->getDestFinfo( 2+ndf )->name() == "setNumSynapse" ); + assert( cinfo->getDestFinfo( 3+ndf )->name() == "getNumSynapse" ); + */ + + assert(cinfo->getDestFinfo(0 + ndf) == cinfo->findFinfo("setVm")); + assert(cinfo->getDestFinfo(1 + ndf) == cinfo->findFinfo("getVm")); + assert(cinfo->getDestFinfo(2 + ndf) == cinfo->findFinfo("setTau")); + assert(cinfo->getDestFinfo(3 + ndf) == cinfo->findFinfo("getTau")); + + assert(cinfo->getDestFinfo(4 + ndf) == cinfo->findFinfo("setThresh")); + assert(cinfo->getDestFinfo(5 + ndf) == cinfo->findFinfo("getThresh")); + assert(cinfo->getDestFinfo(6 + ndf) == + cinfo->findFinfo("setRefractoryPeriod")); + assert(cinfo->getDestFinfo(7 + ndf) == + cinfo->findFinfo("getRefractoryPeriod")); + assert(cinfo->getDestFinfo(8 + ndf) == cinfo->findFinfo("activation")); + assert(cinfo->getDestFinfo(9 + ndf) == cinfo->findFinfo("process")); + assert(cinfo->getDestFinfo(10 + ndf) == cinfo->findFinfo("reinit")); + + unsigned int nvf = neutralCinfo->getNumValueFinfo(); + assert(nvf == 19); + assert(cinfo->getNumValueFinfo() == 4 + nvf); + assert(cinfo->getValueFinfo(0 + nvf) == cinfo->findFinfo("Vm")); + assert(cinfo->getValueFinfo(1 + nvf) == cinfo->findFinfo("tau")); + assert(cinfo->getValueFinfo(2 + nvf) == cinfo->findFinfo("thresh")); + assert(cinfo->getValueFinfo(3 + nvf) == + cinfo->findFinfo("refractoryPeriod")); + + unsigned int nlf = neutralCinfo->getNumLookupFinfo(); + assert(nlf == 4); // Neutral inserts a lookup field for neighbors + assert(cinfo->getNumLookupFinfo() == 0 + nlf); + assert(cinfo->getLookupFinfo(0 + nlf)->name() == "dummy"); + + unsigned int nshf = neutralCinfo->getNumSharedFinfo(); + assert(nshf == 0); + assert(cinfo->getNumSharedFinfo() == 1 + nshf); + assert(cinfo->getSharedFinfo(0 + nshf) == cinfo->findFinfo("proc")); + + cout << "." << flush; } void testCinfoElements() { - Id intFireCinfoId( "/classes/IntFire" ); - // const Cinfo *neutralCinfo = Neutral::initCinfo(); - // unsigned int nvf = neutralCinfo->getNumValueFinfo(); - // unsigned int nsf = neutralCinfo->getNumSrcFinfo(); - // unsigned int ndf = neutralCinfo->getNumDestFinfo(); - //unsigned int sdf = SynHandler::initCinfo()->getNumDestFinfo(); - - assert( intFireCinfoId != Id() ); - assert( Field< string >::get( intFireCinfoId, "name" ) == "IntFire" ); - assert( Field< string >::get( intFireCinfoId, "baseClass" ) == - "Neutral" ); - Id intFireValueFinfoId( "/classes/IntFire/valueFinfo" ); - unsigned int n = Field< unsigned int >::get( - intFireValueFinfoId, "numData" ); - assert( n == 4 ); - Id intFireSrcFinfoId( "/classes/IntFire/srcFinfo" ); - assert( intFireSrcFinfoId != Id() ); - n = Field< unsigned int >::get( intFireSrcFinfoId, "numData" ); - assert( n == 1 ); - Id intFireDestFinfoId( "/classes/IntFire/destFinfo" ); - assert( intFireDestFinfoId != Id() ); - n = Field< unsigned int >::get( intFireDestFinfoId, "numData" ); - assert( n == 11 ); - - ObjId temp( intFireSrcFinfoId, 0 ); - string foo = Field< string >::get( temp, "fieldName" ); - assert( foo == "spikeOut" ); - - foo = Field< string >::get( temp, "type" ); - assert( foo == "double" ); - - n = Field< unsigned int >::get( intFireDestFinfoId, "numField" ); - assert( n == 1 ); - - temp = ObjId( intFireDestFinfoId, 7 ); - string str = Field< string >::get( temp, "fieldName" ); - assert( str == "getRefractoryPeriod"); - temp = ObjId( intFireDestFinfoId, 10 ); - str = Field< string >::get( temp, "fieldName" ); - assert( str == "reinit" ); - cout << "." << flush; + Id intFireCinfoId("/classes/IntFire"); + // const Cinfo *neutralCinfo = Neutral::initCinfo(); + // unsigned int nvf = neutralCinfo->getNumValueFinfo(); + // unsigned int nsf = neutralCinfo->getNumSrcFinfo(); + // unsigned int ndf = neutralCinfo->getNumDestFinfo(); + // unsigned int sdf = SynHandler::initCinfo()->getNumDestFinfo(); + + assert(intFireCinfoId != Id()); + assert(Field::get(intFireCinfoId, "name") == "IntFire"); + assert(Field::get(intFireCinfoId, "baseClass") == "Neutral"); + Id intFireValueFinfoId("/classes/IntFire/valueFinfo"); + unsigned int n = Field::get(intFireValueFinfoId, "numData"); + assert(n == 4); + Id intFireSrcFinfoId("/classes/IntFire/srcFinfo"); + assert(intFireSrcFinfoId != Id()); + n = Field::get(intFireSrcFinfoId, "numData"); + assert(n == 1); + Id intFireDestFinfoId("/classes/IntFire/destFinfo"); + assert(intFireDestFinfoId != Id()); + n = Field::get(intFireDestFinfoId, "numData"); + assert(n == 11); + + ObjId temp(intFireSrcFinfoId, 0); + string foo = Field::get(temp, "fieldName"); + assert(foo == "spikeOut"); + + foo = Field::get(temp, "type"); + assert(foo == "double"); + + n = Field::get(intFireDestFinfoId, "numField"); + assert(n == 1); + + temp = ObjId(intFireDestFinfoId, 7); + string str = Field::get(temp, "fieldName"); + assert(str == "getRefractoryPeriod"); + temp = ObjId(intFireDestFinfoId, 10); + str = Field::get(temp, "fieldName"); + assert(str == "reinit"); + cout << "." << flush; } void testMsgSrcDestFields() { - ////////////////////////////////////////////////////////////// - // Setup - ////////////////////////////////////////////////////////////// - /* This is initialized in testSharedMsg() - static SrcFinfo1< string > s1( "s1", "" ); - static SrcFinfo2< int, int > s2( "s2", "" ); - static DestFinfo d0( "d0", "", - new OpFunc0< Test >( & Test::handleS0 ) ); - static DestFinfo d1( "d1", "", - new EpFunc1< Test, string >( &Test::handleS1 ) ); - static DestFinfo d2( "d2", "", - new EpFunc2< Test, int, int >( &Test::handleS2 ) ); - - Test::sharedVec[0] = &s0; - Test::sharedVec[1] = &d0; - Test::sharedVec[2] = &s1; - Test::sharedVec[3] = &d1; - Test::sharedVec[4] = &s2; - Test::sharedVec[5] = &d2; - */ - - Id t1 = Id::nextId(); - Id t2 = Id::nextId(); - // bool ret = Test::initCinfo()->create( t1, "test1", 1 ); - Element* e1 = new GlobalDataElement( t1, Test::initCinfo(), "test1" ); - assert( e1 ); - assert( e1 == t1.element() ); - Element* e2 = new GlobalDataElement( t2, Test::initCinfo(), "test2", 1 ); - // ret = Test::initCinfo()->create( t2, "test2", 1 ); - assert( e2 ); - assert( e2 == t2.element() ); - - // Set up message. The actual routine is in Shell.cpp, but here we - // do it independently. - const Finfo* shareFinfo = Test::initCinfo()->findFinfo( "shared" ); - assert( shareFinfo != 0 ); - Msg* m = new OneToOneMsg( t1.eref(), t2.eref(), 0 ); - assert( m != 0 ); - bool ret = shareFinfo->addMsg( shareFinfo, m->mid(), t1.element() ); - assert( ret ); - - ////////////////////////////////////////////////////////////// - // Test Element::getFieldsOfOutgoingMsg - ////////////////////////////////////////////////////////////// - vector< pair< BindIndex, FuncId > > pairs; - e1->getFieldsOfOutgoingMsg( m->mid(), pairs ); - assert( pairs.size() == 3 ); - assert( pairs[0].first == dynamic_cast< SrcFinfo* >(Test::sharedVec[0])->getBindIndex() ); - assert( pairs[0].second == dynamic_cast< DestFinfo* >(Test::sharedVec[1])->getFid() ); - - assert( pairs[1].first == dynamic_cast< SrcFinfo* >(Test::sharedVec[2])->getBindIndex() ); - assert( pairs[1].second == dynamic_cast< DestFinfo* >(Test::sharedVec[3])->getFid() ); - - assert( pairs[2].first == dynamic_cast< SrcFinfo* >(Test::sharedVec[4])->getBindIndex() ); - assert( pairs[2].second == dynamic_cast< DestFinfo* >(Test::sharedVec[5])->getFid() ); - - e2->getFieldsOfOutgoingMsg( m->mid(), pairs ); - assert( pairs.size() == 3 ); - - ////////////////////////////////////////////////////////////// - // Test Cinfo::srcFinfoName - ////////////////////////////////////////////////////////////// - assert( Test::initCinfo()->srcFinfoName( pairs[0].first ) == "s0" ); - assert( Test::initCinfo()->srcFinfoName( pairs[1].first ) == "s1" ); - assert( Test::initCinfo()->srcFinfoName( pairs[2].first ) == "s2" ); - - ////////////////////////////////////////////////////////////// - // Test Cinfo::destFinfoName - ////////////////////////////////////////////////////////////// - assert( Test::initCinfo()->destFinfoName( pairs[0].second ) == "d0" ); - assert( Test::initCinfo()->destFinfoName( pairs[1].second ) == "d1" ); - assert( Test::initCinfo()->destFinfoName( pairs[2].second ) == "d2" ); - ////////////////////////////////////////////////////////////// - // Test Msg::getSrcFieldsOnE1 and family - ////////////////////////////////////////////////////////////// - vector< string > fieldNames; - fieldNames = m->getSrcFieldsOnE1(); - assert( fieldNames.size() == 3 ); - assert( fieldNames[0] == "s0" ); - assert( fieldNames[1] == "s1" ); - assert( fieldNames[2] == "s2" ); - - fieldNames = m->getDestFieldsOnE2(); - assert( fieldNames.size() == 3 ); - assert( fieldNames[0] == "d0" ); - assert( fieldNames[1] == "d1" ); - assert( fieldNames[2] == "d2" ); - - fieldNames = m->getSrcFieldsOnE2(); - assert( fieldNames.size() == 3 ); - assert( fieldNames[0] == "s0" ); - assert( fieldNames[1] == "s1" ); - assert( fieldNames[2] == "s2" ); - - fieldNames = m->getDestFieldsOnE1(); - assert( fieldNames.size() == 3 ); - assert( fieldNames[0] == "d0" ); - assert( fieldNames[1] == "d1" ); - assert( fieldNames[2] == "d2" ); - - ////////////////////////////////////////////////////////////// - // getMsgTargetAndFunctions - ////////////////////////////////////////////////////////////// - vector< ObjId > tgt; - vector< string > func; - unsigned int numTgt = e1->getMsgTargetAndFunctions( 0, - dynamic_cast< SrcFinfo* >(Test::sharedVec[0] ), - tgt, func ); - assert( numTgt == tgt.size() ); - assert( tgt.size() == 1 ); - assert( tgt[0] == ObjId( t2, 0 ) ); - assert( func[0] == "d0" ); - - // Note that the srcFinfo #2 is in sharedVec[4] - numTgt = e2->getMsgTargetAndFunctions( 0, - dynamic_cast< SrcFinfo* >(Test::sharedVec[4] ), - tgt, func ); - assert( numTgt == tgt.size() ); - assert( tgt.size() == 1 ); - assert( tgt[0] == ObjId( t1, 0 ) ); - assert( func[0] == "d2" ); - - ////////////////////////////////////////////////////////////// - // getMsgSourceAndSender - ////////////////////////////////////////////////////////////// - vector< ObjId > source; - vector< string > sender; - FuncId fid = - static_cast< const DestFinfo* >( Test::sharedVec[5] )->getFid(); - unsigned int numSrc = t2.element()->getMsgSourceAndSender( - fid, source, sender ); - assert( numSrc == 1 ); - assert( source.size() == 1 ); - assert( source[0] == tgt[0] ); - assert( sender[0] == Test::sharedVec[4]->name() ); - cout << "." << flush; - - ////////////////////////////////////////////////////////////// - // Clean up. - ////////////////////////////////////////////////////////////// - t1.destroy(); - t2.destroy(); - cout << "." << flush; + ////////////////////////////////////////////////////////////// + // Setup + ////////////////////////////////////////////////////////////// + /* This is initialized in testSharedMsg() + static SrcFinfo1< string > s1( "s1", "" ); + static SrcFinfo2< int, int > s2( "s2", "" ); + static DestFinfo d0( "d0", "", + new OpFunc0< Test >( & Test::handleS0 ) ); + static DestFinfo d1( "d1", "", + new EpFunc1< Test, string >( &Test::handleS1 ) ); + static DestFinfo d2( "d2", "", + new EpFunc2< Test, int, int >( &Test::handleS2 ) ); + + Test::sharedVec[0] = &s0; + Test::sharedVec[1] = &d0; + Test::sharedVec[2] = &s1; + Test::sharedVec[3] = &d1; + Test::sharedVec[4] = &s2; + Test::sharedVec[5] = &d2; + */ + + Id t1 = Id::nextId(); + Id t2 = Id::nextId(); + // bool ret = Test::initCinfo()->create( t1, "test1", 1 ); + Element* e1 = new GlobalDataElement(t1, Test::initCinfo(), "test1"); + assert(e1); + assert(e1 == t1.element()); + Element* e2 = new GlobalDataElement(t2, Test::initCinfo(), "test2", 1); + // ret = Test::initCinfo()->create( t2, "test2", 1 ); + assert(e2); + assert(e2 == t2.element()); + + // Set up message. The actual routine is in Shell.cpp, but here we + // do it independently. + const Finfo* shareFinfo = Test::initCinfo()->findFinfo("shared"); + assert(shareFinfo != 0); + Msg* m = new OneToOneMsg(t1.eref(), t2.eref(), 0); + assert(m != 0); + bool ret = shareFinfo->addMsg(shareFinfo, m->mid(), t1.element()); + assert(ret); + + ////////////////////////////////////////////////////////////// + // Test Element::getFieldsOfOutgoingMsg + ////////////////////////////////////////////////////////////// + vector> pairs; + e1->getFieldsOfOutgoingMsg(m->mid(), pairs); + assert(pairs.size() == 3); + assert(pairs[0].first == + dynamic_cast(Test::sharedVec[0])->getBindIndex()); + assert(pairs[0].second == + dynamic_cast(Test::sharedVec[1])->getFid()); + + assert(pairs[1].first == + dynamic_cast(Test::sharedVec[2])->getBindIndex()); + assert(pairs[1].second == + dynamic_cast(Test::sharedVec[3])->getFid()); + + assert(pairs[2].first == + dynamic_cast(Test::sharedVec[4])->getBindIndex()); + assert(pairs[2].second == + dynamic_cast(Test::sharedVec[5])->getFid()); + + e2->getFieldsOfOutgoingMsg(m->mid(), pairs); + assert(pairs.size() == 3); + + ////////////////////////////////////////////////////////////// + // Test Cinfo::srcFinfoName + ////////////////////////////////////////////////////////////// + assert(Test::initCinfo()->srcFinfoName(pairs[0].first) == "s0"); + assert(Test::initCinfo()->srcFinfoName(pairs[1].first) == "s1"); + assert(Test::initCinfo()->srcFinfoName(pairs[2].first) == "s2"); + + ////////////////////////////////////////////////////////////// + // Test Cinfo::destFinfoName + ////////////////////////////////////////////////////////////// + assert(Test::initCinfo()->destFinfoName(pairs[0].second) == "d0"); + assert(Test::initCinfo()->destFinfoName(pairs[1].second) == "d1"); + assert(Test::initCinfo()->destFinfoName(pairs[2].second) == "d2"); + ////////////////////////////////////////////////////////////// + // Test Msg::getSrcFieldsOnE1 and family + ////////////////////////////////////////////////////////////// + vector fieldNames; + fieldNames = m->getSrcFieldsOnE1(); + assert(fieldNames.size() == 3); + assert(fieldNames[0] == "s0"); + assert(fieldNames[1] == "s1"); + assert(fieldNames[2] == "s2"); + + fieldNames = m->getDestFieldsOnE2(); + assert(fieldNames.size() == 3); + assert(fieldNames[0] == "d0"); + assert(fieldNames[1] == "d1"); + assert(fieldNames[2] == "d2"); + + fieldNames = m->getSrcFieldsOnE2(); + assert(fieldNames.size() == 3); + assert(fieldNames[0] == "s0"); + assert(fieldNames[1] == "s1"); + assert(fieldNames[2] == "s2"); + + fieldNames = m->getDestFieldsOnE1(); + assert(fieldNames.size() == 3); + assert(fieldNames[0] == "d0"); + assert(fieldNames[1] == "d1"); + assert(fieldNames[2] == "d2"); + + ////////////////////////////////////////////////////////////// + // getMsgTargetAndFunctions + ////////////////////////////////////////////////////////////// + vector tgt; + vector func; + unsigned int numTgt = e1->getMsgTargetAndFunctions( + 0, dynamic_cast(Test::sharedVec[0]), tgt, func); + assert(numTgt == tgt.size()); + assert(tgt.size() == 1); + assert(tgt[0] == ObjId(t2, 0)); + assert(func[0] == "d0"); + + // Note that the srcFinfo #2 is in sharedVec[4] + numTgt = e2->getMsgTargetAndFunctions( + 0, dynamic_cast(Test::sharedVec[4]), tgt, func); + assert(numTgt == tgt.size()); + assert(tgt.size() == 1); + assert(tgt[0] == ObjId(t1, 0)); + assert(func[0] == "d2"); + + ////////////////////////////////////////////////////////////// + // getMsgSourceAndSender + ////////////////////////////////////////////////////////////// + vector source; + vector sender; + FuncId fid = static_cast(Test::sharedVec[5])->getFid(); + unsigned int numSrc = + t2.element()->getMsgSourceAndSender(fid, source, sender); + assert(numSrc == 1); + assert(source.size() == 1); + assert(source[0] == tgt[0]); + assert(sender[0] == Test::sharedVec[4]->name()); + cout << "." << flush; + + ////////////////////////////////////////////////////////////// + // Clean up. + ////////////////////////////////////////////////////////////// + t1.destroy(); + t2.destroy(); + cout << "." << flush; } void testHopFunc() { - extern const double* checkHopFuncTestBuffer(); - - HopIndex hop2( 1234, MooseTestHop ); - HopFunc2< string, double > two( hop2 ); - - two.op( Id(3).eref(), "two", 2468.0 ); - const double* buf = checkHopFuncTestBuffer(); - const TgtInfo* tgt = reinterpret_cast< const TgtInfo* >( buf ); - assert( tgt->bindIndex() == 1234 ); - assert( tgt->dataSize() == 2 ); - const char* c = reinterpret_cast< const char* >( - buf + TgtInfo::headerSize ); - assert( strcmp( c, "two" ) == 0 ); - assert( doubleEq( buf[TgtInfo::headerSize + 1], 2468.0 ) ); - - HopIndex hop3( 36912, MooseTestHop ); - HopFunc3< string, int, vector< double > > three( hop3 ); - vector< double > temp( 3 ); - temp[0] = 11222; - temp[1] = 24332; - temp[2] = 234232342; - three.op( Id(3).eref(), "three", 3333, temp ); - - assert( tgt->bindIndex() == 36912 ); - assert( tgt->dataSize() == 6 ); - c = reinterpret_cast< const char* >( buf + TgtInfo::headerSize ); - assert( strcmp( c, "three" ) == 0 ); - int i = TgtInfo::headerSize + 1; - assert( doubleEq( buf[i++], 3333.0 ) ); - assert( doubleEq( buf[i++], 3.0 ) ); // Size of array. - assert( doubleEq( buf[i++], temp[0] ) ); - assert( doubleEq( buf[i++], temp[1] ) ); - assert( doubleEq( buf[i++], temp[2] ) ); - - cout << "." << flush; + extern const double* checkHopFuncTestBuffer(); + + HopIndex hop2(1234, MooseTestHop); + HopFunc2 two(hop2); + + two.op(Id(3).eref(), "two", 2468.0); + const double* buf = checkHopFuncTestBuffer(); + const TgtInfo* tgt = reinterpret_cast(buf); + assert(tgt->bindIndex() == 1234); + assert(tgt->dataSize() == 2); + const char* c = reinterpret_cast(buf + TgtInfo::headerSize); + assert(strcmp(c, "two") == 0); + assert(doubleEq(buf[TgtInfo::headerSize + 1], 2468.0)); + + HopIndex hop3(36912, MooseTestHop); + HopFunc3> three(hop3); + vector temp(3); + temp[0] = 11222; + temp[1] = 24332; + temp[2] = 234232342; + three.op(Id(3).eref(), "three", 3333, temp); + + assert(tgt->bindIndex() == 36912); + assert(tgt->dataSize() == 6); + c = reinterpret_cast(buf + TgtInfo::headerSize); + assert(strcmp(c, "three") == 0); + int i = TgtInfo::headerSize + 1; + assert(doubleEq(buf[i++], 3333.0)); + assert(doubleEq(buf[i++], 3.0)); // Size of array. + assert(doubleEq(buf[i++], temp[0])); + assert(doubleEq(buf[i++], temp[1])); + assert(doubleEq(buf[i++], temp[2])); + + cout << "." << flush; } -void testAsync( ) +void testAsync() { - showFields(); + showFields(); #ifdef DO_UNIT_TESTS - testSendMsg(); - testCreateMsg(); - testSetGet(); - testSetGetDouble(); - testSetGetSynapse(); - testSetGetVec(); - test2ArgSetVec(); - testSetRepeat(); - testStrSet(); - testStrGet(); - testLookupSetGet(); -// testSendSpike(); - testSparseMatrix(); - testSparseMatrix2(); - testSparseMatrixReorder(); - testSparseMatrixFill(); - testSparseMsg(); - testSharedMsg(); - testConvVector(); - testConvVectorOfVectors(); - testMsgField(); - // testSetGetExtField(); Unsure if we're keeping ext fields. - testIsA(); - testFinfoFields(); - testCinfoFields(); - testCinfoElements(); - testMsgSrcDestFields(); - testHopFunc(); + testSendMsg(); + testCreateMsg(); + testSetGet(); + testSetGetDouble(); + testSetGetSynapse(); + testSetGetVec(); + test2ArgSetVec(); + testSetRepeat(); + testStrSet(); + testStrGet(); + testLookupSetGet(); + // testSendSpike(); + testSparseMatrix(); + testSparseMatrix2(); + testSparseMatrixReorder(); + testSparseMatrixFill(); + testSparseMsg(); + testSharedMsg(); + testConvVector(); + testConvVectorOfVectors(); + testMsgField(); + // testSetGetExtField(); Unsure if we're keeping ext fields. + testIsA(); + testFinfoFields(); + testCinfoFields(); + testCinfoElements(); + testMsgSrcDestFields(); + testHopFunc(); #endif } diff --git a/basecode/testGlobals.cpp b/basecode/testGlobals.cpp new file mode 100644 index 0000000000..9094c6cce3 --- /dev/null +++ b/basecode/testGlobals.cpp @@ -0,0 +1,20 @@ +/*** + * Description: Tests functions in global.h + * + * Created: 2020-04-03 + + * Author: Dilawar Singh + * License: MIT License + */ + +#include "global.h" +#include "../utility/simple_assert.hpp" + + +int main(int argc, const char *argv[]) +{ + // Add tests here. + // + return 0; +} + diff --git a/biophysics/Compartment.cpp b/biophysics/Compartment.cpp index 4f7742f7ef..86273a1e85 100644 --- a/biophysics/Compartment.cpp +++ b/biophysics/Compartment.cpp @@ -8,7 +8,7 @@ **********************************************************************/ #include "../basecode/header.h" -#include "../basecode/global.h" +#include "../randnum/randnum.h" #include "CompartmentBase.h" #include "Compartment.h" diff --git a/biophysics/HHChannel.cpp b/biophysics/HHChannel.cpp index e7c72b5ad1..3d84fe6975 100644 --- a/biophysics/HHChannel.cpp +++ b/biophysics/HHChannel.cpp @@ -23,80 +23,72 @@ const int HHChannel::INSTANT_Z = 4; const Cinfo* HHChannel::initCinfo() { -/////////////////////////////////////////////////////// - static string doc[] = - { - "Name", "HHChannel", - "Author", "Upinder S. Bhalla, 2007, NCBS", - "Description", "HHChannel: Hodgkin-Huxley type voltage-gated Ion channel. Something " - "like the old tabchannel from GENESIS, but also presents " - "a similar interface as hhchan from GENESIS. ", - }; - - static Dinfo< HHChannel > dinfo; - - static Cinfo HHChannelCinfo( - "HHChannel", - HHChannelBase::initCinfo(), - 0, - 0, - &dinfo, - doc, - sizeof(doc)/sizeof(string) - ); - - return &HHChannelCinfo; + /////////////////////////////////////////////////////// + static string doc[] = { + "Name", "HHChannel", "Author", "Upinder S. Bhalla, 2007, NCBS", + "Description", + "HHChannel: Hodgkin-Huxley type voltage-gated Ion channel. Something " + "like the old tabchannel from GENESIS, but also presents " + "a similar interface as hhchan from GENESIS. ", }; + + static Dinfo dinfo; + + static Cinfo HHChannelCinfo("HHChannel", HHChannelBase::initCinfo(), 0, 0, + &dinfo, doc, sizeof(doc) / sizeof(string)); + + return &HHChannelCinfo; } static const Cinfo* hhChannelCinfo = HHChannel::initCinfo(); ////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////// // Constructor /////////////////////////////////////////////////// HHChannel::HHChannel() - : - conc_( 0.0 ), - instant_( 0 ), - X_( 0.0 ), Y_( 0.0 ), Z_( 0.0 ), - xInited_( false ), yInited_( false ), zInited_( false ), - g_( 0.0 ), - xGate_( 0 ), - yGate_( 0 ), - zGate_( 0 ), - myId_() + : conc_(0.0), + instant_(0), + X_(0.0), + Y_(0.0), + Z_(0.0), + xInited_(false), + yInited_(false), + zInited_(false), + g_(0.0), + xGate_(0), + yGate_(0), + zGate_(0), + myId_() { - ; + ; } HHChannel::~HHChannel() { - // if ( xGate_ && reinterpret_cast< char* >( this ) == - // ObjId( xGate_->originalChannelId(), 0 ).data() ) - // delete xGate_; - // if ( yGate_ && reinterpret_cast< char* >( this ) == - // ObjId( yGate_->originalChannelId(), 0 ).data() ) - // delete yGate_; - // if ( zGate_ && reinterpret_cast< char* >( this ) == - // ObjId( zGate_->originalChannelId(), 0 ).data() ) - // delete zGate_; + // if ( xGate_ && reinterpret_cast< char* >( this ) == + // ObjId( xGate_->originalChannelId(), 0 ).data() ) + // delete xGate_; + // if ( yGate_ && reinterpret_cast< char* >( this ) == + // ObjId( yGate_->originalChannelId(), 0 ).data() ) + // delete yGate_; + // if ( zGate_ && reinterpret_cast< char* >( this ) == + // ObjId( zGate_->originalChannelId(), 0 ).data() ) + // delete zGate_; } -bool HHChannel::setGatePower( const Eref& e, double power, - double *assignee, const string& gateType ) +bool HHChannel::setGatePower(const Eref& e, double power, double* assignee, + const string& gateType) { - if ( doubleEq( power, *assignee ) ) - return false; + if (doubleEq(power, *assignee)) return false; - if ( doubleEq( *assignee, 0.0 ) && power > 0 ) { - createGate( e, gateType ); - } else if ( doubleEq( power, 0.0 ) ) { - // destroyGate( e, gateType ); - } - *assignee = power; + if (doubleEq(*assignee, 0.0) && power > 0) { + createGate(e, gateType); + } else if (doubleEq(power, 0.0)) { + // destroyGate( e, gateType ); + } + *assignee = power; - return true; + return true; } /** @@ -105,24 +97,22 @@ bool HHChannel::setGatePower( const Eref& e, double power, * If the gate exists and has multiple parents, then make a new gate. * If the gate does not exist, make a new gate */ -void HHChannel::vSetXpower( const Eref& e, double power ) +void HHChannel::vSetXpower(const Eref& e, double power) { - if ( setGatePower( e, power, &Xpower_, "X" ) ) - takeXpower_ = selectPower( power ); + if (setGatePower(e, power, &Xpower_, "X")) takeXpower_ = selectPower(power); } -void HHChannel::vSetYpower( const Eref& e, double power ) +void HHChannel::vSetYpower(const Eref& e, double power) { - if ( setGatePower( e, power, &Ypower_, "Y" ) ) - takeYpower_ = selectPower( power ); + if (setGatePower(e, power, &Ypower_, "Y")) takeYpower_ = selectPower(power); } -void HHChannel::vSetZpower( const Eref& e, double power ) +void HHChannel::vSetZpower(const Eref& e, double power) { - if ( setGatePower( e, power, &Zpower_, "Z" ) ) { - takeZpower_ = selectPower( power ); - useConcentration_ = 1; // Not sure about this. - } + if (setGatePower(e, power, &Zpower_, "Z")) { + takeZpower_ = selectPower(power); + useConcentration_ = 1; // Not sure about this. + } } /** @@ -143,128 +133,128 @@ void HHChannel::vSetZpower( const Eref& e, double power ) // Assuming that the elements are simple elements. Use Eref for // general case -bool HHChannel::checkOriginal( Id chanId ) const +bool HHChannel::checkOriginal(Id chanId) const { - bool isOriginal = 1; - if ( xGate_ ) { - isOriginal = xGate_->isOriginalChannel( chanId ); - } else if ( yGate_ ) { - isOriginal = yGate_->isOriginalChannel( chanId ); - } else if ( zGate_ ) { - isOriginal = zGate_->isOriginalChannel( chanId ); - } - return isOriginal; + bool isOriginal = 1; + if (xGate_) { + isOriginal = xGate_->isOriginalChannel(chanId); + } else if (yGate_) { + isOriginal = yGate_->isOriginalChannel(chanId); + } else if (zGate_) { + isOriginal = zGate_->isOriginalChannel(chanId); + } + return isOriginal; } -void HHChannel::innerCreateGate( const string& gateName, - HHGate** gatePtr, Id chanId, Id gateId ) +void HHChannel::innerCreateGate(const string& gateName, HHGate** gatePtr, + Id chanId, Id gateId) { - //Shell* shell = reinterpret_cast< Shell* >( ObjId( Id(), 0 ).data() ); - if ( *gatePtr ) { - cout << "Warning: HHChannel::createGate: '" << gateName << - "' on Element '" << chanId.path() << "' already present\n"; - return; - } - *gatePtr = new HHGate( chanId, gateId ); + // Shell* shell = reinterpret_cast< Shell* >( ObjId( Id(), 0 ).data() ); + if (*gatePtr) { + cout << "Warning: HHChannel::createGate: '" << gateName + << "' on Element '" << chanId.path() << "' already present\n"; + return; + } + *gatePtr = new HHGate(chanId, gateId); } -void HHChannel::vCreateGate( const Eref& e, - string gateType ) +void HHChannel::vCreateGate(const Eref& e, string gateType) { - if ( !checkOriginal( e.id() ) ) { - cout << "Warning: HHChannel::createGate: Not allowed from copied channel:\n" << e.id().path() << "\n"; - return; - } - - if ( gateType == "X" ) - innerCreateGate( "xGate", &xGate_, e.id(), Id(e.id().value() + 1) ); - else if ( gateType == "Y" ) - innerCreateGate( "yGate", &yGate_, e.id(), Id(e.id().value() + 2) ); - else if ( gateType == "Z" ) - innerCreateGate( "zGate", &zGate_, e.id(), Id(e.id().value() + 3) ); - else - cout << "Warning: HHChannel::createGate: Unknown gate type '" << - gateType << "'. Ignored\n"; + if (!checkOriginal(e.id())) { + cout << "Warning: HHChannel::createGate: Not allowed from copied " + "channel:\n" << e.id().path() << "\n"; + return; + } + + if (gateType == "X") + innerCreateGate("xGate", &xGate_, e.id(), Id(e.id().value() + 1)); + else if (gateType == "Y") + innerCreateGate("yGate", &yGate_, e.id(), Id(e.id().value() + 2)); + else if (gateType == "Z") + innerCreateGate("zGate", &zGate_, e.id(), Id(e.id().value() + 3)); + else + cout << "Warning: HHChannel::createGate: Unknown gate type '" + << gateType << "'. Ignored\n"; } -void HHChannel::innerDestroyGate( const string& gateName, - HHGate** gatePtr, Id chanId ) +void HHChannel::innerDestroyGate(const string& gateName, HHGate** gatePtr, + Id chanId) { - if ( *gatePtr == 0 ) { - cout << "Warning: HHChannel::destroyGate: '" << gateName << - "' on Element '" << chanId.path() << "' not present\n"; - return; - } - delete (*gatePtr); - *gatePtr = 0; + if (*gatePtr == 0) { + cout << "Warning: HHChannel::destroyGate: '" << gateName + << "' on Element '" << chanId.path() << "' not present\n"; + return; + } + delete (*gatePtr); + *gatePtr = 0; } -void HHChannel::destroyGate( const Eref& e, - string gateType ) +void HHChannel::destroyGate(const Eref& e, string gateType) { - if ( !checkOriginal( e.id() ) ) { - cout << "Warning: HHChannel::destroyGate: Not allowed from copied channel:\n" << e.id().path() << "\n"; - return; - } - - if ( gateType == "X" ) - innerDestroyGate( "xGate", &xGate_, e.id() ); - else if ( gateType == "Y" ) - innerDestroyGate( "yGate", &yGate_, e.id() ); - else if ( gateType == "Z" ) - innerDestroyGate( "zGate", &zGate_, e.id() ); - else - cout << "Warning: HHChannel::destroyGate: Unknown gate type '" << - gateType << "'. Ignored\n"; + if (!checkOriginal(e.id())) { + cout << "Warning: HHChannel::destroyGate: Not allowed from copied " + "channel:\n" << e.id().path() << "\n"; + return; + } + + if (gateType == "X") + innerDestroyGate("xGate", &xGate_, e.id()); + else if (gateType == "Y") + innerDestroyGate("yGate", &yGate_, e.id()); + else if (gateType == "Z") + innerDestroyGate("zGate", &zGate_, e.id()); + else + cout << "Warning: HHChannel::destroyGate: Unknown gate type '" + << gateType << "'. Ignored\n"; } /////////////////////////////////////////////////// // Field function definitions /////////////////////////////////////////////////// -void HHChannel::vSetInstant( const Eref& e, int instant ) +void HHChannel::vSetInstant(const Eref& e, int instant) { - instant_ = instant; + instant_ = instant; } -int HHChannel::vGetInstant( const Eref& e ) const +int HHChannel::vGetInstant(const Eref& e) const { - return instant_; + return instant_; } -void HHChannel::vSetX( const Eref& e, double X ) +void HHChannel::vSetX(const Eref& e, double X) { - X_ = X; - xInited_ = true; + X_ = X; + xInited_ = true; } -double HHChannel::vGetX( const Eref& e ) const +double HHChannel::vGetX(const Eref& e) const { - return X_; + return X_; } -void HHChannel::vSetY( const Eref& e, double Y ) +void HHChannel::vSetY(const Eref& e, double Y) { - Y_ = Y; - yInited_ = true; + Y_ = Y; + yInited_ = true; } -double HHChannel::vGetY( const Eref& e ) const +double HHChannel::vGetY(const Eref& e) const { - return Y_; + return Y_; } -void HHChannel::vSetZ( const Eref& e, double Z ) +void HHChannel::vSetZ(const Eref& e, double Z) { - Z_ = Z; - zInited_ = true; + Z_ = Z; + zInited_ = true; } -double HHChannel::vGetZ( const Eref& e ) const +double HHChannel::vGetZ(const Eref& e) const { - return Z_; + return Z_; } -void HHChannel::vSetUseConcentration( const Eref& e, int value ) +void HHChannel::vSetUseConcentration(const Eref& e, int value) { - useConcentration_ = value; + useConcentration_ = value; } /////////////////////////////////////////////////// @@ -275,161 +265,155 @@ void HHChannel::vSetUseConcentration( const Eref& e, int value ) * Returns the state variable for the new timestep based on * the internal variables A_ and B_ which were passed in from the gate. */ -double HHChannel::integrate( double state, double dt, double A, double B ) +double HHChannel::integrate(double state, double dt, double A, double B) { - if ( B > EPSILON ) { - double x = exp( -B * dt ); - return state * x + ( A / B ) * ( 1 - x ); - } - return state + A * dt ; + if (B > EPSILON) { + double x = exp(-B * dt); + return state * x + (A / B) * (1 - x); + } + return state + A * dt; } -void HHChannel::vProcess( const Eref& e, ProcPtr info ) +void HHChannel::vProcess(const Eref& e, ProcPtr info) { - g_ += ChanCommon::vGetGbar( e ); - double A = 0; - double B = 0; - if ( Xpower_ > 0 ) { - xGate_->lookupBoth( Vm_, &A, &B ); - if ( instant_ & INSTANT_X ) - X_ = A/B; - else - X_ = integrate( X_, info->dt, A, B ); - g_ *= takeXpower_( X_, Xpower_ ); - } - - if ( Ypower_ > 0 ) { - yGate_->lookupBoth( Vm_, &A, &B ); - if ( instant_ & INSTANT_Y ) - Y_ = A/B; - else - Y_ = integrate( Y_, info->dt, A, B ); - - g_ *= takeYpower_( Y_, Ypower_ ); - } - - if ( Zpower_ > 0 ) { - if ( useConcentration_ ) - zGate_->lookupBoth( conc_, &A, &B ); - else - zGate_->lookupBoth( Vm_, &A, &B ); - if ( instant_ & INSTANT_Z ) - Z_ = A/B; - else - Z_ = integrate( Z_, info->dt, A, B ); - - g_ *= takeZpower_( Z_, Zpower_ ); - } - - ChanCommon::vSetGk( e, g_ * HHChannelBase::modulation_ ); - ChanCommon::updateIk(); - // Gk_ = g_; - // Ik_ = ( Ek_ - Vm_ ) * g_; - - // Send out the relevant channel messages. - ChanCommon::sendProcessMsgs( e, info ); - - g_ = 0.0; + g_ += ChanCommon::vGetGbar(e); + double A = 0; + double B = 0; + if (Xpower_ > 0) { + xGate_->lookupBoth(Vm_, &A, &B); + if (instant_ & INSTANT_X) + X_ = A / B; + else + X_ = integrate(X_, info->dt, A, B); + g_ *= takeXpower_(X_, Xpower_); + } + + if (Ypower_ > 0) { + yGate_->lookupBoth(Vm_, &A, &B); + if (instant_ & INSTANT_Y) + Y_ = A / B; + else + Y_ = integrate(Y_, info->dt, A, B); + + g_ *= takeYpower_(Y_, Ypower_); + } + + if (Zpower_ > 0) { + if (useConcentration_) + zGate_->lookupBoth(conc_, &A, &B); + else + zGate_->lookupBoth(Vm_, &A, &B); + if (instant_ & INSTANT_Z) + Z_ = A / B; + else + Z_ = integrate(Z_, info->dt, A, B); + + g_ *= takeZpower_(Z_, Zpower_); + } + + ChanCommon::vSetGk(e, g_ * HHChannelBase::modulation_); + ChanCommon::updateIk(); + // Gk_ = g_; + // Ik_ = ( Ek_ - Vm_ ) * g_; + + // Send out the relevant channel messages. + ChanCommon::sendProcessMsgs(e, info); + + g_ = 0.0; } /** * Here we get the steady-state values for the gate (the 'instant' * calculation) as A_/B_. */ -void HHChannel::vReinit( const Eref& er, ProcPtr info ) +void HHChannel::vReinit(const Eref& er, ProcPtr info) { - g_ = ChanCommon::vGetGbar( er ); - Element* e = er.element(); - - double A = 0.0; - double B = 0.0; - if ( Xpower_ > 0 ) { - assert( xGate_ ); - xGate_->lookupBoth( Vm_, &A, &B ); - if ( B < EPSILON ) { - cout << "Warning: B_ value for " << e->getName() << - " is ~0. Check X table\n"; - return; - } - if (!xInited_) - X_ = A/B; - g_ *= takeXpower_( X_, Xpower_ ); - } - - if ( Ypower_ > 0 ) { - assert( yGate_ ); - yGate_->lookupBoth( Vm_, &A, &B ); - if ( B < EPSILON ) { - cout << "Warning: B value for " << e->getName() << - " is ~0. Check Y table\n"; - return; - } - if (!yInited_) - Y_ = A/B; - g_ *= takeYpower_( Y_, Ypower_ ); - } - - if ( Zpower_ > 0 ) { - assert( zGate_ ); - if ( useConcentration_ ) - zGate_->lookupBoth( conc_, &A, &B ); - else - zGate_->lookupBoth( Vm_, &A, &B ); - if ( B < EPSILON ) { - cout << "Warning: B value for " << e->getName() << - " is ~0. Check Z table\n"; - return; - } - if (!zInited_) - Z_ = A/B; - g_ *= takeZpower_( Z_, Zpower_ ); - } - - ChanCommon::vSetGk( er, g_ * HHChannelBase::modulation_ ); - ChanCommon::updateIk(); - // Gk_ = g_; - // Ik_ = ( Ek_ - Vm_ ) * g_; - - // Send out the relevant channel messages. - // Same for reinit as for process. - ChanCommon::sendReinitMsgs( er, info ); - - g_ = 0.0; + g_ = ChanCommon::vGetGbar(er); + Element* e = er.element(); + + double A = 0.0; + double B = 0.0; + if (Xpower_ > 0) { + assert(xGate_); + xGate_->lookupBoth(Vm_, &A, &B); + if (B < EPSILON) { + cout << "Warning: B_ value for " << e->getName() + << " is ~0. Check X table\n"; + return; + } + if (!xInited_) X_ = A / B; + g_ *= takeXpower_(X_, Xpower_); + } + + if (Ypower_ > 0) { + assert(yGate_); + yGate_->lookupBoth(Vm_, &A, &B); + if (B < EPSILON) { + cout << "Warning: B value for " << e->getName() + << " is ~0. Check Y table\n"; + return; + } + if (!yInited_) Y_ = A / B; + g_ *= takeYpower_(Y_, Ypower_); + } + + if (Zpower_ > 0) { + assert(zGate_); + if (useConcentration_) + zGate_->lookupBoth(conc_, &A, &B); + else + zGate_->lookupBoth(Vm_, &A, &B); + if (B < EPSILON) { + cout << "Warning: B value for " << e->getName() + << " is ~0. Check Z table\n"; + return; + } + if (!zInited_) Z_ = A / B; + g_ *= takeZpower_(Z_, Zpower_); + } + + ChanCommon::vSetGk(er, g_ * HHChannelBase::modulation_); + ChanCommon::updateIk(); + // Gk_ = g_; + // Ik_ = ( Ek_ - Vm_ ) * g_; + + // Send out the relevant channel messages. + // Same for reinit as for process. + ChanCommon::sendReinitMsgs(er, info); + + g_ = 0.0; } -void HHChannel::vHandleConc( const Eref& e, double conc ) +void HHChannel::vHandleConc(const Eref& e, double conc) { - conc_ = conc; + conc_ = conc; } -void HHChannel::vSetModulation( const Eref& e, double modulation ) +void HHChannel::vSetModulation(const Eref& e, double modulation) { - if ( modulation > 0.0 ) - HHChannelBase::modulation_ = modulation; + if (modulation > 0.0) HHChannelBase::modulation_ = modulation; } -double HHChannel::vGetModulation( const Eref& e ) const +double HHChannel::vGetModulation(const Eref& e) const { - return HHChannelBase::modulation_; + return HHChannelBase::modulation_; } - /////////////////////////////////////////////////// // HHGate functions /////////////////////////////////////////////////// - -HHGate* HHChannel::vGetXgate( unsigned int i ) const +HHGate* HHChannel::vGetXgate(unsigned int i) const { - return xGate_; + return xGate_; } -HHGate* HHChannel::vGetYgate( unsigned int i ) const +HHGate* HHChannel::vGetYgate(unsigned int i) const { - return yGate_; + return yGate_; } -HHGate* HHChannel::vGetZgate( unsigned int i ) const +HHGate* HHChannel::vGetZgate(unsigned int i) const { - return zGate_; + return zGate_; } diff --git a/biophysics/HHChannel.h b/biophysics/HHChannel.h index abda2d115d..2417749a69 100644 --- a/biophysics/HHChannel.h +++ b/biophysics/HHChannel.h @@ -45,173 +45,169 @@ * on each node. */ -class HHChannel: public HHChannelBase, public ChanCommon -{ +class HHChannel : public HHChannelBase, public ChanCommon { #ifdef DO_UNIT_TESTS - friend void testHHChannel(); - friend void testHHGateCreation(); -#endif // DO_UNIT_TESTS - public: - HHChannel(); - ~HHChannel(); - - ///////////////////////////////////////////////////////////// - // Value field access function definitions - ///////////////////////////////////////////////////////////// - - void vSetXpower( const Eref& e, double Xpower ); - void vSetYpower( const Eref& e, double Ypower ); - void vSetZpower( const Eref& e, double Zpower ); - void vSetInstant( const Eref& e, int Instant ); - int vGetInstant( const Eref& e ) const; - void vSetX( const Eref& e, double X ); - double vGetX( const Eref& e ) const; - void vSetY( const Eref& e, double Y ); - double vGetY( const Eref& e ) const; - void vSetZ( const Eref& e, double Z ); - double vGetZ( const Eref& e ) const; - void vSetUseConcentration( const Eref& e, int value ); - void vSetModulation( const Eref& e, double modulation ); - double vGetModulation( const Eref& e ) const; - - void innerSetXpower( double Xpower ); - void innerSetYpower( double Ypower ); - void innerSetZpower( double Zpower ); - - ///////////////////////////////////////////////////////////// - // Dest function definitions - ///////////////////////////////////////////////////////////// - - /** - * processFunc handles the update and calculations every - * clock tick. It first sends the request for evaluation of - * the gate variables to the respective gate objects and - * recieves their response immediately through a return - * message. This is done so that many channel instances can - * share the same gate lookup tables, but do so cleanly. - * Such messages should never go to a remote node. - * Then the function does its own little calculations to - * send back to the parent compartment through regular - * messages. - */ - void vProcess( const Eref& e, ProcPtr p ); - - /** - * Reinitializes the values for the channel. This involves - * computing the steady-state value for the channel gates - * using the provided Vm from the parent compartment. It - * involves a similar cycle through the gates and then - * updates to the parent compartment as for the processFunc. - */ - void vReinit( const Eref& e, ProcPtr p ); - - /** - * Assign the local Vm_ to the incoming Vm from the compartment - void handleVm( double Vm ); - */ - - /** - * Assign the local conc_ to the incoming conc from the - * concentration calculations for the compartment. Typically - * the message source will be a CaConc object, but there - * are other options for computing the conc. - */ - void vHandleConc( const Eref& e, double conc ); - - ///////////////////////////////////////////////////////////// - // Gate handling functions - ///////////////////////////////////////////////////////////// - /** - * Access function used for the X gate. The index is ignored. - */ - HHGate* vGetXgate( unsigned int i ) const; - - /** - * Access function used for the Y gate. The index is ignored. - */ - HHGate* vGetYgate( unsigned int i ) const; - - /** - * Access function used for the Z gate. The index is ignored. - */ - HHGate* vGetZgate( unsigned int i ) const; - - /// Inner utility function for creating the gate. - void innerCreateGate( - const string& gateName, - HHGate** gatePtr, Id chanId, Id gateId ); - - /// Returns true if channel is original, false if copy. - bool checkOriginal( Id chanId ) const; - - void vCreateGate( const Eref& e, string gateType ); - /** - * Utility function for destroying gate. Works only on original - * HHChannel. Somewhat dangerous, should never be used after a - * copy has been made as the pointer of the gate will be in use - * elsewhere. - */ - void destroyGate( const Eref& e, string gateType ); - - /** - * Inner utility for destroying the gate - */ - void innerDestroyGate( const string& gateName, - HHGate** gatePtr, Id chanId ); - - /** - * Utility for altering gate powers - */ - bool setGatePower( const Eref& e, double power, - double* assignee, const string& gateType ); - - ///////////////////////////////////////////////////////////// - static const Cinfo* initCinfo(); - - private: - /// Conc_ is input variable for Ca-dependent channels. - double conc_; - - double ( *takeXpower_ )( double, double ); - double ( *takeYpower_ )( double, double ); - double ( *takeZpower_ )( double, double ); - - /// bitmapped flag for X, Y, Z, to do equil calculation for gate - int instant_; - /// Channel actual conductance depending on opening of gates. - /// State variable for X gate - double X_; - /// State variable for Y gate - double Y_; - /// State variable for Z gate - double Z_; - - bool xInited_, yInited_, zInited_; // true when a state variable - // has been initialized - double g_; /// Internal variable used to calculate conductance - - double integrate( double state, double dt, double A, double B ); - - /** - * HHGate data structure for the xGate. This is writable only - * on the HHChannel that originally created the HHGate, for others - * it must be treated as readonly. - */ - HHGate* xGate_; - - /// HHGate data structure for the yGate. - HHGate* yGate_; - - /// HHGate data structure for the yGate. - HHGate* zGate_; - - Id myId_; - - static const double EPSILON; - static const int INSTANT_X; - static const int INSTANT_Y; - static const int INSTANT_Z; + friend void testHHChannel(); + friend void testHHGateCreation(); +#endif // DO_UNIT_TESTS +public: + HHChannel(); + ~HHChannel(); + + ///////////////////////////////////////////////////////////// + // Value field access function definitions + ///////////////////////////////////////////////////////////// + + void vSetXpower(const Eref& e, double Xpower); + void vSetYpower(const Eref& e, double Ypower); + void vSetZpower(const Eref& e, double Zpower); + void vSetInstant(const Eref& e, int Instant); + int vGetInstant(const Eref& e) const; + void vSetX(const Eref& e, double X); + double vGetX(const Eref& e) const; + void vSetY(const Eref& e, double Y); + double vGetY(const Eref& e) const; + void vSetZ(const Eref& e, double Z); + double vGetZ(const Eref& e) const; + void vSetUseConcentration(const Eref& e, int value); + void vSetModulation(const Eref& e, double modulation); + double vGetModulation(const Eref& e) const; + + void innerSetXpower(double Xpower); + void innerSetYpower(double Ypower); + void innerSetZpower(double Zpower); + + ///////////////////////////////////////////////////////////// + // Dest function definitions + ///////////////////////////////////////////////////////////// + + /** + * processFunc handles the update and calculations every + * clock tick. It first sends the request for evaluation of + * the gate variables to the respective gate objects and + * recieves their response immediately through a return + * message. This is done so that many channel instances can + * share the same gate lookup tables, but do so cleanly. + * Such messages should never go to a remote node. + * Then the function does its own little calculations to + * send back to the parent compartment through regular + * messages. + */ + void vProcess(const Eref& e, ProcPtr p); + + /** + * Reinitializes the values for the channel. This involves + * computing the steady-state value for the channel gates + * using the provided Vm from the parent compartment. It + * involves a similar cycle through the gates and then + * updates to the parent compartment as for the processFunc. + */ + void vReinit(const Eref& e, ProcPtr p); + + /** + * Assign the local Vm_ to the incoming Vm from the compartment + void handleVm( double Vm ); + */ + + /** + * Assign the local conc_ to the incoming conc from the + * concentration calculations for the compartment. Typically + * the message source will be a CaConc object, but there + * are other options for computing the conc. + */ + void vHandleConc(const Eref& e, double conc); + + ///////////////////////////////////////////////////////////// + // Gate handling functions + ///////////////////////////////////////////////////////////// + /** + * Access function used for the X gate. The index is ignored. + */ + HHGate* vGetXgate(unsigned int i) const; + + /** + * Access function used for the Y gate. The index is ignored. + */ + HHGate* vGetYgate(unsigned int i) const; + + /** + * Access function used for the Z gate. The index is ignored. + */ + HHGate* vGetZgate(unsigned int i) const; + + /// Inner utility function for creating the gate. + void innerCreateGate(const string& gateName, HHGate** gatePtr, Id chanId, + Id gateId); + + /// Returns true if channel is original, false if copy. + bool checkOriginal(Id chanId) const; + + void vCreateGate(const Eref& e, string gateType); + /** + * Utility function for destroying gate. Works only on original + * HHChannel. Somewhat dangerous, should never be used after a + * copy has been made as the pointer of the gate will be in use + * elsewhere. + */ + void destroyGate(const Eref& e, string gateType); + + /** + * Inner utility for destroying the gate + */ + void innerDestroyGate(const string& gateName, HHGate** gatePtr, Id chanId); + + /** + * Utility for altering gate powers + */ + bool setGatePower(const Eref& e, double power, double* assignee, + const string& gateType); + + ///////////////////////////////////////////////////////////// + static const Cinfo* initCinfo(); + +private: + /// Conc_ is input variable for Ca-dependent channels. + double conc_; + + double (*takeXpower_)(double, double); + double (*takeYpower_)(double, double); + double (*takeZpower_)(double, double); + + /// bitmapped flag for X, Y, Z, to do equil calculation for gate + int instant_; + /// Channel actual conductance depending on opening of gates. + /// State variable for X gate + double X_; + /// State variable for Y gate + double Y_; + /// State variable for Z gate + double Z_; + + bool xInited_, yInited_, zInited_; // true when a state variable + // has been initialized + double g_; /// Internal variable used to calculate conductance + + double integrate(double state, double dt, double A, double B); + + /** + * HHGate data structure for the xGate. This is writable only + * on the HHChannel that originally created the HHGate, for others + * it must be treated as readonly. + */ + HHGate* xGate_; + + /// HHGate data structure for the yGate. + HHGate* yGate_; + + /// HHGate data structure for the yGate. + HHGate* zGate_; + + Id myId_; + + static const double EPSILON; + static const int INSTANT_X; + static const int INSTANT_Y; + static const int INSTANT_Z; }; - -#endif // _HHChannel_h +#endif // _HHChannel_h diff --git a/biophysics/HHChannelBase.cpp b/biophysics/HHChannelBase.cpp index 9181338005..46dc496555 100644 --- a/biophysics/HHChannelBase.cpp +++ b/biophysics/HHChannelBase.cpp @@ -15,181 +15,159 @@ const Cinfo* HHChannelBase::initCinfo() { - ///////////////////////////////////////////////////////////////////// - // Shared messages - ///////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////// - // Field definitions - /////////////////////////////////////////////////////// - static ElementValueFinfo< HHChannelBase, double > Xpower( "Xpower", - "Power for X gate", - &HHChannelBase::setXpower, - &HHChannelBase::getXpower - ); - static ElementValueFinfo< HHChannelBase, double > Ypower( "Ypower", - "Power for Y gate", - &HHChannelBase::setYpower, - &HHChannelBase::getYpower - ); - static ElementValueFinfo< HHChannelBase, double > Zpower( "Zpower", - "Power for Z gate", - &HHChannelBase::setZpower, - &HHChannelBase::getZpower - ); - static ElementValueFinfo< HHChannelBase, int > instant( "instant", - "Bitmapped flag: bit 0 = Xgate, bit 1 = Ygate, bit 2 = Zgate" - "When true, specifies that the lookup table value should be" - "used directly as the state of the channel, rather than used" - "as a rate term for numerical integration for the state", - &HHChannelBase::setInstant, - &HHChannelBase::getInstant - ); - static ElementValueFinfo< HHChannelBase, double > X( "X", - "State variable for X gate", - &HHChannelBase::setX, - &HHChannelBase::getX - ); - static ElementValueFinfo< HHChannelBase, double > Y( "Y", - "State variable for Y gate", - &HHChannelBase::setY, - &HHChannelBase::getY - ); - static ElementValueFinfo< HHChannelBase, double > Z( "Z", - "State variable for Y gate", - &HHChannelBase::setZ, - &HHChannelBase::getZ - ); - static ElementValueFinfo< HHChannelBase, int > useConcentration( - "useConcentration", - "Flag: when true, use concentration message rather than Vm to" - "control Z gate", - &HHChannelBase::setUseConcentration, - &HHChannelBase::getUseConcentration - ); - -/////////////////////////////////////////////////////// -// MsgSrc definitions -/////////////////////////////////////////////////////// - // IkOut SrcFinfo defined in base classes. - -/////////////////////////////////////////////////////// -// MsgDest definitions -/////////////////////////////////////////////////////// - static DestFinfo concen( "concen", - "Incoming message from Concen object to specific conc to use" - "in the Z gate calculations", - new EpFunc1< HHChannelBase, double >( &HHChannelBase::handleConc ) - ); - static DestFinfo createGate( "createGate", - "Function to create specified gate." - "Argument: Gate type [X Y Z]", - new EpFunc1< HHChannelBase, string >( &HHChannelBase::createGate ) - ); -/////////////////////////////////////////////////////// -// FieldElementFinfo definition for HHGates. Note that these are made -// with the deferCreate flag off, so that the HHGates are created -// right away even if they are empty. -// Assume only a single entry allocated in each gate. -/////////////////////////////////////////////////////// - static FieldElementFinfo< HHChannelBase, HHGate > gateX( "gateX", - "Sets up HHGate X for channel", - HHGate::initCinfo(), - &HHChannelBase::getXgate, - &HHChannelBase::setNumGates, - &HHChannelBase::getNumXgates - // 1 - ); - static FieldElementFinfo< HHChannelBase, HHGate > gateY( "gateY", - "Sets up HHGate Y for channel", - HHGate::initCinfo(), - &HHChannelBase::getYgate, - &HHChannelBase::setNumGates, - &HHChannelBase::getNumYgates - // 1 - ); - static FieldElementFinfo< HHChannelBase, HHGate > gateZ( "gateZ", - "Sets up HHGate Z for channel", - HHGate::initCinfo(), - &HHChannelBase::getZgate, - &HHChannelBase::setNumGates, - &HHChannelBase::getNumZgates - // 1 - ); - -/////////////////////////////////////////////////////// - static Finfo* HHChannelBaseFinfos[] = - { - &Xpower, // Value - &Ypower, // Value - &Zpower, // Value - &instant, // Value - &X, // Value - &Y, // Value - &Z, // Value - &useConcentration, // Value - &concen, // Dest - &createGate, // Dest - &gateX, // FieldElement - &gateY, // FieldElement - &gateZ // FieldElement - }; - - static string doc[] = - { - "Name", "HHChannelBase", - "Author", "Upinder S. Bhalla, 2014, NCBS", - "Description", "HHChannelBase: Base class for " - "Hodgkin-Huxley type voltage-gated Ion channels. Something " - "like the old tabchannel from GENESIS, but also presents " - "a similar interface as hhchan from GENESIS. ", - }; - - static ZeroSizeDinfo< int > dinfo; - - static Cinfo HHChannelBaseCinfo( - "HHChannelBase", - ChanBase::initCinfo(), - HHChannelBaseFinfos, - sizeof( HHChannelBaseFinfos )/sizeof(Finfo *), - &dinfo, - doc, - sizeof(doc)/sizeof(string) - ); - - return &HHChannelBaseCinfo; + ///////////////////////////////////////////////////////////////////// + // Shared messages + ///////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////// + // Field definitions + /////////////////////////////////////////////////////// + static ElementValueFinfo Xpower( + "Xpower", "Power for X gate", &HHChannelBase::setXpower, + &HHChannelBase::getXpower); + static ElementValueFinfo Ypower( + "Ypower", "Power for Y gate", &HHChannelBase::setYpower, + &HHChannelBase::getYpower); + static ElementValueFinfo Zpower( + "Zpower", "Power for Z gate", &HHChannelBase::setZpower, + &HHChannelBase::getZpower); + static ElementValueFinfo instant( + "instant", + "Bitmapped flag: bit 0 = Xgate, bit 1 = Ygate, bit 2 = Zgate" + "When true, specifies that the lookup table value should be" + "used directly as the state of the channel, rather than used" + "as a rate term for numerical integration for the state", + &HHChannelBase::setInstant, &HHChannelBase::getInstant); + static ElementValueFinfo X( + "X", "State variable for X gate", &HHChannelBase::setX, + &HHChannelBase::getX); + static ElementValueFinfo Y( + "Y", "State variable for Y gate", &HHChannelBase::setY, + &HHChannelBase::getY); + static ElementValueFinfo Z( + "Z", "State variable for Y gate", &HHChannelBase::setZ, + &HHChannelBase::getZ); + static ElementValueFinfo useConcentration( + "useConcentration", + "Flag: when true, use concentration message rather than Vm to" + "control Z gate", + &HHChannelBase::setUseConcentration, + &HHChannelBase::getUseConcentration); + + /////////////////////////////////////////////////////// + // MsgSrc definitions + /////////////////////////////////////////////////////// + // IkOut SrcFinfo defined in base classes. + + /////////////////////////////////////////////////////// + // MsgDest definitions + /////////////////////////////////////////////////////// + static DestFinfo concen( + "concen", + "Incoming message from Concen object to specific conc to use" + "in the Z gate calculations", + new EpFunc1(&HHChannelBase::handleConc)); + static DestFinfo createGate( + "createGate", + "Function to create specified gate." + "Argument: Gate type [X Y Z]", + new EpFunc1(&HHChannelBase::createGate)); + /////////////////////////////////////////////////////// + // FieldElementFinfo definition for HHGates. Note that these are made + // with the deferCreate flag off, so that the HHGates are created + // right away even if they are empty. + // Assume only a single entry allocated in each gate. + /////////////////////////////////////////////////////// + static FieldElementFinfo gateX( + "gateX", "Sets up HHGate X for channel", HHGate::initCinfo(), + &HHChannelBase::getXgate, &HHChannelBase::setNumGates, + &HHChannelBase::getNumXgates + // 1 + ); + static FieldElementFinfo gateY( + "gateY", "Sets up HHGate Y for channel", HHGate::initCinfo(), + &HHChannelBase::getYgate, &HHChannelBase::setNumGates, + &HHChannelBase::getNumYgates + // 1 + ); + static FieldElementFinfo gateZ( + "gateZ", "Sets up HHGate Z for channel", HHGate::initCinfo(), + &HHChannelBase::getZgate, &HHChannelBase::setNumGates, + &HHChannelBase::getNumZgates + // 1 + ); + + /////////////////////////////////////////////////////// + static Finfo* HHChannelBaseFinfos[] = { + &Xpower, // Value + &Ypower, // Value + &Zpower, // Value + &instant, // Value + &X, // Value + &Y, // Value + &Z, // Value + &useConcentration, // Value + &concen, // Dest + &createGate, // Dest + &gateX, // FieldElement + &gateY, // FieldElement + &gateZ // FieldElement + }; + + static string doc[] = { + "Name", + "HHChannelBase", + "Author", + "Upinder S. Bhalla, 2014, NCBS", + "Description", + "HHChannelBase: Base class for " + "Hodgkin-Huxley type voltage-gated Ion channels. Something " + "like the old tabchannel from GENESIS, but also presents " + "a similar interface as hhchan from GENESIS. ", + }; + + static ZeroSizeDinfo dinfo; + + static Cinfo HHChannelBaseCinfo( + "HHChannelBase", ChanBase::initCinfo(), HHChannelBaseFinfos, + sizeof(HHChannelBaseFinfos) / sizeof(Finfo*), &dinfo, doc, + sizeof(doc) / sizeof(string)); + + return &HHChannelBaseCinfo; } static const Cinfo* hhChannelCinfo = HHChannelBase::initCinfo(); ////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////// // Constructor /////////////////////////////////////////////////// HHChannelBase::HHChannelBase() - : - Xpower_( 0.0 ), - Ypower_( 0.0 ), - Zpower_( 0.0 ), - useConcentration_( 0 ), - modulation_( 1.0 ) -{;} + : Xpower_(0.0), + Ypower_(0.0), + Zpower_(0.0), + useConcentration_(0), + modulation_(1.0) +{ + ; +} HHChannelBase::~HHChannelBase() -{;} +{ + ; +} -bool checkPower( double power ) +bool checkPower(double power) { - if ( power < 0.0 ) { - cout << "Warning: HHChannelBase::setPower: Cannot be negative\n"; - return false; - } - if ( power > 5.0 ) { - cout << "Warning: HHChannelBase::setPower: unlikely to be > 5\n"; - return false; - } - return true; + if(power < 0.0) { + cout << "Warning: HHChannelBase::setPower: Cannot be negative\n"; + return false; + } + if(power > 5.0) { + cout << "Warning: HHChannelBase::setPower: unlikely to be > 5\n"; + return false; + } + return true; } /** * Assigns the Xpower for this gate. If the gate exists and has @@ -197,217 +175,219 @@ bool checkPower( double power ) * If the gate exists and has multiple parents, then make a new gate. * If the gate does not exist, make a new gate */ -void HHChannelBase::setXpower( const Eref& e, double power ) +void HHChannelBase::setXpower(const Eref& e, double power) { - if ( checkPower( power ) ) - vSetXpower( e, power ); + if(checkPower(power)) + vSetXpower(e, power); } -void HHChannelBase::setYpower( const Eref& e, double power ) +void HHChannelBase::setYpower(const Eref& e, double power) { - if ( checkPower( power ) ) - vSetYpower( e, power ); + if(checkPower(power)) + vSetYpower(e, power); } -void HHChannelBase::setZpower( const Eref& e, double power ) +void HHChannelBase::setZpower(const Eref& e, double power) { - if ( checkPower( power ) ) - vSetZpower( e, power ); + if(checkPower(power)) + vSetZpower(e, power); } -void HHChannelBase::createGate( const Eref& e, string gateType ) +void HHChannelBase::createGate(const Eref& e, string gateType) { - vCreateGate( e, gateType ); + vCreateGate(e, gateType); } /////////////////////////////////////////////////// // Field function definitions /////////////////////////////////////////////////// -double HHChannelBase::getXpower( const Eref& e ) const +double HHChannelBase::getXpower(const Eref& e) const { - return Xpower_; + return Xpower_; } -double HHChannelBase::getYpower( const Eref& e ) const +double HHChannelBase::getYpower(const Eref& e) const { - return Ypower_; + return Ypower_; } -double HHChannelBase::getZpower( const Eref& e ) const +double HHChannelBase::getZpower(const Eref& e) const { - return Zpower_; + return Zpower_; } -void HHChannelBase::setInstant( const Eref& e, int instant ) +void HHChannelBase::setInstant(const Eref& e, int instant) { - vSetInstant( e, instant ); + vSetInstant(e, instant); } -int HHChannelBase::getInstant( const Eref& e ) const +int HHChannelBase::getInstant(const Eref& e) const { - return vGetInstant( e ); + return vGetInstant(e); } -void HHChannelBase::setX( const Eref& e, double X ) +void HHChannelBase::setX(const Eref& e, double X) { - vSetX( e, X ); + vSetX(e, X); } -double HHChannelBase::getX( const Eref& e ) const +double HHChannelBase::getX(const Eref& e) const { - return vGetX( e ); + return vGetX(e); } -void HHChannelBase::setY( const Eref& e, double Y ) +void HHChannelBase::setY(const Eref& e, double Y) { - vSetY( e, Y ); + vSetY(e, Y); } -double HHChannelBase::getY( const Eref& e ) const +double HHChannelBase::getY(const Eref& e) const { - return vGetY( e ); + return vGetY(e); } -void HHChannelBase::setZ( const Eref& e, double Z ) +void HHChannelBase::setZ(const Eref& e, double Z) { - vSetZ( e, Z ); + vSetZ(e, Z); } -double HHChannelBase::getZ( const Eref& e ) const +double HHChannelBase::getZ(const Eref& e) const { - return vGetZ( e ); + return vGetZ(e); } -void HHChannelBase::setUseConcentration( const Eref& e, int value ) +void HHChannelBase::setUseConcentration(const Eref& e, int value) { - useConcentration_ = value; - vSetUseConcentration( e, value ); + useConcentration_ = value; + vSetUseConcentration(e, value); } -int HHChannelBase::getUseConcentration( const Eref& e) const +int HHChannelBase::getUseConcentration(const Eref& e) const { - return useConcentration_; + return useConcentration_; } -double HHChannelBase::vGetModulation( const Eref& e) const +double HHChannelBase::vGetModulation(const Eref& e) const { - return modulation_; + return modulation_; } /////////////////////////////////////////////////// // Dest function definitions /////////////////////////////////////////////////// -void HHChannelBase::handleConc( const Eref& e, double conc ) +void HHChannelBase::handleConc(const Eref& e, double conc) { - vHandleConc( e, conc ); + vHandleConc(e, conc); } - /////////////////////////////////////////////////// // HHGate functions /////////////////////////////////////////////////// - -HHGate* HHChannelBase::getXgate( unsigned int i ) +HHGate* HHChannelBase::getXgate(unsigned int i) { - return vGetXgate( i ); + return vGetXgate(i); } -HHGate* HHChannelBase::getYgate( unsigned int i ) +HHGate* HHChannelBase::getYgate(unsigned int i) { - return vGetYgate( i ); + return vGetYgate(i); } -HHGate* HHChannelBase::getZgate( unsigned int i ) +HHGate* HHChannelBase::getZgate(unsigned int i) { - return vGetZgate( i ); + return vGetZgate(i); } -void HHChannelBase::setNumGates( unsigned int num ) -{ ; } +void HHChannelBase::setNumGates(unsigned int num) +{ + ; +} -unsigned int HHChannelBase::getNumXgates() const +unsigned int HHChannelBase::getNumXgates() const { - return ( vGetXgate(0) != 0 ); + return (vGetXgate(0) != 0); } -unsigned int HHChannelBase::getNumYgates() const +unsigned int HHChannelBase::getNumYgates() const { - return ( vGetYgate(0) != 0 ); + return (vGetYgate(0) != 0); } -unsigned int HHChannelBase::getNumZgates() const +unsigned int HHChannelBase::getNumZgates() const { - return ( vGetZgate(0) != 0 ); + return (vGetZgate(0) != 0); } /////////////////////////////////////////////////// // Utility function /////////////////////////////////////////////////// -double HHChannelBase::powerN( double x, double p ) +double HHChannelBase::powerN(double x, double p) { - if ( x > 0.0 ) - return exp( p * log( x ) ); - return 0.0; + if(x > 0.0) + return exp(p * log(x)); + return 0.0; } -PFDD HHChannelBase::selectPower( double power ) +PFDD HHChannelBase::selectPower(double power) { - if ( doubleEq( power, 0.0 ) ) - return powerN; - else if ( doubleEq( power, 1.0 ) ) - return power1; - else if ( doubleEq( power, 2.0 ) ) - return power2; - else if ( doubleEq( power, 3.0 ) ) - return power3; - else if ( doubleEq( power, 4.0 ) ) - return power4; - else - return powerN; + if(doubleEq(power, 0.0)) + return powerN; + else if(doubleEq(power, 1.0)) + return power1; + else if(doubleEq(power, 2.0)) + return power2; + else if(doubleEq(power, 3.0)) + return power3; + else if(doubleEq(power, 4.0)) + return power4; + else + return powerN; } ///////////////////////////////////////////////////////////////////// // Dummy instantiation, the zombie derivatives make the real function -void HHChannelBase::vSetSolver( const Eref& e, Id hsolve ) -{;} - -void HHChannelBase::zombify( Element* orig, const Cinfo* zClass, Id hsolve ) -{ - if ( orig->cinfo() == zClass ) - return; - unsigned int start = orig->localDataStart(); - unsigned int num = orig->numLocalData(); - if ( num == 0 ) - return; - // Parameters are Gbar, Ek, Xpower, Ypower, Zpower, useConcentration - // We also want to haul the original gates over, this is done earlier - // in the HSolve building process. So just six terms. - vector< double > chandata( num * 6, 0.0 ); - vector< double >::iterator j = chandata.begin(); - - for ( unsigned int i = 0; i < num; ++i ) { - Eref er( orig, i + start ); - const HHChannelBase* hb = - reinterpret_cast< const HHChannelBase* >( er.data() ); - *j = hb->vGetGbar( er ); - *(j+1) = hb->vGetEk( er); - *(j+2) = hb->getXpower( er ); - *(j+3) = hb->getYpower( er ); - *(j+4) = hb->getZpower( er ); - *(j+5) = hb->getUseConcentration( er ); - j+= 6; - } - orig->zombieSwap( zClass ); - j = chandata.begin(); - for ( unsigned int i = 0; i < num; ++i ) { - Eref er( orig, i + start ); - HHChannelBase* hb = reinterpret_cast< HHChannelBase* >( er.data() ); - hb->vSetSolver( er, hsolve ); - hb->vSetGbar( er, *j ); - hb->vSetEk( er, *(j+1) ); - hb->vSetXpower( er, *(j+2) ); - hb->vSetYpower( er, *(j+3) ); - hb->vSetZpower( er, *(j+4) ); - // hb->vSetUseConcentration( er, *(j+5) > 0.5 ); - // Disable this assignment because the Solver already reads the - // value, and it triggers an error msg. - j+= 6; - } +void HHChannelBase::vSetSolver(const Eref& e, Id hsolve) +{ + ; +} + +void HHChannelBase::zombify(Element* orig, const Cinfo* zClass, Id hsolve) +{ + if(orig->cinfo() == zClass) + return; + unsigned int start = orig->localDataStart(); + unsigned int num = orig->numLocalData(); + if(num == 0) + return; + // Parameters are Gbar, Ek, Xpower, Ypower, Zpower, useConcentration + // We also want to haul the original gates over, this is done earlier + // in the HSolve building process. So just six terms. + vector chandata(num * 6, 0.0); + vector::iterator j = chandata.begin(); + + for(unsigned int i = 0; i < num; ++i) { + Eref er(orig, i + start); + const HHChannelBase* hb = + reinterpret_cast(er.data()); + *j = hb->vGetGbar(er); + *(j + 1) = hb->vGetEk(er); + *(j + 2) = hb->getXpower(er); + *(j + 3) = hb->getYpower(er); + *(j + 4) = hb->getZpower(er); + *(j + 5) = hb->getUseConcentration(er); + j += 6; + } + orig->zombieSwap(zClass); + j = chandata.begin(); + for(unsigned int i = 0; i < num; ++i) { + Eref er(orig, i + start); + HHChannelBase* hb = reinterpret_cast(er.data()); + hb->vSetSolver(er, hsolve); + hb->vSetGbar(er, *j); + hb->vSetEk(er, *(j + 1)); + hb->vSetXpower(er, *(j + 2)); + hb->vSetYpower(er, *(j + 3)); + hb->vSetZpower(er, *(j + 4)); + // hb->vSetUseConcentration( er, *(j+5) > 0.5 ); + // Disable this assignment because the Solver already reads the + // value, and it triggers an error msg. + j += 6; + } } diff --git a/biophysics/HHGate.cpp b/biophysics/HHGate.cpp index eadfeca86f..f4e3787355 100644 --- a/biophysics/HHGate.cpp +++ b/biophysics/HHGate.cpp @@ -18,97 +18,77 @@ const Cinfo* HHGate::initCinfo() /////////////////////////////////////////////////////// // Field definitions. /////////////////////////////////////////////////////// - static ReadOnlyLookupValueFinfo< HHGate, double, double > A( "A", - "lookupA: Look up the A gate value from a double. Usually does" - "so by direct scaling and offset to an integer lookup, using" - "a fine enough table granularity that there is little error." - "Alternatively uses linear interpolation." - "The range of the double is predefined based on knowledge of" - "voltage or conc ranges, and the granularity is specified by" - "the xmin, xmax, and dV fields.", - &HHGate::lookupA ); - static ReadOnlyLookupValueFinfo< HHGate, double, double > B( "B", - "lookupB: Look up the B gate value from a double." - "Note that this looks up the raw tables, which are transformed" - "from the reference parameters.", - &HHGate::lookupB ); - - static ElementValueFinfo< HHGate, vector< double > > alpha( "alpha", - "Parameters for voltage-dependent rates, alpha:" - "Set up alpha term using 5 parameters, as follows:" - "y(x) = (A + B * x) / (C + exp((x + D) / F))" - "The original HH equations can readily be cast into this form", - &HHGate::setAlpha, - &HHGate::getAlpha - ); - - static ElementValueFinfo< HHGate, vector< double > > beta( "beta", - "Parameters for voltage-dependent rates, beta:" - "Set up beta term using 5 parameters, as follows:" - "y(x) = (A + B * x) / (C + exp((x + D) / F))" - "The original HH equations can readily be cast into this form", - &HHGate::setBeta, - &HHGate::getBeta - ); - - static ElementValueFinfo< HHGate, vector< double > > tau( "tau", - "Parameters for voltage-dependent rates, tau:" - "Set up tau curve using 5 parameters, as follows:" - "y(x) = (A + B * x) / (C + exp((x + D) / F))", - &HHGate::setTau, - &HHGate::getTau - ); - - static ElementValueFinfo< HHGate, vector< double > > mInfinity( + static ReadOnlyLookupValueFinfo A( + "A", + "lookupA: Look up the A gate value from a double. Usually does" + "so by direct scaling and offset to an integer lookup, using" + "a fine enough table granularity that there is little error." + "Alternatively uses linear interpolation." + "The range of the double is predefined based on knowledge of" + "voltage or conc ranges, and the granularity is specified by" + "the xmin, xmax, and dV fields.", + &HHGate::lookupA); + static ReadOnlyLookupValueFinfo B( + "B", + "lookupB: Look up the B gate value from a double." + "Note that this looks up the raw tables, which are transformed" + "from the reference parameters.", + &HHGate::lookupB); + + static ElementValueFinfo> alpha( + "alpha", + "Parameters for voltage-dependent rates, alpha:" + "Set up alpha term using 5 parameters, as follows:" + "y(x) = (A + B * x) / (C + exp((x + D) / F))" + "The original HH equations can readily be cast into this form", + &HHGate::setAlpha, &HHGate::getAlpha); + + static ElementValueFinfo> beta( + "beta", + "Parameters for voltage-dependent rates, beta:" + "Set up beta term using 5 parameters, as follows:" + "y(x) = (A + B * x) / (C + exp((x + D) / F))" + "The original HH equations can readily be cast into this form", + &HHGate::setBeta, &HHGate::getBeta); + + static ElementValueFinfo> tau( + "tau", + "Parameters for voltage-dependent rates, tau:" + "Set up tau curve using 5 parameters, as follows:" + "y(x) = (A + B * x) / (C + exp((x + D) / F))", + &HHGate::setTau, &HHGate::getTau); + + static ElementValueFinfo> mInfinity( "mInfinity", "Parameters for voltage-dependent rates, mInfinity:" "Set up mInfinity curve using 5 parameters, as follows:" "y(x) = (A + B * x) / (C + exp((x + D) / F))" "The original HH equations can readily be cast into this form", - &HHGate::setMinfinity, - &HHGate::getMinfinity - ); - - static ElementValueFinfo< HHGate, double > min( "min", - "Minimum range for lookup", - &HHGate::setMin, - &HHGate::getMin - ); - - static ElementValueFinfo< HHGate, double > max( "max", - "Minimum range for lookup", - &HHGate::setMax, - &HHGate::getMax - ); - - static ElementValueFinfo< HHGate, unsigned int > divs( "divs", - "Divisions for lookup. Zero means to use linear interpolation", - &HHGate::setDivs, - &HHGate::getDivs - ); - - static ElementValueFinfo< HHGate, vector< double > > tableA( - "tableA", - "Table of A entries", - &HHGate::setTableA, - &HHGate::getTableA - ); - - static ElementValueFinfo< HHGate, vector< double > > tableB( - "tableB", - "Table of alpha + beta entries", - &HHGate::setTableB, - &HHGate::getTableB - ); - - static ElementValueFinfo< HHGate, bool > useInterpolation( + &HHGate::setMinfinity, &HHGate::getMinfinity); + + static ElementValueFinfo min( + "min", "Minimum range for lookup", &HHGate::setMin, &HHGate::getMin); + + static ElementValueFinfo max( + "max", "Minimum range for lookup", &HHGate::setMax, &HHGate::getMax); + + static ElementValueFinfo divs( + "divs", "Divisions for lookup. Zero means to use linear interpolation", + &HHGate::setDivs, &HHGate::getDivs); + + static ElementValueFinfo> tableA( + "tableA", "Table of A entries", &HHGate::setTableA, &HHGate::getTableA); + + static ElementValueFinfo> tableB( + "tableB", "Table of alpha + beta entries", &HHGate::setTableB, + &HHGate::getTableB); + + static ElementValueFinfo useInterpolation( "useInterpolation", "Flag: use linear interpolation if true, else direct lookup", - &HHGate::setUseInterpolation, - &HHGate::getUseInterpolation - ); + &HHGate::setUseInterpolation, &HHGate::getUseInterpolation); - static ElementValueFinfo< HHGate, vector< double > > alphaParms( + static ElementValueFinfo> alphaParms( "alphaParms", "Set up both gates using 13 parameters, as follows:" "setupAlpha AA AB AC AD AF BA BB BC BD BF xdivs xmin xmax" @@ -121,101 +101,95 @@ const Cinfo* HHGate::initCinfo() "The equation describing each table is:" "y(x) = (A + B * x) / (C + exp((x + D) / F))" "The original HH equations can readily be cast into this form", - &HHGate::setupAlpha, - &HHGate::getAlphaParms - ); + &HHGate::setupAlpha, &HHGate::getAlphaParms); /////////////////////////////////////////////////////// // DestFinfos /////////////////////////////////////////////////////// - static DestFinfo setupAlpha( "setupAlpha", - "Set up both gates using 13 parameters, as follows:" - "setupAlpha AA AB AC AD AF BA BB BC BD BF xdivs xmin xmax" - "Here AA-AF are Coefficients A to F of the alpha (forward) term" - "Here BA-BF are Coefficients A to F of the beta (reverse) term" - "Here xdivs is the number of entries in the table," - "xmin and xmax define the range for lookup." - "Outside this range the returned value will be the low [high]" - "entry of the table." - "The equation describing each table is:" - "y(x) = (A + B * x) / (C + exp((x + D) / F))" - "The original HH equations can readily be cast into this form", - new EpFunc1< HHGate, vector< double > >( &HHGate::setupAlpha ) - ); - static DestFinfo setupTau( "setupTau", - "Identical to setupAlpha, except that the forms specified by" - "the 13 parameters are for the tau and m-infinity curves rather" - "than the alpha and beta terms. So the parameters are:" - "setupTau TA TB TC TD TF MA MB MC MD MF xdivs xmin xmax" - "As before, the equation describing each curve is:" - "y(x) = (A + B * x) / (C + exp((x + D) / F))", - new EpFunc1< HHGate, vector< double > >( &HHGate::setupTau ) - ); - static DestFinfo tweakAlpha( "tweakAlpha", - "Dummy function for backward compatibility. It used to convert" - "the tables from alpha, beta values to alpha, alpha+beta" - "because the internal calculations used these forms. Not" - "needed now, deprecated.", - new OpFunc0< HHGate >( &HHGate::tweakAlpha ) - ); - static DestFinfo tweakTau( "tweakTau", - "Dummy function for backward compatibility. It used to convert" - "the tables from tau, minf values to alpha, alpha+beta" - "because the internal calculations used these forms. Not" - "needed now, deprecated.", - new OpFunc0< HHGate >( &HHGate::tweakTau ) - ); - static DestFinfo setupGate( "setupGate", - "Sets up one gate at a time using the alpha/beta form." - "Has 9 parameters, as follows:" - "setupGate A B C D F xdivs xmin xmax is_beta" - "This sets up the gate using the equation:" - "y(x) = (A + B * x) / (C + exp((x + D) / F))" - "Deprecated.", - new EpFunc1< HHGate, vector< double > >( &HHGate::setupGate ) - ); - static Finfo* HHGateFinfos[] = - { - &A, // ReadOnlyLookupValue - &B, // ReadOnlyLookupValue - &alpha, // ElementValue - &beta, // ElementValue - &tau, // ElementValue - &mInfinity, // ElementValue - &min, // ElementValue - &max, // ElementValue - &divs, // ElementValue - &tableA, // ElementValue - &tableB, // ElementValue - &useInterpolation, // ElementValue - &alphaParms, // ElementValue - &setupAlpha, // Dest - &setupTau, // Dest - &tweakAlpha, // Dest - &tweakTau, // Dest - &setupGate, // Dest + static DestFinfo setupAlpha( + "setupAlpha", + "Set up both gates using 13 parameters, as follows:" + "setupAlpha AA AB AC AD AF BA BB BC BD BF xdivs xmin xmax" + "Here AA-AF are Coefficients A to F of the alpha (forward) term" + "Here BA-BF are Coefficients A to F of the beta (reverse) term" + "Here xdivs is the number of entries in the table," + "xmin and xmax define the range for lookup." + "Outside this range the returned value will be the low [high]" + "entry of the table." + "The equation describing each table is:" + "y(x) = (A + B * x) / (C + exp((x + D) / F))" + "The original HH equations can readily be cast into this form", + new EpFunc1>(&HHGate::setupAlpha)); + static DestFinfo setupTau( + "setupTau", + "Identical to setupAlpha, except that the forms specified by" + "the 13 parameters are for the tau and m-infinity curves rather" + "than the alpha and beta terms. So the parameters are:" + "setupTau TA TB TC TD TF MA MB MC MD MF xdivs xmin xmax" + "As before, the equation describing each curve is:" + "y(x) = (A + B * x) / (C + exp((x + D) / F))", + new EpFunc1>(&HHGate::setupTau)); + static DestFinfo tweakAlpha( + "tweakAlpha", + "Dummy function for backward compatibility. It used to convert" + "the tables from alpha, beta values to alpha, alpha+beta" + "because the internal calculations used these forms. Not" + "needed now, deprecated.", + new OpFunc0(&HHGate::tweakAlpha)); + static DestFinfo tweakTau( + "tweakTau", + "Dummy function for backward compatibility. It used to convert" + "the tables from tau, minf values to alpha, alpha+beta" + "because the internal calculations used these forms. Not" + "needed now, deprecated.", + new OpFunc0(&HHGate::tweakTau)); + static DestFinfo setupGate( + "setupGate", + "Sets up one gate at a time using the alpha/beta form." + "Has 9 parameters, as follows:" + "setupGate A B C D F xdivs xmin xmax is_beta" + "This sets up the gate using the equation:" + "y(x) = (A + B * x) / (C + exp((x + D) / F))" + "Deprecated.", + new EpFunc1>(&HHGate::setupGate)); + static Finfo* HHGateFinfos[] = { + &A, // ReadOnlyLookupValue + &B, // ReadOnlyLookupValue + &alpha, // ElementValue + &beta, // ElementValue + &tau, // ElementValue + &mInfinity, // ElementValue + &min, // ElementValue + &max, // ElementValue + &divs, // ElementValue + &tableA, // ElementValue + &tableB, // ElementValue + &useInterpolation, // ElementValue + &alphaParms, // ElementValue + &setupAlpha, // Dest + &setupTau, // Dest + &tweakAlpha, // Dest + &tweakTau, // Dest + &setupGate, // Dest }; - static string doc[] = - { - "Name", "HHGate", - "Author", "Upinder S. Bhalla, 2011, NCBS", - "Description", "HHGate: Gate for Hodkgin-Huxley type channels, equivalent to the " + static string doc[] = { + "Name", + "HHGate", + "Author", + "Upinder S. Bhalla, 2011, NCBS", + "Description", + "HHGate: Gate for Hodkgin-Huxley type channels, equivalent to the " "m and h terms on the Na squid channel and the n term on K. " "This takes the voltage and state variable from the channel, " "computes the new value of the state variable and a scaling, " "depending on gate power, for the conductance.", }; - static Dinfo< HHGate > dinfo; - static Cinfo HHGateCinfo( - "HHGate", - Neutral::initCinfo(), - HHGateFinfos, sizeof(HHGateFinfos)/sizeof(Finfo *), - &dinfo, - doc, - sizeof(doc)/sizeof(string) - ); + static Dinfo dinfo; + static Cinfo HHGateCinfo("HHGate", Neutral::initCinfo(), HHGateFinfos, + sizeof(HHGateFinfos) / sizeof(Finfo*), &dinfo, doc, + sizeof(doc) / sizeof(string)); return &HHGateCinfo; } @@ -225,331 +199,309 @@ static const Cinfo* hhGateCinfo = HHGate::initCinfo(); // Core class functions /////////////////////////////////////////////////// HHGate::HHGate() - : xmin_(0), xmax_(1), invDx_(1), + : xmin_(0), + xmax_(1), + invDx_(1), originalChanId_(0), originalGateId_(0), lookupByInterpolation_(0), isDirectTable_(0) -{;} - -HHGate::HHGate( Id originalChanId, Id originalGateId ) - : - A_( 1, 0.0 ), - B_( 1, 0.0 ), - xmin_(0), xmax_(1), invDx_(1), - originalChanId_( originalChanId ), - originalGateId_( originalGateId ), - lookupByInterpolation_(0), - isDirectTable_(0) -{;} +{ + ; +} + +HHGate::HHGate(Id originalChanId, Id originalGateId) + : A_(1, 0.0), + B_(1, 0.0), + xmin_(0), + xmax_(1), + invDx_(1), + originalChanId_(originalChanId), + originalGateId_(originalGateId), + lookupByInterpolation_(0), + isDirectTable_(0) +{ + ; +} /////////////////////////////////////////////////// // Field function definitions /////////////////////////////////////////////////// -double HHGate::lookupTable( const vector< double >& tab, double v ) const +double HHGate::lookupTable(const vector& tab, double v) const { - if ( v <= xmin_ ) return tab[0]; - if ( v >= xmax_ ) return tab.back(); - if ( lookupByInterpolation_ ) - { - unsigned int index = - static_cast< unsigned int >( ( v - xmin_ ) * invDx_ ); - assert( tab.size() > index ); - double frac = ( v - xmin_ - index / invDx_ ) * invDx_; - return tab[ index ] * ( 1 - frac ) + tab[ index + 1 ] * frac; + if(v <= xmin_) + return tab[0]; + if(v >= xmax_) + return tab.back(); + if(lookupByInterpolation_) { + unsigned int index = static_cast((v - xmin_) * invDx_); + assert(tab.size() > index); + double frac = (v - xmin_ - index / invDx_) * invDx_; + return tab[index] * (1 - frac) + tab[index + 1] * frac; } - else - { - return tab[ static_cast< unsigned int >( (v - xmin_) * invDx_ ) ]; + else { + return tab[static_cast((v - xmin_) * invDx_)]; } } -double HHGate::lookupA( double v ) const +double HHGate::lookupA(double v) const { - return lookupTable( A_, v ); + return lookupTable(A_, v); } -double HHGate::lookupB( double v ) const +double HHGate::lookupB(double v) const { - return lookupTable( B_, v ); + return lookupTable(B_, v); } -void HHGate::lookupBoth( double v, double* A, double* B ) const +void HHGate::lookupBoth(double v, double* A, double* B) const { - if ( v <= xmin_ ) - { + if(v <= xmin_) { *A = A_[0]; *B = B_[0]; } - else if ( v >= xmax_ ) - { + else if(v >= xmax_) { *A = A_.back(); *B = B_.back(); } - else - { - unsigned int index = - static_cast< unsigned int >( ( v - xmin_ ) * invDx_ ); - assert( A_.size() > index && B_.size() > index ); - if ( lookupByInterpolation_ ) - { - double frac = ( v - xmin_ - index / invDx_ ) * invDx_; - *A = A_[ index ] * ( 1 - frac ) + A_[ index + 1 ] * frac; - *B = B_[ index ] * ( 1 - frac ) + B_[ index + 1 ] * frac; + else { + unsigned int index = static_cast((v - xmin_) * invDx_); + assert(A_.size() > index && B_.size() > index); + if(lookupByInterpolation_) { + double frac = (v - xmin_ - index / invDx_) * invDx_; + *A = A_[index] * (1 - frac) + A_[index + 1] * frac; + *B = B_[index] * (1 - frac) + B_[index + 1] * frac; } - else - { - *A = A_[ index ]; - *B = B_[ index ]; + else { + *A = A_[index]; + *B = B_[index]; } } } -vector< double > HHGate::getAlpha( const Eref& e) const +vector HHGate::getAlpha(const Eref& e) const { return alpha_; } -void HHGate::setAlpha( const Eref& e, vector< double > val ) +void HHGate::setAlpha(const Eref& e, vector val) { - if ( val.size() != 5 ) - { - cout << "Error: HHGate::setAlpha on " << e.id().path() << - ": Number of entries on argument vector should be 5, was " << - val.size() << endl; + if(val.size() != 5) { + cout << "Error: HHGate::setAlpha on " << e.id().path() + << ": Number of entries on argument vector should be 5, was " + << val.size() << endl; return; } - if ( checkOriginal( e.id(), "alpha" ) ) - { + if(checkOriginal(e.id(), "alpha")) { alpha_ = val; updateTauMinf(); updateTables(); } } -vector< double > HHGate::getBeta( const Eref& e) const +vector HHGate::getBeta(const Eref& e) const { return beta_; } -void HHGate::setBeta( const Eref& e, vector< double > val ) +void HHGate::setBeta(const Eref& e, vector val) { - if ( val.size() != 5 ) - { - cout << "Error: HHGate::setBeta on " << e.id().path() << - ": Number of entries on argument vector should be 5, was " << - val.size() << endl; + if(val.size() != 5) { + cout << "Error: HHGate::setBeta on " << e.id().path() + << ": Number of entries on argument vector should be 5, was " + << val.size() << endl; return; } - if ( checkOriginal( e.id(), "beta" ) ) - { + if(checkOriginal(e.id(), "beta")) { beta_ = val; updateTauMinf(); updateTables(); } } -vector< double > HHGate::getTau( const Eref& e) const +vector HHGate::getTau(const Eref& e) const { return tau_; } -void HHGate::setTau( const Eref& e, vector< double > val ) +void HHGate::setTau(const Eref& e, vector val) { - if ( val.size() != 5 ) - { - cout << "Error: HHGate::setTau on " << e.id().path() << - ": Number of entries on argument vector should be 5, was " << - val.size() << endl; + if(val.size() != 5) { + cout << "Error: HHGate::setTau on " << e.id().path() + << ": Number of entries on argument vector should be 5, was " + << val.size() << endl; return; } - if ( checkOriginal( e.id(), "tau" ) ) - { + if(checkOriginal(e.id(), "tau")) { tau_ = val; updateAlphaBeta(); updateTables(); } } -vector< double > HHGate::getMinfinity( const Eref& e) const +vector HHGate::getMinfinity(const Eref& e) const { return mInfinity_; } -void HHGate::setMinfinity( const Eref& e, vector< double > val ) +void HHGate::setMinfinity(const Eref& e, vector val) { - if ( val.size() != 5 ) - { - cout << "Error: HHGate::setMinfinity on " << e.id().path() << - ": Number of entries on argument vector should be 5, was " << - val.size() << endl; + if(val.size() != 5) { + cout << "Error: HHGate::setMinfinity on " << e.id().path() + << ": Number of entries on argument vector should be 5, was " + << val.size() << endl; return; } - if ( checkOriginal( e.id(), "mInfinity" ) ) - { + if(checkOriginal(e.id(), "mInfinity")) { mInfinity_ = val; updateAlphaBeta(); updateTables(); } } -double HHGate::getMin( const Eref& e) const +double HHGate::getMin(const Eref& e) const { return xmin_; } -void HHGate::setMin( const Eref& e, double val ) +void HHGate::setMin(const Eref& e, double val) { - if ( checkOriginal( e.id(), "min" ) ) - { + if(checkOriginal(e.id(), "min")) { xmin_ = val; unsigned int xdivs = A_.size() - 1; - if ( isDirectTable_ && xdivs > 0 ) - { + if(isDirectTable_ && xdivs > 0) { // Stuff here to stretch out table using interpolation. - invDx_ = static_cast< double >( xdivs ) / ( xmax_ - val ); - tabFill( A_, xdivs, val, xmax_ ); - tabFill( B_, xdivs, val, xmax_ ); + invDx_ = static_cast(xdivs) / (xmax_ - val); + tabFill(A_, xdivs, val, xmax_); + tabFill(B_, xdivs, val, xmax_); } - else - { + else { updateTables(); } } } -double HHGate::getMax( const Eref& e) const +double HHGate::getMax(const Eref& e) const { return xmax_; } -void HHGate::setMax( const Eref& e, double val ) +void HHGate::setMax(const Eref& e, double val) { - if ( checkOriginal( e.id(), "max" ) ) - { + if(checkOriginal(e.id(), "max")) { xmax_ = val; unsigned int xdivs = A_.size() - 1; - if ( isDirectTable_ && xdivs > 0 ) - { + if(isDirectTable_ && xdivs > 0) { // Set up using direct assignment of table values. - invDx_ = static_cast< double >( xdivs ) / ( val - xmin_ ); - tabFill( A_, xdivs, xmin_, val ); - tabFill( B_, xdivs, xmin_, val ); + invDx_ = static_cast(xdivs) / (val - xmin_); + tabFill(A_, xdivs, xmin_, val); + tabFill(B_, xdivs, xmin_, val); } - else - { + else { // Set up using functional form. here we just recalculate. updateTables(); } } } -unsigned int HHGate::getDivs( const Eref& e) const +unsigned int HHGate::getDivs(const Eref& e) const { return A_.size() - 1; } -void HHGate::setDivs( const Eref& e, unsigned int val ) +void HHGate::setDivs(const Eref& e, unsigned int val) { - if ( checkOriginal( e.id(), "divs" ) ) - { - if ( isDirectTable_ ) - { - invDx_ = static_cast< double >( val ) / ( xmax_ - xmin_ ); - tabFill( A_, val, xmin_, xmax_ ); - tabFill( B_, val, xmin_, xmax_ ); + if(checkOriginal(e.id(), "divs")) { + if(isDirectTable_) { + invDx_ = static_cast(val) / (xmax_ - xmin_); + tabFill(A_, val, xmin_, xmax_); + tabFill(B_, val, xmin_, xmax_); } - else - { + else { /// Stuff here to redo sizes. - A_.resize( val + 1 ); - B_.resize( val + 1 ); - invDx_ = static_cast< double >( val ) / ( xmax_ - xmin_ ); + A_.resize(val + 1); + B_.resize(val + 1); + invDx_ = static_cast(val) / (xmax_ - xmin_); updateTables(); } } } -vector< double > HHGate::getTableA( const Eref& e) const +vector HHGate::getTableA(const Eref& e) const { return A_; } -void HHGate::setTableA( const Eref& e, vector< double > v ) +void HHGate::setTableA(const Eref& e, vector v) { - if ( v.size() < 2 ) - { + if(v.size() < 2) { cout << "Warning: HHGate::setTableA: size must be >= 2 entries on " << e.id().path() << endl; return; } - if ( checkOriginal( e.id(), "tableA" ) ) - { + if(checkOriginal(e.id(), "tableA")) { isDirectTable_ = 1; A_ = v; unsigned int xdivs = A_.size() - 1; - invDx_ = static_cast< double >( xdivs ) / ( xmax_ - xmin_ ); + invDx_ = static_cast(xdivs) / (xmax_ - xmin_); } } -vector< double > HHGate::getTableB( const Eref& e) const +vector HHGate::getTableB(const Eref& e) const { return B_; } -void HHGate::setTableB( const Eref& e, vector< double > v ) +void HHGate::setTableB(const Eref& e, vector v) { - if ( checkOriginal( e.id(), "tableB" ) ) - { + if(checkOriginal(e.id(), "tableB")) { isDirectTable_ = 1; - if ( A_.size() != v.size() ) - { - cout << "Warning: HHGate::setTableB: size should be same as table A: " << v.size() << " != " << A_.size() << ". Ignoring.\n"; + if(A_.size() != v.size()) { + cout << "Warning: HHGate::setTableB: size should be same as table " + "A: " + << v.size() << " != " << A_.size() << ". Ignoring.\n"; return; } B_ = v; } } -bool HHGate::getUseInterpolation( const Eref& e) const +bool HHGate::getUseInterpolation(const Eref& e) const { return lookupByInterpolation_; } -void HHGate::setUseInterpolation( const Eref& e, bool val ) +void HHGate::setUseInterpolation(const Eref& e, bool val) { - if ( checkOriginal( e.id(), "useInterpolation" ) ) + if(checkOriginal(e.id(), "useInterpolation")) lookupByInterpolation_ = val; } -void HHGate::setupAlpha( const Eref& e, - vector< double > parms ) +void HHGate::setupAlpha(const Eref& e, vector parms) { - if ( checkOriginal( e.id(), "setupAlpha" ) ) - { - if ( parms.size() != 13 ) - { + if(checkOriginal(e.id(), "setupAlpha")) { + if(parms.size() != 13) { cout << "HHGate::setupAlpha: Error: parms.size() != 13\n"; return; } - setupTables( parms, false ); - alpha_.resize( 5, 0 ); - beta_.resize( 5, 0 ); - for ( unsigned int i = 0; i < 5; ++i ) + setupTables(parms, false); + alpha_.resize(5, 0); + beta_.resize(5, 0); + for(unsigned int i = 0; i < 5; ++i) alpha_[i] = parms[i]; - for ( unsigned int i = 5; i < 10; ++i ) + for(unsigned int i = 5; i < 10; ++i) beta_[i - 5] = parms[i]; } } -vector< double > HHGate::getAlphaParms( const Eref& e ) const +vector HHGate::getAlphaParms(const Eref& e) const { - vector< double > ret = alpha_; - ret.insert( ret.end(), beta_.begin(), beta_.end() ); - ret.push_back( A_.size() ); - ret.push_back( xmin_ ); - ret.push_back( xmax_ ); + vector ret = alpha_; + ret.insert(ret.end(), beta_.begin(), beta_.end()); + ret.push_back(A_.size()); + ret.push_back(xmin_); + ret.push_back(xmax_); return ret; } @@ -558,28 +510,25 @@ vector< double > HHGate::getAlphaParms( const Eref& e ) const // Dest function definitions /////////////////////////////////////////////////// -void HHGate::setupTau( const Eref& e, - vector< double > parms ) +void HHGate::setupTau(const Eref& e, vector parms) { - if ( checkOriginal( e.id(), "setupTau" ) ) - { - if ( parms.size() != 13 ) - { + if(checkOriginal(e.id(), "setupTau")) { + if(parms.size() != 13) { cout << "HHGate::setupTau: Error: parms.size() != 13\n"; return; } - setupTables( parms, true ); + setupTables(parms, true); } } void HHGate::tweakAlpha() { - ; // Dummy + ; // Dummy } void HHGate::tweakTau() { - ; // Dummy + ; // Dummy } /** @@ -587,22 +536,23 @@ void HHGate::tweakTau() * function setup_tab_values, * fine tuned by Erik De Schutter. */ -void HHGate::setupTables( const vector< double >& parms, bool doTau ) +void HHGate::setupTables(const vector& parms, bool doTau) { - assert( parms.size() == 13 ); + assert(parms.size() == 13); static const int XDIVS = 10; static const int XMIN = 11; static const int XMAX = 12; - if ( parms[XDIVS] < 1 ) return; - unsigned int xdivs = static_cast< unsigned int >( parms[XDIVS] ); + if(parms[XDIVS] < 1) + return; + unsigned int xdivs = static_cast(parms[XDIVS]); - A_.resize( xdivs + 1 ); - B_.resize( xdivs + 1 ); + A_.resize(xdivs + 1); + B_.resize(xdivs + 1); xmin_ = parms[XMIN]; xmax_ = parms[XMAX]; - assert( xmax_ > xmin_ ); - invDx_ = xdivs / (xmax_ - xmin_ ); - double dx = ( xmax_ - xmin_ ) / xdivs; + assert(xmax_ > xmin_); + invDx_ = xdivs / (xmax_ - xmin_); + double dx = (xmax_ - xmin_) / xdivs; double x = xmin_; double prevAentry = 0.0; @@ -611,55 +561,47 @@ void HHGate::setupTables( const vector< double >& parms, bool doTau ) double temp2 = 0.0; unsigned int i; - for( i = 0; i <= xdivs; i++ ) - { - if ( fabs( parms[4] ) < SINGULARITY ) - { + for(i = 0; i <= xdivs; i++) { + if(fabs(parms[4]) < SINGULARITY) { temp = 0.0; A_[i] = temp; } - else - { - temp2 = parms[2] + exp( ( x + parms[3] ) / parms[4] ); - if ( fabs( temp2 ) < SINGULARITY ) - { - temp2 = parms[2] + exp( ( x + dx/10.0 + parms[3] ) / parms[4] ); - temp = ( parms[0] + parms[1] * (x + dx/10 ) ) / temp2; - - temp2 = parms[2] + exp( ( x - dx/10.0 + parms[3] ) / parms[4] ); - temp += ( parms[0] + parms[1] * (x - dx/10 ) ) / temp2; + else { + temp2 = parms[2] + exp((x + parms[3]) / parms[4]); + if(fabs(temp2) < SINGULARITY) { + temp2 = parms[2] + exp((x + dx / 10.0 + parms[3]) / parms[4]); + temp = (parms[0] + parms[1] * (x + dx / 10)) / temp2; + + temp2 = parms[2] + exp((x - dx / 10.0 + parms[3]) / parms[4]); + temp += (parms[0] + parms[1] * (x - dx / 10)) / temp2; temp /= 2.0; - // cout << "interpolated temp = " << temp << ", prev = " << prevAentry << endl; + // cout << "interpolated temp = " << temp << ", prev = " << + // prevAentry << endl; // temp = prevAentry; A_[i] = temp; } - else - { - temp = ( parms[0] + parms[1] * x) / temp2; + else { + temp = (parms[0] + parms[1] * x) / temp2; A_[i] = temp; } } - if ( fabs( parms[9] ) < SINGULARITY ) - { + if(fabs(parms[9]) < SINGULARITY) { B_[i] = 0.0; } - else - { - temp2 = parms[7] + exp( ( x + parms[8] ) / parms[9] ); - if ( fabs( temp2 ) < SINGULARITY ) - { - temp2 = parms[7] + exp( ( x + dx/10.0 + parms[8] ) / parms[9] ); - temp = (parms[5] + parms[6] * (x + dx/10) ) / temp2; - temp2 = parms[7] + exp( ( x - dx/10.0 + parms[8] ) / parms[9] ); - temp += (parms[5] + parms[6] * (x - dx/10) ) / temp2; + else { + temp2 = parms[7] + exp((x + parms[8]) / parms[9]); + if(fabs(temp2) < SINGULARITY) { + temp2 = parms[7] + exp((x + dx / 10.0 + parms[8]) / parms[9]); + temp = (parms[5] + parms[6] * (x + dx / 10)) / temp2; + temp2 = parms[7] + exp((x - dx / 10.0 + parms[8]) / parms[9]); + temp += (parms[5] + parms[6] * (x - dx / 10)) / temp2; temp /= 2.0; B_[i] = temp; // B_[i] = prevBentry; } - else - { - B_[i] = (parms[5] + parms[6] * x ) / temp2; + else { + B_[i] = (parms[5] + parms[6] * x) / temp2; // B_.table_[i] = ( parms[5] + parms[6] * x ) / temp2; } } @@ -667,7 +609,7 @@ void HHGate::setupTables( const vector< double >& parms, bool doTau ) // the relation to the GENESIS version clearer. // Note the additional SINGULARITY check, to fix a bug // in the earlier code. - if ( doTau == 0 && fabs( temp2 ) > SINGULARITY ) + if(doTau == 0 && fabs(temp2) > SINGULARITY) B_[i] += temp; prevAentry = A_[i]; @@ -677,19 +619,15 @@ void HHGate::setupTables( const vector< double >& parms, bool doTau ) prevAentry = 0.0; prevBentry = 0.0; - if ( doTau ) - { - for( i = 0; i <= xdivs; i++ ) - { + if(doTau) { + for(i = 0; i <= xdivs; i++) { temp = A_[i]; temp2 = B_[i]; - if ( fabs( temp ) < SINGULARITY ) - { + if(fabs(temp) < SINGULARITY) { A_[i] = prevAentry; B_[i] = prevBentry; } - else - { + else { A_[i] = temp2 / temp; B_[i] = 1.0 / temp; } @@ -704,37 +642,32 @@ void HHGate::setupTables( const vector< double >& parms, bool doTau ) * alpha/beta or minf/tau values. See code in * GENESIS/src/olf/new_interp.c, function tweak_tab_values */ -void HHGate::tweakTables( bool doTau ) +void HHGate::tweakTables(bool doTau) { unsigned int i; unsigned int size = A_.size(); - assert( size == B_.size() ); - if ( doTau ) - { - for ( i = 0; i < size; i++ ) - { - double temp = A_[ i ]; - double temp2 = B_[ i ]; - if ( fabs( temp ) < SINGULARITY ) - { - if ( temp < 0.0 ) + assert(size == B_.size()); + if(doTau) { + for(i = 0; i < size; i++) { + double temp = A_[i]; + double temp2 = B_[i]; + if(fabs(temp) < SINGULARITY) { + if(temp < 0.0) temp = -SINGULARITY; else temp = SINGULARITY; } - A_[ i ] = temp2 / temp; - B_[ i ] = 1.0 / temp; + A_[i] = temp2 / temp; + B_[i] = 1.0 / temp; } } - else - { - for ( i = 0; i < size; i++ ) + else { + for(i = 0; i < size; i++) B_[i] = A_[i] + B_[i]; } } -void HHGate::setupGate( const Eref& e, - vector< double > parms ) +void HHGate::setupGate(const Eref& e, vector parms) { // The nine arguments are : // A B C D F size min max isbeta @@ -743,11 +676,10 @@ void HHGate::setupGate( const Eref& e, // HHGate form of alpha, alpha+beta, assuming that the alpha gate // has already been setup. This uses tweakTables. // We may need to resize the tables if they don't match here. - if ( !checkOriginal( e.id(), "setupGate" ) ) + if(!checkOriginal(e.id(), "setupGate")) return; - if ( parms.size() != 9 ) - { + if(parms.size() != 9) { cout << "HHGate::setupGate: Error: parms.size() != 9\n"; return; } @@ -757,64 +689,55 @@ void HHGate::setupGate( const Eref& e, double C = parms[2]; double D = parms[3]; double F = parms[4]; - int size = static_cast< int > (parms[5] ); + int size = static_cast(parms[5]); double min = parms[6]; double max = parms[7]; - bool isBeta = static_cast< bool >( parms[8] ); + bool isBeta = static_cast(parms[8]); - vector< double >& ip = ( isBeta ) ? B_ : A_; + vector& ip = (isBeta) ? B_ : A_; - if ( size <= 0 ) // Look up size, min, max from the interpol + if(size <= 0) // Look up size, min, max from the interpol { size = ip.size() - 1; - if ( size <= 0 ) - { + if(size <= 0) { cout << "Error: setupGate has zero size\n"; return; } } - else - { - ip.resize( size + 1 ); + else { + ip.resize(size + 1); } - double dx = ( max - min ) / static_cast< double >( size ); + double dx = (max - min) / static_cast(size); double x = min + dx / 2.0; - for ( int i = 0; i <= size; i++ ) - { - if ( fabs ( F ) < SINGULARITY ) - { + for(int i = 0; i <= size; i++) { + if(fabs(F) < SINGULARITY) { ip[i] = 0.0; } - else - { - double temp2 = C + exp( ( x + D ) / F ); - if ( fabs( temp2 ) < SINGULARITY ) - ip[i] = ip[i-1]; + else { + double temp2 = C + exp((x + D) / F); + if(fabs(temp2) < SINGULARITY) + ip[i] = ip[i - 1]; else - ip[i] = ( A + B * x ) / temp2; + ip[i] = (A + B * x) / temp2; } } - if ( isBeta ) - { - assert( A_.size() > 0 ); + if(isBeta) { + assert(A_.size() > 0); // Here we ensure that the tables are the same size - if ( A_.size() != B_.size() ) - { - if ( A_.size() > B_.size() ) - { + if(A_.size() != B_.size()) { + if(A_.size() > B_.size()) { // Note that the tabFill expects to allocate the // terminating entry, so we put in size - 1. - tabFill( B_, A_.size() - 1, xmin_, xmax_ ); + tabFill(B_, A_.size() - 1, xmin_, xmax_); } - else - { - tabFill( A_, B_.size() - 1, xmin_, xmax_ ); + else { + tabFill(A_, B_.size() - 1, xmin_, xmax_); } } // Then we do the tweaking to convert to HHChannel form. - tweakTables( 0 ); + tweakTables(0); } } @@ -828,47 +751,45 @@ void HHGate::setupGate( const Eref& e, * newXdivs is one less than the size of the table; it is the number of * subdivisions that the table represents. */ -void HHGate::tabFill( vector< double >& table, - unsigned int newXdivs, double newXmin, double newXmax ) +void HHGate::tabFill(vector& table, unsigned int newXdivs, + double newXmin, double newXmax) { - if ( newXdivs < 3 ) - { + if(newXdivs < 3) { cout << "Error: tabFill: # divs must be >= 3. Not filling table.\n"; return; } - vector< double > old = table; - double newDx = ( newXmax - newXmin ) / newXdivs; - table.resize( newXdivs + 1 ); + vector old = table; + double newDx = (newXmax - newXmin) / newXdivs; + table.resize(newXdivs + 1); bool origLookupMode = lookupByInterpolation_; lookupByInterpolation_ = 1; - for( unsigned int i = 0; i <= newXdivs; ++i ) - { - table[i] = lookupTable( table, newXmin + i * newDx ); + for(unsigned int i = 0; i <= newXdivs; ++i) { + table[i] = lookupTable(table, newXmin + i * newDx); } lookupByInterpolation_ = origLookupMode; } -bool HHGate::checkOriginal( Id id, const string& field ) const +bool HHGate::checkOriginal(Id id, const string& field) const { - if ( id == originalGateId_ ) + if(id == originalGateId_) return 1; - cout << "Warning: HHGate: attempt to set field '" << field << "' on " << - id.path() << "\nwhich is not the original Gate element. Ignored.\n"; + cout << "Warning: HHGate: attempt to set field '" << field << "' on " + << id.path() << ", which is not the original Gate element. Ignored.\n"; return 0; } -bool HHGate::isOriginalChannel( Id id ) const +bool HHGate::isOriginalChannel(Id id) const { - return ( id == originalChanId_ ); + return (id == originalChanId_); } -bool HHGate::isOriginalGate( Id id ) const +bool HHGate::isOriginalGate(Id id) const { - return ( id == originalGateId_ ); + return (id == originalGateId_); } Id HHGate::originalChannelId() const @@ -891,13 +812,13 @@ void HHGate::updateTauMinf() void HHGate::updateTables() { - if ( alpha_.size() == 0 || beta_.size() == 0 ) + if(alpha_.size() == 0 || beta_.size() == 0) return; - vector< double > parms = alpha_; - parms.insert( parms.end(), beta_.begin(), beta_.end() ); - parms.push_back( A_.size() ); - parms.push_back( xmin_ ); - parms.push_back( xmax_ ); + vector parms = alpha_; + parms.insert(parms.end(), beta_.begin(), beta_.end()); + parms.push_back(A_.size()); + parms.push_back(xmin_); + parms.push_back(xmax_); - setupTables( parms, 0 ); + setupTables(parms, 0); } diff --git a/biophysics/HHGate.h b/biophysics/HHGate.h index eadb2821cf..a3bb4a3ce9 100644 --- a/biophysics/HHGate.h +++ b/biophysics/HHGate.h @@ -29,212 +29,211 @@ * original HHChannel, but all the others do have read permission. */ -class HHGate -{ - friend void testHHGateLookup(); - friend void testHHGateSetup(); - public: - /** - * Dummy constructor, to keep Dinfo happy. Should never be used - */ - HHGate(); - - /** - * This constructor is the one meant to be used. It takes the - * originalId of the parent HHChannel as a required argument, - * so that any subsequent 'write' functions can be checked to - * see if they are legal. Also tracks its own Id. - */ - HHGate( Id originalChanId, Id originalGateId ); - - ////////////////////////////////////////////////////////// - // LookupValueFinfos - ////////////////////////////////////////////////////////// - /** - * lookupA: Look up the A vector from a double. Typically does - * so by direct scaling and offset to an integer lookup, using - * a fine enough table granularity that there is little error. - * Alternatively uses linear interpolation. - * The range of the double is predefined based on knowledge of - * voltage or conc ranges, and the granularity is specified by - * the xmin, xmax, and invDx fields. - */ - double lookupA( double v ) const; - - /** - * lookupB: Look up the B vector from a double, similar to lookupA. - */ - double lookupB( double v ) const; - - ////////////////////////////////////////////////////////// - // Field functions - ////////////////////////////////////////////////////////// - void setAlpha( const Eref& e, vector< double > val); - vector< double > getAlpha( const Eref& e) const; - void setBeta( const Eref& e, vector< double > val ); - vector< double > getBeta( const Eref& e) const; - void setTau( const Eref& e, vector< double > val ); - vector< double > getTau( const Eref& e) const; - void setMinfinity( const Eref& e, - vector< double > val ); - vector< double > getMinfinity( const Eref& e) const; - - void setMin( const Eref& e, double val ); - double getMin( const Eref& e) const; - void setMax( const Eref& e, double val ); - double getMax( const Eref& e) const; - void setDivs( const Eref& e, unsigned int val ); - unsigned int getDivs( const Eref& e) const; - - void setTableA( const Eref& e, vector< double > v); - vector< double > getTableA( const Eref& e) const; - - void setTableB( const Eref& e, vector< double > v); - vector< double > getTableB( const Eref& e) const; - - void setUseInterpolation( const Eref& e, bool val ); - bool getUseInterpolation( const Eref& e) const; - - void setupAlpha( const Eref& e, vector< double > parms ); - vector< double > getAlphaParms( const Eref& e ) const; - - ////////////////////////////////////////////////////////// - // DestFinfos - ////////////////////////////////////////////////////////// - void setupTau( const Eref& e, vector< double > parms ); - void tweakAlpha(); - void tweakTau(); - void setupGate( const Eref& e, vector< double > parms ); - void setupTables( const vector< double >& parms, bool doTau ); - void tweakTables( bool doTau ); - - /** - * Single call to get both A and B values by lookup - */ - void lookupBoth( double v, double* A, double* B ) const; - - - ///////////////////////////////////////////////////////////////// - // Utility funcs - ///////////////////////////////////////////////////////////////// - /** - * Returns looked up value of specified table - */ - double lookupTable( const vector< double >& tab, double v ) const; - - /** - * Checks if the provided Id is the one that the HHGate was created - * on. If true, fine, otherwise complains about trying to set the - * field. - */ - bool checkOriginal( Id id, const string& field ) const; - - /** - * isOriginalChannel returns true if the provided Id is the Id of - * the channel on which the HHGate was created. - */ - bool isOriginalChannel( Id id ) const; - - /** - * isOriginalChannel returns true if the provided Id is the Id of - * the Gate created at the same time as the original channel. - */ - bool isOriginalGate( Id id ) const; - - /** - * Returns the Id of the original Channel. - */ - Id originalChannelId() const; - - /** - * Returns the Id of the original Gate. - */ - Id originalGateId() const; - - /** - * tabFill does interpolation and range resizing for - * a table representing a lookup function. - * newXdivs is one less than the size of the table; it is the number - * of subdivisions that the table represents. - * Does NOT alter the existing xmin and xmax, but it does resize - * the table. - */ - void tabFill( vector< double >& table, - unsigned int newXdivs, double newXmin, double newXmax ); - - /** - * Update the Tau and Minfinity parameters because the alpha or - * beta tables have changed. - */ - void updateTauMinf(); - - /** - * Update the alpha and beta parameters because the tau or - * minfinity tables have changed. - */ - void updateAlphaBeta(); - - /** - * Take the current alpha/beta parameters, and xdivs, xmin, xmax; - * and rebuild the tables. - */ - void updateTables(); - - static const Cinfo* initCinfo(); - private: - /// 5 parameters for alpha - vector< double > alpha_; - - /// 5 parameters for beta - vector< double > beta_; - - /// 5 parameters for tau - vector< double > tau_; - - /// 5 parameters for mInfinity - vector< double > mInfinity_; - - /// The actual lookup table for calculations. Holds alpha(V). - vector< double > A_; - - /// The lookup table for calculations. Holds alpha(V) + beta(V). - vector< double > B_; - - /// Minimum of the voltage (or conc) range. - double xmin_; - - /// Max of the voltage (or conc) range. - double xmax_; - - /// increment of the range. - double invDx_; - - /** - * Id of original channel, the one which has actually allocated it, - * All other Elements have to treat the values as readonly. - */ - Id originalChanId_; - - /** - * Id of original Gate, the one which was created with the original - * channel. - * All other Elements have to treat the values as readonly. - */ - Id originalGateId_; - - /** - * Flag: Use linear interpolation for lookup if true, use direct - * table lookup if false. - */ - bool lookupByInterpolation_; - - /** - * Flag to indicate if table entries have been assigned directly - * (as direct experimental data, or an externally defined V-dep - * function). When zero it means that the curve-fit forms from - * setupAlpha etc. have been used. - */ - bool isDirectTable_; +class HHGate { + friend void testHHGateLookup(); + friend void testHHGateSetup(); + +public: + /** + * Dummy constructor, to keep Dinfo happy. Should never be used + */ + HHGate(); + + /** + * This constructor is the one meant to be used. It takes the + * originalId of the parent HHChannel as a required argument, + * so that any subsequent 'write' functions can be checked to + * see if they are legal. Also tracks its own Id. + */ + HHGate(Id originalChanId, Id originalGateId); + + ////////////////////////////////////////////////////////// + // LookupValueFinfos + ////////////////////////////////////////////////////////// + /** + * lookupA: Look up the A vector from a double. Typically does + * so by direct scaling and offset to an integer lookup, using + * a fine enough table granularity that there is little error. + * Alternatively uses linear interpolation. + * The range of the double is predefined based on knowledge of + * voltage or conc ranges, and the granularity is specified by + * the xmin, xmax, and invDx fields. + */ + double lookupA(double v) const; + + /** + * lookupB: Look up the B vector from a double, similar to lookupA. + */ + double lookupB(double v) const; + + ////////////////////////////////////////////////////////// + // Field functions + ////////////////////////////////////////////////////////// + void setAlpha(const Eref& e, vector val); + vector getAlpha(const Eref& e) const; + void setBeta(const Eref& e, vector val); + vector getBeta(const Eref& e) const; + void setTau(const Eref& e, vector val); + vector getTau(const Eref& e) const; + void setMinfinity(const Eref& e, vector val); + vector getMinfinity(const Eref& e) const; + + void setMin(const Eref& e, double val); + double getMin(const Eref& e) const; + void setMax(const Eref& e, double val); + double getMax(const Eref& e) const; + void setDivs(const Eref& e, unsigned int val); + unsigned int getDivs(const Eref& e) const; + + void setTableA(const Eref& e, vector v); + vector getTableA(const Eref& e) const; + + void setTableB(const Eref& e, vector v); + vector getTableB(const Eref& e) const; + + void setUseInterpolation(const Eref& e, bool val); + bool getUseInterpolation(const Eref& e) const; + + void setupAlpha(const Eref& e, vector parms); + vector getAlphaParms(const Eref& e) const; + + ////////////////////////////////////////////////////////// + // DestFinfos + ////////////////////////////////////////////////////////// + void setupTau(const Eref& e, vector parms); + void tweakAlpha(); + void tweakTau(); + void setupGate(const Eref& e, vector parms); + void setupTables(const vector& parms, bool doTau); + void tweakTables(bool doTau); + + /** + * Single call to get both A and B values by lookup + */ + void lookupBoth(double v, double* A, double* B) const; + + ///////////////////////////////////////////////////////////////// + // Utility funcs + ///////////////////////////////////////////////////////////////// + /** + * Returns looked up value of specified table + */ + double lookupTable(const vector& tab, double v) const; + + /** + * Checks if the provided Id is the one that the HHGate was created + * on. If true, fine, otherwise complains about trying to set the + * field. + */ + bool checkOriginal(Id id, const string& field) const; + + /** + * isOriginalChannel returns true if the provided Id is the Id of + * the channel on which the HHGate was created. + */ + bool isOriginalChannel(Id id) const; + + /** + * isOriginalChannel returns true if the provided Id is the Id of + * the Gate created at the same time as the original channel. + */ + bool isOriginalGate(Id id) const; + + /** + * Returns the Id of the original Channel. + */ + Id originalChannelId() const; + + /** + * Returns the Id of the original Gate. + */ + Id originalGateId() const; + + /** + * tabFill does interpolation and range resizing for + * a table representing a lookup function. + * newXdivs is one less than the size of the table; it is the number + * of subdivisions that the table represents. + * Does NOT alter the existing xmin and xmax, but it does resize + * the table. + */ + void tabFill(vector& table, unsigned int newXdivs, double newXmin, + double newXmax); + + /** + * Update the Tau and Minfinity parameters because the alpha or + * beta tables have changed. + */ + void updateTauMinf(); + + /** + * Update the alpha and beta parameters because the tau or + * minfinity tables have changed. + */ + void updateAlphaBeta(); + + /** + * Take the current alpha/beta parameters, and xdivs, xmin, xmax; + * and rebuild the tables. + */ + void updateTables(); + + static const Cinfo* initCinfo(); + +private: + /// 5 parameters for alpha + vector alpha_; + + /// 5 parameters for beta + vector beta_; + + /// 5 parameters for tau + vector tau_; + + /// 5 parameters for mInfinity + vector mInfinity_; + + /// The actual lookup table for calculations. Holds alpha(V). + vector A_; + + /// The lookup table for calculations. Holds alpha(V) + beta(V). + vector B_; + + /// Minimum of the voltage (or conc) range. + double xmin_; + + /// Max of the voltage (or conc) range. + double xmax_; + + /// increment of the range. + double invDx_; + + /** + * Id of original channel, the one which has actually allocated it, + * All other Elements have to treat the values as readonly. + */ + Id originalChanId_; + + /** + * Id of original Gate, the one which was created with the original + * channel. + * All other Elements have to treat the values as readonly. + */ + Id originalGateId_; + + /** + * Flag: Use linear interpolation for lookup if true, use direct + * table lookup if false. + */ + bool lookupByInterpolation_; + + /** + * Flag to indicate if table entries have been assigned directly + * (as direct experimental data, or an externally defined V-dep + * function). When zero it means that the curve-fit forms from + * setupAlpha etc. have been used. + */ + bool isDirectTable_; }; -#endif // _HHGate_h +#endif // _HHGate_h diff --git a/biophysics/Neuron.cpp b/biophysics/Neuron.cpp index 29c74c52b7..76cf3819b5 100644 --- a/biophysics/Neuron.cpp +++ b/biophysics/Neuron.cpp @@ -12,12 +12,15 @@ #include "../basecode/LookupElementValueFinfo.h" #include "../shell/Shell.h" #include "../shell/Wildcard.h" + +#include "../randnum/randnum.h" + #include "ReadCell.h" #include "../utility/Vec.h" + #include "SwcSegment.h" #include "Spine.h" #include "Neuron.h" -#include "../basecode/global.h" #include "../builtins/MooseParser.h" diff --git a/biophysics/RandSpike.cpp b/biophysics/RandSpike.cpp index 57fdf8afe5..4bdb28c806 100644 --- a/biophysics/RandSpike.cpp +++ b/biophysics/RandSpike.cpp @@ -8,7 +8,7 @@ **********************************************************************/ #include "../basecode/header.h" -#include "../basecode/global.h" +#include "../randnum/randnum.h" #include "RandSpike.h" diff --git a/biophysics/ReadCell.cpp b/biophysics/ReadCell.cpp index 06c0f2461c..ca3e7c903a 100644 --- a/biophysics/ReadCell.cpp +++ b/biophysics/ReadCell.cpp @@ -157,7 +157,7 @@ bool ReadCell::innerRead( ifstream& fin ) lineNum_ = 0; ParseStage parseMode = DATA; - string::size_type pos; + std::string::size_type pos; while ( getline( fin, line ) ) { line = moose::trim( line ); @@ -419,7 +419,7 @@ Id ReadCell::buildCompartment( //~ assert( ret ); //~ if ( !childId.bad() ) { //~ if ( name[ name.length() - 1 ] == ']' ) { - //~ string::size_type pos = name.rfind( '[' ); + //~ auto pos = name.rfind( '[' ); //~ if ( pos == string::npos ) { //~ cerr << "Error: ReadCell: bad child name:" << name << endl; //~ cerr << "File: " << fileName_ << " Line: " << lineNum_ << endl; @@ -570,8 +570,8 @@ Id ReadCell::startGraftCell( const string& cellPath ) ObjId parentObjId; string cellName; - string::size_type pos_1 = cellPath.find_first_of( "/" ); - string::size_type pos_2 = cellPath.find_last_of( "/" ); + auto pos_1 = cellPath.find_first_of( "/" ); + auto pos_2 = cellPath.find_last_of( "/" ); if ( pos_1 != 0 ) { cerr << "Error: ReadCell: *start_cell should be given absolute path.\n"; diff --git a/biophysics/ReadSwc.cpp b/biophysics/ReadSwc.cpp index 9329ed51e1..0aab4abebc 100644 --- a/biophysics/ReadSwc.cpp +++ b/biophysics/ReadSwc.cpp @@ -37,7 +37,7 @@ ReadSwc::ReadSwc( const string& fname ) { if ( temp.length() == 0 ) continue; - string::size_type pos = temp.find_first_not_of( "\t " ); + auto pos = temp.find_first_not_of( "\t " ); if ( pos == string::npos ) continue; if ( temp[pos] == '#' ) diff --git a/biophysics/testBiophysics.cpp b/biophysics/testBiophysics.cpp index 0dde4834ba..e00575e7c5 100644 --- a/biophysics/testBiophysics.cpp +++ b/biophysics/testBiophysics.cpp @@ -7,25 +7,23 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ - #include "../basecode/header.h" -#include "../basecode/global.h" +#include "../randnum/randnum.h" #include "../shell/Shell.h" #include "../utility/testing_macros.hpp" #include "CompartmentBase.h" #include "Compartment.h" -extern void testCompartment(); // Defined in Compartment.cpp -extern void testCompartmentProcess(); // Defined in Compartment.cpp -extern void testMarkovRateTable(); //Defined in MarkovRateTable.cpp -extern void testVectorTable(); //Defined in VectorTable.cpp - +extern void testCompartment(); // Defined in Compartment.cpp +extern void testCompartmentProcess(); // Defined in Compartment.cpp +extern void testMarkovRateTable(); // Defined in MarkovRateTable.cpp +extern void testVectorTable(); // Defined in VectorTable.cpp #ifdef DO_UNIT_TESTS // Use a larger value of runsteps when benchmarking -void testIntFireNetwork( unsigned int runsteps = 5 ) +void testIntFireNetwork(unsigned int runsteps = 5) { static const double thresh = 0.8; static const double Vmax = 1.0; @@ -38,56 +36,53 @@ void testIntFireNetwork( unsigned int runsteps = 5 ) static const unsigned int NUM_TOT_SYN = 104831; unsigned int size = 1024; string arg; - Eref sheller( Id().eref() ); - Shell* shell = reinterpret_cast< Shell* >( sheller.data() ); + Eref sheller(Id().eref()); + Shell* shell = reinterpret_cast(sheller.data()); - Id fire = shell->doCreate( "IntFire", Id(), "network", size ); - assert( fire.element()->getName() == "network" ); + Id fire = shell->doCreate("IntFire", Id(), "network", size); + assert(fire.element()->getName() == "network"); - Id i2 = shell->doCreate( "SimpleSynHandler", fire, "syns", size ); - assert( i2.element()->getName() == "syns" ); + Id i2 = shell->doCreate("SimpleSynHandler", fire, "syns", size); + assert(i2.element()->getName() == "syns"); - Id synId( i2.value() + 1 ); + Id synId(i2.value() + 1); Element* syn = synId.element(); - assert( syn->getName() == "synapse" ); + assert(syn->getName() == "synapse"); - DataId di( 1 ); // DataId( data, field ) - Eref syne( syn, di ); + DataId di(1); // DataId( data, field ) + Eref syne(syn, di); - ObjId mid = shell->doAddMsg( "Sparse", fire, "spikeOut", - ObjId( synId, 0 ), "addSpike" ); + ObjId mid = shell->doAddMsg("Sparse", fire, "spikeOut", ObjId(synId, 0), + "addSpike"); - SetGet2< double, long >::set( mid, "setRandomConnectivity", - connectionProbability, 5489UL ); + SetGet2::set(mid, "setRandomConnectivity", + connectionProbability, 5489UL); - mid = shell->doAddMsg( "OneToOne", i2, "activationOut", - fire, "activation" ); - assert( !mid.bad() ); + mid = shell->doAddMsg("OneToOne", i2, "activationOut", fire, "activation"); + assert(!mid.bad()); unsigned int nd = syn->totNumLocalField(); - if ( Shell::numNodes() == 1 ) - { - EXPECT_EQ( nd, NUM_TOT_SYN, "" ); + if(Shell::numNodes() == 1) { + EXPECT_EQ(nd, NUM_TOT_SYN, "NUM_NODES=1"); } - else if ( Shell::numNodes() == 2 ) - assert( nd == 52446 ); - else if ( Shell::numNodes() == 3 ) - //assert( nd == 34969 ); - assert( nd == 35087 ); - else if ( Shell::numNodes() == 4 ) - assert( nd == 26381 ); + else if(Shell::numNodes() == 2) + assert(nd == 52446); + else if(Shell::numNodes() == 3) + // assert( nd == 34969 ); + assert(nd == 35087); + else if(Shell::numNodes() == 4) + assert(nd == 26381); ////////////////////////////////////////////////////////////////// // Checking access to message info through SparseMsg on many nodes. ////////////////////////////////////////////////////////////////// - vector< ObjId > tgts; - vector< string > funcs; - ObjId oi( fire, 123 ); - tgts = LookupField< string, vector< ObjId > >:: - get( oi, "msgDests", "spikeOut" ); - funcs = LookupField< string, vector< string > >:: - get( oi, "msgDestFunctions", "spikeOut" ); - assert( tgts.size() == funcs.size() ); + vector tgts; + vector funcs; + ObjId oi(fire, 123); + tgts = LookupField>::get(oi, "msgDests", "spikeOut"); + funcs = LookupField>::get(oi, "msgDestFunctions", + "spikeOut"); + assert(tgts.size() == funcs.size()); /* assert( tgts.size() == 116 ); assert( tgts[0] == ObjId( synId, 20, 11 ) ); @@ -97,119 +92,114 @@ void testIntFireNetwork( unsigned int runsteps = 5 ) assert( tgts[91] == ObjId( synId, 792, 12 ) ); assert( tgts[92] == ObjId( synId, 801, 17 ) ); */ - for ( unsigned int i = 0; i < funcs.size(); ++i ) - assert( funcs[i] == "addSpike" ); + for(unsigned int i = 0; i < funcs.size(); ++i) + assert(funcs[i] == "addSpike"); ////////////////////////////////////////////////////////////////// // Here we have an interesting problem. The mtRand might be called // by multiple threads if the above Set call is not complete. - vector< double > origVm( size, 0.0 ); + vector origVm(size, 0.0); // NOTE: From - moose::mtseed( 5489UL ); - for ( unsigned int i = 0; i < size; ++i ) + moose::mtseed(5489UL); + for(unsigned int i = 0; i < size; ++i) origVm[i] = moose::mtrand() * Vmax; double origVm100 = origVm[100]; double origVm900 = origVm[900]; - vector< double > temp; + vector temp; temp.clear(); - temp.resize( size, thresh ); - bool ret = Field< double >::setVec( fire, "thresh", temp ); - assert( ret ); + temp.resize(size, thresh); + bool ret = Field::setVec(fire, "thresh", temp); + assert(ret); temp.clear(); - temp.resize( size, refractoryPeriod ); - ret = Field< double >::setVec( fire, "refractoryPeriod", temp ); - assert( ret ); + temp.resize(size, refractoryPeriod); + ret = Field::setVec(fire, "refractoryPeriod", temp); + assert(ret); // cout << Shell::myNode() << ": fieldSize = " << fieldSize << endl; - vector< unsigned int > numSynVec; - Field< unsigned int >::getVec( i2, "numSynapses", numSynVec ); - assert ( numSynVec.size() == size ); + vector numSynVec; + Field::getVec(i2, "numSynapses", numSynVec); + assert(numSynVec.size() == size); unsigned int numTotSyn = 0; - for ( unsigned int i = 0; i < size; ++i ) + for(unsigned int i = 0; i < size; ++i) numTotSyn += numSynVec[i]; - assert( numTotSyn == NUM_TOT_SYN ); - - vector< vector< double > > weight( size ); - for ( unsigned int i = 0; i < size; ++i ) - { - weight[i].resize( numSynVec[i], 0.0 ); - vector< double > delay( numSynVec[i], 0.0 ); - for ( unsigned int j = 0; j < numSynVec[i]; ++j ) - { - weight[i][ j ] = moose::mtrand() * weightMax; - delay[ j ] = delayMin + moose::mtrand() * ( delayMax - delayMin ); + assert(numTotSyn == NUM_TOT_SYN); + + vector> weight(size); + for(unsigned int i = 0; i < size; ++i) { + weight[i].resize(numSynVec[i], 0.0); + vector delay(numSynVec[i], 0.0); + for(unsigned int j = 0; j < numSynVec[i]; ++j) { + weight[i][j] = moose::mtrand() * weightMax; + delay[j] = delayMin + moose::mtrand() * (delayMax - delayMin); } - ret = Field< double >::setVec( ObjId( synId, i ), "weight", weight[i] ); - assert( ret ); - ret = Field< double >::setVec( ObjId( synId, i ), "delay", delay ); - assert( ret ); + ret = Field::setVec(ObjId(synId, i), "weight", weight[i]); + assert(ret); + ret = Field::setVec(ObjId(synId, i), "delay", delay); + assert(ret); } - for ( unsigned int i = 0; i < size; ++i ) - { - vector< double > retVec(0); - Field< double >::getVec( ObjId( synId, i ), "weight", retVec ); - assert( retVec.size() == numSynVec[i] ); - for ( unsigned int j = 0; j < numSynVec[i]; ++j ) - { - ASSERT_DOUBLE_EQ("", retVec[j], weight[i][j] ); - } + for(unsigned int i = 0; i < size; ++i) { + vector retVec(0); + Field::getVec(ObjId(synId, i), "weight", retVec); + assert(retVec.size() == numSynVec[i]); + for(unsigned int j = 0; j < numSynVec[i]; ++j) + ASSERT_DOUBLE_EQ(retVec[j], weight[i][j], ""); } // We have to have the SynHandlers called before the network of // IntFires since the 'activation' message must be delivered within // the same timestep. - shell->doUseClock("/network/syns", "process", 0 ); - shell->doUseClock("/network", "process", 1 ); - shell->doSetClock( 0, timestep ); - shell->doSetClock( 1, timestep ); - shell->doSetClock( 9, timestep ); + shell->doUseClock("/network/syns", "process", 0); + shell->doUseClock("/network", "process", 1); + shell->doSetClock(0, timestep); + shell->doSetClock(1, timestep); + shell->doSetClock(9, timestep); shell->doReinit(); - ret = Field< double >::setVec( fire, "Vm", origVm ); - assert( ret ); + ret = Field::setVec(fire, "Vm", origVm); + assert(ret); - double retVm100 = Field< double >::get( ObjId( fire, 100 ), "Vm" ); - double retVm900 = Field< double >::get( ObjId( fire, 900 ), "Vm" ); - assert( fabs( retVm100 - origVm100 ) < 1e-6 ); - assert( fabs( retVm900 - origVm900 ) < 1e-6 ); + double retVm100 = Field::get(ObjId(fire, 100), "Vm"); + double retVm900 = Field::get(ObjId(fire, 900), "Vm"); + assert(fabs(retVm100 - origVm100) < 1e-6); + assert(fabs(retVm900 - origVm900) < 1e-6); - shell->doStart( static_cast< double >( timestep * runsteps) + 0.0 ); - if ( runsteps == 5 ) // default for unit tests, others are benchmarks + shell->doStart(static_cast(timestep * runsteps) + 0.0); + if(runsteps == 5) // default for unit tests, others are benchmarks { - retVm100 = Field< double >::get( ObjId( fire, 100 ), "Vm" ); - double retVm101 = Field< double >::get( ObjId( fire, 101 ), "Vm" ); - double retVm102 = Field< double >::get( ObjId( fire, 102 ), "Vm" ); - double retVm99 = Field< double >::get( ObjId( fire, 99 ), "Vm" ); - retVm900 = Field< double >::get( ObjId( fire, 900 ), "Vm" ); - double retVm901 = Field< double >::get( ObjId( fire, 901 ), "Vm" ); - double retVm902 = Field< double >::get( ObjId( fire, 902 ), "Vm" ); + retVm100 = Field::get(ObjId(fire, 100), "Vm"); + double retVm101 = Field::get(ObjId(fire, 101), "Vm"); + double retVm102 = Field::get(ObjId(fire, 102), "Vm"); + double retVm99 = Field::get(ObjId(fire, 99), "Vm"); + retVm900 = Field::get(ObjId(fire, 900), "Vm"); + double retVm901 = Field::get(ObjId(fire, 901), "Vm"); + double retVm902 = Field::get(ObjId(fire, 902), "Vm"); /* - ASSERT_DOUBLE_EQ("", retVm100, 0.00734036 ); - ASSERT_DOUBLE_EQ("", retVm101, 0.246818 ); - ASSERT_DOUBLE_EQ("", retVm102, 0.200087 ); - ASSERT_DOUBLE_EQ("", retVm99, 0.0095779083 ); - ASSERT_DOUBLE_EQ("", retVm900, 0.1150573482 ); - ASSERT_DOUBLE_EQ("", retVm901, 0.289321534 ); - ASSERT_DOUBLE_EQ("", retVm902, 0.01011172486 ); - ASSERT_DOUBLE_EQ("", retVm100, 0.008593194687366486 ); - ASSERT_DOUBLE_EQ("", retVm101, 0.24931678857743744 ); - ASSERT_DOUBLE_EQ("", retVm102, 0.19668269662484533 ); - ASSERT_DOUBLE_EQ("", retVm99, 0.00701607616202429 ); - ASSERT_DOUBLE_EQ("", retVm900, 0.12097053045094018 ); - ASSERT_DOUBLE_EQ("", retVm901, 0.2902593120492995 ); - ASSERT_DOUBLE_EQ("", retVm902, 0.00237157280699805 ); - ASSERT_DOUBLE_EQ("", retVm100, 0.015766608829826119 ); - ASSERT_DOUBLE_EQ("", retVm101, 0.24405557875013356 ); - ASSERT_DOUBLE_EQ("", retVm102, 0.20878261213859917 ); - ASSERT_DOUBLE_EQ("", retVm99, 0.0081746848675747306 ); - ASSERT_DOUBLE_EQ("", retVm900, 0.12525297735741736 ); - ASSERT_DOUBLE_EQ("", retVm901, 0.28303358631241327 ); - ASSERT_DOUBLE_EQ("", retVm902, 0.0096374021108587178 ); + ASSERT_DOUBLE_EQ(retVm100, 0.00734036, ""); + ASSERT_DOUBLE_EQ(retVm101, 0.246818 , ""); + ASSERT_DOUBLE_EQ(retVm102, 0.200087 , ""); + ASSERT_DOUBLE_EQ(retVm99, 0.0095779083, "" ); + ASSERT_DOUBLE_EQ(retVm900, 0.1150573482, ""); + ASSERT_DOUBLE_EQ(retVm901, 0.289321534, ""); + ASSERT_DOUBLE_EQ(retVm902, 0.01011172486, ""); + ASSERT_DOUBLE_EQ(retVm100, 0.008593194687366486, ""); + ASSERT_DOUBLE_EQ(retVm101, 0.24931678857743744, ""); + ASSERT_DOUBLE_EQ(retVm102, 0.19668269662484533 , ""); + ASSERT_DOUBLE_EQ(retVm99, 0.00701607616202429 , ""); + ASSERT_DOUBLE_EQ(retVm900, 0.12097053045094018 , ""); + ASSERT_DOUBLE_EQ(retVm901, 0.2902593120492995 , ""); + ASSERT_DOUBLE_EQ(retVm902, 0.00237157280699805 , ""); + ASSERT_DOUBLE_EQ(retVm100, 0.015766608829826119, ""); + ASSERT_DOUBLE_EQ(retVm101, 0.24405557875013356 , ""); + ASSERT_DOUBLE_EQ(retVm102, 0.20878261213859917 , ""); + ASSERT_DOUBLE_EQ(retVm99, 0.0081746848675747306, ""); + ASSERT_DOUBLE_EQ(retVm900, 0.12525297735741736 , ""); + ASSERT_DOUBLE_EQ(retVm901, 0.28303358631241327 , ""); + ASSERT_DOUBLE_EQ(retVm902, 0.009637402110858717, ""); */ #if 0 @@ -222,32 +212,28 @@ void testIntFireNetwork( unsigned int runsteps = 5 ) cout << std::setprecision(12) << retVm901 << endl; cout << std::setprecision(12) << retVm902 << endl; #endif - ASSERT_DOUBLE_EQ("", retVm100, 0.0752853031478); - ASSERT_DOUBLE_EQ("", retVm101, 0.226731547886 ); - ASSERT_DOUBLE_EQ("", retVm102, 0.204294350789 ); - ASSERT_DOUBLE_EQ("", retVm99, 0.2814616871 ); - ASSERT_DOUBLE_EQ("", retVm900, 0.194820080944 ); - ASSERT_DOUBLE_EQ("", retVm901, 0.0490452677121); - ASSERT_DOUBLE_EQ("", retVm902, 0.214295483534 ); - + ASSERT_DOUBLE_EQ(retVm100, 0.0752853031478, ""); + ASSERT_DOUBLE_EQ(retVm101, 0.226731547886, ""); + ASSERT_DOUBLE_EQ(retVm102, 0.204294350789, ""); + ASSERT_DOUBLE_EQ(retVm99, 0.2814616871, ""); + ASSERT_DOUBLE_EQ(retVm900, 0.194820080944, ""); + ASSERT_DOUBLE_EQ(retVm901, 0.0490452677121, ""); + ASSERT_DOUBLE_EQ(retVm902, 0.214295483534, ""); } /* cout << "testIntFireNetwork: Vm100 = " << retVm100 << ", " << - retVm101 << ", " << retVm102 << ", " << retVm99 << - ", " << Vm100 << endl; + retVm101 << ", " << retVm102 << ", " << retVm99 << + ", " << Vm100 << endl; cout << "Vm900 = " << retVm900 << ", "<< retVm901 << ", " << - retVm902 << ", " << Vm900 << endl; - */ + retVm902 << ", " << Vm900 << endl; + */ cout << "." << flush; - shell->doDelete( fire ); + shell->doDelete(fire); } - static const double EREST = -0.07; - - #if 0 void testHHGateCreation() { @@ -738,544 +724,540 @@ void testHHChannel() cout << "." << flush; } -#endif //#if 0 +#endif //#if 0 ///////////////////////////////////// // Markov Channel unit tests. //////////////////////////////////// -//Sample current obtained from channel in Chapter 20, Sakmann & Neher, Pg. 603. -//The current is sampled at intervals of 10 usec. -static double sampleCurrent[] = {0.0, // This is to handle the value sent by ChanBase on reinit - 0.0000000e+00, 3.0005743e-26, 1.2004594e-25, 2.7015505e-25, 4.8036751e-25, 7.5071776e-25, - 1.0812402e-24, 1.4719693e-24, 1.9229394e-24, 2.4341850e-24, 3.0057404e-24, 3.6376401e-24, - 4.3299183e-24, 5.0826095e-24, 5.8957481e-24, 6.7693684e-24, 7.7035046e-24, 8.6981913e-24, - 9.7534627e-24, 1.0869353e-23, 1.2045897e-23, 1.3283128e-23, 1.4581082e-23, 1.5939791e-23, - 1.7359292e-23, 1.8839616e-23, 2.0380801e-23, 2.1982878e-23, 2.3645883e-23, 2.5369850e-23, - 2.7154813e-23, 2.9000806e-23, 3.0907863e-23, 3.2876020e-23, 3.4905309e-23, 3.6995766e-23, - 3.9147423e-23, 4.1360317e-23, 4.3634480e-23, 4.5969946e-23, 4.8366751e-23, 5.0824928e-23, - 5.3344511e-23, 5.5925535e-23, 5.8568033e-23, 6.1272040e-23, 6.4037589e-23, 6.6864716e-23, - 6.9753453e-23, 7.2703835e-23, 7.5715897e-23, 7.8789672e-23, 8.1925194e-23, 8.5122497e-23, - 8.8381616e-23, 9.1702584e-23, 9.5085435e-23, 9.8530204e-23, 1.0203692e-22, 1.0560563e-22, - 1.0923636e-22, 1.1292913e-22, 1.1668400e-22, 1.2050099e-22, 1.2438013e-22, 1.2832146e-22, - 1.3232502e-22, 1.3639083e-22, 1.4051894e-22, 1.4470937e-22, 1.4896215e-22, 1.5327733e-22, - 1.5765494e-22, 1.6209501e-22, 1.6659757e-22, 1.7116267e-22, 1.7579032e-22, 1.8048057e-22, - 1.8523345e-22, 1.9004900e-22, 1.9492724e-22, 1.9986821e-22, 2.0487195e-22, 2.0993849e-22, - 2.1506786e-22, 2.2026010e-22, 2.2551524e-22, 2.3083331e-22, 2.3621436e-22, 2.4165840e-22, - 2.4716548e-22, 2.5273563e-22, 2.5836888e-22, 2.6406527e-22, 2.6982483e-22, 2.7564760e-22, - 2.8153360e-22, 2.8748287e-22, 2.9349545e-22, 2.9957137e-22, 3.0571067e-22 - }; +// Sample current obtained from channel in Chapter 20, Sakmann & Neher, Pg. 603. +// The current is sampled at intervals of 10 usec. +static double sampleCurrent[] = { + 0.0, // This is to handle the value sent by ChanBase on reinit + 0.0000000e+00, 3.0005743e-26, 1.2004594e-25, 2.7015505e-25, 4.8036751e-25, + 7.5071776e-25, 1.0812402e-24, 1.4719693e-24, 1.9229394e-24, 2.4341850e-24, + 3.0057404e-24, 3.6376401e-24, 4.3299183e-24, 5.0826095e-24, 5.8957481e-24, + 6.7693684e-24, 7.7035046e-24, 8.6981913e-24, 9.7534627e-24, 1.0869353e-23, + 1.2045897e-23, 1.3283128e-23, 1.4581082e-23, 1.5939791e-23, 1.7359292e-23, + 1.8839616e-23, 2.0380801e-23, 2.1982878e-23, 2.3645883e-23, 2.5369850e-23, + 2.7154813e-23, 2.9000806e-23, 3.0907863e-23, 3.2876020e-23, 3.4905309e-23, + 3.6995766e-23, 3.9147423e-23, 4.1360317e-23, 4.3634480e-23, 4.5969946e-23, + 4.8366751e-23, 5.0824928e-23, 5.3344511e-23, 5.5925535e-23, 5.8568033e-23, + 6.1272040e-23, 6.4037589e-23, 6.6864716e-23, 6.9753453e-23, 7.2703835e-23, + 7.5715897e-23, 7.8789672e-23, 8.1925194e-23, 8.5122497e-23, 8.8381616e-23, + 9.1702584e-23, 9.5085435e-23, 9.8530204e-23, 1.0203692e-22, 1.0560563e-22, + 1.0923636e-22, 1.1292913e-22, 1.1668400e-22, 1.2050099e-22, 1.2438013e-22, + 1.2832146e-22, 1.3232502e-22, 1.3639083e-22, 1.4051894e-22, 1.4470937e-22, + 1.4896215e-22, 1.5327733e-22, 1.5765494e-22, 1.6209501e-22, 1.6659757e-22, + 1.7116267e-22, 1.7579032e-22, 1.8048057e-22, 1.8523345e-22, 1.9004900e-22, + 1.9492724e-22, 1.9986821e-22, 2.0487195e-22, 2.0993849e-22, 2.1506786e-22, + 2.2026010e-22, 2.2551524e-22, 2.3083331e-22, 2.3621436e-22, 2.4165840e-22, + 2.4716548e-22, 2.5273563e-22, 2.5836888e-22, 2.6406527e-22, 2.6982483e-22, + 2.7564760e-22, 2.8153360e-22, 2.8748287e-22, 2.9349545e-22, 2.9957137e-22, + 3.0571067e-22}; void testMarkovOdeSolver() { - Shell* shell = reinterpret_cast< Shell* >( ObjId( Id(), 0 ).data() ); + Shell* shell = reinterpret_cast(ObjId(Id(), 0).data()); unsigned size = 1; - Id nid = shell->doCreate( "Neutral", Id(), "n", size ); - Id comptId = shell->doCreate( "Compartment", nid, "compt", size ); - Id rateTabId = shell->doCreate( "MarkovRateTable", comptId, "rateTab", size ); - Id mChanId = shell->doCreate( "MarkovChannel", comptId, "mChan", size ); - Id gslSolverId = shell->doCreate( "MarkovOdeSolver", comptId, "gslSolver", size ); + Id nid = shell->doCreate("Neutral", Id(), "n", size); + Id comptId = shell->doCreate("Compartment", nid, "compt", size); + Id rateTabId = shell->doCreate("MarkovRateTable", comptId, "rateTab", size); + Id mChanId = shell->doCreate("MarkovChannel", comptId, "mChan", size); + Id gslSolverId = + shell->doCreate("MarkovOdeSolver", comptId, "gslSolver", size); - Id tabId = shell->doCreate( "Table", nid, "tab", size ); + Id tabId = shell->doCreate("Table", nid, "tab", size); - ObjId mid = shell->doAddMsg( "Single", ObjId( comptId ), "channel", - ObjId( mChanId ), "channel" ); - assert( !mid.bad() ); + ObjId mid = shell->doAddMsg("Single", ObjId(comptId), "channel", + ObjId(mChanId), "channel"); + assert(!mid.bad()); - mid = shell->doAddMsg( "Single", ObjId( comptId ), "channel", - ObjId( rateTabId ), "channel" ); - assert( !mid.bad() ); - mid = shell->doAddMsg( "Single", ObjId( gslSolverId ), "stateOut", - ObjId( mChanId ), "handleState" ); - assert( !mid.bad() ); + mid = shell->doAddMsg("Single", ObjId(comptId), "channel", ObjId(rateTabId), + "channel"); + assert(!mid.bad()); + mid = shell->doAddMsg("Single", ObjId(gslSolverId), "stateOut", + ObjId(mChanId), "handleState"); + assert(!mid.bad()); - mid = shell->doAddMsg("Single", ObjId( rateTabId ), "instratesOut", - ObjId( gslSolverId ), "handleQ" ); + mid = shell->doAddMsg("Single", ObjId(rateTabId), "instratesOut", + ObjId(gslSolverId), "handleQ"); - mid = shell->doAddMsg( "Single", ObjId( tabId, 0 ), "requestOut", - ObjId( mChanId, 0 ), "getIk" ); - assert( !mid.bad() ); + mid = shell->doAddMsg("Single", ObjId(tabId, 0), "requestOut", + ObjId(mChanId, 0), "getIk"); + assert(!mid.bad()); ////////////////////////////////////////////////////////////////////// // set up compartment properties ////////////////////////////////////////////////////////////////////// - Field< double >::set( comptId, "Cm", 0.007854e-6 ); - Field< double >::set( comptId, "Ra", 7639.44e3 ); // does it matter? - Field< double >::set( comptId, "Rm", 424.4e3 ); - Field< double >::set( comptId, "Em", -0.1 ); - Field< double >::set( comptId, "inject", 0 ); - Field< double >::set( comptId, "initVm", -0.1 ); + Field::set(comptId, "Cm", 0.007854e-6); + Field::set(comptId, "Ra", 7639.44e3); // does it matter? + Field::set(comptId, "Rm", 424.4e3); + Field::set(comptId, "Em", -0.1); + Field::set(comptId, "inject", 0); + Field::set(comptId, "initVm", -0.1); ///////////////////////////////// // - //Setup of Markov Channel. - //This is a simple 5-state channel model taken from Chapter 20, "Single-Channel - //Recording", Sakmann & Neher. - //All the transition rates are constant. + // Setup of Markov Channel. + // This is a simple 5-state channel model taken from Chapter 20, + // "Single-Channel Recording", Sakmann & Neher. All the transition rates + // are constant. // //////////////////////////////// - //Setting number of states, number of open states. - Field< unsigned int >::set( mChanId, "numStates", 5 ); - Field< unsigned int >::set( mChanId, "numOpenStates", 2 ); - - //Setting initial state of system. - vector< double > initState; - - initState.push_back( 0.0 ); - initState.push_back( 0.0 ); - initState.push_back( 0.0 ); - initState.push_back( 0.0 ); - initState.push_back( 1.0 ); - - Field< vector< double > >::set( mChanId, "initialState", initState ); - - vector< string > stateLabels; - - stateLabels.push_back( "O1" ); - stateLabels.push_back( "O2" ); - stateLabels.push_back( "C1" ); - stateLabels.push_back( "C2" ); - stateLabels.push_back( "C3" ); - - Field< vector< string > >::set( mChanId, "labels", stateLabels ); - - vector< double > gBars; - - gBars.push_back( 40e-12 ); - gBars.push_back( 50e-12 ); - - Field< vector< double > >::set( mChanId, "gbar", gBars ); - - //Setting up rate tables. - SetGet1< unsigned int >::set( rateTabId, "init", 5 ); - - //Filling in values into one parameter rate table. Note that all rates here - //are constant. - SetGet3< unsigned int, unsigned int, double >:: - set( rateTabId, "setconst", 1, 2, 0.05 ); - SetGet3< unsigned int, unsigned int, double >:: - set( rateTabId, "setconst", 1, 4, 3 ); - SetGet3< unsigned int, unsigned int, double >:: - set( rateTabId, "setconst", 2, 1, 0.00066667 ); - SetGet3< unsigned int, unsigned int, double >:: - set( rateTabId, "setconst", 2, 3, 0.5 ); - SetGet3< unsigned int, unsigned int, double >:: - set( rateTabId, "setconst", 3, 2, 15 ); - SetGet3< unsigned int, unsigned int, double >:: - set( rateTabId, "setconst", 3, 4, 4 ); - SetGet3< unsigned int, unsigned int, double >:: - set( rateTabId, "setconst", 4, 1, 0.015 ); - SetGet3< unsigned int, unsigned int, double >:: - set( rateTabId, "setconst", 4, 3, 0.05 ); - SetGet3< unsigned int, unsigned int, double >:: - set( rateTabId, "setconst", 4, 5, 2.0 ); - SetGet3< unsigned int, unsigned int, double >:: - set( rateTabId, "setconst", 5, 4, 0.01 ); - - //Setting initial state of the solver. Once this is set, the solver object - //will send out messages containing the updated state to the channel object. - SetGet1< vector< double > >::set( gslSolverId, "init", initState ); - - shell->doSetClock( 0, 1.0e-5 ); - shell->doSetClock( 1, 1.0e-5 ); - shell->doSetClock( 2, 1.0e-5 ); - shell->doSetClock( 3, 1.0e-5 ); - shell->doSetClock( 4, 1.0e-5 ); + // Setting number of states, number of open states. + Field::set(mChanId, "numStates", 5); + Field::set(mChanId, "numOpenStates", 2); + + // Setting initial state of system. + vector initState; + + initState.push_back(0.0); + initState.push_back(0.0); + initState.push_back(0.0); + initState.push_back(0.0); + initState.push_back(1.0); + + Field>::set(mChanId, "initialState", initState); + + vector stateLabels; + + stateLabels.push_back("O1"); + stateLabels.push_back("O2"); + stateLabels.push_back("C1"); + stateLabels.push_back("C2"); + stateLabels.push_back("C3"); + + Field>::set(mChanId, "labels", stateLabels); + + vector gBars; + + gBars.push_back(40e-12); + gBars.push_back(50e-12); + + Field>::set(mChanId, "gbar", gBars); + + // Setting up rate tables. + SetGet1::set(rateTabId, "init", 5); + + // Filling in values into one parameter rate table. Note that all rates here + // are constant. + SetGet3::set(rateTabId, "setconst", 1, + 2, 0.05); + SetGet3::set(rateTabId, "setconst", 1, + 4, 3); + SetGet3::set(rateTabId, "setconst", 2, + 1, 0.00066667); + SetGet3::set(rateTabId, "setconst", 2, + 3, 0.5); + SetGet3::set(rateTabId, "setconst", 3, + 2, 15); + SetGet3::set(rateTabId, "setconst", 3, + 4, 4); + SetGet3::set(rateTabId, "setconst", 4, + 1, 0.015); + SetGet3::set(rateTabId, "setconst", 4, + 3, 0.05); + SetGet3::set(rateTabId, "setconst", 4, + 5, 2.0); + SetGet3::set(rateTabId, "setconst", 5, + 4, 0.01); + + // Setting initial state of the solver. Once this is set, the solver object + // will send out messages containing the updated state to the channel + // object. + SetGet1>::set(gslSolverId, "init", initState); + + shell->doSetClock(0, 1.0e-5); + shell->doSetClock(1, 1.0e-5); + shell->doSetClock(2, 1.0e-5); + shell->doSetClock(3, 1.0e-5); + shell->doSetClock(4, 1.0e-5); + + // Voltage is clamped to -100 mV in the example. Hence, we skip running the + // process function. + shell->doUseClock("/n/compt", "init", 0); + shell->doUseClock("/n/compt", "process", 1); + shell->doUseClock("/n/compt/rateTab", "process", 1); + shell->doUseClock("/n/compt/gslSolver", "process", 1); + shell->doUseClock("/n/compt/mChan,/n/tab", "process", 2); - //Voltage is clamped to -100 mV in the example. Hence, we skip running the - //process function. - shell->doUseClock( "/n/compt", "init", 0 ); - shell->doUseClock( "/n/compt", "process", 1 ); - shell->doUseClock( "/n/compt/rateTab", "process", 1 ); - shell->doUseClock( "/n/compt/gslSolver", "process", 1 ); - shell->doUseClock( "/n/compt/mChan,/n/tab", "process", 2 ); - - shell->doReinit( ); - shell->doReinit( ); - shell->doStart( 1.0e-3 ); + shell->doReinit(); + shell->doReinit(); + shell->doStart(1.0e-3); - vector< double > vec = Field< vector< double > >::get( tabId, "vector" ); + vector vec = Field>::get(tabId, "vector"); - for ( unsigned i = 0; i < 101; ++i ) - { - if (!doubleEq( sampleCurrent[i] * 1e25, vec[i] * 1e25 )) - { - cout << "testMarkovOdeSolver: sample=" << sampleCurrent[i]*1e25 << " calculated=" << vec[i]*1e25 << endl; + for(unsigned i = 0; i < 101; ++i) { + if(!doubleEq(sampleCurrent[i] * 1e25, vec[i] * 1e25)) { + cout << "testMarkovOdeSolver: sample=" << sampleCurrent[i] * 1e25 + << " calculated=" << vec[i] * 1e25 << endl; } - ASSERT_DOUBLE_EQ("", sampleCurrent[i] * 1e25, vec[i] * 1e25 ); + ASSERT_DOUBLE_EQ(sampleCurrent[i] * 1e25, vec[i] * 1e25, ""); // cout << sampleCurrent[i] << " " << vec[i] << endl; } - //Currents involved here are incredibly small. Scaling them up is necessary - //for the doubleEq function to do its job. + // Currents involved here are incredibly small. Scaling them up is necessary + // for the doubleEq function to do its job. - shell->doDelete( nid ); + shell->doDelete(nid); cout << "." << flush; } //////////////// -//The testMarkovOdeSolver() function includes the MarkovChannel object, but -//is a rather trivial case, in that the rates are all constant. -//This test simultaneously tests the MarkovChannel, MarkovOdeSolver, -//MarkovSolverBase and MarkovSolver classes. -//This test involves simulating the 4-state NMDA channel model specified -//in the following paper : +// The testMarkovOdeSolver() function includes the MarkovChannel object, but +// is a rather trivial case, in that the rates are all constant. +// This test simultaneously tests the MarkovChannel, MarkovOdeSolver, +// MarkovSolverBase and MarkovSolver classes. +// This test involves simulating the 4-state NMDA channel model specified +// in the following paper : //"Voltage Dependence of NMDA-Activated Macroscopic Conductances Predicted -//by Single-Channel Kinetics", Craig E. Jahr and Charles F. Stevens, The Journal -//of Neuroscience, 1990, 10(9), pp. 3178-3182. -//It is expected that the MarkovOdeSolver and the MarkovSolver objects will -//give the same answer. +// by Single-Channel Kinetics", Craig E. Jahr and Charles F. Stevens, The +// Journal of Neuroscience, 1990, 10(9), pp. 3178-3182. It is expected that +// the MarkovOdeSolver and the MarkovSolver objects will give the same answer. // -//Note that this is different from the NMDAChan test which involves synapses. +// Note that this is different from the NMDAChan test which involves synapses. /////////////// void testMarkovChannel() { - Shell* shell = reinterpret_cast< Shell* >( ObjId( Id(), 0 ).data() ); + Shell* shell = reinterpret_cast(ObjId(Id(), 0).data()); unsigned size = 1; - Id nid = shell->doCreate( "Neutral", Id(), "n", size ); + Id nid = shell->doCreate("Neutral", Id(), "n", size); - Id gslComptId = shell->doCreate( "Compartment", nid, "gslCompt", size ); - Id exptlComptId = shell->doCreate( "Compartment", nid, - "exptlCompt", size ); + Id gslComptId = shell->doCreate("Compartment", nid, "gslCompt", size); + Id exptlComptId = shell->doCreate("Compartment", nid, "exptlCompt", size); - Id gslRateTableId = shell->doCreate( "MarkovRateTable", gslComptId, - "gslRateTable", size ); - Id exptlRateTableId = shell->doCreate( "MarkovRateTable", exptlComptId, - "exptlRateTable", size ); + Id gslRateTableId = + shell->doCreate("MarkovRateTable", gslComptId, "gslRateTable", size); + Id exptlRateTableId = shell->doCreate("MarkovRateTable", exptlComptId, + "exptlRateTable", size); - Id mChanOdeId = shell->doCreate( "MarkovChannel", gslComptId, - "mChanOde", size ); - Id mChanExptlId = shell->doCreate( "MarkovChannel", exptlComptId, - "mChanExptl", size ); + Id mChanOdeId = + shell->doCreate("MarkovChannel", gslComptId, "mChanOde", size); + Id mChanExptlId = + shell->doCreate("MarkovChannel", exptlComptId, "mChanExptl", size); - Id gslSolverId = shell->doCreate( "MarkovOdeSolver", gslComptId, - "gslSolver", size ); - Id exptlSolverId = shell->doCreate( "MarkovSolver", exptlComptId, - "exptlSolver", size ); + Id gslSolverId = + shell->doCreate("MarkovOdeSolver", gslComptId, "gslSolver", size); + Id exptlSolverId = + shell->doCreate("MarkovSolver", exptlComptId, "exptlSolver", size); - Id gslTableId = shell->doCreate( "Table", nid, "gslTable", size ); - Id exptlTableId = shell->doCreate( "Table", nid, "exptlTable", size ); + Id gslTableId = shell->doCreate("Table", nid, "gslTable", size); + Id exptlTableId = shell->doCreate("Table", nid, "exptlTable", size); - Id int2dTableId = shell->doCreate( "Interpol2D", nid, "int2dTable", size ); - Id vecTableId = shell->doCreate( "VectorTable", nid, "vecTable", size ); + Id int2dTableId = shell->doCreate("Interpol2D", nid, "int2dTable", size); + Id vecTableId = shell->doCreate("VectorTable", nid, "vecTable", size); - vector< double > table1d; - vector< vector< double > > table2d; + vector table1d; + vector> table2d; /////////////////////////// - //Setting up the messaging. + // Setting up the messaging. ////////////////////////// - //Connecting Compartment and MarkovChannel objects. - //Compartment sends Vm to MarkovChannel object. The MarkovChannel, - //via its ChanBase base class, sends back the conductance and current through - //it. - ObjId mid = shell->doAddMsg( "Single", ObjId( gslComptId ), "channel", - ObjId( mChanOdeId ), "channel" ); - assert( !mid.bad() ); + // Connecting Compartment and MarkovChannel objects. + // Compartment sends Vm to MarkovChannel object. The MarkovChannel, + // via its ChanBase base class, sends back the conductance and current + // through it. + ObjId mid = shell->doAddMsg("Single", ObjId(gslComptId), "channel", + ObjId(mChanOdeId), "channel"); + assert(!mid.bad()); - mid = shell->doAddMsg( "Single", ObjId( exptlComptId ), "channel", - ObjId( mChanExptlId ), "channel" ); - assert( !mid.bad() ); + mid = shell->doAddMsg("Single", ObjId(exptlComptId), "channel", + ObjId(mChanExptlId), "channel"); + assert(!mid.bad()); //////// - //Connecting up the MarkovOdeSolver. + // Connecting up the MarkovOdeSolver. /////// - //Connecting Compartment and MarkovRateTable. - //The MarkovRateTable's job is to send out the instantaneous rate matrix, - //Q, to the solver object(s). - //In order to do so, the MarkovRateTable object needs information on - //Vm and ligand concentration to look up the rate from the table provided - //by the user. Hence, the need of the connection to the Compartment object. - //However, unlike a channel object, the MarkovRateTable object does not - //return anything to the Compartment directly, and communicates only with the - //solvers. - mid = shell->doAddMsg( "Single", ObjId( gslComptId ), "channel", - ObjId( gslRateTableId ), "channel" ); - assert( !mid.bad() ); - - //Connecting the MarkovRateTable with the MarkovOdeSolver object. - //As mentioned earlier, the MarkovRateTable object sends out information - //about Q to the MarkovOdeSolver. The MarkovOdeSolver then churns out - //the state of the system for the next time step. - mid = shell->doAddMsg("Single", ObjId( gslRateTableId ), "instratesOut", - ObjId( gslSolverId ), "handleQ" ); - - //Connecting MarkovOdeSolver with MarkovChannel. - //The MarkovOdeSolver object, upon computing the state of the channel, - //sends this information to the MarkovChannel object. The MarkovChannel - //object will compute the expected conductance of the channel and send - //this information to the compartment. - mid = shell->doAddMsg( "Single", ObjId( gslSolverId ), "stateOut", - ObjId( mChanOdeId ), "handleState" ); - assert( !mid.bad() ); + // Connecting Compartment and MarkovRateTable. + // The MarkovRateTable's job is to send out the instantaneous rate matrix, + // Q, to the solver object(s). + // In order to do so, the MarkovRateTable object needs information on + // Vm and ligand concentration to look up the rate from the table provided + // by the user. Hence, the need of the connection to the Compartment object. + // However, unlike a channel object, the MarkovRateTable object does not + // return anything to the Compartment directly, and communicates only with + // the solvers. + mid = shell->doAddMsg("Single", ObjId(gslComptId), "channel", + ObjId(gslRateTableId), "channel"); + assert(!mid.bad()); + + // Connecting the MarkovRateTable with the MarkovOdeSolver object. + // As mentioned earlier, the MarkovRateTable object sends out information + // about Q to the MarkovOdeSolver. The MarkovOdeSolver then churns out + // the state of the system for the next time step. + mid = shell->doAddMsg("Single", ObjId(gslRateTableId), "instratesOut", + ObjId(gslSolverId), "handleQ"); + + // Connecting MarkovOdeSolver with MarkovChannel. + // The MarkovOdeSolver object, upon computing the state of the channel, + // sends this information to the MarkovChannel object. The MarkovChannel + // object will compute the expected conductance of the channel and send + // this information to the compartment. + mid = shell->doAddMsg("Single", ObjId(gslSolverId), "stateOut", + ObjId(mChanOdeId), "handleState"); + assert(!mid.bad()); ////////// - //Connecting up the MarkovSolver class. + // Connecting up the MarkovSolver class. ///////// - //Connecting the MarkovSolver and Compartment. - //The MarkovSolver derives from the MarkovSolverBase class. - //The base class need Vm and ligand concentration information to - //perform lookup and interpolation on the matrix exponential lookup - //tables. - mid = shell->doAddMsg( "Single", ObjId( exptlComptId ), "channel", - ObjId( exptlSolverId ), "channel" ); - assert( !mid.bad() ); + // Connecting the MarkovSolver and Compartment. + // The MarkovSolver derives from the MarkovSolverBase class. + // The base class need Vm and ligand concentration information to + // perform lookup and interpolation on the matrix exponential lookup + // tables. + mid = shell->doAddMsg("Single", ObjId(exptlComptId), "channel", + ObjId(exptlSolverId), "channel"); + assert(!mid.bad()); - mid = shell->doAddMsg( "Single", ObjId( exptlSolverId ), "stateOut", - ObjId( mChanExptlId ), "handleState" ); - assert( !mid.bad() ); + mid = shell->doAddMsg("Single", ObjId(exptlSolverId), "stateOut", + ObjId(mChanExptlId), "handleState"); + assert(!mid.bad()); ///////// - //Connecting up the Table objects to cross-check values. + // Connecting up the Table objects to cross-check values. //////// - //Get the current values from the GSL solver based channel. - mid = shell->doAddMsg( "Single", ObjId( gslTableId ), "requestOut", - ObjId( mChanOdeId ), "getIk" ); - assert( !mid.bad() ); + // Get the current values from the GSL solver based channel. + mid = shell->doAddMsg("Single", ObjId(gslTableId), "requestOut", + ObjId(mChanOdeId), "getIk"); + assert(!mid.bad()); - //Get the current values from the matrix exponential solver based channel. - mid = shell->doAddMsg( "Single", ObjId( exptlTableId ), "requestOut", - ObjId( mChanExptlId ), "getIk" ); - assert( !mid.bad() ); + // Get the current values from the matrix exponential solver based channel. + mid = shell->doAddMsg("Single", ObjId(exptlTableId), "requestOut", + ObjId(mChanExptlId), "getIk"); + assert(!mid.bad()); //////////////////// - //Compartment properties. Identical to ones used in testHHChannel() - //barring a few modifications. + // Compartment properties. Identical to ones used in testHHChannel() + // barring a few modifications. /////////////////// - Field< double >::set( gslComptId, "Cm", 0.007854e-6 ); - Field< double >::set( gslComptId, "Ra", 7639.44e3 ); // does it matter? - Field< double >::set( gslComptId, "Rm", 424.4e3 ); - Field< double >::set( gslComptId, "Em", EREST + 0.1 ); - Field< double >::set( gslComptId, "inject", 0 ); - Field< double >::set( gslComptId, "initVm", EREST ); + Field::set(gslComptId, "Cm", 0.007854e-6); + Field::set(gslComptId, "Ra", 7639.44e3); // does it matter? + Field::set(gslComptId, "Rm", 424.4e3); + Field::set(gslComptId, "Em", EREST + 0.1); + Field::set(gslComptId, "inject", 0); + Field::set(gslComptId, "initVm", EREST); - Field< double >::set( exptlComptId, "Cm", 0.007854e-6 ); - Field< double >::set( exptlComptId, "Ra", 7639.44e3 ); // does it matter? - Field< double >::set( exptlComptId, "Rm", 424.4e3 ); - Field< double >::set( exptlComptId, "Em", EREST + 0.1 ); - Field< double >::set( exptlComptId, "inject", 0 ); - Field< double >::set( exptlComptId, "initVm", EREST ); + Field::set(exptlComptId, "Cm", 0.007854e-6); + Field::set(exptlComptId, "Ra", 7639.44e3); // does it matter? + Field::set(exptlComptId, "Rm", 424.4e3); + Field::set(exptlComptId, "Em", EREST + 0.1); + Field::set(exptlComptId, "inject", 0); + Field::set(exptlComptId, "initVm", EREST); ////////////////// - //Setup of rate tables. - //Refer paper mentioned at the header of the unit test for more - //details. + // Setup of rate tables. + // Refer paper mentioned at the header of the unit test for more + // details. ///////////////// - //Number of states and open states. - Field< unsigned int >::set( mChanOdeId, "numStates", 4 ); - Field< unsigned int >::set( mChanExptlId, "numStates", 4 ); + // Number of states and open states. + Field::set(mChanOdeId, "numStates", 4); + Field::set(mChanExptlId, "numStates", 4); - Field< unsigned int >::set( mChanOdeId, "numOpenStates", 1 ); - Field< unsigned int >::set( mChanExptlId, "numOpenStates", 1 ); + Field::set(mChanOdeId, "numOpenStates", 1); + Field::set(mChanExptlId, "numOpenStates", 1); - vector< string > stateLabels; + vector stateLabels; - //In the MarkovChannel class, the opening states are listed first. - //This is in line with the convention followed in Chapter 20, Sakmann & - //Neher. - stateLabels.push_back( "O" ); //State 1. - stateLabels.push_back( "B1" ); //State 2. - stateLabels.push_back( "B2" ); //State 3. - stateLabels.push_back( "C" ); //State 4. + // In the MarkovChannel class, the opening states are listed first. + // This is in line with the convention followed in Chapter 20, Sakmann & + // Neher. + stateLabels.push_back("O"); // State 1. + stateLabels.push_back("B1"); // State 2. + stateLabels.push_back("B2"); // State 3. + stateLabels.push_back("C"); // State 4. - Field< vector< string > >::set( mChanOdeId, "labels", stateLabels ); - Field< vector< string > >::set( mChanExptlId, "labels", stateLabels ); + Field>::set(mChanOdeId, "labels", stateLabels); + Field>::set(mChanExptlId, "labels", stateLabels); - //Setting up conductance value for single open state. Value chosen - //is quite arbitrary. - vector< double > gBar; + // Setting up conductance value for single open state. Value chosen + // is quite arbitrary. + vector gBar; - gBar.push_back( 5.431553e-9 ); + gBar.push_back(5.431553e-9); - Field< vector< double > >::set( mChanOdeId, "gbar", gBar ); - Field< vector< double > >::set( mChanExptlId, "gbar", gBar ); + Field>::set(mChanOdeId, "gbar", gBar); + Field>::set(mChanExptlId, "gbar", gBar); - //Initial state of the system. This is really an arbitrary choice. - vector< double > initState; + // Initial state of the system. This is really an arbitrary choice. + vector initState; - initState.push_back( 0.00 ); - initState.push_back( 0.20 ); - initState.push_back( 0.80 ); - initState.push_back( 0.00 ); + initState.push_back(0.00); + initState.push_back(0.20); + initState.push_back(0.80); + initState.push_back(0.00); - Field< vector< double > >::set( mChanOdeId, "initialState", initState ); - Field< vector< double > >::set( mChanExptlId, "initialState", initState ); + Field>::set(mChanOdeId, "initialState", initState); + Field>::set(mChanExptlId, "initialState", initState); - //This initializes the GSL solver object. - SetGet1< vector< double > >::set( gslSolverId, "init", initState ); + // This initializes the GSL solver object. + SetGet1>::set(gslSolverId, "init", initState); - //Initializing MarkovRateTable object. + // Initializing MarkovRateTable object. double v; double conc; - SetGet1< unsigned int >::set( gslRateTableId, "init", 4 ); - SetGet1< unsigned int >::set( exptlRateTableId, "init", 4 ); + SetGet1::set(gslRateTableId, "init", 4); + SetGet1::set(exptlRateTableId, "init", 4); - //Setting up lookup tables for the different rates. - //Please note that the rates should be in sec^(-1). + // Setting up lookup tables for the different rates. + // Please note that the rates should be in sec^(-1). - //Transition from "O" to "B1" i.e. r12 or a1. - Field< double >::set( vecTableId, "xmin", -0.10 ); - Field< double >::set( vecTableId, "xmax", 0.10 ); - Field< unsigned int >::set( vecTableId, "xdivs", 200 ); + // Transition from "O" to "B1" i.e. r12 or a1. + Field::set(vecTableId, "xmin", -0.10); + Field::set(vecTableId, "xmax", 0.10); + Field::set(vecTableId, "xdivs", 200); - v = Field< double >::get( vecTableId, "xmin" ); - for ( unsigned int i = 0; i < 201; ++i ) - { - table1d.push_back( 1e3 * exp( -16 * v - 2.91 ) ); + v = Field::get(vecTableId, "xmin"); + for(unsigned int i = 0; i < 201; ++i) { + table1d.push_back(1e3 * exp(-16 * v - 2.91)); v += 0.001; } - Field< vector< double > >::set( vecTableId, "table", table1d ); + Field>::set(vecTableId, "table", table1d); - SetGet4< unsigned int, unsigned int, Id, unsigned int >::set( - gslRateTableId, "set1d", 1, 2, vecTableId, 0 ); - SetGet4< unsigned int, unsigned int, Id, unsigned int >::set( - exptlRateTableId, "set1d", 1, 2, vecTableId, 0 ); + SetGet4::set( + gslRateTableId, "set1d", 1, 2, vecTableId, 0); + SetGet4::set( + exptlRateTableId, "set1d", 1, 2, vecTableId, 0); - table1d.erase( table1d.begin(), table1d.end() ); + table1d.erase(table1d.begin(), table1d.end()); - //Transition from "B1" back to O i.e. r21 or b1 - v = Field< double >::get( vecTableId, "xmin" ); - for ( unsigned int i = 0; i < 201; ++i ) - { - table1d.push_back( 1e3 * exp( 9 * v + 1.22 ) ); + // Transition from "B1" back to O i.e. r21 or b1 + v = Field::get(vecTableId, "xmin"); + for(unsigned int i = 0; i < 201; ++i) { + table1d.push_back(1e3 * exp(9 * v + 1.22)); v += 0.001; } - Field< vector< double > >::set( vecTableId, "table", table1d ); - SetGet4< unsigned int, unsigned int, Id, unsigned int >::set( - gslRateTableId, "set1d", 2, 1, vecTableId, 0 ); - SetGet4< unsigned int, unsigned int, Id, unsigned int >::set( - exptlRateTableId, "set1d", 2, 1, vecTableId, 0 ); - - table1d.erase( table1d.begin(), table1d.end() ); - - //Transition from "O" to "B2" i.e. r13 or a2 - //This is actually a 2D rate. But, there is no change in Mg2+ concentration - //that occurs. Hence, I create a 2D lookup table anyway but I manually - //set the concentration on the rate table object anyway. - - Field< double >::set( gslRateTableId, "ligandConc", 24e-6 ); - Field< double >::set( exptlRateTableId, "ligandConc", 24e-6 ); - - Field< double >::set( int2dTableId, "xmin", -0.10 ); - Field< double >::set( int2dTableId, "xmax", 0.10 ); - Field< double >::set( int2dTableId, "ymin", 0 ); - Field< double >::set( int2dTableId, "ymax", 30e-6 ); - Field< unsigned int >::set( int2dTableId, "xdivs", 200 ); - Field< unsigned int >::set( int2dTableId, "ydivs", 30 ); - - table2d.resize( 201 ); - v = Field< double >::get( int2dTableId, "xmin" ); - for ( unsigned int i = 0; i < 201; ++i ) - { - conc = Field< double >::get( int2dTableId, "ymin" ); - for ( unsigned int j = 0; j < 31; ++j ) - { - table2d[i].push_back( 1e3 * conc * exp( -45 * v - 6.97 ) ); + Field>::set(vecTableId, "table", table1d); + SetGet4::set( + gslRateTableId, "set1d", 2, 1, vecTableId, 0); + SetGet4::set( + exptlRateTableId, "set1d", 2, 1, vecTableId, 0); + + table1d.erase(table1d.begin(), table1d.end()); + + // Transition from "O" to "B2" i.e. r13 or a2 + // This is actually a 2D rate. But, there is no change in Mg2+ concentration + // that occurs. Hence, I create a 2D lookup table anyway but I manually + // set the concentration on the rate table object anyway. + + Field::set(gslRateTableId, "ligandConc", 24e-6); + Field::set(exptlRateTableId, "ligandConc", 24e-6); + + Field::set(int2dTableId, "xmin", -0.10); + Field::set(int2dTableId, "xmax", 0.10); + Field::set(int2dTableId, "ymin", 0); + Field::set(int2dTableId, "ymax", 30e-6); + Field::set(int2dTableId, "xdivs", 200); + Field::set(int2dTableId, "ydivs", 30); + + table2d.resize(201); + v = Field::get(int2dTableId, "xmin"); + for(unsigned int i = 0; i < 201; ++i) { + conc = Field::get(int2dTableId, "ymin"); + for(unsigned int j = 0; j < 31; ++j) { + table2d[i].push_back(1e3 * conc * exp(-45 * v - 6.97)); conc += 1e-6; } v += 1e-3; } - Field< vector< vector< double > > >::set( int2dTableId, "tableVector2D", - table2d ); + Field>>::set(int2dTableId, "tableVector2D", table2d); - SetGet3< unsigned int, unsigned int, Id >::set( gslRateTableId, - "set2d", 1, 3, int2dTableId ); - SetGet3< unsigned int, unsigned int, Id >::set( exptlRateTableId, - "set2d", 1, 3, int2dTableId ); + SetGet3::set(gslRateTableId, "set2d", 1, 3, + int2dTableId); + SetGet3::set(exptlRateTableId, "set2d", 1, + 3, int2dTableId); - //There is only one 2D rate, so no point manually erasing the elements. + // There is only one 2D rate, so no point manually erasing the elements. - //Transition from "B2" to "O" i.e. r31 or b2 + // Transition from "B2" to "O" i.e. r31 or b2 v = -0.10; - for ( unsigned int i = 0; i < 201; ++i ) - { - table1d.push_back( 1e3 * exp( 17 * v + 0.96 ) ); + for(unsigned int i = 0; i < 201; ++i) { + table1d.push_back(1e3 * exp(17 * v + 0.96)); v += 0.001; } - Field< vector< double > >::set( vecTableId, "table", table1d ); - SetGet4< unsigned int, unsigned int, Id, unsigned int >::set( - gslRateTableId, "set1d", 3, 1, vecTableId, 0 ); - SetGet4< unsigned int, unsigned int, Id, unsigned int >::set( - exptlRateTableId, "set1d", 3, 1, vecTableId, 0 ); - - table1d.erase( table1d.begin(), table1d.end() ); - - //Transition from "O" to "C" i.e. r14 - SetGet3< unsigned int, unsigned int, double >::set( gslRateTableId, - "setconst", 1, 4, 1e3 * exp( -2.847 ) ); - SetGet3< unsigned int, unsigned int, double >::set( exptlRateTableId, - "setconst", 1, 4, 1e3 * exp( -2.847 ) ); - - //Transition from "B1" to "C" i.e. r24 - SetGet3< unsigned int, unsigned int, double >::set( gslRateTableId, - "setconst", 2, 4, 1e3 * exp( -0.693 ) ); - SetGet3< unsigned int, unsigned int, double >::set( exptlRateTableId, - "setconst", 2, 4, 1e3 * exp( -0.693 ) ); - - //Transition from "B2" to "C" i.e. r34 - SetGet3< unsigned int, unsigned int, double >::set( gslRateTableId, - "setconst", 3, 4, 1e3* exp( -3.101 ) ); - SetGet3< unsigned int, unsigned int, double >::set( exptlRateTableId, - "setconst", 3, 4, 1e3* exp( -3.101 ) ); - - //Once the rate tables have been set up, we can initialize the - //tables in the MarkovSolver class. - SetGet2< Id, double >::set( exptlSolverId, "init", exptlRateTableId, 1.0e-3 ); - SetGet1< double >::set( exptlSolverId, "ligandConc", 24e-6 ); - Field< vector< double > >::set( exptlSolverId, "initialState", - initState ); - - Field< double >::set( gslSolverId, "relativeAccuracy", 1e-24 ); - Field< double >::set( gslSolverId, "absoluteAccuracy", 1e-24 ); - Field< double >::set( gslSolverId, "internalDt", 1e-24 ); - - shell->doSetClock( 0, 1.0e-3 ); - shell->doSetClock( 1, 1.0e-3 ); - shell->doSetClock( 2, 1.0e-3 ); - shell->doSetClock( 3, 1.0e-3 ); - shell->doSetClock( 4, 1.0e-3 ); - shell->doSetClock( 5, 1.0e-3 ); - - shell->doUseClock( "/n/gslCompt,/n/exptlCompt", "init", 0 ); - shell->doUseClock( "/n/gslCompt,/n/exptlCompt", "process", 1 ); - shell->doUseClock( "/n/gslCompt/gslRateTable,/n/exptlCompt/exptlRateTable", - "process", 2 ); - shell->doUseClock( "/n/gslCompt/gslSolver,/n/exptlCompt/exptlSolver", - "process", 3 ); - shell->doUseClock( "/n/gslCompt/mChanOde,/n/gslTable","process", 4 ); - shell->doUseClock( "/n/exptlCompt/mChanExptl,/n/exptlTable", "process", 5 ); + Field>::set(vecTableId, "table", table1d); + SetGet4::set( + gslRateTableId, "set1d", 3, 1, vecTableId, 0); + SetGet4::set( + exptlRateTableId, "set1d", 3, 1, vecTableId, 0); + + table1d.erase(table1d.begin(), table1d.end()); + + // Transition from "O" to "C" i.e. r14 + SetGet3::set(gslRateTableId, "setconst", + 1, 4, 1e3 * exp(-2.847)); + SetGet3::set( + exptlRateTableId, "setconst", 1, 4, 1e3 * exp(-2.847)); + + // Transition from "B1" to "C" i.e. r24 + SetGet3::set(gslRateTableId, "setconst", + 2, 4, 1e3 * exp(-0.693)); + SetGet3::set( + exptlRateTableId, "setconst", 2, 4, 1e3 * exp(-0.693)); + + // Transition from "B2" to "C" i.e. r34 + SetGet3::set(gslRateTableId, "setconst", + 3, 4, 1e3 * exp(-3.101)); + SetGet3::set( + exptlRateTableId, "setconst", 3, 4, 1e3 * exp(-3.101)); + + // Once the rate tables have been set up, we can initialize the + // tables in the MarkovSolver class. + SetGet2::set(exptlSolverId, "init", exptlRateTableId, 1.0e-3); + SetGet1::set(exptlSolverId, "ligandConc", 24e-6); + Field>::set(exptlSolverId, "initialState", initState); + + Field::set(gslSolverId, "relativeAccuracy", 1e-24); + Field::set(gslSolverId, "absoluteAccuracy", 1e-24); + Field::set(gslSolverId, "internalDt", 1e-24); + + shell->doSetClock(0, 1.0e-3); + shell->doSetClock(1, 1.0e-3); + shell->doSetClock(2, 1.0e-3); + shell->doSetClock(3, 1.0e-3); + shell->doSetClock(4, 1.0e-3); + shell->doSetClock(5, 1.0e-3); + + shell->doUseClock("/n/gslCompt,/n/exptlCompt", "init", 0); + shell->doUseClock("/n/gslCompt,/n/exptlCompt", "process", 1); + shell->doUseClock("/n/gslCompt/gslRateTable,/n/exptlCompt/exptlRateTable", + "process", 2); + shell->doUseClock("/n/gslCompt/gslSolver,/n/exptlCompt/exptlSolver", + "process", 3); + shell->doUseClock("/n/gslCompt/mChanOde,/n/gslTable", "process", 4); + shell->doUseClock("/n/exptlCompt/mChanExptl,/n/exptlTable", "process", 5); shell->doReinit(); // shell->doReinit();// why twice? - subha - shell->doStart( 1.0 ); + shell->doStart(1.0); - vector< double > gslVec = Field< vector< double > >::get( gslTableId, "vector" ); - vector< double > exptlVec = Field< vector< double > >::get( exptlTableId, "vector"); + vector gslVec = Field>::get(gslTableId, "vector"); + vector exptlVec = + Field>::get(exptlTableId, "vector"); - assert( gslVec.size() == 1001 ); - assert( exptlVec.size() == 1001 ); + assert(gslVec.size() == 1001); + assert(exptlVec.size() == 1001); - for ( unsigned int i = 0; i < 1001; ++i ) - assert( doubleApprox( gslVec[i], exptlVec[i] ) ); + for(unsigned int i = 0; i < 1001; ++i) + assert(doubleApprox(gslVec[i], exptlVec[i])); - shell->doDelete( nid ); + shell->doDelete(nid); cout << "." << flush; } - /////////////////////////////////////////////////// // Unit tests for SynChan /////////////////////////////////////////////////// @@ -1291,122 +1273,122 @@ void testMarkovChannel() */ void testSynChan() { - Shell* shell = reinterpret_cast< Shell* >( ObjId( Id(), 0 ).data() ); + Shell* shell = reinterpret_cast(ObjId(Id(), 0).data()); - Id nid = shell->doCreate( "Neutral", Id(), "n", 1 ); + Id nid = shell->doCreate("Neutral", Id(), "n", 1); - Id synChanId = shell->doCreate( "SynChan", nid, "synChan", 1 ); - Id synHandlerId = shell->doCreate( "SimpleSynHandler", synChanId, "syns", 1 ); - Id synId( synHandlerId.value() + 1 ); - Id sgId1 = shell->doCreate( "SpikeGen", nid, "sg1", 1 ); - Id sgId2 = shell->doCreate( "SpikeGen", nid, "sg2", 1 ); + Id synChanId = shell->doCreate("SynChan", nid, "synChan", 1); + Id synHandlerId = shell->doCreate("SimpleSynHandler", synChanId, "syns", 1); + Id synId(synHandlerId.value() + 1); + Id sgId1 = shell->doCreate("SpikeGen", nid, "sg1", 1); + Id sgId2 = shell->doCreate("SpikeGen", nid, "sg2", 1); ProcInfo p; p.dt = 1.0e-4; p.currTime = 0; bool ret; - assert( synId.element()->getName() == "synapse" ); - ret = Field< double >::set( synChanId, "tau1", 1.0e-3 ); - assert( ret ); - ret = Field< double >::set( synChanId, "tau2", 1.0e-3 ); - assert( ret ); - ret = Field< double >::set( synChanId, "Gbar", 1.0 ); - assert( ret ); + assert(synId.element()->getName() == "synapse"); + ret = Field::set(synChanId, "tau1", 1.0e-3); + assert(ret); + ret = Field::set(synChanId, "tau2", 1.0e-3); + assert(ret); + ret = Field::set(synChanId, "Gbar", 1.0); + assert(ret); // This is a hack, should really inspect msgs to automatically figure // out how many synapses are needed. - ret = Field< unsigned int >::set( synHandlerId, "numSynapse", 2 ); - assert( ret ); + ret = Field::set(synHandlerId, "numSynapse", 2); + assert(ret); Element* syne = synId.element(); - assert( syne->totNumLocalField() == 2 ); - - ObjId mid = shell->doAddMsg( "single", - ObjId( sgId1, 0 ), "spikeOut", ObjId( synId, 0, 0 ), "addSpike" ); - assert( mid != Id() ); - mid = shell->doAddMsg( "single", - ObjId( sgId2, 0 ), "spikeOut", ObjId( synId, 0, 1 ), "addSpike" ); - assert( mid != Id() ); - mid = shell->doAddMsg( "single", - synHandlerId, "activationOut", synChanId, "activation" ); - assert( mid != Id() ); - - ret = Field< double >::set( sgId1, "threshold", 0.0 ); - ret = Field< double >::set( sgId1, "refractT", 1.0 ); - ret = Field< bool >::set( sgId1, "edgeTriggered", 0 ); - ret = Field< double >::set( sgId2, "threshold", 0.0 ); - ret = Field< double >::set( sgId2, "refractT", 1.0 ); - ret = Field< bool >::set( sgId2, "edgeTriggered", 0 ); - - ret = Field< double >::set( ObjId( synId, 0, 0 ), "weight", 1.0 ); - assert( ret); - ret = Field< double >::set( ObjId( synId, 0, 0 ), "delay", 0.001 ); - assert( ret); - ret = Field< double >::set( ObjId( synId, 0, 1 ), "weight", 1.0 ); - assert( ret); - ret = Field< double >::set( ObjId( synId, 0, 1 ), "delay", 0.01 ); - assert( ret); + assert(syne->totNumLocalField() == 2); + + ObjId mid = shell->doAddMsg("single", ObjId(sgId1, 0), "spikeOut", + ObjId(synId, 0, 0), "addSpike"); + assert(mid != Id()); + mid = shell->doAddMsg("single", ObjId(sgId2, 0), "spikeOut", + ObjId(synId, 0, 1), "addSpike"); + assert(mid != Id()); + mid = shell->doAddMsg("single", synHandlerId, "activationOut", synChanId, + "activation"); + assert(mid != Id()); + + ret = Field::set(sgId1, "threshold", 0.0); + ret = Field::set(sgId1, "refractT", 1.0); + ret = Field::set(sgId1, "edgeTriggered", 0); + ret = Field::set(sgId2, "threshold", 0.0); + ret = Field::set(sgId2, "refractT", 1.0); + ret = Field::set(sgId2, "edgeTriggered", 0); + + ret = Field::set(ObjId(synId, 0, 0), "weight", 1.0); + assert(ret); + ret = Field::set(ObjId(synId, 0, 0), "delay", 0.001); + assert(ret); + ret = Field::set(ObjId(synId, 0, 1), "weight", 1.0); + assert(ret); + ret = Field::set(ObjId(synId, 0, 1), "delay", 0.01); + assert(ret); double dret; - dret = Field< double >::get( ObjId( synId, 0, 0 ), "weight" ); - ASSERT_DOUBLE_EQ("", dret, 1.0 ); - dret = Field< double >::get( ObjId( synId, 0, 0 ), "delay" ); - ASSERT_DOUBLE_EQ("", dret, 0.001 ); - dret = Field< double >::get( ObjId( synId, 0, 1 ), "weight" ); - ASSERT_DOUBLE_EQ("", dret, 1.0 ); - dret = Field< double >::get( ObjId( synId, 0, 1 ), "delay" ); - ASSERT_DOUBLE_EQ("", dret, 0.01 ); - - dret = SetGet1< double >::set( sgId1, "Vm", 2.0 ); - dret = SetGet1< double >::set( sgId2, "Vm", 2.0 ); - dret = Field< double >::get( synChanId, "Gk" ); - ASSERT_DOUBLE_EQ("", dret, 0.0 ); + dret = Field::get(ObjId(synId, 0, 0), "weight"); + ASSERT_DOUBLE_EQ(dret, 1.0, ""); + dret = Field::get(ObjId(synId, 0, 0), "delay"); + ASSERT_DOUBLE_EQ(dret, 0.001, ""); + dret = Field::get(ObjId(synId, 0, 1), "weight"); + ASSERT_DOUBLE_EQ(dret, 1.0, ""); + dret = Field::get(ObjId(synId, 0, 1), "delay"); + ASSERT_DOUBLE_EQ(dret, 0.01, ""); + + dret = SetGet1::set(sgId1, "Vm", 2.0); + dret = SetGet1::set(sgId2, "Vm", 2.0); + dret = Field::get(synChanId, "Gk"); + ASSERT_DOUBLE_EQ(dret, 0.0, ""); ///////////////////////////////////////////////////////////////////// - shell->doSetClock( 0, 1e-4 ); - shell->doSetClock( 1, 1e-4 ); - shell->doSetClock( 2, 1e-4 ); + shell->doSetClock(0, 1e-4); + shell->doSetClock(1, 1e-4); + shell->doSetClock(2, 1e-4); // shell->doUseClock( "/n/##", "process", 0 ); // shell->doUseClock( "/n/synChan/syns,/n/sg1,/n/sg2", "process", 0 ); - //It turns out that the order of setting of the spikes (sg1, sg2) - //does not affect the outcome. The one thing that is critical is that - //the 'process' call for the 'syns' should be before that of the - //synChan. This is because the 'activation' message from the syns to - //the synChan should proceed within a given timestep otherwise the - //apparent arrival time of the event is delayed. - shell->doUseClock( "/n/sg1,/n/sg2", "process", 0 ); - shell->doUseClock( "/n/synChan/syns", "process", 1 ); - shell->doUseClock( "/n/synChan", "process", 2 ); + // It turns out that the order of setting of the spikes (sg1, sg2) + // does not affect the outcome. The one thing that is critical is that + // the 'process' call for the 'syns' should be before that of the + // synChan. This is because the 'activation' message from the syns to + // the synChan should proceed within a given timestep otherwise the + // apparent arrival time of the event is delayed. + shell->doUseClock("/n/sg1,/n/sg2", "process", 0); + shell->doUseClock("/n/synChan/syns", "process", 1); + shell->doUseClock("/n/synChan", "process", 2); // shell->doStart( 0.001 ); shell->doReinit(); shell->doReinit(); - shell->doStart( 0.001 ); - dret = Field< double >::get( synChanId, "Gk" ); - assert( doubleApprox( dret, 0.0 ) ); + shell->doStart(0.001); + dret = Field::get(synChanId, "Gk"); + assert(doubleApprox(dret, 0.0)); - shell->doStart( 0.0005 ); - dret = Field< double >::get( synChanId, "Gk" ); - assert( doubleApprox( dret, 0.825 ) ); + shell->doStart(0.0005); + dret = Field::get(synChanId, "Gk"); + assert(doubleApprox(dret, 0.825)); - shell->doStart( 0.0005 ); - dret = Field< double >::get( synChanId, "Gk" ); - assert( doubleApprox( dret, 1.0 ) ); + shell->doStart(0.0005); + dret = Field::get(synChanId, "Gk"); + assert(doubleApprox(dret, 1.0)); - shell->doStart( 0.001 ); - dret = Field< double >::get( synChanId, "Gk" ); - assert( doubleApprox( dret, 0.736 ) ); + shell->doStart(0.001); + dret = Field::get(synChanId, "Gk"); + assert(doubleApprox(dret, 0.736)); - shell->doStart( 0.001 ); - dret = Field< double >::get( synChanId, "Gk" ); - assert( doubleApprox( dret, 0.406 ) ); + shell->doStart(0.001); + dret = Field::get(synChanId, "Gk"); + assert(doubleApprox(dret, 0.406)); - shell->doStart( 0.007 ); - dret = Field< double >::get( synChanId, "Gk" ); + shell->doStart(0.007); + dret = Field::get(synChanId, "Gk"); // assert( doubleApprox( dret, 0.997 ) ); - assert( doubleApprox( dret, 1.002 ) ); + assert(doubleApprox(dret, 1.002)); - shell->doDelete( nid ); + shell->doDelete(nid); cout << "." << flush; } @@ -1465,13 +1447,13 @@ void testNMDAChan() double dret; dret = Field< double >::get( ObjId( synId, DataId( 0 ) ), "weight" ); - ASSERT_DOUBLE_EQ("", dret, 1.0 ); + ASSERT_DOUBLE_EQ(dret, 1.0, ""); dret = Field< double >::get( ObjId( synId, DataId( 0 ) ), "delay" ); - ASSERT_DOUBLE_EQ("", dret, 0.001 ); + ASSERT_DOUBLE_EQ(dret, 0.001, ""); dret = SetGet1< double >::set( sgId1, "Vm", 2.0 ); dret = Field< double >::get( synChanId, "Gk" ); - ASSERT_DOUBLE_EQ("", dret, 0.0 ); + ASSERT_DOUBLE_EQ(dret, 0.0, ""); ///////////////////////////////////////////////////////////////////// @@ -1517,36 +1499,33 @@ void testNMDAChan() } #endif -static Id addCompartment( const string& name, - Id neuron, Id parent, - double dx, double dy, double dz, double dia ) +static Id addCompartment(const string& name, Id neuron, Id parent, double dx, + double dy, double dz, double dia) { - static Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); + static Shell* shell = reinterpret_cast(Id().eref().data()); double x0 = 0.0; double y0 = 0.0; double z0 = 0.0; - Id compt = shell->doCreate( "Compartment", neuron, name, 1 ); - if ( parent != Id() ) - { - ObjId mid = shell->doAddMsg( "single", - parent, "axial", compt, "raxial" ); - assert( mid != Id() ); - x0 = Field< double >::get( parent, "x" ); - y0 = Field< double >::get( parent, "y" ); - z0 = Field< double >::get( parent, "z" ); + Id compt = shell->doCreate("Compartment", neuron, name, 1); + if(parent != Id()) { + ObjId mid = shell->doAddMsg("single", parent, "axial", compt, "raxial"); + assert(mid != Id()); + x0 = Field::get(parent, "x"); + y0 = Field::get(parent, "y"); + z0 = Field::get(parent, "z"); } - Field< double >::set( compt, "x0", x0 ); - Field< double >::set( compt, "y0", y0 ); - Field< double >::set( compt, "z0", z0 ); - Field< double >::set( compt, "x", x0 + dx ); - Field< double >::set( compt, "y", y0 + dy ); - Field< double >::set( compt, "z", z0 + dz ); - double length = sqrt( dx*dx + dy*dy + dz*dz ); - Field< double >::set( compt, "length", length ); - Field< double >::set( compt, "diameter", dia ); - Field< double >::set( compt, "Rm", 1.0 / ( PI * length * dia ) ); - Field< double >::set( compt, "Cm", 0.01 * ( PI * length * dia ) ); - Field< double >::set( compt, "Ra", 1 * length / ( PI*0.25*dia*dia ) ); + Field::set(compt, "x0", x0); + Field::set(compt, "y0", y0); + Field::set(compt, "z0", z0); + Field::set(compt, "x", x0 + dx); + Field::set(compt, "y", y0 + dy); + Field::set(compt, "z", z0 + dz); + double length = sqrt(dx * dx + dy * dy + dz * dz); + Field::set(compt, "length", length); + Field::set(compt, "diameter", dia); + Field::set(compt, "Rm", 1.0 / (PI * length * dia)); + Field::set(compt, "Cm", 0.01 * (PI * length * dia)); + Field::set(compt, "Ra", 1 * length / (PI * 0.25 * dia * dia)); return compt; } @@ -1557,112 +1536,110 @@ static Id addCompartment( const string& name, #include "../shell/Wildcard.h" static void testNeuronBuildTree() { - Shell* shell = reinterpret_cast< Shell* >( ObjId( Id(), 0 ).data() ); + Shell* shell = reinterpret_cast(ObjId(Id(), 0).data()); - Id nid = shell->doCreate( "Neuron", Id(), "n", 1 ); + Id nid = shell->doCreate("Neuron", Id(), "n", 1); double somaDia = 5e-6; double dendDia = 2e-6; double branchDia = 1e-6; - static double len[] = { 10e-6, 100e-6, 200e-6, 500e-6 }; - static double dia[] = { somaDia, dendDia, branchDia, branchDia }; - Id soma = addCompartment ( "soma", nid, Id(), 10e-6, 0, 0, somaDia ); - Id dend1 = addCompartment ( "dend1", nid, soma, 100e-6, 0, 0, dendDia); - Id branch1 = addCompartment ( "branch1", nid, dend1, 0, 200e-6, 0, branchDia ); - Id branch2 = addCompartment ( "branch2", nid, dend1, 0, -500e-6, 0, branchDia ); - static double x[] = { 10e-6, 110e-6, 110e-6, 110e-6 }; + static double len[] = {10e-6, 100e-6, 200e-6, 500e-6}; + static double dia[] = {somaDia, dendDia, branchDia, branchDia}; + Id soma = addCompartment("soma", nid, Id(), 10e-6, 0, 0, somaDia); + Id dend1 = addCompartment("dend1", nid, soma, 100e-6, 0, 0, dendDia); + Id branch1 = addCompartment("branch1", nid, dend1, 0, 200e-6, 0, branchDia); + Id branch2 = + addCompartment("branch2", nid, dend1, 0, -500e-6, 0, branchDia); + static double x[] = {10e-6, 110e-6, 110e-6, 110e-6}; static double y[] = {0, 0, 200e-6, -500e-6}; static double z[] = {0, 0, 0, 0}; - SetGet0::set( nid, "buildSegmentTree" ); - - vector< double > e = Field< vector< double > >::get( - nid, "electrotonicDistanceFromSoma" ); - vector< double > g = Field< vector< double > >::get( - nid, "geometricalDistanceFromSoma" ); - vector< double > p = Field< vector< double > >::get( - nid, "pathDistanceFromSoma" ); - assert( e.size() == 4 ); - ASSERT_DOUBLE_EQ("", e[0], 0.0 ); - double dL = 100e-6 / sqrt( dendDia /4.0 ); - ASSERT_DOUBLE_EQ("", e[1], dL ); - double bL1 = dL + 200e-6 / sqrt( branchDia /4.0 ); - ASSERT_DOUBLE_EQ("", e[2], bL1 ); - double bL2 = dL + 500e-6 / sqrt( branchDia/4.0 ); - ASSERT_DOUBLE_EQ("", e[3], bL2 ); - - ASSERT_DOUBLE_EQ("", p[0], 0.0 ); - ASSERT_DOUBLE_EQ("", p[1], 100.0e-6 ); - ASSERT_DOUBLE_EQ("", p[2], 300.0e-6 ); // 100 + 200 microns - ASSERT_DOUBLE_EQ("", p[3], 600.0e-6 ); // 100 + 500 microns - - ASSERT_DOUBLE_EQ("", g[0], 0.0 ); - ASSERT_DOUBLE_EQ("", g[1], 100.0e-6 ); - ASSERT_DOUBLE_EQ("", g[2], sqrt(5.0) * 100.0e-6 ); // 100 + 200 microns - ASSERT_DOUBLE_EQ("", g[3], sqrt(26.0) * 100.0e-6 ); // 100 + 500 microns + SetGet0::set(nid, "buildSegmentTree"); + + vector e = + Field>::get(nid, "electrotonicDistanceFromSoma"); + vector g = + Field>::get(nid, "geometricalDistanceFromSoma"); + vector p = Field>::get(nid, "pathDistanceFromSoma"); + assert(e.size() == 4); + ASSERT_DOUBLE_EQ(e[0], 0.0, ""); + double dL = 100e-6 / sqrt(dendDia / 4.0); + ASSERT_DOUBLE_EQ(e[1], dL, ""); + double bL1 = dL + 200e-6 / sqrt(branchDia / 4.0); + ASSERT_DOUBLE_EQ(e[2], bL1, ""); + double bL2 = dL + 500e-6 / sqrt(branchDia / 4.0); + ASSERT_DOUBLE_EQ(e[3], bL2, ""); + + ASSERT_DOUBLE_EQ(p[0], 0.0, ""); + ASSERT_DOUBLE_EQ(p[1], 100.0e-6, ""); + ASSERT_DOUBLE_EQ(p[2], 300.0e-6, ""); // 100 + 200 microns + ASSERT_DOUBLE_EQ(p[3], 600.0e-6, ""); // 100 + 500 microns + + ASSERT_DOUBLE_EQ(g[0], 0.0, ""); + ASSERT_DOUBLE_EQ(g[1], 100.0e-6, ""); + ASSERT_DOUBLE_EQ(g[2], sqrt(5.0) * 100.0e-6, ""); // 100 + 200 microns + ASSERT_DOUBLE_EQ(g[3], sqrt(26.0) * 100.0e-6, ""); // 100 + 500 microns ////////////////////////////////////////////////////////////////// // Here we test Neuron::evalExprForElist, which uses the muParser // Note that the wildcard list starts with the spine which is not // a compartment. So the indexing of the arrays e, p and g needs care. unsigned int nuParserNumVal = 13; - vector< ObjId > elist; - wildcardFind( "/n/#[ISA=Compartment]", elist ); - Neuron* n = reinterpret_cast< Neuron* >( nid.eref().data() ); - vector< double > val; - n->evalExprForElist( elist, "p + g + L + len + dia + H(1-L)", val ); - assert( val.size() == nuParserNumVal * elist.size() ); + vector elist; + wildcardFind("/n/#[ISA=Compartment]", elist); + Neuron* n = reinterpret_cast(nid.eref().data()); + vector val; + n->evalExprForElist(elist, "p + g + L + len + dia + H(1-L)", val); + assert(val.size() == nuParserNumVal * elist.size()); double maxP = 0.0; double maxG = 0.0; double maxL = 0.0; - for ( unsigned int i = 0; i < elist.size(); ++i ) - { - if ( maxP < p[i] ) maxP = p[i]; - if ( maxG < g[i] ) maxG = g[i]; - if ( maxL < e[i] ) maxL = e[i]; + for(unsigned int i = 0; i < elist.size(); ++i) { + if(maxP < p[i]) + maxP = p[i]; + if(maxG < g[i]) + maxG = g[i]; + if(maxL < e[i]) + maxL = e[i]; } unsigned int j = 0; - for ( unsigned int i = 0; i < elist.size(); ++i ) - { - if ( !elist[i].element()->cinfo()->isA( "CompartmentBase" ) ) + for(unsigned int i = 0; i < elist.size(); ++i) { + if(!elist[i].element()->cinfo()->isA("CompartmentBase")) continue; - assert( val[i * nuParserNumVal] == - p[j] + g[j] + e[j] + len[j] + dia[j] + ( 1.0 - e[j] > 0 ) ); - ASSERT_DOUBLE_EQ("", val[i * nuParserNumVal + 1], p[j] ); - ASSERT_DOUBLE_EQ("", val[i * nuParserNumVal + 2], g[j] ); - ASSERT_DOUBLE_EQ("", val[i * nuParserNumVal + 3], e[j] ); - assert( doubleEq( val[i * nuParserNumVal + 4], len[j] )); - ASSERT_DOUBLE_EQ("", val[i * nuParserNumVal + 5], dia[j] ); - ASSERT_DOUBLE_EQ("", val[i * nuParserNumVal + 6], maxP ); - ASSERT_DOUBLE_EQ("", val[i * nuParserNumVal + 7], maxG ); - ASSERT_DOUBLE_EQ("", val[i * nuParserNumVal + 8], maxL ); - ASSERT_DOUBLE_EQ("", val[i * nuParserNumVal + 9], x[j] ); - ASSERT_DOUBLE_EQ("", val[i * nuParserNumVal + 10], y[j] ); - ASSERT_DOUBLE_EQ("", val[i * nuParserNumVal + 11], z[j] ); - ASSERT_DOUBLE_EQ("", val[i * nuParserNumVal + 12], 0.0 ); + assert(val[i * nuParserNumVal] == + p[j] + g[j] + e[j] + len[j] + dia[j] + (1.0 - e[j] > 0)); + ASSERT_DOUBLE_EQ(val[i * nuParserNumVal + 1], p[j], ""); + ASSERT_DOUBLE_EQ(val[i * nuParserNumVal + 2], g[j], ""); + ASSERT_DOUBLE_EQ(val[i * nuParserNumVal + 3], e[j], ""); + assert(doubleEq(val[i * nuParserNumVal + 4], len[j])); + ASSERT_DOUBLE_EQ(val[i * nuParserNumVal + 5], dia[j], ""); + ASSERT_DOUBLE_EQ(val[i * nuParserNumVal + 6], maxP, ""); + ASSERT_DOUBLE_EQ(val[i * nuParserNumVal + 7], maxG, ""); + ASSERT_DOUBLE_EQ(val[i * nuParserNumVal + 8], maxL, ""); + ASSERT_DOUBLE_EQ(val[i * nuParserNumVal + 9], x[j], ""); + ASSERT_DOUBLE_EQ(val[i * nuParserNumVal + 10], y[j], ""); + ASSERT_DOUBLE_EQ(val[i * nuParserNumVal + 11], z[j], ""); + ASSERT_DOUBLE_EQ(val[i * nuParserNumVal + 12], 0.0, ""); j++; } ////////////////////////////////////////////////////////////////// // Here we test Neuron::makeSpacingDistrib, which uses the muParser // n->evalExprForElist( elist, "H(p-50e-6)*5e-6", val ); - n->evalExprForElist( elist, "H(p-100e-6)*5e-6", val ); - vector< unsigned int > seglistIndex; - vector< unsigned int > elistIndex; - vector< double > pos; - vector< string > line; // empty, just use the default spacingDistrib=0 - n->makeSpacingDistrib( elist, val, seglistIndex, elistIndex, pos, line ); + n->evalExprForElist(elist, "H(p-100e-6)*5e-6", val); + vector seglistIndex; + vector elistIndex; + vector pos; + vector line; // empty, just use the default spacingDistrib=0 + n->makeSpacingDistrib(elist, val, seglistIndex, elistIndex, pos, line); // Can't do this now, it is not determinisitic. // assert( pos.size() == ((800 - 100)/5) ); - // ASSERT_DOUBLE_EQ("", pos[0], 2.5e-6 ); - // ASSERT_DOUBLE_EQ("", pos.back(), 500e-6 - 7.5e-6 ); - assert( seglistIndex[0] == 2 ); - assert( seglistIndex.back() == 3 ); - assert( elistIndex[0] == 2 ); - assert( elistIndex.back() == 3 ); + assert(seglistIndex[0] == 2); + assert(seglistIndex.back() == 3); + assert(elistIndex[0] == 2); + assert(elistIndex.back() == 3); - shell->doDelete( nid ); + shell->doDelete(nid); } - // This tests stuff without using the messaging. void testBiophysics() { @@ -1694,19 +1671,10 @@ void testBiophysicsProcess() #endif } -#else // ifdef DO_UNIT_TESTS +#else // ifdef DO_UNIT_TESTS // Dummy functions to avoid link error. -void testBiophysics() -{ - ; -} -void testBiophysicsProcess() -{ - ; -} -void testIntFireNetwork( unsigned int unsteps = 5 ) -{ - ; -} +void testBiophysics() { ; } +void testBiophysicsProcess() { ; } +void testIntFireNetwork(unsigned int unsteps = 5) { ; } #endif diff --git a/builtins/Function.cpp b/builtins/Function.cpp index ca581a25dc..a4fb8b5662 100644 --- a/builtins/Function.cpp +++ b/builtins/Function.cpp @@ -14,6 +14,7 @@ #include "../utility/strutil.h" #include "../utility/numutil.h" #include "../utility/testing_macros.hpp" +#include "../utility/print_function.hpp" #include "../builtins/MooseParser.h" @@ -197,7 +198,7 @@ const Cinfo * Function::initCinfo() "x", "Input variables (indexed) to the function. These can be passed via messages.", Variable::initCinfo(), - &Function::getVar, + &Function::getX, &Function::setNumVar, &Function::getNumVar ); @@ -213,7 +214,9 @@ const Cinfo * Function::initCinfo() static LookupValueFinfo< Function, string, unsigned int > xindex( "xindex", - "Return the index of given variable. It can be used with field `x`", + "(developer only) Returns the index of a given variable which can be used with field `x`." + " Note that we have a mechanism to map string (variable name) to integer " + " (variable index).", &Function::setVarIndex, &Function::getVarIndex ); @@ -326,7 +329,7 @@ in the same order as the y indices. static const Cinfo * functionCinfo = Function::initCinfo(); Function::Function(): - valid_(false) + valid_(true) , numVar_(0) , lastValue_(0.0) , value_(0.0) @@ -377,7 +380,7 @@ Function& Function::operator=(const Function& rhs) varIndex_[x->getName()] = xs_.size()-1; } // Add all the Ys now. - for(size_t i=0; i < rhs.ys_.size(); i++) + for(unsigned int i=0; i < rhs.ys_.size(); i++) ys_.push_back(shared_ptr(new double(0.0))); parser_->LinkVariables(xs_, ys_, &t_); parser_->SetExpr(rhs.parser_->GetExpr()); @@ -408,7 +411,7 @@ void Function::addXByIndex(const unsigned int index) if(index >= xs_.size()) { - for(size_t i = xs_.size(); i <= index; i++) + for(unsigned int i = xs_.size(); i <= index; i++) { xs_.push_back(shared_ptr(new Variable('x'+to_string(i)))); varIndex_[name] = xs_.size()-1; @@ -531,10 +534,7 @@ void Function::setExpr(const Eref& eref, const string expression) { string expr = moose::trim(expression); if(expr.empty()) - { - // MOOSE_WARN("Empty expression."); return; - } if(valid_ && expr == parser_->GetExpr()) { @@ -602,7 +602,7 @@ string Function::getExpr( const Eref& e ) const { if (!valid_) { - cout << "Error: " << e.objId().path() << "::getExpr() - invalid parser state" << endl; + cerr << __func__ << " Error: " << e.objId().path() << "::getExpr() - invalid parser state" << endl; cout << "\tExpression was : " << parser_->GetExpr() << endl; return ""; } @@ -659,9 +659,7 @@ double Function::getValue() const double Function::getRate() const { if (!valid_) - { - cout << "Error: Function::getValue() - invalid state" << endl; - } + cerr << __func__ << "Error: invalid state" << endl; return rate_; } @@ -686,9 +684,8 @@ vector< double > Function::getY() const double Function::getDerivative() const { double value = 0.0; - if (!valid_) - { - cout << "Error: Function::getDerivative() - invalid state" << endl; + if (!valid_) { + cerr << __func__ << "Error: invalid state" << endl; return value; } return parser_->Derivative(independent_); @@ -716,7 +713,7 @@ void Function::setVar(unsigned int index, double value) MOOSE_WARN("Function: index " << index << " out of bounds."); } -Variable* Function::getVar(unsigned int ii) +Variable* Function::getX(unsigned int ii) { static Variable dummy("DUMMY"); if(ii >= xs_.size()) @@ -766,10 +763,7 @@ bool Function::symbolExists(const string& name) const void Function::process(const Eref &e, ProcPtr p) { if(! valid_) - { - cerr << "Warn: Invalid parser state. " << endl; return; - } // Update values of incoming variables. vector databuf; @@ -779,7 +773,7 @@ void Function::process(const Eref &e, ProcPtr p) value_ = getValue(); rate_ = (value_ - lastValue_) / p->dt; - for (size_t ii = 0; (ii < databuf.size()) && (ii < ys_.size()); ++ii) + for (unsigned int ii = 0; (ii < databuf.size()) && (ii < ys_.size()); ++ii) *ys_[ii] = databuf[ii]; if ( useTrigger_ && value_ < TriggerThreshold ) @@ -820,8 +814,8 @@ void Function::reinit(const Eref &e, ProcPtr p) { if (! (valid_ || parser_->GetExpr().empty())) { - cout << "Error: " << e.objId().path() << "::reinit() - invalid parser state" << endl; - cout << " Expr: '" << parser_->GetExpr() << "'" << endl; + MOOSE_WARN("Error: " << e.objId().path() << "::reinit() - invalid parser state" + << endl << " Expr: '" << parser_->GetExpr() << "'."); return; } diff --git a/builtins/Function.h b/builtins/Function.h index 1d88f65cb2..a63edffad2 100644 --- a/builtins/Function.h +++ b/builtins/Function.h @@ -46,7 +46,7 @@ class Function // get/set the value of variable `name` void setVar(unsigned int index, double value); - Variable* getVar(unsigned int ii); + Variable* getX(unsigned int ii); // get function eval result double getValue() const; diff --git a/builtins/HDF5DataWriter.cpp b/builtins/HDF5DataWriter.cpp index 5f7ba3b93d..50c787e1b5 100644 --- a/builtins/HDF5DataWriter.cpp +++ b/builtins/HDF5DataWriter.cpp @@ -208,7 +208,7 @@ void HDF5DataWriter::reinit(const Eref & e, ProcPtr p) openFile(); for (unsigned int ii = 0; ii < src_.size(); ++ii){ string varname = func_[ii]; - size_t found = varname.find("get"); + unsigned int found = varname.find("get"); if (found == 0){ varname = varname.substr(3); if (varname.length() == 0){ @@ -239,7 +239,7 @@ hid_t HDF5DataWriter::getDataset(string path) } herr_t status = H5Eset_auto2(H5E_DEFAULT, NULL, NULL); // Create the groups corresponding to this path - string::size_type lastslash = path.find_last_of("/"); + string::unsigned intype lastslash = path.find_last_of("/"); vector pathTokens; moose::tokenize(path, "/", pathTokens); hid_t prev_id = filehandle_; diff --git a/builtins/HDF5WriterBase.cpp b/builtins/HDF5WriterBase.cpp index 8e42352443..b0726b26ad 100644 --- a/builtins/HDF5WriterBase.cpp +++ b/builtins/HDF5WriterBase.cpp @@ -56,7 +56,7 @@ using namespace std; hid_t require_attribute(hid_t file_id, string path, hid_t data_type, hid_t data_id) { - size_t attr_start = path.rfind("/"); + unsigned int attr_start = path.rfind("/"); string node_path = "."; string attr_name = ""; if (attr_start == string::npos){ @@ -111,16 +111,16 @@ hid_t require_group(hid_t file, string path) /** Create a new 1D dataset. Make it extensible. */ -hid_t HDF5WriterBase::createDoubleDataset(hid_t parent_id, std::string name, hsize_t size, hsize_t maxsize) +hid_t HDF5WriterBase::createDoubleDataset(hid_t parent_id, std::string name, hunsigned int size, hunsigned int maxsize) { herr_t status; - hsize_t dims[1] = {size}; - hsize_t maxdims[] = {maxsize}; - hsize_t _chunkSize = chunkSize_; + hunsigned int dims[1] = {size}; + hunsigned int maxdims[] = {maxsize}; + hunsigned int _chunkSize = chunkSize_; if (_chunkSize > maxsize){ _chunkSize = maxsize; } - hsize_t chunk_dims[] = {_chunkSize}; + hunsigned int chunk_dims[] = {_chunkSize}; hid_t chunk_params = H5Pcreate(H5P_DATASET_CREATE); status = H5Pset_chunk(chunk_params, 1, chunk_dims); assert( status >= 0 ); @@ -141,20 +141,20 @@ hid_t HDF5WriterBase::createDoubleDataset(hid_t parent_id, std::string name, hsi return dataset_id; } -hid_t HDF5WriterBase::createStringDataset(hid_t parent_id, string name, hsize_t size, hsize_t maxsize) +hid_t HDF5WriterBase::createStringDataset(hid_t parent_id, string name, hunsigned int size, hunsigned int maxsize) { herr_t status; hid_t ftype = H5Tcopy(H5T_C_S1); if (H5Tset_size(ftype, H5T_VARIABLE) < 0){ return -1; } - hsize_t dims[] = {size}; - hsize_t maxdims[] = {maxsize}; - hsize_t _chunkSize = chunkSize_; + hunsigned int dims[] = {size}; + hunsigned int maxdims[] = {maxsize}; + hunsigned int _chunkSize = chunkSize_; if (maxsize < _chunkSize){ _chunkSize = maxsize; } - hsize_t chunk_dims[] = {_chunkSize}; + hunsigned int chunk_dims[] = {_chunkSize}; hid_t chunk_params = H5Pcreate(H5P_DATASET_CREATE); status = H5Pset_chunk(chunk_params, 1, chunk_dims); assert( status >= 0 ); @@ -193,15 +193,15 @@ herr_t HDF5WriterBase::appendToDataset(hid_t dataset_id, const vector< double >& if (data.size() == 0){ return 0; } - hsize_t size = H5Sget_simple_extent_npoints(filespace) + data.size(); + hunsigned int size = H5Sget_simple_extent_npoints(filespace) + data.size(); status = H5Dset_extent(dataset_id, &size); if (status < 0){ return status; } filespace = H5Dget_space(dataset_id); - hsize_t size_increment = data.size(); + hunsigned int size_increment = data.size(); hid_t memspace = H5Screate_simple(1, &size_increment, NULL); - hsize_t start = size - data.size(); + hunsigned int start = size - data.size(); H5Sselect_hyperslab(filespace, H5S_SELECT_SET, &start, NULL, &size_increment, NULL); status = H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, memspace, filespace, @@ -221,7 +221,7 @@ hid_t HDF5WriterBase::createDataset2D(hid_t parent, string name, unsigned int ro } herr_t status; // we need chunking here to allow extensibility - hsize_t chunkdims[] = {rows, chunkSize_}; + hunsigned int chunkdims[] = {rows, chunkSize_}; hid_t chunk_params = H5Pcreate(H5P_DATASET_CREATE); status = H5Pset_chunk(chunk_params, 2, chunkdims); assert(status >= 0); @@ -233,8 +233,8 @@ hid_t HDF5WriterBase::createDataset2D(hid_t parent, string name, unsigned int ro status = H5Pset_szip(chunk_params, sz_opt_mask, HDF5WriterBase::CHUNK_SIZE); } - hsize_t dims[2] = {rows, 0}; - hsize_t maxdims[2] = {rows, H5S_UNLIMITED}; + hunsigned int dims[2] = {rows, 0}; + hunsigned int maxdims[2] = {rows, H5S_UNLIMITED}; hid_t dataspace = H5Screate_simple(2, dims, maxdims); hid_t dset = H5Dcreate2(parent, name.c_str(), H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT, chunk_params, H5P_DEFAULT); H5Pclose(chunk_params); @@ -338,7 +338,7 @@ herr_t writeScalarAttr(hid_t file_id, string path, int value) template <> herr_t writeVectorAttr(hid_t file_id, string path, vector < string > value) { - hsize_t dims[] = {value.size()}; + hunsigned int dims[] = {value.size()}; hid_t space = H5Screate_simple(1, dims, NULL); hid_t dtype = H5Tcopy(H5T_C_S1); H5Tset_size(dtype, H5T_VARIABLE); @@ -357,7 +357,7 @@ herr_t writeVectorAttr(hid_t file_id, string path, vector < string > value) template <> herr_t writeVectorAttr(hid_t file_id, string path, vector < double > value) { - hsize_t dims[] = {value.size()}; + hunsigned int dims[] = {value.size()}; hid_t data_id = H5Screate_simple(1, dims, NULL); hid_t dtype = H5T_NATIVE_DOUBLE; H5Tset_size(dtype, value.size()); @@ -371,7 +371,7 @@ herr_t writeVectorAttr(hid_t file_id, string path, vector < double > value) template <> herr_t writeVectorAttr(hid_t file_id, string path, vector < long > value) { - hsize_t dims[] = {value.size()}; + hunsigned int dims[] = {value.size()}; hid_t data_id = H5Screate_simple(1, dims, NULL); hid_t dtype = H5T_NATIVE_LONG; H5Tset_size(dtype, value.size()); @@ -515,7 +515,7 @@ const Cinfo* HDF5WriterBase::initCinfo() return &hdf5Cinfo; } -const hssize_t HDF5WriterBase::CHUNK_SIZE = 1024; // default chunk size +const hsunsigned int HDF5WriterBase::CHUNK_SIZE = 1024; // default chunk size HDF5WriterBase::HDF5WriterBase(): diff --git a/builtins/HDF5WriterBase.h b/builtins/HDF5WriterBase.h index a7cbd59d78..91497038be 100644 --- a/builtins/HDF5WriterBase.h +++ b/builtins/HDF5WriterBase.h @@ -41,7 +41,7 @@ hid_t require_group(hid_t file_id, string path); class HDF5WriterBase { public: - static const hssize_t CHUNK_SIZE; + static const hsunsigned int CHUNK_SIZE; HDF5WriterBase(); virtual ~HDF5WriterBase(); void setFilename(string filename); @@ -80,8 +80,8 @@ class HDF5WriterBase herr_t openFile(); // C++ sucks - does not allow template specialization inside class - hid_t createDoubleDataset(hid_t parent, std::string name, hsize_t size=0, hsize_t maxsize=H5S_UNLIMITED); - hid_t createStringDataset(hid_t parent, std::string name, hsize_t size=0, hsize_t maxsize=H5S_UNLIMITED); + hid_t createDoubleDataset(hid_t parent, std::string name, hunsigned int size=0, hunsigned int maxsize=H5S_UNLIMITED); + hid_t createStringDataset(hid_t parent, std::string name, hunsigned int size=0, hunsigned int maxsize=H5S_UNLIMITED); herr_t appendToDataset(hid_t dataset, const vector& data); hid_t createDataset2D(hid_t parent, string name, unsigned int rows); diff --git a/builtins/Interpol2D.cpp b/builtins/Interpol2D.cpp index a35fe86a59..6773bde118 100644 --- a/builtins/Interpol2D.cpp +++ b/builtins/Interpol2D.cpp @@ -609,8 +609,8 @@ bool Interpol2D::operator<( const Interpol2D& other ) const if ( table_.size() > other.table_.size() ) return 0; - for ( size_t i = 0; i < table_.size(); i++ ) { - for ( size_t j = 0; j < table_[ i ].size(); j++ ) { + for ( unsigned int i = 0; i < table_.size(); i++ ) { + for ( unsigned int j = 0; j < table_[ i ].size(); j++ ) { if ( table_[ i ][ j ] < other.table_[ i ][ j ] ) return 1; if ( table_[ i ][ j ] > other.table_[ i ][ j ] ) diff --git a/builtins/MooseParser.cpp b/builtins/MooseParser.cpp index 0e73ee34e0..b604bdee7e 100644 --- a/builtins/MooseParser.cpp +++ b/builtins/MooseParser.cpp @@ -12,9 +12,10 @@ #include #include -#include "../basecode/global.h" #include "../basecode/header.h" +#include "../randnum/randnum.h" + #include "../utility/testing_macros.hpp" #include "../utility/print_function.hpp" #include "../utility/strutil.h" @@ -28,7 +29,7 @@ using namespace std; namespace moose { -MooseParser::MooseParser(): valid_(true) +MooseParser::MooseParser(): expr_("0"), valid_(true) { Parser::symbol_table_t symbolTable; symbolTable.add_function("ln", MooseParser::Ln); @@ -39,6 +40,7 @@ MooseParser::MooseParser(): valid_(true) symbolTable.add_function("srand2", MooseParser::SRand2); symbolTable.add_function("fmod", MooseParser::Fmod); expression_.register_symbol_table(symbolTable); + SetExpr(expr_); } MooseParser::~MooseParser() @@ -61,7 +63,7 @@ double MooseParser::Rand( ) double MooseParser::SRand( double seed = -1 ) { if( seed >= 0 ) - moose::mtseed( (size_t) seed ); + moose::mtseed( (unsigned int) seed ); return moose::mtrand(); } @@ -73,7 +75,7 @@ double MooseParser::Rand2( double a, double b ) double MooseParser::SRand2( double a, double b, double seed = -1 ) { if( seed >= 0 ) - moose::mtseed( (size_t) seed ); + moose::mtseed( (unsigned int) seed ); return moose::mtrand( a, b ); } @@ -86,12 +88,12 @@ double MooseParser::Fmod( double a, double b ) /*----------------------------------------------------------------------------- * Get/Set *-----------------------------------------------------------------------------*/ -Parser::symbol_table_t& MooseParser::GetSymbolTable(const size_t nth) +Parser::symbol_table_t& MooseParser::GetSymbolTable(const unsigned int nth) { return expression_.get_symbol_table(nth); } -const Parser::symbol_table_t& MooseParser::GetSymbolTable(const size_t nth) const +const Parser::symbol_table_t& MooseParser::GetSymbolTable(const unsigned int nth) const { return expression_.get_symbol_table(nth); } @@ -105,7 +107,7 @@ void MooseParser::PrintSymbolTable(void) const { stringstream ss; auto symbTable = GetSymbolTable(); - vector> vars; + vector> vars; auto n = symbTable.get_variable_list(vars); ss << "More Information:\nTotal variables " << n << "."; for (auto i : vars) @@ -238,9 +240,9 @@ bool MooseParser::CompileExpr() bool res = parser.compile(expr_, expression_); if(! res) { - std::stringstream ss; + stringstream ss; ss << "Failed to parse '" << expr_ << "' :" << endl; - for (std::size_t i = 0; i < parser.error_count(); ++i) + for (unsigned int i = 0; i < parser.error_count(); ++i) { Parser::error_t error = parser.get_error(i); ss << "Error[" << i << "] Position: " << error.token.position @@ -249,7 +251,7 @@ bool MooseParser::CompileExpr() // map is auto symbTable = GetSymbolTable(); - vector> vars; + vector> vars; auto n = symbTable.get_variable_list(vars); ss << "More Information:\nTotal variables " << n << "."; for (auto i : vars) @@ -278,7 +280,7 @@ bool MooseParser::CompileExprWithUnknown(Function* func) // Get all symbols and create Variable() for them. Note that now the // previos symbol table and compiled expressions are invalid. auto symbTable = GetSymbolTable(); - vector> vars; + vector> vars; symbTable.get_variable_list(vars); // note: Don't clear the symbol table. Constants will also get cleared @@ -302,9 +304,9 @@ bool MooseParser::CompileExprWithUnknown(Function* func) res = parser.compile(expr_, expression_); if(! res) { - std::stringstream ss; + stringstream ss; ss << "Failed to parse '" << expr_ << "' :" << endl; - for (std::size_t i = 0; i < parser.error_count(); ++i) + for (unsigned int i = 0; i < parser.error_count(); ++i) { Parser::error_t error = parser.get_error(i); ss << "Error[" << i << "] Position: " << error.token.position @@ -313,7 +315,7 @@ bool MooseParser::CompileExprWithUnknown(Function* func) // map is auto symbTable = GetSymbolTable(); - vector> vars; + vector> vars; auto n = symbTable.get_variable_list(vars); ss << "More Information:\nTotal variables " << n << "."; for (auto i : vars) @@ -327,7 +329,7 @@ bool MooseParser::CompileExprWithUnknown(Function* func) } -double MooseParser::Derivative(const string& name, size_t nth) const +double MooseParser::Derivative(const string& name, unsigned int nth) const { if(nth > 3) { @@ -345,13 +347,13 @@ double MooseParser::Eval(bool check) const { if(! valid_) { - cout << "Warn: Invalid parser state." << endl; + cout << "MooseParser::Eval: Warn: Invalid parser state." << endl; return 0.0; } if(expr_.empty()) { - cout << "warn: Expr is empty " << endl; + cout << "MooseParser::Eval: warn: Expr is empty " << endl; return 0.0; } @@ -394,10 +396,10 @@ const string MooseParser::GetExpr( ) const void MooseParser::LinkVariables(vector& xs, vector& ys, double* t) { - for(size_t i = 0; i < xs.size(); i++) + for(unsigned int i = 0; i < xs.size(); i++) DefineVar('x'+to_string(i), xs[i]->ref()); - for (size_t i = 0; i < ys.size(); i++) + for (unsigned int i = 0; i < ys.size(); i++) DefineVar('y'+to_string(i), ys[i]); DefineVar("t", t); @@ -405,10 +407,10 @@ void MooseParser::LinkVariables(vector& xs, vector& ys, doub void MooseParser::LinkVariables(vector>& xs, vector>& ys, double* t) { - for(size_t i = 0; i < xs.size(); i++) + for(unsigned int i = 0; i < xs.size(); i++) DefineVar('x'+to_string(i), xs[i]->ref()); - for (size_t i = 0; i < ys.size(); i++) + for (unsigned int i = 0; i < ys.size(); i++) DefineVar('y'+to_string(i), ys[i].get()); DefineVar("t", t); diff --git a/builtins/MooseParser.h b/builtins/MooseParser.h index 9b8d22204a..fb7df13a21 100644 --- a/builtins/MooseParser.h +++ b/builtins/MooseParser.h @@ -64,8 +64,8 @@ class MooseParser /*----------------------------------------------------------------------------- * Set/Get *-----------------------------------------------------------------------------*/ - Parser::symbol_table_t& GetSymbolTable(const size_t nth=0); - const Parser::symbol_table_t& GetSymbolTable(const size_t nth=0) const; + Parser::symbol_table_t& GetSymbolTable(const unsigned int nth=0); + const Parser::symbol_table_t& GetSymbolTable(const unsigned int nth=0) const; /*----------------------------------------------------------------------------- * User interface. @@ -93,7 +93,7 @@ class MooseParser double Eval(bool check=false) const; - double Derivative(const string& name, size_t nth=1) const; + double Derivative(const string& name, unsigned int nth=1) const; double Diff( const double a, const double b) const; @@ -121,15 +121,14 @@ class MooseParser /* data */ string expr_; - double value=0.0; Parser::varmap_type const_map_; Parser::expression_t expression_; /* expression type */ - size_t num_user_defined_funcs_ = 0; + unsigned int num_user_defined_funcs_ = 0; - bool valid_; + bool valid_{false}; }; diff --git a/builtins/MooseSocketInfo.h b/builtins/MooseSocketInfo.h index 9e825eec3c..0e7f423dff 100644 --- a/builtins/MooseSocketInfo.h +++ b/builtins/MooseSocketInfo.h @@ -76,7 +76,7 @@ class MooseSocketInfo string filepath; string host; bool valid; - size_t port; + unsigned int port; }; diff --git a/builtins/Mstring.cpp b/builtins/Mstring.cpp index f19b805e1a..59c14f874b 100644 --- a/builtins/Mstring.cpp +++ b/builtins/Mstring.cpp @@ -11,61 +11,48 @@ const Cinfo* Mstring::initCinfo() { - ////////////////////////////////////////////////////////////// - // Field Definitions - ////////////////////////////////////////////////////////////// - static ValueFinfo< Mstring, string > thisFinfo( - "this", - "Access function for entire Mstring object.", - &Mstring::setThis, - &Mstring::getThis - ); - static ValueFinfo< Mstring, string > valueFinfo( - "value", - "Access function for value field of Mstring object," - "which happens also to be the entire contents of the object.", - &Mstring::setThis, - &Mstring::getThis - ); - - static Finfo* mStringFinfos[] = { - &thisFinfo, // Value - &valueFinfo, // Value - }; - - static Dinfo< Mstring > dinfo; - static Cinfo mStringCinfo ( - "Mstring", - Neutral::initCinfo(), - mStringFinfos, - sizeof( mStringFinfos ) / sizeof ( Finfo* ), - &dinfo - ); - - return &mStringCinfo; + ////////////////////////////////////////////////////////////// + // Field Definitions + ////////////////////////////////////////////////////////////// + static ValueFinfo thisFinfo( + "this", "Access function for entire Mstring object.", &Mstring::setThis, + &Mstring::getThis); + + static ValueFinfo valueFinfo( + "value", + "Access function for value field of Mstring object," + "which happens also to be the entire contents of the object.", + &Mstring::setThis, &Mstring::getThis); + + static Finfo* mStringFinfos[] = {&thisFinfo, // Value + &valueFinfo, // Value + }; + + static Dinfo dinfo; + static Cinfo mStringCinfo("Mstring", Neutral::initCinfo(), mStringFinfos, + sizeof(mStringFinfos) / sizeof(Finfo*), &dinfo); + + return &mStringCinfo; } static const Cinfo* mStringCinfo = Mstring::initCinfo(); -Mstring::Mstring() - : value_( "" ) +Mstring::Mstring() : value_("") { - ; + ; } -Mstring::Mstring( string val ) - : value_( val ) +Mstring::Mstring(string val) : value_(val) { - ; + ; } -void Mstring::setThis( string v ) +void Mstring::setThis(string v) { - value_ = v; + value_ = v; } string Mstring::getThis() const { - return value_; + return value_; } - diff --git a/builtins/Mstring.h b/builtins/Mstring.h index c667b3c15b..b716bf8831 100644 --- a/builtins/Mstring.h +++ b/builtins/Mstring.h @@ -9,31 +9,31 @@ #ifndef _M_STRING_H #define _M_STRING_H -class Mstring -{ - public: - Mstring(); - Mstring( string other ); - - //////////////////////////////////////////////////////////////// - // Field assignment stuff. - //////////////////////////////////////////////////////////////// - - void setThis( string v ); - string getThis() const; - - //////////////////////////////////////////////////////////////// - // Utility stuff - //////////////////////////////////////////////////////////////// - // const Mstring& operator=( const Mstring& other ); - // string operator=( const Mstring& other ); - // string operator=( const string& other ); - - //////////////////////////////////////////////////////////////// - - static const Cinfo* initCinfo(); - private: - string value_; +class Mstring { +public: + Mstring(); + Mstring(string other); + + //////////////////////////////////////////////////////////////// + // Field assignment stuff. + //////////////////////////////////////////////////////////////// + + void setThis(string v); + string getThis() const; + + //////////////////////////////////////////////////////////////// + // Utility stuff + //////////////////////////////////////////////////////////////// + // const Mstring& operator=( const Mstring& other ); + // string operator=( const Mstring& other ); + // string operator=( const string& other ); + + //////////////////////////////////////////////////////////////// + + static const Cinfo* initCinfo(); + +private: + string value_; }; -#endif // _M_STRING_H +#endif // _M_STRING_H diff --git a/builtins/NSDFWriter.cpp b/builtins/NSDFWriter.cpp index 16cd787b22..3148834f65 100644 --- a/builtins/NSDFWriter.cpp +++ b/builtins/NSDFWriter.cpp @@ -214,7 +214,7 @@ void NSDFWriter::sortOutUniformSources(const Eref& eref) for (unsigned int ii = 0; ii < func_.size(); ++ii){ string varname = func_[ii]; - size_t found = varname.find("get"); + unsigned int found = varname.find("get"); if (found == 0){ varname = varname.substr(3); if (varname.length() == 0){ @@ -285,7 +285,7 @@ void NSDFWriter::createUniformMap() sources[jj] = (char*)calloc(src_[ii->second[jj]].path().length()+1, sizeof(char)); strcpy(sources[jj],src_[ii->second[jj]].path().c_str()); } - hid_t ds = createStringDataset(container, fieldName, (hsize_t)ii->second.size(), (hsize_t)ii->second.size()); + hid_t ds = createStringDataset(container, fieldName, (hunsigned int)ii->second.size(), (hunsigned int)ii->second.size()); hid_t memtype = H5Tcopy(H5T_C_S1); status = H5Tset_size(memtype, H5T_VARIABLE); assert(status >= 0); @@ -376,7 +376,7 @@ void NSDFWriter::createEventMap() hid_t ftype = H5Tcreate(H5T_COMPOUND, sizeof(hvl_t) +sizeof(hobj_ref_t)); status = H5Tinsert(ftype, "source", 0, strtype); status = H5Tinsert(ftype, "data", sizeof(hvl_t), H5T_STD_REF_OBJ); - hsize_t dims[1] = {ii->second.size()}; + hunsigned int dims[1] = {ii->second.size()}; hid_t space = H5Screate_simple(1, dims, NULL); // The dataset for mapping is named after the field hid_t ds = H5Dcreate2(classGroup, fieldName.c_str(), ftype, space, @@ -388,7 +388,7 @@ void NSDFWriter::createEventMap() for (unsigned int jj = 0; jj < ii->second.size(); ++jj){ buf->source = ii->second[jj].c_str(); char * dsname = (char*)calloc(256, sizeof(char)); - ssize_t size = H5Iget_name(classFieldToEvent_[ii->first][jj], dsname, 255); + sunsigned int size = H5Iget_name(classFieldToEvent_[ii->first][jj], dsname, 255); if (size > 255){ free(dsname); dsname = (char*)calloc(size, sizeof(char)); @@ -477,15 +477,15 @@ void NSDFWriter::flush() if (filespace < 0){ break; } - hsize_t dims[2]; - hsize_t maxdims[2]; + hunsigned int dims[2]; + hunsigned int maxdims[2]; // retrieve current datset dimensions herr_t status = H5Sget_simple_extent_dims(filespace, dims, maxdims); - hsize_t newdims[] = {dims[0], dims[1] + steps_}; // new column count + hunsigned int newdims[] = {dims[0], dims[1] + steps_}; // new column count status = H5Dset_extent(it->second, newdims); // extend dataset to new column count H5Sclose(filespace); filespace = H5Dget_space(it->second); // get the updated filespace - hsize_t start[2] = {0, dims[1]}; + hunsigned int start[2] = {0, dims[1]}; dims[1] = steps_; // change dims for memspace & hyperslab hid_t memspace = H5Screate_simple(2, dims, NULL); H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, dims, NULL); diff --git a/builtins/SocketStreamer.cpp b/builtins/SocketStreamer.cpp index 38cbae5e09..502f3ca182 100644 --- a/builtins/SocketStreamer.cpp +++ b/builtins/SocketStreamer.cpp @@ -27,7 +27,7 @@ const Cinfo* SocketStreamer::initCinfo() /*----------------------------------------------------------------------------- * Finfos *-----------------------------------------------------------------------------*/ - static ValueFinfo< SocketStreamer, size_t > port( + static ValueFinfo< SocketStreamer, unsigned int > port( "port" , "Set port number for streaming. Valid only of TCP socket." , &SocketStreamer::setPort @@ -42,7 +42,7 @@ const Cinfo* SocketStreamer::initCinfo() , &SocketStreamer::getAddress ); - static ReadOnlyValueFinfo< SocketStreamer, size_t > numTables ( + static ReadOnlyValueFinfo< SocketStreamer, unsigned int > numTables ( "numTables" , "Number of Tables handled by SocketStreamer " , &SocketStreamer::getNumTables @@ -193,7 +193,7 @@ void SocketStreamer::addStringToDoubleVec(vector&res, const string s) * any more connections. */ /* ----------------------------------------------------------------------------*/ -void SocketStreamer::listenToClients(size_t numMaxClients) +void SocketStreamer::listenToClients(unsigned int numMaxClients) { assert(0 < sockfd_ ); assert( numMaxClients > 0 ); @@ -314,7 +314,7 @@ void SocketStreamer::initTCPServer( void ) /* ----------------------------------------------------------------------------*/ void SocketStreamer::dataToStream(map>& data) { - for( size_t i = 0; i < tables_.size(); i++) + for( unsigned int i = 0; i < tables_.size(); i++) { vector vec; tables_[i]->collectData(vec, true, false); @@ -359,7 +359,7 @@ int SocketStreamer::streamData( ) vecToStream_.insert(vecToStream_.end(), v.second.begin(), v.second.end()); } - size_t dtypeSize = sizeof(double); + unsigned int dtypeSize = sizeof(double); int sent = send(clientfd_, (void*) &vecToStream_[0], dtypeSize*vecToStream_.size(), MSG_MORE); LOG(moose::debug, "Sent " << sent << " bytes." ); if( sent < 0 ) @@ -370,10 +370,10 @@ int SocketStreamer::streamData( ) } -bool SocketStreamer::enoughDataToStream(size_t minsize) +bool SocketStreamer::enoughDataToStream(unsigned int minsize) { - for( size_t i = 0; i < tables_.size(); i++) - if(tables_[i]->getVec().size() >= minsize) + for( unsigned int i = 0; i < tables_.size(); i++) + if(tables_[i]->getVector().size() >= minsize) return true; return false; } @@ -443,7 +443,7 @@ void SocketStreamer::reinit(const Eref& e, ProcPtr p) thisDt_ = clk_->getTickDt( e.element()->getTick() ); // Push each table dt_ into vector of dt - for( size_t i = 0; i < tables_.size(); i++) + for( unsigned int i = 0; i < tables_.size(); i++) { Id tId = tableIds_[i]; int tickNum = tId.element()->getTick(); @@ -483,7 +483,7 @@ void SocketStreamer::process(const Eref& e, ProcPtr p) void SocketStreamer::addTable( ObjId table ) { // If this table is not already in the vector, add it. - for( size_t i = 0; i < tableIds_.size(); i++) + for( unsigned int i = 0; i < tableIds_.size(); i++) if( table.path() == tableIds_[i].path() ) return; /* Already added. */ @@ -522,7 +522,7 @@ void SocketStreamer::addTables( vector tables ) void SocketStreamer::removeTable( ObjId table ) { int matchIndex = -1; - for (size_t i = 0; i < tableIds_.size(); i++) + for (unsigned int i = 0; i < tableIds_.size(); i++) { if( table.path() == tableIds_[i].path() ) { @@ -554,18 +554,18 @@ void SocketStreamer::removeTables( vector tables ) * * @return Number of tables. */ -size_t SocketStreamer::getNumTables( void ) const +unsigned int SocketStreamer::getNumTables( void ) const { return tables_.size(); } -void SocketStreamer::setPort( const size_t port ) +void SocketStreamer::setPort( const unsigned int port ) { sockInfo_.port = port; } -size_t SocketStreamer::getPort( void ) const +unsigned int SocketStreamer::getPort( void ) const { return sockInfo_.port; } diff --git a/builtins/SocketStreamer.h b/builtins/SocketStreamer.h index 7e811c817b..901d4826de 100644 --- a/builtins/SocketStreamer.h +++ b/builtins/SocketStreamer.h @@ -74,10 +74,10 @@ class SocketStreamer : public StreamerBase void configureSocketServer( void ); // Make connection to client - void listenToClients(size_t numMaxClients); + void listenToClients(unsigned int numMaxClients); // Find minimum number of elements in tables. - pair minMaxNumberOfElemementsInTables( ); + pair minMaxNumberOfElemementsInTables( ); /* Cleaup before quitting */ void cleanUp( void ); @@ -85,19 +85,19 @@ class SocketStreamer : public StreamerBase string getAddress( void ) const; void setAddress( const string addr ); - size_t getPort( void ) const; - void setPort( const size_t port ); + unsigned int getPort( void ) const; + void setPort( const unsigned int port ); /*----------------------------------------------------------------------------- * Streaming data. *-----------------------------------------------------------------------------*/ - bool enoughDataToStream(size_t minsize=10); + bool enoughDataToStream(unsigned int minsize=10); int streamData(); // connect is monitored in a thread. void connect( void ); void stream(void); - size_t getNumTables( void ) const; + unsigned int getNumTables( void ) const; void addTable( ObjId table ); void addTables( vector tables); @@ -158,7 +158,7 @@ class SocketStreamer : public StreamerBase MooseSocketInfo sockInfo_; // How long it takes between process calls. - size_t processTickMicroSec; + unsigned int processTickMicroSec; std::chrono::high_resolution_clock::time_point timeStamp_; }; diff --git a/builtins/Streamer.cpp b/builtins/Streamer.cpp index ce8e144c14..c28aedd7f1 100644 --- a/builtins/Streamer.cpp +++ b/builtins/Streamer.cpp @@ -44,13 +44,13 @@ const Cinfo* Streamer::initCinfo() , &Streamer::getFormat ); - static ReadOnlyValueFinfo numTables ( + static ReadOnlyValueFinfo numTables ( "numTables" , "Number of Tables handled by Streamer " , &Streamer::getNumTables ); - static ReadOnlyValueFinfo numWriteEvents( + static ReadOnlyValueFinfo numWriteEvents( "numWriteEvents" , "Number of time streamer was called to write. (For debugging/performance reason only)" , &Streamer::getNumWriteEvents @@ -75,25 +75,25 @@ const Cinfo* Streamer::initCinfo() static DestFinfo addTable( "addTable" , "Add a table to Streamer" - , new OpFunc1( &Streamer::addTable ) + , new OpFunc1( &Streamer::addTable ) ); static DestFinfo addTables( "addTables" , "Add many tables to Streamer" - , new OpFunc1 >( &Streamer::addTables ) + , new OpFunc1 >( &Streamer::addTables ) ); static DestFinfo removeTable( "removeTable" , "Remove a table from Streamer" - , new OpFunc1( &Streamer::removeTable ) + , new OpFunc1( &Streamer::removeTable ) ); static DestFinfo removeTables( "removeTables" , "Remove tables -- if found -- from Streamer" - , new OpFunc1 >( &Streamer::removeTables ) + , new OpFunc1 >( &Streamer::removeTables ) ); /*----------------------------------------------------------------------------- @@ -182,7 +182,7 @@ void Streamer::reinit(const Eref& e, ProcPtr p) } Clock* clk = reinterpret_cast( Id(1).eref().data() ); - for (size_t i = 0; i < tableIds_.size(); i++) + for (unsigned int i = 0; i < tableIds_.size(); i++) { int tickNum = tableIds_[i].element()->getTick(); double tick = clk->getTickDt( tickNum ); @@ -203,7 +203,7 @@ void Streamer::reinit(const Eref& e, ProcPtr p) // Push each table dt_ into vector of dt - for( size_t i = 0; i < tables_.size(); i++) + for( unsigned int i = 0; i < tables_.size(); i++) { Id tId = tableIds_[i]; int tickNum = tId.element()->getTick(); @@ -212,7 +212,7 @@ void Streamer::reinit(const Eref& e, ProcPtr p) // Make sure all tables have same dt_ else disable the streamer. vector invalidTables; - for (size_t i = 1; i < tableTick_.size(); i++) + for (unsigned int i = 1; i < tableTick_.size(); i++) { if( tableTick_[i] != tableTick_[0] ) { @@ -227,7 +227,7 @@ void Streamer::reinit(const Eref& e, ProcPtr p) } } - for (size_t i = 0; i < invalidTables.size(); i++) + for (unsigned int i = 0; i < invalidTables.size(); i++) { tables_.erase( tables_.begin() + i ); tableDt_.erase( tableDt_.begin() + i ); @@ -280,10 +280,10 @@ void Streamer::process(const Eref& e, ProcPtr p) * * @param table Id of table. */ -void Streamer::addTable( Id table ) +void Streamer::addTable( ObjId table ) { // If this table is not already in the vector, add it. - for( size_t i = 0; i < tableIds_.size(); i++) + for( unsigned int i = 0; i < tableIds_.size(); i++) if( table.path() == tableIds_[i].path() ) return; /* Already added. */ @@ -306,11 +306,11 @@ void Streamer::addTable( Id table ) * * @param tables */ -void Streamer::addTables( vector tables ) +void Streamer::addTables( vector tables ) { if( tables.size() == 0 ) return; - for( vector::const_iterator it = tables.begin(); it != tables.end(); it++) + for(auto it = tables.begin(); it != tables.end(); it++) addTable( *it ); } @@ -320,10 +320,10 @@ void Streamer::addTables( vector tables ) * * @param table. Id of table. */ -void Streamer::removeTable( Id table ) +void Streamer::removeTable( ObjId table ) { int matchIndex = -1; - for (size_t i = 0; i < tableIds_.size(); i++) + for (unsigned int i = 0; i < tableIds_.size(); i++) if( table.path() == tableIds_[i].path() ) { matchIndex = i; @@ -343,9 +343,9 @@ void Streamer::removeTable( Id table ) * * @param tables */ -void Streamer::removeTables( vector tables ) +void Streamer::removeTables( vector tables ) { - for( vector::const_iterator it = tables.begin(); it != tables.end(); it++) + for(auto it = tables.cbegin(); it != tables.cend(); it++) removeTable( *it ); } @@ -354,7 +354,7 @@ void Streamer::removeTables( vector tables ) * * @return Number of tables. */ -size_t Streamer::getNumTables( void ) const +unsigned int Streamer::getNumTables( void ) const { return tables_.size(); } @@ -367,7 +367,7 @@ size_t Streamer::getNumTables( void ) const * @Returns */ /* ----------------------------------------------------------------------------*/ -size_t Streamer::getNumWriteEvents( void ) const +unsigned int Streamer::getNumWriteEvents( void ) const { return numWriteEvents_; } @@ -409,16 +409,16 @@ string Streamer::getFormat( void ) const */ void Streamer::zipWithTime( ) { - size_t numEntriesInEachTable = tables_[0]->getVecSize( ); + unsigned int numEntriesInEachTable = tables_[0]->getVecSize( ); //LOG( moose::debug, "Entries in each table " << numEntriesInEachTable ); // Collect data from all table. If some table does not have enough data, // fill it with nan vector< vector< double > > collectedData; - for( size_t i = 0; i < tables_.size( ); i++ ) + for( unsigned int i = 0; i < tables_.size( ); i++ ) { - vector tVec( tables_[i]->getVec( ) ); + vector tVec( tables_[i]->getVector( ) ); if( tVec.size( ) <= numEntriesInEachTable ) { #if 0 @@ -434,16 +434,16 @@ void Streamer::zipWithTime( ) // Turn it into a table format. Its like taking a transpose of vector< // vector >. double allTableDt = tableDt_[ 0 ]; - for( size_t i = 0; i < collectedData[0].size( ); i++ ) + for( unsigned int i = 0; i < collectedData[0].size( ); i++ ) { data_.push_back( currTime_ ); currTime_ += allTableDt; - for( size_t ii = 0; ii < collectedData.size(); ii++ ) + for( unsigned int ii = 0; ii < collectedData.size(); ii++ ) data_.push_back( collectedData[ ii ][ i ] ); } // After collection data from table, clear tables. - for(size_t i = 0; i < tables_.size(); i++ ) + for(unsigned int i = 0; i < tables_.size(); i++ ) tables_[i]->clearVec( ); return; diff --git a/builtins/Streamer.h b/builtins/Streamer.h index 34876332d7..e7c1edf7e2 100644 --- a/builtins/Streamer.h +++ b/builtins/Streamer.h @@ -48,14 +48,14 @@ class Streamer : public StreamerBase string getFormat( void ) const; void setFormat( string format ); - size_t getNumTables( void ) const; - size_t getNumWriteEvents( void ) const; + unsigned int getNumTables( void ) const; + unsigned int getNumWriteEvents( void ) const; - void addTable( Id table ); - void addTables( vector tables); + void addTable( ObjId table ); + void addTables( vector tables); - void removeTable( Id table ); - void removeTables( vector table ); + void removeTable( ObjId table ); + void removeTables( vector table ); void zipWithTime( ); @@ -76,7 +76,7 @@ class Streamer : public StreamerBase string datafilePath_; string format_; - size_t numWriteEvents_; + unsigned int numWriteEvents_; bool isOutfilePathSet_; @@ -89,7 +89,7 @@ class Streamer : public StreamerBase double currTime_; // Used for adding or removing tables - vector tableIds_; + vector tableIds_; vector tables_; vector columns_; diff --git a/builtins/StreamerBase.cpp b/builtins/StreamerBase.cpp index 53477407fc..e944ce8322 100644 --- a/builtins/StreamerBase.cpp +++ b/builtins/StreamerBase.cpp @@ -110,10 +110,10 @@ void StreamerBase::writeToCSVFile( const string& filepath, const OpenMode openmo } string text = ""; - for( size_t i = 0; i < data.size(); i+=columns.size() ) + for( unsigned int i = 0; i < data.size(); i+=columns.size() ) { // Start of a new row. - for( size_t ii = 0; ii < columns.size(); ii++ ) + for( unsigned int ii = 0; ii < columns.size(); ii++ ) text += moose::toString( data[i+ii] ) + delimiter_; // At the end of each row, we remove the delimiter_ and append newline_. diff --git a/builtins/Table.cpp b/builtins/Table.cpp index d36d564e23..1d353d741a 100644 --- a/builtins/Table.cpp +++ b/builtins/Table.cpp @@ -395,7 +395,7 @@ void Table::setFormat( string format ) else LOG( moose::warning , "Unsupported format " << format - << " only sv is supported" + << " only csv is supported for single table." ); } @@ -471,7 +471,7 @@ double Table::getDt( void ) const void Table::mergeWithTime( vector& data ) { auto v = vec(); - for (size_t i = 0; i < v.size(); i++) + for (unsigned int i = 0; i < v.size(); i++) { data.push_back(tvec_[i]); data.push_back(v[i]); @@ -492,7 +492,7 @@ string Table::toJSON(bool withTime, bool clear) if( clear ) lastN_ = 0; - for (size_t i = lastN_; i < v.size(); i++) + for (unsigned int i = lastN_; i < v.size(); i++) { if(withTime) ss << '[' << tvec_[i] << ',' << v[i] << "],"; @@ -527,7 +527,7 @@ void Table::collectData(vector& data, bool withTime, bool clear) if( clear ) lastN_ = 0; - for (size_t i = lastN_; i < v.size(); i++) + for (unsigned int i = lastN_; i < v.size(); i++) { if(withTime) data.push_back(tvec_[i]); diff --git a/builtins/Table.h b/builtins/Table.h index ff1edbb3fd..3efa30a198 100644 --- a/builtins/Table.h +++ b/builtins/Table.h @@ -95,7 +95,7 @@ class Table: public TableBase // Upto which indices we have read the data. This variable is used when // SocketStreamer is used. - size_t lastN_ = 0; + unsigned int lastN_ = 0; string tablePath_; diff --git a/builtins/TableBase.cpp b/builtins/TableBase.cpp index c0976bc2de..cf20f42c2e 100644 --- a/builtins/TableBase.cpp +++ b/builtins/TableBase.cpp @@ -8,7 +8,9 @@ **********************************************************************/ #include "../basecode/header.h" + #include + #include "../utility/strutil.h" #include "TableBase.h" @@ -20,8 +22,8 @@ const Cinfo* TableBase::initCinfo() static ValueFinfo< TableBase, vector< double > > vec( "vector", "vector with all table entries", - &TableBase::setVec, - &TableBase::getVec + &TableBase::setVector, + &TableBase::getVector ); static ValueFinfo< TableBase, string > plotDump( @@ -201,7 +203,7 @@ bool isNamedPlot( const string& line, const string& plotname ) if ( line[0] == '/' && line[1] == 'p' ) { string name = line.substr( strlen( "/plotname" ) ); - string::size_type pos = name.find_first_not_of( " " ); + auto pos = name.find_first_not_of( " " ); if ( pos == string::npos ) { cout << "TableBase::loadXplot: Malformed plotname line '" << @@ -507,12 +509,12 @@ unsigned int TableBase::getVecSize() const return vec_.size(); } -vector< double > TableBase::getVec() const +vector< double > TableBase::getVector() const { return vec_; } -void TableBase::setVec( vector< double > val ) +void TableBase::setVector( vector< double > val ) { vec_ = val; } @@ -537,7 +539,7 @@ string TableBase::getPlotDump() const void TableBase::setPlotDump( string v ) { - std::size_t pos = v.rfind(" "); + auto pos = v.rfind(" "); string fname = v.substr( 0, pos ); string plotname = "plot"; if ( pos != string::npos ) diff --git a/builtins/TableBase.h b/builtins/TableBase.h index d04389711a..9a107bc2f5 100644 --- a/builtins/TableBase.h +++ b/builtins/TableBase.h @@ -24,10 +24,11 @@ class TableBase /*----------------------------------------------------------------------------- * Functions related to field assignment. *-----------------------------------------------------------------------------*/ - vector< double > getVec() const; + vector< double > getVector() const; + const vector< double >& data( ); - void setVec( vector< double > val ); + void setVector( vector< double > val ); double getOutputValue() const; void setOutputValue( double val ); diff --git a/builtins/testBuiltins.cpp b/builtins/testBuiltins.cpp index d94f4ecf77..d8c0d26a90 100644 --- a/builtins/testBuiltins.cpp +++ b/builtins/testBuiltins.cpp @@ -257,7 +257,9 @@ void testTable() for ( unsigned int i = 0; i < 100; ++i ) { t->input( sqrt((double) i ) ); } + vector< double > values = Field< vector< double > >::get( tabid, "vector"); + assert( values.size() == 100 ); for ( unsigned int i = 0; i < 100; ++i ) { double ret = LookupField< unsigned int, double >::get( tabid, "y", i ); diff --git a/builtins/testNSDF.cpp b/builtins/testNSDF.cpp index 9c40f8ec73..8e84e774de 100644 --- a/builtins/testNSDF.cpp +++ b/builtins/testNSDF.cpp @@ -70,7 +70,7 @@ void testCreateStringDataset() { const char * data[STR_DSET_LEN] = {"You have to", "live", "life", "to the limit"}; hid_t file, memtype, dset; - hsize_t size = STR_DSET_LEN; + hunsigned int size = STR_DSET_LEN; herr_t status; HDF5WriterBase writer; string h5Filename = moose::random_string( 10 ); diff --git a/devel/CMakeLists.txt b/devel/CMakeLists.txt index 4ea7b7fa8f..73b8f0cd82 100644 --- a/devel/CMakeLists.txt +++ b/devel/CMakeLists.txt @@ -12,3 +12,9 @@ add_custom_target(centos COMMENT "Building moose on centos" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} VERBATIM) + +add_custom_target(gitlab + COMMAND gitlab-runner exec docker build + COMMENT "Replicating gitlab build using Docker." + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + VERBATIM) diff --git a/devel/Doxyfile.in b/devel/Doxyfile.in new file mode 100644 index 0000000000..ff855db5d9 --- /dev/null +++ b/devel/Doxyfile.in @@ -0,0 +1,2280 @@ +# Doxyfile 1.8.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "MOOSE" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = @MOOSE_VERSION@ + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is included in +# the documentation. The maximum height of the logo should not exceed 55 pixels +# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo +# to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/docs + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese- +# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en, +# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# Turkish, Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a +# new page for each member. If set to NO, the documentation of a member will be +# part of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. +# +# Note For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO these classes will be included in the various overviews. This option has +# no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the +# todo list. This list is created by putting \todo commands in the +# documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the +# test list. This list is created by putting \test commands in the +# documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES the list +# will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. Do not use file names with spaces, bibtex cannot handle them. See +# also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO doxygen will only warn about wrong or incomplete parameter +# documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. +# Note: If this tag is empty the current directory is searched. + +INPUT = @CMAKE_SOURCE_DIR@ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank the +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, +# *.qsf, *.as and *.js. + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = */external/* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER ) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- +# defined cascading style sheet that is included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefor more robust against future updates. +# Doxygen will copy the style sheet file to the output directory. For an example +# see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the stylesheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated ( +# YES) or that it should be included in the master .chm file ( NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated ( +# YES) or a normal table of contents ( NO) in the .chm file. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /