diff --git a/OASIS_matlab b/OASIS_matlab
index 5cafa3b..0a1251f 160000
--- a/OASIS_matlab
+++ b/OASIS_matlab
@@ -1 +1 @@
-Subproject commit 5cafa3b0d1fb9bb1a61b951d5a65db9ef3dd5767
+Subproject commit 0a1251f41b5999899d34a1a7fa5e04b5c7729972
diff --git a/deconvolveCa/LICENSE b/deconvolveCa/LICENSE
deleted file mode 100644
index 9cecc1d..0000000
--- a/deconvolveCa/LICENSE
+++ /dev/null
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- {one line to give the program's name and a brief idea of what it does.}
- Copyright (C) {year} {name of author}
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- {project} Copyright (C) {year} {fullname}
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-.
diff --git a/deconvolveCa/MCMC/.gitignore b/deconvolveCa/MCMC/.gitignore
deleted file mode 100644
index 70d86e5..0000000
--- a/deconvolveCa/MCMC/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-
-*.m~
-
-*.m~
diff --git a/deconvolveCa/MCMC/README.md b/deconvolveCa/MCMC/README.md
deleted file mode 100644
index df9e158..0000000
--- a/deconvolveCa/MCMC/README.md
+++ /dev/null
@@ -1,47 +0,0 @@
-[![Join the chat at https://gitter.im/epnev/ca_source_extraction](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/epnev/ca_source_extraction?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-MCMC spike inference in continuous time
-==========================
-
-The code takes as an input a time series vector of calcium observations
-and produces samples from the posterior distribution of the underlying
-spike in continuous time. The code also samples the model parameters
-(baseline, spike amplitude, initial calcium concentration, firing rate,
-noise variance) and also iteratively re-estimates the discrete time
-constant of the model. More info can be found at
-
-Pnevmatikakis, E., Merel, J., Pakman, A. & Paninski, L. (2014).
-Bayesian spike inference from calcium imaging data. Asilomar Conf. on
-Signals, Systems, and Computers. http://arxiv.org/abs/1311.6864
-
-For initializing the MCMC sampler, the algorithm uses the constrained deconvolution method maintained separately in https://github.com/epnev/constrained-foopsi
-
-### Contributors
-
-Eftychios A. Pnevmatikakis, Simons Foundation
-
-John Merel, Columbia University
-
-### Contact
-
-For questions join the chat room (see the button above) or open an issue (for bugs etc).
-
-### Acknowledgements
-
-Special thanks to Tim Machado for providing the demo dataset.
-
-License
-=======
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
diff --git a/deconvolveCa/MCMC/cont_ca_sampler.m b/deconvolveCa/MCMC/cont_ca_sampler.m
deleted file mode 100644
index fd21254..0000000
--- a/deconvolveCa/MCMC/cont_ca_sampler.m
+++ /dev/null
@@ -1,420 +0,0 @@
-function SAMPLES = cont_ca_sampler(Y,params)
-
-% MCMC continuous time sampler of spiketimes given a fluorescence trace Y
-
-% Inputs:
-% Y data
-% params parameters structure
-% params.g discrete time constant(s) (estimated if not provided)
-% params.sn initializer for noise (estimated if not provided)
-% params.b initializer for baseline (estimated if not provided)
-% params.c1 initializer for initial concentration (estimated if not provided)
-% params.Nsamples number of samples after burn in (default 500)
-% params.B number of burn in samples (default 200)
-% params.marg flag for marginalized sampler for baseline and initial concentration (default 0)
-% params.upd_gam flag for updating gamma (default 1)
-% params.gam_step number of samples after which gamma is updated (default 50)
-% params.std_move standard deviation of shifting kernel (default 3*Dt)
-% params.add_move number of add moves per iteration (default T/100)
-% params.init initial sample
-% params.f imaging rate (default 1)
-% params.p order of AR model (p == 1 or p == 2, default 1)
-% params.defg default discrete time constants in case constrained_foopsi cannot find stable estimates
-% params.TauStd standard deviation for time constants in continuous time (default [0.2,2])
-% params.A_lb lower bound for spike amplitude (default 0.1*range(Y))
-% params.b_lb lower bound for baseline (default 0.01 quantile of Y)
-% params.c1_lb lower bound for initial value (default 0)
-
-% output struct SAMPLES
-% ss Nsamples x 1 cells with spike times for each sample
-% ns Nsamples x 1 vector with number of spikes
-% Am Nsamples x 1 vector with samples for spike amplitude
-% ld Nsamples x 1 vector with samples for firing rate
-
-% If marginalized sampler is used (params.marg = 1)
-% Cb posterior mean and sd for baseline
-% Cin posterior mean and sd for initial condition
-% else
-% Cb Nsamples x 1 vector with samples for baseline
-% Cin Nsamples x 1 vector with samples for initial concentration
-% sn Nsamples x 1 vector with samples for noise variance
-
-% If gamma is updated (params.upd_gam = 1)
-% g Nsamples x p vector with the gamma updates
-
-% Author: Eftychios A. Pnevmatikakis and Josh Merel
-
-% Reference: Pnevmatikakis et al., Bayesian spike inference from calcium
-% imaging data, Asilomar 2013.
-
-Y = Y(:);
-T = length(Y);
-isanY = ~isnan(Y); % Deal with possible missing entries
-E = speye(T);
-E = E(isanY,:);
-
-% define default parameters
-defparams.g = []; % initializer for time constants
-defparams.sn = []; % initializer for noise std
-defparams.b = []; % initializer for baseline concentration
-defparams.c1 = []; % initializer for initial concentration
-defparams.c = []; % initializer for calcium concentration
-defparams.sp = []; % initializer for spiking signal
-defparams.bas_nonneg = 0; % allow negative baseline during initialization
-defparams.Nsamples = 400; % number of samples after burn in period
-defparams.B = 200; % length of burn in period
-defparams.marg = 0; % flag to marginalize out baseline and initial concentration
-defparams.upd_gam = 1; % flag for updating time constants
-defparams.gam_step = 1; % flag for how often to update time constants
-defparams.A_lb = 0.1*range(Y); % lower bound for spike amplitude
-defparams.b_lb = quantile(Y,0.01); % lower bound for baseline
-defparams.c1_lb = 0; % lower bound for initial concentration
-
-defparams.std_move = 3; % standard deviation of spike move kernel
-defparams.add_move = ceil(T/100); % number of add moves
-defparams.init = []; % sampler initializer
-defparams.f = 1; % imaging rate (irrelevant)
-defparams.p = 1; % order of AR process (use p = 1 or p = 2)
-defparams.defg = [0.6,0.95]; % default time constant roots
-defparams.TauStd = [.2,2]; % Standard deviation for time constant proposal
-defparams.prec = 1e-2; % Precision parameter when adding new spikes
-defparams.con_lam = true; % Flag for constant firing across time
-defparams.print_flag = 0;
-
-if nargin < 2
- params = defparams;
-else
- if ~isfield(params,'g'); params.g = defparams.g; end
- if ~isfield(params,'sn'); params.sn = defparams.sn; end
- if ~isfield(params,'b'); params.b = defparams.b; end
- if ~isfield(params,'c1'); params.c1 = defparams.c1; end
- if ~isfield(params,'c'); params.c = defparams.c; end
- if ~isfield(params,'sp'); params.sp = defparams.sp; end
- if ~isfield(params,'bas_nonneg'); params.bas_nonneg = defparams.bas_nonneg; end
- if ~isfield(params,'Nsamples'); params.Nsamples = defparams.Nsamples; end
- if ~isfield(params,'B'); params.B = defparams.B; end
- if ~isfield(params,'marg'); params.marg = defparams.marg; end
- if ~isfield(params,'upd_gam'); params.upd_gam = defparams.upd_gam; end
- if ~isfield(params,'gam_step'); params.gam_step = defparams.gam_step; end
- if ~isfield(params,'std_move'); params.std_move = defparams.std_move; end
- if ~isfield(params,'add_move'); params.add_move = defparams.add_move; end
- if ~isfield(params,'init'); params.init = defparams.init; end
- if ~isfield(params,'f'); params.f = defparams.f; end
- if ~isfield(params,'p'); params.p = defparams.p; end
- if ~isfield(params,'defg'); params.defg = defparams.defg; end
- if ~isfield(params,'TauStd'); params.TauStd = defparams.TauStd; end
- if ~isfield(params,'A_lb'); params.A_lb = defparams.A_lb; end
- if ~isfield(params,'b_lb'); params.b_lb = defparams.b_lb; end
- if ~isfield(params,'c1_lb'); params.c1_lb = defparams.c1_lb; end
- if ~isfield(params,'prec'); params.prec = defparams.prec; end
- if ~isfield(params,'con_lam'); params.con_lam = defparams.con_lam; end
- if ~isfield(params,'print_flag'); params.print_flag = defparams.print_flag; end
-end
-
-Dt = 1; % length of time bin
-
-marg_flag = params.marg;
-gam_flag = params.upd_gam;
-gam_step = params.gam_step;
-std_move = params.std_move;
-add_move = params.add_move;
-
-if isempty(params.init)
- params.init = get_initial_sample(Y,params);
-end
-SAM = params.init;
-
-if isempty(params.g)
- p = params.p;
-else
- p = length(params.g); % order of autoregressive process
-end
-
-g = SAM.g(:)'; % check initial time constants, if not reasonable set to default values
-
-if g == 0
- gr = params.defg;
- pl = poly(gr);
- g = -pl(2:end);
- p = 2;
-end
-gr = sort(roots([1,-g(:)']));
-if p == 1; gr = [0,max(gr)]; end
-if any(gr<0) || any(~isreal(gr)) || length(gr)>2 || max(gr)>0.998
- gr = params.defg;
-end
-tau = -Dt./log(gr);
-tau1_std = max(tau(1)/100,params.TauStd(1));
-tau2_std = min(tau(2)/5,params.TauStd(2));
-ge = max(gr).^(0:T-1)';
-if p == 1
- G1 = sparse(1:T,1:T,Inf*ones(T,1));
-elseif p == 2
- G1 = spdiags(ones(T,1)*[-min(gr),1],[-1:0],T,T);
-else
- error('This order of the AR process is currently not supported');
-end
-G2 = spdiags(ones(T,1)*[-max(gr),1],[-1:0],T,T);
-
-sg = SAM.sg;
-
-spiketimes_ = SAM.spiketimes_;
-lam_ = SAM.lam_;
-A_ = SAM.A_*diff(gr);
-b_ = max(SAM.b_,prctile(Y,8));
-C_in = max(min(SAM.C_in,Y(1)-b_),0);
-
-s_1 = zeros(T,1);
-s_2 = zeros(T,1);
-s_1(ceil(spiketimes_/Dt)) = exp((spiketimes_ - Dt*ceil(spiketimes_/Dt))/tau(1));
-s_2(ceil(spiketimes_/Dt)) = exp((spiketimes_ - Dt*ceil(spiketimes_/Dt))/tau(2));
-
-prec = params.prec;
-
-ef_d = exp(-(0:T)/tau(2)); % construct transient exponentials
-if p == 1
- h_max = 1; % max value of transient
- ef_h = [0,0];
- e_support = find(ef_dT*Dt) = 2*T*Dt - spiketimes(spiketimes>T*Dt);
- spiketimes_ = spiketimes;
- trunc_spikes = ceil(spiketimes/Dt);
- trunc_spikes(trunc_spikes == 0) = 1;
- s_1 = zeros(T,1);
- s_2 = zeros(T,1);
- s_1(trunc_spikes) = exp((spiketimes_ - Dt*trunc_spikes)/tau(1));
- s_2(trunc_spikes) = exp((spiketimes_ - Dt*trunc_spikes)/tau(2));
- if p == 1; G1sp = zeros(T,1); else G1sp = G1\s_1(:); end
- Gs = (-G1sp+G2\s_2(:))/diff(gr);
-
- %s_ = s_2 - s_1 - min(gr)*[0;s_2(1:end-1)] + max(gr)*[0;s_1(1:end-1)];
- %Gs = filter(1,[1,-sum(gr),prod(gr)]',s_/diff(gr));
-
- ss{i} = spiketimes;
- nsp = length(spiketimes);
- ns(i) = nsp;
- lam(i) = nsp/(T*Dt);
- lam_ = lam(i);
-
- AM = [Gs,ones(T,1),ge];
- EAM = E*AM;
- L = inv(Ld + EAM'*EAM/sg^2);
- mu_post = (Ld + EAM'*EAM/sg^2)\(EAM'*Y(isanY)/sg^2 + Sp\mu);
- if ~marg_flag
- x_in = [A_;b_;C_in];
- if any(x_in <= lb)
- x_in = max(x_in,(1+0.1*sign(lb)).*lb) + 1e-5;
- end
- if all(isnan(L(:))) % FN added to avoid error in R = chol(L) in HMC_exact2 due to L not being positive definite. It happens when isnan(det(Ld + AM'*AM/sg^2)), ie when Ld + AM'*AM/sg^2 is singular (not invertible).
- Am(i) = NaN;
- Cb(i) = NaN;
- Cin(i) = NaN';
- else
- [temp,~] = HMC_exact2(eye(3), -lb, L, mu_post, 1, Ns, x_in);
- Am(i) = temp(1,Ns);
- Cb(i) = temp(2,Ns);
- Cin(i) = temp(3,Ns)';
- end
- A_ = Am(i);
- b_ = Cb(i);
- C_in = Cin(i);
-
- Ym = Y - b_ - ge*C_in;
- res = Ym - A_*Gs;
- sg = 1./sqrt(gamrnd(1+length(isanY)/2,1/(0.1 + sum((res(isanY).^2)/2))));
- SG(i) = sg;
- else
- repeat = 1;
- cnt = 0;
- while repeat
- A_ = mu_post(1) + sqrt(L(1,1))*randn;
- repeat = (A_<0);
- cnt = cnt + 1;
- if cnt > 1e3
- error('The marginalized sampler cannot find a valid amplitude value. Set params.marg = 0 and try again.')
- end
- end
- Am(i) = A_;
- if i > B
- mub = mub + mu_post(2:3); %mu_post(1+(1:p));
- Sigb = Sigb + L(2:3,2:3); %L(1+(1:p),1+(1:p));
- end
- end
- if gam_flag
- if mod(i-B,gam_step) == 0 % update time constants
- if p >= 2 % update rise time constant
- logC = -norm(Y(isanY) - EAM*[A_;b_;C_in])^2;
- tau_ = tau;
- tau_temp = tau_(1)+(tau1_std*randn);
- while tau_temp >tau(2) || tau_temptau_max || tau_temp
- Copyright (C)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- , 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/deconvolveCa/MCMC/plot_continuous_samples.m b/deconvolveCa/MCMC/plot_continuous_samples.m
deleted file mode 100644
index 52a832a..0000000
--- a/deconvolveCa/MCMC/plot_continuous_samples.m
+++ /dev/null
@@ -1,143 +0,0 @@
-function plot_continuous_samples(SAMPLES,Y)
-
-% plot results of MCMC sampler
-% The mean calcium sample, spike sampler raster plot and samples for
-% amplitude, number of spikes, discrete time constants, noise variance,
-% baseline and initial concentration are generated, together with their
-% autocorrelation functions. If the marginalized flag was used, then the
-% posterior pdfs of baseline and initial concentration are plotted.
-
-% Inputs:
-% SAMPLES: structure with SAMPLES obtained from cont_ca_sampler.m
-% Y: inpurt fluorescence trace
-
-% Author: Eftychios A. Pnevmatikakis, 2016, Simons Foundation
-
-T = length(Y);
-N = length(SAMPLES.ns);
-show_gamma = 1;
-P = SAMPLES.params;
-P.f = 1;
-g = P.g(:);
-p = min(length(g),2);
-Dt = 1/P.f; % length of time bin
-if ~isfield(SAMPLES,'g');
- show_gamma = 0;
- SAMPLES.g = ones(N,1)*g';
-end
-
-if p == 1
- tau_1 = 0;
- tau_2 = -Dt/log(g); % continuous time constant
- G1 = speye(T);
- G2 = spdiags(ones(T,1)*[-g,1],[-1:0],T,T);
- ge = P.g.^((0:T-1)');
-elseif p == 2
- gr = roots([1,-g']);
- p1_continuous = log(min(gr))/Dt;
- p2_continuous = log(max(gr))/Dt;
- tau_1 = -1/p1_continuous; %tau h - smaller (tau_d * tau_r)/(tau_d + tau_r)
- tau_2 = -1/p2_continuous; %tau decay - larger
- G1 = spdiags(ones(T,1)*[-min(gr),1],[-1:0],T,T);
- G2 = spdiags(ones(T,1)*[-max(gr),1],[-1:0],T,T);
- ge = G2\[1;zeros(T-1,1)];
-else
- error('This order of the AR process is currently not supported');
-end
-
-
-if length(SAMPLES.Cb) == 2
- marg = 1; % marginalized sampler
-else
- marg = 0; % full sampler
-end
-
-C_rec = zeros(N,T);
-for rep = 1:N
- %trunc_spikes = ceil(SAMPLES.ss{rep}/Dt);
- tau = SAMPLES.g(rep,:);
- gr = exp(-1./tau);
- ge = max(gr).^(0:T-1)';
- s_1 = sparse(ceil(SAMPLES.ss{rep}/Dt),1,exp((SAMPLES.ss{rep} - Dt*ceil(SAMPLES.ss{rep}/Dt))/tau(1)),T,1);
- s_2 = sparse(ceil(SAMPLES.ss{rep}/Dt),1,exp((SAMPLES.ss{rep} - Dt*ceil(SAMPLES.ss{rep}/Dt))/tau(2)),T,1);
- if gr(1) == 0
- G1 = sparse(1:T,1:T,Inf*ones(T,1)); G1sp = zeros(T,1);
- else
- G1 = spdiags(ones(T,1)*[-min(gr),1],[-1:0],T,T); G1sp = G1\s_1(:);
- end
- G2 = spdiags(ones(T,1)*[-max(gr),1],[-1:0],T,T);
- Gs = (-G1sp+ G2\s_2(:))/diff(gr);
- if marg
- %C_rec(rep,:) = SAMPLES.Cb(1) + SAMPLES.Am(rep)*filter(1,[1,-SAMPLES.g(rep,:)],full(s_)+[SAMPLES.Cin(:,1)',zeros(1,T-p)]);
- C_rec(rep,:) = SAMPLES.Cb(1) + SAMPLES.Am(rep)*Gs + (ge*SAMPLES.Cin(:,1));
- else
- %C_rec(rep,:) = SAMPLES.Cb(rep) + SAMPLES.Am(rep)*filter(1,[1,-SAMPLES.g(rep,:)],full(s_)+[SAMPLES.Cin(rep,:),zeros(1,T-p)]);
- C_rec(rep,:) = SAMPLES.Cb(rep) + SAMPLES.Am(rep)*Gs + (ge*SAMPLES.Cin(rep,:)');
- end
-end
-Nc = 60;
-
-if marg
- rows = 4;
-else
- rows = 5;
-end
-
-figure;
- set(gcf, 'PaperUnits', 'inches','Units', 'inches')
- set(gcf, 'PaperPositionMode', 'manual')
- set(gcf, 'PaperPosition',[0,0, 14, 15])
- set(gcf, 'Position',[2,2, 14, 15])
- ha(1) = subplot(rows,4,[1:4]);plot(Dt*(1:T),Y); hold all; plot(Dt*(1:T),mean(C_rec,1),'linewidth',2);
- title('Calcium traces','fontweight','bold','fontsize',14)
- legend('Raw data','Mean sample');
- ha(2) = subplot(rows,4,[5:8]); imagesc((1:T)*Dt,1:N,samples_cell2mat(SAMPLES.ss,T));
- title('Spike raster plot','fontweight','bold','fontsize',14)
- linkaxes(ha,'x');
- subplot(rows,4,4+5); plot(1:N,SAMPLES.ns); title('# of spikes','fontweight','bold','fontsize',14)
- subplot(rows,4,4+6); plot(-Nc:Nc,xcov(SAMPLES.ns,Nc,'coeff')); set(gca,'XLim',[-Nc,Nc]);
- title('Autocorrelation','fontweight','bold','fontsize',14)
-
- if ~show_gamma
- subplot(rows,4,4+7); plot(1:N,SAMPLES.ld); title('Firing Rate','fontweight','bold','fontsize',14)
- subplot(rows,4,4+8); plot(-Nc:Nc,xcov(SAMPLES.ld,Nc,'coeff')); set(gca,'XLim',[-Nc,Nc])
- title('Autocorrelation','fontweight','bold','fontsize',14)
- else
- if gr(1) == 0
- subplot(rows,4,4+7); plot(1:N,exp(-1./SAMPLES.g(:,2))); title('Decay Time Constant','fontweight','bold','fontsize',14);
- subplot(rows,4,4+8); plot(-Nc:Nc,xcov(exp(-1./SAMPLES.g(:,2)),Nc,'coeff')); title('Autocorrelation','fontweight','bold','fontsize',14);
- set(gca,'XLim',[-Nc,Nc])
- else
- subplot(rows,4,4+7); plot(1:N,exp(-1./SAMPLES.g)); title('Decay Time Constants','fontweight','bold','fontsize',14);
- g_cov = xcov(exp(-1./SAMPLES.g),Nc,'coeff');
- subplot(rows,4,4+8); plot(-Nc:Nc,g_cov(:,[1,4])); title('Autocorrelation','fontweight','bold','fontsize',14);
- set(gca,'XLim',[-Nc,Nc])
- end
- end
-
- subplot(rows,4,4+9); plot(1:N,SAMPLES.Am); title('Spike Amplitude','fontweight','bold','fontsize',14)
- subplot(rows,4,4+10); plot(-Nc:Nc,xcov(SAMPLES.Am,Nc,'coeff')); set(gca,'XLim',[-Nc,Nc])
- title('Autocorrelation','fontweight','bold','fontsize',14)
- if marg
- xx = SAMPLES.Cb(1) + linspace(-4*SAMPLES.Cb(2),4*SAMPLES.Cb(2));
- subplot(4,4,15); plot(xx,normpdf(xx,SAMPLES.Cb(1),SAMPLES.Cb(2)));
- set(gca,'XLim',[xx(1),xx(end)])
- title('Marg. post. of baseline','fontweight','bold','fontsize',14)
-
- xx = SAMPLES.Cin(1) + linspace(-4*SAMPLES.Cin(2),4*SAMPLES.Cin(2));
- subplot(4,4,16); plot(xx,normpdf(xx,SAMPLES.Cin(1),SAMPLES.Cin(2)));
- set(gca,'XLim',[xx(1),xx(end)])
- title('Marg. post. of initial con','fontweight','bold','fontsize',14)
- else
- subplot(5,4,4+11); plot(1:N,SAMPLES.Cb); title('Baseline','fontweight','bold','fontsize',14)
- subplot(5,4,4+12); plot(-Nc:Nc,xcov(SAMPLES.Cb,Nc,'coeff')); set(gca,'XLim',[-Nc,Nc])
- title('Autocorrelation','fontweight','bold','fontsize',14)
- subplot(5,4,4+13); plot(1:N,SAMPLES.Cin); title('Initial Concentration','fontweight','bold','fontsize',14)
- xcov_Cin = xcov(SAMPLES.Cin,Nc,'coeff');
- subplot(5,4,4+14); plot(-Nc:Nc,xcov_Cin); set(gca,'XLim',[-Nc,Nc])
- title('Autocorrelation','fontweight','bold','fontsize',14)
- subplot(5,4,4+15); plot(1:N,SAMPLES.sn2); title('Noise variance','fontweight','bold','fontsize',14)
- subplot(5,4,4+16); plot(-Nc:Nc,xcov(SAMPLES.sn2,Nc,'coeff')); set(gca,'XLim',[-Nc,Nc])
- title('Autocorrelation','fontweight','bold','fontsize',14)
- end
- drawnow;
\ No newline at end of file
diff --git a/deconvolveCa/MCMC/sampling_demo_ar2.m b/deconvolveCa/MCMC/sampling_demo_ar2.m
deleted file mode 100644
index 43c885e..0000000
--- a/deconvolveCa/MCMC/sampling_demo_ar2.m
+++ /dev/null
@@ -1,64 +0,0 @@
-% creating a demo for the MCMC sampler
-
-clearvars;
-addpath utilities
-dt = 1e-1; % Data is generated with provided dt but sampled with Dt = 1
-T = 7000;
-ld = 0.05; % rate spikes per second
-
-s = rand(1,round(T/dt)) < ld*dt;
-tau_rise = 2;
-tau_decay = 10;
-hmax = tau_decay/(tau_decay+tau_rise)*(tau_rise/(tau_decay+tau_rise))^(tau_rise/tau_decay);
-[g,h1] = tau_c2d(tau_rise,tau_decay,dt);
-
-b = hmax/4; % baseline value
-cin = [.2*b,.15*b]; % initial concentration
-c = [cin,filter(h1,[1,-g],s(3:end),filtic(h1,[1,-g],cin))] + b; % true calcium at original resolution
-c_true = c(round(1/dt):round(1/dt):round(T/dt)); % true calcium at sampled resolution
-sg = hmax/4; % noise level
-y = c_true + sg*randn(1,length(c_true)); % noisy observations
-
-figure;subplot(2,1,1); plot(dt:dt:T,c); hold all; scatter(1:T,y,'r*');
- legend('True Calcium','Observed Values');
-
-%% Run constrained deconvolution approach (constrained foopsi)
-
-[g2,h2] = tau_c2d(tau_rise,tau_decay,1); % generate discrete time constants
-
-[ca_foopsi,cb,c1,~,~,spikes_foopsi] = constrained_foopsi(y,[],[],g2);
-
-% do some plotting
-spiketimes{1} = find(s)*dt;
-spikeRaster = samples_cell2mat(spiketimes,T,1);
-f = find(spikeRaster);
-spikes = zeros(sum(spikeRaster),2);
-count = 0;
-for cnt = 1:length(f)
- spikes(count+(1:spikeRaster(f(cnt))),1) = f(cnt);
- spikes(count+(1:spikeRaster(f(cnt))),2) = 0.95 + 0.025*max(spikes_foopsi)*(1:spikeRaster(f(cnt)));
- count = count + spikeRaster(f(cnt));
-end
-
-subplot(2,1,2);
-stem(spikes_foopsi); hold all;
- scatter(spikes(:,1),spikes(:,2)-0.95+max(spikes_foopsi),15,'magenta','filled');
- axis([1,T,0,max(spikes(:,2))-0.95+max(spikes_foopsi)]);
- title('Foopsi Spikes','FontWeight','bold','Fontsize',14); xlabel('Timestep','FontWeight','bold','Fontsize',16);
- legend('Foopsi Spikes','Ground Truth');
- drawnow;
-
-%% run continuous time MCMC sampler
-
-params.p = 2;
-params.g = g2;
-params.sp = spikes_foopsi; % pass results of foopsi for initialization (if not, they are computed)
-params.c = ca_foopsi;
-params.b = cb;
-params.c1 = c1;
-params.sn = sg;
-params.marg = 0;
-
-SAMPLES = cont_ca_sampler(y,params); %% MCMC
-plot_continuous_samples(SAMPLES,y(:));
-M = plot_marginals(SAMPLES.ss,T,spikeRaster);
\ No newline at end of file
diff --git a/deconvolveCa/MCMC/utilities/HMC_exact2.m b/deconvolveCa/MCMC/utilities/HMC_exact2.m
deleted file mode 100644
index a3b53ab..0000000
--- a/deconvolveCa/MCMC/utilities/HMC_exact2.m
+++ /dev/null
@@ -1,229 +0,0 @@
-function [Xs, bounce_count] = HMC_exact2(F, g, M, mu_r, cov, L, initial_X)
-
-% Author: Ari Pakman
-
-% returns samples from a d-dimensional Gaussian with m constraints given by F*X+g >0
-% If cov == true
-% then M is the covariance and the mean is mu = mu_r
-% if cov== false
-% then M is the precision matrix and the log-density is -1/2 X'*M*X + r'*X
-
-% Input
-% F: m x d matrix
-% g: m x 1 vector
-% M d x d matrix, must be symmmetric and definite positive
-% mu_r d x 1 vector.
-% cov: see explanation above
-% L: number of samples desired
-% initial_X d x 1 vector. Must satisfy the constraint.
-
-
-% Output
-% Xs: d x L matrix, each column is a sample
-% bounce_count: number of times the particle bounced
-
-%% go to a whitened frame
-
-m = size(g,1);
-if size(F,1) ~= m
- display('error');
- return
-end
-
-
-if cov
- mu= mu_r;
- g = g + F*mu;
- %if min(eig(M))<0
- % M = M - 1.01*min(eig(M))*eye(size(M,1));
- %end
- R = chol(M);
- F = F*R';
- initial_X= initial_X -mu;
- initial_X = R'\initial_X;
-
-else
- r=mu_r;
- R=chol(M); % M = R'*R
- mu = R\(R'\r);
- g = g+F*mu;
- F = F/R; % this is the time-consuming step in this code section
- initial_X= initial_X -mu;
- initial_X = R*initial_X;
-end
-
-
-
-
-
-d = size(initial_X,1);
-
-
-Xs=NaN;
-
-bounce_count =0;
-
-nearzero= 10000*eps;
-
-
-
-
-% Verify that initial_X is feasible
- c= F*initial_X +g;
- if any(c<0)
- display('error: inconsistent initial condition');
- return
- end
-
-
-
-% Unsparcify the linear constraints
-g=full(g);
-F2 = sum(F.*F,2); % squared norm of the rows of F, needed for reflecting the velocity
-F=full(F); % if we don't unsparcify qj= F(j,:)*V/F2(j) becomes very slow.
-Ft = F';
-
-
-%% Sampling loop
-
-
-last_X= initial_X;
-Xs=zeros(d,L);
-Xs(:,1)=initial_X;
-
-i=2;
-while (i <= L)
-%i
-stop=0;
-j=0;
-V0= normrnd(0,1, d,1); % initial velocity
-X = last_X;
-
-T=pi/2; % total time the particle will move
-tt=0; % records how much time the particle already moved
-
- while (1)
- a = V0;
- a= real(a);
- b = X;
-
- fa = F*a;
- fb = F*b;
-
- U = sqrt(fa.^2 + fb.^2);
- phi = atan2(-fa,fb); % -pi < phi < +pi
-
-
-
- pn = abs(g./U)<=1; % these are the walls that may be hit
-
-
- % find the first time constraint becomes zero
-
- if any(pn)
- inds = find(pn);
-
- phn= phi(pn);
-
- t1=-phn + acos(-g(pn)./U(pn)); % time at which coordinates hit the walls
- % t1 in [-pi, 2*pi]
- t1(t1<0) = 2*pi + t1(t1<0); % t1 in [0, 2*pi]
- t2 = -t1 -2*phn; % second solution to hit the walls
- % t2 in [-4*pi, 2*pi]
- t2(t2<0) = 2*pi + t2(t2<0); % t2 in [-2*pi, 2*pi]
- t2(t2<0) = 2*pi + t2(t2<0); % t2 in [0, 2*pi]
-
-
- % if there was a previous reflection (j>0)
- % and there is a potential reflection at the sample plane
- % make sure that a new reflection at j is not found because of numerical error
- if j>0
- if pn(j)==1
- indj=sum(pn(1:j));
- tt1 = t1(indj);
- if abs(tt1) < nearzero || abs(tt1-2*pi)< nearzero
- t1(indj)=Inf;
- else
- tt2 = t2(indj);
- if abs(tt2) < nearzero || abs(tt1-2*pi)< nearzero
- t2(indj) = Inf;
- end
- end
- end
- end
-
-
- [mt1 ind1] = min(t1);
- [mt2 ind2] = min(t2);
-
- [mt ind12] = min([mt1 mt2]);
-
- if ind12==1
- m_ind = ind1;
- else
- m_ind= ind2;
- end
-
- % find the reflection plane
- j = inds(m_ind); % j is an index in the full vector of dim-m, not in the restriced vector determined by pn.
-
- else %if pn(i) =0 for all i
- mt =T;
- end %if pn(i)
-
- tt=tt+mt;
-% fprintf(num2str(tt/T));
-
- if tt>=T
- mt= mt-(tt-T);
- stop=1;
-
- end
-
- % move the particle a time mt
-
- X = a*sin(mt) + b*cos(mt);
- V = a*cos(mt) - b*sin(mt);
-
- if stop
- break;
- end
-
- % compute reflected velocity
-
- qj= F(j,:)*V/F2(j);
- V0 = V -2*qj*Ft(:,j);
- bounce_count = bounce_count+ 1;
-
- % dif =V0'*M*V0 - V'*M*V;
-
- end % while(1)
-
- % at this point we have a sampled value X, but due to possible
- % numerical instabilities we check that the candidate X satisfies the
- % constraints before accepting it.
-
- if all(F*X +g > 0)
- Xs(:,i)=X;
- last_X = X;
- i= i+1;
-
- else
- disp('hmc reject')
-
- end
-
-end %while (i <= L)
-
-% transform back to the unwhitened frame
-if cov
- Xs = R'*Xs + repmat(mu, 1,L);
-else
- Xs = R\Xs + repmat(mu, 1,L);
-end
-
-
-
-
-end
-
diff --git a/deconvolveCa/MCMC/utilities/addSpike.m b/deconvolveCa/MCMC/utilities/addSpike.m
deleted file mode 100644
index 05e2195..0000000
--- a/deconvolveCa/MCMC/utilities/addSpike.m
+++ /dev/null
@@ -1,65 +0,0 @@
-function [newSpikeTrain, newCalcium, newLL] = addSpike(oldSpikeTrain,oldCalcium,oldLL,filters,tau,obsCalcium,timeToAdd,indx,Dt,A)
-
-% Add a given spike to the existing spike train.
-
-% Inputs:
-% oldSpikeTrain: current spike train
-% oldCalcium: current noiseless calcium trace
-% oldLL: current value of the log-likelihood function
-% filters: exponential rise and decay kernels for calcium transient
-% tau: continuous time rise and decay time constants
-% obsCalcium: observed fluorescence trace
-% timetoAdd: time of the spike to be added
-% indx: place where the new spike is added in the existing spike train vector
-% Dt: time-bin width
-% A: spike amplitude
-
-% Outputs:
-% newSpikeTrain: new vector of spike times
-% newCalcium: new noiseless calcium trace
-% newLL: new value of the log-likelihood function
-
-% Author: Eftychios A. Pnevmatikakis and Josh Merel
-
- tau_h = tau(1);
- tau_d = tau(2);
-
- ef_h = filters{1,1};
- ef_d = filters{1,2};
- ef_nh = filters{2,1};
- ef_nd = filters{2,2};
-
- if isempty(oldSpikeTrain); indx = 1; end
- newSpikeTrain = [oldSpikeTrain(1:indx-1) timeToAdd oldSpikeTrain(indx:end)]; %possibly inefficient, change if problematic (only likely to be a problem for large numbers of spikes)
-
- %use infinite precision to scale the precomputed FIR approximation to the calcium transient
- wk_h = A*exp((timeToAdd - Dt*ceil(timeToAdd/Dt))/tau_h);
- wk_d = A*exp((timeToAdd - Dt*ceil(timeToAdd/Dt))/tau_d);
-
- %%%%%%%%%%%%%%%%%
- %handle ef_h first
- newCalcium = oldCalcium;
- tmp = 1 + (floor(timeToAdd):min((length(ef_h)+floor(timeToAdd)-1),length(newCalcium)-1));
- wef_h = wk_h*ef_h(1:length(tmp));
- newCalcium(tmp) = newCalcium(tmp) + wef_h;
-
- %if you really want to, ef*ef' could be precomputed and passed in
- relevantResidual = obsCalcium(tmp)-oldCalcium(tmp);
- relevantResidual(isnan(relevantResidual)) = 0;
- %newLL = oldLL - ( wk_h^2*norm(ef_h(1:length(tmp)))^2 - 2*relevantResidual*(wk_h*ef_h(1:length(tmp))'));
- newLL = oldLL - ( wk_h^2*ef_nh(length(tmp)) - 2*relevantResidual*wef_h(:));
- oldCalcium = newCalcium;
- oldLL = newLL;
- %%%%%%%%%%%%%%%%%
-
- %%%%%%%%%%%%%%%%%
- %handle ef_d next
- tmp = 1 + (floor(timeToAdd):min((length(ef_d)+floor(timeToAdd)-1),length(newCalcium)-1));
- wef_d = wk_d*ef_d(1:length(tmp));
- newCalcium(tmp) = newCalcium(tmp) + wef_d;
-
- relevantResidual = obsCalcium(tmp)-oldCalcium(tmp);
- relevantResidual(isnan(relevantResidual)) = 0;
- %newLL = oldLL - ( wk_d^2*norm(ef_d(1:length(tmp)))^2 - 2*relevantResidual*(wk_d*ef_d(1:length(tmp))'));
- newLL = oldLL - ( wk_d^2*ef_nd(length(tmp)) - 2*relevantResidual*wef_d(:));
- %%%%%%%%%%%%%%%%%
\ No newline at end of file
diff --git a/deconvolveCa/MCMC/utilities/get_initial_sample.m b/deconvolveCa/MCMC/utilities/get_initial_sample.m
deleted file mode 100644
index 774a6f4..0000000
--- a/deconvolveCa/MCMC/utilities/get_initial_sample.m
+++ /dev/null
@@ -1,51 +0,0 @@
-function SAM = get_initial_sample(Y,params)
-
-% obtain initial sample by performing sparse noise-constrained deconvolution
-
-% Inputs:
-% Y: observed fluorescence trace
-% params: parameter struct (results of constrained foopsi can be passed here to avoid unnecessary computation)
-
-% Output:
-% SAM: sample structure with values for spikes in continuous time,
-% amplitude, baseline, noise, initial concentration and time constants
-
-% Author: Eftychios A. Pnevmatikakis, 2016, Simons Foundation
-
-
-if isfield(params,'p'); options.p = params.p; else options.p = 1; end
-if isempty(params.c) || isempty(params.b) || isempty(params.c1) || isempty(params.g) || isempty(params.sn) || isempty(params.sp)
- fprintf('Initializing using noise constrained FOOPSI... ');
- options.bas_nonneg = params.bas_nonneg;
- [c,b,c1,g,sn,sp] = constrained_foopsi(Y,params.b,params.c1,params.g,params.sn,options);
- fprintf('done. \n');
-else
- c = params.c;
- b = params.b;
- c1 = params.c1;
- g = params.g;
- sn = params.sn;
- sp = params.sp;
-end
-
-Dt = 1;
-T = length(Y);
-if ~exist('sp','var')
- G = make_G_matrix(T,params.g);
- sp = G*c;
-end
-s_in = sp>0.15*max(sp);
-spiketimes_ = Dt*(find(s_in) + rand(size(find(s_in))) - 0.5);
-spiketimes_(spiketimes_ >= T*Dt) = 2*T*Dt - spiketimes_(spiketimes_ >= T*Dt);
-SAM.lam_ = length(spiketimes_)/(T*Dt);
-SAM.spiketimes_ = spiketimes_;
-
-SAM.A_ = max(median(sp(s_in)),max(sp(s_in))/4); % initial amplitude value
-if length(g) == 2
- SAM.A_ = SAM.A_/sqrt(g(1)^2+4*g(2));
-end
-
-SAM.b_ = max(b,min(Y)+range(Y)/25); % initial baseline value
-SAM.C_in = max(c1,(Y(1)-b)/10); % initial value sample
-SAM.sg = sn; % initial noise value
-SAM.g = g; % initial time constant value
\ No newline at end of file
diff --git a/deconvolveCa/MCMC/utilities/get_next_spikes.m b/deconvolveCa/MCMC/utilities/get_next_spikes.m
deleted file mode 100644
index 35e2a22..0000000
--- a/deconvolveCa/MCMC/utilities/get_next_spikes.m
+++ /dev/null
@@ -1,159 +0,0 @@
-function [new_spikes, new_calcium, moves] = get_next_spikes(curr_spikes,curr_calcium,calciumSignal,filters,tau,calciumNoiseVar, lam, proposalSTD, add_move, Dt, A, con_lam)
-
-% Function for sampling the next of spike times given the current set of spike time and observed fluorescence trace
-
-% Inputs:
-% curr_spikes: current set of spike times in continuous time
-% curr_calcium: current estimate of noiseless calcium trace
-% calciumSingal: observed fluorescence trace
-% filters: exponential rise and decay kernels for calcium transient
-% tau: continuous time rise and decay time constants
-% calciumNoiseVar: observation noise variance
-% lam: function handle for computing firing rate
-% proposalSTD: standard deviation for perturbing a spike time
-% add_move: # of addition/removal proposals per sample
-% Dt: time-bin width
-% A: spike amplitude
-% con_lam: flag for constant firing rate (speeds up computation)
-
-% Outputs:
-% new_spikes: new set of spike times
-% new_calcium: new estimate of noiseless calcium trace
-% moves: acceptance probabilities for perturbing,adding, droping spikes respectively
-
-% Author: Eftychios A. Pnevmatikakis and Josh Merel
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %% initialize some parameters
- T = length(calciumSignal); %for all of this, units are bins and spiketrains go from 0 to T where T is number of bins
- ff = ~isnan(calciumSignal); % entries with data
-
- %% start with initial spiketrain and initial predicted calcium
- si = curr_spikes; %initial set of spike times has no spikes - this will not be sorted but that shouldn't be a problem
- new_calcium = curr_calcium; %initial calcium is set to baseline
-
- N = length(si); %number of spikes in spiketrain
-
- %initial logC - compute likelihood initially completely - updates to likelihood will be local
- logC = -norm(new_calcium(ff)-calciumSignal(ff))^2;
-
- %flag for uniform vs likelihood proposal (if using likelihood proposal, then time shifts are pure Gibbs)
- %this really should be split into four cases (not implemented yet),
- % 1) RW for time shifts with uniform add/drop
- % 2) RW for time shifts with likelihood proposal add/drop
- % 3) Gibbs for time shifts with uniform add/drop
- % 4) Gibbs for time shifts with likelihood proposal add/drop
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- addMoves = [0 0]; %first elem is number successful, second is number total
- dropMoves = [0 0];
- timeMoves = [0 0];
-
- %% loop over spikes, perform spike time move (could parallelize here for non-interacting spikes, i.e. spikes that are far enough away)
-
- for ni = 1:N %possibly go through in a random order (if you like)
-
- tmpi = si(ni);
- tmpi_ = si(ni)+(proposalSTD*randn); %with bouncing off edges
- if tmpi_<0
- tmpi_ = -(tmpi_);
- elseif tmpi_>T
- tmpi_ = T-(tmpi_-T);
- end
-
- %set si_ to set of spikes with the move and ci_ to adjusted calcium and update logC_ to adjusted
-% [si_, ci_, logC_] = removeSpike(si,ci,logC,ef,tau,calciumSignal,tmpi,ni,Dt,A);
-% [si_, ci_, logC_] = addSpike(si_,ci_,logC_,ef,tau,calciumSignal,tmpi_,ni,Dt,A);
- [si_, ci_, logC_] = replaceSpike(si,new_calcium,logC,filters,tau,calciumSignal,tmpi,ni,tmpi_,Dt,A);
-
- %accept or reject
- ratio = exp((logC_-logC)/(2*calciumNoiseVar));
- if ~con_lam; ratio = ratio*lam(tmpi)/lam(tmpi_); end
- if ratio>1 %accept
- si = si_;
- new_calcium = ci_;
- logC = logC_;
- timeMoves = timeMoves + [1 1];
- elseif rand1 %accept
- si = si_;
- new_calcium = ci_;
- logC = logC_;
- addMoves = addMoves + [1 1];
- elseif rand0
- %propose a uniform removal
- tmpi = randi(N);
- [si_, ci_, logC_] = removeSpike(si,new_calcium,logC,filters,tau,calciumSignal,si(tmpi),tmpi,Dt,A);
-
- %reverse probability
- rprob = 1/(T*Dt);
-
- %compute forward prob
- fprob = 1/N;
-
- %accept or reject
- ratio = exp((logC_ - logC)/(2*calciumNoiseVar))*(rprob/fprob)*(1/lam(si(tmpi))); %posterior times reverse prob/forward prob
-
- if ratio>1 %accept
- si = si_;
- new_calcium = ci_;
- logC = logC_;
- dropMoves = dropMoves + [1 1];
- elseif rand floor(timetoAdd)
- wef_h = wk_hr*[zeros(1,min(length(tmp),floor(timetoRemove)-floor(timetoAdd))),ef_h(1:length(tmp)-(floor(timetoRemove)-floor(timetoAdd)))] - wk_ha*ef_h(1:length(tmp));
- else
- wef_h = wk_hr*ef_h(1:length(tmp)) - wk_ha*[zeros(1,min(length(tmp),floor(timetoAdd)-floor(timetoRemove))),ef_h(1:length(tmp)-(floor(timetoAdd)-floor(timetoRemove)))];
- end
- newCalcium(tmp) = newCalcium(tmp) - wef_h;
- end
-
- %%%%%%%%%%%%%%%%%
- %handle ef_d next
- tmp = 1+ (min_t:min((length(ef_d)+min_t-1),length(newCalcium)-1));
- if floor(timetoRemove) == floor(timetoAdd)
- wef_d = (wk_dr-wk_da)*ef_d(1:length(tmp));
- elseif floor(timetoRemove) > floor(timetoAdd)
- wef_d = wk_dr*[zeros(1,min(length(tmp),floor(timetoRemove)-floor(timetoAdd))),ef_d(1:length(tmp)-(floor(timetoRemove)-floor(timetoAdd)))] - wk_da*ef_d(1:length(tmp));
- else
- wef_d = wk_dr*ef_d(1:length(tmp)) - wk_da*[zeros(1,min(length(tmp),floor(timetoAdd)-floor(timetoRemove))),ef_d(1:length(tmp)-(floor(timetoAdd)-floor(timetoRemove)))];
- end
- newCalcium(tmp) = newCalcium(tmp) - wef_d;
-
- obstemp = obsCalcium(tmp);
- newLL = oldLL - norm(newCalcium(tmp)-obstemp)^2 + norm(oldCalcium(tmp)-obstemp)^2; %+ 2*(newCalcium(tmp)-oldCalcium
- %%%%%%%%%%%%%%%%
\ No newline at end of file
diff --git a/deconvolveCa/MCMC/utilities/samples_cell2mat.m b/deconvolveCa/MCMC/utilities/samples_cell2mat.m
deleted file mode 100644
index afd442c..0000000
--- a/deconvolveCa/MCMC/utilities/samples_cell2mat.m
+++ /dev/null
@@ -1,24 +0,0 @@
-function spikeRaster = samples_cell2mat(sampleCell,T,Dt)
-
-% Constructs matrix of spike raster plot from cell array of spike times
-
-% Inputs:
-% sampleCell: Cell array with spike times in continuous time (SAMPLES.ss)
-% T: End time of trace/experiment
-% Dt: Time-bin resolution (default: 1)
-
-% Output:
-% spikeRaster: Spike raster plot matrix
-
-% Author: Eftychios A. Pnevmatikakis and Josh Merel
-
-if nargin == 2
- Dt = 1;
-end
-bins = 0:Dt:(T-Dt);
-nsamples = length(sampleCell);
-spikeRaster = zeros(nsamples,length(bins));
-for i = 1:nsamples
- tmp = histc([sampleCell{i}(:); inf],[bins, (T+1)]);
- spikeRaster(i,:) = tmp(1:(end-1))';
-end
\ No newline at end of file
diff --git a/deconvolveCa/MCMC/utilities/tau_c2d.m b/deconvolveCa/MCMC/utilities/tau_c2d.m
deleted file mode 100644
index 7815606..0000000
--- a/deconvolveCa/MCMC/utilities/tau_c2d.m
+++ /dev/null
@@ -1,15 +0,0 @@
-function [g,h1] = tau_c2d(tau_r,tau_d,dt)
-
-% convert continuous time constants to discrete with resolution dt
-% h(t) = (1-exp(-t/tau_r))*exp(-t/tau_d)
-% g: discrete time constants
-% h1: h(dt);
-% h*s can be written in discrete form as filter(h1,[1,-g],s)
-
-% Author: Eftychios A. Pnevmatikakis, 2016, Simons Foundation
-
-A = [-(2/tau_d+1/tau_r), - (tau_r+tau_d)/(tau_r*tau_d^2); 1 0];
-lc = eig(A*dt);
-ld = exp(lc);
-g = [sum(ld),-prod(ld)];
-h1 = (1-exp(-dt/tau_r))*exp(-dt/tau_d);
\ No newline at end of file
diff --git a/deconvolveCa/MCMC/utilities/tau_d2c.m b/deconvolveCa/MCMC/utilities/tau_d2c.m
deleted file mode 100644
index f29514c..0000000
--- a/deconvolveCa/MCMC/utilities/tau_d2c.m
+++ /dev/null
@@ -1,15 +0,0 @@
-function tau = tau_d2c(g,dt)
-
-% convert discrete time constantswith resolution dt to continuous
-% h(t) = (1-exp(-t/tau(1)))*exp(-t/tau(2))
-
-% Author: Eftychios A. Pnevmatikakis, 2016, Simons Foundation
-
-gr = max(roots([1,-g(:)']),0);
-p1_continuous = log(min(gr))/dt;
-p2_continuous = log(max(gr))/dt;
-tau_1 = -1/p1_continuous; %tau h - smaller (tau_d * tau_r)/(tau_d + tau_r)
-tau_2 = -1/p2_continuous; %tau decay - larger
-
-tau_rise = 1/(1/tau_1 - 1/tau_2);
-tau = [tau_rise,tau_2]; %tau_h , tau_d
\ No newline at end of file
diff --git a/deconvolveCa/MCMC/wrapper.m b/deconvolveCa/MCMC/wrapper.m
deleted file mode 100644
index 9c680d7..0000000
--- a/deconvolveCa/MCMC/wrapper.m
+++ /dev/null
@@ -1,13 +0,0 @@
-clear;
-load traceData.mat;
-addpath utilities
-addpath(genpath('../constrained-foopsi'));
-%Y = squeeze(traceData.traces(129,7,:)); % pick a particular trace (low SNR)
-Y = mean(squeeze(traceData.traces(:,7,:))); % average over ROI (high SNR)
-
-%% run MCMC sampler and plot results
-params.p = 1;
-params.print_flag = 1;
-params.B = 300;
-SAMP = cont_ca_sampler(Y,params);
-plot_continuous_samples(SAMP,Y);
\ No newline at end of file
diff --git a/deconvolveCa/README.md b/deconvolveCa/README.md
deleted file mode 100644
index d315134..0000000
--- a/deconvolveCa/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# OASIS: Fast online deconvolution of calcium imaging data
-
-Code accompanying the paper "Fast Active Set Method for Online Spike Inference from Calcium Imaging". [arXiv, 2016]
-
-Python: https://github.com/j-friedrich/OASIS
-
-MATLAB: https://github.com/zhoupc/OASIS_matlab
-
-### Use OASIS
-
-The implementation of OASIS requires several functions for different formulation of the optimization problems. They can be found within the folder `OASIS_matlab/oasis/`. However, we highly recommend you use the wrapper function `deconvolveCa.m` to run differnet algorithms with one command.
-
-| | AR1 | AR2 | convolution ( difference of 2 expfunctions) | convolution |
-| --------------------- | ---- | ---- | ---------------------------------------- | ----------- |
-| FOOPSI[1] | √ | √ | √ | √ |
-| Constrained-FOOPSI[2] | √ | | | |
-| Thresholded-FOOPSI[3] | √ | √ | | |
-
-
-
-### Installation
-Run setup.m to add OASIS function to the search path of MATLAB
-
-`>> setup`
-
-### Examples
-The scripts to reproduce the figures are in the subfolder 'examples' with names obvious from the arXiv paper. They can be run with
-
-`>> run examples/paper/fig*.m `
-
-There is also a function **deconvolveCa.m** wrapping all formulations of the problem. You might only need this one for your problem. See a list of examples in the demo script **oasis_test.m**,
-
-`>> edit examples/all_examples.m`
-
-### Benchmarks
-
-
-
-### References
-
-[1]Vogelstein, J.T., Packer, A.M., Machado, T.A., Sippy, T., Babadi, B., Yuste, R. and Paninski, L., 2010. Fast nonnegative deconvolution for spike train inference from population calcium imaging. *Journal of neurophysiology*,*104*(6), pp.3691-3704.
-
-[2]Pnevmatikakis, E.A., Soudry, D., Gao, Y., Machado, T.A., Merel, J., Pfau, D., Reardon, T., Mu, Y., Lacefield, C., Yang, W. and Ahrens, M., 2016. Simultaneous denoising, deconvolution, and demixing of calcium imaging data. *Neuron*, *89*(2), pp.285-299.
-
-[3]Friedrich, J., Zhou, P., and Paninski, L., 2016. Fast Active Set Methods for Online Deconvolution of Calcium Imaging Data. *arXiv preprint arXiv:*1609.00639.
\ No newline at end of file
diff --git a/deconvolveCa/constrained-foopsi/.gitignore b/deconvolveCa/constrained-foopsi/.gitignore
deleted file mode 100644
index 25d91a6..0000000
--- a/deconvolveCa/constrained-foopsi/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-
-*.m~
-*.gif
diff --git a/deconvolveCa/constrained-foopsi/MCEM_foopsi.m b/deconvolveCa/constrained-foopsi/MCEM_foopsi.m
deleted file mode 100644
index 0e7b727..0000000
--- a/deconvolveCa/constrained-foopsi/MCEM_foopsi.m
+++ /dev/null
@@ -1,135 +0,0 @@
-function [c,b,c1,g,sn,sp] = MCEM_foopsi(y,b,c1,g,sn,options)
- defoptions.dt = 1;
- defoptions.MaxIter = 10;
- defoptions.MaxInerIter = 50;
- defoptions.TauStd = [0.2,2];
- defoptions.default_g = [0.6,0.9];
-
- if nargin < 6; options.defoptions; end
- if ~isfield(options,'dt'); options.dt = defoptions.dt; end
- if ~isfield(options,'MaxIter'); options.MaxIter = defoptions.MaxIter; end
- if ~isfield(options,'MaxInerIter'); options.MaxInerIter = defoptions.MaxInerIter; end
- if ~isfield(options,'TauStd'); options.TauStd = defoptions.TauStd; end
- if ~isfield(options,'default_g'); options.default_g = defoptions.default_g; end
-
- dt = options.dt;
-
- if nargin < 5
- sn = [];
- if nargin < 4
- g = [];
- if nargin < 3
- c1 = [];
- if nargin < 2
- b = [];
- end
- end
- end
- end
-
-
-% initialization
-
- [c,b,c1,g,sn,sp] = constrained_foopsi(y,b,c1,g,sn,options);
- T = length(y);
- p = length(g);
- gr_ = sort(roots([1,-g(:)']));
- if p == 1; gr_ = [0,gr_]; end
- if any(gr_<0) || any(~isreal(gr_))
- gr_ = options.default_g;
- end
- tau = -dt./log(gr_);
- if p == 1
- gr_(1) = 0;
- G1sp = zeros(T,1);
- else
- G1sp = make_G_matrix(T,gr_(1))\sp(:);
- end
- tau1_std = max(tau(1)/5,options.TauStd(1));
- tau2_std = min(tau(2)/10,options.TauStd(2));
- tauMoves = [0 0];
- tau_min = 0;
- tau_max = 2*tau(2);
- gd_vec = max(gr_).^(0:T-1)';
- tau_sam = zeros(options.MaxIter,2);
- for iter = 1:options.MaxIter
- TAU = zeros(options.MaxInerIter,2);
- for iner_iter = 1:options.MaxInerIter
- if p >= 2 % update rise time constant
- logC = -norm(y(:) - c(:) - b - c1*gd_vec(:))^2;
- tau_ = tau;
- tau_temp = tau_(1)+(tau1_std*randn);
- while tau_temp >tau(2) || tau_temptau_max || tau_temp
- min | sum(sp)
- c,sp,b,c1 |
- subject to: sp| >= 0
- b| >= 0
- G*c| = sp
- c1| >= 0
- ||y-b-c - c_in|| | <= sn*sqrt(T)
-
-
-File constained_foopsi.m
- Variables: |
----------------|-----------------
- y: | raw fluorescence data (vector of length(T))
- c: | denoised calcium concentration (Tx1 vector)
- b: | baseline concentration (scalar)
- c1: | initial concentration (scalar)
- g: | discrete time constant(s) (scalar or 2x1 vector)
- sn: | noise standard deviation (scalar)
- sp: | spike vector (Tx1 vector)
-
- USAGE:
- [c,b,c1,g,sn,sp] = constrained_foopsi(y,b,c1,g,sn,OPTIONS)
- The parameters b,cin,g,sn can be given or else are estimated from the data
-
- OPTIONS: (stuct for specifying options)
- p: order for AR model, used when g is not given (default 2)
- method: methods for performing spike inference
- available methods: 'dual' uses dual ascent
- 'cvx' uses the cvx package available from cvxr.com (default)
- 'lars' uses the least regression algorithm
- 'spgl1' uses the spgl1 package available from math.ucdavis.edu/~mpf/spgl1/ (usually fastest)
- bas_nonneg: flag for setting the baseline lower bound. if 1, then b >= 0 else b >= min(y)
- noise_range: frequency range over which the noise power is estimated. Default [Fs/4,Fs/2]
- noise_method: method to average the PSD in order to obtain a robust noise level estimate
- lags: number of extra autocovariance lags to be considered when estimating the time constants
- resparse: number of times that the solution is resparsened (default 0). Currently available only with methods 'cvx', 'spgl'
-
-
-The noise is estimated with a power spectral density approach and the time constants from the signal autocovariance.
-
-The algorithm can also handle missing data (appearing as NaNs in y) due to motion artifacts or for super-resolution approaches
-
-The algorithm is presented in more detail in
-
-Pnevmatikakis, E. A., Gao, Y., Soudry, D., Pfau, D., Lacefield, C., Poskanzer, K., ... & Paninski, L. (2014). A structured matrix factorization framework for large scale calcium imaging data analysis. arXiv preprint arXiv:1409.2903. http://arxiv.org/abs/1409.2903
-
-Toolbox Dependencies
-=======
-The signal processing toolbox is optional. If present it is used for computing the power spectral density and the autocovariance function.
-
-License
-=======
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
diff --git a/deconvolveCa/constrained-foopsi/acknowledgements.txt b/deconvolveCa/constrained-foopsi/acknowledgements.txt
deleted file mode 100644
index eaee8a5..0000000
--- a/deconvolveCa/constrained-foopsi/acknowledgements.txt
+++ /dev/null
@@ -1 +0,0 @@
-Thanks to D. Soudry, W. Yang and D. Greenberg
diff --git a/deconvolveCa/constrained-foopsi/constrained_foopsi.m b/deconvolveCa/constrained-foopsi/constrained_foopsi.m
deleted file mode 100644
index 43a411f..0000000
--- a/deconvolveCa/constrained-foopsi/constrained_foopsi.m
+++ /dev/null
@@ -1,298 +0,0 @@
-function [c,b,c1,g,sn,sp] = constrained_foopsi(y,b,c1,g,sn,options)
-% spike inference using a constrained foopsi approach:
-% min sum(sp)
-% c,sp,b,c1
-% subject to: sp >= 0
-% b >= 0
-% G*c = sp
-% c1 >= 0
-% ||y-b-c - c_in|| <= sn*sqrt(T)
-
-% Variables:
-% y: raw fluorescence data (vector of length(T))
-% c: denoised calcium concentration (Tx1 vector)
-% b: baseline concentration (scalar)
-% c1: initial concentration (scalar)
-% g: discrete time constant(s) (scalar or 2x1 vector)
-% sn: noise standard deviation (scalar)
-% sp: spike vector (Tx1 vector)
-
-% USAGE:
-% [c,b,c1,g,sn,sp] = constrained_foopsi(y,b,c1,g,sn,OPTIONS)
-% The parameters b,cin,g,sn can be given or else are estimated from the data
-
-% OPTIONS: (stuct for specifying options)
-% p: order for AR model, used when g is not given (default 2)
-% method: methods for performing spike inference
-% available methods: 'dual' uses dual ascent
-% 'cvx' uses the cvx package available from cvxr.com (default)
-% 'lars' uses the least regression algorithm
-% 'spgl1' uses the spgl1 package available from
-% math.ucdavis.edu/~mpf/spgl1/ (usually fastest)
-% bas_nonneg: flag for setting the baseline lower bound. if 1, then b >= 0 else b >= min(y)
-% noise_range: frequency range over which the noise power is estimated. Default [Fs/4,Fs/2]
-% noise_method: method to average the PSD in order to obtain a robust noise level estimate
-% lags: number of extra autocovariance lags to be considered when estimating the time constants
-% resparse: number of times that the solution is resparsened (default 0). Currently available only with methods 'cvx', 'spgl'
-% fudge_factor: scaling constant to reduce bias in the time constant estimation (default 1 - no scaling)
-
-% Written by:
-% Eftychios A. Pnevmatikakis, Simons Foundation, 2015
-
-defoptions.p = 2;
-defoptions.method = 'cvx';
-defoptions.bas_nonneg = 1; % nonnegativity option for baseline estimation
-defoptions.noise_range = [0.25,0.5]; % frequency range over which to estimate the noise
-defoptions.noise_method = 'logmexp'; % method for which to estimate the noise level
-defoptions.lags = 5; % number of extra lags when computing the AR coefficients
-defoptions.resparse = 0; % number of times to re-sparse solution
-defoptions.fudge_factor = 1; % fudge factor for time constants
-
-if nargin < 6
- options = defoptions;
- if nargin < 5
- sn = [];
- if nargin < 4
- g = [];
- if nargin < 3
- c1 = [];
- if nargin < 2
- b = [];
- end
- end
- end
- end
-end
-
-if ~isfield(options,'p'); options.p = defoptions.p; end
-if ~isfield(options,'method'); options.method = defoptions.method; end
-if ~isfield(options,'bas_nonneg'); options.bas_nonneg = defoptions.bas_nonneg; end
-if ~isfield(options,'noise_range'); options.noise_range = defoptions.noise_range; end
-if ~isfield(options,'noise_method'); options.noise_method = defoptions.noise_method; end
-if ~isfield(options,'lags'); options.lags = defoptions.lags; end
-if ~isfield(options,'resparse'); options.resparse = defoptions.resparse; end
-if ~isfield(options,'fudge_factor'); options.fudge_factor = defoptions.fudge_factor; end
-
-method = options.method;
-if isempty(b);
- bas_est = 1;
-else
- bas_est = 0;
-end
-if isempty(c1)
- c1_est = 1;
-else
- c1_est = 0;
-end
-
-y = y(:);
-T = length(y);
-y_full = y;
-mis_data = isnan(y);
-E = speye(T);
-E(mis_data,:) = [];
-
-if any(mis_data)
- y_full(mis_data) = interp1(find(~mis_data),y(~mis_data),find(mis_data));
-end
-
-
-if isempty(sn)
- sn = GetSn(y_full,options.noise_range,options.noise_method);
-end
-if isempty(g)
- g = estimate_time_constants(y_full,options.p,sn,options.lags);
- while max(abs(roots([1,-g(:)']))>1) && options.p < 5
- warning('No stable AR(%i) model found. Checking for AR(%i) model \n',options.p,options.p+1);
- options.p = options.p + 1;
- g = estimate_time_constants(y,options.p,sn,options.lags);
- end
- if options.p == 5
- g = 0;
- end
- %fprintf('Stable AR(%i) model found \n',options.p);
- % re-adjust time constant values
- rg = roots([1;-g(:)]);
- if ~isreal(rg); rg = real(rg) + .001*randn(size(rg)); end
- rg(rg>1) = 0.95 + 0.001*randn(size(rg(rg>1)));
- rg(rg<0) = 0.15 + 0.001*randn(size(rg(rg<0)));
- pg = poly(options.fudge_factor*rg);
- g = -pg(2:end);
-end
-if options.bas_nonneg % lower bound for baseline
- b_lb = 0;
-else
- b_lb = min(y);
-end
-
-if strcmpi(method,'dual'); method = 'dual';
-elseif strcmpi(method,'cvx'); method = 'cvx';
-elseif strcmpi(method,'lars'); method = 'lars';
-elseif strcmpi(method,'spgl1'); method = 'spgl1';
-else fprintf('Invalid choice of method. Using CVX \n'); method = 'cvx';
-end
-
-if strcmpi(method,'dual') && any(mis_data)
- warning('Dual method does not support missing data. Switching to CVX');
- method = 'cvx';
-end
-
-if options.resparse > 0 && (strcmpi(method,'dual') || strcmpi(method,'lars'))
- warning('Resparsening is not supported with chosen method. Switching to CVX');
- method = 'cvx';
-end
-
-pathCell = regexp(path, pathsep, 'split');
-g = g(:);
-G = spdiags(ones(T,1)*[-g(end:-1:1)',1],-length(g):0,T,T);
-gd = max(roots([1,-g'])); % decay time constant for initial concentration
-gd_vec = gd.^((0:T-1)');
-
-switch method
- case 'dual'
- v = G'*ones(T,1);
- thr = sn*sqrt(T-sum(mis_data));
- if bas_est; b = 0; end
- if c1_est; c1 = 0; end
- myfun = @(Ald) lagrangian_temporal_gradient(Ald,thr^2,y(~mis_data)-b-c1*gd_vec(~mis_data),bas_est,c1_est);
- c = [G\max(G*y,0);zeros(bas_est);zeros(c1_est)];
- options_dual = optimset('GradObj','On','Display','Off','Algorithm','interior-point','TolX',1e-8);
- ld_in = 10;
- [ld,~,flag] = fmincon(myfun,ld_in,[],[],[],[],0,[],[],options_dual);
- if (flag == -2) || (flag == -3)
- warning('Problem seems unbounded or infeasible. Try a different method.');
- end
- if bas_est; b = c(T+bas_est); end
- if c1_est; c1 = c(end); end
- c = c(1:T);
- sp = G*c;
- case 'cvx'
- onPath = ~isempty(which('cvx_begin'));
- if onPath
- c = zeros(T,1+options.resparse);
- sp = zeros(T,1+options.resparse);
- bas = zeros(1+options.resparse,1);
- cin = zeros(1+options.resparse,1);
- w_ = ones(T,1);
- for rep = 1:options.resparse+1
- [c(:,rep),bas(rep),cin(rep)] = cvx_foopsi(y,b,c1,sn,b_lb,g,w_,~mis_data);
- sp(:,rep) = G*c(:,rep);
- w_ = 1./(max(sp(:,rep),0) + 1e-8);
- end
- sp(sp<1e-6) = 0;
- c = G\sp;
- b = bas;
- c1 = cin;
- else
- error('CVX does not appear to be on the MATLAB path. It can be downloaded from cvxr.com \n');
- end
- case 'lars'
- Ginv = E*[full(G\speye(T)),ones(T,bas_est),gd_vec*ones(1,c1_est)];
- if bas_est; b = 0; end
- if c1_est; c1 = 0; end
- [~, ~, spikes, ~, ~] = lars_regression_noise(y(~mis_data)-b_lb*bas_est - b - c1*gd_vec(~mis_data), Ginv, 1, sn^2*(T-sum(mis_data)));
- sp = spikes(1:T);
- b = (spikes(T+bas_est)+b_lb)*bas_est + b*(1-bas_est);
- c1 = spikes(end)*c1_est + c1*(1-c1_est);
- c = G\sp;
- case 'spgl1'
- onPath = ~isempty(which('spgl1'));
- if onPath
- Gx = @(x,mode) G_inv_mat(x,mode,T,g,gd_vec,bas_est,c1_est,E);
- c = zeros(T,1+options.resparse);
- sp = zeros(T,1+options.resparse);
- bas = zeros(1+options.resparse,1);
- cin = zeros(1+options.resparse,1);
- w_ = ones(T,1);
- for rep = 1:options.resparse+1
- if bas_est; b = 0; w_ = [w_;1e-10]; end
- if c1_est; c1 = 0; w_ = [w_;1e-10]; end
- options_spgl = spgSetParms('project',@NormL1NN_project ,'primal_norm', @NormL1NN_primal,'dual_norm',@NormL1NN_dual,'verbosity',0,'weights',w_);
- [spikes,r,~,~] = spg_bpdn( Gx, y(~mis_data)-b_lb*bas_est - (1-bas_est)*b-(1-c1_est)*c1*gd_vec(~mis_data), sn*sqrt(T-sum(mis_data)),options_spgl);
- c(:,rep) = G\spikes(1:T); %Gx([spikes(1:T);0],1); %% calcium signal
- bas(rep) = b*(1-bas_est) + bas_est*spikes(T+bas_est)+b_lb*bas_est; %% baseline
- cin(rep) = c1*(1-c1_est) + c1_est*spikes(end);
- sp(:,rep) = spikes(1:T); %% spiking signal
- w_ = 1./(spikes(1:T)+1e-8);
- end
- b = bas;
- c1 = cin;
- %sn = norm(r)/sqrt(T);
- else
- error('SPGL1 does not appear to be on the MATLAB path. It can be downloaded from math.ucdavis.edu/~mpf/spgl1 \n');
- end
-end
-
- function sn = GetSn(Y,range_ff,method)
- % estimate noise level with a power spectral density method
- L=length(Y);
-% if ~isempty(which('pmtm'))
-% [psd_Y,ff] = pmtm(Y,5/2,1000,1);
-% end
- if ~isempty(which('pwelch'));
- [psd_Y,ff]=pwelch(Y,round(L/8),[],1000,1);
- else
- xdft = fft(Y);
- xdft = xdft(:,1:round(L/2)+1);
- psd_Y = (1/L) * abs(xdft).^2;
- ff = 0:1/L:1/2;
- psd_Y(2:end-1) = 2*psd_Y(2:end-1);
- end
- ind=ff>range_ff(1);
- ind(ff>range_ff(2))=0;
- switch method
- case 'mean'
- sn=sqrt(mean(psd_Y(ind)/2));
- case 'median'
- sn=sqrt(median(psd_Y(ind)/2));
- case 'logmexp'
- sn = sqrt(exp(mean(log(psd_Y(ind)/2))));
- end
- end
-
-
- function g = estimate_time_constants(y,p,sn,lags)
- % estimate time constants from the sample autocovariance function
-
- lags = lags + p;
- if ~isempty(which('xcov')) %signal processing toolbox
- xc = xcov(y,lags,'biased');
- else
- ynormed = (y - mean(y));
- xc = nan(lags + 1, 1);
- for k = 0:lags
- xc(k + 1) = ynormed(1 + k:end)' * ynormed(1:end - k);
- end
- xc = [flipud(xc(2:end)); xc] / numel(y);
- end
- xc = xc(:);
- A = toeplitz(xc(lags+(1:lags)),xc(lags+(1:p))) - sn^2*eye(lags,p);
- g = pinv(A)*xc(lags+2:end);
- end
-
- function [f,grad] = lagrangian_temporal_gradient(Al,thr,y_raw,bas_flag,c1_flag)
- options_qp = optimset('Display','Off','Algorithm','interior-point-convex');
- H = [speye(T),ones(T,bas_flag),gd_vec*ones(1,c1_flag);...
- ones(bas_flag,T),T*ones(bas_flag),(1-gd^T)/(1-gd)*ones(c1_flag,bas_flag);...
- (gd_vec*ones(1,c1_flag))',(1-gd^T)/(1-gd)*ones(c1_flag,bas_flag),(1-gd^(2*T))/(1-gd^2)*ones(c1_flag,c1_flag)];
- Ay = [y_raw;sum(y_raw)*ones(bas_flag);gd_vec'*y_raw*ones(c1_flag)];
- c = quadprog(2*Al(1)*H,[v;zeros(bas_flag+c1_flag,1)]-2*Al(1)*Ay,[-G,sparse(T,bas_flag+c1_flag);sparse(bas_flag+c1_flag,T),-speye(bas_flag+c1_flag)]...
- ,[sparse(T,1);-b_lb*ones(bas_flag);zeros(c1_flag)],[],[],[],[],c,options_qp);
- f = v'*c(1:T);
- grad = [sum((c(1:T)-y_raw + c(T+bas_flag)*bas_flag + c(end)*gd_vec*c1_flag).^2)-thr];
- f = f + Al(:)'*grad;
- end
-
- function b = G_inv_mat(x,mode,NT,gs,gd_vec,bas_flag,c1_flag,Emat)
- if mode == 1
- b = filter(1,[1;-gs(:)],x(1:NT)) + bas_flag*x(NT+bas_flag) + c1_flag*gd_vec*x(end);
- b = Emat*b;
- %b = G\x(1:NT) + x(NT+bas_flag)*bas_flag + x(end)*c1_flag;
- elseif mode == 2
- x = Emat'*x;
- b = [flipud(filter(1,[1;-gs(:)],flipud(x)));ones(bas_flag,1)*sum(x);ones(c1_flag,1)*(gd_vec'*x)];
- %b = [G'\x;ones(bas_flag,1)*sum(x);ones(c1_flag,1)*(gd_vec'*x)] ;
- end
- end
-
-end
diff --git a/deconvolveCa/constrained-foopsi/cvx_foopsi.m b/deconvolveCa/constrained-foopsi/cvx_foopsi.m
deleted file mode 100644
index 4fb92a1..0000000
--- a/deconvolveCa/constrained-foopsi/cvx_foopsi.m
+++ /dev/null
@@ -1,46 +0,0 @@
-function [c,b,c1] = cvx_foopsi(y,b,c1,sn,b_lb,g,w,keep)
-
-% implementation of constrained foopsi in CVX
-% Written by Eftychios Pnevmatikakis
-
- if isempty(b)
- bas_est = 1;
- else
- bas_est = 0;
- end
- if isempty(c1)
- c1_est = 1;
- else
- c1_est = 0;
- end
- gd = max(roots([1,-g(:)']));
- T = length(y);
- G = spdiags(ones(T,1)*[-g(end:-1:1)',1],-length(g):0,T,T);
- gd_vec = gd.^((0:T-1)');
- cvx_begin quiet
- variable c2(T)
- if bas_est; variable b; end
- if c1_est; variable c1; end
- minimize(w'*(G*c2))
- subject to
- G*c2>=0;
- norm(y(keep)-c2(keep)-b-c1*gd_vec(keep))<=sqrt(sum(keep))*sn;
- if bas_est; b>=b_lb; end
- if c1_est; c1>=0; end
- cvx_end
- if strcmpi(cvx_status,'Infeasible');
- %disp('Problem is infeasible, adjusting noise value.');
- cvx_begin quiet
- variable c2(T)
- if bas_est; variable b; end
- if c1_est; variable c1; end
- minimize(norm(y(keep)-c2(keep)-b-c1*gd_vec(keep)))
- subject to
- G*c2>=0;
- if bas_est; b>=b_lb; end
- if c1_est; c1>=0; end
- cvx_end
- sn = cvx_optval/sqrt(sum(keep));
- end
- c = c2;
-end
\ No newline at end of file
diff --git a/deconvolveCa/constrained-foopsi/lars_regression_noise.m b/deconvolveCa/constrained-foopsi/lars_regression_noise.m
deleted file mode 100644
index bfe70be..0000000
--- a/deconvolveCa/constrained-foopsi/lars_regression_noise.m
+++ /dev/null
@@ -1,286 +0,0 @@
-function [Ws, lambdas, W_lam, lam, flag] = lars_regression_noise(Y, X, positive, noise)
-
-% run LARS for regression problems with LASSO penalty, with optional positivity constraints
-% Author: Eftychios Pnevmatikakis. Adapted code from Ari Pakman
-
-
-% Input Parameters:
-% Y: Y(:,t) is the observed data at time t
-% X: the regresion problem is Y=X*W + noise
-% maxcomps: maximum number of active components to allow
-% positive: a flag to enforce positivity
-% noise: the noise of the observation equation. if it is not
-% provided as an argument, the noise is computed from the
-% variance at the end point of the algorithm. The noise is
-% used in the computation of the Cp criterion.
-
-
-% Output Parameters:
-% Ws: weights from each iteration
-% lambdas: lambda values at each iteration
-% Cps: C_p estimates
-% last_break: last_break(m) == n means that the last break with m non-zero weights is at Ws(:,:,n)
-
-
-verbose=false;
-%verbose=true;
-
-k=1;
-
-T = size(Y,2); % # of time steps
-N = size(X,2); % # of compartments
-
-maxcomps = N;
-
-W = zeros(N,k);
-active_set = zeros(N,k);
-visited_set = zeros(N,k);
-
-lambdas = [];
-
-Ws=zeros(size(W,1),size(W,2),maxcomps); % Just preallocation. Ws may end with more or less than maxcomp columns
-
-
-%%
-
-r = X'*Y(:); % N-dim vector
-M = -X'*X; % N x N matrix
-
-%% begin main loop
-
-%fprintf('\n i = ');
-i = 1;
-flag = 0;
-while 1
- if flag == 1;
- W_lam = 0;
- break;
- end
- % fprintf('%d,',i);
-
- %% calculate new gradient component if necessary
-
- if i>1 && new && visited_set(new) ==0
-
- visited_set(new) =1; % remember this direction was computed
-
- end
-
- %% Compute full gradient of Q
-
- dQ = r + M*W;
-
- %% Compute new W
- if i == 1
- if positive
- dQa = dQ;
- else
- dQa = abs(dQ);
- end
- [lambda, new] = max(dQa(:));
-
- if lambda < 0
- disp('All negative directions!')
- break
- end
-
- else
-
- % calculate vector to travel along
-
-% disp('calc velocity')
-
- [avec, gamma_plus, gamma_minus] = calcAvec(new, dQ, W, lambda, active_set, M, positive);
-
- % calculate time of travel and next new direction
-
- if new==0 % if we just dropped a direction we don't allow it to emerge
- if dropped_sign == 1 % with the same sign
- gamma_plus(dropped) = inf;
- else
- gamma_minus(dropped) = inf;
- end
- end
-
-
- gamma_plus(active_set == 1) = inf; % don't consider active components
- gamma_plus(gamma_plus <= 0) = inf; % or components outside the range [0, lambda]
- gamma_plus(gamma_plus> lambda) =inf;
- [gp_min, gp_min_ind] = min(gamma_plus(:));
-
-
- if positive
- gm_min = inf; % don't consider new directions that would grow negative
- else
- gamma_minus(active_set == 1) = inf;
- gamma_minus(gamma_minus> lambda) =inf;
- gamma_minus(gamma_minus <= 0) = inf;
- [gm_min, gm_min_ind] = min(gamma_minus(:));
-
- end
-
- [g_min, which] = min([gp_min, gm_min]);
-
- if g_min == inf; % if there are no possible new components, try move to the end
- g_min = lambda; % This happens when all the components are already active or, if positive==1, when there are no new positive directions
- end
-
-
-
- % LARS check (is g_min*avec too large?)
- gamma_zero = -W(active_set == 1) ./ avec;
- gamma_zero_full = zeros(N,k);
- gamma_zero_full(active_set == 1) = gamma_zero;
- gamma_zero_full(gamma_zero_full <= 0) = inf;
- [gz_min, gz_min_ind] = min(gamma_zero_full(:));
-
- if gz_min < g_min
- if verbose
- fprintf('DROPPING active weight: %d.\n', gz_min_ind)
- end
- active_set(gz_min_ind) = 0;
- dropped = gz_min_ind;
- dropped_sign = sign(W(dropped));
- W(gz_min_ind) = 0;
- avec = avec(gamma_zero ~= gz_min);
- g_min = gz_min;
- new = 0;
-
- elseif g_min < lambda
- if which == 1
- new = gp_min_ind;
- if verbose
- fprintf('new positive component: %d.\n', new)
- end
- else
- new = gm_min_ind;
- fprintf('new negative component: %d.\n', new)
- end
- end
-
- W(active_set == 1) = W(active_set == 1) + g_min * avec;
-
- if positive
- if any (W<0)
- min(W);
- flag = 1;
- %error('negative W component');
- end
- end
-
- lambda = lambda - g_min;
- end
-
-
-
-
-%% Update weights and lambdas
-
- lambdas(i) = lambda;
- Ws(:,:,i)=W;
- res = norm(Y-X*W,'fro')^2;
-%% Check finishing conditions
-
-
- if lambda ==0 || (new && sum(active_set(:)) == maxcomps) || (res < noise)
- if verbose
- fprintf('end. \n');
- end
-
- break
- end
-
-%%
- if new
- active_set(new) = 1;
- end
-
-
- i = i + 1;
-end
-%% end main loop
-
-%% final calculation of mus
-if flag == 0
- if i > 1
- Ws= squeeze(Ws(:,:,1:length(lambdas)));
- w_dir = -(Ws(:,i) - Ws(:,i-1))/(lambdas(i)-lambdas(i-1));
- Aw = X*w_dir;
- y_res = Y - X*(Ws(:,i-1) + w_dir*lambdas(i-1));
- ld = roots([norm(Aw)^2,-2*(Aw'*y_res),y_res'*y_res-noise]);
- lam = ld(intersect(find(ld>lambdas(i)),find(ld= 0;
- norm(Y-X*W_lam)<= sqrt(noise);
- cvx_end
- lam = 10;
- end
-else
- W_lam = 0;
- Ws = 0;
- lambdas = 0;
- lam = 0;
-end
-end
-
-%%%%%%%%%% begin auxiliary functions %%%%%%%%%%
-
-
-%%
-function [avec, gamma_plus, gamma_minus] = calcAvec(new, dQ, W, lambda, active_set, M, positive)
-
-[r,c] = find(active_set);
-Mm = -M(r,r);
-
-
-Mm=(Mm + Mm')/2;
-
-% verify that there is no numerical instability
-eigMm = eig(Mm);
-if any(eigMm < 0)
- min(eigMm)
- %error('The matrix Mm has negative eigenvalues')
- flag = 1;
-end
-
-
-b = sign(W);
-if new
- b(new) = sign(dQ(new));
-end
-b = b(active_set == 1);
-
-avec = Mm\b;
-
-if positive
- if new
- in = sum(active_set(1:new));
- if avec(in) <0
- new;
- %error('new component of a is negative')
- flag = 1;
- end
- end
-end
-
-
-
-one_vec = ones(size(W));
-
-dQa = zeros(size(W));
-for j=1:length(r)
- dQa = dQa + avec(j)*M(:, r(j));
-end
-
-gamma_plus = (lambda - dQ)./(one_vec + dQa);
-gamma_minus = (lambda + dQ)./(one_vec - dQa);
-
-end
diff --git a/deconvolveCa/constrained-foopsi/license.txt b/deconvolveCa/constrained-foopsi/license.txt
deleted file mode 100644
index d159169..0000000
--- a/deconvolveCa/constrained-foopsi/license.txt
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- , 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/deconvolveCa/deconvolveCa.m b/deconvolveCa/deconvolveCa.m
deleted file mode 100644
index 75ed71d..0000000
--- a/deconvolveCa/deconvolveCa.m
+++ /dev/null
@@ -1,328 +0,0 @@
-function [c, s, options] = deconvolveCa(y, varargin)
-%% infer the most likely discretized spike train underlying an fluorescence trace
-%% Solves mutliple formulation of the problem
-% 1) FOOPSI,
-% mininize_{c,s} 1/2 * norm(y-c,2)^2 + lambda * norm(s,1)
-% subject to c>=0, s>=0, s=Gc
-% 2) constrained FOOPSI
-% minimize_{c,s} norm(s, q)
-% subject to norm(y-c,2) <= sn*sqrt(T), c>=0, s>=0, s=Gc
-% where q is either 1 or 0, rendering the problem convex or non-convex.
-% 3) hard threshrinkage
-% minimize_{c,s} 1/2 * norm(y-c, 2)^2
-% subjec to c>=0, s=Gc, s=0 or s>=smin
-% 4) Nonnegative least square problem (NNLS)
-% min_{s} norm(y - s*h, 2)^2 + lambda * norm(s,1)
-% subject to s>=0
-
-%% inputs:
-% y: T x 1 vector, fluorescence trace
-% varargin: variable input arguments
-% type: string, defines the model of the deconvolution kernel. possible
-% options are:
-% 'ar1': auto-regressive model with order p=1
-% 'ar2': auto-regressive model with order p=2
-% 'exp2': the convolution kernel is modeled as the difference of two
-% exponential functions -
-% h(t) = (exp(-t/tau_d) - exp(-t/tau_r)) / (tau_d-tau_r)
-% 'kernel': a vector of the convolution kernel
-% pars: parameters for the specified convolution kernel. it has
-% different shapes for differrent types of the convolution model:
-% 'ar1': scalar
-% 'ar2': 2 x 1 vector, [r_1, r_2]
-% 'exp2': 2 x 1 vector, [tau_r, tau_d]
-% 'kernel': maxISI x 1 vector, the kernel.
-% sn: scalar, standard deviation of the noise distribution. If no
-% values is give, then sn is estimated from the data based on power
-% spectual density method.
-% b: fluorescence baseline vlaues. default is 0
-% optimize_pars: estimate the parameters of the convolution kernel. default: 0
-% optimize_b: estimate the baseline. default: 0
-% lambda: penalty parameter
-% method: methods for running deconvolution. {'foopsi',
-% 'constrained_foopsi' (default), 'thresholded'},
-
-%% outputs:
-% c: T x 1 vector, denoised trace
-% s: T x 1 vector, deconvolved signal
-% b: fluorescence baseline
-% kernel: struct variable containing the parameters for the selected
-% convolution model
-% lambda: Optimal Lagrange multiplier for noise constraint under L1 penalty
-% """olves the noise constrained sparse nonnegat
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-%% input arguments
-y = reshape(y, [], 1); % reshape the trace as a vector
-options = parseinputs(varargin{:}); % parse input arguments
-if isempty(y)
- c = []; s = [];
- return;
-end
-win = options.window; % length of the convolution kernel
-% estimate the noise
-if isempty(options.sn)
- options.sn = GetSn(y);
-end
-% estimate time constant
-if isempty(options.pars) || all(options.pars==0)
- switch options.type
- case 'ar1'
- try
- options.pars = estimate_time_constant(y, 1, options.sn);
- catch
- c = y*0;
- s = c;
- fprintf('fail to deconvolve the trace\n');
- return;
- end
- if length(options.pars)~=1
- c = zeros(size(y));
- s = zeros(size(y));
- options.pars = 0;
- return;
- end
- case 'ar2'
- options.pars = estimate_time_constant(y, 2, options.sn);
- if length(options.pars)~=2
- c = zeros(size(y));
- s = zeros(size(y));
- options.pars =[0,0];
- return;
- end
- case 'exp2'
- g = estimate_time_constant(y, 2, options.sn);
- options.pars = ar2exp(g);
- case 'kernel'
- g = estimate_time_constant(y, 2, options.sn);
- taus = ar2exp(g);
- options.pars = exp2kernel(taus, options.win); % convolution kernel
- end
-end
-
-%% run deconvolution
-c = y;
-s = y;
-switch lower(options.method)
- case 'foopsi' %% use FOOPSI
- if strcmpi(options.type, 'ar1') % AR 1
- if options.smin<0
- options.smin = abs(options.smin)*options.sn;
- end
-
- gmax = exp(-1/options.max_tau);
- [c, s, options.b, options.pars] = foopsi_oasisAR1(y-options.b, options.pars, options.lambda, ...
- options.smin, options.optimize_b, options.optimize_pars, [], options.maxIter, gmax);
- elseif strcmpi(options.type, 'ar2') % AR 2
- if options.smin<0
- options.smin = abs(options.smin)*options.sn/max_ht(options.pars);
- end
- [c, s, options.b, options.pars] = foopsi_oasisAR2(y-options.b, options.pars, options.lambda, ...
- options.smin);
- elseif strcmpi(options.type, 'exp2') % difference of two exponential functions
- kernel = exp2kernel(options.pars, options.window);
- [c, s] = onnls(y-options.b, kernel, options.lambda, ...
- options.shift, options.window);
- elseif strcmpi(options.type, 'kernel') % convolution kernel itself
- [c, s] = onnls(y-options.b, options.pars, options.lambda, ...
- options.shift, options.window);
- else
- disp('to be done');
- end
- case 'constrained'
- if strcmpi(options.type, 'ar1') % AR1
- [c, s, options.b, options.pars, options.lambda] = constrained_oasisAR1(y,...
- options.pars, options.sn, options.optimize_b, options.optimize_pars, ...
- [], options.maxIter);
- else
- [cc, options.b, c1, options.pars, options.sn, s] = constrained_foopsi(y,[],[],options.pars,options.sn, ...
- options.extra_params);
- gd = max(roots([1,-options.pars'])); % decay time constant for initial concentration
- gd_vec = gd.^((0:length(y)-1));
- c = cc(:) + c1*gd_vec';
- options.cin = c1;
- end
- case 'thresholded' %% Use hard-shrinkage method
- if strcmpi(options.type, 'ar1')
- [c, s, options.b, options.pars, options.smin] = thresholded_oasisAR1(y,...
- options.pars, options.sn, options.optimize_b, options.optimize_pars, ...
- [], options.maxIter, options.thresh_factor, options.p_noise);
- % if and(options.smin==0, options.optimize_smin) % smin is given
- % [c, s, options.b, options.pars, options.smin] = thresholded_oasisAR1(y,...
- % options.pars, options.sn, options.optimize_b, options.optimize_pars, ...
- % [], options.maxIter, options.thresh_factor);
- % else
- % [c, s] = oasisAR1(y-options.b, options.pars, options.lambda, ...
- % options.smin);
- % end
- elseif strcmpi(options.type, 'ar2')
- [c, s, options.b, options.pars, options.smin] = thresholded_oasisAR2(y,...
- options.pars, options.sn, options.smin, options.optimize_b, options.optimize_pars, ...
- [], options.maxIter, options.thresh_factor);
- % if and(options.smin==0, options.optimize_smin) % smin is given
- % [c, s, options.b, options.pars, options.smin] = thresholded_oasisAR2(y,...
- % options.pars, options.sn, options.optimize_b, options.optimize_pars, ...
- % [], options.maxIter, options.thresh_factor);
- % else
- % [c, s] = oasisAR2(y-options.b, options.pars, options.lambda, ...
- % options.smin);
- % end
- elseif strcmpi(options.type, 'exp2') % difference of two exponential functions
- d = options.pars(1);
- r = options.pars(2);
- options.pars = (exp(log(d)*(1:win)) - exp(log(r)*(1:win))) / (d-r); % convolution kernel
- [c, s] = onnls(y-options.b, options.pars, options.lambda, ...
- options.shift, options.window, [], [], [], options.smin);
- elseif strcmpi(options.type, 'kernel') % convolution kernel itself
- [c, s] = onnls(y-options.b, options.pars, options.lambda, ...
- options.shift, options.window, [], [], [], options.smin);
- else
- disp('to be done');
- end
- case 'mcmc'
- SAMP = cont_ca_sampler(y,options.extra_params);
- options.extra_params = SAMP;
- options.mcmc_results = SAMP;
- plot_continuous_samples(SAMP,y);
-end
-
-function options=parseinputs(varargin)
-%% parse input variables
-
-%% default options
-options.type = 'ar1';
-options.pars = [];
-options.sn = [];
-options.b = 0;
-options.lambda = 0;
-options.optimize_b = false;
-options.optimize_pars = false;
-options.optimize_smin = false;
-options.method = 'constrained';
-options.window = 200;
-options.shift = 100;
-options.smin = 0;
-options.maxIter = 10;
-options.thresh_factor = 1.0;
-options.extra_params = [];
-options.p_noise = 0.9999;
-options.max_tau = 100;
-
-if isempty(varargin)
- return;
-elseif isstruct(varargin{1}) && ~isempty(varargin{1})
- tmp_options = varargin{1};
- field_nams = fieldnames(tmp_options);
- for m=1:length(field_nams)
- eval(sprintf('options.%s=tmp_options.%s;', field_nams{m}, field_nams{m}));
- end
- k = 2;
-else
- k = 1;
-end
-%% parse all input arguments
-while k<=nargin
- if isempty(varargin{k})
- k = k+1;
- end
- switch lower(varargin{k})
- case {'ar1', 'ar2', 'exp2', 'kernel'}
- % convolution kernel type
- options.type = lower(varargin{k});
- if (k
-end
-fprintf('FOOPSI: %.3f seconds\n', toc);
-fprintf('\n**************AR 1**************\n');
-
-%% AR(2)
-% simulation
-g = [1.7, -0.712];
-sn = 1;
-seed = 3;
-[Y, trueC, trueSpikes] = gen_data(g, sn, [], [], [], [], [], seed);
-[N, T] = size(Y);
-
-% deconvolution
-lam = 25;
-[c_onnls, s_onnls] = onnls(Y(1,:), g, lam);
-[c_foopsi, s_foopsi] = foopsi(Y(1,:), g, lam);
-figure('papersize', [15, 4]);
-init_fig;
-
-% plot results
-figure('papersize', [15, 4]);
-init_fig;
-
-% c
-axes('position', [.05, .57, .46, .37]);
-hold on;
-plot(Y(1,:), 'color', col{8}/255, 'linewidth', 0.5);
-alpha(.7);
-plot(trueC(1,:), 'color', col{3}/255, 'linewidth', 1.5);
-plot(c_onnls, 'color', col{1}/255);
-plot(c_foopsi, '--', 'color', col{7}/255);
-axis tight;
-xlim([0, 1200]);
-set(gca, 'xtick', 0:300:1500);
-set(gca, 'xticklabel', []);
-ylim(round([1+min(Y(1,:)), max(Y(1,:))-0.5]));
-ylabel('Fluor.');
-box off;
-% s
-axes('position', [.05, .18, .46, .37]);
-hold on;
-plot(trueSpikes(1,:), 'color', col{3}/255, 'linewidth', 1.5);
-plot(s_onnls, 'color', col{1}/255);
-plot(s_foopsi, '--', 'color', col{7}/255);
-axis tight;
-xlim([0, 1200]);
-set(gca, 'xtick', 0:300:1500);
-set(gca, 'xticklabel', get(gca, 'xtick')/30);
-set(gca, 'ytick', [0,1]);
-xlabel('Time [s]');
-ylabel('Activity.');
-
-%% timeit
-fprintf('\n**************AR 2**************\n');
-tic;
-for m=1:N
- [c_onnls, s_onnls] = onnls(Y(m,:), g, lam);
-end
-fprintf('online NNLS: %.3f seconds\n', toc);
-
-tic;
-for m=1:N
- [c_foopsi, s_foopsi] = foopsi(Y(m,:), g, lam);
-end
-fprintf('FOOPSI: %.3f seconds\n', toc);
-fprintf('\n**************AR 2**************\n');
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deconvolveCa/examples/Paper/fig4.m b/deconvolveCa/examples/Paper/fig4.m
deleted file mode 100644
index ee8b7fc..0000000
--- a/deconvolveCa/examples/Paper/fig4.m
+++ /dev/null
@@ -1,150 +0,0 @@
-%%
-close all; clc;
-addpath('./scripts');
-col = {[0 114 178],[0 158 115], [213 94 0],[230 159 0],...
- [86 180 233], [204 121 167], [64 224 208], [240 228 66]};
-figure('papersize', [14.4, 7.2]);
-init_fig;
-
-%% load the test data
-gam = 0.95;
-sn = .3;
-T = 1500;
-lam = 0;
-load fig4_data;
-y = reshape(y, [],1);
-g = .9;
-g0 = g;
-ax0 = .06;
-ax1 = .2;
-
-%% plot initial result
-[solution, spks, active_set] = oasisAR1(y, g, lam);
-axes('position', [ax1, 0.87, 1-ax1, .12]);
-fig4_plot_trace;
-legend('Data', 'Truth', 'Estimate', 'orientation', 'horizental',...
- 'location', [0.01+ax1, 0.96, 0.35, 0.0345]);
-
-%% solve for lambda
-c = solution;
-temp = zeros(size(c));
-len_active_set = size(active_set,1);
-for ii=1:len_active_set
- ti = active_set(ii, 3);
- li = active_set(ii, 4);
- idx = 0:(li-1);
- temp(ti+idx) = (1-g^li)/ active_set(ii,2) * g.^(idx);
-end
-res = y - solution;
-aa = temp'*temp;
-bb = res'*temp;
-cc = res'*res - sn^2*T;
-active_set_0 = active_set;
-ll = (-bb + sqrt(bb^2-aa*cc)) / aa;
-active_set_0(:,1) = active_set_0(:,1) - ll*(1-g.^(active_set_0(:,4)));
-spks = 0*spks;
-for ii=1:len_active_set
- ti = active_set(ii, 3);
- li = active_set(ii, 4);
- idx = 0:(li-1);
- solution(ti+idx) = active_set_0(ii,1)/active_set_0(ii,2) * (g.^(idx));
- if ii>1
- spks(ti) = solution(ti) - g*solution(ti-1);
- end
-end
-
-% plot results after updating lambda, but before running oasis to fix
-% violations
-axes('position', [ax1, .73, 1-ax1, .12]);
-fig4_plot_trace;
-
-% plot the depence of RSS on lambda
-lam_vec = linspace(0, 2.0, 100);
-RSS_vec = zeros(size(lam_vec));
-for m=1:length(lam_vec);
- RSS_vec(m) = norm((res-lam_vec(m)*temp),2)^2;
-end
-
-axes('position', [ax0, .75, .08, .12]); hold on;
-plot(lam_vec, RSS_vec, 'color', col{2}/255);
-
-% the optimal value
-thresh = sn.^2 * T;
-plot([-.1, ll], thresh*[1,1], 'k');
-plot([ll, ll], [100, thresh], 'k');
-scatter(0, RSS_vec(1), 50, col{1}/255);
-xlim([0, 1.7]);
-ylim([114, 138]);
-set(gca,'ytick', thresh);
-set(gca, 'yticklabel', '\sigma^2T');
-set(gca, 'xtick', [0,lam+ll]);
-set(gca, 'xticklabel', {0, '\lambda^*'});
-
-%% plot result after rerunning oasis to fix violations
-lam = lam + ll;
-[solution, spks, active_set] = oasisAR1(y, g, lam, [], active_set_0);
-axes('position', [ax1, .59, 1-ax1, .12]);
-fig4_plot_trace;
-ylabel('Fluorescence');
-
-%% solve for gamma
-[~, ~, g] = update_g(y, active_set,g, lam);
-axes('position', [ax0, .47, .08, .12]); hold on;
-g_vec = linspace(.85, 0.99);
-rss_vec = compute_rss_g(g_vec, y, active_set, lam);
-plot(g_vec, rss_vec, 'color', col{2}/255);
-xlim([min(g_vec), max(g_vec)]);
-scatter(g0, compute_rss_g(g0, y, active_set, lam), 50, col{1}/255, 'filled');
-set(gca, 'xtick', g);
-set(gca, 'xticklabel', '\gamma^*');
-set(gca,'ytick', thresh);
-set(gca, 'yticklabel', '\sigma^2T');
-% plot result after updating gamma, but before rerunning oasis to fix
-% violations
-len_active_set = size(active_set, 1);
-ma = max(active_set(:, 4));
-h = g.^((0:ma)');
-hh = cumsum(h.*h);
-for ii=1:len_active_set
- ti = active_set(ii,3);
- li = active_set(ii,4);
- idx = ti:(ti+li-1);
- active_set(ii,1) = (y(idx)-lam*(1-g))'*h(1:li);
- active_set(ii,2) = hh(li);
-end
-for ii=1:length(active_set_0)
- ti = active_set_0(ii,3);
- li = active_set_0(ii,4);
- idx = ti:(ti+li-1);
- solution(idx) = active_set_0(ii,1)/active_set_0(ii,2) * h(1:li);
-end
-solution(solution<0) = 0;
-spks = [0; solution(2:end)-g*solution(1:(end-1))];
-axes('position', [ax1, .45, 1 - ax1, .12]); hold on;
-fig4_plot_trace;
-
-%% plot result after rerunning oasis to fix violatiosn
-[solution, spks, active_set] = oasisAR1(y, g, lam,[], active_set);
-axes('position', [ax1, .31, 1 - ax1, .12]); hold on;
-fig4_plot_trace;
-
-%% do more iterations
-for miter=1:3
- [~, active_set, lam, ~] = update_lam(y, solution, active_set, g, lam, thresh);
- [solution, active_set, g, spks] = update_g(y, active_set, g, lam);
-end
-axes('position', [ax1, .07, 1 - ax1, .12]);
-hold on;
-fig4_plot_trace;
-sol_given_g = constrained_oasisAR1(y, .95, sn);
-estimated_g = estimate_parameters(y, 1);
-fprintf('\n*******************\n');
-fprintf('estimated gamma via autocorrelation: %.4f\n', estimated_g);
-fprintf('optimized gamma : %.4f\n', g);
-fprintf('\n*******************\n');
-sol_PSD_g = constrained_oasisAR1(y, estimated_g, 0);
-h1 = plot(sol_given_g, '--', 'color', col{7}/255);
-h2 = plot(sol_PSD_g, 'color', col{6}/255);
-legend([h1, h2], 'true \gamma', '\gamma from autocovariance', ...
- 'orientation', 'horizontal', 'location', [0.01+ax1, 0.16, 0.35, 0.0345]);
-saveas(gcf, 'fig/opt_g+l_new.pdf')
\ No newline at end of file
diff --git a/deconvolveCa/examples/Paper/fig5.m b/deconvolveCa/examples/Paper/fig5.m
deleted file mode 100644
index cc7440e..0000000
--- a/deconvolveCa/examples/Paper/fig5.m
+++ /dev/null
@@ -1,191 +0,0 @@
-%%
-clear; clc; close all;
-col = {[0 114 178],[0 158 115], [213 94 0],[230 159 0],...
- [86 180 233], [204 121 167], [64 224 208], [240 228 66]};
-
-%% AR (1)
-% simulation
-g = .95;
-sn = .3;
-[Y, trueC, trueSpikes] = gen_data(g, sn, [], [],[], [], 1, 10);
-y = Y(1, :);
-
-% run deconvolution
-[c, s] = constrained_foopsi_cvx(y, g, sn);
-[c_t, s_t] = oasisAR1(y, g, 0, .55);
-
-% check the dependence on smin
-smin = 0:0.1:1.1;
-res = zeros(length(smin), length(y));
-for m=1:length(smin)
- [~, res(m, :)] = oasisAR1(y, g, 0, smin(m));
-end
-% plot results
-figure('papersize', [10,9]);
-init_fig;
-ymax = ceil(max(y)*2)/2;
-ymin = quantile(y(1:500), 0.02);
-% c
-axes('position', [.13, .7, .86, .29]); hold on;
-plot(y, 'color', col{8}/255);
-alpha(.7);
-plot(trueC(1, :), 'color', col{3}/255, 'linewidth', 3);
-plot(c, 'color', col{1}/255);
-plot(c_t, 'color', col{2}/255);
-legend('Data', 'Truth', 'Thresh', 'L1', 'orientation', 'horizental');
-ylim([ymin, ymax]);
-xlim([0, 452]);
-set(gca, 'xtick', 0:150:500);
-set(gca, 'xticklabel', []);
-set(gca, 'ytick', 0:1:ymax);
-ylabel('Fluor.');
-
-%s
-axes('position', [.13, .39, .86, .29]); hold on;
-for m=find(trueSpikes(1,1:500))
- plot([m, m], [0, 1], 'color', col{3}/255);
-end
-plot([0, 450], [0, 0], 'color', col{3}/255);
-for m=find(s(1:500))
- plot([m, m], [0, s(m)]+2.5, 'color', col{1}/255);
-end
-plot([0, 450], [1, 1]*2.5, 'color', col{1}/255);
-for m=find(s_t(1:500)')
- plot([m, m], [0, s_t(m)]+1.25, 'color', col{2}/255);
-end
-plot([0, 450], [1, 1]*1.25, 'color', col{2}/255);
-
-ylim([0, 3.5]);
-xlim([0, 452]);
-set(gca, 'xtick', 0:150:500);
-set(gca, 'xticklabel', []);
-set(gca, 'ytick', 0:1.25: 2.5);
-set(gca, 'yticklabel', {'Thresh.', 'Truth', 'L1'})
-
-% dependence on smin
-axes('position', [.13, .08, .86, .29]); hold on;
-for m=find(trueSpikes(1,1:500))
- plot([m, m], [-.08, -0.16], 'r');
-end
-for rr=1:length(smin)
- for m=find(res(rr, 1:500))
- plot([m, m], rr*.1+[-0.14, -0.06], 'color', 'k');
- end
-end
-
-ylim([-0.2, smin(end)]);
-xlim([0, 452]);
-set(gca, 'xtick', 0:150:500);
-set(gca, 'xticklabel', get(gca, 'xtick')/30)
-set(gca, 'ytick', 0:0.5:1);
-ylabel('s_{min}');
-
-saveas(gcf, 'fig/threshAR1.pdf');
-
-
-%% AR (2)
-% simulation
-g = [1.7, -0.712];
-sn = 1;
-seed = 1;
-[Y, trueC, trueSpikes] = gen_data(g, sn, [],[],[],[], [], seed);
-% Y(:, 1:150) = [];
-% trueC(:,1:150) = [];
-% trueSpikes(:,1:150) = [];
-y = Y(1, :);
-
-% run deconvolution
-[c, s] = constrained_foopsi_cvx(y, g, sn);
-[c_t, s_t] = oasisAR2(y, g, 0, .55);
-
-% check the dependence on smin
-smin = 0:0.1:1.1;
-res = zeros(length(smin), length(y));
-for m=1:length(smin)
- [~, res(m, :)] = oasisAR2(y, g, 0, smin(m));
-end
-% plot results
-figure('papersize', [10,9]);
-init_fig;
-ymax = ceil(max(y)*2)/2;
-ymin = quantile(y(1:500), 0.02);
-% c
-axes('position', [.13, .7, .86, .29]); hold on;
-plot(y, 'color', col{8}/255);
-alpha(.7);
-plot(trueC(1, :), 'color', col{3}/255, 'linewidth', 3);
-plot(c, 'color', col{1}/255);
-plot(c_t, 'color', col{2}/255);
-legend('Data', 'Truth', 'Thresh', 'L1', 'orientation', 'horizental');
-ylim([ymin, ymax]);
-xlim([0, 452]);
-set(gca, 'xtick', 0:150:500);
-set(gca, 'xticklabel', []);
-set(gca, 'ytick', 0:1:ymax);
-ylabel('Fluor.');
-
-%s
-axes('position', [.13, .39, .86, .29]); hold on;
-for m=find(trueSpikes(1,1:500))
- plot([m, m], [0, 1], 'color', col{3}/255);
-end
-plot([0, 450], [0, 0], 'color', col{3}/255);
-for m=find(s(1:500))
- plot([m, m], [0, s(m)]+2.5, 'color', col{1}/255);
-end
-plot([0, 450], [1, 1]*2.5, 'color', col{1}/255);
-for m=find(s_t(1:500)')
- plot([m, m], [0, s_t(m)]+1.25, 'color', col{2}/255);
-end
-plot([0, 450], [1, 1]*1.25, 'color', col{2}/255);
-
-ylim([0, 3.5]);
-xlim([0, 452]);
-set(gca, 'xtick', 0:150:500);
-set(gca, 'xticklabel', []);
-set(gca, 'ytick', 0:1.25: 2.5);
-set(gca, 'yticklabel', {'Thresh.', 'Truth', 'L1'})
-
-% dependence on smin
-axes('position', [.13, .08, .86, .29]); hold on;
-for m=find(trueSpikes(1,1:500))
- plot([m, m], [-.08, -0.16], 'r');
-end
-for rr=1:length(smin)
- for m=find(res(rr, 1:500))
- plot([m, m], rr*.1+[-0.14, -0.06], 'color', 'k');
- end
-end
-
-ylim([-0.2, smin(end)]);
-xlim([0, 452]);
-set(gca, 'xtick', 0:150:500);
-set(gca, 'xticklabel', get(gca, 'xtick')/30)
-set(gca, 'ytick', 0:0.5:1);
-ylabel('s_{min}');
-
-saveas(gcf, 'fig/threshAR2.pdf');
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deconvolveCa/examples/Paper/fig6.m b/deconvolveCa/examples/Paper/fig6.m
deleted file mode 100644
index 0d6d0c4..0000000
--- a/deconvolveCa/examples/Paper/fig6.m
+++ /dev/null
@@ -1,7 +0,0 @@
-%%
-close all; clc;
-addpath('./scripts');
-col = {[0 114 178],[0 158 115], [213 94 0],[230 159 0],...
- [86 180 233], [204 121 167], [64 224 208], [240 228 66]};
-figure('papersize', [14, 7]);
-init_fig;
\ No newline at end of file
diff --git a/deconvolveCa/examples/Paper/scripts/compute_rss_g.m b/deconvolveCa/examples/Paper/scripts/compute_rss_g.m
deleted file mode 100644
index 503eb36..0000000
--- a/deconvolveCa/examples/Paper/scripts/compute_rss_g.m
+++ /dev/null
@@ -1,65 +0,0 @@
-function rss_vec = compute_rss_g(g, y, Aset, lam)
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% Aset: npools*4 matrix, previous active sets
-% g: scalar, Parameter of the AR(1) process that models the fluorescence ...
-%impulse response.
-% lam: scalar, curret value of sparsity penalty parameter lambda.
-
-%% outputs
-% rss_vec: vector with the same elements as g.
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-
-%% initialization
-len_active_set = size(Aset, 1); %number of active sets
-y = reshape(y,[],1); % fluorescence data
-maxl = max(Aset(:, 4)); % maximum ISI
-c = zeros(size(y)); % the optimal denoised trace
-
-%% function for computing the optimal RSS given fixed AR coefficient g and the active set
- function rss = rss_g(g)
- yp = y - lam*(1-g); % include the penalty term
- h = exp(log(g)*(0:maxl)'); % response kernel
- hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- for ii=1:len_active_set
- li = Aset(ii, 4);
- ti = Aset(ii, 3);
- idx = ti:(ti+li-1);
- tmp_v = yp(idx)' * h(1:li) / hh(li);
- c(idx) = tmp_v*h(1:li);
- end
- res = y-c;
- rss = res'*res; % residual sum of squares
- end
-
-rss_vec = zeros(size(g));
-for m=1:length(g)
- rss_vec(m) = rss_g(g(m));
-end
-end
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deconvolveCa/examples/Paper/scripts/fig2_demo_deconvolveAR1.m b/deconvolveCa/examples/Paper/scripts/fig2_demo_deconvolveAR1.m
deleted file mode 100644
index cabaf37..0000000
--- a/deconvolveCa/examples/Paper/scripts/fig2_demo_deconvolveAR1.m
+++ /dev/null
@@ -1,222 +0,0 @@
-function c = fig2_demo_deconvolveAR1(y, g, lam, video, trueSpikes)
-%% extract neural activity from a fluorescence trace using an active set
-% method for sparse nonnegative deconvolution
-
-%% inputs:
-% y: T*1 vector, raw fluorescence trace
-% g: scalar, AR(1) coefficient
-% lam: scalar, tuning parameter for sparsity
-
-%% outputs
-% c: T*1 vector, denoised trace
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% proted from the Python implementation from Johannes Friedrich
-
-%% initialization
-y = reshape(y, [], 1);
-if ~exist('g', 'var') || isempty(g); g = 0.95; end
-if ~exist('lam', 'var') || isempty(lam); lam = 0; end
-
-len_active_set = length(y);
-Aset = ones(len_active_set, 4); % each row is one pool: (vi, wi, t, l)
-Aset(:,1) = y - lam; % vi
-Aset(:,3) = (1:len_active_set); % ti
-Aset(end, 1) = y(end) - lam/(1-g);
-Aset(end, 3) = len_active_set;
-Aset(1,1) = max(Aset(1,1), 0);
-
-%% run OASIS
-ii = 1;
-counter = 1;
-if video
- figure('papersize', [15, 6]);
- init_fig;
- avi_file = VideoWriter('fig/Video.avi');
- avi_file.FrameRate = 10;
- avi_file.open();
-else
- figure('papersize', [3,3]);
- init_fig;
-end
-while ii < len_active_set
- % find the active set
- while (ii=Aset(ii,1)*g^(Aset(ii,4)))
- ii = ii + 1;
- end
-
- if ii == len_active_set; break; end
-
- if video
- cb_video(y, Aset, g, ii, trueSpikes);
- avi_file.writeVideo(getframe(gcf));
- else
- cb(y, Aset, g, counter, ii, trueSpikes);
- end
- counter = counter+1;
- %% merge pools
- while ii>0 && (Aset(ii+1,1) < Aset(ii,1)*g^(Aset(ii,4)))
- temp = Aset(ii,2) + Aset(ii+1,2)*(g^(2*Aset(ii, 4)));
- Aset(ii,1) = (Aset(ii,1)*Aset(ii,2) + Aset(ii+1,1)*Aset(ii+1, 2)* ...
- (g^(Aset(ii,4)))) / temp;
- if ii==1
- Aset(ii,1) = max(Aset(ii,1), 0);
- end
- Aset(ii, 2) = temp;
- Aset(ii, 4) = Aset(ii, 4) + Aset(ii+1, 4);
- Aset(ii+1, :) = [];
- ii = ii - 1;
- end
-
- ii = ii + 1;
- len_active_set = size(Aset,1);
-end
-
-%% construct solution for all t
-c = zeros(size(y));
-c(Aset(:, 3)) = Aset(:, 1);
-for ii=1:len_active_set
- t0 = Aset(ii,3);
- tau = Aset(ii, 4);
- c(t0:(t0+tau-1)) = Aset(ii,1) * (g.^(0:(tau-1)));
-end
-if video
- avi_file.close();
-end
-end
-
-function cb(y, Aset, g, counter, current, trueSpikes)
-%% function for taking snapshot of OASIS procedures
-if ~exist('fig', 'dir')
- mkdir fig;
-end
-len_active_set = size(Aset,1);
-% construct solution
-c = zeros(size(y));
-Aset(:,1) = max(0, Aset(:, 1));
-c(Aset(:, 3)) = Aset(:, 1);
-for ii=1:len_active_set
- t0 = Aset(ii,3);
- tau = Aset(ii, 4);
- c(t0:(t0+tau-1)) = Aset(ii,1) * (g.^(0:(tau-1)));
-end
-% plot results
-clf; hold on;
-% use different color to separate pools
-ymax = 1.2;
-for m=1:2:len_active_set
- t0 = Aset(m, 3);
- t1 = Aset(m, 3) + Aset(m, 4);
- fill([t0+0.1, t1, t1, t0+0.1], [0.01, 0.01, ymax, ymax], [1,1,1]*0.9, 'edgecolor', 'w');
-end
-temp = find(trueSpikes);
-for m=1:length(temp);
- plot([1, 1]*temp(m), [0, ymax], 'r', 'linewidth', 3);
-end
-ind = 48-ceil((y-min(y))/range(y)*16);
-col_map = jet();
-col = col_map(ind, :);
-% current estimation of c
-plot(c, 'color', 'k', 'linewidth', 2);
-scatter(1:length(y), c, 100, col, 'filled', 'markeredgecolor', 'k');
-% scatter plot the current pool
-t = Aset(current, 3)+(1:Aset(current, 4));
-plot(t, c(t), '+b', 'markersize', 10);
-ylim([-0, ymax]);
-xlim([1, length(y)-1]);
-set(gca, 'xtick', []);
-set(gca, 'ytick', []);
-box off;
-pause(.1);
-saveas(gcf, sprintf('fig/%d.pdf', counter));
-end
-
-
-function cb_video(y, Aset, g, current, trueSpikes)
-%% function for taking snapshot of OASIS procedures and save the results as a video
-if ~exist('fig', 'dir')
- mkdir fig;
-end
-len_active_set = size(Aset,1);
-% construct solution
-c = zeros(size(y));
-c(Aset(:, 3)) = Aset(:, 1);
-for ii=1:len_active_set
- t0 = Aset(ii,3);
- tau = Aset(ii, 4);
- c(t0:(t0+tau-1)) = Aset(ii,1) * (g.^(0:(tau-1)));
-end
-s = c;
-for t=2:length(y)
- s(t) = c(t) - g*c(t-1);
-end
-% plot results
-clf;
-axes('position', [0.05, 0.55, 0.9, 0.4]); cla; hold on;
-ymax = 1.8;
-% use different color to separate pools
-for m=1:2:len_active_set
- t0 = Aset(m, 3);
- t1 = Aset(m, 3) + Aset(m, 4);
- fill([t0, t1, t1, t0], [0.01, 0.01, ymax, ymax], [1,1,1]*0.9, 'edgecolor', 'w');
-end
-temp = find(trueSpikes);
-for m=1:length(temp);
- plot([1, 1]*temp(m), [0, ymax], 'r', 'linewidth', 3);
-end
-ax = gca;
-ax.XAxisLocation = 'origin';
-plot([0, 0], [-0.6, 0], 'w', 'linewidth', 4);
-plot([0, length(y)], [0, 0], 'k', 'linewidth', 4);
-plot([0, 0], [0, ymax], 'k', 'linewidth', 4);
-
-ind = 48-ceil((y-min(y))/range(y)*16);
-col_map = jet();
-col = col_map(ind, :);
-% current estimation of c
-plot(c, 'color', 'k', 'linewidth', 2);
-scatter(1:length(y), c, 80, col, 'filled', 'markeredgecolor', 'k');
-% scatter plot the current pool
-t = Aset(current, 3)+(1:Aset(current, 4));
-plot(t, c(t), '+b', 'markersize', 10);
-ylim([-0.6, ymax]);
-xlim([0, length(y)-1]);
-set(gca, 'xtick', []);
-set(gca, 'ytick', []);
-ylabel('Fluorescence');
-
-%% plot spike trains
-axes('position', [0.05, 0.1, 0.9, 0.4]); cla; hold on;
-ymax = 1.5;
-% use different color to separate pools
-for m=1:2:len_active_set
- t0 = Aset(m, 3);
- t1 = Aset(m, 3) + Aset(m, 4);
- fill([t0, t1, t1, t0], [0.01, 0.01, ymax, ymax], [1,1,1]*0.9, 'edgecolor', 'w');
-end
-temp = find(trueSpikes);
-for m=1:length(temp);
- plot([1, 1]*temp(m), [0, ymax], 'r', 'linewidth', 3);
-end
-ax = gca;
-ax.XAxisLocation = 'origin';
-plot([0, 0], [-0.6, 0], 'w', 'linewidth', 4);
-plot([0, length(y)], [0, 0], 'k', 'linewidth', 4);
-plot([0, 0], [0, ymax], 'k', 'linewidth', 4);
-s = c;
-plot([1,1], [0, s(1)], 'k', 'linewidth', 3);
-for t=2:length(y)
- s(t) = c(t) - g*c(t-1);
- plot([t, t], [0, s(t)], 'k', 'linewidth', 3);
-end
-scatter(1:length(y), s, 80, col, 'filled', 'markeredgecolor', 'k');
-% scatter plot the current pool
-t = Aset(current, 3)+(1:Aset(current, 4));
-plot(t, s(t), '+b', 'markersize', 10);
-ylim([-0.6, ymax]);
-xlim([0, length(y)-1]);
-set(gca, 'xtick', []);
-set(gca, 'ytick', []);
-ylabel('Spikes');
-xlabel('Time');
-end
\ No newline at end of file
diff --git a/deconvolveCa/examples/Paper/scripts/fig4_plot_trace.m b/deconvolveCa/examples/Paper/scripts/fig4_plot_trace.m
deleted file mode 100644
index 07f6bd2..0000000
--- a/deconvolveCa/examples/Paper/scripts/fig4_plot_trace.m
+++ /dev/null
@@ -1,16 +0,0 @@
-plot(y, 'color', col{8}/255, 'linewidth', 1);
-hold on;
-plot(trueC, 'color', col{3}/255);
-plot(solution, 'color', col{1}/255);
-text(700, 2.8, sprintf('Correlation: %.3f', corr(trueS, spks)), ...
- 'fontweight', 'bold', 'fontsize', 16);
-xlim([0, 1500]);
-ylim([min(y), 3.3]);
-ax = gca;
-ax.XAxisLocation = 'origin';
-ax.YAxisLocation = 'origin';
-set(gca, 'ytick', 0:2:max(y));
-set(gca, 'xtick', 0:300:1200);
-set(gca, 'xticklabel', []);
-set(gca, 'yticklabel', [0,2]);
-box off;
\ No newline at end of file
diff --git a/deconvolveCa/examples/Paper/scripts/show_results.m b/deconvolveCa/examples/Paper/scripts/show_results.m
deleted file mode 100644
index ad86773..0000000
--- a/deconvolveCa/examples/Paper/scripts/show_results.m
+++ /dev/null
@@ -1,29 +0,0 @@
-init_fig;
-
-% c
-axes('position', [.05, .57, .95, .37]);
-hold on;
-plot(y, 'color', col{8}/255);
-alpha(.7);
-plot(true_c, 'color', col{3}/255, 'linewidth', 1.5);
-plot(c_oasis, '-.', 'color', col{1}/255);
-axis tight;
-xlim([0, 2000]);
-set(gca, 'xtick', [0, 25, 50, 75]*30);
-set(gca, 'xticklabel', []);
-set(gca, 'ytick', 0:2);
-ylabel('Fluor.');
-box off;
-legend('Data', 'Truth', 'OASIS', 'location', 'northeast', 'orientation', 'horizental');
-% s
-axes('position', [.05, .18, .95, .37]);
-hold on;
-plot(true_s, 'color', col{3}/255, 'linewidth', 1.5);
-plot(s_oasis, '-.', 'color', col{1}/255);
-axis tight;
-xlim([0, 2000]);
-set(gca, 'xtick', [0, 25, 50, 75]*30);
-set(gca, 'xticklabel', get(gca, 'xtick')/30);
-set(gca, 'ytick', [0,1]);
-xlabel('Time [s]');
-ylabel('Activity.');
\ No newline at end of file
diff --git a/deconvolveCa/examples/Paper/test_all.m b/deconvolveCa/examples/Paper/test_all.m
deleted file mode 100644
index 0170178..0000000
--- a/deconvolveCa/examples/Paper/test_all.m
+++ /dev/null
@@ -1,5 +0,0 @@
-fig1;
-fig2;
-fig3;
-fig4;
-fig5;
\ No newline at end of file
diff --git a/deconvolveCa/examples/ar1_constrained_foopsi.m b/deconvolveCa/examples/ar1_constrained_foopsi.m
deleted file mode 100644
index f90ab69..0000000
--- a/deconvolveCa/examples/ar1_constrained_foopsi.m
+++ /dev/null
@@ -1,74 +0,0 @@
-%% test modulate for all oasis functions.
-col = {[0 114 178],[0 158 115], [213 94 0],[230 159 0],...
- [86 180 233], [204 121 167], [64 224 208], [240 228 66]}; % colors
-plot_cvx = false;
-
-%% example 7: constrained-foopsi, AR1
-g = 0.95; % AR coefficient
-noise = .3;
-T = 3000;
-framerate = 30;
-firerate = 0.5;
-b = 0; % baseline
-N = 1; % number of trials
-seed = 13; % seed for genrating random variables
-[y, true_c, true_s] = gen_data(g, noise, T, framerate, firerate, b, N, seed);
-
-% cvx solution
-[c_cvx, s_cvx] = constrained_foopsi(y, g, noise);
-% case 1: all parameters are known
-[c_oasis, s_oasis] = deconvolveCa(y, 'ar1', g, 'constrained', 'sn', noise); %#ok<*ASGLU>
-
-figure('name', 'constrained-FOOPSI, AR1, known: g, sn', 'papersize', [15, 4]);
-plot_cvx = true;
-show_results;
-plot_cvx = false;
-
-% case 2: nothing is known, estimate g with auto-correlation method
-[c_oasis, s_oasis,options] = deconvolveCa(y, 'ar1', 'constrained');
-
-fprintf('true gamma: %.3f\n', g);
-fprintf('estimated gamma: %.3f\n', options.pars);
-
-figure('name', 'FOOPSI, AR1, estimated: g, sn', 'papersize', [15, 4]);
-show_results;
-
-% case 3: nothing is know, estimate g with auto-correlation method first
-% and then update it to minimize the RSS
-[c_oasis, s_oasis, options] = deconvolveCa(y, 'ar1', 'constrained', ...
- 'optimize_pars');
-
-fprintf('true gamma: %.3f\n', g);
-fprintf('estimated gamma: %.3f\n', options.pars);
-
-figure('name', 'FOOPSI, AR1, estimated: g, sn, update:g', 'papersize', [15, 4]);
-show_results;
-
-% case 4: nothing is know, estimate g with auto-correlation method first
-% and then update it to minimize the RSS, the baseline is also unknown
-true_b = 0.5;
-[c_oasis, s_oasis, options] = deconvolveCa(y+true_b, 'ar1', g,...
- 'constrained','optimize_b', 'sn', noise);
-fprintf('true gamma: %.3f\n', g);
-fprintf('estimated gamma: %.3f\n', options.pars);
-fprintf('true b: %.3f\n', true_b);
-fprintf('estimated b: %.3f\n', options.b);
-fprintf('tuning parameter: %.3f\n', options.lambda);
-
-figure('name', 'FOOPSI, AR1, estimated: g, sn, lambda', 'papersize', [15, 4]);
-show_results;
-
-% case 5: nothing is know, estimate g with auto-correlation method first
-% and then update it to minimize the RSS, the baseline is also unknown
-true_b = 0.5;
-[c_oasis, s_oasis, options] = deconvolveCa(y+true_b, 'ar1',...
- 'constrained','optimize_b', 'optimize_pars');
-fprintf('true gamma: %.3f\n', g);
-fprintf('estimated gamma: %.3f\n', options.pars);
-fprintf('estimated b: %.3f\n', options.b);
-fprintf('tuning parameter: %.3f\n', options.lambda);
-
-figure('name', 'FOOPSI, AR1, estimated: g, sn, lambda, update:g', 'papersize', [15, 4]);
-show_results;
-
-%%
\ No newline at end of file
diff --git a/deconvolveCa/examples/ar1_foopsi.m b/deconvolveCa/examples/ar1_foopsi.m
deleted file mode 100644
index 984a9c9..0000000
--- a/deconvolveCa/examples/ar1_foopsi.m
+++ /dev/null
@@ -1,47 +0,0 @@
-%% test modulate for all oasis functions.
-col = {[0 114 178],[0 158 115], [213 94 0],[230 159 0],...
- [86 180 233], [204 121 167], [64 224 208], [240 228 66]}; % colors
-plot_cvx = false;
-
-%% example 1: foopsi, AR1 model. This model is used when the sampling rate is low
-g = 0.95; % AR coefficient
-noise = .3;
-T = 3000;
-framerate = 30;
-firerate = 0.5;
-b = 0; % baseline
-N = 1; % number of trials
-seed = 13; % seed for genrating random variables
-[y, true_c, true_s] = gen_data(g, noise, T, framerate, firerate, b, N, seed);
-
-% case 1: all parameters are known
-lambda = 2.4;
-[c_oasis, s_oasis] = deconvolveCa(y, 'ar1', g, 'foopsi', 'lambda', lambda); %#ok<*ASGLU>
-[c_cvx, s_cvx] = foopsi(y, g, lambda);
-
-figure('name', 'FOOPSI, AR1, known: g, lambda', 'papersize', [15, 4]);
-plot_cvx = true;
-show_results;
-plot_cvx = false;
-
-% case 2: know lambda
-lambda = 2.4;
-[c_oasis, s_oasis, options] = deconvolveCa(y, 'ar1', 'foopsi', 'lambda', lambda);
-
-fprintf('true gamma: %.3f\n', g);
-fprintf('estimated gamma: %.3f\n', options.pars);
-
-figure('name', 'FOOPSI, AR1, known:lambda, estimated: g', 'papersize', [15, 4]);
-show_results;
-
-% case 3: know lambda, fit g
-lambda = 2.4;
-[c_oasis, s_oasis, options] = deconvolveCa(y, 'ar1', 'foopsi', 'lambda', lambda, ...
- 'optimize_pars');
-
-fprintf('true gamma: %.3f\n', g);
-fprintf('estimated gamma: %.3f\n', options.pars);
-
-figure('name', 'MCMC, AR1');
-show_results;
-%%%%%%%%%%%%%% END %%%%%%%%%%%%%%%%%%
diff --git a/deconvolveCa/examples/ar1_mcmc.m b/deconvolveCa/examples/ar1_mcmc.m
deleted file mode 100644
index 426709f..0000000
--- a/deconvolveCa/examples/ar1_mcmc.m
+++ /dev/null
@@ -1,27 +0,0 @@
-%% test modulate for all oasis functions.
-col = {[0 114 178],[0 158 115], [213 94 0],[230 159 0],...
- [86 180 233], [204 121 167], [64 224 208], [240 228 66]}; % colors
-plot_cvx = false;
-
-%% example 1: foopsi, AR1 model. This model is used when the sampling rate is low
-g = 0.95; % AR coefficient
-noise = .3;
-T = 3000;
-framerate = 30;
-firerate = 0.5;
-b = 0; % baseline
-N = 1; % number of trials
-seed = 13; % seed for genrating random variables
-[y, true_c, true_s] = gen_data(g, noise, T, framerate, firerate, b, N, seed);
-
-% case 1: all parameters are known
-lambda = 2.4;
-params.p = 1;
-params.B = 1;
-[c_oasis, s_oasis] = deconvolveCa(y, 'mcmc', params); %#ok<*ASGLU>
-[c_cvx, s_cvx] = foopsi(y, g, lambda);
-
-figure('name', 'FOOPSI, AR1, known: g, lambda', 'papersize', [15, 4]);
-plot_cvx = true;
-show_results;
-plot_cvx = false;
diff --git a/deconvolveCa/examples/ar1_thresholded_foopsi.m b/deconvolveCa/examples/ar1_thresholded_foopsi.m
deleted file mode 100644
index 14fbb67..0000000
--- a/deconvolveCa/examples/ar1_thresholded_foopsi.m
+++ /dev/null
@@ -1,38 +0,0 @@
-%% test modulate for all oasis functions.
-col = {[0 114 178],[0 158 115], [213 94 0],[230 159 0],...
- [86 180 233], [204 121 167], [64 224 208], [240 228 66]}; % colors
-plot_cvx = false;
-
-%% example 4: hard threshold, AR1 model
-g = 0.95; % AR coefficient
-noise = .3;
-T = 3000;
-framerate = 30;
-firerate = 0.5;
-b = 0; % baseline
-N = 1; % number of trials
-seed = 13; % seed for genrating random variables
-[y, true_c, true_s] = gen_data(g, noise, T, framerate, firerate, b, N, seed);
-
-% case 1: all parameters are known
-smin = 0.5;
-[c_oasis, s_oasis, options] = deconvolveCa(y, 'ar1', g, 'thresholded', 'smin', smin); %#ok<*ASGLU>
-
-figure('name', 'threshold, AR1, known: g, lambda, smin', 'papersize', [15, 4]);
-show_results;
-
-% case 2: know smin
-[c_oasis, s_oasis, options] = deconvolveCa(y, 'ar1', 'thresholded', 'smin', smin);
-
-fprintf('true gamma: %.3f\n', g);
-fprintf('estimated gamma: %.3f\n', options.pars);
-
-figure('name', 'threshold, AR1, known:smin, estimated: g', 'papersize', [15, 4]);
-show_results;
-
-% case 3: optimize the thershold, g, and the baseline
-[c_oasis, s_oasis, options] = deconvolveCa(y, 'ar1', g, ...
- 'thresholded', 'optimize_smin', 'optimize_pars', 'thresh_factor', 0.99); %#ok<*ASGLU>
-
-figure('name', 'threshold, AR1, known: g, sn, estimate: smin, g', 'papersize', [15, 4]);
-show_results;
\ No newline at end of file
diff --git a/deconvolveCa/examples/ar2_foopsi.m b/deconvolveCa/examples/ar2_foopsi.m
deleted file mode 100644
index d269914..0000000
--- a/deconvolveCa/examples/ar2_foopsi.m
+++ /dev/null
@@ -1,36 +0,0 @@
-%% test modulate for all oasis functions.
-col = {[0 114 178],[0 158 115], [213 94 0],[230 159 0],...
- [86 180 233], [204 121 167], [64 224 208], [240 228 66]}; % colors
-plot_cvx = false;
-
-%% example 2: foopsi, AR2 model
-g = [1.7, -0.712]; % AR coefficient
-noise = 1;
-T = 3000;
-framerate = 30;
-firerate = 0.5;
-b = 0; % baseline
-N = 20; % number of trials
-seed = 3; % seed for genrating random variables
-[Y, trueC, trueS] = gen_data(g, noise, T, framerate, firerate, b, N, seed);
-y = Y(1,:);
-true_c = trueC(1,:); %#ok<*NASGU>
-true_s = trueS(1,:);
-% case 1: all parameters are known
-lambda = 25;
-[c_oasis, s_oasis] = deconvolveCa(y, 'ar2', g, 'foopsi', 'lambda', lambda); %#ok<*ASGLU>
-
-figure('name', 'FOOPSI, AR2, known: g, lambda', 'papersize', [15, 4]);
-show_results;
-
-% case 2: know lambda
-lambda = 2.5;
-[c_oasis, s_oasis, options] = deconvolveCa(y, 'ar2', 'sn', noise, 'foopsi', 'lambda',...
- lambda);
-fprintf('true gamma: %.3f\t %.3f\n', g(1), g(2));
-fprintf('estimated gamma: %.3f\t %.3f\n', options.pars(1), options.pars(2));
-
-figure('name', 'FOOPSI, AR2, known:lambda, estimated: g', 'papersize', [15, 4]);
-show_results;
-
-%%%%%%%%%%%%%% END %%%%%%%%%%%%%%%%%%
diff --git a/deconvolveCa/examples/ar2_mcmc.m b/deconvolveCa/examples/ar2_mcmc.m
deleted file mode 100644
index b920824..0000000
--- a/deconvolveCa/examples/ar2_mcmc.m
+++ /dev/null
@@ -1,26 +0,0 @@
-%% test modulate for all oasis functions.
-col = {[0 114 178],[0 158 115], [213 94 0],[230 159 0],...
- [86 180 233], [204 121 167], [64 224 208], [240 228 66]}; % colors
-plot_cvx = false;
-
-%% example 2: foopsi, AR2 model
-g = [1.7, -0.712]; % AR coefficient
-noise = 1;
-T = 3000;
-framerate = 30;
-firerate = 0.5;
-b = 0; % baseline
-N = 20; % number of trials
-seed = 3; % seed for genrating random variables
-[Y, trueC, trueS] = gen_data(g, noise, T, framerate, firerate, b, N, seed);
-y = Y(1,:);
-true_c = trueC(1,:); %#ok<*NASGU>
-true_s = trueS(1,:);
-% case 1: all parameters are known
-lambda = 25;
-params.p = 2;
-params.B = 300;
-[c_oasis, s_oasis] = deconvolveCa(y, 'mcmc', params); %#ok<*ASGLU>
-
-figure('name', 'FOOPSI, AR2, known: g, lambda', 'papersize', [15, 4]);
-show_results;
diff --git a/deconvolveCa/examples/ar2_thresholded_foopsi.m b/deconvolveCa/examples/ar2_thresholded_foopsi.m
deleted file mode 100644
index e3be1a6..0000000
--- a/deconvolveCa/examples/ar2_thresholded_foopsi.m
+++ /dev/null
@@ -1,54 +0,0 @@
-%% test modulate for all oasis functions.
-col = {[0 114 178],[0 158 115], [213 94 0],[230 159 0],...
- [86 180 233], [204 121 167], [64 224 208], [240 228 66]}; % colors
-plot_cvx = false;
-
-
-%% threshold, AR2 model
-g = [1.7, -0.712]; % AR coefficient
-noise = 1;
-T = 3000;
-framerate = 30;
-firerate = 0.5;
-b = 0; % baseline
-N = 20; % number of trials
-seed = 3; % seed for genrating random variables
-[Y, trueC, trueS] = gen_data(g, noise, T, framerate, firerate, b, N, seed);
-y = Y(1,:);
-true_c = trueC(1,:); %#ok<*NASGU>
-true_s = trueS(1,:);
-% case 1: all parameters are known
-smin = 0.5;
-[c_oasis, s_oasis] = deconvolveCa(y, 'ar2', g, 'thresholded', 'smin', smin); %#ok<*ASGLU>
-figure('name', 'threshold, AR2, known: g, smin', 'papersize', [15, 4]);
-show_results;
-
-% case 2: know smin
-smin = 0.5;
-[c_oasis, s_oasis, options] = deconvolveCa(y, 'ar2', 'sn', noise, 'thresholded',...
- 'smin', smin);
-fprintf('true gamma: %.3f\t %.3f\n', g(1), g(2));
-fprintf('estimated gamma: %.3f\t %.3f\n', options.pars(1), options.pars(2));
-
-figure('name', 'threshold, AR2, known:smin, estimated: g', 'papersize', [15, 4]);
-show_results;
-
-%% case 3: know smin, update g
-smin = 0.5;
-[c_oasis, s_oasis, options] = deconvolveCa(y, 'ar2', 'sn', noise, 'thresholded',...
- 'smin', smin, 'optimize_pars');
-fprintf('true gamma: %.3f\t %.3f\n', g(1), g(2));
-fprintf('estimated gamma: %.3f\t %.3f\n', options.pars(1), options.pars(2));
-
-figure('name', 'threshold, AR2, known:smin, estimated: g', 'papersize', [15, 4]);
-show_results;
-
-%% case 3: estimate smin
-[c_oasis, s_oasis, options] = deconvolveCa(y, 'ar2', 'sn', noise, 'thresholded',...
- 'optimize_smin','optimize_pars', 'thresh_factor', 1);
-% fprintf('true gamma: %.3f\t %.3f\n', g(1), g(2));
-% fprintf('estimated gamma: %.3f\t %.3f\n', options.pars(1), options.pars(2));
-fprintf('estimated smin: %.3f\n', options.smin);
-figure('name', 'threshold, AR2, known:smin, estimated: g', 'papersize', [15, 4]);
-show_results;
-%%%%%%%%%%%%%% END %%%%%%%%%%%%%%%%%%
diff --git a/deconvolveCa/examples/foopsi_kernel.m b/deconvolveCa/examples/foopsi_kernel.m
deleted file mode 100644
index a59c334..0000000
--- a/deconvolveCa/examples/foopsi_kernel.m
+++ /dev/null
@@ -1,157 +0,0 @@
-function [c, s, b, g, active_set] = foopsi_oasisAR1(y, g, lam, optimize_b,...
- optimize_g, decimate, maxIter)
-%% Infer the most likely discretized spike train underlying an AR(1) fluorescence trace
-% Solves the sparse non-negative deconvolution problem
-% min 1/2|c-y|^2 + lam |s|_1 subject to s_t = c_t-g c_{t-1} >= 0
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: scalar, Parameter of the AR(1) process that models the fluorescence ...
-%impulse response.
-% lam: scalar, sparsity penalty parameter
-% optimize_b: bool, optimize baseline if True
-% optimize_g: integer, number of large, isolated events to consider for
-% optimizing g
-% decimate: int, decimation factor for estimating hyper-parameters faster
-% on decimated data
-% maxIter: int, maximum number of iterations
-% active_set: npool x 4 matrix, warm stared active sets
-
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-% b: scalar, fluorescence baseline
-% g: scalar, parameter of the AR(1) process
-% active_set: npool x 4 matrix, active sets
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-
-%% input arguments
-y = reshape(y, [], 1);
-T = length(y);
-
-if ~exist('g', 'var') || isempty(g)
- g = estimate_time_constant(y, 1);
-end
-if ~exist('lam', 'var') || isempty(lam); lam = 0; end
-if ~exist('optimize_b', 'var') || isempty(optimize_b)
- optimize_b = false;
-end
-if ~exist('optimize_g', 'var') || isempty(optimize_g)
- optimize_g = 0;
-end
-if ~exist('decimate', 'var') || isempty(decimate)
- decimate = 1;
-else
- decimate = max(1, round(decimate));
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = 10;
-end
-
-% change parameters due to downsampling
-if decimate>1
- decimate = 1; %#ok
- disp('to be done');
- % fluo = y;
- % y = resample(y, 1, decimate);
- % g = g^decimate;
- % thresh = thresh / decimate / decimate;
- % T = length(y);
-end
-
-%% optimize parameters
-if ~optimize_b %% don't optimize the baseline b
- %% initialization
- b = 0;
- [solution, spks, active_set] = oasisAR1(y, g, lam);
-
- %% iteratively update parameters g
- if optimize_g % update g
- [solution, active_set, g, spks] = update_g(y, active_set,lam);
- end
-else
- %% initialization
- b = quantile(y, 0.15);
- [solution, spks, active_set] = oasisAR1(y-b, g, lam);
-
- %% iteratively update parameters g and b
- for m=1:maxIter
- b = mean(y-solution);
- if optimize_g % update g
- g0 = g;
- [solution, active_set, g, spks] = update_g(y-b, active_set,lam);
- if abs(g-g0)/g0 < 1e-3 % g is converged
- optimize_g = false;
- end
- else
- break;
- end
- end
-end
-c = solution;
-s = spks;
-end
-%update the AR coefficient: g
-function [c, active_set, g, s] = update_g(y, active_set, lam)
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% active_set: npools*4 matrix, previous active sets.
-% lam: scalar, curret value of sparsity penalty parameter lambda.
-
-%% outputs
-% c: T*1 vector
-% s: T*1 vector, spike train
-% active_set: npool x 4 matrix, active sets
-% g: scalar
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-%% initialization
-
-len_active_set = size(active_set, 1); %number of active sets
-y = reshape(y,[],1); % fluorescence data
-maxl = max(active_set(:, 4)); % maximum ISI
-c = zeros(size(y)); % the optimal denoised trace
-
-%% find the optimal g and get the warm started active_set
-g = fminbnd(@rss_g, 0, 1);
-yp = y - lam*(1-g);
-for m=1:len_active_set
- tmp_h = exp(log(g)*(0:maxl)'); % response kernel
- tmp_hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- li = active_set(m, 4);
- ti = active_set(m, 3);
- idx = ti:(ti+li-1);
- active_set(m,1) = (yp(idx))'*tmp_h(1:li);
- active_set(m,2) = tmp_hh(li);
-end
-[c,s,active_set] = oasisAR1(y, g, lam, [], active_set);
-
-%% nested functions
- function rss = rss_g(g)
- h = exp(log(g)*(0:maxl)'); % response kernel
- hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- yp = y - lam*(1-g); % include the penalty term
- for ii=1:len_active_set
- li = active_set(ii, 4);
- ti = active_set(ii, 3);
- idx = ti:(ti+li-1);
- tmp_v = max(yp(idx)' * h(1:li) / hh(li), 0);
- c(idx) = tmp_v*h(1:li);
- end
- res = y-c;
- rss = res'*res; % residual sum of squares
- end
-end
\ No newline at end of file
diff --git a/deconvolveCa/examples/foopsi_onnls.m b/deconvolveCa/examples/foopsi_onnls.m
deleted file mode 100644
index 4a3b45b..0000000
--- a/deconvolveCa/examples/foopsi_onnls.m
+++ /dev/null
@@ -1,190 +0,0 @@
-function [c, s, b, g, active_set] = foopsi_exp2(y, taus, lam, optimize_b,...
- optimize_kernel, decimate, maxIter, shift, win, tol, mask, smin)
-
-%% Infer the most likely discretized spike train for the model c = conv(s, kernel)
-% Solves the sparse non-negative deconvolution problem
-% min 1/2|c-y|^2 + lam |s|_1 subject to c = conv(s, kernel)>= 0
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: scalar, Parameter of the AR(1) process that models the fluorescence ...
-%impulse response.
-% lam: scalar, sparsity penalty parameter
-% optimize_b: bool, optimize baseline if True
-% optimize_g: integer, number of large, isolated events to consider for
-% optimizing g
-% decimate: int, decimation factor for estimating hyper-parameters faster
-% on decimated data
-% maxIter: int, maximum number of iterations
-% shift: integer scalar, number of frames by which to shift window from on run of
-% NNLS to the next, default-100
-% win: integer acalar, window size
-% tol: scalar, tolerance parameters
-% maxIter: scalar, maximum number of iterations before termination
-% mask: T * 1 boolean vector, restrict potential spike times
-% smin: scalar, minimum spike size
-
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-% b: scalar, fluorescence baseline
-% taus: 1*2 vector, [tau_d, tau_r]
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-
-%% input arguments
-y = reshape(y, [], 1);
-T = length(y);
-
-if ~exist('shift', 'var') || isempty(shift)
- shift = 100;
-end
-if ~exist('win', 'var') || isempty(win)
- win = 200;
-end
-
-if ~exist('tol', 'var') || isempty(tol)
- tol = 1e-9;
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = [];
-end
-if ~exist('mask', 'var') || isempty(mask)
- mask = true(T,1);
-end
-if ~exist('smin', 'var') || isempty(smin)
- smin = 0;
-end
-
-if ~exist('kernel', 'var') || isempty(kernel)
- g = estimate_time_constant(y, 2);
- taus = ar2exp(g);
- kernel = exp2kernel(taus, win);
-end
-
-if ~exist('lam', 'var') || isempty(lam); lam = 0; end
-if ~exist('optimize_b', 'var') || isempty(optimize_b)
- optimize_b = false;
-end
-if ~exist('optimize_g', 'var') || isempty(optimize_g)
- optimize_g = 0;
-end
-if ~exist('decimate', 'var') || isempty(decimate)
- decimate = 1;
-else
- decimate = max(1, round(decimate));
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = 10;
-end
-
-% change parameters due to downsampling
-if decimate>1
- decimate = 1; %#ok
- disp('to be done');
- % fluo = y;
- % y = resample(y, 1, decimate);
- % g = g^decimate;
- % thresh = thresh / decimate / decimate;
- % T = length(y);
-end
-
-%% optimize parameters
-if ~optimize_b %% don't optimize the baseline b
- %% initialization
- b = 0;
- [solution, spks] = onnls(y, kernel, lam, shift, win, tol, maxIter, mask, smin);
-
- %% iteratively update parameters g
- if optimize_g % update g
- pars.vals = taus;
- [pars, s] = update_tau(y, spks, pars, nspk);
- end
-else
- disp('to be done');
-% %% initialization
-% b = quantile(y, 0.15);
-% [solution, spks, active_set] = oasisAR1(y-b, g, lam);
-%
-% %% iteratively update parameters g and b
-% for m=1:maxIter
-% b = mean(y-solution);
-% if optimize_g % update g
-% g0 = g;
-% [solution, active_set, g, spks] = update_g(y-b, active_set,lam);
-% if abs(g-g0)/g0 < 1e-3 % g is converged
-% optimize_g = false;
-% end
-% else
-% break;
-% end
-% end
-end
-c = solution;
-s = spks;
-end
-
-
-%update the AR coefficient: g
-% function [c, active_set, g, s] = update_g(y, active_set, lam)
-% %% inputs:
-% % y: T*1 vector, One dimensional array containing the fluorescence intensities
-% %withone entry per time-bin.
-% % active_set: npools*4 matrix, previous active sets.
-% % lam: scalar, curret value of sparsity penalty parameter lambda.
-%
-% %% outputs
-% % c: T*1 vector
-% % s: T*1 vector, spike train
-% % active_set: npool x 4 matrix, active sets
-% % g: scalar
-%
-% %% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% % ported from the Python implementation from Johannes Friedrich
-%
-% %% References
-% % Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-%
-% %% initialization
-%
-% len_active_set = size(active_set, 1); %number of active sets
-% y = reshape(y,[],1); % fluorescence data
-% maxl = max(active_set(:, 4)); % maximum ISI
-% c = zeros(size(y)); % the optimal denoised trace
-%
-% %% find the optimal g and get the warm started active_set
-% g = fminbnd(@rss_g, 0, 1);
-% yp = y - lam*(1-g);
-% for m=1:len_active_set
-% tmp_h = exp(log(g)*(0:maxl)'); % response kernel
-% tmp_hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
-% li = active_set(m, 4);
-% ti = active_set(m, 3);
-% idx = ti:(ti+li-1);
-% active_set(m,1) = (yp(idx))'*tmp_h(1:li);
-% active_set(m,2) = tmp_hh(li);
-% end
-% [c,s,active_set] = oasisAR1(y, g, lam, [], active_set);
-%
-% %% nested functions
-% function rss = rss_g(g)
-% h = exp(log(g)*(0:maxl)'); % response kernel
-% hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
-% yp = y - lam*(1-g); % include the penalty term
-% for ii=1:len_active_set
-% li = active_set(ii, 4);
-% ti = active_set(ii, 3);
-% idx = ti:(ti+li-1);
-% tmp_v = max(yp(idx)' * h(1:li) / hh(li), 0);
-% c(idx) = tmp_v*h(1:li);
-% end
-% res = y-c;
-% rss = res'*res; % residual sum of squares
-% end
-% end
\ No newline at end of file
diff --git a/deconvolveCa/examples/kernel_foopsi.m b/deconvolveCa/examples/kernel_foopsi.m
deleted file mode 100644
index 4f8c0cf..0000000
--- a/deconvolveCa/examples/kernel_foopsi.m
+++ /dev/null
@@ -1,63 +0,0 @@
-%% test modulate for all oasis functions.
-col = {[0 114 178],[0 158 115], [213 94 0],[230 159 0],...
- [86 180 233], [204 121 167], [64 224 208], [240 228 66]}; % colors
-plot_cvx = false;
-
-%% example 3: foopsi, convolution kernel
-g = [1.7, -0.712]; % AR coefficient
-noise = 1;
-T = 3000;
-framerate = 30;
-firerate = 0.5;
-b = 0; % baseline
-N = 20; % number of trials
-seed = 3; % seed for genrating random variables
-[Y, trueC, trueS] = gen_data(g, noise, T, framerate, firerate, b, N, seed);
-y = Y(1,:);
-true_c = trueC(1,:); %#ok<*NASGU>
-true_s = trueS(1,:);
-taus = ar2exp(g);
-w = 200;
-taus = ar2exp(g);
-ht = exp2kernel(taus, w);
-% case 1: use the difference of two exponential functions to construct a
-% kernel
-lambda = 25;
-[c_oasis, s_oasis] = deconvolveCa(y, 'exp2', taus, 'foopsi', 'lambda', lambda, ...
- 'shift', 100, 'window', 200); %#ok<*ASGLU>
-
-figure('name', 'FOOPSI, exp2, known: g, lambda', 'papersize', [15, 4]);
-show_results;
-
-% case 2: use the kernel directly
-lambda = 25;
-[c_oasis, s_oasis] = deconvolveCa(y, 'kernel', ht, 'foopsi', 'lambda', ...
- lambda, 'shift', 100, 'window', 200); %#ok<*ASGLU>
-
-figure('name', 'FOOPSI, kernel, known: g, lambda', 'papersize', [15, 4]);
-show_results;
-
-
-%% case 3: estimate the time constants
-lambda = 0;
-taus = ar2exp(g);
-[c_oasis, s_oasis, options] = deconvolveCa(y, 'exp2', 'foopsi', 'lambda', lambda, ...
- 'shift', 100, 'window', 200, 'smin', 0.5); %#ok<*ASGLU>
-
-figure('name', 'FOOPSI, exp2, known: g, lambda', 'papersize', [15, 4]);
-show_results;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deconvolveCa/examples/kernel_thresholded_foopsi.m b/deconvolveCa/examples/kernel_thresholded_foopsi.m
deleted file mode 100644
index 247eb96..0000000
--- a/deconvolveCa/examples/kernel_thresholded_foopsi.m
+++ /dev/null
@@ -1,39 +0,0 @@
-%% test modulate for all oasis functions.
-col = {[0 114 178],[0 158 115], [213 94 0],[230 159 0],...
- [86 180 233], [204 121 167], [64 224 208], [240 228 66]}; % colors
-plot_cvx = false;
-
-
-%% threshold foopsi, convolution kernel
-g = [1.7, -0.712]; % AR coefficient
-noise = 1;
-T = 3000;
-framerate = 30;
-firerate = 0.5;
-b = 0; % baseline
-N = 20; % number of trials
-seed = 3; % seed for genrating random variables
-[Y, trueC, trueS] = gen_data(g, noise, T, framerate, firerate, b, N, seed);
-y = Y(1,:);
-true_c = trueC(1,:); %#ok<*NASGU>
-true_s = trueS(1,:);
-temp = roots([1, -g(1), -g(2)]);
-d = max(temp);
-r = min(temp);
-w = 200;
-ht = (exp(log(d)*(1:w)) - exp(log(r)*(1:w))) / (d-r); % convolution kernel
-
-% case 1: all parameters are known, the kernel is the sum of two
-% exponential functions
-smin = 0.5;
-pars = [d, r];
-[c_oasis, s_oasis] = deconvolveCa(y, 'exp2', pars, 'thresholded', 'smin', smin); %#ok<*ASGLU>
-figure('name', 'threshold, exp2, known: taur, taud, smin', 'papersize', [15, 4]);
-show_results;
-
-% case 1: all parameters are known
-smin = 0.5;
-[c_oasis, s_oasis] = deconvolveCa(y, 'kernel', ht, 'thresholded', 'smin', smin); %#ok<*ASGLU>
-figure('name', 'threshold, kernel, known: kernel, smin', 'papersize', [15, 4]);
-show_results;
-%%%%%%%%%%%%%% END %%%%%%%%%%%%%%%%%%
diff --git a/deconvolveCa/examples/show_results.m b/deconvolveCa/examples/show_results.m
deleted file mode 100644
index 7b9f3af..0000000
--- a/deconvolveCa/examples/show_results.m
+++ /dev/null
@@ -1,39 +0,0 @@
-init_fig;
-
-% c
-axes('position', [.05, .57, .95, .37]);
-hold on;
-plot(y, 'color', col{8}/255);
-alpha(.7);
-plot(true_c, 'color', col{3}/255, 'linewidth', 1.5);
-plot(c_oasis, '-.', 'color', col{5}/255);
-if plot_cvx && exist('c_cvx', 'var')
- plot(c_cvx, '-.', 'color', col{7}/255);
-end
-axis tight;
-xlim([0, 2000]);
-set(gca, 'xtick', [0, 25, 50, 75]*30);
-set(gca, 'xticklabel', []);
-set(gca, 'ytick', 0:2);
-ylabel('Fluor.');
-box off;
-if plot_cvx
- legend('Data', 'Truth', 'OASIS', 'CVX', 'location', 'northeast', 'orientation', 'horizental');
-else
- legend('Data', 'Truth', 'OASIS', 'location', 'northeast', 'orientation', 'horizental');
-end
-% s
-axes('position', [.05, .18, .95, .37]);
-hold on;
-plot(true_s, 'color', col{3}/255, 'linewidth', 1.5);
-plot(s_oasis, '-.', 'color', col{5}/255);
-if plot_cvx && exist('s_cvx', 'var')
- plot(s_cvx, '-.', 'color', col{7}/255);
-end
-axis tight;
-xlim([0, 2000]);
-set(gca, 'xtick', [0, 25, 50, 75]*30);
-set(gca, 'xticklabel', get(gca, 'xtick')/30);
-set(gca, 'ytick', [0,1]);
-xlabel('Time [s]');
-ylabel('Activity.');
\ No newline at end of file
diff --git a/deconvolveCa/examples/test_all.m b/deconvolveCa/examples/test_all.m
deleted file mode 100644
index a1c5de5..0000000
--- a/deconvolveCa/examples/test_all.m
+++ /dev/null
@@ -1,85 +0,0 @@
-%% FOOPSI (all done )
-% AR1
-fprintf('AR1, FOOPSI...');
-try
- ar1_foopsi;
- fprintf('success!\n\n');
- drawnow;
-catch
- fprintf('fail!\n\n');
-end
-
-% AR2
-fprintf('\nAR2, FOOPSI...');
-try
- ar2_foopsi;
- fprintf('success!\n\n');
- drawnow;
-catch
- fprintf('fail!\n\n');
-end
-
-% kernel
-fprintf('\nkernel, FOOPSI...');
-try
- kernel_foopsi;
- fprintf('success!\n\n');
- drawnow;
-catch
- fprintf('fail!\n\n');
-end
-
-
-%% Constrained FOOPSI (need AR2, kernel )
-% AR1
-fprintf('\nAR1, constrained FOOPSI...');
-try
- ar1_constrained_foopsi;
- fprintf('success!\n\n');
- drawnow;
-catch
- fprintf('fail!\n\n');
-end
-
-%% Thresholded FOOPSI (all done)
-% AR1
-fprintf('\nAR1, thresholded FOOPSI...');
-try
- ar1_thresholded_foopsi;
- fprintf('success!\n\n');
- drawnow;
-catch
- fprintf('fail!\n\n');
-end
-
-% AR2
-fprintf('\nAR2, thresholded FOOPSI... ');
-try
- ar2_thresholded_foopsi;
- fprintf('success!\n\n');
- drawnow;
-catch
- fprintf('fail!\n\n');
-end
-
-
-% AR2
-fprintf('\nkernel, thresholded FOOPSI... ');
-try
- kernel_thresholded_foopsi;
- fprintf('success!\n\n');
- drawnow;
-catch
- fprintf('fail!\n\n');
-end
-
-%% MCMC
-% AR1
-fprintf('\nAR1, MCMC...');
-try
- ar1_mcmc;
- fprintf('success!\n\n');
- drawnow;
-catch
- fprintf('fail!\n\n');
-end
diff --git a/deconvolveCa/functions/GetSn.m b/deconvolveCa/functions/GetSn.m
deleted file mode 100644
index ea4850c..0000000
--- a/deconvolveCa/functions/GetSn.m
+++ /dev/null
@@ -1,50 +0,0 @@
-function sn = GetSn(Y, range_ff, method)
-%% Estimate noise standard deviation
-
-%% inputs:
-% Y: N X T matrix, fluorescence trace
-% range_ff : 1 x 2 vector, nonnegative, max value <= 0.5, range of frequency (x Nyquist rate) over which the spectrum is averaged
-% method: string, method of averaging: Mean, median, exponentiated mean of logvalues (default)
-
-%% outputs:
-% sn: scalar, std of the noise
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% adapted from the MATLAB implemention by Eftychios Pnevmatikakis and the
-% Python implementation from Johannes Friedrich
-
-%% References
-% Pnevmatikakis E. et.al., Neuron 2016, Simultaneous Denoising, Deconvolution, and Demixing of Calcium Imaging Data
-
-%% input arguments
-if ~exist('range_ff', 'var') || isempty(range_ff)
- range_ff = [.25, .5];
-end
-if ~exist('method', 'var') || isempty(method)
- method = 'logmexp';
-end
-if any(size(Y)==1)
- Y = reshape(Y, [], 1);
-else
- Y = Y';
-end
-
-%% estimate the noise
-[psdx, ff] = pwelch(double(Y), [],[],[], 1);
-indf = and(ff>=range_ff(1), ff<=range_ff(2));
-switch method
- case 'mean'
- sn=sqrt(mean(psdx(indf, :)/2));
- case 'median'
- sn=sqrt(median(psdx(indf,:)/2));
- case 'logmexp'
- sn = sqrt(exp(mean(log(psdx(indf,:)/2))));
- otherwise
- fprintf('wrong method! use logmexp instead.\n');
- sn = sqrt(exp(mean(log(psdx(indf,:)/2))));
-end
-sn = sn';
-
-
-
-
diff --git a/deconvolveCa/functions/ar2exp.m b/deconvolveCa/functions/ar2exp.m
deleted file mode 100644
index c7afbb1..0000000
--- a/deconvolveCa/functions/ar2exp.m
+++ /dev/null
@@ -1,13 +0,0 @@
-function tau_dr = ar2exp(g)
-%% get parameters of the convolution kernel for AR2 process
-if length(g)==1
- g(2) = 0;
-end
-
-temp = roots([1, -g(1), -g(2)]);
-d = max(temp);
-r = min(temp);
-tau_d = -1/log(d);
-tau_r = -1/log(r);
-
-tau_dr = [tau_d, tau_r];
\ No newline at end of file
diff --git a/deconvolveCa/functions/choose_smin.m b/deconvolveCa/functions/choose_smin.m
deleted file mode 100644
index 40a6576..0000000
--- a/deconvolveCa/functions/choose_smin.m
+++ /dev/null
@@ -1,42 +0,0 @@
-function smin = choose_smin(kernel,sn,prob)
-%% Choose minimal spike spike to enforce sparsity constraint in spike inference
-% The function chooses a regularization weight for sparse deconvolution
-% with a given kernel and noise level. The weight of the regularizer
-% is chosen such that noise alone cannot lead to a non-zero solution is
-% at least prob.
-
-% Inputs:
-% kernel: deconvolution kernel
-% if length(kernel) == 1 or length(kernel) == 2, then kernel
-% is treated as a set of discrete time constants g. Otherwise,
-% it is treated as the actual vector.
-% sn: noise level
-% prob: probability of zero solution (deafult: 0.99)
-
-% Output:
-% smin: minimal spike size
-
-% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-% modified from choose_lambda.m Eftychios A. Pnevmatikakis, 2016, Simons Foundation
-% based on ideas and discussions with J. Tubiana and G. Debregeas,
-% Laboratorie Jean Parrin, UPMC, France
-
-% Reference for this approach:
-% Selesnick, I. (2012). Sparse deconvolution (an MM algorithm)
-
-%%
-
-if nargin < 3 || isempty(prob)
- prob = 0.99999;
-end
-
-if nargin < 2 || isempty(sn)
- sn = 1;
- warning('Noise value not provided. Using sn = 1...')
-end
-
-if length(kernel) <= 2
- kernel = filter(1,[1,-kernel(:)'],[1,zeros(1,999)]);
-end
-
-smin = sn/norm(kernel)*norminv(prob);
\ No newline at end of file
diff --git a/deconvolveCa/functions/constrained_foopsi_cvx.m b/deconvolveCa/functions/constrained_foopsi_cvx.m
deleted file mode 100644
index 7e0d163..0000000
--- a/deconvolveCa/functions/constrained_foopsi_cvx.m
+++ /dev/null
@@ -1,56 +0,0 @@
-function [c, s] = constrained_foopsi_cvx(y, g, sn, solver)
-%% Infer the most likely discretized spike train underlying an AR(1) fluorescence trace
-% Solves the sparse non-negative deconvolution problem
-% min |s|_1 subject to s=G*c >=0 and |y-c|_2^2=\sigma*T^2
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: scalar, Parameter of the AR(1) process that models the fluorescence ...
-%impulse response.
-% sn: scalar, noise standard deviation
-% solver: string, optimization solver
-
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-% Pnevmatikakis E. et.al., Neuron 2016, Simultaneous Denoising, Deconvolution, and Demixing of Calcium Imaging Data
-
-%% initialization
-y = reshape(y, [], 1);
-T = length(y);
-if ~exist('g', 'var') || isempty(g); g = estimate_time_constant(y, 1); end
-if ~exist('sn', 'var') || isempty(sn); sn = GetSn(y); end
-if ~exist('solver', 'var') || isempty(solver); solver = 'SDPT3'; end
-
-% construct the deconvolution matrix (s=G*c)
-len_g = length(g);
-g = reshape(g, 1, []);
-indc = bsxfun(@minus, (1:T)', 0:len_g);
-indr = repmat((1:T)', [1, len_g+1]);
-v = ones(T,1)*[1,-g];
-ind = (indc>0);
-G = sparse(indr(ind), indc(ind), v(ind), T, T);
-
-%% run optimization
-% cvx_solver(solver);
-cvx_begin quiet
- variable c(T)
- minimize(norm(c,1))
- subject to
- G*c >=0;
- norm(y-c,2) <= sn*sqrt(T);
-cvx_end
-
-s = reshape(G*c, 1, []);
-s(1) = 0;
-c = reshape(c,1, []);
-
-
-
diff --git a/deconvolveCa/functions/estimate_baseline_noise.m b/deconvolveCa/functions/estimate_baseline_noise.m
deleted file mode 100644
index 62321e3..0000000
--- a/deconvolveCa/functions/estimate_baseline_noise.m
+++ /dev/null
@@ -1,35 +0,0 @@
-function [b, sn] = estimate_baseline_noise(y, bmin)
-%% estimate the baseline and noise level for single calcium trace
-%% inputs:
-% y: T*1 vector, calcium trace
-% thr: scalar, threshold for choosing points for fitting a gaussian
-% distribution.
-% bmin: scalar, minimum value of the baseline, default(-inf)
-%% outputs:
-% b: scalar, baseline
-% sn: scalar, sigma of the noise
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-
-%% input arguments
-if ~exist('bmin', 'var') || isempty(bmin)
- bmin = -inf;
-end
-
-%% create the histogram for fitting
-temp = quantile(y, 0:0.1:1);
-dbin = max(min(diff(temp))/3, (max(temp)-min(temp))/1000);
-bins = temp(1):dbin:temp(end);
-nums = hist(y, bins);
-
-%% fit a gaussian distribution: nums = A * exp(-(bins-b)/(2*sig^2))
-if isempty(bins)
- b = mean(y);
- sn = 0;
- return;
-end
-[b, sn] = fit_gauss1(bins, nums, 0.3, 3);
-
-if b1) && p < 5
-% warning('No stable AR(%i) model found. Checking for AR(%i) model \n',p, p+1);
- p = p + 1;
- g = estimate_time_constant(y,p,sn,lags);
-end
-if p == 5
- g = 0;
-end
-
-% re-adjust time constant values
-rg = roots([1;-g(:)]);
-if ~isreal(rg); rg = real(rg) + .001*randn(size(rg)); end
-rg(rg>1) = 0.95 + 0.001*randn(size(rg(rg>1)));
-rg(rg<0) = 0.15 + 0.001*randn(size(rg(rg<0)));
-pg = poly(fudge_factor*rg);
-g = -pg(2:end);
-
diff --git a/deconvolveCa/functions/exp2ar.m b/deconvolveCa/functions/exp2ar.m
deleted file mode 100644
index b2ea5fc..0000000
--- a/deconvolveCa/functions/exp2ar.m
+++ /dev/null
@@ -1,8 +0,0 @@
-function g = exp2ar(tau_dr)
-%% convert a convolution function to an AR(2) model
-
-d = exp(-1/tau_dr(1));
-r = exp(-1/tau_dr(2));
-
-g(1) = d+r;
-g(2) = -d*r;
\ No newline at end of file
diff --git a/deconvolveCa/functions/exp2kernel.m b/deconvolveCa/functions/exp2kernel.m
deleted file mode 100644
index 039f473..0000000
--- a/deconvolveCa/functions/exp2kernel.m
+++ /dev/null
@@ -1,17 +0,0 @@
-function ht = exp2kernel(taus, nmax)
-%% create the convolution kernel given tau_rise and tau_decay
-
-%% inputs:
-% taus: 1*2 vector, [tau_decay tau_rise]
-% nmax: scalar, length of the kernel
-
-%% outputs:
-% ht: nmax*1 kernel, convolution kernel
-
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-
-t = (1:nmax)';
-d = exp(-1./taus(1));
-r = exp(-1./taus(2));
-ht = (exp(log(d)*t) - exp(log(r)*t) ) / (d - r);
-ht = ht/sum(ht);
\ No newline at end of file
diff --git a/deconvolveCa/functions/fit_gauss1.m b/deconvolveCa/functions/fit_gauss1.m
deleted file mode 100644
index 199251f..0000000
--- a/deconvolveCa/functions/fit_gauss1.m
+++ /dev/null
@@ -1,83 +0,0 @@
-function [mu, sig, A] = fit_gauss1(x, y, thr, maxIter, mu_fix)
-%% fit a gaussin curve given the data (x, y): y = A*exp(-(x-mu)^2/2/sig^2)
-
-%% inputs:
-% x: T*1 vector
-% y: T*1 vector
-% thr: scalar, threshold for selecting points for fitting
-% maxIter: scalar, maximum iteration
-% mu_fix: boolean, fix the center to be 0 or not
-%% outputs:
-% mu: scalar, center of the peak
-% sig: scalar, gaussian width
-% A: scalar, amplitude of the gaussian curve
-
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-%% Reference:
-% A Simple Algorithm for Fitting a Gaussian Function , Hongwei Guo, 2011
-
-%% input arguments
-x = reshape(x, [], 1);
-y = reshape(y, [], 1);
-T = length(y);
-
-if ~exist('thr', 'var') || isempty(thr)
- thr = 0.1;
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = 5;
-end
-if ~exist('mu_fix', 'var') || isempty(mu_fix)
- mu_fix = false;
-end
-ind = (y>max(y)*thr);
-x = x(ind);
-y = y(ind);
-
-x2 = x.^2;
-x3 = x.^3;
-x4 = x.^4;
-y2 = y.^2;
-logy = log(y);
-y2logy = y2.*logy;
-vec1 = ones(1, length(y));
-
-warning('off','MATLAB:nearlySingularMatrix');
-warning('off','MATLAB:SingularMatrix');
-%% fit the curve
-if mu_fix % fix the mu to be 0
- for miter=1:maxIter
- M = [vec1*y2, x2'*y2; ...
- x2'*y2, x4'*y2];
- b = [vec1*y2logy; x2'*y2logy];
- p = M\b;
-
- logy = p(1)*vec1' + p(2)*x2;
- y = exp(logy);
- y2 = y.^2;
- y2logy = y2.*logy;
- end
-
- mu= 0;
- sig = sqrt(-0.5/p(2));
- A = exp(p(1));
-else
- for miter=1:maxIter
- M = [vec1*y2, x'*y2, x2'*y2; ...
- x'*y2, x2'*y2, x3'*y2; ...
- x2'*y2, x3'*y2, x4'*y2];
- b = [vec1*y2logy; x'*y2logy; x2'*y2logy];
- p = (M)\b;
-
- logy = p(1)*vec1' + p(2)*x + p(3)*x2;
- y = exp(logy);
- y2 = y.^2;
- y2logy = y2.*logy;
- end
- mu= -p(2)/2/p(3);
- sig = abs(sqrt(-0.5/p(3)));
- A = exp(p(1)-0.25*p(2)^2/p(3));
-end
-
-warning('on','MATLAB:nearlySingularMatrix');
-warning('on','MATLAB:SingularMatrix');
diff --git a/deconvolveCa/functions/foopsi.m b/deconvolveCa/functions/foopsi.m
deleted file mode 100644
index 2e46a79..0000000
--- a/deconvolveCa/functions/foopsi.m
+++ /dev/null
@@ -1,59 +0,0 @@
-function [c, s] = foopsi(y, g, lam, solver)
-%% Infer the most likely discretized spike train underlying an AR(1) fluorescence trace
-% Solves the sparse non-negative deconvolution problem
-% min 1/2|c-y|^2 + lam |s|_1 subject to s_t = c_t-g c_{t-1} >= 0
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: scalar, Parameter of the AR(1) process that models the fluorescence ...
-%impulse response.
-% lam: scalar, sparsity penalty parameter lambda.
-% solver: string, optimization solver
-
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-%% initialization
-y = reshape(y, [], 1);
-T = length(y);
-if ~exist('g', 'var') || isempty(g); g = estimate_time_constant(y, 2); end
-
-
-if ~exist('lam', 'var') || isempty(lam); lam = 0; end
-if ~exist('solver', 'var') || isempty(smin); solver = 'SDPT3'; end
-
-% construct the deconvolution matrix (s=G*c)
-len_g = length(g);
-g = reshape(g, 1, []);
-indc = bsxfun(@minus, (1:T)', 0:len_g);
-indr = repmat((1:T)', [1, len_g+1]);
-v = ones(T,1)*[1,-g];
-ind = (indc>0);
-G = sparse(indr(ind), indc(ind), v(ind), T, T);
-
-%% run optimization
-% cvx_solver(solver);
-
-cvx_begin quiet
-variable c(T)
-minimize(0.5*(c-y)'*(c-y) + lam*(1-sum(g))*norm(c,1))
-subject to
-G*c >=0;
-cvx_end
-
-s = reshape(G*c, 1, []);
-s(1) = 0;
-c = reshape(c,1, []);
-
-
-
-
-
diff --git a/deconvolveCa/functions/gen_data.m b/deconvolveCa/functions/gen_data.m
deleted file mode 100644
index dc37c3d..0000000
--- a/deconvolveCa/functions/gen_data.m
+++ /dev/null
@@ -1,62 +0,0 @@
-function [Y, truth, trueSpikes] = gen_data(gam, noise, T, framerate, ...
- firerate, b, N, seed)
-
-%% input arguments
-if ~exist('gam', 'var') || isempty(gam)
- gam = .95;
-end
-if ~exist('noise', 'var') || isempty(noise)
- noise = .3;
-end
-if ~exist('T', 'var') || isempty(T)
- T = 3000;
-end
-if ~exist('framerate', 'var') || isempty(framerate)
- framerate = 30;
-end
-if ~exist('firerate', 'var') || isempty(firerate)
- firerate = .5;
-end
-if ~exist('b', 'var') || isempty(b)
- b = 0;
-end
-if ~exist('N', 'var') || isempty(N)
- N = 20;
-end
-if ~exist('seed', 'var') || isempty(seed)
- seed = 13;
-end
-
-%% run simulation
-rng(seed);
-trueSpikes = (rand(N, T) < firerate/framerate);
-truth = double(trueSpikes);
-p = length(gam);
-gam = [flipud(reshape(gam, [], 1)); 1];
-
-for t=(p+1):T
- truth(:, t) = truth(:, (t-p):t) * gam;
-end
-
-Y = b + truth + noise * randn(N, T);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deconvolveCa/functions/gen_sinusoidal_data.m b/deconvolveCa/functions/gen_sinusoidal_data.m
deleted file mode 100644
index fc27cf2..0000000
--- a/deconvolveCa/functions/gen_sinusoidal_data.m
+++ /dev/null
@@ -1,63 +0,0 @@
-function [Y, truth, trueSpikes] = gen_sinusoidal_data(gam, noise, T, framerate, ...
- firerate, b, N, seed)
-
-%% input arguments
-if ~exist('gam', 'var') || isempty(gam)
- gam = .95;
-end
-if ~exist('noise', 'var') || isempty(noise)
- noise = .3;
-end
-if ~exist('T', 'var') || isempty(T)
- T = 3000;
-end
-if ~exist('framerate', 'var') || isempty(framerate)
- framerate = 30;
-end
-if ~exist('firerate', 'var') || isempty(firerate)
- firerate = .5;
-end
-if ~exist('b', 'var') || isempty(b)
- b = 0;
-end
-if ~exist('N', 'var') || isempty(N)
- N = 20;
-end
-if ~exist('seed', 'var') || isempty(seed)
- seed = 13;
-end
-
-%% run simulation
-rng(seed);
-trueSpikes = bsxfun(@lt, rand(N, T),...
- 4 * firerate/framerate * sin((1:T)/50).^3);
-truth = double(trueSpikes);
-p = length(gam);
-gam = [flipud(reshape(gam, [], 1)); 1];
-
-for t=(p+1):T
- truth(:, t) = truth(:, (t-p):t) * gam;
-end
-
-Y = b + truth + noise * randn(N, T);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deconvolveCa/functions/init_fig.m b/deconvolveCa/functions/init_fig.m
deleted file mode 100644
index 018003b..0000000
--- a/deconvolveCa/functions/init_fig.m
+++ /dev/null
@@ -1,5 +0,0 @@
-set(gcf, 'color', 'w', ...
- 'defaultAxesFontSize', 20, ...)
- 'defaultlinelinewidth',2, ...
- 'position', [0, 0, 100*get(gcf, 'papersize')], ...
- 'paperposition', [0, 0, get(gcf, 'papersize')])
diff --git a/deconvolveCa/functions/max_ht.m b/deconvolveCa/functions/max_ht.m
deleted file mode 100644
index 0aeb3f9..0000000
--- a/deconvolveCa/functions/max_ht.m
+++ /dev/null
@@ -1,28 +0,0 @@
-function vmax = max_ht(pars1, pars2)
-%% Get the maximum response value following one calcium transient
-%% inputs:
-% pars1: if nargin<2, pars1 is the AR coefficients; else pars1 is the
-% decay time constant
-% pars2: the rising time constant
-%% outputs:
-% ht: nmax*1 kernel, convolution kernel
-
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-if nargin<2
- if length(pars1) ==1
- % AR1 model
- vmax = 1;
- return;
- else
- % AR2 model
- taus = ar2exp(pars1);
- end
-else
- taus = [pars1, pars2];
-end
-
-t = (1:ceil(taus(1)*2))';
-d = exp(-1./taus(1));
-r = exp(-1./taus(2));
-ht = (exp(log(d)*t) - exp(log(r)*t) ) / (d - r);
-vmax = max(ht);
\ No newline at end of file
diff --git a/deconvolveCa/oasis/choose_lambda.m b/deconvolveCa/oasis/choose_lambda.m
deleted file mode 100644
index dede18a..0000000
--- a/deconvolveCa/oasis/choose_lambda.m
+++ /dev/null
@@ -1,41 +0,0 @@
-function lam = choose_lambda(kernel,sn,prob)
-%% Choose regularizer weight for sparse deconvolution
-% The function chooses a regularization weight for sparse deconvolution
-% with a given kernel and noise level. The weight of the regularizer
-% is chosen such that noise alone cannot lead to a non-zero solution is
-% at least prob.
-
-% Inputs:
-% kernel: deconvolution kernel
-% if length(kernel) == 1 or length(kernel) == 2, then kernel
-% is treated as a set of discrete time constants g. Otherwise,
-% it is treated as the actual vector.
-% sn: noise level
-% prob: probability of zero solution (deafult: 0.99)
-
-% Output:
-% lam: regularization weight
-
-% Author: Eftychios A. Pnevmatikakis, 2016, Simons Foundation
-% based on ideas and discussions with J. Tubiana and G. Debregeas,
-% Laboratorie Jean Parrin, UPMC, France
-
-% Reference for this approach:
-% Selesnick, I. (2012). Sparse deconvolution (an MM algorithm)
-
-%%
-
-if nargin < 3 || isempty(prob)
- prob = 0.99;
-end
-
-if nargin < 2 || isempty(sn)
- sn = 1;
- warning('Noise value not provided. Using sn = 1...')
-end
-
-if length(kernel) <= 2
- kernel = filter(1,[1,-kernel(:)'],[1,zeros(1,999)]);
-end
-
-lam = sn*norm(kernel)*norminv(prob);
\ No newline at end of file
diff --git a/deconvolveCa/oasis/constrained_oasisAR1.m b/deconvolveCa/oasis/constrained_oasisAR1.m
deleted file mode 100644
index ab4f72f..0000000
--- a/deconvolveCa/oasis/constrained_oasisAR1.m
+++ /dev/null
@@ -1,250 +0,0 @@
-function [c, s, b, g, lam, active_set] = constrained_oasisAR1(y, g, sn, optimize_b,...
- optimize_g, decimate, maxIter)
-%% Infer the most likely discretized spike train underlying an AR(1) fluorescence trace
-% Solves the sparse non-negative deconvolution problem
-% min 1/2|c-y|^2 + lam |s|_1 subject to s_t = c_t-g c_{t-1} >=s_min or =0
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: scalar, Parameter of the AR(1) process that models the fluorescence ...
-%impulse response.
-% sn: scalar, standard deviation of the noise distribution
-% optimize_b: bool, optimize baseline if True
-% optimize_g: integer, number of large, isolated events to consider for
-% optimizing g
-% decimate: int, decimation factor for estimating hyper-parameters faster
-% on decimated data
-% maxIter: int, maximum number of iterations
-% active_set: npool x 4 matrix, warm stared active sets
-
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-% b: scalar, fluorescence baseline
-% g: scalar, parameter of the AR(1) process
-% lam: scalar, sparsity penalty parameter
-% active_set: npool x 4 matrix, active sets
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-
-%% input arguments
-y = reshape(y, [], 1);
-T = length(y);
-
-if ~exist('g', 'var') || isempty(g)
- g = estimate_time_constant(y, 1);
-end
-if ~exist('sn', 'var') || isempty(sn)
- sn = GetSn(y);
-end
-if ~exist('lam', 'var') || isempty(lam); lam = 0; end
-if ~exist('optimize_b', 'var') || isempty(optimize_b)
- optimize_b = false;
-end
-if ~exist('optimize_g', 'var') || isempty(optimize_g)
- optimize_g = 0;
-end
-if ~exist('decimate', 'var') || isempty(decimate)
- decimate = 1;
-else
- decimate = max(1, round(decimate));
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = 10;
-end
-
-thresh = sn * sn * T;
-lam = 0;
-
-% change parameters due to downsampling
-if decimate>1
- decimate = 1; %#ok
- disp('to be done');
- % fluo = y;
- % y = resample(y, 1, decimate);
- % g = g^decimate;
- % thresh = thresh / decimate / decimate;
- % T = length(y);
-end
-g_converged = false;
-
-%% optimize parameters
-tol = 1e-4;
-% flag_lam = true;
-if ~optimize_b %% don't optimize the baseline b
- %% initialization
- b = 0;
- [solution, spks, active_set] = oasisAR1(y, g, lam);
-
- %% iteratively update parameters lambda & g
- for miter=1:maxIter
- % update g
- if and(optimize_g, ~g_converged);
- g0 = g;
- [solution, active_set, g, spks] = update_g(y, active_set,lam);
- if abs(g-g0)/g0 < 1e-3 % g is converged
- g_converged = true;
- end
- end
- res = y - solution;
- RSS = res' * res;
- len_active_set = size(active_set, 1);
- if RSS>thresh % constrained form has been found, stop
- break;
- else
- % update lam
- update_phi;
- lam = lam + dphi;
- end
- end
-else
- %% initialization
- b = quantile(y, 0.15);
- [solution, spks, active_set] = oasisAR1(y-b, g, lam);
- update_lam_b;
-
- %% optimize the baseline b and dependends on the optimized g too
- g_converged = false;
- for miter=1:maxIter
- res = y - solution - b;
- RSS = res' * res;
- len_active_set = size(active_set,1);
-
- if or(abs(RSS-thresh) < tol, sum(solution)<1e-9)
- break;
- else
- %% update b & lamba
- update_phi();
- update_lam_b();
- % update b and g
- % update b and g
- if and(optimize_g, ~g_converged);
- g0 = g;
- [solution, active_set, g, spks] = update_g(y-b, active_set,lam);
- if abs(g-g0)/g0 < 1e-4;
- g_converged = true;
- end
- end
-
- end
- end
-
-end
-c = solution;
-s = spks;
-
-%% nested functions
- function update_phi() % estimate dphi to match the thresholded RSS
- zeta = zeros(size(solution));
- maxl = max(active_set(:, 4));
- h = g.^(0:maxl);
- for ii=1:len_active_set
- ti = active_set(ii, 3);
- li = active_set(ii, 4);
- idx = 0:(li-1);
- if ii1e-9
- flag_phi = false;
- return;
- else
- flag_phi = true;
- end
- active_set(:,1) = active_set(:,1) - dphi*(1-g.^active_set(:,4));
- [solution, spks, active_set] = oasisAR1([], g, lam, [], active_set);
- end
-
- function update_lam_b() % estimate lambda & b
- db = mean(y-solution) - b;
- b = b + db;
- dlam = -db/(1-g);
-
- lam = lam + dlam;
- % correct the last pool
- active_set(end,1) = active_set(end,1) - lam*g^(active_set(end,4));
- ti = active_set(end,3); li = active_set(end,4); idx = 0:(li-1);
- solution(ti+idx) = max(0, active_set(end,1)/active_set(end,2)) * (g.^idx);
- end
-
-end
-%update the AR coefficient: g
-function [c, active_set, g, s] = update_g(y, active_set, lam)
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% active_set: npools*4 matrix, previous active sets.
-% lam: scalar, curret value of sparsity penalty parameter lambda.
-
-%% outputs
-% c: T*1 vector
-% s: T*1 vector, spike train
-% active_set: npool x 4 matrix, active sets
-% g: scalar
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-%% initialization
-
-len_active_set = size(active_set, 1); %number of active sets
-y = reshape(y,[],1); % fluorescence data
-maxl = max(active_set(:, 4)); % maximum ISI
-c = zeros(size(y)); % the optimal denoised trace
-
-%% find the optimal g and get the warm started active_set
-g = fminbnd(@rss_g, 0, 1);
-yp = y - lam*(1-g);
-for m=1:len_active_set
- tmp_h = exp(log(g)*(0:maxl)'); % response kernel
- tmp_hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- li = active_set(m, 4);
- ti = active_set(m, 3);
- idx = ti:(ti+li-1);
- active_set(m,1) = (yp(idx))'*tmp_h(1:li);
- active_set(m,2) = tmp_hh(li);
-end
-[c,s,active_set] = oasisAR1(y, g, lam, [], active_set);
-
-%% nested functions
- function rss = rss_g(g)
- h = exp(log(g)*(0:maxl)'); % response kernel
- hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- yp = y - lam*(1-g); % include the penalty term
- for ii=1:len_active_set
- li = active_set(ii, 4);
- ti = active_set(ii, 3);
- idx = ti:(ti+li-1);
- tmp_v = max(yp(idx)' * h(1:li) / hh(li), 0);
- c(idx) = tmp_v*h(1:li);
- end
- res = y-c;
- rss = res'*res; % residual sum of squares
- end
-end
\ No newline at end of file
diff --git a/deconvolveCa/oasis/constrained_oasisAR2.m b/deconvolveCa/oasis/constrained_oasisAR2.m
deleted file mode 100644
index 99a013e..0000000
--- a/deconvolveCa/oasis/constrained_oasisAR2.m
+++ /dev/null
@@ -1,252 +0,0 @@
-function [c, s, b, g, lam, active_set] = constrained_oasisAR2(y, g, sn, optimize_b,...
- optimize_g, decimate, maxIter)
-%% Infer the most likely discretized spike train underlying an AR(2) fluorescence trace
-% Solves the sparse non-negative deconvolution problem
-% min lam |s|_1
-% subject to |y-c|_2^2 <= sn^2*T
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: 2 x 1 vector, Parameter of the AR(2) process that models the fluorescence ...
-%impulse response.
-% sn: scalar, standard deviation of the noise distribution
-% optimize_b: bool, optimize baseline if True
-% optimize_g: integer, number of large, isolated events to consider for
-% optimizing g
-% decimate: int, decimation factor for estimating hyper-parameters faster
-% on decimated data
-% maxIter: int, maximum number of iterations
-% active_set: npool x 4 matrix, warm stared active sets
-
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-% b: scalar, fluorescence baseline
-% g: scalar, parameter of the AR(1) process
-% lam: scalar, sparsity penalty parameter
-% active_set: npool x 4 matrix, active sets
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-
-%% input arguments
-y = reshape(y, [], 1);
-T = length(y);
-
-if ~exist('g', 'var') || isempty(g)
- g = estimate_time_constant(y, 2);
-end
-if ~exist('sn', 'var') || isempty(sn)
- sn = GetSn(y);
-end
-if ~exist('lam', 'var') || isempty(lam); lam = 0; end
-if ~exist('optimize_b', 'var') || isempty(optimize_b)
- optimize_b = false;
-end
-if ~exist('optimize_g', 'var') || isempty(optimize_g)
- optimize_g = 0;
-end
-if ~exist('decimate', 'var') || isempty(decimate)
- decimate = 1;
-else
- decimate = max(1, round(decimate));
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = 10;
-end
-
-thresh = sn * sn * T;
-lam = 0;
-
-% change parameters due to downsampling
-if decimate>1
- decimate = 1; %#ok
- disp('to be done');
- % fluo = y;
- % y = resample(y, 1, decimate);
- % g = g^decimate;
- % thresh = thresh / decimate / decimate;
- % T = length(y);
-end
-g_converged = false;
-
-%% optimize parameters
-tol = 1e-4;
-flag_lam = true;
-if ~optimize_b %% don't optimize the baseline b
- %% initialization
- b = 0;
- [solution, spks, active_set] = oasisAR2(y, g, lam);
-
- %% iteratively update parameters lambda & g
- for miter=1:maxIter
- res = y - solution;
- RSS = res' * res;
- len_active_set = size(active_set, 1);
- if or(abs(RSS-thresh) < tol, ~flag_lam) % constrained form has been found, stop
- break;
- else
- % update lam
- update_phi;
- lam = lam + dphi;
-
- % update g
- if and(optimize_g, ~g_converged);
- g0 = g;
- [solution, active_set, g, spks] = update_g(y, active_set,lam);
- if abs(g-g0)/g0 < 1e-3 % g is converged
- g_converged = true;
- end
- end
- end
- end
-else
- %% initialization
- b = quantile(y, 0.15);
- [solution, spks, active_set] = oasisAR2(y-b, g, lam);
- update_lam_b;
-
- %% optimize the baseline b and dependends on the optimized g too
- g_converged = false;
- for miter=1:maxIter
- res = y - solution - b;
- RSS = res' * res;
- len_active_set = size(active_set,1);
-
- if or(abs(RSS-thresh) < tol, sum(solution)<1e-9)
- break;
- else
- %% update b & lamba
- update_phi();
- update_lam_b();
- % update b and g
- % update b and g
- if and(optimize_g, ~g_converged);
- g0 = g;
- [solution, active_set, g, spks] = update_g(y-b, active_set,lam);
- if abs(g-g0)/g0 < 1e-4;
- g_converged = true;
- end
- end
-
- end
- end
-
-end
-c = solution;
-s = spks;
-
-%% nested functions
- function update_phi() % estimate dphi to match the thresholded RSS
- zeta = zeros(size(solution));
- maxl = max(active_set(:, 4));
- h = g.^(0:maxl);
- for ii=1:len_active_set
- ti = active_set(ii, 3);
- li = active_set(ii, 4);
- idx = 0:(li-1);
- if ii1e-9
- flag_phi = false;
- return;
- else
- flag_phi = true;
- end
- active_set(:,1) = active_set(:,1) - dphi*(1-g.^active_set(:,4));
- [solution, spks, active_set] = oasisAR2([], g, lam, [], active_set);
- end
-
- function update_lam_b() % estimate lambda & b
- db = mean(y-solution) - b;
- b = b + db;
- dlam = -db/(1-g);
-
- lam = lam + dlam;
- % correct the last pool
- active_set(end,1) = active_set(end,1) - lam*g^(active_set(end,4));
- ti = active_set(end,3); li = active_set(end,4); idx = 0:(li-1);
- solution(ti+idx) = max(0, active_set(end,1)/active_set(end,2)) * (g.^idx);
- end
-
-end
- %update the AR coefficient: g
-function [c, active_set, g, s] = update_g(y, active_set, lam)
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% active_set: npools*4 matrix, previous active sets.
-% lam: scalar, curret value of sparsity penalty parameter lambda.
-
-%% outputs
-% c: T*1 vector
-% s: T*1 vector, spike train
-% active_set: npool x 4 matrix, active sets
-% g: scalar
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-%% initialization
-
-len_active_set = size(active_set, 1); %number of active sets
-y = reshape(y,[],1); % fluorescence data
-maxl = max(active_set(:, 4)); % maximum ISI
-c = zeros(size(y)); % the optimal denoised trace
-
-%% find the optimal g and get the warm started active_set
-g = fminbnd(@rss_g, 0, 1);
-yp = y - lam*(1-g);
-for m=1:len_active_set
- tmp_h = exp(log(g)*(0:maxl)'); % response kernel
- tmp_hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- li = active_set(m, 4);
- ti = active_set(m, 3);
- idx = ti:(ti+li-1);
- active_set(m,1) = (yp(idx))'*tmp_h(1:li);
- active_set(m,2) = tmp_hh(li);
-end
-[c,s,active_set] = oasisAR2(y, g, lam, [], active_set);
-
-%% nested functions
- function rss = rss_g(g)
- h = exp(log(g)*(0:maxl)'); % response kernel
- hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- yp = y - lam*(1-g); % include the penalty term
- for ii=1:len_active_set
- li = active_set(ii, 4);
- ti = active_set(ii, 3);
- idx = ti:(ti+li-1);
- tmp_v = max(yp(idx)' * h(1:li) / hh(li), 0);
- c(idx) = tmp_v*h(1:li);
- end
- res = y-c;
- rss = res'*res; % residual sum of squares
- end
-end
\ No newline at end of file
diff --git a/deconvolveCa/oasis/create_kernel.m b/deconvolveCa/oasis/create_kernel.m
deleted file mode 100644
index 254de2e..0000000
--- a/deconvolveCa/oasis/create_kernel.m
+++ /dev/null
@@ -1,83 +0,0 @@
-function kernel = create_kernel(kernel_type, pars, nMax, lb, ub, bound_pars)
-%% create convolution kernel
-%% inputs:
-% kernel_type: string, convolution kernel type. now support {'exp',
-% 'exp2', 'vector'}
-% pars: parameters for the selected kernel type
-% nMax: length of the kernel
-% lb: lower bound for each parameter
-% ub: upper bound for each parameter
-% bound_pars: logical variable, bound the parameters or not {1, 0}
-%% outputs
-% kernel: struct variable
-
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-
-%% kernel size
-if ~exist('nMax', 'var') || isempty(nMax)
- nMax = 50;
-end
-kernel.nMax = nMax;
-
-%% initialize kernel
-if ~exist('kernel_type', 'var') || isempty(kernel_type)
- kernel_type = 'exp2';
-end
-if strcmpi(kernel_type, 'exp')
- % single exponential function: ~ exp(-t/tau)
- kernel.type = 'exp';
- % parameter
- if ~exist('pars', 'var') || isempty(pars)
- kernel.pars = [5, .1];
- else
- kernel = kernel.pars;
- end
- % function handle
- kernel.fhandle = @(pars, t) exp(-t/pars) * (1-exp(-1/pars)) ...
- / (1-exp(-nMax/pars));
-elseif strcmpi(kernel_type, 'vector')
- % single vector
- kernel.type = 'vector';
- % parameter
- if ~exist('pars', 'var') || isempty(pars)
- kernel.pars = exp(-(1:nMax)/10);
- else
- kernel.pars = pars;
- end
- % function handle
- kernel.fhandle = @(pars, t) pars/sum(pars);
-else
- % differencing of two exponential function:
- % ~ exp(-t/tau_d)-exp(-t/tau_r)
- kernel.type = 'exp2';
-
- % parameters
- if ~exist('pars', 'var') || isempty(pars)
- kernel.pars = [10, 1];
- else
- kernel.pars = pars;
- end
- % function handle
- kernel.fhandle = @(pars, t) (exp(-t/pars(1)) - exp(-t/pars(2))) ...
- /( (1-exp(-nMax/pars(1)))/(1-exp(-1/pars(1))) ...
- - (1-exp(-nMax/pars(2)))/(1-exp(-1/pars(2))));
-end
-
-% lower and upper bounds for parameters
-if ~exist('lb', 'var') || isempty(lb)
- kernel.lb = 0.5*kernel.pars;
-else
- kernel.lb = lb;
-end
-if ~exist('ub', 'var') || isempty(ub)
- kernel.ub = 2*kernel.pars;
-else
- kernel.ub = ub;
-end
-
-% bound the parameters of not
-if ~exist('bound_pars', 'var')||isempty(bound_pars)
- kernel.bound_pars = false;
-else
- kernel.bound_pars = bound_pars;
-end
\ No newline at end of file
diff --git a/deconvolveCa/oasis/deconvCa.m b/deconvolveCa/oasis/deconvCa.m
deleted file mode 100644
index 4454ee9..0000000
--- a/deconvolveCa/oasis/deconvCa.m
+++ /dev/null
@@ -1,356 +0,0 @@
-function [c, s, kernel, iter] = deconvCa(y, kernel, smin, fit_gt, debug_on, sn, maxIter, theta, lambda)
-%% deconvolve calcium traces to infer spike counts
-%% inputs:
-% y: 1*T vector, observed calcium traces
-% kernel: struct variable with two fields {'fhandle', 'pars', nMax}. kernel
-% deterines the convolution kernel
-% fhandle: function handle, the function form of the response function
-% pars: p*1 vector, parameters for fhandle
-% nMax: scalar, maximum number of frames required by calcium indicators
-% to return resting states
-% smin: scalar, minimum number of nonzero spike count within each bin
-% fit_gt: true or false. iteratively fit gt or not
-% debug_on: play and save video of the whole procedure.
-% sn: noise power
-% maxIter: scalar, maximum iterations for running OASIS, default (3)
-% theta: 1*T vecotr, weight vector at each time point
-% lambda: scalar, tuning parameter
-
-%% outputs:
-% c: 1*T vector, inferred calcium trace
-% s: 1*T vector, inferred spike train
-% kernel: convolution kernel
-% iters: number of iterations for updating irf
-
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-% This work is based on one NIPS paper by Johannes Friedrich & Liam
-% Paninski
-
-%% input arugments
-y = reshape(y, 1, []); % convert data into row vector
-if ~exist('sn', 'var') || isempty(sn)
- sn = get_noise_fft(y);
-end
-T = length(y); % number of frames
-
-% get convolution kernel
-if ~exist('kernel', 'var') || isempty(kernel)
- kernel = create_kernel('exp2');
-end
-fhandle = kernel.fhandle;
-nMax = kernel.nMax;
-
-y = [y, zeros(1, nMax)]; % add few more elements for computation convenience
-
-% threshold of the spike
-if ~exist('smin', 'var') || isempty(smin)
- smin = 3*sn; % min spike count
-else
- smin = smin * sn;
-end
-
-% fit response function or not
-if ~exist('fit_gt', 'var') || isempty(fit_gt)
- fit_gt = false;
-end
-thresh = 1e-3;
-
-% debug mode
-if ~exist('debug_on', 'var') || isempty(debug_on)
- debug_on = false;
-end
-
-% maximum iterations for running OASIS
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = 5;
-end
-
-% tuning parameter for enforcing sparsity
-if ~exist('lambda', 'var') || isempty(lambda)
- lambda = 0; % tuning parameter
-end
-
-% weight for each frame
-if ~exist('theta', 'var')|| isempty(theta) || (length(theta)==1) % weight vector
- theta = ones(1, T);
-elseif length(theta)==T
- theta = reshape(theta, 1, T);
-else
- disp('elements in theta should be equal to elements in y');
- return;
-end
-
-% tuning parameter for enforcing sparsity
-if ~exist('lambda', 'var') || isempty(lambda)
- lambda = 0; % tuning parameter
-end
-
-%% running OASIS
-if debug_on
- figure('position', [1, 1 1500, 250]);
- plot(y); hold on;
- a = plot(y, 'r');
- avi_file = VideoWriter('example.avi');
- avi_file.open();
- xlim([1, T]);
-end
-
-f0 = inf; % objective function
-y0 = y; % backup the raw trace
-iter = 1; % iteratiosn
-for iter = 1:maxIter
- if debug_on
- title(sprintf('Iter %d, norm(residual) = %.4f', iter, f0));
- end
- % normalize gt to make its maximum value to be 1
- gt = fhandle(kernel.pars, 1:nMax); % 1*nMax, response function of calcium transients
- ind0 = 1; %correct the response function of the first event
- gt = [reshape(gt, 1, nMax), zeros(1, T)]; % add few more elements to gt for computation convenience
-
- gt_max = max(gt);
- gt = gt/gt_max;
- gt1 = [gt(ind0:end), zeros(1, ind0-1)]; % kernel for the first frame
-
- %% initialize values for the results
- s = zeros(size(y)); % spike count within each bin
- v = zeros(size(y)); % sum(theta_t*y_t) - lambda
- w = zeros(size(y)); % sum(theta_t^2 * g(t-ti+1)^2))
- pool_ti = zeros(size(y)); % first frame of each pool
-
- % initialize the first pool
- v(1) = theta(1)*y(1)*gt1(1) - lambda;
- w(1) = (theta(1)*gt1(1))^2;
- s(1) = max(0, v(1) / w(1));
- % if s(1)=nMax % no influences from the previous events
- vi = theta(t)*y(t)*gt(1) - lambda;
- elseif tpre>1 % estimate vi and subtract the effect of the previous event
- vi = theta(t) * (y(t)-s(tpre)*gt(t-tpre+1)) * gt(1) - lambda;
- else % special treatment with the first event
- vi = theta(t) * (y(t)-s(tpre)*gt1(t-tpre+1)) * gt(1) - lambda;
- end
- wi = (theta(t) * gt(1))^2;
- si = vi/wi;
-
- % check the violatoin of si
- if si>smin && frame_valid % no violation, create a new pool to save the result and move to the next new pool
- % peel off the previous event
- if (t-tpre)1
- y(tpre+(1:nMax)-1) = y(tpre+(1:nMax)-1) - s(tpre)*gt(1:nMax);
- else
- y(tpre+(1:nMax)-1) = y(tpre+(1:nMax)-1) - s(tpre)*gt1(1:nMax);
- end
- end
- pool_ti(ii) = t; % create a new pool
- tpre = t;
- v(t) = vi;
- w(t) = wi;
- s(t) = si;
- ii = ii+1; % move to the next pool
- t = t+1;
- else % with violation
- frame_valid = true; % allows the next frame to be valid
- if (t-tpre)>=nMax
- % ignore this frame directly and move to the next frame
- t = t + 1;
- continue;
- elseif tpre>1 % merge it to the current pool
- v(tpre) = v(tpre) + theta(t)*y(t)*gt(t-tpre+1);
- w(tpre) = w(tpre) + (theta(t)*gt(t-tpre+1))^2;
- else
- v(tpre) = v(tpre) + theta(t)*y(t)*gt1(t-tpre+1);
- w(tpre) = w(tpre) + (theta(t)*gt1(t-tpre+1));
- end
- s(tpre) = v(tpre)/w(tpre); % update the current event
-
- % check the violation of the current pool
- if s(tpre)>smin % the previous event is still avaiable
- t = t+1;
- continue;
- elseif ii==2 %the previous pool is not available anymore, but it's the first pool
- s(tpre) = max(0, s(tpre));
- t = t+1;
- else % not available, then delete the current pool and force its first frame to be
- % event-free.
- t = tpre; % go back to the first frame of the current pull
-
- frame_valid = false; % force the frame t to be invalid
- ii = ii-1;
- tpre = pool_ti(ii-1);
-
- % add back the signal of the previous pool
- if (t-tpre)>nMax
- t = t+1;
- frame_valid = true;
- continue;
- elseif tpre>1
- y(tpre+(1:nMax)-1) = y(tpre+(1:nMax)-1) + s(tpre)*gt(1:nMax);
- else
- y(tpre+(1:nMax)-1) = y(tpre+(1:nMax)-1) + s(tpre)*gt1(1:nMax);
- end
- end
- end
- end
- %% collect the results
- pool_ti(ii:end) = [];
- temp = s(pool_ti);
- s = zeros(1, T);
- s(pool_ti) = temp;
- temp = s;
- temp(1) = 0;
- c = conv(temp, gt(1:nMax));
- c = c(1:T) + s(1)*gt1(1:T);
- f1 = norm(y(1:T)-c, 2);
- s = s*sum(gt);
- if debug_on
- delete(a);
- a = plot(c, 'r');
- drawnow();
- temp = getframe();
- temp.cdata = imresize(temp.cdata, [200, 1500]);
- avi_file.writeVideo(temp);
- end
-
- %% break the while loop
- if ~fit_gt % don't iterate gt
- break;
- elseif (f0-f1)/f0 <= thresh % improvement is small, stop
- break;
- else % move to the next iteration
- y = y0;
- if strcmpi(kernel.type, 'exp2')
- [kernel, ~] = update_kernel_exp2(y(1:T), s, kernel);
- else
- break;
- end
- f0 = f1;
- iter = iter + 1;
- % return;
- end
-end
-
-if debug_on
- avi_file.close();
- close(gcf);
-end
-end
-
-%% estimate the noise power
-function [sn,psdx,ff] = get_noise_fft(Y,options)
-% Written by:
-% Eftychios A. Pnevmatikakis, Simons Foundation, 2015
-% with minor adaption by Pengcheng Zhou, Carnegie Mellon University, 2015
-options.noise_range = [.25, .5];
-range_ff = options.noise_range;
-options.noise_method = 'logmexp';
-method = options.noise_method;
-options.block_size = [64, 64];
-block_size = options.block_size;
-options.split_data = false;
-split_data = options.split_data;
-options.max_timesteps = 3000;
-
-dims = ndims(Y);
-sizY = size(Y);
-N = min(sizY(end),options.max_timesteps);
-if N < sizY(end)
- %Y = reshape(Y,prod(sizY(1:end-1)),[]);
- Y(prod(sizY(1:end-1))*N+1:end) = [];
- Y = reshape(Y,[sizY(1:end-1),N]);
-end
-
-Fs = 1;
-ff = 0:Fs/N:Fs/2;
-indf=ff>range_ff(1);
-indf(ff>range_ff(2))=0;
-if dims > 1
- d = prod(sizY(1:dims-1));
- Y = reshape(Y,d,N);
- Nb = prod(block_size);
- SN = cell(ceil(d/Nb),1);
- PSDX = cell(ceil(d/Nb),1);
- if ~split_data
- for ind = 1:ceil(d/Nb);
- xdft = fft(Y((ind-1)*Nb+1:min(ind*Nb,d),:),[],2);
- xdft = xdft(:,1: floor(N/2)+1); % FN: floor added.
- psdx = (1/(Fs*N)) * abs(xdft).^2;
- psdx(:,2:end-1) = 2*psdx(:,2:end-1);
- %SN{ind} = mean_psd(psdx(:,indf),method);
- switch method
- case 'mean'
- SN{ind}=sqrt(mean(psdx(:,indf)/2,2));
- case 'median'
- SN{ind}=sqrt(median(psdx(:,indf)/2),2);
- case 'logmexp'
- SN{ind} = sqrt(exp(mean(log(psdx(:,indf)/2),2)));
- end
- PSDX{ind} = psdx;
- end
- else
- nc = ceil(d/Nb);
- Yc = mat2cell(Y,[Nb*ones(nc-1,1);d-(nc-1)*Nb],N);
- parfor ind = 1:ceil(d/Nb);
- xdft = fft(Yc{ind},[],2);
- xdft = xdft(:,1:floor(N/2)+1);
- psdx = (1/(Fs*N)) * abs(xdft).^2;
- psdx(:,2:end-1) = 2*psdx(:,2:end-1);
- Yc{ind} = [];
- switch method
- case 'mean'
- SN{ind}=sqrt(mean(psdx(:,indf)/2,2));
- case 'median'
- SN{ind}=sqrt(median(psdx(:,indf)/2),2);
- case 'logmexp'
- SN{ind} = sqrt(exp(mean(log(psdx(:,indf)/2),2)));
- end
-
- end
- end
- sn = cell2mat(SN);
-else
- xdft = fft(Y);
- xdft = xdft(:,1:floor(N/2)+1);
- psdx = (1/(Fs*N)) * abs(xdft).^2;
- psdx(:,2:end-1) = 2*psdx(:,2:end-1);
- switch method
- case 'mean'
- sn = sqrt(mean(psdx(:,indf)/2,2));
- case 'median'
- sn = sqrt(median(psdx(:,indf)/2),2);
- case 'logmexp'
- sn = sqrt(exp(mean(log(psdx(:,indf)/2),2)));
- end
-end
-psdx = cell2mat(PSDX);
-if dims > 2
- sn = reshape(sn,sizY(1:dims-1));
-end
-end
diff --git a/deconvolveCa/oasis/dsKernel.m b/deconvolveCa/oasis/dsKernel.m
deleted file mode 100644
index 519fd76..0000000
--- a/deconvolveCa/oasis/dsKernel.m
+++ /dev/null
@@ -1,42 +0,0 @@
-function kernel_new = dsKernel(kernel, tsub)
-%% downsample/upsample the convolution kernel
-%% inputs:
-% kernel: struct variable with fields {'kernel_type', 'pars', 'nMax', 'lb', 'ub', 'bound_pars'}
-% kernel_type: string, convolution kernel type. now support {'exp',
-% 'exp2', 'vector'}
-% pars: parameters for the selected kernel type
-% nMax: length of the kernel
-% lb: lower bound for each parameter
-% ub: upper bound for each parameter
-% bound_pars: logical variable, bound the parameters or not {1, 0}
-%% outputs
-% kernel: struct variable
-
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-
-kernel_new = kernel;
-if nargin<2 || isempty(tsub)
- return;
-end
-
-%% kernel size
-kernel_new.nMax = ceil(kernel.nMax/tsub);
-
-%% kernel type
-kernel_type = kernel.type;
-if strcmpi(kernel_type, 'exp')
- % single exponential function: ~ exp(-t/tau)
- kernel_new.pars = kernel.pars/tsub;
-elseif strcmpi(kernel_type, 'vector')
- % single vector
-len_kernel = length(kernel.pars);
- kernel_new.pars = resample(kernel.pars, ceil(len_kernel/tsub), len_kernel);
-else
- % differencing of two exponential function:
- % ~ exp(-t/tau_d)-exp(-t/tau_r)
- kernel_new.pars = kernel.pars/tsub;
-end
-
-%% lower and upper bounds for parameters
-kernel_new.lb = kernel.lb / tsub;
-kernel_new.ub = kernel.ub / tsub;
\ No newline at end of file
diff --git a/deconvolveCa/oasis/foopsi_oasisAR1.m b/deconvolveCa/oasis/foopsi_oasisAR1.m
deleted file mode 100644
index d09c53e..0000000
--- a/deconvolveCa/oasis/foopsi_oasisAR1.m
+++ /dev/null
@@ -1,171 +0,0 @@
-function [c, s, b, g, active_set] = foopsi_oasisAR1(y, g, lam, smin, optimize_b,...
- optimize_g, decimate, maxIter, gmax)
-%% Infer the most likely discretized spike train underlying an AR(1) fluorescence trace
-% Solves the sparse non-negative deconvolution problem
-% min 1/2|c-y|^2 + lam |s|_1 subject to s_t = c_t-g c_{t-1} >= 0
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: scalar, Parameter of the AR(1) process that models the fluorescence ...
-%impulse response.
-% lam: scalar, sparsity penalty parameter
-% optimize_b: bool, optimize baseline if True
-% optimize_g: integer, number of large, isolated events to consider for
-% optimizing g
-% decimate: int, decimation factor for estimating hyper-parameters faster
-% on decimated data
-% maxIter: int, maximum number of iterations
-% active_set: npool x 4 matrix, warm stared active sets
-% gmax: scalar, maximum value of g
-
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-% b: scalar, fluorescence baseline
-% g: scalar, parameter of the AR(1) process
-% active_set: npool x 4 matrix, active sets
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-
-%% input arguments
-y = reshape(y, [], 1);
-T = length(y);
-
-if ~exist('g', 'var') || isempty(g)
- g = estimate_time_constant(y, 1);
-end
-if ~exist('lam', 'var') || isempty(lam); lam = 0; end
-if ~exist('smin', 'var') || isempty(smin)
- smin = 0;
-elseif smin<0
- smin = abs(smin) * GetSn(y); % use a threshold that is proportional to the noise level
-end
-if ~exist('optimize_b', 'var') || isempty(optimize_b)
- optimize_b = false;
-end
-if ~exist('optimize_g', 'var') || isempty(optimize_g)
- optimize_g = 0;
-end
-if ~exist('decimate', 'var') || isempty(decimate)
- decimate = 1;
-else
- decimate = max(1, round(decimate));
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = 10;
-end
-
-% change parameters due to downsampling
-if decimate>1
- decimate = 1; %#ok
- disp('to be done');
- % fluo = y;
- % y = resample(y, 1, decimate);
- % g = g^decimate;
- % thresh = thresh / decimate / decimate;
- % T = length(y);
-end
-
-%% optimize parameters
-if ~optimize_b %% don't optimize the baseline b
- %% initialization
- b = 0;
- [solution, spks, active_set] = oasisAR1(y, g, lam, smin);
-
- %% iteratively update parameters g
- if optimize_g % update g
- [solution, active_set, g, spks] = update_g(y, active_set,lam, smin);
- end
-else
- %% initialization
- b = quantile(y, 0.15);
- [solution, spks, active_set] = oasisAR1(y-b, g, lam, smin);
-
- %% iteratively update parameters g and b
- for m=1:maxIter
- b = mean(y-solution);
- if optimize_g % update g
- g0 = g;
- if g>gmax % spike counts are too small. stop
- g = estimate_time_constant(y, 1);
- [solution, spks, active_set] = oasisAR1(y-b, g, lam, smin);
- break;
- end
- if isempty(active_set)
- break;
- end
- [solution, active_set, g, spks] = update_g(y-b, active_set,lam, smin);
- if abs(g-g0)/g0 < 1e-3 % g is converged
- optimize_g = false;
- end
- else
- break;
- end
- end
-end
-c = solution;
-s = spks;
-end
-%update the AR coefficient: g
-function [c, active_set, g, s] = update_g(y, active_set, lam, smin)
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% active_set: npools*4 matrix, previous active sets.
-% lam: scalar, curret value of sparsity penalty parameter lambda.
-
-%% outputs
-% c: T*1 vector
-% s: T*1 vector, spike train
-% active_set: npool x 4 matrix, active sets
-% g: scalar
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-%% initialization
-
-len_active_set = size(active_set, 1); %number of active sets
-y = reshape(y,[],1); % fluorescence data
-maxl = max(active_set(:, 4)); % maximum ISI
-c = zeros(size(y)); % the optimal denoised trace
-
-%% find the optimal g and get the warm started active_set
-g = fminbnd(@rss_g, 0, 1);
-yp = y - lam*(1-g);
-for m=1:len_active_set
- tmp_h = exp(log(g)*(0:maxl)'); % response kernel
- tmp_hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- li = active_set(m, 4);
- ti = active_set(m, 3);
- idx = ti:(ti+li-1);
- active_set(m,1) = (yp(idx))'*tmp_h(1:li);
- active_set(m,2) = tmp_hh(li);
-end
-[c,s,active_set] = oasisAR1(y, g, lam, smin, active_set);
-
-%% nested functions
- function rss = rss_g(g)
- h = exp(log(g)*(0:maxl)'); % response kernel
- hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- yp = y - lam*(1-g); % include the penalty term
- for ii=1:len_active_set
- li = active_set(ii, 4);
- ti = active_set(ii, 3);
- idx = ti:(ti+li-1);
- tmp_v = max(yp(idx)' * h(1:li) / hh(li), 0);
- c(idx) = tmp_v*h(1:li);
- end
- res = y-c;
- rss = res'*res; % residual sum of squares
- end
-end
\ No newline at end of file
diff --git a/deconvolveCa/oasis/foopsi_oasisAR2.m b/deconvolveCa/oasis/foopsi_oasisAR2.m
deleted file mode 100644
index be475d4..0000000
--- a/deconvolveCa/oasis/foopsi_oasisAR2.m
+++ /dev/null
@@ -1,191 +0,0 @@
-function [c, s, b, g, active_set] = foopsi_oasisAR2(y, g, lam, smin, optimize_b,...
- optimize_g, decimate, maxIter)
-%% Infer the most likely discretized spike train underlying an AR(2) fluorescence trace
-% Solves the sparse non-negative deconvolution problem
-% min 1/2|c-y|^2 + lam |s|_1 subject to s_t = c_t-g_1 c_{t-1}- g_2 c_{t-2} >= 0
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: 1*2 vector, Parameter of the AR(2) process that models the fluorescence ...
-%impulse response.
-% lam: scalar, sparsity penalty parameter
-% smin: scalar, minimum spike size
-% optimize_b: bool, optimize baseline if True
-% optimize_g: integer, number of large, isolated events to consider for
-% optimizing g
-% decimate: int, decimation factor for estimating hyper-parameters faster
-% on decimated data
-% maxIter: int, maximum number of iterations
-% active_set: npool x 4 matrix, warm stared active sets
-
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-% b: scalar, fluorescence baseline
-% g: scalar, parameter of the AR(1) process
-% active_set: npool x 4 matrix, active sets
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-
-%% input arguments
-y = reshape(y, [], 1);
-T = length(y);
-
-if ~exist('g', 'var') || isempty(g)
- g = estimate_time_constant(y, 2);
-end
-if ~exist('lam', 'var') || isempty(lam); lam = 0; end
-
-if ~exist('smin', 'var') || isempty(smin);
- smin = 0;
-end
-if ~exist('optimize_b', 'var') || isempty(optimize_b)
- optimize_b = false;
-end
-if ~exist('optimize_g', 'var') || isempty(optimize_g)
- optimize_g = 0;
-end
-if ~exist('decimate', 'var') || isempty(decimate)
- decimate = 1;
-else
- decimate = max(1, round(decimate));
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = 10;
-end
-
-% change parameters due to downsampling
-if decimate>1
- decimate = 1; %#ok
- disp('to be done');
- % fluo = y;
- % y = resample(y, 1, decimate);
- % g = g^decimate;
- % thresh = thresh / decimate / decimate;
- % T = length(y);
-end
-
-%% optimize parameters
-if ~optimize_b %% don't optimize the baseline b
- %% initialization
- b = 0;
- [solution, spks, active_set] = oasisAR2(y, g, lam, smin);
-
- %% iteratively update parameters g
- if optimize_g;
- g_old = g;
- g = update_g(y-b, g, spks);
- [solution, spks,active_set] = oasisAR2(y, g, 0, smin);
- end
-else
- disp('to be done');
-% %% initialization
-% b = quantile(y, 0.15);
-% [solution, spks, active_set] = oasisAR2(y-b, g, lam, smin);
-%
- %% iteratively update parameters g and b
-% for m=1:maxIter
-% b = mean(y-solution);
-% if and(optimize_g, ~g_converged);
-% g0 = g;
-% g = update_g(y-b, g, spks);
-% smin = choose_smin(g, sn, 0.9999);
-% [solution, spks,active_set] = oasisAR2(y, g, 0, smin);
-%
-% if norm(g-g0,2)/norm(g0) < 1e-3 % g is converged
-% g_converged = true;
-% end
-% else
-% break;
-% end
-% end
-end
-c = solution;
-s = spks;
-end
-
-
-%update the AR coefficient: g
-function g = update_g(y, g, spks)
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: 2x1 vector, AR2 parameters
-% active_set: npools*4 matrix, previous active sets.
-% smin: scalr, minimize size of nonzero spikes
-
-%% outputs
-% c: T*1 vector
-% s: T*1 vector, spike train
-% active_set: npool x 4 matrix, active sets
-% g: scalar
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-
-%% initialization
-s_th = quantile(spks(spks>1e-3), 0.25);
-tsp = find(spks>=s_th);
-tsp = reshape(tsp, 1, []);
-time_p = find(conv2(double(spks<=s_th), ones(30,1), 'same')>0);
-time_p = reshape(time_p,[],1);
-y = reshape(y,[],1); % fluorescence data
-yp = y(time_p);
-T = length(y);
-tau_dr = ar2exp(g);
-tau_d = tau_dr(1);
-tau_r = tau_dr(2);
-warning('off', 'MATLAB:singularMatrix');
-
-%% find the optimal g and get the warm started active_set
-tau_d0 = tau_d;
-tau_r0 = tau_r;
-bnd_d = tau_d0 * [1/4, 4];
-bnd_r = tau_r0 * [1/4, 4];
-for m=1:10
- tau_r = fminbnd(@rss_taur, bnd_r(1), bnd_r(2));
- tau_d = fminbnd(@rss_taud, bnd_d(1), bnd_d(2));
- if and(abs(tau_d-tau_d0)/tau_d0 < 1e-4, abs(tau_r-tau_r0)/tau_r0 < 1e-4)
- break;
- else
- tau_d0 = tau_d;
- tau_r0 = tau_r;
- end
-end
-
-%% compute the optimal solution
-g = exp2ar([tau_d, tau_r]);
-
-%% nested functions
-
- function rss = rss_taur(tau_r)
- ht = (exp(-(1:T)/tau_d) - exp(-(1:T)/tau_r))/(tau_d-tau_r);
- ht(T) = 0;
- ind = bsxfun(@minus, time_p, tsp);
- ind(ind<=0) = T;
- V = ht(ind);
-
- % find the best value of st
- s = (V'*V)\(V'*yp);
- res = yp - V*s;
- rss = res' * res;
- end
-
- function rss = rss_taud(tau_d)
- ht = (exp(-(1:T)/tau_d) - exp(-(1:T)/tau_r))/(tau_d-tau_r);
- ht(T) = 0;
- ind = bsxfun(@minus, time_p, tsp);
- ind(ind<=0) = T;
- V = ht(ind);
-
- % find the best value of st
- s = (V'*V)\(V'*yp);
- res = yp - V*s;
- rss = res' * res;
- end
-end
\ No newline at end of file
diff --git a/deconvolveCa/oasis/oasisAR1.m b/deconvolveCa/oasis/oasisAR1.m
deleted file mode 100644
index f7bb114..0000000
--- a/deconvolveCa/oasis/oasisAR1.m
+++ /dev/null
@@ -1,109 +0,0 @@
-function [c, s, active_set] = oasisAR1(y, g, lam, smin, active_set)
-%% Infer the most likely discretized spike train underlying an AR(1) fluorescence trace
-% Solves the sparse non-negative deconvolution problem
-% min 1/2|c-y|^2 + lam |s|_1 subject to s_t = c_t-g c_{t-1} >=s_min or =0
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% OR %%
-% len_active_set*4 matrix, active set
-
-% g: scalar, Parameter of the AR(1) process that models the fluorescence ...
-%impulse response.
-% lam: scalar, sparsity penalty parameter lambda.
-% smin: scalar, optional, default 0
-%miniumal non-zero activity within each bin (minimal 'spike size').
-% active_set: npool x 4 matrix, warm stared active sets
-
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-% active_set: npool x 4 matrix, active sets
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-%% initialization
-y = reshape(y, [], 1);
-if isempty(y)
- T = sum(active_set(:,4));
-else
-T = length(y);
-end
-if ~exist('g', 'var') || isempty(g)
- g = estimate_time_constant(y);
-elseif length(g)>1
- c = zeros(T,1);
- s = zeros(T,1);
- active_set = [];
- return;
-end
-if ~exist('lam', 'var') || isempty(lam); lam = 0; end
-if ~exist('smin', 'var') || isempty(smin); smin = 0; end
-if ~exist('active_set', 'var') || isempty(active_set)
- len_active_set = T;
- active_set = [y-lam*(1-g),ones(T,1),(1:T)',ones(T,1),(1:T)'-1, (1:T)'+1]; % each row is one pool: (vi, wi, t, l)
- active_set(end, :) = [y(end)-lam,1,T,1,T-1,nan] ;
- active_set(1,5) = nan;
-else
- len_active_set = size(active_set,1);
- active_set(:,5) = [nan; (1:len_active_set-1)'];
- active_set(:,6) = [(2:len_active_set)';nan];
-end
-idx = true(len_active_set,1);
-
-%% run OASIS
-ii = 1;
-ii_next = active_set(ii,6);
-while ~isnan(ii_next)
- % find the active set
- while (~isnan(ii_next)) && (active_set(ii_next,1)/active_set(ii_next,2)...
- >=active_set(ii,1)/active_set(ii,2)*g^(active_set(ii,4))+smin)
- active_set(ii_next,5) = ii;
- ii = ii_next;
- ii_next = active_set(ii,6);
- end
-
- if isnan(ii_next); break; end
-
- %% merge pools
- active_set(ii,1) = active_set(ii,1) + active_set(ii_next,1)* (g^(active_set(ii,4)));
- active_set(ii,2) = active_set(ii,2) + active_set(ii_next,2)*(g^(2*active_set(ii,4)));
- active_set(ii,4) = active_set(ii,4) + active_set(ii_next,4);
- active_set(ii,6) = active_set(ii_next,6);
- idx(ii_next) = false;
- ii_next = active_set(ii,6);
- ii_prev = active_set(ii, 5);
-
- %% backtrack until violations fixed
- while (~isnan(ii_prev)) && (active_set(ii,1)/active_set(ii,2)<...
- active_set(ii_prev,1)/active_set(ii_prev,2)*g^(active_set(ii_prev,4))+smin)
- ii_next = ii;
- ii = ii_prev;
- active_set(ii,1) = active_set(ii,1) + active_set(ii_next,1)* (g^(active_set(ii,4)));
- active_set(ii,2) = active_set(ii,2) + active_set(ii_next,2)*(g^(2*active_set(ii,4)));
- active_set(ii,4) = active_set(ii,4) + active_set(ii_next,4);
- active_set(ii,6) = active_set(ii_next,6);
- idx(ii_next) = false;
-
- ii_prev = active_set(ii, 5);
- ii_next = active_set(ii,6);
- end
-end
-active_set(~idx, :) = [];
-len_active_set = size(active_set,1);
-
-%% construct solution for all t
-c = zeros(T, 1);
-s = c;
-for ii=1:len_active_set
- t0 = active_set(ii,3);
- tau = active_set(ii, 4);
- c(t0:(t0+tau-1)) = max(0,active_set(ii,1)/active_set(ii,2)) * (g.^(0:(tau-1)));
-end
-
-s(active_set(2:end,3)) = c(active_set(2:end,3)) - g*c(active_set(2:end,3)-1);
diff --git a/deconvolveCa/oasis/oasisAR2.m b/deconvolveCa/oasis/oasisAR2.m
deleted file mode 100644
index e11e69d..0000000
--- a/deconvolveCa/oasis/oasisAR2.m
+++ /dev/null
@@ -1,156 +0,0 @@
-function [c, s, active_set] = oasisAR2(y, g, lam, smin, T_over_ISI, jitter, active_set)
-%% Infer the most likely discretized spike train underlying an AR(2) fluorescence trace
-% Solves the sparse non-negative deconvolution problem
-% min 1/2|c-y|^2 + lam |s|_1 subject to s_t = c_t-g1*c_{t-1}-g2*c_{t-2} >=s_min or =0
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g1: scalar, first parameter of the AR(2) process that models the fluorescence ...
-%impulse response.
-% g2: scalar, second parameter of the AR(2) process that models the fluorescence ...
-%impulse response.
-% lam: scalar, sparsity penalty parameter lambda.
-% smin: scalar, optional, default 0
-%miniumal non-zero activity within each bin (minimal 'spike size').
-% T_over_ISI: scalar, ratio of recording duration T and maximumal
-% inter-spike-interval. default: 1
-% jitter: bool, perform correction step by jittering spike times to
-% minimize RSS. it helps to avoid delayed spike detection. default:
-% false;
-
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-% active_set: npool * 4 matrix, active set
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-%% initialization
-y = reshape(y, [], 1);
-if ~exist('g', 'var') || isempty(g)
- g = estimate_time_constant(y, 2);
-end
-g1 = g(1);
-g2 = g(2);
-
-if ~exist('lam', 'var') || isempty(lam); lam = 0; end
-if ~exist('smin', 'var') || isempty(smin); smin = 0; end
-if ~exist('T_over_ISI', 'var') || isempty(T_over_ISI)
- T_over_ISI = 1;
-end
-if ~exist('jitter', 'var') || isempty(jitter)
- jitter = false;
-end
-
-%% initialization
-T = length(y);
-yp = y - lam * (1-g1-g2);
-yp(end-1) = y(end-1) - lam*(1-g1);
-yp(end) = y(end) - lam;
-
-if ~exist('active_set', 'var') || isempty(active_set)
- % active set
- len_active_set = length(y);
- active_set = [yp, yp, (1:T)', ones(T,1), (1:T)'-1, (1:T)'+1];
- active_set(1,5) = nan;
- active_set(end,6) = nan;
-else
- len_active_set = size(active_set,1);
- active_set(:,5) = [nan;(1:len_active_set-1)'];
- active_set(:,6) = [(2:len_active_set)';nan];
-end
-idx = true(len_active_set,1);
-
-% precompute
-len_g = T / T_over_ISI;
-temp = roots([1, -g1, -g2]);
-d = max(temp); r = min(temp);
-g11 = (exp(log(d)*(1:len_g)') - exp(log(r)*(1:len_g)')) / (d-r);
-g12 = [0; g2*g11(1:(end-1))];
-g11g11 = cumsum(g11.*g11);
-g11g12 = cumsum(g11.*g12);
-
-%% run OASIS
-ii = 2;
-ii_next = active_set(ii,6);
-ii_prev = active_set(ii,5);
-while ~isnan(ii_next)
- % find the active set
- while (~isnan(ii_next)) && (g11(active_set(ii,4)+1)*active_set(ii,1) + ...
- g12(active_set(ii,4)+1)*active_set(ii_prev,2) + smin <= active_set(ii_next,1))
- active_set(ii_next,5) = ii;
- ii = ii_next; % move to the next pool
- ii_next = active_set(ii,6);
- ii_prev = active_set(ii,5);
- end
- if isnan(ii_next); break; end
-
- %% merge pools
- active_set(ii, 4) = active_set(ii, 4) + active_set(ii_next, 4);
- ti = active_set(ii,3);
- li = active_set(ii,4);
- active_set(ii,1) = (g11(1:li)'*yp(ti+(1:li)-1) - g11g12(li)*active_set(ii_prev,2))/g11g11(li);
- active_set(ii,2) = g11(li)*active_set(ii,1) + g12(li)*active_set(ii_prev,2);
- idx(ii_next) = false;
- active_set(ii,6) = active_set(ii_next, 6);
- ii_next = active_set(ii, 6);
- if ~isnan(ii_next)
- active_set(ii_next,5) = ii;
- end
-
- ii_prev_1 = active_set(ii,5);
- ii_prev_2 = active_set(ii_prev_1,5);
- %% backtrack until violations fixed
- while (~isnan(ii_prev_2)) && (g11(active_set(ii_prev_1,4)+1)*active_set(ii_prev_1,1) + g12(active_set(ii_prev_1,4)+1)...
- *active_set(ii_prev_2,2) + smin > active_set(ii,1))
- ii_next = ii;
- ii = ii_prev_1;
- ii_prev = ii_prev_2;
-
- active_set(ii, 4) = active_set(ii, 4) + active_set(ii_next, 4);
- ti = active_set(ii,3);
- li = active_set(ii,4);
- active_set(ii,1) = (g11(1:li)'*yp(ti+(1:li)-1) - g11g12(li)*active_set(ii_prev,2))/g11g11(li);
- active_set(ii,2) = g11(li)*active_set(ii,1) + g12(li)*active_set(ii_prev,2);
- idx(ii_next) = false;
- active_set(ii,6) = active_set(ii_next, 6);
- ii_next = active_set(ii, 6);
- if ~isnan(ii_next)
- active_set(ii_next,5) = ii;
- end
- ii_prev_1 = active_set(ii,5);
- ii_prev_2 = active_set(ii_prev_1,5);
- end
-
-end
-
-%% jitter
-% a_s = active_set;
-if jitter
- disp('to be done\n');
-end
-
-active_set(~idx, :) = [];
-len_active_set = size(active_set,1);
-
-%% construct solution for all t
-c = zeros(T,1);
-for ii=1:len_active_set
- vi = active_set(ii,1);
- ti = active_set(ii,3);
- li = active_set(ii,4);
- c(ti) = vi;
-
- for m=1:(li-1)
- c(ti+m) = g1*c(ti+m-1) + g2*c(ti+m-2);
- end
-end
-c(c<0) = 0;
-
-s = [0;0;0; c(4:end)-g1*c(3:(end-1))-g2*c(2:(end-2))];
-s(s= 0
-
-%% inputs:
-% y: T*1 vector, vth dimensional array containing the fluorescence intensities
- %withone entry per time-bin.
-% g: vector, shape (p,)
-% if p in (1,2): AR coefficients for AR(p) process
-% else: kernel that models the fluorescence implulse response
-% lam: scalar, sparsity penalty parameter lambda.
-% shift: integer scalar, number of frames by which to shift window from on run of
-% NNLS to the next, default-100
-% win: integer acalar, window size
-% tol: scalar, tolerance parameters
-% maxIter: scalar, maximum number of iterations before termination
-% mask: T * 1 boolean vector, restrict potential spike times
-% smin: scalar, minimum spike size
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-%% input arguments
-T = length(y);
-y = reshape(y, [], 1);
-
-if ~exist('lam', 'var') || isempty(lam)
- lam = 0;
-end
-if ~exist('shift', 'var') || isempty(shift)
- shift = 100;
-end
-if ~exist('win', 'var') || isempty(win)
- win = 200;
-end
-
-if ~exist('tol', 'var') || isempty(tol)
- tol = 1e-9;
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = [];
-end
-if ~exist('mask', 'var') || isempty(mask)
- mask = true(T,1);
-end
-if ~exist('smin', 'var') || isempty(smin)
- smin = 0;
-end
-%% get the response kernel
-w = win;
-K = zeros(w);
-[u, t] = meshgrid(1:w, 1:w);
-ind = 1+t-u;
-if length(g)==1
- h = exp(log(g)*(0:(w-1)));
-elseif length(g)==2
- temp = roots([1, -g(1), -g(2)]);
- d = max(temp);
- r = min(temp);
- h = (exp(log(d)*(1:w)) - exp(log(r)*(1:w))) / (d-r); % convolution kernel
-else
- h = g;
-end
-K(ind>0) = h(ind(ind>0)); % convolution matrix
-KK = K'*K;
-
-%% initialization
-a = sum(inv(K));
-yp = y - lam * a(1);
-yp((end-w+1):end) = yp((end-w+1):end) - lam * a';
-s = zeros(T, 1);
-c = zeros(T, 1);
-
-%% run online deconvolution
-t = 1;
-yp0 = yp;
-while t <= T-w+1
- ind = t:(t+w-1);
- s(ind) = nnls(KK, K'*yp(ind), s(ind), tol, maxIter, mask(ind));
- yp(ind) = yp(ind) - K(:, 1:shift)*s(t:(t+shift-1));
- c(ind) = c(ind) + K(:, 1:shift)*s(t:(t+shift-1));
- t = t + shift;
-end
-s(t:T) = nnls(KK((t+w-T):w, (t+w-T):w), K(1:(T-t+1), 1:(T-t+1))'*yp(t:T), ...
- s(t:T), tol, maxIter, mask(t:T));
-c(t:T) = c(t:T) + K((t+w-T):w, (t+w-T):w) * s(t:T);
-
-%% running thresholded version
-if smin>0
- yp = yp0;
- c = zeros(size(c));
- mask = (s>smin/100);
- t = 1;
- while t <= T-w+1
- ind = t:(t+w-1);
- s(ind) = nnls(KK, K'*yp(ind), s(ind), tol, maxIter, mask(ind), smin);
- yp(ind) = yp(ind) - K(:, 1:shift)*s(t:(t+shift-1));
- c(ind) = c(ind) + K(:, 1:shift)*s(t:(t+shift-1));
- t = t + shift;
- end
- s(t:T) = nnls(KK((t+w-T):w, (t+w-T):w), K(1:(T-t+1), 1:(T-t+1))'*yp(t:T), ...
- s(t:T), tol, maxIter, mask(t:T), smin);
- c(t:T) = c(t:T) + K((t+w-T):w, (t+w-T):w) * s(t:T);
-end
-
-
-function s = nnls(KK, Ky, s, tol, maxIter, mask, smin)
-%% fast algorithm for solving nonnegativity constrained least squared
-% problem minize norm(y-K*s, 2), s.t. s>=0.
-
-%% inputs:
-% KK: p x p matrix, K'*K
-% Ky: n x 1 vector, K'*y
-% s: p x 1 vector, warm started s
-% tol: scalar, smallest nonzero values
-% maxIter: scalar, maximum nonzero values
-% mask: p x 1 vector, mask to restrict potential spike times considered
-% smin: scala, minimize size of the spike
-
-%% outputs:
-% s: p x 1 vector, solution
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-% Bro R & Jong S, Journal of Chemometrics 1997, A FAST NON-NEGATIVITY-CONSTRAINED LEAST SQUARES ALGORITHM
-
-
-%% input arguments
-if ~exist('mask', 'var')||isempty(mask)
- mask = true(size(KK,1), 1);
-elseif any(mask)
- KK = KK(mask, mask);
- Ky = Ky(mask);
-else
- s = double(mask);
- return;
-end
-
-p = size(KK,2); % dimension of s
-if ~exist('smin', 'var') || isempty(smin)
- smin = 0;
-end
-vth = ones(p,1)*smin;
-if ~exist('s', 'var') || isempty(s)
- s = zeros(p, 1);
- l = Ky;
- Pset = false(p,1);
-else
- s = s(mask);
- s = s - smin;
- Pset = (s>0);
- s(~Pset) = 0;
- l = Ky - KK*s - KK * Pset*smin;
-end
-if ~exist('tol', 'var') || isempty(tol)
- tol = 1e-9;
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = p;
-end
-
-
-% outer loop: loop for passive set
-[~, ind] = max(l);
-for miter =1:maxIter
- % remove element from the active set
- Pset(ind) = true;
-
- % solve unconstrained least squares over the passive set
- try
- mu = KK(Pset, Pset) \ (Ky(Pset)-KK(Pset, Pset)*vth(Pset));
- catch % sigular issue
- mu = (KK(Pset, Pset) + tol*eye(sum(Pset))) \ (Ky(Pset)...
- -KK(Pset, Pset)*vth(Pset));
- end
-
- % inner loop: correct nonnegativity violations
- while any(mu<=0)
- temp = s(Pset) ./ (s(Pset)-mu);
- a = min(temp(mu<0));
- s(Pset) = s(Pset) + a*(mu-s(Pset));
- Pset(s<=tol) = false;
-
- % solve unconstrained least squares over the passive set
- try
- mu = KK(Pset, Pset) \ (Ky(Pset)-KK(Pset, Pset)*vth(Pset));
- catch % sigular issue
- mu = (KK(Pset, Pset) + tol*eye(sum(Pset))) \ (Ky(Pset)...
- -KK(Pset, Pset)*vth(Pset));
- end
- end
-
- s(Pset) = mu;
- l = Ky - KK*s - KK*Pset*smin;
- % at least one iteration
- [lmax, ind] = max(l);
- if lmax < tol % no more passive set
- break;
- end
-end
-s(Pset) = mu + smin;
-temp = double(mask);
-temp(mask) = s;
-s = temp;
diff --git a/deconvolveCa/oasis/test_oasis.m b/deconvolveCa/oasis/test_oasis.m
deleted file mode 100644
index 6f888a6..0000000
--- a/deconvolveCa/oasis/test_oasis.m
+++ /dev/null
@@ -1,34 +0,0 @@
-%% function
-clear; clc; close all;
-T = 1000;
-s = double(rand(1, T)>0.98);
-sig = 0.04;
-
-% example
-tau_d = 5;
-tau_r = 1;
-nMax = 100;
-pars = [tau_d, tau_r];
-kernel = create_kernel('exp2', pars, nMax);
-
-t = 1:kernel.nMax;
-gt = kernel.fhandle(kernel.pars, t);
-c1 = conv(s, gt);
-c1 = c1(1:T);
-y1 = c1 + randn(1, T) * sig;
-
-%% use the true convolution kernel
-kernel0 = kernel;
-kernel0.pars = [10, 0.1];
-kernel0.bound_pars = false;
-figure('position', [1,1,1500, 200]);
-plot(y1);
-hold on;
-plot(c1, 'r', 'linewidth', 2);
-plot(-s*0.1, 'r', 'linewidth', 2);
-tic;
-[chat, shat, kernel_fit, iters] = deconvCa(y1, kernel0, 2, true, false);
-toc;
-plot(chat,'-.g','linewidth', 2);
-plot(-shat*0.1, '-.g', 'linewidth', 2); %, '-.');
-legend('data', 'ground truth: c','ground truth: s', 'OASIS:c', 'OASIS: s'); % 'gound truth: s', 'OASIS: c', 'OASIS: s');
\ No newline at end of file
diff --git a/deconvolveCa/oasis/thresholded_nnls.m b/deconvolveCa/oasis/thresholded_nnls.m
deleted file mode 100644
index 0a612fe..0000000
--- a/deconvolveCa/oasis/thresholded_nnls.m
+++ /dev/null
@@ -1,220 +0,0 @@
-function [c, s] = thresholded_nnls(y, g, sn, smin, shift, win, tol, maxIter, mask, thresh_factor)
-%% Infer the most likely discretized spike train underlying an AR(2) fluorescence trace
-% Solves the sparse non-negative deconvolution problem
-% min 1/2|Ks-y|^2 + lam * |s|_1 subject to s_t = c_t-g c_{t-1} >= 0
-
-%% inputs:
-% y: T*1 vector, vth dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: vector, shape (p,)
-% if p in (1,2): AR coefficients for AR(p) process
-% else: kernel that models the fluorescence implulse response
-% sn: scalar, standard deviation of the noise
-% smin: scalar, minimum spike size
-% shift: integer scalar, number of frames by which to shift window from on run of
-% NNLS to the next, default-100
-% win: integer acalar, window size
-% tol: scalar, tolerance parameters
-% maxIter: scalar, maximum number of iterations before termination
-% mask: T * 1 boolean vector, restrict potential spike times
-% smin: scalar, minimum spike size
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-%% input arguments
-T = length(y);
-y = reshape(y, [], 1);
-
-if ~exist('sn', 'var') || isempty(sn)
- sn = GetSn(y);
-end
-if ~exist('shift', 'var') || isempty(shift)
- shift = 100;
-end
-if ~exist('win', 'var') || isempty(win)
- win = 200;
-end
-
-if ~exist('tol', 'var') || isempty(tol)
- tol = 1e-9;
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = [];
-end
-if ~exist('mask', 'var') || isempty(mask)
- mask = true(T,1);
-end
-if ~exist('smin', 'var') || isempty(smin)
- smin = 0;
-end
-
-thresh = thresh_factor* sn * sn * T;
-
-%% get the response kernel
-w = win;
-K = zeros(w);
-[u, t] = meshgrid(1:w, 1:w);
-ind = 1+t-u;
-if length(g)==1
- h = exp(log(g)*(0:(w-1)));
-elseif length(g)==2
- temp = roots([1, -g(1), -g(2)]);
- d = max(temp);
- r = min(temp);
- h = (exp(log(d)*(1:w)) - exp(log(r)*(1:w))) / (d-r); % convolution kernel
-else
- h = g;
-end
-K(ind>0) = h(ind(ind>0)); % convolution matrix
-KK = K'*K;
-
-%% initialization
-a = sum(inv(K));
-yp = y - lam * a(1);
-yp((end-w+1):end) = yp((end-w+1):end) - lam * a';
-s = zeros(T, 1);
-c = zeros(T, 1);
-
-%% run online deconvolution
-t = 1;
-yp0 = yp;
-while t <= T-w+1
- ind = t:(t+w-1);
- s(ind) = nnls(KK, K'*yp(ind), s(ind), tol, maxIter, mask(ind));
- yp(ind) = yp(ind) - K(:, 1:shift)*s(t:(t+shift-1));
- c(ind) = c(ind) + K(:, 1:shift)*s(t:(t+shift-1));
- t = t + shift;
-end
-s(t:T) = nnls(KK((t+w-T):w, (t+w-T):w), K(1:(T-t+1), 1:(T-t+1))'*yp(t:T), ...
- s(t:T), tol, maxIter, mask(t:T));
-c(t:T) = c(t:T) + K((t+w-T):w, (t+w-T):w) * s(t:T);
-
-%% running thresholded version for fast initialization
-if smin>0
- yp = yp0;
- c = zeros(size(c));
- mask = (s>1e-4);
- t = 1;
- while true
- % [tmp_min, ind] = min(s(mask));
- ind = t:(t+w-1);
- s(ind) = nnls(KK, K'*yp(ind), s(ind), tol, maxIter, mask(ind), smin);
- yp(ind) = yp(ind) - K(:, 1:shift)*s(t:(t+shift-1));
- c(ind) = c(ind) + K(:, 1:shift)*s(t:(t+shift-1));
- t = t + shift;
- end
- s(t:T) = nnls(KK((t+w-T):w, (t+w-T):w), K(1:(T-t+1), 1:(T-t+1))'*yp(t:T), ...
- s(t:T), tol, maxIter, mask(t:T), smin);
- c(t:T) = c(t:T) + K((t+w-T):w, (t+w-T):w) * s(t:T);
-end
-
-%%
-
-function s = nnls(KK, Ky, s, tol, maxIter, mask, smin)
-%% fast algorithm for solving nonnegativity constrained least squared
-% problem minize norm(y-K*s, 2), s.t. s>=0.
-
-%% inputs:
-% KK: p x p matrix, K'*K
-% Ky: n x 1 vector, K'*y
-% s: p x 1 vector, warm started s
-% tol: scalar, smallest nonzero values
-% maxIter: scalar, maximum nonzero values
-% mask: p x 1 vector, mask to restrict potential spike times considered
-% smin: scala, minimize size of the spike
-
-%% outputs:
-% s: p x 1 vector, solution
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-% Bro R & Jong S, Journal of Chemometrics 1997, A FAST NON-NEGATIVITY-CONSTRAINED LEAST SQUARES ALGORITHM
-
-
-%% input arguments
-if ~exist('mask', 'var')||isempty(mask)
- mask = true(size(KK,1), 1);
-elseif any(mask)
- KK = KK(mask, mask);
- Ky = Ky(mask);
-else
- s = double(mask);
- return;
-end
-
-p = size(KK,2); % dimension of s
-if ~exist('smin', 'var') || isempty(smin)
- smin = 0;
-end
-vth = ones(p,1)*smin;
-if ~exist('s', 'var') || isempty(s)
- s = zeros(p, 1);
- l = Ky;
- Pset = false(p,1);
-else
- s = s(mask);
- s = s - smin;
- Pset = (s>0);
- s(~Pset) = 0;
- l = Ky - KK*s - KK * Pset*smin;
-end
-if ~exist('tol', 'var') || isempty(tol)
- tol = 1e-9;
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = p;
-end
-
-
-% outer loop: loop for passive set
-[~, ind] = max(l);
-for miter =1:maxIter
- % remove element from the active set
- Pset(ind) = true;
-
- % solve unconstrained least squares over the passive set
- try
- mu = KK(Pset, Pset) \ (Ky(Pset)-KK(Pset, Pset)*vth(Pset));
- catch % sigular issue
- mu = (KK(Pset, Pset) + tol*eye(sum(Pset))) \ (Ky(Pset)...
- -KK(Pset, Pset)*vth(Pset));
- end
-
- % inner loop: correct nonnegativity violations
- while any(mu<=0)
- temp = s(Pset) ./ (s(Pset)-mu);
- a = min(temp(mu<0));
- s(Pset) = s(Pset) + a*(mu-s(Pset));
- Pset(s<=tol) = false;
-
- % solve unconstrained least squares over the passive set
- try
- mu = KK(Pset, Pset) \ (Ky(Pset)-KK(Pset, Pset)*vth(Pset));
- catch % sigular issue
- mu = (KK(Pset, Pset) + tol*eye(sum(Pset))) \ (Ky(Pset)...
- -KK(Pset, Pset)*vth(Pset));
- end
- end
-
- s(Pset) = mu;
- l = Ky - KK*s - KK*Pset*smin;
- % at least one iteration
- [lmax, ind] = max(l);
- if lmax < tol % no more passive set
- break;
- end
-end
-s(Pset) = mu + smin;
-temp = double(mask);
-temp(mask) = s;
-s = temp;
diff --git a/deconvolveCa/oasis/thresholded_oasisAR1.m b/deconvolveCa/oasis/thresholded_oasisAR1.m
deleted file mode 100644
index 99115c8..0000000
--- a/deconvolveCa/oasis/thresholded_oasisAR1.m
+++ /dev/null
@@ -1,266 +0,0 @@
-function [c, s, b, g, smin, active_set] = thresholded_oasisAR1(y, g, sn, optimize_b,...
- optimize_g, decimate, maxIter, thresh_factor, p_noise)
-%% Infer the most likely discretized spike train underlying an AR(1) fluorescence trace
-% Solves the sparse non-negative deconvolution problem
-% min 1/2|c-y|^2 subject to s_t = c_t-g c_{t-1} >=s_min or =0
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: scalar, Parameter of the AR(1) process that models the fluorescence ...
-%impulse response.
-% sn: scalar, standard deviation of the noise distribution
-% optimize_b: bool, optimize baseline if True
-% optimize_g: integer, number of large, isolated events to consider for
-% optimizing g
-% decimate: int, decimation factor for estimating hyper-parameters faster
-% on decimated data
-% maxIter: int, maximum number of iterations
-% active_set: npool x 4 matrix, warm stared active sets
-% thresh_factor: scalar, set the maximum thresh as thresh_factor*sn^2*T
-% smin_p: scalar, the probability of rejecting false spikes resulted from
-% noise
-
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-% b: scalar, fluorescence baseline
-% g: scalar, parameter of the AR(1) process
-% smin: scalar, minimum nonzero spike count
-% active_set: npool x 4 matrix, active sets
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-
-%% input arguments
-y = reshape(y, [], 1);
-T = length(y);
-
-if ~exist('g', 'var') || isempty(g)
- g = estimate_time_constant(y, 1);
- g = g(1);
-end
-
-if ~exist('optimize_b', 'var') || isempty(optimize_b)
- optimize_b = false;
-end
-
-if ~exist('sn', 'var') || isempty(sn)
- if optimize_b
- [b, sn] = estimate_baseline_noise(y);
- else
- [~, sn] = estimate_baseline_noise(y);
- end
-end
-if ~exist('optimize_g', 'var') || isempty(optimize_g)
- optimize_g = 0;
-end
-if ~exist('decimate', 'var') || isempty(decimate)
- decimate = 1;
-else
- decimate = max(1, round(decimate));
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = 10;
-end
-if ~exist('thresh_factor', 'var') || isempty(thresh_factor)
- thresh_factor = 1.0;
-end
-if ~exist('p_noise', 'var') || isempty(p_noise)
- p_noise = 0.9999;
-end
-
-% thresh = thresh_factor* sn * sn * T;
-smin = choose_smin(g, sn, p_noise);
-thresh = thresh_factor* sn * sn * T;
-
-% change parameters due to downsampling
-if decimate>1
- decimate = 1; %#ok
- disp('to be done');
- % fluo = y;
- % y = resample(y, 1, decimate);
- % g = g^decimate;
- % thresh = thresh / decimate / decimate;
- % T = length(y);
-end
-g_converged = false;
-
-%% optimize parameters
-tol = 1e-4;
-if ~optimize_b %% don't optimize the baseline b
- b = 0;
- %% initialization
- [solution, spks, active_set] = oasisAR1(y, g, [], smin);
-
- res = y - solution;
- RSS0 = res' * res;
- %% optimize the baseline b and dependends on the optimized g too
- for miter=1:maxIter
- if isempty(active_set)
- break;
- end
- % update b and g
- if and(optimize_g, ~g_converged);
- g0 = g;
- [solution, active_set, g, spks] = update_g(y, active_set, smin);
- if abs(g-g0)/g0 < 1e-4;
- g_converged = true;
- end
- end
-
- res = y - solution;
- RSS = res' * res;
- if abs(RSS-RSS0)1
- ind = floor((ind_start+ind_end)/2);
- tmp_smin = sv(ind);
- [tmp_solution, tmp_spks, tmp_active_set] = oasisAR1([], g, [], ...
- tmp_smin, active_set);
- sqRSS = norm(y-tmp_solution,2);
- if sqRSSthresh % decrease smin
- ind_end = ind;
- else
- break;
- end
- end
- end
-
-
-end
-
-%update the AR coefficient: g
-function [c, active_set, g, s] = update_g(y, active_set, smin)
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% active_set: npools*4 matrix, previous active sets.
-% smin: scalr, minimize size of nonzero spikes
-
-%% outputs
-% c: T*1 vector
-% s: T*1 vector, spike train
-% active_set: npool x 4 matrix, active sets
-% g: scalar
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-%% initialization
-
-len_active_set = size(active_set, 1); %number of active sets
-y = reshape(y,[],1); % fluorescence data
-maxl = max(active_set(:, 4)); % maximum ISI
-c = zeros(size(y)); % the optimal denoised trace
-
-%% find the optimal g and get the warm started active_set
-g = fminbnd(@rss_g, 0, 1);
-yp = y;
-for m=1:len_active_set
- tmp_h = exp(log(g)*(0:maxl)'); % response kernel
- tmp_hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- li = active_set(m, 4);
- ti = active_set(m, 3);
- idx = ti:(ti+li-1);
- active_set(m,1) = (yp(idx))'*tmp_h(1:li);
- active_set(m,2) = tmp_hh(li);
-end
-[c,s,active_set] = oasisAR1(y, g, 0, smin, active_set);
-
-%% nested functions
- function rss = rss_g(g)
- h = exp(log(g)*(0:maxl)'); % response kernel
- hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- yp = y; % include the penalty term
- for ii=1:len_active_set
- li = active_set(ii, 4);
- ti = active_set(ii, 3);
- idx = ti:(ti+li-1);
- tmp_v = max(yp(idx)' * h(1:li) / hh(li), 0);
- c(idx) = tmp_v*h(1:li);
- end
- res = y-c;
- rss = res'*res; % residual sum of squares
- end
-end
\ No newline at end of file
diff --git a/deconvolveCa/oasis/thresholded_oasisAR2.m b/deconvolveCa/oasis/thresholded_oasisAR2.m
deleted file mode 100644
index f93512b..0000000
--- a/deconvolveCa/oasis/thresholded_oasisAR2.m
+++ /dev/null
@@ -1,322 +0,0 @@
-function [c, s, b, g, smin, active_set] = thresholded_oasisAR2(y, g, sn, smin, optimize_b,...
- optimize_g, decimate, maxIter, thresh_factor)
-%% Infer the most likely discretized spike train underlying an AR(2) fluorescence trace
-% Solves the sparse non-negative deconvolution problem
-% min 1/2|c-y|^2 + lam |s|_1 subject to s_t = c_t-g_1*c_{t-1} - g_2*c_{t-2}>=s_min or =0
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: scalar, Parameter of the AR(1) process that models the fluorescence ...
-%impulse response.
-% sn: scalar, standard deviation of the noise distribution
-% optimize_b: bool, optimize baseline if True
-% optimize_g: integer, number of large, isolated events to consider for
-% optimizing g
-% decimate: int, decimation factor for estimating hyper-parameters faster
-% on decimated data
-% maxIter: int, maximum number of iterations
-% active_set: npool x 4 matrix, warm stared active sets
-% thresh_factor: scalar, set the maximum thresh as thresh_factor*sn^2*T
-
-%% outputs
-% c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
-% s: T*1 vector, discetized deconvolved neural activity (spikes)
-% b: scalar, fluorescence baseline
-% g: scalar, parameter of the AR(1) process
-% smin: scalar, minimum nonzero spike count
-% active_set: npool x 4 matrix, active sets
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-
-%% input arguments
-y = reshape(y, [], 1);
-T = length(y);
-
-if ~exist('g', 'var') || isempty(g)
- g = estimate_time_constant(y, 2);
-end
-
-if ~exist('optimize_b', 'var') || isempty(optimize_b)
- optimize_b = false;
-end
-
-if ~exist('sn', 'var') || isempty(sn)
- if optimize_b
- [b, sn] = estimate_baseline_noise(y);
- else
- [~, sn] = estimate_baseline_noise(y-smooth(y,100));
- end
-end
-if ~exist('optimize_g', 'var') || isempty(optimize_g)
- optimize_g = 0;
-end
-if ~exist('decimate', 'var') || isempty(decimate)
- decimate = 1;
-else
- decimate = max(1, round(decimate));
-end
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = 10;
-end
-if ~exist('thresh_factor', 'var') || isempty(thresh_factor)
- thresh_factor = 1.0;
-end
-
-%% start from smin that avoid counting gaussian noise as a spike
-smin = choose_smin(g, sn, 0.99999999);
-thresh = thresh_factor* sn * sn * T;
-
-% change parameters due to downsampling
-if decimate>1
- decimate = 1; %#ok
- disp('to be done');
- % fluo = y;
- % y = resample(y, 1, decimate);
- % g = g^decimate;
- % thresh = thresh / decimate / decimate;
- % T = length(y);
-end
-g_converged = false;
-
-%% optimize parameters
-tol = 1e-4;
-if ~optimize_b %% don't optimize the baseline b
- %% initialization
- b = 0;
- [solution, spks, active_set] = oasisAR2(y, g, [], smin);
-
- res = y - solution;
- RSS0 = res' * res;
- %% iteratively update parameters lambda & g
- for miter=1:maxIter
- if isempty(active_set)
- break;
- end
- % update g
- if miter==1 && and(optimize_g, ~g_converged);
- g0 = g;
- g = update_g(y-b, g, spks);
- smin = choose_smin(g, sn, 0.9999);
- [solution, spks,active_set] = oasisAR2(y, g, 0, smin);
- if norm(g-g0,2)/norm(g0) < 1e-3 % g is converged
- g_converged = true;
- end
- end
-
- res = y - solution;
- RSS = res' * res;
- if abs(RSS-RSS0)thresh, sum(solution)<1e-9) % constrained form has been found, stop
- break;
- else
- RSS0 = RSS;
- % update smin
- [smin, solution, spks, active_set] = update_smin(y, g, smin,...
- solution, spks, active_set, sqrt(thresh), max(spks));
- end
- end
-else
- %% initialization
- [b, ~] = estimate_baseline_noise(y);
- [solution, spks, active_set] = oasisAR2(y-b, g, [], smin);
-
- res = y - solution -b;
- RSS0 = res' * res;
- %% iteratively update parameters lambda & g
- for miter=1:maxIter
- if isempty(active_set)
- break;
- end
- % update g
- if and(optimize_g, ~g_converged);
- g0 = g;
- g = update_g(y-b, g, spks);
- smin = choose_smin(g, sn, 0.9999);
- [solution, spks,active_set] = oasisAR2(y, g, 0, smin);
-
- if norm(g-g0,2)/norm(g0) < 1e-3 % g is converged
- g_converged = true;
- end
- end
-
- res = y - solution -b;
- RSS = res' * res;
- if abs(RSS-RSS0)thresh, sum(solution)<1e-9) % constrained form has been found, stop
- break;
- else
- RSS0 = RSS;
- % update smin
- [smin, solution, spks, active_set] = update_smin(y-b, g, smin,...
- solution, spks, active_set, sqrt(thresh), max(spks));
- b = mean(y-solution);
- end
- end
-end
-c = solution;
-s = spks;
-g = g(1:2);
-
-%% nested functions
- function [smin, solution, spks, active_set] = update_smin(y, g, smin, solution, ...
- spks, active_set, thresh, s_max)
- %%estimate smin to match the thresholded RSS
- len_active_set = size(active_set, 1);
- sv = linspace(smin, s_max, min(9, len_active_set));
- ind_start = 1;
- ind_end = length(sv);
-
- while (ind_end-ind_start)>1
- ind = floor((ind_start+ind_end)/2);
- tmp_smin = sv(ind);
- [tmp_solution, tmp_spks, tmp_active_set] = oasisAR2(y, g, [], ...
- tmp_smin, [], [], active_set);
- sqRSS = norm(y-tmp_solution,2);
- if sqRSSthresh % decrease smin
- ind_end = ind;
- else
- break;
- end
- end
- end
-
-
-end
-%
-% function [c, active_set, g, s] = update_g(y, g, spks, smin, c)
-% %% update the AR coefficient: g
-%
-%
-% %% residual
-% yres = y - c;
-% T = length(y);
-% %% convolution kernel
-% ht = filter(1,[1,-g],[1,zeros(1,500)]);
-% ht(ht<0.01) = [];
-% w = length(ht);
-% ht = [ zeros(1, 2), ht];
-% %% find all spikes
-% tsp = find(spks>0);
-% tsp(tsp<3) = [];
-% tsp(tsp==T) = [];
-% spv = spks(tsp);
-%
-%
-% %% compute the mean waveform
-% mean_trace = zeros(1, 2+w);
-% for m=1:length(tsp)
-% ti = tsp(m);
-% if ti<= T-w
-% mean_trace = mean_trace + ht*spv(m) + yres((ti-2):(ti+w-1))' ;
-% else
-% ind = (ti-2):T;
-% mean_trace(1:(T-ti+3)) = mean_trace(1:(T-ti+3)) + ht(1:(T-ti+3))*spv(m) + yres(ind)'/spv(m);
-% end
-% end
-%
-% g = estimate_time_constant(mean_trace);
-% [c, s, active_set] = oasisAR2(y, g, [], smin);
-% end
-
-%update the AR coefficient: g
-function g = update_g(y, g, spks)
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% g: 2x1 vector, AR2 parameters
-% active_set: npools*4 matrix, previous active sets.
-% smin: scalr, minimize size of nonzero spikes
-
-%% outputs
-% c: T*1 vector
-% s: T*1 vector, spike train
-% active_set: npool x 4 matrix, active sets
-% g: scalar
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-
-%% initialization
-s_th = quantile(spks(spks>1e-3), 0.25);
-tsp = find(spks>=s_th);
-tsp = reshape(tsp, 1, []);
-time_p = find(conv2(double(spks<=s_th), ones(30,1), 'same')>0);
-time_p = reshape(time_p,[],1);
-y = reshape(y,[],1); % fluorescence data
-yp = y(time_p);
-T = length(y);
-tau_dr = ar2exp(g);
-tau_d = tau_dr(1);
-tau_r = tau_dr(2);
-warning('off', 'MATLAB:singularMatrix');
-
-%% find the optimal g and get the warm started active_set
-tau_d0 = tau_d;
-tau_r0 = tau_r;
-bnd_d = tau_d0 * [1/4, 4];
-bnd_r = tau_r0 * [1/4, 4];
-for m=1:10
- try
- tau_r = fminbnd(@rss_taur, bnd_r(1), bnd_r(2));
- tau_d = fminbnd(@rss_taud, bnd_d(1), bnd_d(2));
- catch
- break;
- end
- if and(abs(tau_d-tau_d0)/tau_d0 < 1e-4, abs(tau_r-tau_r0)/tau_r0 < 1e-4)
- break;
- else
- tau_d0 = tau_d;
- tau_r0 = tau_r;
- end
-end
-
-%% compute the optimal solution
-g = exp2ar([tau_d, tau_r]);
-
-%% nested functions
-
- function rss = rss_taur(tau_r)
- ht = (exp(-(1:T)/tau_d) - exp(-(1:T)/tau_r))/(tau_d-tau_r);
- ht(T) = 0;
- ind = bsxfun(@minus, time_p, tsp);
- ind(ind<=0) = T;
- V = ht(ind);
-
- % find the best value of st
- s = (V'*V)\(V'*yp);
- res = yp - V*s;
- rss = res' * res;
- end
-
- function rss = rss_taud(tau_d)
- ht = (exp(-(1:T)/tau_d) - exp(-(1:T)/tau_r))/(tau_d-tau_r);
- ht(T) = 0;
- ind = bsxfun(@minus, time_p, tsp);
- ind(ind<=0) = T;
- V = ht(ind);
-
- % find the best value of st
- s = (V'*V)\(V'*yp);
- res = yp - V*s;
- rss = res' * res;
- end
-end
\ No newline at end of file
diff --git a/deconvolveCa/oasis/update_g.m b/deconvolveCa/oasis/update_g.m
deleted file mode 100644
index c28ba80..0000000
--- a/deconvolveCa/oasis/update_g.m
+++ /dev/null
@@ -1,83 +0,0 @@
-function [c, active_set, g, s] = update_g(y, active_set, g, lam)
-%% update the tuning parameter lambda to reduce |s|_1 while |y-c|_2^2 <= sn^2*T
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
-%withone entry per time-bin.
-% active_set: npools*4 matrix, previous active sets
-% g: scalar, Parameter of the AR(1) process that models the fluorescence ...
-%impulse response.
-% lam: scalar, curret value of sparsity penalty parameter lambda.
-
-%% outputs
-% c: T*1 vector
-% s: T*1 vector, spike train
-% active_set: npool x 4 matrix, active sets
-% g: scalar
-
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-%% initialization
-len_active_set = size(active_set, 1); %number of active sets
-y = reshape(y,[],1); % fluorescence data
-maxl = max(active_set(:, 4)); % maximum ISI
-c = zeros(size(y)); % the optimal denoised trace
-
-%% find the optimal g and get the warm started active_set
-g = fminbnd(@rss_g, 0, 1);
-yp = y - lam*(1-g);
-for m=1:len_active_set
- tmp_h = exp(log(g)*(0:maxl)'); % response kernel
- tmp_hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- li = active_set(m, 4);
- ti = active_set(m, 3);
- idx = ti:(ti+li-1);
- active_set(m,1) = (yp(idx))'*tmp_h(1:li);
- active_set(m,2) = tmp_hh(li);
-end
-[c,s,active_set] = oasisAR1(y, g, lam, [], active_set);
-
-%% nested functions
- function rss = rss_g(g)
- h = exp(log(g)*(0:maxl)'); % response kernel
- hh = cumsum(h.*h); % hh(k) = h(1:k)'*h(1:k)
- yp = y - lam*(1-g); % include the penalty term
- for ii=1:len_active_set
- li = active_set(ii, 4);
- ti = active_set(ii, 3);
- idx = ti:(ti+li-1);
- tmp_v = max(yp(idx)' * h(1:li) / hh(li), 0);
- c(idx) = tmp_v*h(1:li);
- end
- res = y-c;
- rss = res'*res; % residual sum of squares
- end
-end
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deconvolveCa/oasis/update_kernel_exp2.m b/deconvolveCa/oasis/update_kernel_exp2.m
deleted file mode 100644
index 991e3b9..0000000
--- a/deconvolveCa/oasis/update_kernel_exp2.m
+++ /dev/null
@@ -1,131 +0,0 @@
-function [kernel, s] = update_kernel_exp2(y, s, kernel)
-%% estimate convolution kernel with the form of exp(-t/tau_d)-exp(-t/tau_r)
-
-%% inputs:
-% y: 1 X T vector, observed fluorescence trace
-% s: 1 X T vector, spike counts
-% kernel: struct variable with fields {'type', 'fhandle', 'pars',
-% 'nMax', 'lb', 'ub'}, it determines the parametric convolution kernel
-% nMax: scalar, length of the convolution kernel
-% lb: 2 X 1 vector, lower bounds of tau_d and tau_r
-% ub: 2 X 1 vector, upper bounds of tau_d and tau_r
-%% outputs:
-% kernel: same as input
-% s: optimal spike train
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-
-if ~exist('kernel', 'var') || isempty(kernel)
- kernel = create_kernel('exp2');
-elseif ~strcmpi(kernel.type, 'exp2')
- kernel = create_kernel('exp2');
- kernel.nMax = kernel.nMax;
-end
-
-bound_pars = kernel.bound_pars;
-if bound_pars
- lb = kernel.lb;
- ub = kernel.ub;
-else
- lb = kernel.pars/2;
- ub = kernel.pars*2;
-end
-nMax = kernel.nMax;
-fhandle = kernel.fhandle;
-
-t = 1:nMax;
-T = length(y); %number of frames
-y = reshape(y, T, 1); % observed fluorescence
-s = reshape(s, T, 1); % spike counts
-
-%% create regression matrix
-sind = reshape(find(s), 1, []); % indices of all spikes
-nspk = length(sind); % number of vents
-if nspk<2 % no events, stop running
- return;
-end
-temp = bsxfun(@plus, (0:(nMax-1))', sind); % frames that are affected by s
-ind = (temp<=T); % remove frames
-[ind_tau, ind_s] = find(ind); %ind_tau corresponds to tau=(t-t'+1); ind_s corresponds to t'; t' is the spike time
-yind = temp(ind(:));
-temp = sparse(yind, ind_s, ind_tau, T, nspk); % tmtp: t-t'
-ind_nonzero = (sum(temp,2)>0); % choose frames affected by s
-yv = y(ind_nonzero);
-ny = length(yv); % number of frames used
-temp = temp(ind_nonzero, :);
-[rsub, csub, tmtp] = find(temp);
-
-%% find the optimal solution by shrinking the searching area
-K = 5;
-s_all = zeros(K, K, length(sind));
-% min_tau1 = lb(1);
-% max_tau1 = ub(1);
-% min_tau2 = lb(2);
-% max_tau2 = ub(2);
-f0 = inf;
-thresh = 1e-3;
-warning('off','MATLAB:nearlySingularMatrix')
-warning('off','MATLAB:singularMatrix')
-while true
- tau_1 = linspace(lb(1), ub(1), K);
- tau_2 = linspace(lb(2), ub(2), K);
- rss = inf(K);
-
- for m=1:K
- tau_d = tau_1(m);
- for n=1:K
- tau_r = tau_2(n);
- if tau_r>tau_d
- break;
- end
- gt = fhandle([tau_d, tau_r], t);
- H = sparse(rsub, csub, gt(tmtp), ny, nspk);
- sv = (H'*H)\(H'*yv);
- s_all(m, n, :) = sv;
- rss(m, n) = norm(H*sv-yv, 2);
- end
- end
-
- f1 = min(rss(:)); % new residual
- [indr, indc] = find(rss==f1, 1);
- if (f0-f1)/f1 < thresh %improvement is small
- break;
- elseif bound_pars % shrink the searching area and parameters are bounded
- f0 = f1;
- lb(1) = tau_1(max(1, indr-1));
- ub(1) = tau_1(min(K, indr+1));
- lb(2) = tau_2(max(1, indc-1));
- ub(2) = tau_2(min(K, indc+1));
- else % searching areas are not bounded
- f0 = f1;
- if indr==1
- lb(1) = lb(1)/2;
- ub(1) = tau_1(2);
- elseif indr==K
- lb(1) = tau_1(K-1);
- ub(1) = ub(1)*2;
- else
- lb(1) = tau_1(indr-1);
- ub(1) = tau_1(indr+1);
- end
-
- if indc==1
- lb(2) = lb(2)/2;
- ub(2) = tau_2(2);
- elseif indc==K
- lb(2) = tau_2(K-1);
- ub(2) = ub(2)*2;
- else
- lb(2) = tau_2(indc-1);
- ub(2) = tau_2(indc+1);
- end
-
- end
-end
-warning('on','MATLAB:nearlySingularMatrix')
-warning('on','MATLAB:singularMatrix')
-sv = squeeze(s_all(indr, indc, :));
-s(sind) = sv;
-kernel.pars = [tau_1(indr), tau_2(indc)];
-kernel.fhandle = fhandle;
-kernel.nMax = nMax;
-end
\ No newline at end of file
diff --git a/deconvolveCa/oasis/update_lam.m b/deconvolveCa/oasis/update_lam.m
deleted file mode 100644
index 76557fc..0000000
--- a/deconvolveCa/oasis/update_lam.m
+++ /dev/null
@@ -1,78 +0,0 @@
-function [c, active_set, lam, s, flag_lam] = update_lam(y, c, active_set, g, lam, thresh)
-%% update the tuning parameter lambda to reduce |s|_1 while |y-c|_2^2 <= sn^2*T
-
-%% inputs:
-% y: T*1 vector, One dimensional array containing the fluorescence intensities
- %withone entry per time-bin.
-% c: T*1 vector, previous c
-% active_set: npools*4 matrix, previous active sets
-% g: scalar, Parameter of the AR(1) process that models the fluorescence ...
- %impulse response.
-% lam: scalar, curret value of sparsity penalty parameter lambda.
-% thresh: maximum residual sn*T^2
-
-%% outputs
-% c: T*1 vector
-% s: T*1 vector, spike train
-% active_set: npool x 4 matrix, active sets
-% lam: scalar, new tuning parameter
-% flag_lam: bool, True if it update lam with success
-%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
-% ported from the Python implementation from Johannes Friedrich
-
-%% References
-% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging
-
-c = reshape(c, [],1);
-y = reshape(y, [],1);
-len_active_set = size(active_set,1);
-
-res = y - c;
-RSS = res'*res;
-
-temp = zeros(size(c));
-for ii=1:len_active_set
- ti = active_set(ii, 3);
- li = active_set(ii, 4);
- idx = 0:(li-1);
- temp(ti+idx) = (1-g^li)/ active_set(ii,2) * g.^(idx);
-end
-
-aa = temp'*temp;
-bb = res'*temp;
-cc = RSS-thresh;
-ll = (-bb + sqrt(bb^2-aa*cc)) / aa;
-if imag(ll)~=0
- flag_lam = false;
- s = [0; c(2:end)-c(1:(end-1))*g];
- return;
-else
- flag_lam = true;
-end
-lam = lam + ll;
-
-active_set(:,1) = active_set(:,1) - ll*(1-g.^active_set(:,4));
-[c, s, active_set] = oasisAR1(y, g, lam, 0, active_set);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deconvolveCa/oasis/update_tau.m b/deconvolveCa/oasis/update_tau.m
deleted file mode 100644
index 7ae9a8a..0000000
--- a/deconvolveCa/oasis/update_tau.m
+++ /dev/null
@@ -1,144 +0,0 @@
-function [pars, s] = update_tau(y, s, pars, nspk)
-%% estimate convolution kernel with the form of exp(-t/tau_d)-exp(-t/tau_r)
-
-%% inputs:
-% y: 1 X T vector, observed fluorescence trace
-% s: 1 X T vector, spike counts
-% pars: struct variable with fields {'fhandle', 'vals', 'nMax', 'lb', 'ub'},
-% it determines the parametric convolution kernel.
-% vals: scalar, current value of the [tau_d, tau_r]
-% nMax: scalar, length of the convolution kernel
-% lb: 2 X 1 vector, lower bounds of tau_d and tau_r
-% ub: 2 X 1 vector, upper bounds of tau_d and tau_r
-% bound_pars: boolean, bound the time constants or not
-% 'nspk': scalar, number of spikes to be used for inferring the time
-% constants
-
-%% outputs:
-% kernel: same as input
-% s: optimal spike train
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-
-%% initialization
-vals = pars.vals; % current values of tau_d and tau_r
-nMax = pars.nMax; % maximum length of the kernel
-
-t = 1:nMax;
-T = length(y); %number of frames
-y = reshape(y, [], 1); % raw calcium traces
-s = reshape(s, [], 1); % estimated time constants
-
-if ~exist('nspk', 'var')||isempty(nspk)
- nspk = 10;
-end
-[tsp, ~, spk_v] = find(s>0); % find the spike positions
-v_thr = quantile(spk_v, 1-nspk/length(spk_v)); % find the thresholded value of chosing spikes for fitting spike trains
-tsp_top = tsp(spk_v>=v_thr);
-s(tsp_top) = 0;
-
-% compute the residual
-kernel = exp2kernel(vals, (1:nMax)');
-c = conv(s, kernel);
-y = y - c(1:T); % remove signals from the small spikes
-
-
-bound_pars = pars.bound_pars;
-if bound_pars
- lb = pars.lb;
- ub = pars.ub;
-else
- lb = pars.vals/2;
- ub = pars.vals*2;
-end
-
-%% create regression matrix
-sind = reshape(tsp_top, 1, []); % indices of all spikes
-nspk = length(sind); % number of vents
-if nspk<2 % no events, stop running
- return;
-end
-temp = bsxfun(@plus, (0:(nMax-1))', sind); % frames that are affected by s
-ind = (temp<=T); % remove invalid frames
-[ind_tau, ind_s] = find(ind); %ind_tau corresponds to tau=(t-t'+1); ind_s corresponds to t'; t' is the spike time
-yind = temp(ind(:));
-temp = sparse(yind, ind_s, ind_tau, T, nspk); % tmtp: t-t'
-ind_nonzero = (sum(temp,2)>0); % choose frames affected by s
-yv = y(ind_nonzero);
-ny = length(yv); % number of frames used
-temp = temp(ind_nonzero, :);
-[rsub, csub, tmtp] = find(temp);
-
-%% find the optimal solution by shrinking the searching area
-K = 5;
-s_all = zeros(K, K, length(sind));
-% min_tau1 = lb(1);
-% max_tau1 = ub(1);
-% min_tau2 = lb(2);
-% max_tau2 = ub(2);
-f0 = inf;
-thresh = 1e-3;
-warning('off','MATLAB:nearlySingularMatrix')
-warning('off','MATLAB:singularMatrix')
-while true
- tau_1 = linspace(lb(1), ub(1), K);
- tau_2 = linspace(lb(2), ub(2), K);
- rss = inf(K);
-
- for m=1:K
- tau_d = tau_1(m);
- for n=1:K
- tau_r = tau_2(n);
- if tau_r>tau_d
- break;
- end
- gt = exp2kernel([tau_d, tau_r], t);
- H = sparse(rsub, csub, gt(tmtp), ny, nspk);
- sv = (H'*H)\(H'*yv);
- s_all(m, n, :) = sv;
- rss(m, n) = norm(H*sv-yv, 2);
- end
- end
-
- f1 = min(rss(:)); % new residual
- [indr, indc] = find(rss==f1, 1);
- if (f0-f1)/f1 < thresh %improvement is small
- break;
- elseif bound_pars % shrink the searching area and parameters are bounded
- f0 = f1;
- lb(1) = tau_1(max(1, indr-1));
- ub(1) = tau_1(min(K, indr+1));
- lb(2) = tau_2(max(1, indc-1));
- ub(2) = tau_2(min(K, indc+1));
- else % searching areas are not bounded
- f0 = f1;
- if indr==1
- lb(1) = lb(1)/2;
- ub(1) = tau_1(2);
- elseif indr==K
- lb(1) = tau_1(K-1);
- ub(1) = ub(1)*2;
- else
- lb(1) = tau_1(indr-1);
- ub(1) = tau_1(indr+1);
- end
-
- if indc==1
- lb(2) = lb(2)/2;
- ub(2) = tau_2(2);
- elseif indc==K
- lb(2) = tau_2(K-1);
- ub(2) = ub(2)*2;
- else
- lb(2) = tau_2(indc-1);
- ub(2) = tau_2(indc+1);
- end
-
- end
-end
-warning('on','MATLAB:nearlySingularMatrix')
-warning('on','MATLAB:singularMatrix')
-sv = squeeze(s_all(indr, indc, :));
-s(tsp_top) = sv;
-pars.vals = [tau_1(indr), tau_2(indc)];
-pars.nMax = nMax;
-end
\ No newline at end of file
diff --git a/deconvolveCa/oasis_kernel/choose_smin.m b/deconvolveCa/oasis_kernel/choose_smin.m
deleted file mode 100644
index 1fd55eb..0000000
--- a/deconvolveCa/oasis_kernel/choose_smin.m
+++ /dev/null
@@ -1,42 +0,0 @@
-function smin = choose_smin(kernel,sn,prob)
-%% Choose minimal spike spike to enforce sparsity constraint in spike inference
-% The function chooses a regularization weight for sparse deconvolution
-% with a given kernel and noise level. The weight of the regularizer
-% is chosen such that noise alone cannot lead to a non-zero solution is
-% at least prob.
-
-% Inputs:
-% kernel: deconvolution kernel
-% if length(kernel) == 1 or length(kernel) == 2, then kernel
-% is treated as a set of discrete time constants g. Otherwise,
-% it is treated as the actual vector.
-% sn: noise level
-% prob: probability of zero solution (deafult: 0.99)
-
-% Output:
-% smin: minimal spike size
-
-% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-% modified from choose_lambda.m Eftychios A. Pnevmatikakis, 2016, Simons Foundation
-% based on ideas and discussions with J. Tubiana and G. Debregeas,
-% Laboratorie Jean Parrin, UPMC, France
-
-% Reference for this approach:
-% Selesnick, I. (2012). Sparse deconvolution (an MM algorithm)
-
-%%
-
-if nargin < 3 || isempty(prob)
- prob = 0.9999;
-end
-
-if nargin < 2 || isempty(sn)
- sn = 1;
- warning('Noise value not provided. Using sn = 1...')
-end
-
-if length(kernel) <= 2
- kernel = filter(1,[1,-kernel(:)'],[1,zeros(1,999)]);
-end
-
-smin = sn/norm(kernel)*norminv(prob);
\ No newline at end of file
diff --git a/deconvolveCa/oasis_kernel/create_kernel.m b/deconvolveCa/oasis_kernel/create_kernel.m
deleted file mode 100644
index 254de2e..0000000
--- a/deconvolveCa/oasis_kernel/create_kernel.m
+++ /dev/null
@@ -1,83 +0,0 @@
-function kernel = create_kernel(kernel_type, pars, nMax, lb, ub, bound_pars)
-%% create convolution kernel
-%% inputs:
-% kernel_type: string, convolution kernel type. now support {'exp',
-% 'exp2', 'vector'}
-% pars: parameters for the selected kernel type
-% nMax: length of the kernel
-% lb: lower bound for each parameter
-% ub: upper bound for each parameter
-% bound_pars: logical variable, bound the parameters or not {1, 0}
-%% outputs
-% kernel: struct variable
-
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-
-%% kernel size
-if ~exist('nMax', 'var') || isempty(nMax)
- nMax = 50;
-end
-kernel.nMax = nMax;
-
-%% initialize kernel
-if ~exist('kernel_type', 'var') || isempty(kernel_type)
- kernel_type = 'exp2';
-end
-if strcmpi(kernel_type, 'exp')
- % single exponential function: ~ exp(-t/tau)
- kernel.type = 'exp';
- % parameter
- if ~exist('pars', 'var') || isempty(pars)
- kernel.pars = [5, .1];
- else
- kernel = kernel.pars;
- end
- % function handle
- kernel.fhandle = @(pars, t) exp(-t/pars) * (1-exp(-1/pars)) ...
- / (1-exp(-nMax/pars));
-elseif strcmpi(kernel_type, 'vector')
- % single vector
- kernel.type = 'vector';
- % parameter
- if ~exist('pars', 'var') || isempty(pars)
- kernel.pars = exp(-(1:nMax)/10);
- else
- kernel.pars = pars;
- end
- % function handle
- kernel.fhandle = @(pars, t) pars/sum(pars);
-else
- % differencing of two exponential function:
- % ~ exp(-t/tau_d)-exp(-t/tau_r)
- kernel.type = 'exp2';
-
- % parameters
- if ~exist('pars', 'var') || isempty(pars)
- kernel.pars = [10, 1];
- else
- kernel.pars = pars;
- end
- % function handle
- kernel.fhandle = @(pars, t) (exp(-t/pars(1)) - exp(-t/pars(2))) ...
- /( (1-exp(-nMax/pars(1)))/(1-exp(-1/pars(1))) ...
- - (1-exp(-nMax/pars(2)))/(1-exp(-1/pars(2))));
-end
-
-% lower and upper bounds for parameters
-if ~exist('lb', 'var') || isempty(lb)
- kernel.lb = 0.5*kernel.pars;
-else
- kernel.lb = lb;
-end
-if ~exist('ub', 'var') || isempty(ub)
- kernel.ub = 2*kernel.pars;
-else
- kernel.ub = ub;
-end
-
-% bound the parameters of not
-if ~exist('bound_pars', 'var')||isempty(bound_pars)
- kernel.bound_pars = false;
-else
- kernel.bound_pars = bound_pars;
-end
\ No newline at end of file
diff --git a/deconvolveCa/oasis_kernel/deconvCa.m b/deconvolveCa/oasis_kernel/deconvCa.m
deleted file mode 100644
index 044cf81..0000000
--- a/deconvolveCa/oasis_kernel/deconvCa.m
+++ /dev/null
@@ -1,358 +0,0 @@
-function [c, s, kernel, iter] = deconvCa(y, kernel, smin, fit_gt, debug_on, sn, maxIter, theta, lambda)
-%% deconvolve calcium traces to infer spike counts
-%% inputs:
-% y: 1*T vector, observed calcium traces
-% kernel: struct variable with two fields {'fhandle', 'pars', nMax}. kernel
-% deterines the convolution kernel
-% fhandle: function handle, the function form of the response function
-% pars: p*1 vector, parameters for fhandle
-% nMax: scalar, maximum number of frames required by calcium indicators
-% to return resting states
-% smin: scalar, minimum number of nonzero spike count within each bin
-% fit_gt: true or false. iteratively fit gt or not
-% debug_on: play and save video of the whole procedure.
-% sn: noise power
-% maxIter: scalar, maximum iterations for running OASIS, default (3)
-% theta: 1*T vecotr, weight vector at each time point
-% lambda: scalar, tuning parameter
-
-%% outputs:
-% c: 1*T vector, inferred calcium trace
-% s: 1*T vector, inferred spike train
-% kernel: convolution kernel
-% iters: number of iterations for updating irf
-
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-% This work is based on one NIPS paper by Johannes Friedrich & Liam
-% Paninski
-
-%% input arugments
-y = reshape(y, 1, []); % convert data into row vector
-if ~exist('sn', 'var') || isempty(sn)
- sn = get_noise_fft(y);
-end
-T = length(y); % number of frames
-
-% get convolution kernel
-if ~exist('kernel', 'var') || isempty(kernel)
- kernel = create_kernel('exp2', ar2exp(estimate_time_constant(y,2)));
-end
-fhandle = kernel.fhandle;
-nMax = kernel.nMax;
-
-y = [y, zeros(1, nMax)]; % add few more elements for computation convenience
-
-% threshold of the spike
-if ~exist('smin', 'var') || isempty(smin)
- smin = 3*sn; % min spike count
-else
- smin = smin * sn;
-end
-
-% fit response function or not
-if ~exist('fit_gt', 'var') || isempty(fit_gt)
- fit_gt = false;
-else
- kernel.pars = ar2exp(estimate_time_constant(y,2));
-end
-thresh = 1e-3;
-
-% debug mode
-if ~exist('debug_on', 'var') || isempty(debug_on)
- debug_on = false;
-end
-
-% maximum iterations for running OASIS
-if ~exist('maxIter', 'var') || isempty(maxIter)
- maxIter = 5;
-end
-
-% tuning parameter for enforcing sparsity
-if ~exist('lambda', 'var') || isempty(lambda)
- lambda = 0; % tuning parameter
-end
-
-% weight for each frame
-if ~exist('theta', 'var')|| isempty(theta) || (length(theta)==1) % weight vector
- theta = ones(1, T);
-elseif length(theta)==T
- theta = reshape(theta, 1, T);
-else
- disp('elements in theta should be equal to elements in y');
- return;
-end
-
-% tuning parameter for enforcing sparsity
-if ~exist('lambda', 'var') || isempty(lambda)
- lambda = 0; % tuning parameter
-end
-
-%% running OASIS
-if debug_on
- figure('position', [1, 1 1500, 250]);
- plot(y); hold on;
- a = plot(y, 'r');
- avi_file = VideoWriter('example.avi');
- avi_file.open();
- xlim([1, T]);
-end
-
-f0 = inf; % objective function
-y0 = y; % backup the raw trace
-iter = 1; % iteratiosn
-for iter = 1:maxIter
- if debug_on
- title(sprintf('Iter %d, norm(residual) = %.4f', iter, f0));
- end
- % normalize gt to make its maximum value to be 1
- gt = fhandle(kernel.pars, 1:nMax); % 1*nMax, response function of calcium transients
- ind0 = 1; %correct the response function of the first event
- gt = [reshape(gt, 1, nMax), zeros(1, T)]; % add few more elements to gt for computation convenience
-
- gt_max = max(gt);
- gt = gt/gt_max;
- gt1 = [gt(ind0:end), zeros(1, ind0-1)]; % kernel for the first frame
-
- %% initialize values for the results
- s = zeros(size(y)); % spike count within each bin
- v = zeros(size(y)); % sum(theta_t*y_t) - lambda
- w = zeros(size(y)); % sum(theta_t^2 * g(t-ti+1)^2))
- pool_ti = zeros(size(y)); % first frame of each pool
-
- % initialize the first pool
- v(1) = theta(1)*y(1)*gt1(1) - lambda;
- w(1) = (theta(1)*gt1(1))^2;
- s(1) = max(0, v(1) / w(1));
- % if s(1)=nMax % no influences from the previous events
- vi = theta(t)*y(t)*gt(1) - lambda;
- elseif tpre>1 % estimate vi and subtract the effect of the previous event
- vi = theta(t) * (y(t)-s(tpre)*gt(t-tpre+1)) * gt(1) - lambda;
- else % special treatment with the first event
- vi = theta(t) * (y(t)-s(tpre)*gt1(t-tpre+1)) * gt(1) - lambda;
- end
- wi = (theta(t) * gt(1))^2;
- si = vi/wi;
-
- % check the violatoin of si
- if si>smin && frame_valid % no violation, create a new pool to save the result and move to the next new pool
- % peel off the previous event
- if (t-tpre)1
- y(tpre+(1:nMax)-1) = y(tpre+(1:nMax)-1) - s(tpre)*gt(1:nMax);
- else
- y(tpre+(1:nMax)-1) = y(tpre+(1:nMax)-1) - s(tpre)*gt1(1:nMax);
- end
- end
- pool_ti(ii) = t; % create a new pool
- tpre = t;
- v(t) = vi;
- w(t) = wi;
- s(t) = si;
- ii = ii+1; % move to the next pool
- t = t+1;
- else % with violation
- frame_valid = true; % allows the next frame to be valid
- if (t-tpre)>=nMax
- % ignore this frame directly and move to the next frame
- t = t + 1;
- continue;
- elseif tpre>1 % merge it to the current pool
- v(tpre) = v(tpre) + theta(t)*y(t)*gt(t-tpre+1);
- w(tpre) = w(tpre) + (theta(t)*gt(t-tpre+1))^2;
- else
- v(tpre) = v(tpre) + theta(t)*y(t)*gt1(t-tpre+1);
- w(tpre) = w(tpre) + (theta(t)*gt1(t-tpre+1));
- end
- s(tpre) = v(tpre)/w(tpre); % update the current event
-
- % check the violation of the current pool
- if s(tpre)>smin % the previous event is still avaiable
- t = t+1;
- continue;
- elseif ii==2 %the previous pool is not available anymore, but it's the first pool
- s(tpre) = max(0, s(tpre));
- t = t+1;
- else % not available, then delete the current pool and force its first frame to be
- % event-free.
- t = tpre; % go back to the first frame of the current pull
-
- frame_valid = false; % force the frame t to be invalid
- ii = ii-1;
- tpre = pool_ti(ii-1);
-
- % add back the signal of the previous pool
- if (t-tpre)>nMax
- t = t+1;
- frame_valid = true;
- continue;
- elseif tpre>1
- y(tpre+(1:nMax)-1) = y(tpre+(1:nMax)-1) + s(tpre)*gt(1:nMax);
- else
- y(tpre+(1:nMax)-1) = y(tpre+(1:nMax)-1) + s(tpre)*gt1(1:nMax);
- end
- end
- end
- end
- %% collect the results
- pool_ti(ii:end) = [];
- temp = s(pool_ti);
- s = zeros(1, T);
- s(pool_ti) = temp;
- temp = s;
- temp(1) = 0;
- c = conv(temp, gt(1:nMax));
- c = c(1:T) + s(1)*gt1(1:T);
- f1 = norm(y(1:T)-c, 2);
- s = s*sum(gt);
- if debug_on
- delete(a);
- a = plot(c, 'r');
- drawnow();
- temp = getframe();
- temp.cdata = imresize(temp.cdata, [200, 1500]);
- avi_file.writeVideo(temp);
- end
-
- %% break the while loop
- if ~fit_gt % don't iterate gt
- break;
- elseif (f0-f1)/f0 <= thresh % improvement is small, stop
- break;
- else % move to the next iteration
- y = y0;
- if strcmpi(kernel.type, 'exp2')
- [kernel, ~] = update_kernel_exp2(y(1:T), s, kernel);
- else
- break;
- end
- f0 = f1;
- iter = iter + 1;
- % return;
- end
-end
-
-if debug_on
- avi_file.close();
- close(gcf);
-end
-end
-
-%% estimate the noise power
-function [sn,psdx,ff] = get_noise_fft(Y,options)
-% Written by:
-% Eftychios A. Pnevmatikakis, Simons Foundation, 2015
-% with minor adaption by Pengcheng Zhou, Carnegie Mellon University, 2015
-options.noise_range = [.25, .5];
-range_ff = options.noise_range;
-options.noise_method = 'logmexp';
-method = options.noise_method;
-options.block_size = [64, 64];
-block_size = options.block_size;
-options.split_data = false;
-split_data = options.split_data;
-options.max_timesteps = 3000;
-
-dims = ndims(Y);
-sizY = size(Y);
-N = min(sizY(end),options.max_timesteps);
-if N < sizY(end)
- %Y = reshape(Y,prod(sizY(1:end-1)),[]);
- Y(prod(sizY(1:end-1))*N+1:end) = [];
- Y = reshape(Y,[sizY(1:end-1),N]);
-end
-
-Fs = 1;
-ff = 0:Fs/N:Fs/2;
-indf=ff>range_ff(1);
-indf(ff>range_ff(2))=0;
-if dims > 1
- d = prod(sizY(1:dims-1));
- Y = reshape(Y,d,N);
- Nb = prod(block_size);
- SN = cell(ceil(d/Nb),1);
- PSDX = cell(ceil(d/Nb),1);
- if ~split_data
- for ind = 1:ceil(d/Nb);
- xdft = fft(Y((ind-1)*Nb+1:min(ind*Nb,d),:),[],2);
- xdft = xdft(:,1: floor(N/2)+1); % FN: floor added.
- psdx = (1/(Fs*N)) * abs(xdft).^2;
- psdx(:,2:end-1) = 2*psdx(:,2:end-1);
- %SN{ind} = mean_psd(psdx(:,indf),method);
- switch method
- case 'mean'
- SN{ind}=sqrt(mean(psdx(:,indf)/2,2));
- case 'median'
- SN{ind}=sqrt(median(psdx(:,indf)/2),2);
- case 'logmexp'
- SN{ind} = sqrt(exp(mean(log(psdx(:,indf)/2),2)));
- end
- PSDX{ind} = psdx;
- end
- else
- nc = ceil(d/Nb);
- Yc = mat2cell(Y,[Nb*ones(nc-1,1);d-(nc-1)*Nb],N);
- parfor ind = 1:ceil(d/Nb);
- xdft = fft(Yc{ind},[],2);
- xdft = xdft(:,1:floor(N/2)+1);
- psdx = (1/(Fs*N)) * abs(xdft).^2;
- psdx(:,2:end-1) = 2*psdx(:,2:end-1);
- Yc{ind} = [];
- switch method
- case 'mean'
- SN{ind}=sqrt(mean(psdx(:,indf)/2,2));
- case 'median'
- SN{ind}=sqrt(median(psdx(:,indf)/2),2);
- case 'logmexp'
- SN{ind} = sqrt(exp(mean(log(psdx(:,indf)/2),2)));
- end
-
- end
- end
- sn = cell2mat(SN);
-else
- xdft = fft(Y);
- xdft = xdft(:,1:floor(N/2)+1);
- psdx = (1/(Fs*N)) * abs(xdft).^2;
- psdx(:,2:end-1) = 2*psdx(:,2:end-1);
- switch method
- case 'mean'
- sn = sqrt(mean(psdx(:,indf)/2,2));
- case 'median'
- sn = sqrt(median(psdx(:,indf)/2),2);
- case 'logmexp'
- sn = sqrt(exp(mean(log(psdx(:,indf)/2),2)));
- end
-end
-psdx = cell2mat(PSDX);
-if dims > 2
- sn = reshape(sn,sizY(1:dims-1));
-end
-end
diff --git a/deconvolveCa/oasis_kernel/dsKernel.m b/deconvolveCa/oasis_kernel/dsKernel.m
deleted file mode 100644
index 519fd76..0000000
--- a/deconvolveCa/oasis_kernel/dsKernel.m
+++ /dev/null
@@ -1,42 +0,0 @@
-function kernel_new = dsKernel(kernel, tsub)
-%% downsample/upsample the convolution kernel
-%% inputs:
-% kernel: struct variable with fields {'kernel_type', 'pars', 'nMax', 'lb', 'ub', 'bound_pars'}
-% kernel_type: string, convolution kernel type. now support {'exp',
-% 'exp2', 'vector'}
-% pars: parameters for the selected kernel type
-% nMax: length of the kernel
-% lb: lower bound for each parameter
-% ub: upper bound for each parameter
-% bound_pars: logical variable, bound the parameters or not {1, 0}
-%% outputs
-% kernel: struct variable
-
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-
-kernel_new = kernel;
-if nargin<2 || isempty(tsub)
- return;
-end
-
-%% kernel size
-kernel_new.nMax = ceil(kernel.nMax/tsub);
-
-%% kernel type
-kernel_type = kernel.type;
-if strcmpi(kernel_type, 'exp')
- % single exponential function: ~ exp(-t/tau)
- kernel_new.pars = kernel.pars/tsub;
-elseif strcmpi(kernel_type, 'vector')
- % single vector
-len_kernel = length(kernel.pars);
- kernel_new.pars = resample(kernel.pars, ceil(len_kernel/tsub), len_kernel);
-else
- % differencing of two exponential function:
- % ~ exp(-t/tau_d)-exp(-t/tau_r)
- kernel_new.pars = kernel.pars/tsub;
-end
-
-%% lower and upper bounds for parameters
-kernel_new.lb = kernel.lb / tsub;
-kernel_new.ub = kernel.ub / tsub;
\ No newline at end of file
diff --git a/deconvolveCa/oasis_kernel/test_oasis.m b/deconvolveCa/oasis_kernel/test_oasis.m
deleted file mode 100644
index 6f888a6..0000000
--- a/deconvolveCa/oasis_kernel/test_oasis.m
+++ /dev/null
@@ -1,34 +0,0 @@
-%% function
-clear; clc; close all;
-T = 1000;
-s = double(rand(1, T)>0.98);
-sig = 0.04;
-
-% example
-tau_d = 5;
-tau_r = 1;
-nMax = 100;
-pars = [tau_d, tau_r];
-kernel = create_kernel('exp2', pars, nMax);
-
-t = 1:kernel.nMax;
-gt = kernel.fhandle(kernel.pars, t);
-c1 = conv(s, gt);
-c1 = c1(1:T);
-y1 = c1 + randn(1, T) * sig;
-
-%% use the true convolution kernel
-kernel0 = kernel;
-kernel0.pars = [10, 0.1];
-kernel0.bound_pars = false;
-figure('position', [1,1,1500, 200]);
-plot(y1);
-hold on;
-plot(c1, 'r', 'linewidth', 2);
-plot(-s*0.1, 'r', 'linewidth', 2);
-tic;
-[chat, shat, kernel_fit, iters] = deconvCa(y1, kernel0, 2, true, false);
-toc;
-plot(chat,'-.g','linewidth', 2);
-plot(-shat*0.1, '-.g', 'linewidth', 2); %, '-.');
-legend('data', 'ground truth: c','ground truth: s', 'OASIS:c', 'OASIS: s'); % 'gound truth: s', 'OASIS: c', 'OASIS: s');
\ No newline at end of file
diff --git a/deconvolveCa/oasis_kernel/update_kernel_exp2.m b/deconvolveCa/oasis_kernel/update_kernel_exp2.m
deleted file mode 100644
index 3d46768..0000000
--- a/deconvolveCa/oasis_kernel/update_kernel_exp2.m
+++ /dev/null
@@ -1,130 +0,0 @@
-function [kernel, s] = update_kernel_exp2(y, s, kernel)
-%% estimate convolution kernel with the form of exp(-t/tau_d)-exp(-t/tau_r)
-
-%% inputs:
-% y: 1 X T vector, observed fluorescence trace
-% s: 1 X T vector, spike counts
-% kernel: struct variable with fields {'type', 'fhandle', 'pars',
-% 'nMax', 'lb', 'ub'}, it determines the parametric convolution kernel
-% nMax: scalar, length of the convolution kernel
-% lb: 2 X 1 vector, lower bounds of tau_d and tau_r
-% ub: 2 X 1 vector, upper bounds of tau_d and tau_r
-%% outputs:
-% kernel: same as input
-% s: optimal spike train
-%% Author: Pengcheng Zhou, Carnegie Mellon University, 2016
-if ~exist('kernel', 'var') || isempty(kernel)
- kernel = create_kernel('exp2');
-elseif ~strcmpi(kernel.type, 'exp2')
- kernel = create_kernel('exp2');
- kernel.nMax = kernel.nMax;
-end
-
-bound_pars = kernel.bound_pars;
-if bound_pars
- lb = kernel.lb;
- ub = kernel.ub;
-else
- lb = kernel.pars/2;
- ub = kernel.pars*2;
-end
-nMax = kernel.nMax;
-fhandle = kernel.fhandle;
-
-t = 1:nMax;
-T = length(y); %number of frames
-y = reshape(y, T, 1); % observed fluorescence
-s = reshape(s, T, 1); % spike counts
-
-%% create regression matrix
-sind = reshape(find(s), 1, []); % indices of all spikes
-nspk = length(sind); % number of vents
-if nspk<2 % no events, stop running
- return;
-end
-temp = bsxfun(@plus, (0:(nMax-1))', sind); % frames that are affected by s
-ind = (temp<=T); % remove frames
-[ind_tau, ind_s] = find(ind); %ind_tau corresponds to tau=(t-t'+1); ind_s corresponds to t'; t' is the spike time
-yind = temp(ind(:));
-temp = sparse(yind, ind_s, ind_tau, T, nspk); % tmtp: t-t'
-ind_nonzero = (sum(temp,2)>0); % choose frames affected by s
-yv = y(ind_nonzero);
-ny = length(yv); % number of frames used
-temp = temp(ind_nonzero, :);
-[rsub, csub, tmtp] = find(temp);
-
-%% find the optimal solution by shrinking the searching area
-K = 5;
-s_all = zeros(K, K, length(sind));
-% min_tau1 = lb(1);
-% max_tau1 = ub(1);
-% min_tau2 = lb(2);
-% max_tau2 = ub(2);
-f0 = inf;
-thresh = 1e-3;
-warning('off','MATLAB:nearlySingularMatrix')
-warning('off','MATLAB:singularMatrix')
-while true
- tau_1 = linspace(lb(1), ub(1), K);
- tau_2 = linspace(lb(2), ub(2), K);
- rss = inf(K);
-
- for m=1:K
- tau_d = tau_1(m);
- for n=1:K
- tau_r = tau_2(n);
- if tau_r>tau_d
- break;
- end
- gt = fhandle([tau_d, tau_r], t);
- H = sparse(rsub, csub, gt(tmtp), ny, nspk);
- sv = (H'*H)\(H'*yv);
- s_all(m, n, :) = sv;
- rss(m, n) = norm(H*sv-yv, 2);
- end
- end
-
- f1 = min(rss(:)); % new residual
- [indr, indc] = find(rss==f1, 1);
- if (f0-f1)/f1 < thresh %improvement is small
- break;
- elseif bound_pars % shrink the searching area and parameters are bounded
- f0 = f1;
- lb(1) = tau_1(max(1, indr-1));
- ub(1) = tau_1(min(K, indr+1));
- lb(2) = tau_2(max(1, indc-1));
- ub(2) = tau_2(min(K, indc+1));
- else % searching areas are not bounded
- f0 = f1;
- if indr==1
- lb(1) = lb(1)/2;
- ub(1) = tau_1(2);
- elseif indr==K
- lb(1) = tau_1(K-1);
- ub(1) = ub(1)*2;
- else
- lb(1) = tau_1(indr-1);
- ub(1) = tau_1(indr+1);
- end
-
- if indc==1
- lb(2) = lb(2)/2;
- ub(2) = tau_2(2);
- elseif indc==K
- lb(2) = tau_2(K-1);
- ub(2) = ub(2)*2;
- else
- lb(2) = tau_2(indc-1);
- ub(2) = tau_2(indc+1);
- end
-
- end
-end
-warning('on','MATLAB:nearlySingularMatrix')
-warning('on','MATLAB:singularMatrix')
-sv = squeeze(s_all(indr, indc, :));
-s(sind) = sv;
-kernel.pars = [tau_1(indr), tau_2(indc)];
-kernel.fhandle = fhandle;
-kernel.nMax = nMax;
-end
\ No newline at end of file
diff --git a/deconvolveCa/setup.m b/deconvolveCa/setup.m
deleted file mode 100644
index 01d8b0c..0000000
--- a/deconvolveCa/setup.m
+++ /dev/null
@@ -1,36 +0,0 @@
-oasis_folder = fileparts(mfilename('fullpath'));
-addpath(sprintf('%s', oasis_folder));
-addpath(sprintf('%s%sfunctions', oasis_folder, filesep));
-addpath(sprintf('%s%soasis', oasis_folder, filesep));
-addpath(sprintf('%s%soasis_kernel', oasis_folder, filesep));
-addpath(sprintf('%s%sMCMC', oasis_folder, filesep));
-addpath(sprintf('%s%sMCMC%sutilities', oasis_folder, filesep, filesep));
-
-%% install convex optimization solvers
-optimization_folder = sprintf('%s%soptimization', oasis_folder, filesep);
-if ~exist(optimization_folder, 'dir');
- mkdir(optimization_folder);
-end
-
-% install cvx
-if isempty(which('cvx_begin.m'))
- if ~exist('cvx', 'dir')
- %install cvx
- if ismac
- cvx_url = 'http://web.cvxr.com/cvx/cvx-maci64.zip';
- elseif isunix
- cvx_url = 'http://web.cvxr.com/cvx/cvx-a64.zip';
- elseif ispc
- cvx_url = 'http://web.cvxr.com/cvx/cvx-w64.zip';
- else
- fprints('Your platform is not supported by CVX\n');
- return;
- end
- fprintf('Downloading CVX...\n');
- unzip(cvx_url, optimization_folder);
- end
- run(sprintf('%s%scvx%scvx_setup', optimization_folder, filesep, filesep));
-end
-
-%% save the current path
-%savepath();