Adding all files

LT1AB
Eric Gurrola 2019-01-16 11:40:08 -08:00
commit 9f9a2b0805
2471 changed files with 402831 additions and 0 deletions

22
LICENSE Normal file
View File

@ -0,0 +1,22 @@
Copyright 2008 California Institute of Technology. ALL RIGHTS RESERVED.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
United States Government Sponsorship acknowledged. This software is subject to
U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
(No [Export] License Required except when exporting to an embargoed country,
end user, or in support of a prohibited end use). By downloading this software,
the user agrees to comply with all applicable U.S. export laws and regulations.
The user has the responsibility to obtain export licenses, or other export
authority as may be required before exporting this software to any 'EAR99'
embargoed foreign country or citizen of those countries.

422
LICENSE-2.0.html Normal file
View File

@ -0,0 +1,422 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Home page of The Apache Software Foundation">
<link rel="apple-touch-icon" sizes="57x57" href="/favicons/apple-touch-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/favicons/apple-touch-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/favicons/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/favicons/apple-touch-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/favicons/apple-touch-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/favicons/apple-touch-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/favicons/apple-touch-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/favicons/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon-180x180.png">
<link rel="icon" type="image/png" href="/favicons/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/favicons/favicon-194x194.png" sizes="194x194">
<link rel="icon" type="image/png" href="/favicons/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="/favicons/android-chrome-192x192.png" sizes="192x192">
<link rel="icon" type="image/png" href="/favicons/favicon-16x16.png" sizes="16x16">
<link rel="manifest" href="/favicons/manifest.json">
<link rel="shortcut icon" href="/favicons/favicon.ico">
<meta name="msapplication-TileColor" content="#603cba">
<meta name="msapplication-TileImage" content="/favicons/mstile-144x144.png">
<meta name="msapplication-config" content="/favicons/browserconfig.xml">
<meta name="theme-color" content="#303284">
<title>Apache License, Version 2.0</title>
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700%7cDroid+Serif:400,700' rel='stylesheet' type='text/css'>
<link href="/css/min.bootstrap.css" rel="stylesheet">
<link href="/css/styles.css" rel="stylesheet">
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the &quot;License&quot;); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -->
</head>
<body>
<!-- Navigation -->
<header>
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#mainnav-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="#" class="navbar-brand"><span class="glyphicon glyphicon-home"></span></a>
</div>
<div class="collapse navbar-collapse" id="mainnav-collapse">
<div style="line-height:20px; padding-top:5px; float:left"><a href="/">Home</a>&nbsp;&raquo&nbsp;<a href="/licenses/">Licenses</a></div>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">About <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="/foundation">Overview</a></li>
<li><a href="/foundation/members.html">Members</a></li>
<li><a href="/foundation/how-it-works.html">Process</a></li>
<li><a href="/foundation/sponsorship.html">Sponsorship</a></li>
<li><a href="/foundation/glossary.html">Glossary</a></li>
<li><a href="/foundation/preFAQ.html">FAQ</a></li>
<li><a href="/foundation/policies/conduct.html">Code of Conduct</a></li>
<li><a href="/foundation/contact.html ">Contact</a></li>
</ul>
</li>
<li><a href="/index.html#projects-list">Projects</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">People <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="http://people.apache.org/">Overview</a></li>
<li><a href="http://people.apache.org/committer-index.html">Committers</a></li>
<li><a href="/foundation/how-it-works.html#meritocracy">Meritocracy</a></li>
<li><a href="/foundation/how-it-works.html#roles">Roles</a></li>
<li><a href="/foundation/policies/conduct.html">Code of Conduct</a></li>
<li><a href="http://planet.apache.org/">Planet Apache</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Involved <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="/foundation/getinvolved.html">Overview</a></li>
<li><a href="http://community.apache.org/">Community Development</a></li>
<li><a href="/foundation/policies/conduct.html">Code of Conduct</a></li>
<li><a href="http://helpwanted.apache.org/">Help Wanted</a></li>
<li><a href="http://www.apachecon.com/">ApacheCon</a></li>
</ul>
</li>
<li><a href="/dyn/closer.cgi">Download</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Support Apache <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="/foundation/sponsorship.html">Sponsorship</a></li>
<li><a href="/foundation/contributing.html">Donations</a></li>
<li><a href="/foundation/buy_stuff.html">Buy Stuff</a></li>
<li><a href="/foundation/thanks.html">Thanks</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
</header>
<!-- / Navigation -->
<div class="container">
<div class="row">
<div class="col-md-6 col-sm-5 col-xs-12">
<img src="/img/asf_logo.png" alt="Apache Logo" style="max-width: 100%;">
</div>
<div class="col-md-3 col-sm-3 col-xs-6">
<a href="http://apache.org/foundation/contributing.html" title="Support Apache">
<img src="/images/SupportApache-small.png" style="height: 150px; width: 150px; margin-top: 5px; margin-bottom: 5px;">
</a>
</div>
<div class="col-md-3 col-sm-4 col-xs-6">
<div class="input-group" style="margin-bottom: 5px;">
<script>
(function() {
var cx = '005703438322411770421:5mgshgrgx2u';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//cse.google.com/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script>
<gcse:searchbox-only></gcse:searchbox-only>
</div>
<a role="button" class="btn btn-block btn-default btn-xs" href="/foundation/how-it-works.html">The Apache Way</a>
<a role="button" class="btn btn-block btn-default btn-xs" href="https://community.apache.org/contributors/">Contribute</a>
<a role="button" class="btn btn-block btn-default btn-xs" href="/foundation/thanks.html">ASF Sponsors</a>
</div>
</div>
</div>
<div class="container"><style type="text/css">
/* The following code is added by mdx_elementid.py
It was originally lifted from http://subversion.apache.org/style/site.css */
/*
* Hide class="elementid-permalink", except when an enclosing heading
* has the :hover property.
*/
.headerlink, .elementid-permalink {
visibility: hidden;
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
<p>Apache License<br></br>Version 2.0, January 2004<br></br>
<a href="http://www.apache.org/licenses/">http://www.apache.org/licenses/</a> </p>
<p>TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION</p>
<p><strong><a name="definitions">1. Definitions</a></strong>.</p>
<p>"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.</p>
<p>"Licensor" shall mean the copyright owner or entity authorized by the
copyright owner that is granting the License.</p>
<p>"Legal Entity" shall mean the union of the acting entity and all other
entities that control, are controlled by, or are under common control with
that entity. For the purposes of this definition, "control" means (i) the
power, direct or indirect, to cause the direction or management of such
entity, whether by contract or otherwise, or (ii) ownership of fifty
percent (50%) or more of the outstanding shares, or (iii) beneficial
ownership of such entity.</p>
<p>"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.</p>
<p>"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation source,
and configuration files.</p>
<p>"Object" form shall mean any form resulting from mechanical transformation
or translation of a Source form, including but not limited to compiled
object code, generated documentation, and conversions to other media types.</p>
<p>"Work" shall mean the work of authorship, whether in Source or Object form,
made available under the License, as indicated by a copyright notice that
is included in or attached to the work (an example is provided in the
Appendix below).</p>
<p>"Derivative Works" shall mean any work, whether in Source or Object form,
that is based on (or derived from) the Work and for which the editorial
revisions, annotations, elaborations, or other modifications represent, as
a whole, an original work of authorship. For the purposes of this License,
Derivative Works shall not include works that remain separable from, or
merely link (or bind by name) to the interfaces of, the Work and Derivative
Works thereof.</p>
<p>"Contribution" shall mean any work of authorship, including the original
version of the Work and any modifications or additions to that Work or
Derivative Works thereof, that is intentionally submitted to Licensor for
inclusion in the Work by the copyright owner or by an individual or Legal
Entity authorized to submit on behalf of the copyright owner. For the
purposes of this definition, "submitted" means any form of electronic,
verbal, or written communication sent to the Licensor or its
representatives, including but not limited to communication on electronic
mailing lists, source code control systems, and issue tracking systems that
are managed by, or on behalf of, the Licensor for the purpose of discussing
and improving the Work, but excluding communication that is conspicuously
marked or otherwise designated in writing by the copyright owner as "Not a
Contribution."</p>
<p>"Contributor" shall mean Licensor and any individual or Legal Entity on
behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.</p>
<p><strong><a name="copyright">2. Grant of Copyright License</a></strong>. Subject to the
terms and conditions of this License, each Contributor hereby grants to You
a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of, publicly
display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.</p>
<p><strong><a name="patent">3. Grant of Patent License</a></strong>. Subject to the terms
and conditions of this License, each Contributor hereby grants to You a
perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made, use,
offer to sell, sell, import, and otherwise transfer the Work, where such
license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by
combination of their Contribution(s) with the Work to which such
Contribution(s) was submitted. If You institute patent litigation against
any entity (including a cross-claim or counterclaim in a lawsuit) alleging
that the Work or a Contribution incorporated within the Work constitutes
direct or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate as of the
date such litigation is filed.</p>
<p><strong><a name="redistribution">4. Redistribution</a></strong>. You may reproduce and
distribute copies of the Work or Derivative Works thereof in any medium,
with or without modifications, and in Source or Object form, provided that
You meet the following conditions:</p>
<ol style="list-style: lower-latin;">
<li>You must give any other recipients of the Work or Derivative Works a
copy of this License; and</li>
<li>You must cause any modified files to carry prominent notices stating
that You changed the files; and</li>
<li>You must retain, in the Source form of any Derivative Works that You
distribute, all copyright, patent, trademark, and attribution notices from
the Source form of the Work, excluding those notices that do not pertain to
any part of the Derivative Works; and</li>
<li>If the Work includes a "NOTICE" text file as part of its distribution,
then any Derivative Works that You distribute must include a readable copy
of the attribution notices contained within such NOTICE file, excluding
those notices that do not pertain to any part of the Derivative Works, in
at least one of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or documentation,
if provided along with the Derivative Works; or, within a display generated
by the Derivative Works, if and wherever such third-party notices normally
appear. The contents of the NOTICE file are for informational purposes only
and do not modify the License. You may add Your own attribution notices
within Derivative Works that You distribute, alongside or as an addendum to
the NOTICE text from the Work, provided that such additional attribution
notices cannot be construed as modifying the License.
<br/>
<br/>
You may add Your own copyright statement to Your modifications and may
provide additional or different license terms and conditions for use,
reproduction, or distribution of Your modifications, or for any such
Derivative Works as a whole, provided Your use, reproduction, and
distribution of the Work otherwise complies with the conditions stated in
this License.
</li>
</ol>
<p><strong><a name="contributions">5. Submission of Contributions</a></strong>. Unless You
explicitly state otherwise, any Contribution intentionally submitted for
inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the
terms of any separate license agreement you may have executed with Licensor
regarding such Contributions.</p>
<p><strong><a name="trademarks">6. Trademarks</a></strong>. This License does not grant
permission to use the trade names, trademarks, service marks, or product
names of the Licensor, except as required for reasonable and customary use
in describing the origin of the Work and reproducing the content of the
NOTICE file.</p>
<p><strong><a name="no-warranty">7. Disclaimer of Warranty</a></strong>. Unless required by
applicable law or agreed to in writing, Licensor provides the Work (and
each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including,
without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You
are solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise
of permissions under this License.</p>
<p><strong><a name="no-liability">8. Limitation of Liability</a></strong>. In no event and
under no legal theory, whether in tort (including negligence), contract, or
otherwise, unless required by applicable law (such as deliberate and
grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a result
of this License or out of the use or inability to use the Work (including
but not limited to damages for loss of goodwill, work stoppage, computer
failure or malfunction, or any and all other commercial damages or losses),
even if such Contributor has been advised of the possibility of such
damages.</p>
<p><strong><a name="additional">9. Accepting Warranty or Additional Liability</a></strong>.
While redistributing the Work or Derivative Works thereof, You may choose
to offer, and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this License.
However, in accepting such obligations, You may act only on Your own behalf
and on Your sole responsibility, not on behalf of any other Contributor,
and only if You agree to indemnify, defend, and hold each Contributor
harmless for any liability incurred by, or claims asserted against, such
Contributor by reason of your accepting any such warranty or additional
liability.</p>
<p>END OF TERMS AND CONDITIONS</p>
<h1 id="apply">APPENDIX: How to apply the Apache License to your work<a class="headerlink" href="#apply" title="Permanent link">&para;</a></h1>
<p>To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included
on the same "printed page" as the copyright notice for easier
identification within third-party archives.</p>
<div class="codehilite"><pre>Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
</pre></div></div>
<!-- Footer -->
<footer class="bg-primary">
<div class="container">
<div class="row">
<br />
<div class="col-sm-1">
</div>
<div class="col-sm-2">
<h5 class="white">Community</h5>
<ul class="list-unstyled white" role="menu">
<li><a href="http://community.apache.org/">Overview</a></li>
<li><a href="/foundation/conferences.html">Conferences</a></li>
<li><a href="http://community.apache.org/gsoc.html">Summer of Code</a></li>
<li><a href="http://community.apache.org/newcomers/">Getting Started</a></li>
<li><a href="/foundation/how-it-works.html">The Apache Way</a></li>
<li><a href="/travel/">Travel Assistance</a></li>
<li><a href="/foundation/getinvolved.html">Get Involved</a></li>
<li><a href="/foundation/policies/conduct.html">Code of Conduct</a></li>
<li><a href="http://community.apache.org/newbiefaq.html">Community FAQ</a></li>
<li><a href="/memorials/">Memorials</a></li>
</ul>
</div>
<div class="col-sm-2">
<h5 class="white">Innovation</h5>
<ul class="list-unstyled white" role="menu">
<li><a href="http://incubator.apache.org/">Incubator</a></li>
<li><a href="http://labs.apache.org/">Labs</a></li>
<li><a href="/licenses/">Licensing</a></li>
<li><a href="/foundation/license-faq.html">Licensing FAQ</a></li>
<li><a href="/foundation/marks/">Trademark Policy</a></li>
<li><a href="/foundation/contact.html">Contacts</a></li>
</ul>
</div>
<div class="col-sm-2">
<h5 class="white">Tech Operations</h5>
<ul class="list-unstyled white" role="menu">
<li><a href="/dev/">Developer Information</a></li>
<li><a href="/dev/infrastructure.html">Infrastructure</a></li>
<li><a href="/security/">Security</a></li>
<li><a href="http://status.apache.org">Status</a></li>
<li><a href="/foundation/contact.html">Contacts</a></li>
</ul>
</div>
<div class="col-sm-2">
<h5 class="white">Press</h5>
<ul class="list-unstyled white" role="menu">
<li><a href="/press/">Overview</a></li>
<li><a href="https://blogs.apache.org/">ASF News</a></li>
<li><a href="https://blogs.apache.org/foundation/">Announcements</a></li>
<li><a href="https://twitter.com/TheASF">Twitter Feed</a></li>
<li><a href="/press/#contact">Contacts</a></li>
</ul>
</div>
<div class="col-sm-2">
<h5 class="white">Legal</h5>
<ul class="list-unstyled white" role="menu">
<li><a href="/legal/">Legal Affairs</a></li>
<li><a href="/legal/dmca.html">DMCA</a></li>
<li><a href="/licenses/">Licenses</a></li>
<li><a href="/foundation/marks/">Trademark Policy</a></li>
<li><a href="/foundation/records/">Public Records</a></li>
<li><a href="/foundation/policies/privacy.html">Privacy Policy</a></li>
<li><a href="/licenses/exports/">Export Information</a></li>
<li><a href="/foundation/license-faq.html">License/Distribution FAQ</a></li>
<li><a href="/foundation/contact.html">Contacts</a></li>
</ul>
</div>
<div class="col-sm-1">
</div>
</div>
<hr class="col-lg-12 hr-white" />
<div class="row">
<div class="col-lg-12">
<p class="text-center">Copyright &#169; 2018 The Apache Software Foundation, Licensed under the <a class="white" href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
<p class="text-center">Apache and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
</div>
</div>
</div>
</footer>
<!-- / Footer -->
<script src="/js/jquery-2.1.1.min.js"></script>
<script src="/js/bootstrap.js"></script>
</body>
</html>

202
LICENSE-2.0.txt Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

880
README.txt Normal file
View File

@ -0,0 +1,880 @@
================================================================================
ISCE Python3 Version
================================================================================
This is the Interferometric synthetic aperture radar Scientific Computing
Environment (ISCE). Its initial development was funded by NASA's Earth Science
Technology Office (ESTO) under the Advanced Information Systems Technology
(AIST) 2008 and is currently being funded under the NASA-ISRO SAR (NISAR)
project.
THIS IS RESEARCH CODE PROVIDED TO YOU "AS IS" WITH NO WARRANTIES OF CORRECTNESS.
USE AT YOUR OWN RISK.
Use of this software is controlled by a non-commercial use license agreement
provided by the California Institute of Technology Jet Propulsion Laboratory.
You must obtain a license in order to use this software. Please consult the
LICENSE file found in this package.
ISCE is a framework designed for the purpose of processing Interferometric
Synthetic Aperture Radar (InSAR) data. The framework aspects of it have been
designed as a general software development framework. It may have additional
utility in a general sense for building other types of software packages. In
its InSAR aspect ISCE supports data from many space-borne satellites and one
air-borne platform. We continue to increase the number of sensors supported.
At this time the sensors that are supported are the following: ALOS, ALOS2,
COSMO_SKYMED, ENVISAT, ERS, KOMPSAT5, RADARSAT1, RADARSAT2, RISAT1, Sentinel1,
TERRASARX, and UAVSAR.
Starting with svn revision number r1349 (2014-03-28) ISCE was converted to work
with Python3. From that point forward major development has been limited to
that version. Some bug fixes and new code developed in the Python3 version were
merged into the Python2 version to support our Python2 users, but going forward
we highly recommend that our users convert to using the Python3 version. We
plan to release a "final" Python2 version of the code very soon.
================================================================================
Contents
================================================================================
1. Software Dependencies
1.1 Installing software dependencies with standard package managers
1.2 Installing Virtual Machine Images with Dependencies Pre-Installed
1.3 Installing dependencies with provided setup script
1.4 Hints for installing dependencies by hand.
1.5 Note On 'python3' Exectuable Convention
2. Building ISCE
2.1 Configuration control: SCONS_CONFIG_DIR and SConfigISCE
2.2 Install ISCE
2.3 Setup Your Environment
3. Running ISCE
3.1 Running ISCE from the command line
3.2 Running ISCE in the Python interpreter
3.3 Running ISCE with steps
3.4 NOTE on DEM
4. Input Files
5. Component Configurability
5.1 Component Names: Family and Instance
5.2 Component Configuration Files: Locations, Names, Priorities
5.3 Component Configuration Help
================================================================================
1. Software Dependencies
================================================================================
Basic:
------
gcc >= 4.7
fftw 3.2.2
Python >= 3.2 (3.3 preferred)
scons >= 2.0.1
curl - for automatic DEM downloads
gdal, gdal.py >= 2.0
For a few sensor types:
-----------------------
hdf5 >= 1.8.5 and h5py >= 1.3.1 - for COSMO-SkyMed, Kompsat5, and 'Generic' sensor
spiceypy - for RadarSAT1
For mdx (image visualization tool) options:
-------------------------------------------
Motif libraries and include files
ImageMagick - for mdx production of kml file (advanced feature)
grace - for mdx production of color table and line plots (advanced feature)
For the "unwrap 2 stage" option:
--------------------------------
RelaxIV and Pulp are required. Information on getting these packages if
you want to try the unwrap 2 stage option:
* RelaxIV (a minimum cost flow relaxation algorithm coded in C++ by
Antonio Frangioni and Claudio Gentile at the University of Pisa,
based on the Fortran code developed by by Dimitri Bertsekas while
at MIT) available by request at http://www.di.unipi.it/~frangio.
So that ISCE will compile it properly, the RelaxIV files should
be placed in the directory: 'contrib/UnwrapComp/src/RelaxIV'.
* PULP: Use easy_install or pip to install it or else clone it from,
https://github.com/coin-or/pulp. Make sure the path to the installed
pulp.py is on your PYTHONPATH environment variable (it should be the case
if you use easy_install or pip).
Optional for splitSpectrum, GPUtopozero, and GPUgeo2rdr:
--------------------------------------------------------
cython3 - must have an executable named cython3 (use a symbolic link)
cuda - for GPUtopozero and GPUgeo2rdr
--------------------------------------------------------------------------------
1.1 Installing software dependencies with standard package managers
--------------------------------------------------------------------------------
The easiest way to install most of these is with package managers such as
'apt-get' on Linux systems or 'macports' on MacOsX. To use these, however,
will require that you have superuser permission on your computer. The
following URL gives additional information on installing prerequisites for
ISCE:
https://winsar.unavco.org/portal/wiki/Manual%20installation%20using%20repository%20managers/
If it is not possible for you to install the software yourself and you
can't convince the System Administrator on your computer to install the
dependencies, then we provide virtual machine images (VMs) with the
dependencies pre-installed (see Section 1.2).
As a last resort we provide an *experimental* setup script named install.sh
described in Section 1.3 that will allow you to do a "user" installation of the
basic dependencies, setup your environment variables, and install ISCE for you.
For the truly adventurous who want to install dependencies by hand we provide
some hints in Section 1.4.
When you have installed the dependencies you can skip the other sections about
installing the dependencies and read Section 1.5 about the 'python3' convention
and then Section 2 on building ISCE and configuring your environment.
--------------------------------------------------------------------------------
1.2 Installing Virtual Machine Images with Dependencies Pre-Installed
--------------------------------------------------------------------------------
If you don't have superuser privileges on your machine and your system is not
up to date with the software dependencies required to use ISCE, then you can
download Virtual Machine Images (VMs) at the following URL:
Full link: http://earthdef.caltech.edu/boards/4/topics/305
Simple link: http://tinyurl.com/iscevm
Instructions on how to install the Virtual Machines are given there.
--------------------------------------------------------------------------------
1.3 Installing dependencies with provided setup script
--------------------------------------------------------------------------------
This distribution includes an *experimental* script that is designed to
download, build, and install all relevant packages needed for ISCE (except for
h5py, which presently must be built by hand but is only needed for Cosmo-Skymed,
spiceypy, only needed for RadarSAT1, and gdal python bindings). This script is
meant as a last resort for those adventurous persons who may not have root
privileges on their machine to install software with standard package managers
or a virutal machine (VM) image (see Section 1.1 or 1.2).
The script is in the setup directory, and is called install.sh. To run it, you
should cd to the setup directory, then issue the command
> install.sh -h
to see instructions on how to run the script. The minimal command option is
simply,
> install.sh -p <INSTALL_PATH>
where <INSTALL_PATH> is a path where you have permission to create files. This
will check whether the dependencies exist on your default paths and then install
those that do not on the specified path.
The path should be in a local directory away from the system areas to avoid
conflicts and so that administrator privileges are not needed. The config.py
file contains a list of urls where the packages are currently downloaded from
Commenting out a particular package will prevent installation of that package.
If the specified server for a particular package in this file is not available,
then you can simply browse the web for a different server for this package and
replace it in the config.py file. Below under the "Building ISCE" section,
there are instructions on how to point to these packages for building ISCE.
Once all these packages are built, you must setup your PATH and LD_LIBRARY_PATH
variables in the unix shell to ensure that these packages are used for compiling
and linking rather than the default system packages.
--------------------------------------------------------------------------------
1.4 Hints for installing dependencies by hand.
--------------------------------------------------------------------------------
If you would prefer to install all these packages by hand, follow this procedure:
Compile the following
for Radarsat2, Sentinel1A and Tandem-X gdal with python bindings >= 1.9
Building gcc/gfortran
---------------------
Building gcc from source code can be a difficult undertaking. Refer to the
detailed directions at http://gcc.gnu.org/install/ for further help.
Building fftw-3.2.2
-------------------
Get fftw-3.2.2 from: http://www.fftw.org/fftw-3.2.2.tar.gz
Untar the file fftw-3.2.2.tar.gz using
tar -zxvf fftw-3.2.2.tar.gz
cd fftw-3.2.2
then run ./configure --enable-single --enable-shared --prefix=<directory>
where <directory> is the full path to an installation location where you have
write access. Then run,
make
make install
Building Python
---------------
Get the Python source code from http://www.python.org/ftp/python/3.3.5/Python-3.3.5.tgz
Untar the file Python-3.3.5.tgz using
tar -zxvf Python-3.3.5.tgz
cd Python-3.3.5
Then run
./configure --prefix=<directory>
where <directory> is the full path to an installation location where you
have write access. Then run,
make
make install
Builing scons
At this time scons only works with Python2. The scons developers have
announced that they are working on a Python3 version of scons. In the
meantime, you should have Python2.6 or Python2.7 available to you by
default if your computer is new enough. Otherwise repeat the above
steps with 3.3.5 replaced with 2.7.8.
Get scons http://prdownloads.sourceforge.net/scons/scons-2.0.1.tar.gz
Untar the file scons-2.0.1.tar.gz using
tar -zxvf scons-2.0.1.tar.gz
cd scons-2.0.1.tar.gz
Then, using the version of Python you just built, run
python2.6 setup.py build
python2.6 setup.py install
Building hdf5 [Only necessary for COSMO-SkyMed support]
-------------
Get the source code from:
http://www.hdfgroup.org/ftp/HDF5/current/src/hdf5-1.8.6.tar.gz
Building h5py [Only necessary for COSMO-SkyMed support]
Get the h5py source code from:
http://code.google.com/p/h5py/downloads/detail?name=h5py-1.3.1.tar.gz
Building gdal-bindings [Only necessary for Radarsat2, Tandem-X and Sentinel 1A]
----------------
On most linux distributions, gdal can installed along with its python bindings
using standard repository management tools.
If you don't have gdal, you can find instructions on building GDAL here
http://trac.osgeo.org/gdal/wiki/BuildHints
Remember to use configure with --with-python option to automatically build
python bindings.
Else, if you already have gdal installed on your system but without python
buindings, use easy_install corresponding to your python 3 version. You may
need to setup LD_LIBRARY_PATH correctly to include path to libgdal.so
easy_install GDAL
Building SpiceyPy [Only necessary for Radarsat1]
----------------
JPL's CSPICE library (http://naif.jpl.nasa.gov/naif/toolkit_C.html) is needed
for this. Follow instructions at https://github.com/Apollo117/SpiceyPy to
install SpiceyPy, after installing CSPICE.
Once all these packages are built, you must setup your PATH and LD_LIBRARY_PATH
variables in the unix shell to ensure that these packages are used for compiling
and linking rather than the default system packages.
To use the Spice software you will need to download the data files indicated in
the component/isceobj/Orbit/db/kernels.list file. You should download those
files into that directory (or else make soft links in that directory to where
you download them) so that ISCE can find them in the place it expects.
--------------------------------------------------------------------------------
1.5 Note On 'python3' Exectuable Convention
--------------------------------------------------------------------------------
We follow the convention of most package managers in using the executable
'python3' for Python3.x and 'python' for Python2.x. This makes it easy to turn
Python code into executable commands that know which version of Python they
should invoke by naming the appropriate version at the top of the executable
file (as in #!/usr/bin/env python3 or #!/usr/bin/env python). Unfortunately,
not all package managers (such as macports) follow this convention. Therefore,
if you use one of a package manager that does not create the 'python3'
executable automatically, then you should place a soft link on your path to
have the command 'python3' on your path. Then you will be able to execute an
ISCE application such as 'insarApp.py as "> insarApp.py" rather than as
"> /path-to-Python3/python insarApp.py".
================================================================================
2. Building ISCE
================================================================================
--------------------------------------------------------------------------------
2.1 Configuration control: SCONS_CONFIG_DIR and SConfigISCE
--------------------------------------------------------------------------------
Scons requires that configuration information be present in a directory
specified by the environment variable SCONS_CONFIG_DIR. First, create a
build configuration file, called SConfigISCE and place it in your chosen
SCONS_CONFIG_DIR. The SConfigISCE file should contain the following
information, note that the #-symbol denotes a comment and does not need
to be present in the SConfigISCE file:
NOTE: Locations vary from system to system, so make sure to use the appropriate location.
The one listed here are just for illustrative purpose.
# The directory in which ISCE will be built
PRJ_SCONS_BUILD = $ISCE_BUILD_ROOT/isce
# The directory into which ISCE will be installed
PRJ_SCONS_INSTALL = $ISCE_INSTALL_ROOT/isce
# The location of libraries, such as libstdc++, libfftw3 (for most system
# it's /usr/lib and/or /usr/local/lib/ and/or /opt/local/lib)
LIBPATH = $YOUR_LIB_LOCATION_HOME/lib64 $YOUR_LIB_LOCATION_HOME/lib
# The location of Python.h. If you have multiple installations of python
# make sure that it points to the right one
CPPPATH = $YOUR_PYTHON_INSTALLATION_LOCATION/include/python3.xm $YOUR_PYTHON_INSTALLATION_LOCATION/lib/python3.x/site-packages/numpy/core/include
# The location of the fftw3.h (most likely something like /usr/include or
# /usr/local/include /opt/local/include
FORTRANPATH = $YOUR_FFTW3_INSTALLATION_LOCATION/include
# The location of your Fortran compiler. If not specified it will use the system one
FORTRAN = $YOUR_COMPILER_LOCATION/bin/gfortran
# The location of your C compiler. If not specified it will use the system one
CC = $YOUR_COMPILER_LOCATION/bin/gcc
# The location of your C++ compiler. If not specified it will use the system one
CXX = $YOUR_COMPILER_LOCATION/bin/g++
#libraries needed for mdx display utility
MOTIFLIBPATH = /opt/local/lib # path to libXm.dylib
X11LIBPATH = /opt/local/lib # path to libXt.dylib
MOTIFINCPATH = /opt/local/include # path to location of the Xm
# directory with various include files (.h)
X11INCPATH = /opt/local/include # path to location of the X11 directory
# with various include files
#Explicitly enable cuda if needed
ENABLE_CUDA = True
CUDA_TOOLKIT_PATH = $YOUR_CUDA_INSTALLATION #/usr/local/cuda
In the above listing of the SConfigISCE file, $ISCE_BUILD_ROOT and
$ISCE_INSTALL_ROOT may be actual environment variables that you create or else
you can replace them with the actual paths you choose to use for the build files
and the install files. Also, in the following the capitalization of 'isce' as
lower case does matter. This is the case-sensitive package name that Python
code uses for importing isce.
--------------------------------------------------------------------------------
2.2 Install ISCE
--------------------------------------------------------------------------------
Untar the file isce.tar.gz
cd isce
scons install
For a verbose install run:
scons -Q install
The scons command also allows you to explicitly specify the name of the
SConfigISCE file, which could be used to specify an alternative file for
(say SConfigISCE_NEW) which must still be located in the same
SCONS_CONFIG_DIR, run
scons install --setupfile=SConfigISCE_NEW
This will build the necessary components and install them into the location
specified in the configuration file as PRJ_SCONS_INSTALL.
--------------------------------------------------------------------------------
2.3 Setup Your Environment
--------------------------------------------------------------------------------
Once everything is installed, you will need to set the following environment
variables to run the programs included in ISCE ($ISCE_INSTALL_ROOT may be an
environment variable you created in 2.1 above or else replace it with the actual
path to where you installed ISCE):
export PYTHONPATH=$ISCE_INSTALL_ROOT:$PYTHONPATH
and to put the executable commands in the ISCE applications directory on your
PATH for convenience,
export ISCE_HOME=$ISCE_INSTALL_ROOT/isce
export PATH=$ISCE_HOME/applications:$PATH
An optional environment variable is $ISCEDB. This variable points to a
directory in which you may place xml files containing global preferences. More
information on this directory and the files that you might place there is
given below in Section 4. For now you can ignore this environment variable.
To test your installation and your environment, do the following:
> python3
>>> import isce
>>> isce.version.release_version
================================================================================
3. Running ISCE
================================================================================
---------------------------------------------------------------------------------
3.1 Running ISCE from the command line
---------------------------------------------------------------------------------
Copy the example xml files located in the example directory in the ISCE source
tree to a working directory and modify them to point to your own data. Run
them using the command:
> $ISCE_HOME/applications/insarApp.py isceInputFile.xml
or (with $ISCE_HOME/applications on your PATH) simply,
> insarApp.py isceInputFile.xml
The name of the input file on the command line is arbitrary. ISCE also looks
for appropriately named input files in the local directory
You can also ask ISCE for help from the command line:
> insarApp.py --help
This will tell you the basic command and the options for the input file.
Example input files are also given in the 'examples/input_files' directory.
As explained in the Component Configurability section below, it is also possible
to run insarApp.py without giving an input file on the command line. ISCE will
automatically find configuration files for applications and components if they
are named appropriately.
---------------------------------------------------------------------------------
3.2 Running ISCE in the Python interpreter
---------------------------------------------------------------------------------
It is also possible to run ISCE from within the Python interpreter. If you have
an input file named insarInputs.xml you can do the following:
%> python3
>>> import isce
>>> from insarApp import Insar
>>> a = Insar(name="insarApp", cmdline="insarInputs.xml")
>>> a.configure()
>>> a.run()
(As explained in the Component Configurability section below, if the file
insarInputs.xml were named insarApp.xml or insar.xml, then the 'cmdline' input
on the line creating 'a' would not be necessary. The file 'insarApp.xml' would
be loaded automatically because when 'a' is created above it is given the name
'insarApp'. A file named 'insar.xml' would also be loaded automatically if it
exists because the code defining insarApp.py gives all instances of it the
'family' name 'insar'. See the Component Configurability section below for
details.)
---------------------------------------------------------------------------------
3.3 Running ISCE with steps
---------------------------------------------------------------------------------
An other way to run ISCE is the following:
insarApp.py insar.xml --steps
This will run insarApp.py from beginning to end as is done without the
--steps option, but with the added feature that the workflow state is
stored in files after each step in the processing using Python's pickle
module. This method of running insarApp.py is only a little slower
and it uses extra disc space to store the pickle files, but it
provides some advantage for debugging and for stopping and starting a
workflow at any predetermined point in the flow.
The full options for running insarApp.py with steps is the following:
insarApp.py insar.xml [--steps] [--start=<s>] [--end=<s>] [--dostep=<s>]
where <s> is the name of a step. To see the full ordered list of steps
the user can issue the following command:
insarApp.py insar.xml --steps --help
The --steps option was explained above.
The --start and --end option can be used together to process a range of steps.
The --dostep option is used to process a single step.
For the --start and --dostep options to work, of course, requires that the
steps preceding the starting step have been run previously because the
state of the work flow at the beginning of the first step to be run must
be stored from a previous run.
An example for using steps might be to execute the end-to-end workflow
with --steps to store the state of the workflow after every step as in,
insarApp.py insar.xml --steps
Then use --steps to rerun some of the steps (perhaps you made a code
modification for one of the steps and want to test it without starting
from the beginning) as in
insarApp.py insar.xml --start=<step-name1> --end=<step-name2>
or to rerun a single step as in
insarApp.py insar.xml --dostep=<step-name>
Running insarApp.py with --steps also enables one to enter the Python
interpreter after a run and load the state of the workflow at any stage
and introspect the objects in the flow and play with them as follows,
for example:
%> python3
>>> import isce
>>> f = open("PICKLE/formslc")
>>> import pickle
>>> a = pickle.load(f)
>>> o = f.getMasterOrbit()
>>> t, x, p, off = o._unpackOrbit()
>>> print t
>>> print x
>>>
Someone with familiarity of the inner workings of ISCE can exploit
this mode of interacting with the pickle object to discover much about
the workflow states and also to edit the state to see its effect
on a subsequent run with --dostep or --start.
---------------------------------------------------------------------------------
3.4 NOTE on DEM
---------------------------------------------------------------------------------
- If a dem component is provided but the dem is the EGM96 geo reference
(which is the case for SRTM DEMs) it will be converted into WGS84.
A new file with suffix wgs84 is created. If it is already in WGS84
nothing happens.
- If no dem component is specified in input a EGM96 will be downloaded
and the it will be converted into WGS84. There will be then two files,
an EGM96 with no suffix, and the WGS84 with the wgs84 suffix.
================================================================================
4. Input Files
================================================================================
Input files are structured 'xml' documents. This section will briefly
introduce their structure using a special case appropriate for processing ALOS
data. Examples for the other sensor types can be found in the directory
'examples/input_files'.
The basic (ALOS) input file looks like this (indentation is optional):
insarApp.xml:
-------------
<insarApp>
<component name="insarApp">
<property name="sensor name">ALOS</property>
<component name="Master">
<property name="IMAGEFILE">
/a/b/c/20070215/IMG-HH-ALPSRP056480670-H1.0__A
</property>
<property name="LEADERFILE">
/a/b/c/20070215/LED-ALPSRP056480670-H1.0__A
</property>
<property name="OUTPUT">20070215.raw </property>
</component>
<component name="Slave">
<property name="IMAGEFILE">
/a/b/c/20061231/IMG-HH-ALPSRP049770670-H1.0__A
</property>
<property name="LEADERFILE">
/a/b/c/20061231/LED-ALPSRP049770670-H1.0__A
</property>
<property name="OUTPUT">20061231.raw </property>
</component>
</component>
</insarApp>
The data are enclosed between an opening tag and a closing tag. The <insarApp>
tag is closed by the </insarApp> tag for example. This outer tag is necessary
but its name has no significance. You can give it any name you like. The
other tags, however, need to have the names shown above. There are 'property',
and 'component' tags shown in this example.
The component tags have names that match a Component name in the ISCE code.
The component tag named 'insarApp' refers to the configuration information for
the Application (which is a Component) named "insarApp". Components contain
properties and other components that are configurable. The property tags
give the values of a single variable in the ISCE code. One of the properties
defined in insarApp.py is the "sensor name" property. In the above example
it is given the value ALOS. In order to run insarApp.py two images need to
be specified. These are defined as components named 'Master' and 'Slave'.
These components have properties named 'IMAGEFILE', 'LEADERFILE', and 'OUTPUT'
with the values given in the above example.
NOTE: the capitalization of the property and component names are not of any
importance. You could enter 'imagefile' instead of 'IMAGEFILE', for example,
and it would work correctly. Also extra spaces in names that include spaces,
such as "sensor name" do not matter.
There is a lot of flexibility provided by ISCE when constructing these input
files through the use of "catalog" tags and "constant" tags.
A "catalog" tag can be used to indicate that the contents that would normally
be found between an opening ad closing "component" tag are defined in another
xml file. For example, the insarApp.xml file shown above could have been split
between three files as follows:
insarApp.xml
------------
<insarApp>
<component name="insar">
<property name="Sensor name">ALOS</property>
<component name="master">
<catalog>20070215.xml</catalog>
</component>
<component name="slave">
<catalog>20061231.xml</catalog>
</component>
</component>
</insarApp>
20070215.xml
------------
<component name="Master">
<property name="IMAGEFILE">
/a/b/c/20070215/IMG-HH-ALPSRP056480670-H1.0__A
</property>
<property name="LEADERFILE">
/a/b/c/20070215/LED-ALPSRP056480670-H1.0__A
</property>
<property name="OUTPUT">20070215.raw </property>
</component>
20061231.xml
------------
<component name="Slave">
<property name="IMAGEFILE">
/a/b/c/20061231/IMG-HH-ALPSRP049770670-H1.0__A
</property>
<property name="LEADERFILE">
/a/b/c/20061231/LED-ALPSRP049770670-H1.0__A
</property>
<property name="OUTPUT">20061231.raw</property>
</component>
A "constant" tag can be used to define a constant for convenience inside
an xml file. For example, the dates '20070215' and '20061231' are used
multiple times in the above files. Also, the base path '/a/b/c/' is used
multiple times. A constant defined in a constant tag is used in constructing
values by sandwiching it between two '$' symbols. For example, if a constant
named "date1" is defined then to use it we would enter '$date1'. The following
example insarApp.xml file should make this clear:
insarApp.xml
------------
<insarApp>
<constant name="dir">/a/b/c </constant>
<constant name="date1">20070215</constant>
<constant name="date2">20061231</constant>
<constant name="dir1">$dir$/$date1$</constant>
<constant name="dir2">$dir$/$date2$</constant>
<component name="insarApp">
<property name="sensor name">ALOS</property>
<component name="Master">
<property name="IMAGEFILE">
$dir1$/IMG-HH-ALPSRP056480670-H1.0__A
</property>
<property name="LEADERFILE">
$dir1$/LED-ALPSRP056480670-H1.0__A
</property>
<property name="OUTPUT">$date1$.raw </property>
</component>
<component name="Slave">
<property name="IMAGEFILE">
$dir2$/IMG-HH-ALPSRP049770670-H1.0__A
</property>
<property name="LEADERFILE">
$dir2$/LED-ALPSRP049770670-H1.0__A
</property>
<property name="OUTPUT">$date2$.raw </property>
</component>
</component>
</insarApp>
Note: as of the time of this release constants do not work with catalog files.
This will be fixed in a future release.
================================================================================
5. Component Configurability
================================================================================
In the examples for running insarApp.py (Section 3.1 and 3.3 above) the input
data were entered by giving the name of an 'xml' file on the command line. The
ISCE framework parses that 'xml' file to assign values to the configurable
variables in the isce Application insarApp.py. The Application executes
several steps in its workflow. Each of those steps are handled by a Component
that is also configurable from input data. Each component may be configured
independently from user input using appropriately named and placed xml files.
This section will explain how to name these xml files and where to place them.
----------------------------------------------------------------------------
5.1 Component Names: Family and Instance
----------------------------------------------------------------------------
Each configurable component has two "names" associated with it. These names
are used in locating possible configuration xml files for those components. The
first name associated with a configurable component is its "family" name. For
insarApp.py, the family name is "insar". Inside the insarApp.py file an
Application is created from a base class named Insar. That base class defines
the family name "insar" that is given to every instance created from it. The
particular instance that is created in the file insarApp.py is given the
'instance name' 'insarApp'. If you look in the file near the bottom you will
see the line,
insar = Insar(name="insarApp")
This line creates an instance of the class Insar (that is given the family name
'insar' elsewhere in the file) and gives it the instance name "insarApp".
Other applications could be created that could make several different instances
of the Insar. Each instance would have the family name "insar" and would be
given a unique instance name. This is possible for every component. In the
above example xml files instances name "Master" and "Slave" of a family named
"alos" are created.
----------------------------------------------------------------------------
5.2 Component Configuration Files: Locations, Names, Priorities
----------------------------------------------------------------------------
The ISCE framework looks for xml configuration files when configuring every
Component in its flow in 3 different places with different priorities. The
configuration sequence loads configuration parameters found in these xml files
in the sequence lowest to highest priority overwriting any parameters defined
as it moves up the priority sequence. This layered approach allows a couple
of advantages. It allows the user to define common parameters for all instances
in one file while defining specific instance parameters in files named for those
specific instances. It also allows global preferences to be set in a special
directory that will apply unless the user overrides them with a higher priority
xml file.
The priority sequence has two layers. The first layer is location of the xml
file and the second is the name of the file. Within each of the 3 location
priorities indicated below, the filename priority goes from 'family name' to
'instance name'. That is, within a given location priority level, a file
named after the 'family name' is loaded first and then a file with the
'instance name' is loaded next and overwrites any property values read from the
'family name' file.
The priority sequence for location is as follows:
(1) The highest priority location is on the command line. On the command line
the filename can be anything you choose. Configuration parameters can also be
entered directly on the command line as in the following example:
> insarApp.py insar.master.output=master_c.raw
This example indicates that the variable named 'output' of the Component
named 'master' belonging to the Component (or Application) named 'insar'
will be given the name "master_c.raw".
The priority sequence on the command line goes from lowest priority on the left
to highest priority on the right. So, if we use the command line,
> insarApp.py myInputFile.xml insar.master.output=master_c.raw
where the myInputFile.xml file also gives a value for the insar master output
file as master_d.raw, then the one defined on the right will win, i.e.,
master_c.raw.
(2) The next priority location is the local directory in which insarApp.py is
executed. Any xml file placed in this directory named according to either the
family name or the instance name for any configurable component in ISCE will be
read while configuring the component.
(3) If you define an environment variable named $ISCEDB, you can place xml files
with family names or instance names that will be read when configuring
Configurable Components. These files placed in the $ISCEDB directory have the
lowest priority when configuring properties of the Components. The files placed
in the ISCEDB directory can be used to define global settings that will apply
unless the xml files in the local directory or the command line override those
preferences.
----------------------------------------------------------------------------
5.2 Component Configuration Structure
----------------------------------------------------------------------------
However, the component tag has to have the family name of the Component/
Application. In the above examples you see
that the outermost component tag has the name "insar", which is the family name
of the class Insar of which insarApp is an instance.
----------------------------------------------------------------------------
5.3 Component Configuration Help
----------------------------------------------------------------------------
At this time there is limited information about component configurability
through the command
> insarApp.py --help
Future deliveries will improve this situation. In the meantime we describe
here how to discover from the code which Components and parameters are
configurable. One note of caution is that it is possible for a parameter
to appear to be configurable from user input when the particular flow will
not allow this degree of freedom. Experience and evolving documentation will
be of use in determining these cases.
How to find out whether a component is configurable, what its configurable
parameters are, what "name" to use in the xml file, and what name to give to
the xml file.
Let's take as an example, Nstage.py, which is in components/mroipac/ampcor.
Open it in an editor and search for the string "class Nstage". It is on
line 243. You will see that it inherits from Component. This is the minimum
requirement for it to be a configurable component.
Now look above that line and you will see several variable names being set
equal to a call to Component.Parameter. These declarations define these
variables as configurable parameters. They are entered in the "parameter_list"
starting on line 248. That is the method by which these Parameters are made
configurable parameters of the Component Nstage.
Each of the parameters defines the "public_name", which is the "name" that you
would enter in the xml file. For instance if you want to set the gross offset
in range, which is defined starting on line 130 in the variable
ACROSS_GROSS_OFFSET, then you would use an xml tag like the following (assuming
you have determined that the gross offset in range is about 150 pixels):
<property name="ACROSS_GROSS_OFFSET">150</property>
Now, to determine what to call the xml file and what "name" to use in the
component tag. A configurable component has a "family" name and an instance
"name". It is registered as having these names by calling the
Component.__init__ constructor, which is done on line 672. On that line you
will see that the call to __init__ passes 'family=self.__class__.family' and
'name=name' to the Component constructor (super class of Nstage). The family
name is given as "nstage" on line 245. The instance name is passed as the
value of the 'name=name' and was passed to it from whatever program created it.
Nstage is created in components/isceobj/InsarProc/runOffsetprf_nstage.py where
it is given the name 'insarapp_slcs_nstage' on line 107 and also in
components/isceobj/InsarProc/runRgoffset_nstage.py where it is given the name
'insarapp_intsim_nstage' on line 58. If you are setting a parameter that
should be the same for both of these uses of Nstage, then you can use the
family name 'nstage' for the name of the xml file as 'nstage.xml'. It is more
likely that you will want to use the instance names, 'insarapp_slcs_nstage.xml'
and 'insarapp_intsim_nstage.xml'. Use the family name 'nstage' for the
component tag 'name'.
Example for SLC matching use of Nstage:
Filename: insarapp_slcs_nstage.xml:
<dummy>
<component name="nstage">
<property name="ACROSS_GROSS_OFFSET">150</property>
</component>
</dummy>
==============================================================================
END OF FILE
==============================================================================

282
SConstruct Normal file
View File

@ -0,0 +1,282 @@
#!/usr/bin/env python
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
import sys
if sys.version_info[0] == 2:
print('Building with scons from python2')
else:
print('Building with scons from python3')
if 'SCONS_CONFIG_DIR' in os.environ:
sconsConfigDir = os.environ['SCONS_CONFIG_DIR']
else:
print("Error. Need to set the variable SCONS_CONFIG_DIR in the shell environment")
raise Exception
from configuration import sconsConfigFile
#allow scons to take the input argument --setupfile=someOtherFile to allow change of the default SConfigISCE
AddOption('--setupfile',dest='setupfile',type='string',default='SConfigISCE')
AddOption('--isrerun',dest='isrerun',type='string',default='no')
AddOption('--skipcheck',dest='skipcheck', action='store_true', default=False)
env = Environment(ENV = os.environ)
sconsSetupFile = GetOption('setupfile')
isrerun = GetOption('isrerun')
skipcheck = GetOption('skipcheck')
sconsConfigFile.setupScons(env,sconsSetupFile)
#add some information that are necessary to build the framework such as specific includes, libpath and so on
buildDir = env['PRJ_SCONS_BUILD']
libPath = os.path.join(buildDir,'libs')
#this is the directory where all the built library are put so they can easily be found during linking
env['PRJ_LIB_DIR'] = libPath
# add the libPath to the LIBPATH environment that is where all the libs are serched
env.AppendUnique(LIBPATH = [libPath])
# add the modPath to the FORTRANMODDIR environment that is where all the fortran mods are searched
#not working yet
modPath = os.path.join(buildDir,'mods')
env['FORTRANMODDIR'] = modPath
env.AppendUnique(FORTRANPATH = [modPath])
env.AppendUnique(F90PATH = [modPath])
env.AppendUnique(F77PATH = [modPath])
#add the includes needed by the framework
imageApiInc = os.path.join(buildDir,'components/iscesys/ImageApi/include')
dataCasterInc = os.path.join(buildDir,'components/iscesys/ImageApi/DataCaster/include')
lineAccessorInc = os.path.join(buildDir,'components/isceobj/LineAccessor/include')
stdOEInc = os.path.join(buildDir,'components/iscesys/StdOE/include')
utilInc = os.path.join(buildDir,'components/isceobj/Util/include')
utilLibInc = os.path.join(buildDir,'components/isceobj/Util/Library/include')
env.AppendUnique(CPPPATH = [imageApiInc,dataCasterInc,lineAccessorInc,stdOEInc,utilInc,utilLibInc])
env['HELPER_DIR'] = os.path.join(env['PRJ_SCONS_INSTALL'],'helper')
env['HELPER_BUILD_DIR'] = os.path.join(env['PRJ_SCONS_BUILD'],'helper')
#put the pointer function createHelp in the environment so it can be access anywhere
from configuration.buildHelper import createHelp
env['HELP_BUILDER'] = createHelp
#Create an env variable to hold all the modules added to the sys.path by default.
#They are the same as the one in in __init__.py in the same directory of this file
moduleList = []
installDir = env['PRJ_SCONS_INSTALL']
moduleList.append(os.path.join(installDir,'applications'))
moduleList.append(os.path.join(installDir,'components'))
env['ISCEPATH'] = moduleList
env.PrependUnique(LIBS=['gdal'])
Export('env')
inst = env['PRJ_SCONS_INSTALL']
####new part
#####PSA. Check for header files and libraries up front
confinst = Configure(env)
hdrparams = [('python3 header', 'Python.h', 'Install python3-dev or add path to Python.h to CPPPATH'),
('fftw3', 'fftw3.h', 'Install fftw3 or libfftw3-dev or add path to fftw3.h to CPPPATH and FORTRANPATH'),
('hdf5', 'hdf5.h', 'Install HDF5 of libhdf5-dev or add path to hdf5.h to CPPPATH'),
('X11', 'X11/Xlib.h', 'Install X11 or libx11-dev or add path to X11 directory to X11INCPATH'),
('Xm', 'Xm/Xm.h', 'Install libXm or libXm-dev or add path to Xm directory to MOTIFINCPATH'),
('openmp', 'omp.h', 'Compiler not built with OpenMP. Use a different compiler or add path to omp.h to CPPPATH'),]
allflag = False
for (name,hname,msg) in hdrparams:
if not (confinst.CheckCHeader(hname) or confinst.CheckCXXHeader(hname)):
print('Could not find: {0} header for {1}'.format(hname, name))
print('Error: {0}'.format(msg))
allflag = True
libparams= [('libhdf5', 'hdf5', 'Install hdf5 or libhdf5-dev'),
('libfftw3f', 'fftw3f', 'Install fftw3 or libfftw3-dev'),
('libXm', 'Xm', 'Install Xm or libXm-dev'),
('libXt', 'Xt', 'Install Xt or libXt-dev')]
for (name,hname,msg) in libparams:
if not confinst.CheckLib(hname):
print('Could not find: {0} lib for {1}'.format(hname, name))
print('Error: {0}'.format(msg))
allflag = True
if env.FindFile('fftw3.f', env['FORTRANPATH']) is None:
print('Checking for F include fftw3 ... no')
print('Could not find: fftw3.f header for fftw3')
print('Error: Install fftw3 or libfftw3-dev or add path to FORTRANPATH')
allflag = True
else:
print('Checking for F include fftw3 ... yes'.format(name))
###This part added to handle GDAL and C++11
gdal_version = os.popen('gdal-config --version').read()
print('GDAL version: {0}'.format(gdal_version))
try:
gdal_subversion = int(gdal_version.split('.')[1])
except:
raise Exception('gdal-config not found. GDAL does not appear to be installed ... cannot proceed. If you have installed gdal, ensure that you have path to gdal-config in your environment')
env['GDALISCXX11'] = None
if gdal_subversion >= 3:
env['GDALISCXX11'] = 'True'
##Add C++11 for GDAL checks
#Save default environment if C++11
if env['GDALISCXX11']:
preCXX11 = confinst.env['CXXFLAGS']
confinst.env.Replace(CXXFLAGS=preCXX11 + ['-std=c++11'])
if not confinst.CheckCXXHeader('gdal_priv.h'):
print('Could not find: gdal_priv.h for gdal')
print('Install gdal or add path to gdal includes to CPPPATH')
allflag = True
if not confinst.CheckLib('gdal'):
print('Could not find: libgdal for gdal')
print('Install gdal or include path to libs to LIBPATH')
allflag = True
###If C++11, revert to original environment
if env['GDALISCXX11']:
confinst.env.Replace(CXXFLAGS=preCXX11)
###Decide whether to complain or continue
if (allflag and not skipcheck):
print('Not all components of ISCE will be installed and can result in errors.')
raw_input('Press Enter to continue.... Ctrl-C to exit')
elif (allflag and skipcheck):
print('Not all components of ISCE will be installed and can result in errors.')
print('User has requested to skip checks. Expect failures ... continuing')
else:
print('Scons appears to find everything needed for installation')
try:
# Older versions of scons do not have CheckProg, so 'try' to use it
if confinst.CheckProg('cython3'):
env['CYTHON3'] = True
else:
print('cython3 is not installed. Packages that depend on cython3 will not be installed.')
env['CYTHON3'] = False
except:
# If CheckProg is not available set env['CYTHON3'] = True and hope for the best
# If the cython3 link does not exist, then a later error should prompt the user to
# create the cython3 link to their cython installed as cython.
env['CYTHON3'] = True
pass
env = confinst.Finish()
###End of new part
### GPU branch-specific modifications
if 'ENABLE_CUDA' in env and env['ENABLE_CUDA'].upper() == 'TRUE':
print('User requested compilation with CUDA, if available')
try:
env.Tool('cuda', toolpath=['scons_tools'])
env['GPU_ACC_ENABLED'] = True
print("CUDA-relevant libraries and toolkit found. GPU acceleration may be enabled.")
except:
env['GPU_ACC_ENABLED'] = False
print("CUDA-relevant libraries or toolkit not found. GPU acceleration will be disabled.")
else:
print('User did not request CUDA support. Add ENABLE_CUDA = True to SConfigISCE to enable CUDA support')
env['GPU_ACC_ENABLED'] = False
### End of GPU branch-specific modifications
file = '__init__.py'
if not os.path.exists(file):
fout = open(file,"w")
fout.write("#!/usr/bin/env python3")
fout.close()
env.Install(inst,file)
try:
from subprocess import check_output
svn_revision = check_output('svnversion').strip() or 'Unknown'
if sys.version_info[0] == 3:
svn_revision = svn_revision.decode('utf-8')
except ImportError:
try:
import popen2
stdout, stdin, stderr = popen2.popen3('svnversion')
svn_revision = stdout.read().strip()
if stderr.read():
raise Exception
except Exception:
svn_revision = 'Unknown'
except OSError:
svn_revision = 'Unknown'
if not os.path.exists(inst):
os.makedirs(inst)
fvers = open(os.path.join(inst,'version.py'),'w')
from release_history import release_version, release_svn_revision, release_date
fvers_lines = ["release_version = '"+release_version+"'\n",
"release_svn_revision = '"+release_svn_revision+"'\n",
"release_date = '"+release_date+"'\n",
"svn_revision = '"+svn_revision+"'\n\n"]
fvers.write(''.join(fvers_lines))
fvers.close()
v = 0
if isrerun == 'no':
cmd = 'scons -Q install --isrerun=yes'
if skipcheck:
cmd += ' --skipcheck'
v = os.system(cmd)
if v == 0:
env.Alias('install',inst)
applications = os.path.join('applications','SConscript')
SConscript(applications)
components = os.path.join('components','SConscript')
SConscript(components)
defaults = os.path.join('defaults','SConscript')
SConscript(defaults)
library = os.path.join('library','SConscript')
SConscript(library)
contrib = os.path.join('contrib','SConscript')
SConscript(contrib)
if 'test' in sys.argv:
#Run the unit tests
env['Test'] = True
else:
#Don't run tests.
#This option only installs test support package for future test runs.
env['Test'] = False
tests = os.path.join('test', 'SConscript')
SConscript(tests)

49
__init__.py Executable file
View File

@ -0,0 +1,49 @@
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import print_function
from .version import release_version, release_svn_revision, release_date
from .version import svn_revision
__version__ = release_version
import sys, os
isce_path = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(1,isce_path)
sys.path.insert(1,os.path.join(isce_path,'applications'))
sys.path.insert(1,os.path.join(isce_path,'components'))
sys.path.insert(1,os.path.join(isce_path,'library'))
try:
os.environ['ISCE_HOME']
except KeyError:
print('Using default ISCE Path: %s'%(isce_path))
os.environ['ISCE_HOME'] = isce_path

View File

@ -0,0 +1,76 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Walter Szeliga
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
import math
import logging
import logging.config
logging.config.fileConfig(os.path.join(os.environ['ISCE_HOME'], 'defaults',
'logging', 'logging.conf'))
from iscesys.Compatibility import Compatibility
Compatibility.checkPythonVersion()
from isceobj.Location.Peg import Peg
from iscesys.Component.FactoryInit import FactoryInit
class CalculatePegPoint(FactoryInit):
def calculatePegPoint(self):
self.logger.info("Parsing Raw Data")
self.sensorObj.parse()
frame = self.sensorObj.getFrame()
# First, get the orbit nadir location at mid-swath and the end of the scene
orbit = self.sensorObj.getFrame().getOrbit()
midxyz = orbit.interpolateOrbit(frame.getSensingMid())
endxyz = orbit.interpolateOrbit(frame.getSensingStop())
# Next, calculate the satellite heading from the mid-point to the end of the scene
ellipsoid = frame.getInstrument().getPlatform().getPlanet().get_elp()
midllh = ellipsoid.xyz_to_llh(midxyz.getPosition())
endllh = ellipsoid.xyz_to_llh(endxyz.getPosition())
heading = ellipsoid.geo_hdg(midllh,endllh)
# Then create a peg point from this data
peg = Peg(latitude=midllh[0],longitude=midllh[1],heading=heading,ellipsoid=ellipsoid)
self.logger.info("Peg Point:\n%s" % peg)
def __init__(self,arglist):
FactoryInit.__init__(self)
self.initFactory(arglist)
self.sensorObj = self.getComponent('Sensor')
self.logger = logging.getLogger('isce.calculatePegPoint')
if __name__ == "__main__":
import sys
if (len(sys.argv) < 2):
print("Usage:%s <xml-parameter file>" % sys.argv[0])
sys.exit(1)
runObj = CalculatePegPoint(sys.argv[1:])
runObj.calculatePegPoint()

228
applications/ISCE2ROIPAC.py Normal file
View File

@ -0,0 +1,228 @@
#!/usr/bin/env python3
import isce
from lxml import objectify as OB
from collections import OrderedDict
from datetime import datetime, time
import os
import ConfigParser as CP
import io
from isceobj import Constants as Cn
import numpy as np
import ast
xmlTimeFormat = '%Y-%m-%d %H:%M:%S.%f'
class insarProcXML(object):
'''
Read in the metadata files generated by ISCE and create ROI-PAC equivalents.
'''
def __init__(self, xmlfile='insarProc.xml'):
'''Constructor. Not much here.'''
self.xmlfile = xmlfile
fin = open(self.xmlfile)
self.xml = OB.fromstring(fin.read())
fin.close()
def raw_rsc(self, key=None, write=False):
'''Write out the RSC files for Raw data.'''
if key not in ['master', 'slave']:
raise ValueError('Raw Files can only be written for master or slave.')
rsc = OrderedDict()
######Sequence similar to Envisat's raw.rsc file
rsc['FIRST_FRAME'] = 0
#####Get Scene time
root = getattr(self.xml, key)
frame=root.frame
sensmid = datetime.strptime(frame.SENSING_MID.text, xmlTimeFormat)
sensstart = datetime.strptime(frame.SENSING_START.text, xmlTimeFormat)
sensstop = datetime.strptime(frame.SENSING_STOP.text, xmlTimeFormat)
rsc['FIRST_FRAME_SCENE_CENTER_TIME'] = sensmid.strftime('%Y%m%d%H%M%S') + '{0:2d}'.format(int(sensmid.microsecond/1000.))
rsc['FIRST_FRAME_SCENE_CENTER_LINE'] = 0
rsc['DATE'] = sensmid.strftime('%y%m%d')
rsc['FIRST_LINE_YEAR'] = sensstart.strftime('%Y')
rsc['FIRST_LINE_MONTH_OF_YEAR'] = sensstart.strftime('%m')
rsc['FIRST_LINE_DAY_OF_MONTH'] = sensstart.strftime('%d')
rsc['FIRST_CENTER_HOUR_OF_DAY'] = sensmid.strftime('%H')
rsc['FIRST_CENTER_MN_OF_HOUR'] = sensmid.strftime('%M')
rsc['FIRST_CENTER_S_OF_MN'] = sensmid.strftime('%S')
rsc['FIRST_CENTER_MS_OF_S'] = int(round(sensmid.microsecond/1000.))
rsc['PROCESSING_FACILITY'] = frame.PROCESSING_FACILITY.text
rsc['PROCESSING_SYSTEM'] = frame.PROCESSING_SYSTEM.text
rsc['PROCESSING_SYSTEM_VERSION'] = frame.PROCESSING_SYSTEM_VERSION.text
######Platform information.
instrument = root.instrument
platform = "[platform]\n" + instrument.PLATFORM.text
platform = platform.decode('string_escape')
temp = CP.RawConfigParser()
temp.readfp(io.BytesIO(platform))
rsc['PLATFORM'] = temp.get('platform','Mission')[1:-1]
rsc['ANTENNA_LENGTH'] = temp.get('platform', 'Antenna Length')[1:-1]
rsc['ANTENNA_SIDE'] = temp.get('platform', 'Look Direction')[1:-1]
del temp
rsc['ORBIT_NUMBER'] = frame.ORBIT_NUMBER.text
rsc['STARTING_RANGE'] = frame.STARTING_RANGE.text
rsc['ONE_WAY_DELAY'] = None #Undefined
rsc['RANGE_PIXEL_SIZE'] = Cn.SPEED_OF_LIGHT
rsc['PRF'] = instrument.PRF.text
rsc['FILE_LENGTH'] = int(frame.NUMBER_OF_LINES.text)
rsc['WIDTH'] = int(frame.NUMBER_OF_SAMPLES.text)
rsc['YMIN'] = 0
rsc['YMAX'] = rsc['FILE_LENGTH']
rsc['XMIN'] = 0 #Assuming no prior header bytes
rsc['XMAX']= rsc['WIDTH']
rsc['RANGE_SAMPLING_FREQUENCY'] = instrument.RANGE_SAMPLING_RATE.text
#####Get planet desciption
planet = self.xml.planet
rsc['PLANET_GM'] = planet.GM.text
rsc['PLANET_SPINRATE'] = planet.SPINRATE.text
temp = sensstart - datetime.combine(sensstart.date(), time(0))
rsc['FIRST_LINE_UTC'] = temp.total_seconds()
temp = sensmid - datetime.combine(sensmid.date(), time(0))
rsc['CENTER_LINE_UTC'] = temp.total_seconds()
temp = sensstop - datetime.combine(sensstop.date(), time(0))
rsc['LAST_LINE_UTC'] = temp.total_seconds()
root1 = getattr(self.xml.runEstimateHeights, 'CHV_'+key)
rsc['HEIGHT'] = root1.outputs.HEIGHT.text
rsc['VELOCITY'] = root1.outputs.VELOCITY.text
rsc['HEIGHT_DT'] = None #Undefined
rsc['LATITUDE'] = None #Undefined
rsc['LONGITUDE'] = None #Undefined
rsc['EQUATORIAL_RADIUS'] = planet.ellipsoid.SEMIMAJOR_AXIS.text
rsc['ECCENTRICITY_SQUARED'] = planet.ellipsoid.ECCENTRICITY_SQUARED.text
rsc['EARTH_RADIUS'] = None
rsc['FILE_START'] = 1
rsc['WAVELENGTH'] = instrument.RADAR_WAVELENGTH.text
rsc['PULSE_LENGTH'] = instrument.RANGE_PULSE_DURATION.text
rsc['CHIRP_SLOPE'] = instrument.CHIRP_SLOPE.text
rsc['I_BIAS'] = root.iBias.text
rsc['Q_BIAS'] = root.qBias.text
rsc['DOPPLER_RANGE0'] = None
rsc['DOPPLER_RANGE1'] = None
rsc['DOPPLER_RANGE2'] = None
rsc['DOPPLER_RANGE3'] = None
rsc['SQUINT'] = None #Could be 0. never used
rsc['ROI_PAC_VERSION'] = 3
if write:
outfilename = root.sensor.OUTPUT + '.rsc'
fid = open(outfilename, 'w')
for kk, vv in rsc.iteritems():
fid.write('{0:<40} {1:<40}\n'.format(kk,vv))
fid.close()
return rsc
def slc_rsc(self, key=None, raw=None, write=False):
'''
Create rsc files for all the interferograms generated by ISCE.
'''
if key not in ['master', 'slave']:
raise ValueError('SLC files can only be written for master or slave.')
if raw is None:
rsc = self.raw_rsc(key=key, write=False)
else:
rsc = raw
root = getattr(self.xml, key)
rootslc = getattr(self.xml.runFormSLC, key)
#####Values that have changed.
rsc['RAW_DATA_RANGE'] = rsc['STARTING_RANGE']
rsc['STARTING_RANGE'] = rootslc.outputs.STARTING_RANGE.text
rsc['FILE_LENGTH'] = None #Needs to be output
rsc['WIDTH'] = int(rootslc.outputs.SLC_WIDTH.text)
rsc['XMIN'] = 0
rsc['XMAX'] = rsc['WIDTH']
rsc['YMIN'] = 0
rsc['YMAX'] = None
rsc['FIRST_LINE_UTC'] = None
rsc['CENTER_LINE_UTC'] = None
rsc['LAST_LINE_UTC'] = None
rsc['HEIGHT'] = rootslc.inputs.SPACECRAFT_HEIGHT.text
rsc['HEIGHT_DT'] = None
rsc['VELOCITY'] = rootslc.inputs.BODY_FIXED_VELOCITY.text
rsc['LATITUDE'] = None
rsc['LONGITUDE'] = None
#rsc['HEADING'] = float(self.xml.getpeg.outputs.PEG_HEADING)*180.0/np.pi
rsc['HEADING'] = None #Verify the source
rsc['EARTH_RADIUS'] = rootslc.inputs.PLANET_LOCAL_RADIUS.text
dop =ast.literal_eval(rootslc.inputs.DOPPLER_CENTROID_COEFFICIENTS.text)
rsc['DOPPLER_RANGE0'] = dop[0]
rsc['DOPPLER_RANGE1'] = None #Check units per meter / per pixel
rsc['DOPPLER_RANGE2'] = None
rsc['DOPPLER_RANGE3'] = None
rsc['DELTA_LINE_UTC'] = None
rsc['AZIMUTH_PIXEL_SIZE'] = None
rsc['RANGE_PIXEL_SIZE'] = None
rsc['RANGE_OFFSET'] = None
rsc['RLOOKS'] = 1
rsc['ALOOKS'] = 1
rsc['PEG_UTC'] = 1
rsc['HEIGHT_DS'] = None
rsc['HEIGHT_DDS'] = None
rsc['CROSSTRACK_POS'] = None
rsc['CROSSTRACK_POS_DS'] = None
rsc['CROSSTRACK_POS_DDS'] = None
rsc['VELOCITY_S'] = None
rsc['VELOCITY_C'] = None
rsc['VELOCITY_H'] = None
rsc['ACCELERATION_S'] = None
rsc['ACCELERATION_C'] = None
rsc['ACCELERATION_H'] = None
rsc['VERT_VELOCITY'] = None
rsc['VERT_VELOCITY_DS'] = None
rsc['CROSSTRACK_VELOCITY'] = None
rsc['CROSSTRACK_VELOCITY_DS'] = None
rsc['ALONGTRACK_VELOCITY'] = None
rsc['ALONGTRACK_VELOCITY_DS'] = None
rsc['PEG_UTC'] = None
rsc['SQUINT'] = None
if write:
outfilename = os.path.splitext(root.sensor.OUTPUT.text)[0]+'.slc.rsc'
fid = open(outfilename, 'w')
for kk, vv in rsc.iteritems():
fid.write('{0:<40} {1:<40}\n'.format(kk,vv))
fid.close()
if __name__ == '__main__':
'''Run the test on input xml file.'''
converter = insarProcXML()
master_raw_rsc = converter.raw_rsc(key='master', write=True)
slave_raw_rsc = converter.raw_rsc(key='slave', write=True)
master_slc_rsc = converter.slc_rsc(raw=master_raw_rsc, key='master', write=True)
slave_slc_rsc = converter.slc_rsc(raw=slave_raw_rsc, key='slave', write=True)

266
applications/PrepareStack.py Executable file
View File

@ -0,0 +1,266 @@
#!/usr/bin/env python3
from __future__ import print_function
import argparse
import isce
from make_raw import makeRawApp
import numpy as np
import os
import itertools
from isceobj.XmlUtil.XmlUtil import XmlUtil
from isceobj.Orbit.Orbit import Orbit, StateVector
from iscesys.StdOEL.StdOELPy import create_writer
#import sarxml
import stdproc
import datetime
stdWriter = create_writer("log", "", True, filename="prepareStack.log")
def pulseTiming(frame):
#From runPulseTiming() in InsarProc
numberOfLines = frame.getNumberOfLines()
prf = frame.getInstrument().getPulseRepetitionFrequency()
pri = 1.0 / prf
startTime = frame.getSensingStart()
orbit = frame.getOrbit()
pulseOrbit = Orbit()
startTimeUTC0 = (startTime - datetime.datetime(startTime.year,startTime.month,startTime.day))
timeVec = [pri*i + startTimeUTC0.seconds + 10**-6*startTimeUTC0.microseconds for i in xrange(numberOfLines)]
for i in range(numberOfLines):
dt = i * pri
time = startTime + datetime.timedelta(seconds=dt)
sv = orbit.interpolateOrbit(time, method='hermite')
pulseOrbit.addStateVector(sv)
return pulseOrbit
def getPeg(planet, orbit):
#Returns relevant peg point. From runSetMocompPath.py
objPeg = stdproc.createGetpeg()
objPeg.wireInputPort(name='planet', object=planet)
objPeg.wireInputPort(name='Orbit', object=orbit)
stdWriter.setFileTag("getpeg", "log")
stdWriter.setFileTag("getpeg", "err")
stdWriter.setFileTag("getpeg", "out")
# objSetmocomppath.setStdWriter(self._stdWriter)
objPeg.setStdWriter(stdWriter)
objPeg.estimatePeg()
return objPeg.getPeg(), objPeg.getAverageHeight()
class orbit_info:
def __init__(self, sar, fname):
'''Initialize with a sarProc object and corresponding XML file name'''
orbit = pulseTiming(sar.make_raw.frame)
tim, pos, vel, offset = orbit._unpackOrbit()
planet = sar.make_raw.planet
self.tim = tim
self.pos = pos
self.vel = vel
self.dt = sar.make_raw.frame.sensingMid
self.prf = sar.make_raw.doppler.prf
self.fd = sar.make_raw.dopplerValues() * self.prf
self.nvec = len(self.tim)
self.peg, self.hgt = getPeg(planet, orbit)
self.rds = self.peg.getRadiusOfCurvature()
self.rng = sar.make_raw.frame.startingRange
self.clook = None
self.slook = None
self.filename = fname
self.computeLookAngle()
def computeLookAngle(self):
self.clook = (2*self.hgt*self.rds+self.hgt**2+self.rng**2)/(2*self.rng*(self.rds+self.hgt))
self.slook = np.sqrt(1-self.clook**2)
# print('Estimated Look Angle: %3.2f degrees'%(np.arccos(self.clook)*180.0/np.pi))
def getBaseline(self, slave):
'''Compute baseline between current object and another orbit object.'''
ind = np.int(self.nvec/2)
mpos = np.array(self.pos[ind])
mvel = np.array(self.vel[ind])
#######From the ROI-PAC scripts
rvec = mpos/np.linalg.norm(mpos)
crp = np.cross(rvec, mvel)/np.linalg.norm(mvel)
crp = crp/np.linalg.norm(crp)
vvec = np.cross(crp, rvec)
mvel = np.linalg.norm(mvel)
ind = np.int(slave.nvec/2) #First guess
spos = np.array(slave.pos[ind])
svel = np.array(slave.vel[ind])
svel = np.linalg.norm(svel)
dx = spos - mpos;
z_offset = slave.prf*np.dot(dx, vvec)/mvel
ind = np.int(ind - z_offset) #Refined estimate
spos = slave.pos[ind]
svel = slave.vel[ind]
svel = np.linalg.norm(svel)
dx = spos-mpos
hb = np.dot(dx, crp)
vb = np.dot(dx, rvec)
csb = -1.0*hb*self.clook + vb*self.slook
# print('Estimated Baseline: %4.2f'%csb)
return csb
def parse():
# class RangeObj(object):
# '''Class to deal with input ranges.'''
# def __init__(self, start, end):
# self.start = start
# self.end = end
# def __eq__(self, other):
# return self.start <= other <= self.end
def Range(nmin, nmax):
class RangeObj(argparse.Action):
def __call__(self, parser, args, values, option_string=None):
if not nmin <= values <= nmax:
msg = 'Argument "{f}" requires value between {nmin} and {nmax}'.format(f=self.dest, nmin=nmin, nmax=nmax)
raise argparse.ArgumentTypeError(msg)
setattr(args, self.dest, values)
return RangeObj
#####Actual parser set up
parser = argparse.ArgumentParser(description='Computes the baseline plot for given set of SAR images.')
parser.add_argument('fnames', nargs='+', default=None, help = 'XML files corresponding to the SAR scenes.')
parser.add_argument('-Bcrit', dest='Bcrit', default=1200.0, help='Critical Geometric Baseline in meters [0., 10000.]', type=float, action=Range(0., 10000.))
parser.add_argument('-Tau', dest='Tau', default=1080.0, help='Temporal Decorrelation Time Constant in days [0., 3650.]', type=float, action=Range(0., 3650.))
parser.add_argument('-dop', dest='dop', default=0.5, help='Critical Doppler difference in fraction of PRF', type=float, action=Range(0., 1.))
parser.add_argument('-coh', dest='cThresh', default=0.3, help='Coherence Threshold to estimate viable interferograms. [0., 1.0]', type=float, action=Range(0., 1.))
parser.add_argument('-dir', dest='dirname', default='insar_XML', help='Directory in which the individual insar XML files are created.', type=str, action='store')
parser.add_argument('-base', dest='base', default='base.xml', help='Base XML for the insar.xml files.', type=str)
inps = parser.parse_args()
return inps
if __name__ == '__main__':
inps = parse()
nSar = len(inps.fnames)
print(inps.fnames)
print('Number of SAR Scenes = %d'%nSar)
Orbits = []
print('Reading in all the raw files and metadata.')
for k in xrange(nSar):
sar = makeRawApp()
sar.run(inps.fnames[k])
Orbits.append(orbit_info(sar, inps.fnames[k]))
##########We now have all the pegpoints to start processing.
Dopplers = np.zeros(nSar)
Bperp = np.zeros(nSar)
Days = np.zeros(nSar)
#######Setting the first scene as temporary reference.
master = Orbits[0]
Dopplers[0] = master.fd
Days[0] = master.dt.toordinal()
for k in xrange(1,nSar):
slave = Orbits[k]
Bperp[k] = master.getBaseline(slave)
Dopplers[k] = slave.fd
Days[k] = slave.dt.toordinal()
print("************************************")
print("Index Date Bperp Doppler")
print("************************************")
for k in xrange(nSar):
print('{0:>3} {1:>10} {2:4.2f} {3:4.2f}'.format(k+1, Orbits[k].dt.strftime('%Y-%m-%d'), Bperp[k],Dopplers[k]))
print("************************************")
geomRho = (1-np.clip(np.abs(Bperp[:,None]-Bperp[None,:])/inps.Bcrit, 0., 1.))
tempRho = np.exp(-1.0*np.abs(Days[:,None]-Days[None,:])/inps.Tau)
dopRho = (np.abs(Dopplers[:,None] - Dopplers[None,:])/ master.prf) < inps.dop
Rho = geomRho * tempRho * dopRho
for kk in xrange(nSar):
Rho[kk,kk] = 0.
avgRho = np.mean(Rho, axis=1)*nSar/(nSar-1)
numViable = np.sum((Rho> inps.cThresh), axis=1)
####Currently sorting on average coherence.
masterChoice = np.argsort(avgRho)
masterOrbit = Orbits[masterChoice[0]]
masterBperp = Bperp[masterChoice[0]]
print('*************************************')
print('Ranking for Master Scene Selection: ')
print('**************************************')
print('Rank Index Date nViable Avg. Coh.' )
for kk in xrange(nSar):
ind = masterChoice[kk]
print('{0:>3} {1:>3} {2:>10} {3:>4} {4:>2.3f}'.format(kk+1, ind+1, Orbits[ind].dt.strftime('%Y-%m-%d'), numViable[ind], avgRho[ind]))
print('***************************************')
print('***************************************')
print('List of Viable interferograms:')
print('***************************************')
# if not os.path.isdir(inps.dirname):
# try:
# os.mkdir(inps.dirname)
# except:
# raise OSError("%s Directory cannot be created"%(inps.dirname))
[ii,jj] = np.where(Rho > inps.cThresh)
print('Master Slave Bperp Deltat')
for mind, sind in itertools.izip(ii,jj):
master = Orbits[mind]
slave = Orbits[sind]
if master.dt > slave.dt:
print('{0:>10} {1:>10} {2:>4.2f} {3:>4.2f}'.format(master.dt.strftime('%Y-%m-%d'), slave.dt.strftime('%Y-%m-%d'), Bperp[mind]-Bperp[sind], Days[mind] - Days[sind]))
xmlname = '%s/insar_%s_%s.xml'%(inps.dirname, master.dt.strftime('%Y%m%d'), slave.dt.strftime('%Y%m%d'))
# sarxml.sartoinsarXML(master.filename, slave.filename, base=inps.base, out=xmlname)
print('***************************************')
#######Currently picks master peg point.
print('***************************************')
commonPeg = masterOrbit.peg
print('Common peg point: ')
print(commonPeg)
print('Bperp Range: [%f , %f] '%(Bperp.min()-masterBperp, Bperp.max()-masterBperp))
######Choose median doppler
commonDop = np.median(Dopplers)
maxDop = np.max(Dopplers)
minDop = np.min(Dopplers)
varDop = np.max(np.abs(Dopplers-commonDop))/masterOrbit.prf
print('Common Doppler: ', commonDop)
print('Doppler Range: [%f, %f]'%(minDop, maxDop))
print('MAx Doppler Variation = %f %%'%(varDop*100))
print('******************************************')

85
applications/SConscript Normal file
View File

@ -0,0 +1,85 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
import sys
Import('env')
envapplications = env.Clone()
package = 'applications'
envapplications['PACKAGE'] = package
envapplications['INSTALL_PATH'] = os.path.join(
envapplications['PRJ_SCONS_INSTALL'], package
)
Export('envapplications')
install = envapplications['INSTALL_PATH']
helpList,installHelp = envapplications['HELP_BUILDER'](envapplications,'__init__.py',install)
envapplications.Install(installHelp,helpList)
envapplications.Alias('install',installHelp)
listFiles = ['mdx.py',
# 'PrepareStack.py',
'insarApp.py',
'stripmapApp.py',
'topsApp.py',
# 'topsOffsetApp.py',
# 'xmlGenerator.py',
# 'dpmApp.py',
# 'CalculatePegPoint.py',
# 'calculateBaseline.py',
# 'extractHDROrbit.py',
# 'formSLC.py',
# 'viewMetadata.py',
'make_raw.py',
'__init__.py',
'isceApp.py',
'stitcher.py',
'dem.py',
'demdb.py',
'wbdStitcher.py',
'upsampleDem.py',
'iscehelp.py',
'imageMath.py',
'waterMask.py',
'looks.py',
'isce2gis.py',
'fixImageXml.py',
'isce2geotiff.py',
'dataTileManager.py',
'wbd.py',
'downsampleDEM.py',
'gdal2isce_xml.py',
'scansarApp.py']
# 'isce2he5.py']
envapplications.Install(install, listFiles)
envapplications.Alias('install', install)

46
applications/__init__.py Normal file
View File

@ -0,0 +1,46 @@
## The appications:
__all__ = ['CalculatePegPoint',
'calculateBaseline',
'createGeneric',
'dpmApp',
'extractHDROrbit',
'focus',
'formSLC',
'insarApp',
'isce.log',
'make_input',
'make_raw',
'mdx',
'readdb',
'viewMetadata',
'xmlGenerator']
def createInsar():
from .insarApp import Insar
return Insar()
def createStitcher():
from .stitcher import Stitcher
return Stitcher()
def createWbdStitcher():
from .wbdStitcher import Stitcher
return Stitcher()
def createDataTileManager():
from .dataTileManager import DataTileManager
return DataTileManager()
def getFactoriesInfo():
return {'Insar':
{
'factory':'createInsar'
},
'DemsStitcher':
{
'factory':'createStitcher'
},
'WbdsStitcher':
{
'factory':'createWbdStitcher'
},
'DataTileManager':
{
'factory':'createDataTileManager'
}
}

View File

@ -0,0 +1,85 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Walter Szeliga
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
import logging
import logging.config
logging.config.fileConfig(os.path.join(os.environ['ISCE_HOME'], 'defaults',
'logging', 'logging.conf'))
from iscesys.Compatibility import Compatibility
Compatibility.checkPythonVersion()
from iscesys.Component.FactoryInit import FactoryInit
from mroipac.baseline.Baseline import Baseline
class calculateBaselineApp(FactoryInit):
def main(self):
masterFrame = self.populateFrame(self.masterObj)
slaveFrame = self.populateFrame(self.slaveObj)
# Calculate the baseline information
baseline = Baseline()
baseline.wireInputPort(name='masterFrame',object=masterFrame)
baseline.wireInputPort(name='slaveFrame',object=slaveFrame)
baseline.wireInputPort(name='masterOrbit',object=masterFrame.getOrbit())
baseline.wireInputPort(name='slaveOrbit',object=slaveFrame.getOrbit())
baseline.wireInputPort(name='ellipsoid',object=masterFrame.getInstrument().getPlatform().getPlanet().get_elp())
baseline.baseline()
print(baseline)
def populateFrame(self,sensorObj):
# Parse the image metadata and extract the image
self.logger.info('Parsing image metadata')
sensorObj.parse()
frame = sensorObj.getFrame()
# Calculate the height, height_dt, and velocity
self.logger.info("Calculating Spacecraft Velocity")
frame.calculateHeightDt()
frame.calculateVelocity()
return frame
def __init__(self,arglist):
FactoryInit.__init__(self)
self.initFactory(arglist)
self.masterObj = self.getComponent('Master')
self.slaveObj = self.getComponent('Slave')
self.logger = logging.getLogger('isce.calculateBaseline')
if __name__ == "__main__":
import sys
if (len(sys.argv) < 2):
print("Usage:%s <xml-parameter file>" % sys.argv[0])
sys.exit(1)
runObj = calculateBaselineApp(sys.argv[1:])
runObj.main()

94
applications/createGeneric.py Executable file
View File

@ -0,0 +1,94 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Walter Szeliga
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
import logging
import logging.config
logging.config.fileConfig(os.path.join(os.environ['ISCE_HOME'], 'defaults',
'logging', 'logging.conf'))
import isceobj
from iscesys.Component.FactoryInit import FactoryInit
class ToGeneric(object):
# Convert from a satellite-specific format, to a generic HDF5-based format.
def __init__(self,rawObj=None):
self.rawObj = rawObj
self.logger = logging.getLogger('isce.toGeneric')
def convert(self):
from isceobj.Sensor.Generic import Generic
doppler = isceobj.Doppler.useDOPIQ()
hhRaw = self.make_raw(self.rawObj,doppler)
hhRaw.getFrame().getImage().createImage()
writer = Generic()
writer.frame = hhRaw.getFrame()
writer.write('test.h5',compression='gzip')
def make_raw(self,sensor,doppler):
"""
Extract the unfocused SAR image and associated data
@param sensor (\a isceobj.Sensor) the sensor object
@param doppler (\a isceobj.Doppler) the doppler object
@return (\a make_raw) a make_raw instance
"""
from make_raw import make_raw
import stdproc
import isceobj
# Extract raw image
self.logger.info("Creating Raw Image")
mr = make_raw()
mr.wireInputPort(name='sensor',object=sensor)
mr.wireInputPort(name='doppler',object=doppler)
mr.make_raw()
return mr
def main():
import sys
import isceobj
fi = FactoryInit()
fi.fileInit = sys.argv[1]
fi.defaultInitModule = 'InitFromXmlFile'
fi.initComponentFromFile()
master = fi.getComponent('Master')
toGeneric = ToGeneric(rawObj=master)
toGeneric.convert()
if __name__ == "__main__":
main()

166
applications/dataTileManager.py Executable file
View File

@ -0,0 +1,166 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import isce
import logging
import logging.config
from iscesys.Component.Application import Application
from iscesys.Component.Component import Component
import os
DATA_SOURCE = Component.Parameter('_dataSource',
public_name='dataSource',
default = '',
type = str,
mandatory = True,
doc = "Data source such as dem1 (3o m resolution), dem3 (90 m resolution) \n" +\
"or wbd for water body mask")
ACTION = Component.Parameter('_action',
public_name='action',
default = 'stitch',
type = str,
mandatory = False,
doc = "Action to be performed: stitch, download or stitchcorrect"
)
BBOX = Component.Parameter('_bbox',
public_name='bbox',
default = [],
container=list,
type = float,
mandatory = False,
doc = "Defines the spatial region in the format south north west east.\n" + \
"The values should be from (-90,90) for latitudes and (-180,180) for longitudes.")
PAIRS = Component.Parameter('_pairs',
public_name='pairs',
default = [],
container=list,
type = float,
mandatory = False,
doc = "Set of latitude and longitude pairs for which action = 'download' is performed.\n" +\
"The format is [lat0,lon0,lat1,lon1,...,latn,lonn ].\n" +\
"The values should be from (-90,90) for latitudes and (-180,180) for longitudes")
MANAGER = Application.Facility(
'_manager',
public_name='manager',
module='iscesys.DataManager',
factory='createManager',
mandatory=False,
args=(DATA_SOURCE,),
doc="Factory to instantiate the tile manager based on the DATA_SOURCE value"
)
class DataTileManager(Application):
def main(self):
if(self._action == 'stitch' or self._action == 'stitchcorrect'):
if(self._bbox):
lat = self._bbox[0:2]
lon = self._bbox[2:4]
if not(self.manager.stitch(lat,lon)):
print('Could not create a stitched file. Some tiles are missing')
if(self.action == 'stitchcorrect'):
self.manager.correct()
else:
print('Error. The bbox parameter must be specified when action is stitch')
raise ValueError
elif(self.action == 'download'):
if(self._bbox):
lat = self._bbox[0:2]
lon = self._bbox[2:4]
fromBounds = True
elif(self._pairs):
lat = self._pairs[::2]
lon = self._pairs[1::2]
fromBounds = False
if(not (self._bbox or self._pairs)):
print('Error. Either the bbox or the pairs parameters must be specified when action is download')
raise ValueError
self.manager.download(lat,lon,fromBounds)
else:
print('Unrecognized action',self._action)
return
def Usage(self):
print("\nUsage: dataTileManager.py input.xml\n")
print("NOTE: if you don't want to store your password in a file you can run it as\n" +\
"'dataTileManager.py input.xml dataTileManager.manager.username=yourUsername\n" +\
"dataTileManager.manager.password=yourPassword'\n\n" )
family = 'datatilemanager'
parameter_list = (
DATA_SOURCE,
ACTION,
PAIRS,
BBOX
)
facility_list = (MANAGER,)
@property
def manager(self):
return self._manager
@manager.setter
def manager(self,val):
self._manager = val
@property
def action(self):
return self._action
@action.setter
def action(self,val):
self._action = val
@property
def dataSource(self):
return self._dataSource
@dataSource.setter
def dataSource(self,val):
self._dataSource = val
@property
def pairs(self):
return self._pairs
@pairs.setter
def pairs(self,val):
self._pairs = val
@property
def bbox(self):
return self._bbox
@bbox.setter
def bbox(self,val):
self._bbox = val
def __init__(self,family = '', name = ''):
super(DataTileManager, self).__init__(family if family else self.__class__.family, name=name)
self._test = None
if __name__ == "__main__":
import sys
dt = DataTileManager()
dt.configure()
dt.run()

162
applications/dem.py Executable file
View File

@ -0,0 +1,162 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import isce
import sys
import os
import argparse
from contrib.demUtils import createDemStitcher
def main():
#if not argument provided force the --help flag
if(len(sys.argv) == 1):
sys.argv.append('-h')
# Use the epilog to add usage examples
epilog = 'Usage examples:\n\n'
epilog += 'Stitch (-a stitch) 1 arcsec dems (-s 1) in the bounding region 31 33 -114 -112 using the url (-u) and the log in credentials provided (-n,-w).\n'
epilog += 'Create a rsc metadata file (-m) and report the download results (-r)\n'
epilog += 'dem.py -a stitch -b 31 33 -114 -112 -s 1 -m rsc -r -n your_username -w your_password -u https://aria-alt-dav.jpl.nasa.gov/repository/products/SRTM1_v3/ \n\n'
epilog += 'Download (-a download) the 3 arcsec (-s 3) whose lat/lon are 31 -114 and 31 -115 (-p)\n'
epilog += 'dem.py -a download -p 31 -114 31 -115 -s 3 \n\n'
epilog += 'Stitch the requested files and apply EGM96 -> WGS84 correction (-c)\n'
epilog += 'dem.py -a stitch -b 31 33 -114 -113 -r -s 1 -c\n\n'
epilog += 'Download from bounding boxes (-b)\n'
epilog += 'dem.py -a download -b 31 33 -114 -113 -r -s 1\n\n'
epilog += 'Stitch the files in the local directory (-l) in the bounding region provided keeping the\n'
epilog += 'zip files after stitching (-k)\n'
epilog += 'dem.py -a stitch -b 31 33 -114 -113 -k -r -l -s 1\n\n'
#set the formatter_class=argparse.RawDescriptionHelpFormatter otherwise it splits the epilog lines with its own default format
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,epilog=epilog)
parser.add_argument('-a', '--action', type = str, default = 'stitch', dest = 'action', help = 'Possible actions: stitch or download (default: %(default)s). ')
parser.add_argument('-c', '--correct', action = 'store_true', dest = 'correct', help = 'Apply correction EGM96 -> WGS84 (default: %(default)s). The output metadata is in xml format only')
parser.add_argument('-m', '--meta', type = str, default = 'xml', dest = 'meta', help = 'What type of metadata file is created. Possible values: \
xml or rsc (default: %(default)s)')
parser.add_argument('-s', '--source', type = int, default = 1, dest = 'source', help = 'Dem SRTM source. Possible values 1 or 3 (default: %(default)s)')
parser.add_argument('-f', '--filling', action = 'store_true', dest = 'filling', help = 'Flag to instruct to fill missing Dems with null values \
(default null value -32768. Use -v or --filling_value option to change it)')
parser.add_argument('-v', '--filling_value', type = int, default = -32768, dest = 'fillingValue', help = 'Value used to fill missing Dems (default: %(default)s)')
parser.add_argument('-b', '--bbox', type = int, default = None, nargs = '+', dest = 'bbox', help = 'Defines the spatial region in the format south north west east.\
The values should be integers from (-90,90) for latitudes and (0,360) or (-180,180) for longitudes.')
parser.add_argument('-p', '--pairs', type = int, default = None, nargs = '+', dest = 'pairs', help = 'Set of latitude and longitude pairs for which --action = download is performed.\
The values should be integers from (-90,90) for latitudes and (0,360) or (-180,180) for longitudes')
parser.add_argument('-k', '--keep', action = 'store_true', dest = 'keep', help = 'If the option is present then the single files used for stitching are kept. If -l or --local is specified than the flag is automatically set (default: %(default)s)')
parser.add_argument('-r', '--report', action = 'store_true', dest = 'report', help = 'If the option is present then failed and succeeded downloads are printed (default: %(default)s)')
parser.add_argument('-l', '--local', action = 'store_true', dest = 'local', help = 'If the option is present then use the files that are in the location \
specified by --dir. If not present --dir indicates the directory where the files are downloaded (default: %(default)s)')
parser.add_argument('-d', '--dir', type = str, dest = 'dir', default = './', help = 'If used in conjunction with --local it specifies the location where the DEMs are located \
otherwise it specifies the directory where the DEMs are downloaded and the stitched DEM is generated (default: %(default)s)')
parser.add_argument('-o', '--output', type = str, dest = 'output', default = None, help = 'Name of the output file to be created in --dir. If not provided the system generates one based on the bbox extremes')
parser.add_argument('-n', '--uname', type = str, dest = 'uname', default = None, help = 'User name if using a server that requires authentication')
parser.add_argument('-w', '--password', type = str, dest = 'password', default = None, help = 'Password if using a server that requires authentication')
parser.add_argument('-t', '--type', type = str, dest = 'type', default = 'version3', help = \
'Use version 3 or version 2 SRTM')
parser.add_argument('-x', '--noextras', action = 'store_true', dest = 'noextras', help = 'Use this flag if the filenames do not have extra part')
parser.add_argument('-u', '--url', type = str, dest = 'url', default = None, help = \
'If --type=version2 then this is part of the url where the DEM files are located. The actual location must be' + \
'the one specified by --url plus /srtm/version2_1/SRTM(1,3).' \
+'If --type=version3 then it represents the full path url')
args = parser.parse_args()
#first get the url,uname and password since are needed in the constructor
ds = createDemStitcher(args.type)
ds.configure()
if(args.url):
if(args.type == 'version3'):
if(args.source == 1):
ds._url1 = args.url
elif(args.source == 3):
ds._url3 = args.url
else:
print('Unrecognized source')
raise ValueError
else:
ds.setUrl(args.url)
ds.setUsername(args.uname)
ds.setPassword(args.password)
ds._keepAfterFailed = True
#avoid to accidentally remove local file if -k is forgotten
#if one wants can remove them manually
if(args.local):
args.keep = True
if(args.meta == 'xml'):
ds.setCreateXmlMetadata(True)
elif(args.meta == 'rsc'):
ds.setCreateRscMetadata(True)
if(args.noextras):
ds._hasExtras = False
ds.setUseLocalDirectory(args.local)
ds.setFillingValue(args.fillingValue)
ds.setFilling() if args.filling else ds.setNoFilling()
if(args.action == 'stitch'):
if(args.bbox):
lat = args.bbox[0:2]
lon = args.bbox[2:4]
if (args.output is None):
args.output = ds.defaultName(args.bbox)
if not(ds.stitchDems(lat,lon,args.source,args.output,args.dir,keep=args.keep)):
print('Could not create a stitched DEM. Some tiles are missing')
else:
if(args.correct):
ds.correct()
#ds.correct(args.output,args.source,width,min(lat[0],lat[1]),min(lon[0],lon[1]))
else:
print('Error. The --bbox (or -b) option must be specified when --action stitch is used')
raise ValueError
elif(args.action == 'download'):
if(args.bbox):
lat = args.bbox[0:2]
lon = args.bbox[2:4]
ds.getDemsInBox(lat,lon,args.source,args.dir)
#can make the bbox and pairs mutually esclusive if replace the if below with elif
if(args.pairs):
ds.downloadFilesFromList(args.pairs[::2],args.pairs[1::2],args.source,args.dir)
if(not (args.bbox or args.pairs)):
print('Error. Either the --bbox (-b) or the --pairs (-p) options must be specified when --action download is used')
raise ValueError
else:
print('Unrecognized action -a or --action',args.action)
return
if(args.report):
for k,v in list(ds._downloadReport.items()):
print(k,'=',v)
if __name__ == '__main__':
sys.exit(main())

81
applications/demdb.py Executable file
View File

@ -0,0 +1,81 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2018 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Eric Gurrola
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import sys
import isce
from isceobj.InsarProc.createDem import createDem
from iscesys.DataManager import createManager
class INSAR:
def __init__(self, snwe):
# flag to control continuation of processing in the case that
# a dem is not available or cannot be downloaded. Obviously,
# this should be False for this application
self.proceedIfZeroDem = False
class SELF:
def __init__(me, snwe, hiresonly=False):
me.geocode_bbox = snwe
me.insar = INSAR(snwe)
me.demStitcher = createManager('dem1', 'iscestitcher')
# True indicates, to only download from high res server.
# False indicates, download high res dem if available,
# otherwise download from the low res server.
me.useHighResolutionDemOnly = hiresonly
class INFO:
def __init__(self, snwe):
self.extremes = snwe
def getExtremes(self, x):
return self.extremes
if __name__=="__main__":
if len(sys.argv) < 5:
print("Usage: demdb.py s n w e [h]")
print("where s, n, w, e are latitude, longitude bounds in degrees")
print("The optional 'h' flag indicates to only download a high res dem,"+
"if available.\n"
"If 'h' is not on the command line, then a low res dem will be "+
"downloaded,\nif the hi res is not available.")
sys.exit(0)
snwe = list(map(float,sys.argv[1:5]))
print("snwe = ", snwe)
if 'h' in sys.argv:
print("set hiresonly to True")
hiresonly = True
else:
hiresonly = False
self = SELF(snwe, hiresonly)
info = INFO(snwe)
createDem(self,info)

94
applications/downsampleDEM.py Executable file
View File

@ -0,0 +1,94 @@
#!/usr/bin/env python3
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2017 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: David Bekaert
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import sys
import argparse
import os
from osgeo import gdal
# command line parsing of input file
def cmdLineParse():
'''
Command line parser.
'''
parser = argparse.ArgumentParser(description='Generate down-sample DEM from wgs84.vrt DEM file')
parser.add_argument('-i','--input', dest='input_dem_vrt', type=str, required=True, help='Input DEM vrt filename (GDAL supported)')
parser.add_argument('-rmeter','--res_meter', dest='res_meter', type=str, default='', required=False, help='DEM output resolution in m units')
parser.add_argument('-rsec','--res_seconds', dest='res_seconds', type=str, default ='', required=False, help='DEM output resolution in arc seconds units')
return parser.parse_args()
# main script
if __name__ == '__main__':
'''
Main driver.
'''
# Parse command line
inps = cmdLineParse()
if inps.res_meter == '' and inps.res_seconds == '':
raise Exception('Provide either rmeter or rsec argument for DEM resolution')
# check if the input file exist
if not os.path.isfile(inps.input_dem_vrt):
raise Exception('Input file is not found ....')
# check if the provided input file is a .vrt file and also get the envi filename
input_dem_envi, file_extension = os.path.splitext(inps.input_dem_vrt)
if file_extension != '.vrt':
raise Exception('Input file is not a vrt file ....')
# get the file path
input_path = os.path.dirname(os.path.abspath(inps.input_dem_vrt))
# convert the output resolution from m in degrees
# (this is approximate, could use instead exact expression)
if inps.res_meter != '':
gdal_opts = gdal.WarpOptions(format='ENVI',outputType=gdal.GDT_Int16,dstSRS='EPSG:4326',xRes=float(inps.res_meter)/110/1000,yRes=float(inps.res_meter)/110/1000,targetAlignedPixels=True)
# res_degree = float(inps.res_meter)/110/1000
elif inps.res_seconds != '':
gdal_opts = gdal.WarpOptions(format='ENVI',outputType=gdal.GDT_Int16,dstSRS='EPSG:4326',xRes=float(inps.res_seconds)*1/60*1/60,yRes=float(inps.res_seconds)*1/60*1/60,targetAlignedPixels=True)
# res_degree = float(1/60*1/60*float(inps.res_seconds))
# The ENVI filename of the coarse DEM to be generated
coarse_dem_envi = os.path.join(input_path, "Coarse_" + input_dem_envi)
# Using gdal to down-sample the WGS84 DEM
# cmd = "gdalwarp -t_srs EPSG:4326 -ot Int16 -of ENVI -tap -tr " + str(res_degree) + " " + str(res_degree) + " " + inps.input_dem_vrt + " " + coarse_dem_envi
# os.system(cmd)
ds = gdal.Warp(coarse_dem_envi,inps.input_dem_vrt,options=gdal_opts)
ds = None
# Generating the ISCE xml and vrt of this coarse DEM
cmd = "gdal2isce_xml.py -i " + coarse_dem_envi
os.system(cmd)

644
applications/dpmApp.py Executable file
View File

@ -0,0 +1,644 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import print_function
import time
import os
import isce
import isceobj
import iscesys
from iscesys.Compatibility import Compatibility
from isceobj.Pause import pause
from iscesys.ImageUtil.ImageUtil import ImageUtil as IU
from iscesys.Component.Application import Application
from isce.applications.insarApp import _InsarBase, logger
class Dpm(_InsarBase):
"""Dpm Application class:
Implements Dpm processing flow for a pair of scenes from
sensor raw data to geocoded correlation.
"""
def __init__(self):
super(Dpm, self).__init__()
## This indicates something has gone wrong, I must delete geocode.
del self.runGeocode
## extends _InsarBase_steps, but not in the same was as main
def _steps(self):
super(Dpm, self)._steps()
# Geocode
self.step('geocodecorifg', func=self.geocodeCorIfg)
self.step('geocodecor4rlks', func=self.geocodeCor4rlks)
self.step('renderProcDoc', func=self.renderProcDoc)
self.step('timerend', local='timeEnd',func=time.time)
self.step('logtime', func=logger.info,
delayed_args = (" 'Total Time: %i seconds'%(timeEnd-timeStart)",)
)
return None
def renderProcDoc(self):
self.insar.procDoc.renderXml()
def coherence(self):
self.runCoherence(self.correlation_method)
self.renderProcDoc()
def geocodeCorIfg(self):
corFilename = self.insar.coherenceFilename
corintFilename = corFilename.replace('.cor','.corint')
widthInt = self.insar.resampIntImage.width
rmg_to_cmplx(corFilename,corintFilename,widthInt)
corintGeocodeFilename = corintFilename+'.geo'
demGeocodeFilename = corintFilename+'.demcrop'
geo = self.runGeocode(corintFilename,
widthInt,
corintGeocodeFilename,
demGeocodeFilename)
geoWidth = geo.computeGeoImageWidth()
print("geocodecor: widthGeo = ", geoWidth)
ifgGeocodeFilename = self.insar.geocodeFilename
demCropFilename = self.insar.demCropFilename
topoflatIntFilename = self.insar.topophaseFlatFilename
widthInt = self.insar.resampIntImage.width
geo = self.runGeocode(topoflatIntFilename,
widthInt,
ifgGeocodeFilename,
demCropFilename)
geoWidth = geo.computeGeoImageWidth()
print("geocodeifg: widthGeo = ", geoWidth)
corGeocodeFilename = corFilename + '.geo'
cmplx_to_rmg(corintGeocodeFilename, corGeocodeFilename, geoWidth)
self.geo_to_rsc(ifgGeocodeFilename, corGeocodeFilename)
return None
def geocodeCor4rlks(self):
corFilename = self.insar.coherenceFilename
corintFilename = corFilename.replace('.cor','.corint')
widthInt = self.insar.resampIntImage.width
#Not the right place for this block. Create the 4rlks correlation file and
# geocode it.
#~/Util/isce/components/mroipac/looks/Nbymhgt.py
# topophase.cor topophase_4rlks.cor 9480 4 4
cor4rlksFilename = corFilename.replace('.cor','_4rlks.cor')
from mroipac.looks.Nbymhgt import Nbymhgt
nbymh = Nbymhgt()
nbymh.inputImage = corFilename
nbymh.outputImage = cor4rlksFilename
nbymh.width = widthInt
nbymh.rangeLook = 4
nbymh.azimuthLook = 4
nbymh.nbymhgt()
width4rlksInt = widthInt/4
corint4rlksFilename = cor4rlksFilename.replace('.cor','.corint')
rmg_to_cmplx(cor4rlksFilename, corint4rlksFilename, width4rlksInt)
corint4rlksGeocodeFilename = corint4rlksFilename+'.geo'
dem4rlksGeocodeFilename = corint4rlksFilename+'.demcrop'
geo4rlks = self.runGeocode4rlks(corint4rlksFilename,
width4rlksInt,
corint4rlksGeocodeFilename,
dem4rlksGeocodeFilename)
geo4rlksWidth = geo4rlks.computeGeoImageWidth()
print("geocodecor: widthGeo = ", geo4rlksWidth)
cor4rlksGeocodeFilename = cor4rlksFilename + '.geo'
cmplx_to_rmg(corint4rlksGeocodeFilename, cor4rlksGeocodeFilename, geo4rlksWidth)
# self.geo_to_rsc(ifgGeocodeFilename,corGeocodeFilename)
return None
def geo_to_rsc(self, ifgGeoFile, corGeoFile):
from isceobj.XmlUtil.XmlUtil import XmlUtil
xmlDat = {'Coordinate1':{'size':None,'startingValue':None,'delta':None},
'Coordinate2':{'size':None,'startingValue':None,'delta':None}}
rscXML = {'WIDTH':('Coordinate1','size'),
'X_FIRST':('Coordinate1','startingValue'),
'X_STEP':('Coordinate1','delta'),
'FILE_LENGTH':('Coordinate2','size'),
'Y_FIRST':('Coordinate2','startingValue'),
'Y_STEP':('Coordinate2','delta')}
rscOrder = ('WIDTH','FILE_LENGTH','X_FIRST','X_STEP','Y_FIRST','Y_STEP')
ifgGeoXmlFile = ifgGeoFile + '.xml'
xu = XmlUtil()
xuf = xu.readFile(ifgGeoXmlFile)
c = xuf.findall('component')
for cx in c:
cxn = cx.attrib['name']
p = cx.findall('property')
for e in p:
xmlDat[cxn][e.attrib['name']] = e.findall('value')[0].text
corGeoRscFile = corGeoFile + '.rsc'
with open(corGeoRscFile,'w') as RSC:
spc = " "*25
for a in rscOrder:
RSC.write(
"%s%s%s\n" % (a,spc[0:25-len(a)],xmlDat[rscXML[a][0]][rscXML[a][1]])
)
return None
def runGeocode(self, inFilename, widthIn, geoFilename, demcropFilename):
import stdproc
from isceobj import createDemImage
print("runGeocode: inFilename, widthIn = ", inFilename, widthIn)
print("runGeocode: geoFilename, demcropFilename = ", geoFilename, demcropFilename)
logger.info("Geocoding Image")
# Initialize the Dem
demImage = createDemImage()
IU.copyAttributes(self.insar.demImage, demImage)
demImage.setAccessMode('read')
demImage.createImage()
# Initialize the flattened interferogram
from isceobj import createIntImage, createImage
intImage = createIntImage()
intImage.filename = inFilename
intImage.width = widthIn
intImage.setAccessMode('read')
intImage.createImage()
minLat, maxLat, minLon, maxLon = self.insar.topo.snwe
planet = self.insar.masterFrame.instrument.getPlatform().getPlanet()
objGeo = stdproc.createGeocode()
objGeo.listInputPorts()
objGeo.wireInputPort(name='peg',object=self.insar.peg)
objGeo.wireInputPort(name='frame',object=self.insar.masterFrame)
objGeo.wireInputPort(name='planet',object=planet)
objGeo.wireInputPort(name='dem',object=demImage)
objGeo.wireInputPort(name='interferogram',object=intImage)
objGeo.wireInputPort(name='geoPosting', object=self.geoPosting)
print("self.geoPosting = ", self.geoPosting)
objGeo.snwe = minLat, maxLat, minLon, maxLon
objGeo.geoFilename = geoFilename
objGeo.demCropFilename = demcropFilename
#set the tag used in the outfile. each message is precided by this tag
#is the writer is not of "file" type the call has no effect
objGeo.stdWriter = self.stdWriter.set_file_tags("geocode", "log", "err", "out")
# see mocompbaseline
objFormSlc1 = self.insar.formSLC1
mocompPosition1 = objFormSlc1.getMocompPosition()
posIndx = 1
objGeo.referenceOrbit = mocompPosition1[posIndx]
prf1 = self.insar.masterFrame.instrument.getPulseRepetitionFrequency()
dp = self.insar.dopplerCentroid.getDopplerCoefficients(inHz=False)[0]
v = self.insar.procVelocity
h = self.insar.averageHeight
objGeo.setDopplerCentroidConstantTerm(dp)
objGeo.setBodyFixedVelocity(v)
objGeo.setSpacecraftHeight(h)
objGeo.setNumberRangeLooks(self.insar.numberRangeLooks)
objGeo.setNumberAzimuthLooks(self.insar.numberAzimuthLooks)
# I have no idea what ismocomp means
goodLines = self.insar.numberValidPulses
patchSize = self.insar.patchSize
# this variable was hardcoded in geocode.f90 and was equal to (8192 - 2048)/2
is_mocomp = self.insar.is_mocomp
# is_mocomp = int((patchSize - goodLines)/2)
objGeo.setISMocomp(is_mocomp)
objGeo.geocode()
intImage.finalizeImage()
demImage.finalizeImage()
return objGeo
def runGeocode4rlks(self, inFilename, widthIn, geoFilename, demcropFilename):
import stdproc
from isceobj import createIntImage, createImage
print("runGeocode4rlks: inFilename, widthIn = ", inFilename, widthIn)
print("runGeocode4rlks: geoFilename, demcropFilename = ",
geoFilename,
demcropFilename)
pause(message="Paused in runGeocode4rlks")
logger.info("Geocoding Image")
# Initialize the Dem
from isceobj import createDemImage
demImage = createDemImage()
IU.copyAttributes(self.insar.demImage,demImage)
demImage.setAccessMode('read')
demImage.createImage()
print("demImage.firstLatitude = ", demImage.firstLatitude)
print("demImage.firstLongitude = ", demImage.firstLongitude)
print("demImage.deltaLatitude = ", demImage.deltaLatitude)
print("demImage.deltaLongitude = ", demImage.deltaLongitude)
print("demImage.width = ", demImage.width)
print("demImage.length = ", demImage.length)
demImage_lastLatitude = (
demImage.firstLatitude + (demImage.length-1)*demImage.deltaLatitude
)
demImage_lastLongitude = (
demImage.firstLongitude + (demImage.width-1)*demImage.deltaLongitude
)
print("demImage_lastLatitude = ", demImage_lastLatitude)
print("demImage_lastLongitude = ", demImage_lastLongitude)
# Initialize the input image
intImage = createIntImage()
intImage.setFilename(inFilename)
intImage.setWidth(widthIn)
intImage.setAccessMode('read')
intImage.createImage()
minLat, maxLat, minLon, maxLon = self.insar.topo.snwe
print("objTopo.minLat = ", minLat)
print("objTopo.minLon = ", minLon)
print("objTopo.maxLat = ", maxLat)
print("objTopo.maxLon = ", maxLon)
pause(message="Paused in runGeocode4rlks")
planet = self.insar.masterFrame.instrument.getPlatform().getPlanet()
objGeo = stdproc.createGeocode()
objGeo.listInputPorts()
objGeo.wireInputPort(name='peg',object=self.insar.peg)
# objGeo.wireInputPort(name='frame',object=self.insar.masterFrame)
objGeo.rangeFirstSample = self.insar.masterFrame.getStartingRange()
objGeo.slantRangePixelSpacing = self.insar.masterFrame.instrument.getRangePixelSize()*4
objGeo.prf = self.insar.masterFrame.instrument.getPulseRepetitionFrequency()
objGeo.radarWavelength = self.insar.masterFrame.instrument.getRadarWavelength()
objGeo.wireInputPort(name='planet',object=planet)
objGeo.wireInputPort(name='dem',object=demImage)
objGeo.wireInputPort(name='interferogram',object=intImage)
print("self.geoPosting = ",self.geoPosting)
objGeo.wireInputPort(name='geoPosting',object=self.geoPosting)
objGeo.snwe = minLat, maxLat, minLon, maxLon
objGeo.setGeocodeFilename(geoFilename)
objGeo.setDemCropFilename(demcropFilename)
#set the tag used in the outfile. each message is precided by this tag
#is the writer is not of "file" type the call has no effect
objGeo.stdWriter = self.stdWriter.set_file_tags("geocode", "log", "err", "out")
# see mocompbaseline
objFormSlc1 = self.insar.formSLC1
mocompPosition1 = objFormSlc1.getMocompPosition()
posIndx = 1
objGeo.setReferenceOrbit(mocompPosition1[posIndx])
prf1 = self.insar.masterFrame.instrument.getPulseRepetitionFrequency()
dp = self.insar.dopplerCentroid.getDopplerCoefficients(inHz=False)[0]
v = self.insar.procVelocity
h = self.insar.averageHeight
objGeo.setDopplerCentroidConstantTerm(dp)
objGeo.setBodyFixedVelocity(v)
objGeo.setSpacecraftHeight(h)
objGeo.setNumberRangeLooks(1.0) #self.insar.numberRangeLooks)
objGeo.setNumberAzimuthLooks(1.0) #self.insar.numberAzimuthLooks)
# I have no idea what ismocomp means
goodLines = self.insar.numberValidPulses
patchSize = self.insar.patchSize
# this variable was hardcoded in geocode.f90 and was equal to (8192 - 2048)/2
is_mocomp = self.insar.is_mocomp
# is_mocomp = int((patchSize - goodLines)/2)
objGeo.setISMocomp(is_mocomp)
objGeo.geocode()
print("Input state paraemters to gecode.f90:")
print("Minimum Latitude = ", objGeo.minimumLatitude)
print("Maximum Latitude = ", objGeo.maximumLatitude)
print("Minimum Longitude = ", objGeo.minimumLongitude)
print("Maximum Longitude = ", objGeo.maximumLongitude)
print("Ellipsoid Major Semi Axis = ", objGeo.ellipsoidMajorSemiAxis)
print("Ellipsoid Eccentricity Squared = ", objGeo.ellipsoidEccentricitySquared)
print("Peg Latitude = ", objGeo.pegLatitude)
print("Peg Longitude = ", objGeo.pegLongitude)
print("Peg Heading = ", objGeo.pegHeading)
print("Range Pixel Spacing = ", objGeo.slantRangePixelSpacing)
print("Range First Sample = ", objGeo.rangeFirstSample)
print("Spacecraft Height = ", objGeo.spacecraftHeight)
print("Planet Local Radius = ", objGeo.planetLocalRadius)
print("Body Fixed Velocity = ", objGeo.bodyFixedVelocity)
print("Doppler Centroid Constant Term = ", objGeo.dopplerCentroidConstantTerm)
print("PRF = ", objGeo.prf)
print("Radar Wavelength = ", objGeo.radarWavelength)
print("S Coordinate First Line = ", objGeo.sCoordinateFirstLine)
print("Azimuth Spacing = ", objGeo.azimuthSpacing)
print("First Latitude = ", objGeo.firstLatitude)
print("First Longitude = ", objGeo.firstLongitude)
print("Delta Latitude = ", objGeo.deltaLatitude)
print("Delta Longitude = ", objGeo.deltaLongitude)
print("Length = ", objGeo.length)
print("Width = ", objGeo.width)
print("Number Range Looks = ", objGeo.numberRangeLooks)
print("Number Azimuth Looks = ", objGeo.numberAzimuthLooks)
print("Number Points Per DEM Post = ", objGeo.numberPointsPerDemPost)
print("Is Mocomp = ", objGeo.isMocomp)
print("DEM Width = ", objGeo.demWidth)
print("DEM Length = ", objGeo.demLength)
# print("Reference Orbit = ", objGeo.referenceOrbit)
print("Dim1 Reference Orbit = ", objGeo.dim1_referenceOrbit)
intImage.finalizeImage()
demImage.finalizeImage()
return objGeo
def runGeocodeCor(self):
import stdproc
logger.info("Geocoding Correlation")
objFormSlc1 = self.insar.formSLC1
# Initialize the Dem
from isceobj import createDemImage, createIntImage, createImage
demImage = createDemImage()
IU.copyAttributes(self.insar.demImage,demImage)
demImage.setAccessMode('read')
demImage.createImage()
topoflatIntFilename = self.insar.topophaseFlatFilename
widthInt = self.insar.resampIntImage.width
intImage = createIntImage()
widthInt = self.insar.resampIntImage.width
intImage.setFilename(corintFilename)
intImage.setWidth(widthInt)
intImage.setAccessMode('read')
intImage.createImage()
posIndx = 1
mocompPosition1 = objFormSlc1.getMocompPosition()
minLat, maxLat, minLon, maxLon = self.insar.topo.snwe
planet = self.insar.masterFrame.instrument.getPlatform().getPlanet()
objGeo = stdproc.createGeocode()
objGeo.wireInputPort(name='peg',object=self.insar.peg)
objGeo.wireInputPort(name='frame',object=self.insar.masterFrame)
objGeo.wireInputPort(name='planet',object=planet)
objGeo.wireInputPort(name='dem',object=demImage)
objGeo.wireInputPort(name='interferogram',object=intImage)
objGeo.snwe = minLat, maxLat, minLon, maxLon
corGeocodeFilename = corintFilename+'.geo'
demGeocodeFilename = corintFilename+'.demcrop'
objGeo.setGeocodeFilename(corGeocodeFilename)
objGeo.setDemCropFilename(demGeocodeFilename)
#set the tag used in the outfile. each message is precided by this tag
#is the writer is not of "file" type the call has no effect
objGeo.stdWriter = self.stdWriter.set_file_tags("geocode", "log", "err", "out")
# see mocompbaseline
objGeo.setReferenceOrbit(mocompPosition1[posIndx])
prf1 = self.insar.masterFrame.instrument.getPulseRepetitionFrequency()
dp = self.insar.dopplerCentroid.getDopplerCoefficients(inHz=False)[0]
v = self.insar.procVelocity
h = self.insar.averageHeight
objGeo.setDopplerCentroidConstantTerm(dp)
objGeo.setBodyFixedVelocity(v)
objGeo.setSpacecraftHeight(h)
objGeo.setNumberRangeLooks(self.insar.numberRangeLooks)
objGeo.setNumberAzimuthLooks(self.insar.numberAzimuthLooks)
# I have no idea what ismocomp means
goodLines = self.insar.numberValidPulses
patchSize = self.insar.patchSize
# this variable was hardcoded in geocode.f90 and was equal to (8192 - 2048)/2
is_mocomp = int((patchSize - goodLines)/2)
objGeo.setISMocomp(is_mocomp)
objGeo.geocode()
intImage.finalizeImage()
demImage.finalizeImage()
return objGeo
def restart(self):
print("Restarting with Filtering")
return
## main() extends _InsarBase.main()
def main(self):
import time
timeStart = time.time()
super(Dpm, self).main()
# self.runCorrect()
self.runShadecpx2rg()
self.runRgoffset()
# Cull offoutliers
self.iterate_runOffoutliers()
self.runResamp_only()
self.insar.topoIntImage=self.insar.resampOnlyImage
self.runTopo()
self.runCorrect()
# Coherence ?
self.runCoherence(method=self.correlation_method)
#ouput the procDoc and pause in order to process coherence off line
#this processing should really be done using _steps.
self.insar.procDoc.renderXml()
pause(message="Paused in main")
# Filter ?
self.runFilter()
# Unwrap ?
self.verifyUnwrap()
# Geocode
self.geocodeCorIfg()
timeEnd = time.time()
logger.info("Total Time: %i seconds" %(timeEnd - timeStart))
self.insar.procDoc.renderXml()
return None
def rmgcor_ifgphs_to_cmplx(rmg,ifg,cpx,width):
import struct
import math
raise DeprecationWarning("Don't ude this function")
length = int(os.stat(ifg).st_size/8./width)
rmgFile = open(rmg,'rb')
ifgFile = open(ifg,'rb')
cpxFile = open(cpx,'wb')
w = int(width)
width2 = 2*w
fmt = "%df" % (width2,)
aCpxLine = [0.0]*width2
for iii in range(length):
anIfgLine = struct.unpack(fmt,ifgFile.read(width2*4))
aRmgLine = struct.unpack(fmt,rmgFile.read(width2*4))
for jjj in range(w):
ifgPhase = math.atan2(anIfgLine[2*jjj+1],anIfgLine[2*jjj])
# ampVal = aRmgLine[jjj]
corVal = aRmgLine[w+jjj]
aCpxLine[2*jjj] = corVal*math.cos(ifgPhase)
aCpxLine[2*jjj+1] = corVal*math.sin(ifgPhase)
cpxFile.write(struct.pack(fmt,*aCpxLine))
rmgFile.close()
ifgFile.close()
cpxFile.close()
return
def ifg1amp_ifg2amp_to_rmg(ifg1,ifg2,rmg,width):
import struct
import math
raise DeprecationWarning("Don't ude this function")
length = int(os.stat(ifg1).st_size/8./width)
ifg1File = open(ifg1,'rb')
ifg2File = open(ifg2,'rb')
rmgFile = open(rmg,'wb')
w = int(width)
width2 = 2*w
fmt = "%df" % (width2,)
aRmgLine = [0.0]*width2
for iii in range(length):
anIfg1Line = struct.unpack(fmt,ifg1File.read(width2*4))
anIfg2Line = struct.unpack(fmt,ifg2File.read(width2*4))
for jjj in range(w):
amp1 = math.sqrt(anIfg1Line[2*jjj]**2 + anIfg1Line[2*jjj+1]**2)
amp2 = math.sqrt(anIfg2Line[2*jjj]**2 + anIfg2Line[2*jjj+1]**2)
aRmgLine[jjj] = amp1
aRmgLine[w + jjj] = amp2
rmgFile.write(struct.pack(fmt,*aRmgLine))
ifg1File.close()
ifg2File.close()
rmgFile.close()
return
def rmg_to_cmplx(rmg,cpx,width):
import struct
import math
length = int(os.stat(rmg).st_size/8./width)
rmgFile = open(rmg,'rb')
cpxFile = open(cpx,'wb')
w = int(width)
width2 = 2*w
fmt = "%df" % (width2,)
aCpxLine = [0.0]*width2
for iii in range(length):
aRmgLine = struct.unpack(fmt,rmgFile.read(width2*4))
for jjj in range(w):
ampVal = aRmgLine[jjj]
corVal = aRmgLine[w+jjj]
aCpxLine[2*jjj] = ampVal
aCpxLine[2*jjj+1] = corVal
cpxFile.write(struct.pack(fmt,*aCpxLine))
rmgFile.close()
cpxFile.close()
return
def cmplx_to_rmg(ifg1,rmg,width):
import struct
import math
length = int(os.stat(ifg1).st_size/8./width)
ifg1File = open(ifg1,'rb')
rmgFile = open(rmg,'wb')
w = int(width)
width2 = 2*w
fmt = "%df" % (width2,)
aRmgLine = [0.0]*width2
for iii in range(length):
anIfg1Line = struct.unpack(fmt,ifg1File.read(width2*4))
for jjj in range(w):
amp1 = anIfg1Line[2*jjj]
amp2 = anIfg1Line[2*jjj+1]
aRmgLine[jjj] = amp1
aRmgLine[w + jjj] = amp2
rmgFile.write(struct.pack(fmt,*aRmgLine))
ifg1File.close()
rmgFile.close()
return
if __name__ == "__main__":
dpm = Dpm()
dpm.run()

72
applications/extractHDROrbit.py Executable file
View File

@ -0,0 +1,72 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Walter Szeliga
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
import datetime
import logging
import logging.config
logging.config.fileConfig(os.path.join(os.environ['ISCE_HOME'], 'defaults',
'logging', 'logging.conf'))
from iscesys.Compatibility import Compatibility
Compatibility.checkPythonVersion()
from iscesys.Component.FactoryInit import FactoryInit
class extractHDROrbit(FactoryInit):
def main(self):
# Parse the image metadata and extract the image
self.logger.info('Parsing image metadata')
self.sensorObj.parse()
frame = self.sensorObj.getFrame()
for sv in frame.getOrbit():
epoch = self.datetimeToEpoch(sv.getTime())
(x,y,z) = sv.getPosition()
(vx,vy,vz) = sv.getVelocity()
print(epoch,x,y,z,vx,vy,vz)
def datetimeToEpoch(self,dt):
epoch = dt.hour*60*60 + dt.minute*60 + dt.second
return epoch
def __init__(self,arglist):
FactoryInit.__init__(self)
self.initFactory(arglist)
self.sensorObj = self.getComponent('Sensor')
self.logger = logging.getLogger('isce.extractHDROrbits')
if __name__ == "__main__":
import sys
if (len(sys.argv) < 2):
print("Usage:%s <xml-parameter file>" % sys.argv[0])
sys.exit(1)
runObj = extractHDROrbit(sys.argv[1:])
runObj.main()

56
applications/fixImageXml.py Executable file
View File

@ -0,0 +1,56 @@
#!/usr/bin/env python3
import isce
import isceobj
import argparse
import os
def cmdLineParse():
'''
Command line parser.
'''
parser = argparse.ArgumentParser(description='Fixes pathnames in ISCE image XML files. Can be used to do more things in the future.')
parser.add_argument('-i', '--input', type=str, required=True, dest='infile',
help = 'Input image for which the XML file needs to be fixed.')
parser.add_argument('-f', '--full', action='store_true', default=False, dest='full',
help = 'Replace filename with full path including dir in which file is located')
parser.add_argument('-b', '--base', action='store_true', default=False, dest='base',
help = 'Replace filename with basename to use in current directory')
inps = parser.parse_args()
if (inps.full and inps.base):
raise Exception('User requested to use both full path and basename')
if (not inps.full) and (not inps.base):
raise Exception('User did not request any change')
return inps
if __name__ == '__main__':
'''
Main driver.
'''
from imageMath import IML
inps = cmdLineParse()
if inps.infile.endswith('.xml'):
inps.infile = os.path.splitext(inps.infile)[0]
dirname = os.path.dirname(inps.infile)
img, dataname, metaName = IML.loadImage(inps.infile)
if inps.full:
fname = os.path.abspath( os.path.join(dirname, os.path.basename(inps.infile)))
elif inps.base:
fname = os.path.basename( os.path.basename(inps.infile))
else:
raise Exception('Unknown state in {0}'.format(os.path.basename(__file__)))
img.filename = fname
img.setAccessMode('READ')
img.renderHdr()

328
applications/focus.py Executable file
View File

@ -0,0 +1,328 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Walter Szeliga
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
import math
import logging
import logging.config
logging.config.fileConfig(os.path.join(os.environ['ISCE_HOME'], 'defaults',
'logging', 'logging.conf'))
import isceobj
from iscesys.Component.FactoryInit import FactoryInit
from iscesys.DateTimeUtil.DateTimeUtil import DateTimeUtil as DTU
class Focuser(object):
def __init__(self,rawObj=None):
self.rawObj = rawObj
self.logger = logging.getLogger('isce.focus')
def focuser(self):
"""
Create a make_raw object and then focus it!
"""
doppler = isceobj.Doppler.useDOPIQ()
hhRaw = self.make_raw(self.rawObj,doppler)
fd = hhRaw.getDopplerValues().getDopplerCoefficients(inHz=False)
# Hard-wire the doppler for point-target analysis
# C-band point target Doppler
fd = [0.0163810952106773,-0.0000382864254695,0.0000000012335234,0.0]
# L-band point target Doppler
#fd = [0.0700103587387314, 0.0000030023105646, -0.0000000000629754, 0.0]
self.focus(hhRaw,fd)
def make_raw(self,sensor,doppler):
"""
Extract the unfocused SAR image and associated data
@param sensor (\a isceobj.Sensor) the sensor object
@param doppler (\a isceobj.Doppler) the doppler object
@return (\a make_raw) a make_raw instance
"""
from make_raw import make_raw
import stdproc
import isceobj
# Extract raw image
self.logger.info("Creating Raw Image")
mr = make_raw()
mr.wireInputPort(name='sensor',object=sensor)
mr.wireInputPort(name='doppler',object=doppler)
mr.make_raw()
return mr
def focus(self,mr,fd):
"""
Focus SAR data
@param mr (\a make_raw) a make_raw instance
@param fd (\a float) Doppler centroid for focusing
"""
import stdproc
import isceobj
#from isceobj.Sensor.Generic import Generic
# Extract some useful variables
frame = mr.getFrame()
orbit = frame.getOrbit()
planet = frame.getInstrument().getPlatform().getPlanet()
# Calculate Peg Point
self.logger.info("Calculating Peg Point")
peg = self.calculatePegPoint(frame,orbit,planet)
V,H = self.calculateProcessingVelocity(frame,peg)
# Interpolate orbit
self.logger.info("Interpolating Orbit")
pt = stdproc.createPulsetiming()
pt.wireInputPort(name='frame',object=frame)
pt.pulsetiming()
orbit = pt.getOrbit()
# Convert orbit to SCH coordinates
self.logger.info("Converting orbit reference frame")
o2s = stdproc.createOrbit2sch()
o2s.wireInputPort(name='planet',object=planet)
o2s.wireInputPort(name='orbit',object=orbit)
o2s.wireInputPort(name='peg',object=peg)
o2s.setAverageHeight(H)
o2s.orbit2sch()
# Create Raw Image
rawImage = isceobj.createRawImage()
filename = frame.getImage().getFilename()
bytesPerLine = frame.getImage().getXmax()
goodBytes = bytesPerLine - frame.getImage().getXmin()
rawImage.setAccessMode('read')
rawImage.setByteOrder(frame.getImage().byteOrder)
rawImage.setFilename(filename)
rawImage.setNumberGoodBytes(goodBytes)
rawImage.setWidth(bytesPerLine)
rawImage.setXmin(frame.getImage().getXmin())
rawImage.setXmax(bytesPerLine)
rawImage.createImage()
# Create SLC Image
slcImage = isceobj.createSlcImage()
rangeSamplingRate = frame.getInstrument().getRangeSamplingRate()
rangePulseDuration = frame.getInstrument().getPulseLength()
chirpSize = int(rangeSamplingRate*rangePulseDuration)
chirpExtension = 0 #0.5*chirpSize
numberRangeBins = int(goodBytes/2) - chirpSize + chirpExtension
slcImage.setFilename(filename.replace('.raw','.slc'))
slcImage.setByteOrder(frame.getImage().byteOrder)
slcImage.setAccessMode('write')
slcImage.setDataType('CFLOAT')
slcImage.setWidth(numberRangeBins)
slcImage.createImage()
# Calculate motion compenstation correction for Doppler centroid
self.logger.info("Correcting Doppler centroid for motion compensation")
fdmocomp = stdproc.createFdMocomp()
fdmocomp.wireInputPort(name='frame',object=frame)
fdmocomp.wireInputPort(name='peg',object=peg)
fdmocomp.wireInputPort(name='orbit',object=o2s.getOrbit())
fdmocomp.setWidth(numberRangeBins)
fdmocomp.setSatelliteHeight(H)
fdmocomp.setDopplerCoefficients([fd[0],0.0,0.0,0.0])
fdmocomp.fdmocomp()
fd[0] = fdmocomp.getDopplerCentroid()
self.logger.info("Updated Doppler centroid: %s" % (fd))
# Calculate the motion compensation Doppler centroid correction plus rate
#self.logger.info("Testing new Doppler code")
#frate = stdproc.createFRate()
#frate.wireInputPort(name='frame',object=frame)
#frate.wireInputPort(name='peg', object=peg)
#frate.wireInputPort(name='orbit',object=o2s.getOrbit())
#frate.wireInputPort(name='planet',object=planet)
#frate.setWidth(numberRangeBins)
#frate.frate()
#fd = frate.getDopplerCentroid()
#fdrate = frate.getDopplerRate()
#self.logger.info("Updated Doppler centroid and rate: %s %s" % (fd,fdrate))
synthetic_aperature_length = self._calculateSyntheticAperatureLength(frame,V)
patchSize = self.nextpow2(2*synthetic_aperature_length)
valid_az_samples = patchSize - synthetic_aperature_length
rawFileSize = rawImage.getLength()*rawImage.getWidth()
linelength = rawImage.getXmax()
overhead = patchSize - valid_az_samples
numPatches = (1+int((rawFileSize/float(linelength)-overhead)/valid_az_samples))
# Focus image
self.logger.info("Focusing image")
focus = stdproc.createFormSLC()
focus.wireInputPort(name='rawImage',object=rawImage)
focus.wireInputPort(name='slcImage',object=slcImage)
focus.wireInputPort(name='orbit',object=o2s.getOrbit())
focus.wireInputPort(name='frame',object=frame)
focus.wireInputPort(name='peg',object=peg)
focus.wireInputPort(name='planet',object=planet)
focus.setDebugFlag(96)
focus.setBodyFixedVelocity(V)
focus.setSpacecraftHeight(H)
focus.setAzimuthPatchSize(patchSize)
focus.setNumberValidPulses(valid_az_samples)
focus.setSecondaryRangeMigrationFlag('n')
focus.setNumberAzimuthLooks(1)
focus.setNumberPatches(numPatches)
focus.setDopplerCentroidCoefficients(fd)
#focus.setDopplerCentroidCoefficients([fd[0], 0.0, 0.0])
focus.formslc()
mocompPos = focus.getMocompPosition()
fp = open('position.sch','w')
for i in range(len(mocompPos[0])):
fp.write("%f %f\n" % (mocompPos[0][i],mocompPos[1][i]))
fp.close()
slcImage.finalizeImage()
rawImage.finalizeImage()
# Recreate the SLC image
slcImage = isceobj.createSlcImage()
slcImage.setFilename(filename.replace('.raw','.slc'))
slcImage.setAccessMode('read')
slcImage.setDataType('CFLOAT')
slcImage.setWidth(numberRangeBins)
slcImage.createImage()
width = int(slcImage.getWidth())
length = int(slcImage.getLength())
# Create a frame object and write it out using the Generic driver
frame.setImage(slcImage)
frame.setOrbit(o2s.getOrbit())
#writer = Generic()
#writer.frame = frame
#writer.write('test.h5',compression='gzip')
slcImage.finalizeImage()
self.width = width
self.length = length
def calculateProcessingVelocity(self,frame,peg):
"""
Calculate the optimal processing velocity and height from the orbit.
@param frame (\a isceobj.Scene.Frame) the Frame object describing the unfocused SAR data
@param peg (\a isceobj.Location.Peg) a Peg point object defining the origin of the SCH coordinate system
@return (\a tuple) the processing velocity and satellite height
"""
from isceobj.Location.SCH import SCH
orbit = frame.getOrbit()
ellipsoid = frame.getInstrument().getPlatform().getPlanet().get_elp()
# Get the mid point of the orbit
midxyz = orbit.interpolateOrbit(frame.getSensingMid())
midllh = ellipsoid.xyz_to_llh(midxyz.getPosition())
# Calculate the SCH S-velocity
sch = SCH(peg=peg)
midsch = sch.xyz_to_sch(midxyz.getPosition())
midvsch = sch.vxyz_to_vsch(midsch,midxyz.getVelocity())
self.logger.debug("XYZ Velocity: %s" % (midxyz.getVelocity()))
self.logger.debug("SCH Velocity: %s" % (midvsch))
H = midllh[2] # The height at midswath
V = midvsch[0] # SCH S-velocity at midswath
self.logger.debug("Satellite Height: %s" % (H))
return V,H
def calculatePegPoint(self,frame,orbit,planet):
"""
Calculate the peg point used as the origin of the SCH coordinate system during focusing.
@param frame (\a isceobj.Scene.Frame) the Frame object describing the unfocused SAR data
@param orbit (\a isceobj.Orbit.Orbit) the orbit along which to calculate the peg point
@param planet (\a isceobj.Planet.Planet) the planet around which the satellite is orbiting
@return (\a isceobj.Location.Peg) the peg point
"""
from isceobj.Location.Peg import PegFactory
from isceobj.Location.Coordinate import Coordinate
# First, get the orbit nadir location at mid-swath and the end of the scene
midxyz = orbit.interpolateOrbit(frame.getSensingMid())
endxyz = orbit.interpolateOrbit(frame.getSensingStop())
# Next, calculate the satellite heading from the mid-point to the end of the scene
ellipsoid = planet.get_elp()
midllh = ellipsoid.xyz_to_llh(midxyz.getPosition())
endllh = ellipsoid.xyz_to_llh(endxyz.getPosition())
heading = math.degrees(ellipsoid.geo_hdg(midllh,endllh))
# Then create a peg point from this data
coord = Coordinate(latitude=midllh[0],longitude=midllh[1],height=0.0)
peg = PegFactory.fromEllipsoid(coordinate=coord,heading=heading,ellipsoid=ellipsoid)
self.logger.debug("Peg Point: %s" % (peg))
return peg
def _calculateSyntheticAperatureLength(self,frame,v):
"""
Calculate the length of the synthetic aperature in pixels.
@param frame (\a isceobj.Scene.Frame) the Frame object describing the unfocussed SAR data
"""
wavelength = frame.getInstrument().getRadarWavelength()
prf = frame.getInstrument().getPulseRepetitionFrequency()
L = frame.getInstrument().getPlatform().getAntennaLength()
farRange = frame.getFarRange()
syntheticAperatureLength = int(round((wavelength*farRange*prf)/(L*v),0))
return syntheticAperatureLength
def nextpow2(self,v):
v = v-1
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v = v+1
return v
def main():
import sys
import isceobj
fi = FactoryInit()
fi.fileInit = sys.argv[1]
fi.defaultInitModule = 'InitFromXmlFile'
fi.initComponentFromFile()
master = fi.getComponent('Master')
focuser = Focuser(rawObj=master)
focuser.focuser()
if __name__ == "__main__":
main()

62
applications/formSLC.py Executable file
View File

@ -0,0 +1,62 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2011 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from iscesys.Compatibility import Compatibility
Compatibility.checkPythonVersion()
from iscesys.Component.FactoryInit import FactoryInit
class FormSLCApp(FactoryInit):
def main(self):
self.objFormSlc.formSLCImage(self.objRaw,self.objSlc)
print('second time')
self.objFormSlc.formSLCImage(self.objRaw,self.objSlc)
self.objSlc.finalizeImage()
self.objRaw.finalizeImage()
return
def __init__(self, arglist):
FactoryInit.__init__(self)
self.initFactory(arglist)
self.objSlc = self.getComponent('SlcImage')
self.objSlc.createImage()
self.objRaw = self.getComponent('RawImage')
self.objRaw.createImage()
self.objFormSlc = self.getComponent('FormSlc')
return
if __name__ == "__main__":
import sys
runObj = FormSLCApp(sys.argv[1:])
runObj.main()

119
applications/gdal2isce_xml.py Executable file
View File

@ -0,0 +1,119 @@
#!/usr/bin/env python3
#
# Author: Bekaert David
# Year: 2017
import isce
import isceobj
import sys
from osgeo import gdal
import argparse
import os
# command line parsing of input file
def cmdLineParse():
'''
Command line parser.
'''
parser = argparse.ArgumentParser(description='Generate ISCE xml from gdal products')
parser.add_argument('-i','--input', dest='fname', type=str, required=True, help='Input filename (GDAL supported)')
return parser.parse_args()
# main script
if __name__ == '__main__':
'''
Main driver.
'''
# Parse command line
inps = cmdLineParse()
# check if the input file exist
if not os.path.isfile(inps.fname):
raise Exception('Input file is not found ....')
# open the GDAL file and get typical data informationi
GDAL2ISCE_DATATYPE = {
1 : 'BYTE',
2 : 'uint16',
3 : 'SHORT',
4 : 'uint32',
5 : 'INT',
6 : 'FLOAT',
7 : 'DOUBLE',
10: 'CFLOAT',
11: 'complex128',
}
# GDAL2NUMPY_DATATYPE = {
# 1 : np.uint8,
# 2 : np.uint16,
# 3 : np.int16,
# 4 : np.uint32,
# 5 : np.int32,
# 6 : np.float32,
# 7 : np.float64,
# 10: np.complex64,
# 11: np.complex128,
# }
# check if the input file is a vrt
filename, file_extension = os.path.splitext(inps.fname)
print(file_extension)
if file_extension == ".vrt":
inps.outname = filename
else:
inps.outname = inps.fname
print(inps.outname)
# open the GDAL file and get typical data informationi
data = gdal.Open(inps.fname, gdal.GA_ReadOnly)
width = data.RasterXSize
length = data.RasterYSize
bands = data.RasterCount
# output to user
print("width: " + "\t" + str(width))
print("length: " + "\t" + str(length))
print("nof bands:" + "\t" + str(bands))
# getting the datatype information
raster = data.GetRasterBand(1)
dataTypeGdal = raster.DataType
# user look-up dictionary from gdal to isce format
dataType= GDAL2ISCE_DATATYPE[dataTypeGdal]
# output to user
print("dataType: " + "\t" + str(dataType))
# transformation contains gridcorners (lines/pixels or lonlat and the spacing 1/-1 or deltalon/deltalat)
transform = data.GetGeoTransform()
# if a complex data type, then create complex image
# if a real data type, then create a regular image
img = isceobj.createImage()
img.setFilename(os.path.abspath(inps.outname))
img.setWidth(width)
img.setLength(length)
img.setAccessMode('READ')
img.bands = bands
img.dataType = dataType
md = data.GetMetadata('IMAGE_STRUCTURE')
sch = md.get('INTERLEAVE', None)
if sch == 'LINE':
img.scheme = 'BIL'
elif sch == 'PIXEL':
img.scheme = 'BIP'
elif sch == 'BAND':
img.scheme = 'BSQ'
else:
print('Unrecognized interleaving scheme, ' + sch)
print('Assuming default, BIP')
img.scheme = 'BIP'
img.firstLongitude = transform[0]
img.firstLatitude = transform[3]
img.deltaLatitude = transform[5]
img.deltaLongitude = transform[1]
img.dump(inps.outname + ".xml")

445
applications/imageMath.py Executable file
View File

@ -0,0 +1,445 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2013 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Piyush Agram
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import argparse
import symtable
import math
import numpy as np
import os
import sys
import isce
from isceobj.Util.ImageUtil import ImageLib as IML
#####Global parameters
iMath = {
'outFile' : None, ####Output file name
'outBands' : [], ####List of out band mmaps
'outScheme' : 'BSQ', ####Output scheme
'equations' : [], #####List of math equations
'outType' : 'f', ####Output datatype
'width' : None, ####Width of images
'length' : None, ####Length of images
'inBands' : {}, ####Dictionary of input band mmaps
'inFiles' : {}, ####Dictionary input file mmaps
'bboxes' : [] ####Bounding boxes for input mmaps
}
helpStr = """
ISCE Band image with imageMath.py
Examples:
*********
1) imageMath.py -e='a*exp(-1.0*J*arg(b))' -o test.int -t cfloat --a=resampOnlyImage.int --b=topophase.mph
This uses phase from topophase.mph to correct topophase from the interferograms
2) imageMath.py -e='a_0;a_1' --a=resampOnlyImage.amp -o test.amp -s BIL
This converts a BIP image to a BIL image
3) imageMath.py -e="abs(a);sqrt(b_0**2 + b_1**2)" --a=topophase.flat --b="topophase.mph;3419;float;2;BIP" -o test.mag -s BIL
This should produce a BIL (RMG) image where both channels are equal. Input the correct width before testing this.
Rules:
******
0) Input math expressions should be valid python expressions.
1) A math expression for every band of output image is needed. For a multi-band output image, these expressions are separated by a ;.
Example: See Example 2 above.
2) All variable names in the math expressions need to be lower case, single character. Capital characters and multi-char names are reserved for constants and functions respectively.
3) The band of multi-band input images are represented by adding _i to the variable name, where "i" is the band number. All indices are zero-based (C and python).
Example : a_0 represents the first band of the image represented by variable "a".
4) For a single band image, the _0 band notation is optional.
Example: a_0 and a are equivalent for a single band image.
5) For every lower case variable in the equations, another input "--varname" is needed. Example shown above where --a and --b are defined.
6) Variables can be defined in two ways:
a) File name (assuming an ISCE .xml file also exists).
Example --a=resamp.int
b) Image grammar: "Filename;width;datatype;bands;scheme"
Example --a="resamp.int;3200;cfloat;1;BSQ"
- Default value for datatype=float
- Default value for bands = 1
- Default value for scheme = BSQ
c) In the image grammar: Single character codes for datatypes are case sensitive (Numpy convention) whereas multi-character codes are case-insensitive. Internally, everything is translated to numpy convention by the code before processing.
"""
class NumericStringParser(object):
'''
Parse the input expression using Python's inbuilt parser.
'''
def __init__(self, num_string):
'''
Create a parser object with input string.
'''
self.string = num_string
self._restricted = list(IML.fnDict.keys()) + list(IML.constDict.keys())
def parse(self):
'''
Parse the input expression to get list of identifiers.
'''
try:
symTable = symtable.symtable(self.string, 'string', 'eval')
except:
raise IOError('Not a valid python math expression \n' +
self.string)
idents = symTable.get_identifiers()
known = []
unknown = []
for ident in idents:
if ident not in self._restricted:
unknown.append(ident)
else:
known.append(ident)
for val in unknown:
band = val.split('_')[0]
if len(band)!=1:
raise IOError('Multi character variables in input expressions represent functions or constants. Unknown function or constant : %s'%(val))
elif (band.lower() != band):
raise IOError('Single character upper case letters are used for constant. No available constant named %s'%(val))
return unknown, known
#######Command line parsing
def detailedHelp():
'''
Return the detailed help message.
'''
msg = helpStr + '\n\n'+ \
'Available Functions \n' + \
'********************\n' + \
str(IML.fnDict.keys()) + '\n\n' + \
'Available Constants \n' + \
'********************\n' + \
str(IML.constDict.keys()) + '\n\n' + \
'Available DataTypes -> numpy code mapping \n' + \
'***************************************** \n'+ \
IML.printNUMPYMap() + '\n'
return msg
class customArgparseAction(argparse.Action):
def __call__(self, parser, args, values, option_string=None):
'''
The action to be performed.
'''
print(detailedHelp())
parser.print_help()
parser.exit()
def firstPassCommandLine():
'''
Take a first parse at command line parsing.
Read only the basic required fields
'''
#####Create the generic parser to get equation and output format first
parser = argparse.ArgumentParser(description='ISCE Band math calculator.',
formatter_class=IML.customArgparseFormatter)
# help_parser = subparser.add_
parser.add_argument('-H','--hh', nargs=0, action=customArgparseAction,
help='Display detailed help information.')
parser.add_argument('-e','--eval', type=str, required=True, action='store',
help='Expression to evaluate.', dest='equation')
parser.add_argument('-o','--out', type=str, default=None, action='store',
help='Name of the output file', dest='out')
parser.add_argument('-s','--scheme',type=str, default='BSQ', action='store',
help='Output file format.', dest='scheme')
parser.add_argument('-t','--type', type=str, default='float', action='store',
help='Output data type.', dest='dtype')
parser.add_argument('-d','--debug', action='store_true', default=False,
help='Print debugging statements', dest='debug')
parser.add_argument('-n','--noxml', action='store_true', default=False,
help='Do not create an ISCE XML file for the output.', dest='noxml')
#######Parse equation and output format first
args, files = parser.parse_known_args()
#####Check the output scheme for errors
if args.scheme.upper() not in ['BSQ', 'BIL', 'BIP']:
raise IOError('Unknown output scheme: %s'%(args.scheme))
iMath['outScheme'] = args.scheme.upper()
npType = IML.NUMPY_type(args.dtype)
iMath['outType'] = npType
return args, files
def parseInputFile(varname, args):
'''
Get the input string corresponding to given variable name.
'''
inarg = varname.strip()
####Keyname corresponds to specific
key = '--' + inarg
if len(varname.strip()) > 1:
raise IOError('Input variable names should be single characters.\n' +
'Invalid variable name: %s'%varname)
if (inarg != inarg.lower()):
raise IOError('Input variable names should be lower case. \n' +
'Invalud variable name: %s'%varname)
#####Create a simple parser
parser = IML.customArgumentParser(description='Parser for band math.',
add_help=False)
parser.add_argument(key, type=str, required=True, action='store',
help='Input string for a particular variable.', dest='instr')
try:
infile, rest = parser.parse_known_args(args)
except:
raise SyntaxError('Input file : "%s" not defined on command line'%varname)
return infile.instr, rest
def createNamespace():
'''
Hand utility if you want to use imageMath.py from within other python code.
'''
from argparse import Namespace
g = Namespace()
g.debug = False
g.dtype = 'float'
g.equation = None
g.hh = None
g.noxml = False
g.out = None
g.scheme = None
return g
def mergeBbox(inlist):
'''
Merge Bboxes of input files.
'''
if len(inlist) == 0 :
return None
ref = np.array(inlist[0])
diff = np.zeros((len(inlist), 4))
for ind in range(1, len(inlist)):
cand = np.array(inlist[ind])
diff[ind,: ] = cand - ref
diff = np.max(np.abs(diff), axis=0)
if np.any(diff > 1.0e-5):
print('Bounding boxes dont match. Not adding bbox info.')
return None
else:
return ref
#######The main driver that puts everything together
def main(args, files):
#######Set up logger appropriately
logger = IML.createLogger(args.debug, name='imageMath')
logger.debug('Known: '+ str(args))
logger.debug('Optional: '+ str(files))
#######Determine number of input and output bands
bandList = []
for ii,expr in enumerate(args.equation.split(';')):
#####Now parse the equation to get the file names used
nsp = NumericStringParser(expr.strip())
logger.debug('Input Expression: %d : %s'%(ii, expr))
bands, known = nsp.parse()
logger.debug('Unknown variables: ' + str(bands))
logger.debug('Known variables: ' + str(known))
iMath['equations'].append(expr)
bandList = bandList + bands
bandList = IML.uniqueList(bandList)
numOutBands = len(iMath['equations'])
logger.debug('Number of output bands = %d'%(numOutBands))
logger.debug('Number of input bands used = %d'%(len(bandList)))
logger.debug('Input bands used = ' + str(bandList))
#####Determine unique images from the bandList
fileList = IML.bandsToFiles(bandList, logger)
######Create input memmaps
for ii,infile in enumerate(fileList):
fstr, files = parseInputFile(infile, files)
logger.debug('Input string for File %d: %s: %s'%(ii, infile, fstr))
if len(fstr.split(';')) > 1:
fmap = IML.mmapFromStr(fstr, logger)
bbox = None
else:
fmap = IML.mmapFromISCE(fstr, logger)
bbox = IML.getGeoInfo(fstr)
iMath['inFiles'][infile] = fmap
if len(fmap.bands) == 1:
iMath['inBands'][infile] = fmap.bands[0]
for ii in range(len(fmap.bands)):
iMath['inBands']['%s_%d'%(infile, ii)] = fmap.bands[ii]
if bbox is not None:
iMath['bboxes'].append(bbox)
if len(files):
raise IOError('Unused input variables set:\n'+ ' '.join(files))
#######Some debugging
logger.debug('List of available bands: ' + str(iMath['inBands'].keys()))
####If used in calculator mode.
if len(bandList) == 0:
dataDict=dict(IML.fnDict.items() + IML.constDict.items())
logger.info('Calculator mode. No output files created')
for ii, equation in enumerate(iMath['equations']):
res=eval(expr, dataDict)
logger.info('Output Band %d : %f '%(ii, res))
sys.exit(0)
else:
if args.out is None:
raise IOError('Output file has not been defined.')
#####Check if all bands in bandList have been accounted for
for band in bandList:
if band not in iMath['inBands'].keys():
raise ValueError('Undefined band : %s '%(band))
######Check if all the widths match
widths = [img.width for var,img in iMath['inFiles'].items() ]
if len(widths) != widths.count(widths[0]):
logger.debug('Widths of images: ' +
str([(var, img.name, img.width) for var,img in iMath['inFiles'].items()]))
raise IOError('Input images are not of same width')
iMath['width'] = widths[0]
logger.debug('Output Width = %d'%(iMath['width']))
#######Check if all the lengths match
lengths=[img.length for var,img in iMath['inFiles'].items()]
if len(lengths) != lengths.count(lengths[0]):
logger.debug('Lengths of images: ' +
str([(var, img.name, img.length) for var,img in iMath['inFiles'].items()]))
raise IOError('Input images are not of the same length')
iMath['length'] = lengths[0]
logger.debug('Output Length = %d'%(iMath['length']))
#####Now create the output file
outmap = IML.memmap(args.out, mode='write', nchannels=numOutBands,
nxx=iMath['width'], nyy=iMath['length'], scheme=iMath['outScheme'],
dataType=iMath['outType'])
logger.debug('Creating output ISCE mmap with \n' +
'file = %s \n'%(args.out) +
'bands = %d \n'%(numOutBands) +
'width = %d \n'%(iMath['width']) +
'length = %d \n'%(iMath['length'])+
'scheme = %s \n'%(iMath['outScheme']) +
'dtype = %s \n'%(iMath['outType']))
iMath['outBands'] = outmap.bands
#####Start evaluating the expressions
####Set up the name space to use
dataDict=dict(IML.fnDict.items() | IML.constDict.items())
bands = iMath['inBands']
outBands = iMath['outBands']
####Array representing columns
dataDict['COL'] = np.arange(iMath['width'], dtype=np.float)
#####Replace ^ by **
for lineno in range(int(iMath['length'])):
####Setting row number
dataDict['ROW'] = lineno*1.0
####Load one line from each of the the bands
for band in bandList: #iMath['inBands'].iteritems():
dataDict[band] = bands[band][lineno,:]
####For each output band
for kk,expr in enumerate(iMath['equations']):
res = eval(expr, dataDict)
outBands[kk][lineno,:] = res
######Determine common bbox if any
outputBbox = mergeBbox(iMath['bboxes'])
######Render ISCE XML if needed
if not args.noxml:
IML.renderISCEXML(args.out, numOutBands,
iMath['length'], iMath['width'],
iMath['outType'], iMath['outScheme'],
bbox = outputBbox,
descr = ' '.join(sys.argv))
if __name__ == '__main__':
args, files = firstPassCommandLine()
print('args: ', args)
print('files: ', files)
main(args, files)

1207
applications/insarApp.py Executable file

File diff suppressed because it is too large Load Diff

120
applications/isce2geotiff.py Executable file
View File

@ -0,0 +1,120 @@
#!/usr/bin/env python3
import numpy as np
import os
import argparse
import tempfile
try:
from osgeo import gdal
gdal.UseExceptions()
except ImportError:
raise Exception('gdal python bindings are needed for this script to work.')
def cmdLineParse():
'''
Command line parser.
'''
parser = argparse.ArgumentParser(description='Generate graphics from ISCE products using gdal')
parser.add_argument('-i', dest='infile', type=str, required=True,
help='Input ISCE product file')
parser.add_argument('-o', dest='outfile', type=str, required=True,
help='Output GEOTIFF file')
parser.add_argument('-b', dest='band', type=int, default=0,
help='Band number to use if input image is multiband. Default: 0')
parser.add_argument('-c', dest='clim', type=float, nargs=2, required=True,
help='Color limits for the graphics')
parser.add_argument('-m', dest='cmap', type=str, default='jet',
help='Matplotlib colormap to use')
parser.add_argument('-t', dest='table', type=str, default=None,
help='Color table to use')
parser.add_argument('-n', dest='ncolors', type=int, default=64,
help='Number of colors')
inps = parser.parse_args()
if inps.table is not None:
if inps.reversemap:
raise Exception('Only matplotlib colormaps can be reversed')
return inps
def get_cmap(mapname, N, clim):
'''
Get the colormap from matplotlib.
'''
try:
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.cm as cmx
except ImportError:
raise Exception('Matplotlib is needed if user-defined color table is not provided.')
cmap = plt.get_cmap(mapname)
cNorm = colors.Normalize(vmin = clim[0], vmax = clim[1])
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=cmap)
vals = np.linspace(inps.clim[0], inps.clim[1], endpoint=True)
outname = mapname + '.cpt'
with open(outname, 'w') as fid:
for val in vals:
cval = scalarMap.to_rgba(val)
fid.write('{0} {1} {2} {3} \n'.format(val,int(cval[0]*255), int(cval[1]*255), int(cval[2]*255)))
fid.write('nv 0 0 0 0 \n')
return outname
if __name__ == '__main__':
'''
Main driver.
'''
#Parse command line
inps = cmdLineParse()
####Convert to a gdal format if not already done
try:
ds = gdal.Open(inps.infile)
ds = None
except:
cmd = 'isce2gis.py envi -i {0}'.format(inps.infile)
flag = os.system(cmd)
if flag:
raise Exception('Failed: {0}'.format(cmd))
####Set up the color table
if inps.table is None: ####No custom color map has been provided
cmap = get_cmap(inps.cmap, inps.ncolors, inps.clim)
plt_cmap = True
else:
cmap = table
plt_cmap = False
#####Build VRT
vrtname = inps.outfile+'.vrt'
if os.path.exists(vrtname):
print('VRT file already exists. Cleaning it ....')
os.remove(vrtname)
cmd = 'gdaldem color-relief {0} {1} {2} -alpha -b {3} -of VRT'.format(inps.infile, cmap, vrtname, inps.band+1)
flag = os.system(cmd)
if flag:
raise Exception('Failed: %s'%(cmd))
###Build geotiff
cmd = 'gdal_translate {0} {1}'.format(vrtname, inps.outfile)
flag = os.system(cmd)
if flag:
raise Exception('Failed: %s'%(cmd))

151
applications/isce2gis.py Executable file
View File

@ -0,0 +1,151 @@
#!/usr/bin/env python3
import isce
import isceobj
import argparse
import os
import xml.etree.ElementTree as ET
from imageMath import IML
def cmdLineParse():
'''
Command line parser.
'''
parser = argparse.ArgumentParser(description='Export ISCE products directly to ENVI / VRT formats')
subparsers = parser.add_subparsers(help='Output format options', dest='fmt')
vrtparser = subparsers.add_parser( 'vrt', help='Export with VRT file')
vrtparser.add_argument('-i', '--input', dest='infile', type=str, required=True,
help='ISCE product file to export')
vrtparser.add_argument('--lat', dest='latvrt', type=str, default=None,
help='Location of the latitude file')
vrtparser.add_argument('--lon', dest='lonvrt', type=str, default=None,
help='Location of the longitude file')
enviparser = subparsers.add_parser('envi', help='Export with ENVI hdr file')
enviparser.add_argument('-i', '--input', dest='infile', type=str, required=True,
help='ISCE product file to export')
vals = parser.parse_args()
# print(vals)
return vals
def isce2envi(inname):
'''
Create ENVI hdr for ISCSE product.
'''
img, dataname, metaname = IML.loadImage(inname)
img.renderEnviHDR()
return
def isce2vrt(inname):
'''
Create VRT for ISCE product.
'''
img, dataname, metaname = IML.loadImage(inname)
img.renderVRT()
return
def getVRTinfo(inname):
'''
Verify if the lat / lon VRT info is appropriate.
'''
tree = ET.parse(inname.strip() + '.vrt')
root = tree.getroot()
width = int(root.attrib['rasterXSize'])
length = int(root.attrib['rasterYSize'])
bands = len(root.find('VRTRasterBand'))
if bands != 1:
raise Exception('%s is not a one band image'%(inname+'.vrt'))
return (width, length)
if __name__ == '__main__':
'''
Main driver.
'''
inps = cmdLineParse()
if inps.fmt == 'envi':
isce2envi(inps.infile)
elif inps.fmt == 'vrt':
if (inps.latvrt is None) or (inps.lonvrt is None):
isce2vrt(inps.infile)
else:
# latf = inps.latvrt + '.vrt'
# if not os.path.exists(latf):
isce2vrt(inps.latvrt)
# lonf = inps.lonvrt + '.vrt'
# if not os.path.exists(lonf):
isce2vrt(inps.lonvrt)
latimg, dummy, dummy = IML.loadImage(inps.latvrt)
latwid = latimg.getWidth()
latlgt = latimg.getLength()
if latimg.getBands() != 1:
raise Exception('Latitude image should be single band')
lonimg, dummy, dummy = IML.loadImage(inps.lonvrt)
lonwid = lonimg.getWidth()
lonlgt = lonimg.getLength()
if lonimg.getBands() != 1:
raise Exception('Longitude image should be single band')
img = isceobj.createImage()
img.load(inps.infile + '.xml')
wid = img.getWidth()
lgt = img.getLength()
if any([(latwid - wid) != 0, (lonwid - wid) != 0]):
raise Exception('Widths of image, lat and lon files dont match')
if any([(latlgt - lgt) != 0, (lonlgt - lgt) != 0]):
raise Exception('Lengths of image, lat and lon files dont match')
####Create prelim XML
isce2vrt(inps.infile)
tree = ET.parse(inps.infile + '.vrt')
root = tree.getroot()
meta = ET.SubElement(root, 'metadata')
meta.attrib['domain'] = "GEOLOCATION"
meta.tail = '\n'
meta.text = '\n '
rdict = { 'Y_DATASET' : os.path.relpath(inps.latvrt + '.vrt', os.path.dirname(inps.infile)),
'X_DATASET' : os.path.relpath(inps.lonvrt + '.vrt', os.path.dirname(inps.infile)),
'X_BAND' : "1",
'Y_BAND' : "1",
'PIXEL_OFFSET': "0",
'LINE_OFFSET' : "0",
'LINE_STEP' : "1",
'PIXEL_STEP' : "1" }
for key, val in rdict.items():
data = ET.SubElement(meta, 'mdi')
data.text = val
data.attrib['key'] = key
data.tail = '\n '
data.tail = '\n'
tree.write(inps.infile + '.vrt')

1796
applications/isceApp.py Executable file

File diff suppressed because it is too large Load Diff

559
applications/iscehelp.py Executable file
View File

@ -0,0 +1,559 @@
#!/usr/bin/env python3
#Author:Giangi Sacco
#Copyright 2009-2014, by the California Institute of Technology.
import isce
import os
import sys
import json
import argparse
import collections
import importlib
from iscesys.DictUtils.DictUtils import DictUtils as DU
class Helper(object):
def getRegistered(self):
#Register all the factory that want to provide help
#Each .hlp file has a json structure like
'''
{TypeName
{'args':
{
#positional arguments have as key the position in str format
#since json only allows keys to be string
'0':{'value':values,'type':type},
'1':{'value':values,'type':type}
#keyword arguments have the name of the argument as key
argname:{'value':values,'type':type,'optional':bool,'default':default}
},
'factory':factory,
'package':package,
}
}
'''
registered = {}
helplist = os.listdir(self._helpDir)
for name in helplist:
fullname = os.path.join(self._helpDir,name)
if not name.endswith('.hlp'):
continue
with open(fullname) as fp:
registered.update(json.load(fp))
return collections.OrderedDict(sorted(registered.items()))
def getTypeFromFactory(self,factory):
instanceType = 'N/A'
for k,v in self._registered.items():
if v['factory'] == factory:
instanceType = k
break
return instanceType
def getInstance(self,typeobj):
obj2help = self._registered[typeobj]
args,kwargs = self.getPosAndKwArgs(obj2help)
factory = getattr(importlib.import_module(obj2help['package']),obj2help['factory'])
return factory(*args,**kwargs)
def convert(self,value,type_):
try:
module = importlib.import_module('builtins')
ret = getattr(module,type_)(value)
except:
print("Cannot convert",value,"to a type",type_)
raise Exception
return ret
def askHelp(self, instance, steps=False):
#since it can be called externally, make sure that we remove the
#arguments that are not understood by the isce Parser
try:
sys.argv = [sys.argv[0]]
instance._parameters()
instance.initProperties({})
instance._init()
instance._facilities()
instance._dictionaryOfFacilities = DU.renormalizeKeys(instance._dictionaryOfFacilities)
self.helper(instance, steps)
except Exception as e:
print("No help available.")
def getPosAndKwArgs(self,obj):
args = []
kwargs = {}
if self._inputs.args:#otherwise no args present
for arg,i in zip(self._inputs.args,range(len(self._inputs.args))):
try:
#positional argument
args.append(self.convert(arg,obj['args'][str(i)]['type']))
except Exception as e:
try:
kw,val = arg.split("=")
kwargs[kw] = self.convert(val,obj['args'][kw]['type'])
except Exception as e:
print(e)
raise
return (args,kwargs)
def step_help(self, instance):
instance.help_steps()
instance._add_methods()
instance._steps()
print()
print("Command line options for steps processing are formed by")
print("combining the following three options as required:\n")
print("'--start=<step>', '--end=<step>', '--dostep=<step>'\n")
print("The step names are chosen from the following list:")
print()
npl = 5
nfl = int(len(instance.step_list_help)/npl)
for i in range(nfl):
print(instance.step_list[i*npl:(i+1)*npl])
if len(instance.step_list) % npl:
print(instance.step_list[nfl*npl:])
print()
print("If --start is missing, then processing starts at the "+
"first step.")
print("If --end is missing, then processing ends at the final "+
"step.")
print("If --dostep is used, then only the named step is "+
"processed.")
print()
print("In order to use either --start or --dostep, it is "+
"necessary that a")
print("previous run was done using one of the steps options "+
"to process at least")
print("through the step immediately preceding the starting "+
"step of the current run.")
print()
sys.exit(0)
def helper(self,instance,steps=False):
#if facility is None we print the top level so the recursion ends right away
#if facility is defined (not None) and is not part of the facilities
# then keep going down the tree structure
instance.help()
print()
try:
try:
#only applications have it
instance.Usage()
except Exception:
pass
print()
if steps:
self.step_help(instance)
sys.exit(0)
except Exception as x:
sys.exit(0)
finally:
pass
#sometime there is no help available. Postpone the printing until
#there is something to print for sure
fullMessage = ""
fullMessage = "\nSee the table of configurable parameters listed \n"
fullMessage += "below for a list of parameters that may be specified in the\n"
fullMessage += "input file. See example input xml files in the isce 'examples'\n"
fullMessage += "directory. Read about the input file in the ISCE.pdf document.\n"
# maxname = max(len(n) for n in self.dictionaryOfVariables.keys())
# maxtype = max(len(str(x[1])) for x in self.dictionaryOfVariables.values())
# maxman = max(len(str(x[2])) for x in self.dictionaryOfVariables.values())
# maxdoc = max(len(x) for x in self.descriptionOfVariables.values())
maxname = 27
maxtype = 10
maxman = 10
maxdoc = 30
underman = "="*maxman
undertype = "="*maxtype
undername = "="*maxname
underdoc = "="*maxdoc
spc = " "
n = 1
spc0 = spc*n
fullMessage += "\nThe user configurable inputs are given in the following table.\n"
fullMessage += "Those inputs that are of type 'component' are also listed in\n"
fullMessage += "table of facilities below with additional information.\n"
fullMessage += "To configure the parameters, enter the desired value in the\n"
fullMessage += "input file using a property tag with name = to the name\n"
fullMessage += "given in the table.\n"
line = "name".ljust(maxname,' ')+spc0+"type".ljust(maxtype,' ')
line += spc0+"mandatory".ljust(maxman,' ')+spc0+"doc".ljust(maxdoc,' ')
fullMessage += line + '\n'
line = undername+spc0+undertype+spc0+underman+spc0+underdoc
fullMessage += line + '\n'
#make sure that there is something to print
shallPrint = False
instance.reformatDictionaryOfVariables()
for x, y in collections.OrderedDict(sorted(instance.dictionaryOfVariables.items())).items():
#skip the mandatory private. Those are parameters of Facilities that
#are only used by the framework and the user should not know about
if y['mandatory'] and y['private']:
continue
if x in instance.descriptionOfVariables:
z = instance.descriptionOfVariables[x]['doc']
elif x in instance._dictionaryOfFacilities and 'doc' in instance._dictionaryOfFacilities[x]:
z = instance._dictionaryOfFacilities[x]['doc']
else:
z = 'N/A'
shallPrint = True
try:
yt = str(y['type']).split("'")[1]
except:
yt = str(y['type'])
lines = []
self.cont_string = ''
lines.append(self.columnate_words(x, maxname, self.cont_string))
lines.append(self.columnate_words(yt, maxtype, self.cont_string))
lines.append(self.columnate_words(str(y['mandatory']), maxman, self.cont_string))
lines.append(self.columnate_words(z, maxdoc, self.cont_string))
nlines = max(map(len,lines))
for row in lines:
row += [' ']*(nlines-len(row))
for ll in range(nlines):
fullMessage += lines[0][ll].ljust(maxname,' ')
fullMessage += spc0+lines[1][ll].ljust(maxtype,' ')
fullMessage += spc0+lines[2][ll].ljust(maxman,' ')
fullMessage += spc0+lines[3][ll].ljust(maxdoc,' ') + '\n'
# line = spc0+x.ljust(maxname)+spc0+yt.ljust(maxtype)
# line += spc0+y[2].ljust(maxman)+spc0+z.ljust(maxdoc)
# print(line)
if(shallPrint):
print(fullMessage)
else:
print("No help available\n")
#only print the following if there are facilities
if(instance._dictionaryOfFacilities.keys()):
#maxname = max(len(n) for n in self._dictionaryOfFacilities.keys())
maxname = 20
undername = "="*maxname
# maxmod = max(
# len(x['factorymodule']) for x in
# self._dictionaryOfFacilities.values()
# )
maxmod = 15
undermod = "="*maxmod
# maxfac = max(
# len(x['factoryname']) for x in
# self._dictionaryOfFacilities.values()
# )
maxfac = 17
underfac = "="*maxfac
# maxarg = max(
# len(str(x['args'])) for x in self._dictionaryOfFacilities.values()
# )
maxarg = 20
underarg = "="*maxarg
# maxkwa = max(
# len(str(x['kwargs'])) for x in
# self._dictionaryOfFacilities.values()
# )
maxkwa = 7
# underkwa = "="*max(maxkwa, 6)
underkwa = "="*maxkwa
spc = " "
n = 1
spc0 = spc*n
firstTime = True
for x, y in collections.OrderedDict(sorted(instance._dictionaryOfFacilities.items())).items():
#skip the mandatory private. Those are parameters of Facilities that
#are only used by the framework and the user should not know about
if y['mandatory'] and y['private']:
continue
#only print if there is something
if firstTime:
firstTime = False
print()
print("The configurable facilities are given in the following table.")
print("Enter the component parameter values for any of these "+
"facilities in the")
print("input file using a component tag with name = to "+
"the name given in")
print("the table. The configurable parameters for a facility "+
"are entered with ")
print("property tags inside the component tag. Examples of the "+
"configurable")
print("parameters are available in the examples/inputs directory.")
print("For more help on a given facility run")
print("iscehelp.py -t type")
print("where type (if available) is the second entry in the table")
print()
line = "name".ljust(maxname)+spc0+"type".ljust(maxmod)
print(line)
line = " ".ljust(maxname)+spc0+" ".ljust(maxmod)
print(line)
line = undername+spc0+undermod
print(line)
lines = []
self.cont_string = ''
lines.append(self.columnate_words(x, maxname, self.cont_string))
z = self.columnate_words(self.getTypeFromFactory(y['factoryname']),maxmod, self.cont_string)
lines.append(z)
nlines = max(map(len,lines))
for row in lines:
row += [' ']*(nlines-len(row))
for ll in range(nlines):
out = lines[0][ll].ljust(maxname)
out += spc0+lines[1][ll].ljust(maxmod)
print(out)
# line = spc0+x.ljust(maxname)+spc0+y['factorymodule'].ljust(maxmod)
# line += spc0+y['factoryname'].ljust(maxfac)
# line += spc0+str(y['args']).ljust(maxarg)
# line += spc0+str(y['kwargs']).ljust(maxkwa)
# print(line)
return sys.exit(1)
def columnate_words(self, s, n, cont='',onePerLine=False):
"""
arguments = s (str), n (int), [cont (str)]
s is a sentence
n is the column width
Returns an array of strings of width <= n.
If any word is longer than n, then the word is split with
continuation character cont at the end of each column
"""
#Split the string s into a list of words
a = s.split()
#Check the first word as to whether it fits in n columns
if a:
if len(a[0]) > n:
y = [x for x in self.nsplit(a[0]+" ", n, cont)]
else:
y = [a[0]]
cnt = len(y[-1])
for i in range(1, len(a)):
cnt += len(a[i])+1
if cnt <= n:
if not onePerLine:
y[-1] += " "+a[i]
else:
y.append(a[i])
else:
y += self.nsplit(a[i], n, cont)
if not onePerLine:
cnt = len(y[-1])
else:
cnt = n+1
else:
y = ['']
return y
def nsplit(self, s, nc, cont=''):
x = []
ns = len(s)
n = nc - len(cont)
for i in range(int(ns/n)):
x.append(s[i*n:(i+1)*n]+cont)
if ns%n:
x.append(s[int(ns/n)*n:])
return x
def typeNeedsNoArgs(self,type_):
try:
ret = False
for k,v in self._registered[type_]['args'].items():
#it's positional so it need the args
if k.isdigit():
ret = True
break
elif (not 'optional' in v) or (not ('optional' in v and v['optional'])):
ret = True
break
except Exception:
ret = False
return (not ret)
def printInfo(self,type_,helpIfNoArg = False, steps=False):
#try to print the info of the arguments necessary to instanciate the instance
try:
sortedArgs = collections.OrderedDict(sorted(self._registered[type_]['args'].items()))
maxname = 17
undername = "="*maxname
maxtype = 10
undertype = "="*maxtype
maxargtype = 10
underargtype = "="*maxargtype
maxman = 10
underman = "="*maxman
maxvals = 20
undervals = "="*maxvals
maxdef = 10
underdef = "="*maxdef
spc = " "
n = 1
spc0 = spc*n
line = "name".ljust(maxname,' ')+spc0+"type".ljust(maxtype,' ')+spc0+"argtype".ljust(maxargtype,' ')
line += spc0+"mandatory".ljust(maxman,' ')+spc0+"values".ljust(maxvals,' ')+spc0+"default".ljust(maxdef,' ')
fullMessage = line + '\n'
line = undername+spc0+undertype+spc0+underargtype+spc0+underman+spc0+undervals+spc0+underdef
shallPrint = False
fullMessage += line + '\n'
for arg,val in sortedArgs.items():
try:
type = str(val['type'])
except Exception:
type = 'N/A'
if(arg.isdigit()):
argtype = 'positional'
else:
argtype = 'keyword'
try:
mandatory = 'False' if val['optional'] else 'True'
except Exception:
mandatory = 'True'
try:
default = str(val['default'])
except Exception:
default = 'Not set'
if isinstance(val['value'],list):
posarg = ' '.join(val['value'])
elif isinstance(val['value'],str) and val['value']:
posarg = val['value']
else:
posarg = ''
lines = []
self.cont_string = ''
lines.append(self.columnate_words(arg, maxname, self.cont_string))
lines.append(self.columnate_words(type, maxtype, self.cont_string))
lines.append(self.columnate_words(argtype, maxargtype, self.cont_string))
lines.append(self.columnate_words(mandatory, maxman, self.cont_string))
lines.append(self.columnate_words(posarg, maxvals, self.cont_string,True))
lines.append(self.columnate_words(default, maxdef, self.cont_string))
nlines = max(map(len,lines))
for row in lines:
try:
row += [' ']*(nlines-len(row))
except:
dummy = 1
for ll in range(nlines):
fullMessage += lines[0][ll].ljust(maxname,' ')
fullMessage += spc0+lines[1][ll].ljust(maxtype,' ')
fullMessage += spc0+lines[2][ll].ljust(maxargtype,' ')
fullMessage += spc0+lines[3][ll].ljust(maxman,' ')
fullMessage += spc0+lines[4][ll].ljust(maxvals,' ')
fullMessage += spc0+lines[5][ll].ljust(maxdef,' ') + '\n'
shallPrint = True
# line = spc0+x.ljust(maxname)+spc0+yt.ljust(maxtype)
# line += spc0+y[2].ljust(maxman)+spc0+z.ljust(maxdoc)
# print(line)
if(shallPrint):
print("\nType ",type_, ": Constructor requires arguments described in the\n" +
"table below. Use the -a option with the mandatory arguments\n"+
"to ask for more help. Run iscehelp.py -h for more info on the -a option.\n",sep="")
print(fullMessage)
except Exception:
print("\nType ",type_, ": constructor requires no arguments",sep="")
#try to see if one can create an instance and provide more help
if helpIfNoArg:
instance = self.getInstance(type_)
self.askHelp(instance, self._inputs.steps)
def printAll(self):
for k in self._registered.keys():
self.printInfo(k)
def run(self):
self.parse()
sys.argv = [sys.argv[0]]
noArgs = True
for k,v in self._inputs._get_kwargs():
if(v):
noArgs = False
break
if self._inputs.info or noArgs:
#if no arguments provided i.e. self._input has all the attributes = None
#then print the list of all available helps
self.printAll()
elif self._inputs.type and not self._inputs.args:
#if only -t type is provided print how to get help for that specific type
self.printInfo(self._inputs.type,helpIfNoArg=self.typeNeedsNoArgs(self._inputs.type))
elif self._inputs.type and (self._inputs.args):
#if type and arguments are provided then provide help for that type
if self._inputs.type in self._registered:
instance = self.getInstance(self._inputs.type)
self.askHelp(instance, self._inputs.steps)
else:
print("Help for",self._inputs.type,"is not available. Run iscehelp.py"+\
" with no options to see the list of available type of objects" +\
" one can get help for")
sys.exit(1)
elif self._inputs.type and self._inputs.steps and not self._inputs.args:
#if only -t type is provided print how to get help for that specific type
self.printInfo(self._inputs.type, helpIfNoArg=True,
steps=self._inputs.steps)
elif self._inputs.type and (self._inputs.args) and self._inputs.steps:
#if type and arguments are provided then provide help for that type
if self._inputs.type in self._registered:
instance = self.getInstance(self._inputs.type)
self.askHelp(instance, self._inputs.steps)
else:
print("Help for",self._inputs.type,"is not available. Run iscehelp.py"+\
" with -i (--info) to see the list of available type of objects" +\
" one can get help for")
sys.exit(1)
def parse(self):
epilog = 'Run iscehelp.py with no arguments or with -i option to list the available object\n'
epilog += 'types for which help is provided\n'
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,epilog=epilog)
parser.add_argument('-i','--info',dest='info',action='store_true',help='Provides the list of registered object types')
parser.add_argument('-t','--type',dest='type',type=str,help='Specifies the object type for which help is sought')
parser.add_argument('-a','--args',dest='args',type=str,nargs='+',help='Set of positional and keyword arguments '\
+'that the factory of the object "type" takes.'\
+ 'The keyword arguments are specified as keyword=value with no spaces.')
parser.add_argument('-s','--steps',dest='steps',action='store_true',help='Provides the list of steps in the help message')
self._inputs = parser.parse_args()
def __init__(self):
import isce
#the directory is defined in SConstruct
self._helpDir = os.path.join(isce.__path__[0],'helper')
self._registered = self.getRegistered()
self._inputs = None
def main():
hp = Helper()
hp.run()
if __name__ == '__main__':
main()

126
applications/looks.py Executable file
View File

@ -0,0 +1,126 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2013 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Piyush Agram
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
import logging
import sys
import isce
import argparse
from isceobj.Image import createImage,createDemImage
from mroipac.looks.Looks import Looks
class customArgparseFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter):
'''
For better help message that also shows the defaults.
'''
pass
def cmdLineParse():
'''
Command Line Parser.
'''
parser = argparse.ArgumentParser(description='Take integer number of looks.',
formatter_class=customArgparseFormatter,
epilog = '''
Example:
looks.py -i input.file -o output.file -r 4 -a 4
''')
parser.add_argument('-i','--input', type=str, required=True, help='Input ISCEproduct with a corresponding .xml file.', dest='infile')
parser.add_argument('-o','--output',type=str, default=None, help='Output ISCE DEproduct with a corresponding .xml file.', dest='outfile')
parser.add_argument('-r', '--range', type=int, default=1, help='Number of range looks. Default: 1', dest='rglooks')
parser.add_argument('-a', '--azimuth', type=int, default=1, help='Number of azimuth looks. Default: 1', dest='azlooks')
values = parser.parse_args()
if (values.rglooks == 1) and (values.azlooks == 1):
print('Nothing to do. One look requested in each direction. Exiting ...')
sys.exit(0)
return values
def main(inps):
'''
The main driver.
'''
if inps.infile.endswith('.xml'):
inFileXml = inps.infile
inFile = os.path.splitext(inps.infile)[0]
else:
inFile = inps.infile
inFileXml = inps.infile + '.xml'
if inps.outfile is None:
spl = os.path.splitext(inFile)
ext = '.{0}alks_{1}rlks'.format(inps.azlooks, inps.rglooks)
outFile = spl[0] + ext + spl[1]
elif inps.outfile.endswith('.xml'):
outFile = os.path.splitext(inps.outfile)[0]
else:
outFile = inps.outfile
print('Output filename : {0}'.format(outFile))
#hackish, just to know the image type to instantiate the correct type
#until we put the info about how to generate the instance in the xml
from iscesys.Parsers.FileParserFactory import createFileParser
FP = createFileParser('xml')
tmpProp, tmpFact, tmpMisc = FP.parse(inFileXml)
if('image_type' in tmpProp and tmpProp['image_type'] == 'dem'):
inImage = createDemImage()
else:
inImage = createImage()
inImage.load(inFileXml)
inImage.filename = inFile
lkObj = Looks()
lkObj.setDownLooks(inps.azlooks)
lkObj.setAcrossLooks(inps.rglooks)
lkObj.setInputImage(inImage)
lkObj.setOutputFilename(outFile)
lkObj.looks()
return outFile
if __name__ == '__main__':
'''
Makes the script executable.
'''
inps = cmdLineParse()
main(inps)

179
applications/make_input.py Normal file
View File

@ -0,0 +1,179 @@
import sys
import os
import fnmatch
import Tkinter, tkFileDialog
import xml.etree.ElementTree as ElementTree
class App(Tkinter.Frame):
def __init__(self,master=None):
Tkinter.Frame.__init__(self,master)
self.master.title('ISSI Input File Generator')
self.filterList = None
self.filterX = Tkinter.IntVar()
self.filterY = Tkinter.IntVar()
self.tec = Tkinter.StringVar()
self.fr = Tkinter.StringVar()
self.phase = Tkinter.StringVar()
self.grid()
self._buildGUI()
def findFiles(self,dir):
"""Find a list of the files needed for Faraday Rotation estimation"""
filenames = {'leader': None,
'image': {}}
# Look for files that start with IMG
# note, this will only work with JAXA/ASF style CEOS files
# ERSDAC file nameing structure is not supported
for root,dirs,files in os.walk(dir):
for file in files:
# Find the leader file
if (fnmatch.fnmatch(file,'LED*')):
leaderFile = os.path.join(root,file)
filenames['leader'] = leaderFile
# Find the image files
elif (fnmatch.fnmatch(file,'IMG*')):
polarity = file[4:6]
imageFile = os.path.join(root,file)
filenames['image'][polarity] = imageFile
return filenames
def createImageXML(self,files):
"""Create an XML input file from the dictionary of input files"""
for polarity in ('HH','HV','VH','VV'):
output = polarity + '.xml'
root = ElementTree.Element('component')
# Leader File
leaderProperty = ElementTree.SubElement(root,'property')
leaderName = ElementTree.SubElement(leaderProperty,'name')
leaderValue = ElementTree.SubElement(leaderProperty,'value')
leaderName.text = 'LEADERFILE'
leaderValue.text = files['leader']
# Image File
imageProperty = ElementTree.SubElement(root,'property')
imageName = ElementTree.SubElement(imageProperty,'name')
imageValue = ElementTree.SubElement(imageProperty,'value')
imageName.text = 'IMAGEFILE'
imageValue.text = files['image'][polarity]
tree = ElementTree.ElementTree(root)
self.indent(tree.getroot())
tree.write(output)
def createAuxilliaryXML(self,output):
"""Create an input file with the default file names"""
root = ElementTree.Element('component')
for polarity in ('HH','HV','VH','VV'):
filename = polarity + '.xml'
property = ElementTree.SubElement(root,'property')
name = ElementTree.SubElement(property,'name')
factoryName = ElementTree.SubElement(property,'factoryname')
factoryModule = ElementTree.SubElement(property,'factorymodule')
value = ElementTree.SubElement(property,'value')
name.text = polarity
factoryName.text = 'createALOS'
factoryModule.text = 'isceobj.Sensor'
value.text = filename
tree = ElementTree.ElementTree(root)
self.indent(tree.getroot())
tree.write(output)
def createOutputXML(self,output):
"""Create the output xml file"""
root = ElementTree.Element('component')
products = {'FILTER': self.filterList.get(),
'FILTER_SIZE_X': str(self.filterX.get()),
'FILTER_SIZE_Y': str(self.filterY.get()),
'FARADAY_ROTATION': self.fr.get(),
'TEC': self.tec.get(),
'PHASE': self.phase.get()}
for key in products:
property = ElementTree.SubElement(root,'property')
name = ElementTree.SubElement(property,'name')
value = ElementTree.SubElement(property,'value')
name.text = key
value.text = products[key]
tree = ElementTree.ElementTree(root)
self.indent(tree.getroot())
tree.write(output)
def indent(self,elem, level=0):
"""Indent and XML ElementTree"""
i = "\n" + level*" "
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + " "
if not elem.tail or not elem.tail.strip():
elem.tail = i
for elem in elem:
self.indent(elem, level+1)
if not elem.tail or not elem.tail.strip():
elem.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
def chooseFiles(self):
"""Create a dialog box for the ALOS Quad-pol directory"""
dir = tkFileDialog.askdirectory(parent=self,title="Choose a directory")
if (dir):
files = self.findFiles(dir)
try:
self.createImageXML(files)
self.createAuxilliaryXML('FR.xml')
self.createOutputXML('output.xml')
print("XML Files Created")
except Exception as strerr:
print(strerr)
print("No ALOS files found in %s" % (dir))
def _buildGUI(self):
"""Create widgets and build the GUI"""
filterLabel = Tkinter.Label(self,text='Choose Filter Type:')
xSizeLabel = Tkinter.Label(self,text='Range Filter Size')
ySizeLabel = Tkinter.Label(self,text='Azimuth Filter Size')
tecLabel = Tkinter.Label(self,text='TEC Output Filename')
frLabel = Tkinter.Label(self,text='Faraday Rotation Output Filename')
phaseLabel = Tkinter.Label(self,text='Phase Correction Output Filename')
self.filterList = Tkinter.Spinbox(self,values=('None','Mean','Median','Gaussian'))
xSizeEntry = Tkinter.Entry(self,textvariable=self.filterX)
ySizeEntry = Tkinter.Entry(self,textvariable=self.filterY)
frEntry = Tkinter.Entry(self,textvariable=self.fr)
tecEntry = Tkinter.Entry(self,textvariable=self.tec)
phaseEntry = Tkinter.Entry(self,textvariable=self.phase)
dirButton = Tkinter.Button(self,text="Choose Data Directory",command=self.chooseFiles)
quitButton = Tkinter.Button(self,text="Quit",command=self.quit)
filterLabel.grid(row=0,column=0)
self.filterList.grid(row=0,column=1)
xSizeLabel.grid(row=1,column=0)
xSizeEntry.grid(row=1,column=1)
ySizeLabel.grid(row=2,column=0)
ySizeEntry.grid(row=2,column=1)
frLabel.grid(row=3,column=0)
frEntry.grid(row=3,column=1)
tecLabel.grid(row=4,column=0)
tecEntry.grid(row=4,column=1)
phaseLabel.grid(row=5,column=0)
phaseEntry.grid(row=5,column=1)
dirButton.grid(row=6,column=0)
quitButton.grid(row=6,column=1)
if __name__ == "__main__":
"""
Simple example program for creating input files for ISSI.
"""
app = App()
app.mainloop()

448
applications/make_raw.py Executable file
View File

@ -0,0 +1,448 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Walter Szeliga
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
import logging
import logging.config
logging.config.fileConfig(os.path.join(os.environ['ISCE_HOME'], 'defaults',
'logging', 'logging.conf'))
import isce
from iscesys.Compatibility import Compatibility
from iscesys.Component.Component import Component, Port
from isceobj.Planet.Ellipsoid import Ellipsoid
from isceobj.Doppler.Doppler import Doppler
from isceobj.Orbit.Orbit import Orbit
#from iscesys.DateTimeUtil.DateTimeUtil import DateTimeUtil as DTU
from iscesys import DateTimeUtil as DTU
from iscesys.Component.Application import Application
from isce.applications.insarApp import SENSOR_NAME, DOPPLER_METHOD
from isceobj.Scene.Frame import FrameMixin
from isceobj.Util.decorators import port
SENSOR = Application.Facility('sensor',
public_name='sensor',
module='isceobj.Sensor',
factory='createSensor',
args=(SENSOR_NAME, ),
mandatory=True,
doc="Master raw data component"
)
DOPPLER = Application.Facility('doppler',
public_name='doppler',
module='isceobj.Doppler',
factory='createDoppler',
args=(DOPPLER_METHOD, ),
mandatory=False,
doc="Master Doppler calculation method"
)
class makeRawApp(Application):
parameter_list = (SENSOR_NAME, DOPPLER_METHOD)
facility_list = (SENSOR, DOPPLER)
def main(self):
self.make_raw.wireInputPort(name='doppler', object=self.doppler)
self.make_raw.wireInputPort(name='sensor', object=self.sensor)
self.make_raw.make_raw()
self.printInfo()
def printInfo(self):
print(self.make_raw.frame)
print(self.make_raw)
def __init__(self):
Application.__init__(self, "makeraw")
self.sensor = None
self.doppler = None
self.make_raw = make_raw()
def initFromArglist(self, arglist):
self.initFactory(arglist)
self.sensor = self.getComponent('Sensor')
self.doppler = self.getComponent('Doppler')
class make_raw(Component, FrameMixin):
def __init__(self):
self.sensor = None
self.doppler = None
self.dopplerValues = None
self.frame = None
# Derived Values
self.spacecraftHeight = 0.0
self.heightDt = 0.0
self.velocity = 0.0
self.squint = 0.0
self.iqImage = None
Component.__init__(self)
sensorPort = Port(name='sensor', method=self.addSensor)
dopplerPort = Port(name='doppler', method=self.addDoppler)
self._inputPorts.add(sensorPort)
self._inputPorts.add(dopplerPort)
self.logger = logging.getLogger("isce.make_raw")
return None
def __getstate__(self):
d = dict(self.__dict__)
del d['logger']
return d
def __setstate__(self, d):
self.__dict__.update(d)
self.logger = logging.getLogger("isce.make_raw")
return None
@port('extractImage')
def addSensor(self):
return None
@port('calculateDoppler')
def addDoppler(self):
return None
def getFrame(self):
return self.frame
def getIQImage(self):
return self.iqImage
def getDopplerValues(self):
return self.dopplerValues
def getSpacecraftHeight(self):
return self.spacecraftHeight
def getHeightDT(self):
return self.heightDt
def getVelocity(self):
return self.velocity
def getSquint(self):
return self.squint
def calculateHeightDt(self):
orbit = self.orbit
ellipsoid = self.ellipsoid
startTime = self.sensingStart
midTime = self.sensingMid
sv0 = orbit.interpolate(startTime)
sv1 = orbit.interpolate(midTime)
startHeight = sv0.calculateHeight(ellipsoid)
midHeight = sv1.calculateHeight(ellipsoid)
if 'uav' in self.sensor.family.lower():
self.spacecraftHeight = self.sensor.platformHeight
else:
self.spacecraftHeight = startHeight
self.heightDt = (
(midHeight - startHeight)/
DTU.timeDeltaToSeconds(midTime - startTime)
)
def calculateVelocity(self):
import math
orbit = self.orbit
midTime = self.sensingMid
sv = orbit.interpolateOrbit(midTime)
vx1, vy1, vz1 = sv.velocity
self.velocity = math.sqrt(vx1**2 + vy1**2 + vz1**2)
def calculateSquint(self):
"""Calculate the squint angle
R0 is the starting range
h is the height at mid-swath
v is the velocity at mid-swath
"""
import math
startingRange = self.startingRange
prf = self.PRF
wavelength = self.radarWavelength
h = self.spacecraftHeight
try:
z = self.sensor.terrainHeight
except:
z = 0.0
v = self.velocity
if h - z > startingRange:
raise ValueError(
("Spacecraft Height - Terrain Height (%s) " +
"larger than starting Range (%s)") % (h-z, startingRange))
sinTheta = math.sqrt( 1 - ((h-z)/startingRange)**2 )
if 'a' in self.doppler.quadratic:
fd = self.doppler.quadratic['a']*prf
elif isinstance(self.doppler.quadratic, (list, tuple)):
####For UAVSAR
fd = self.doppler.quadratic[0]
else:
self.logger.error(
"make_raw doesn't handle doppler coefficient object type, ",
type(self.doppler.quadratic)
)
sinSquint = fd/(2.0*v*sinTheta)*wavelength
if sinSquint**2 > 1:
raise ValueError(
"Error in One or More of the Squint Calculation Values\n"+
"Doppler Centroid: %s\nVelocity: %s\nWavelength: %s\n" %
(fd, v, wavelength)
)
self.squint = math.degrees(
math.atan2(sinSquint, math.sqrt(1-sinSquint**2))
)
#squint is used later on from the frame; add it here
self.frame.squintAngle = math.radians(self.squint)
def make_raw(self):
from isceobj.Image import createRawImage, createSlcImage
self.activateInputPorts()
# Parse the image metadata and extract the image
self.logger.info('Extracting image')
try:
self.sensor.extractImage()
except NotImplementedError as strerr:
self.logger.error("%s" % (strerr))
self.logger.error(
"make_raw not implemented for %s" % self.sensor.__class__
)
raise NotImplementedError
#reset the global variable to empty so can go back to use default api
self.sensor.frame.image.renderVRT()
self.frame = self.sensor.frame
#jng NOTE if we pass just the sensor also in the case of raw image we
## can avoid the if
if isinstance(self.frame.image, createRawImage().__class__):
# Calculate the doppler fit
self.logger.info("Calculating Doppler Centroid")
try:
self.doppler.wireInputPort(name='frame',
object=self.frame)
except:
computeFlag = False
else:
computeFlag = True
if computeFlag:
self.doppler.wireInputPort(name='instrument',
object=self.frame.instrument)
self.doppler.wireInputPort(name='image',
object=self.frame.image)
self.doppler.calculateDoppler()
else:
self.doppler.wireInputPort(name='sensor', object=self.sensor)
self.doppler.calculateDoppler()
#new jng compute slc image size here
rangeSamplingRate = self.instrument.rangeSamplingRate
rangePulseDuration = self.instrument.pulseLength
goodBytes = self.frame.image.xmax - self.frame.image.xmin
try:
#check if the instrument implements it, if not set it to zero
chirpExtension = self.instrument.chirpExtension # Should probably be a percentage rather than a set number
except AttributeError:
chirpExtension = 0
chirpSize = int(rangeSamplingRate * rangePulseDuration)
self.frame.numberRangeBins = (int(goodBytes/2) -
chirpSize + chirpExtension)
elif isinstance(self.frame.image, createSlcImage().__class__):
# jng changed in view of the new tsx preproc from Howard
self.doppler.wireInputPort(name='sensor', object=self.sensor)
self.doppler.calculateDoppler()
#new jng compute slc image size here
self.frame.numberRangeBins = self.frame.image.width
else:
message = (
"Unrecognized image type %s" %
str(self.frame.image.__class__)
)
self.logger.error(message)
raise TypeError(message)
# Fit a polynomial to the doppler values. in the tsx case or every
# zero doppler case this function simple sets the a = fd b = 0, c = 0
self.doppler.fitDoppler()
# Create a doppler object
prf = self.frame.instrument.PRF
#coef = self.doppler.coeff_list
#for ii in range(len(coef), 4):
# coef.append(0.0)
if 'a' in self.doppler.quadratic:
coef = [self.doppler.quadratic['a']*prf,0.0,0.0,0.0]
elif isinstance(self.doppler.quadratic, (list, tuple)):
####For UAVSAR
coef = self.doppler.quadratic
else:
self.logger.error(
"make_raw doesn't handle doppler coefficient object type, ",
type(self.doppler.quadratic)
)
self.dopplerValues = Doppler(prf=prf)
self.dopplerValues.setDopplerCoefficients(coef, inHz=True)
if self.frame._dopplerVsPixel is None:
self.frame._dopplerVsPixel = [x*prf for x in coef]
# Calculate the height, height_dt, and velocity
self.logger.info("Calculating Spacecraft Velocity")
self.calculateHeightDt()
self.calculateVelocity()
# Calculate squint angle
self.logger.info("Calculating Squint Angle")
self.calculateSquint()
self.frame.image.numberGoodBytes = self.frame.image.xmax - self.frame.image.xmin
self.frame.image.coord1.coordStart = self.frame.image.xmin
self.createIQImage()
self.frame.image.renderHdr()
#just in case the Sensor does not compute the pulse timing
try:
self.adjustSensingStart()
except:
pass
return None
def createIQImage(self):
from isceobj.Image import createRawIQImage
#create an RawIQImage with appropriate values from the RawImage
self.iqImage = createRawIQImage()
self.iqImage.width = self.frame.image.width/2
self.iqImage.xmax = self.iqImage.width
self.iqImage.length = self.frame.image.length
self.iqImage.coord1.coordStart = int(self.frame.image.coord1.coordStart/2)
self.iqImage.numberGoodSamples = int(self.frame.image.numberGoodBytes/2)
self.iqImage.filename = self.frame.image.filename #the file is the same as for the raw
self.iqImage.inPhase = self.frame.instrument.getInPhaseValue()
self.iqImage.quadrature = self.frame.instrument.getQuadratureValue()
#change the name that will be used for the xml file
filename = self.frame.image.filename.replace('.raw','.iq.xml')
#just in case the extension was not .raw
if not filename.count('.iq'):
filename += '.iq.xml'
self.iqImage.renderHdr(filename)
#change the name that will be used for the vrt file
filename = filename.replace('.xml','.vrt')
self.iqImage.renderVRT(filename)
def adjustSensingStart(self, pulseTimingFilename=None, ext='.aux'):
pulseTimingFilename = (
pulseTimingFilename or
self.frame.image.filename + ext
)
import datetime as dt
import math
import struct
with open(pulseTimingFilename) as fp:
allF = fp.read()
pass
#use only a limited number of point from the first frame
lines = min(len(allF)/16, 10000)
allT = [0]*lines
d0 = struct.unpack('<d', allF[0:8])[0]
day0 = dt.timedelta(d0).days
sec = 0
for i in range(lines):
day, musec = struct.unpack('<dd', allF[i*16:(i+1)*16])
# note the musec are relative to the day, not to the second i.e.
# they are the total musec in the day
td = dt.timedelta(day, sec, musec)
allT[i] = (
(td.microseconds +
(td.seconds +
(td.days - day0) * 24 * 3600.0) * 10**6) / 10**6
)
pass
prf = self.frame.instrument.PRF
sumPart = [allT[i] - i/prf for i in xrange(len(allT))]
sum = math.fsum(sumPart)
sum /= len(allT)
day = day0
sec = math.floor(sum)
musec = (sum - sec)*10**6
sensingOld = self.frame.sensingStart
#day-1 since we start from jan 1 and not jan 0
newSensingStart = (
dt.datetime(sensingOld.year, 1, 1) +
dt.timedelta(day-1, sec, musec)
)
self.frame.setSensingStart(newSensingStart)
self.logger.info("Changing sensing start from %s to %s" %
(str(sensingOld), str(newSensingStart)))
def __str__(self):
retstr = "Velocity: (%s)\n"
retlst = (self.velocity, )
retstr += "HeightDt: (%s)\n"
retlst += (self.heightDt, )
retstr += "Squint: (%s)\n"
retlst += (self.squint, )
retstr += "Height: (%s)\n"
retlst += (self.spacecraftHeight, )
return retstr % retlst
pass
## JEB: added a main for script operation
def main():
return makeRawApp().run()
if __name__ == "__main__":
import sys
if (len(sys.argv) < 2):
print("Usage:%s <xml-parameter file>" % sys.argv[0])
sys.exit(1)
main()

62
applications/mdx.py Executable file
View File

@ -0,0 +1,62 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import print_function
import sys
import os
import math
import isce
from iscesys.Compatibility import Compatibility
Compatibility.checkPythonVersion()
from iscesys.Display.Display import Display
##
# Call mdx.py argv.
# The first element in argv must be the metadata file (i.e. metadata.rsc or metadata.xml) when displaying an image (could be something else when printing help info). If the file does not end by .rsc or .xml, then one needs to specify
# the -type flag that could be rsc or xml. For rsc type of metadata the rsc ROI_PAC format is assumed. For xml type the ISCE xml format is assumed.
# In case the data file name is not simply the metadata file name with the extension removed (for instance metadata file image.int.rsc and data file image.int)
# then use the -image flag and specify the filename.
# If the type of image that needs to be displayed cannot be inferred from the extension (for ROI_PAC type) or from the metadata doc string (ISCE type) then specify the -ext flag.
# To print a list of extensions run mdx.py -ext.
# To print the usage with the list of options just run mdx.py with no arguments.
# The flags -cw,-e,-amp1,-amp2,-chdr,-RMG-Mag,-RMG_Hgt -wrap,-wrap and -cmap have some defaults value depending on the image type. By specifying these flags in the command line the default values can be overwritten.
# Whatever flags in the argv that are not part of the abovementioned ones, will be passed to mdx as arguments at the end of the command.
##
def main(argv = None):
DS = Display()
DS.mdx(argv)
if __name__ == "__main__":
if len(sys.argv) == 1:
sys.exit(main())
else:
sys.exit(main(sys.argv[1:]))

51
applications/readdb.py Executable file
View File

@ -0,0 +1,51 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Eric Gurrola
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# import sqlite3, sql_mod, string # ImportError: No module named sql_mod
import sqlite3, string
con = sqlite3.connect('roi.db')
cur = con.cursor()
tables = {'file1':'file1','file2':'file2','igram1':'igram1','log':'log',
'ambiguity':'ambiguity_table'}
for k, v in tables.items():
print()
print()
print("table: ",v)
print("================")
print()
a = cur.execute('select * from '+v)
for x in a:
print(x)

441
applications/rtcApp.py Executable file
View File

@ -0,0 +1,441 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Authors: Giangi Sacco, Eric Gurrola
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import time
import os
import sys
import logging
import logging.config
import isce
import isceobj
import iscesys
from iscesys.Component.Application import Application
from iscesys.Compatibility import Compatibility
from iscesys.Component.Configurable import SELF
from isceobj import RtcProc
from isceobj.Util.decorators import use_api
logging.config.fileConfig(
os.path.join(os.environ['ISCE_HOME'], 'defaults', 'logging',
'logging.conf')
)
logger = logging.getLogger('isce.grdsar')
SENSOR_NAME = Application.Parameter(
'sensorName',
public_name='sensor name',
default='SENTINEL1',
type=str,
mandatory=True,
doc="Sensor name"
)
USE_HIGH_RESOLUTION_DEM_ONLY = Application.Parameter(
'useHighResolutionDemOnly',
public_name='useHighResolutionDemOnly',
default=False,
type=int,
mandatory=False,
doc=(
"""If True and a dem is not specified in input, it will only
download the SRTM highest resolution dem if it is available
and fill the missing portion with null values (typically -32767)."""
)
)
DEM_FILENAME = Application.Parameter(
'demFilename',
public_name='demFilename',
default='',
type=str,
mandatory=False,
doc="Filename of the Digital Elevation Model (DEM)"
)
WATER_FILENAME = Application.Parameter(
'waterFilename',
public_name='waterFilename',
default='',
type=str,
mandatory=False,
doc='Filename with SWBD data')
APPLY_WATER_MASK = Application.Parameter(
'applyWaterMask',
public_name='apply water mask',
default=False,
type=bool,
mandatory=False,
doc = 'Flag to apply water mask to images')
GEOCODE_BOX = Application.Parameter(
'geocode_bbox',
public_name='geocode bounding box',
default = None,
container=list,
type=float,
doc='Bounding box for geocoding - South, North, West, East in degrees'
)
PICKLE_DUMPER_DIR = Application.Parameter(
'pickleDumpDir',
public_name='pickle dump directory',
default='PICKLE',
type=str,
mandatory=False,
doc=(
"If steps is used, the directory in which to store pickle objects."
)
)
PICKLE_LOAD_DIR = Application.Parameter(
'pickleLoadDir',
public_name='pickle load directory',
default='PICKLE',
type=str,
mandatory=False,
doc=(
"If steps is used, the directory from which to retrieve pickle objects."
)
)
RENDERER = Application.Parameter(
'renderer',
public_name='renderer',
default='xml',
type=str,
mandatory=True,
doc=(
"Format in which the data is serialized when using steps. Options are xml (default) or pickle."
))
NUMBER_AZIMUTH_LOOKS = Application.Parameter('numberAzimuthLooks',
public_name='azimuth looks',
default=None,
type=int,
mandatory=False,
doc='')
NUMBER_RANGE_LOOKS = Application.Parameter('numberRangeLooks',
public_name='range looks',
default=None,
type=int,
mandatory=False,
doc=''
)
POSTING = Application.Parameter('posting',
public_name='azimuth looks',
default = 20.0,
type = float,
mandatory = False,
doc = 'Posting of data used to determine looks')
POLARIZATIONS = Application.Parameter('polarizations',
public_name='polarizations',
default = [],
type = str,
container = list,
doc = 'Polarizations to process')
GEOCODE_LIST = Application.Parameter(
'geocode_list',
public_name='geocode list',
default = None,
container=list,
type=str,
doc = "List of products to geocode."
)
#Facility declarations
MASTER = Application.Facility(
'master',
public_name='Master',
module='isceobj.Sensor.GRD',
factory='createSensor',
args=(SENSOR_NAME, 'master'),
mandatory=True,
doc="GRD data component"
)
DEM_STITCHER = Application.Facility(
'demStitcher',
public_name='demStitcher',
module='iscesys.DataManager',
factory='createManager',
args=('dem1','iscestitcher',),
mandatory=False,
doc="Object that based on the frame bounding boxes creates a DEM"
)
_GRD = Application.Facility(
'_grd',
public_name='rtcproc',
module='isceobj.RtcProc',
factory='createRtcProc',
args = ('rtcAppContext',isceobj.createCatalog('rtcProc')),
mandatory=False,
doc="RtcProc object"
)
class GRDSAR(Application):
family = 'grdsar'
## Define Class parameters in this list
parameter_list = (SENSOR_NAME,
USE_HIGH_RESOLUTION_DEM_ONLY,
DEM_FILENAME,
NUMBER_AZIMUTH_LOOKS,
NUMBER_RANGE_LOOKS,
POSTING,
GEOCODE_BOX,
PICKLE_DUMPER_DIR,
PICKLE_LOAD_DIR,
RENDERER,
POLARIZATIONS,
GEOCODE_LIST)
facility_list = (MASTER,
DEM_STITCHER,
_GRD)
_pickleObj = "_grd"
def __init__(self, family='', name='',cmdline=None):
import isceobj
from isceobj.RtcProc import RtcProc
from iscesys.StdOEL.StdOELPy import create_writer
super().__init__(
family=family if family else self.__class__.family, name=name,
cmdline=cmdline)
self._stdWriter = create_writer("log", "", True, filename="grdsar.log")
self._add_methods()
self._insarProcFact = RtcProc
return None
def Usage(self):
print("Usages: ")
print("rtcApp.py <input-file.xml>")
print("rtcApp.py --steps")
print("rtcApp.py --help")
print("rtcApp.py --help --steps")
def _init(self):
message = (
("ISCE VERSION = %s, RELEASE_SVN_REVISION = %s,"+
"RELEASE_DATE = %s, CURRENT_SVN_REVISION = %s") %
(isce.__version__,
isce.release_svn_revision,
isce.release_date,
isce.svn_revision)
)
logger.info(message)
print(message)
return None
def _configure(self):
self.grd.procDoc._addItem("ISCE_VERSION",
"Release: %s, svn-%s, %s. Current svn-%s" %
(isce.release_version, isce.release_svn_revision,
isce.release_date, isce.svn_revision
),
["rtcProc"]
)
if(self.geocode_list is None):
self.geocode_list = self.grd.geocode_list
else:
g_count = 0
for g in self.geocode_list:
if g not in self.grd.geocode_list:
g_count += 1
#warn if there are any differences in content
if g_count > 0:
print()
logger.warn((
"Some filenames in rtcApp.geocode_list configuration "+
"are different from those in rtcProc. Using names given"+
" to grdApp."))
print("grdApp.geocode_list = {}".format(self.geocode_list))
print(("grdProc.geocode_list = {}".format(
self.grd.geocode_list)))
self.grd.geocode_list = self.geocode_list
return None
@property
def grd(self):
return self._grd
@grd.setter
def grd(self, value):
self._grd = value
return None
@property
def procDoc(self):
return self.grd.procDoc
@procDoc.setter
def procDoc(self):
raise AttributeError(
"Can not assign to .grd.procDoc-- but you hit all its other stuff"
)
def _finalize(self):
pass
def help(self):
from isceobj.Sensor.GRD import SENSORS
print(self.__doc__)
lsensors = list(SENSORS.keys())
lsensors.sort()
print("The currently supported sensors are: ", lsensors)
return None
def help_steps(self):
print(self.__doc__)
print("A description of the individual steps can be found in the README file")
print("and also in the ISCE.pdf document")
return
def renderProcDoc(self):
self.procDoc.renderXml()
def startup(self):
self.help()
self._grd.timeStart = time.time()
def endup(self):
self.renderProcDoc()
self._grd.timeEnd = time.time()
logger.info("Total Time: %i seconds" %
(self._grd.timeEnd-self._grd.timeStart))
return None
## Add instance attribute RunWrapper functions, which emulate methods.
def _add_methods(self):
self.runPreprocessor = RtcProc.createPreprocessor(self)
self.verifyDEM = RtcProc.createVerifyDEM(self)
self.multilook = RtcProc.createLooks(self)
self.runTopo = RtcProc.createTopo(self)
# self.runGeocode = RtcProc.createGeocode(self)
return None
def _steps(self):
self.step('startup', func=self.startup,
doc=("Print a helpful message and "+
"set the startTime of processing")
)
# Run a preprocessor for the two sets of frames
self.step('preprocess',
func=self.runPreprocessor,
doc=(
"""Unpack the input data"""
)
)
# Verify whether the DEM was initialized properly. If not, download
# a DEM
self.step('verifyDEM', func=self.verifyDEM)
#Multilook product as needed
self.step('multilook', func=self.multilook)
##Run topo for each bursts
self.step('topo', func=self.runTopo)
# Geocode
# self.step('geocode', func=self.runGeocode,
# args=(self.geocode_list, self.do_unwrap, self.geocode_bbox))
return None
@use_api
def main(self):
self.help()
timeStart= time.time()
# Run a preprocessor for the two sets of frames
self.runPreprocessor()
#Verify whether user defined a dem component. If not, then download
# SRTM DEM.
self.verifyDEM()
#Multilook as needed
self.multilook()
##Run topo for each burst
self.runTopo()
###Compute covariance
# self.runEstimateCovariance()
# Geocode
# self.runGeocode(self.geocode_list, self.do_unwrap, self.geocode_bbox)
timeEnd = time.time()
logger.info("Total Time: %i seconds" %(timeEnd - timeStart))
self.renderProcDoc()
return None
if __name__ == "__main__":
import sys
grdsar = GRDSAR(name="rtcApp")
grdsar.configure()
grdsar.run()

890
applications/scansarApp.py Executable file
View File

@ -0,0 +1,890 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Authors: Giangi Sacco, Eric Gurrola
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import time
import os
import sys
import logging
import logging.config
import isce
import isceobj
import iscesys
from iscesys.Component.Application import Application
from iscesys.Compatibility import Compatibility
from iscesys.Component.Configurable import SELF
from isceobj import ScansarProc
logging.config.fileConfig(
os.path.join(os.environ['ISCE_HOME'], 'defaults', 'logging',
'logging.conf')
)
logger = logging.getLogger('isce.insar')
SENSOR_NAME = Application.Parameter(
'sensorName',
public_name='sensor name',
default='ALOS2',
type=str,
mandatory=True,
doc="Sensor name"
)
FULL_APERTURE_PRODUCT = Application.Parameter(
'isFullApertureProduct',
public_name='is full aperture product',
default=False,
type=bool,
mandatory=True,
doc= "To indicate full aperture or burst-by-burst")
BURST_OVERLAP_THRESHOLD = Application.Parameter(
'burstOverlapThreshold',
public_name='burst overlap threshold',
default=85.0,
type=float,
mandatory=True,
doc='Minimum burst overlap needed to stop triggering common azimuth spectra filtering')
UNWRAPPER_NAME = Application.Parameter(
'unwrapper_name',
public_name='unwrapper name',
default='icu',
type=str,
mandatory=False,
doc="Unwrapping method to use. To be used in combination with UNWRAP."
)
# not fully supported yet; use UNWRAP instead
DO_UNWRAP = Application.Parameter(
'do_unwrap',
public_name='do unwrap',
default=False,
type=bool,
mandatory=False,
doc="True if unwrapping is desired. To be unsed in combination with UNWRAPPER_NAME."
)
DO_UNWRAP_2STAGE = Application.Parameter(
'do_unwrap_2stage',
public_name='do unwrap 2 stage',
default=False,
type=bool,
mandatory=False,
doc="True if unwrapping is desired. To be unsed in combination with UNWRAPPER_NAME."
)
UNWRAPPER_2STAGE_NAME = Application.Parameter(
'unwrapper_2stage_name',
public_name='unwrapper 2stage name',
default='REDARC0',
type=str,
mandatory=False,
doc="2 Stage Unwrapping method to use. Available: MCF, REDARC0, REDARC1, REDARC2"
)
SOLVER_2STAGE = Application.Parameter(
'solver_2stage',
public_name='SOLVER_2STAGE',
default='pulp',
type=str,
mandatory=False,
doc='Linear Programming Solver for 2Stage; Options: pulp, gurobi, glpk; Used only for Redundant Arcs'
)
USE_HIGH_RESOLUTION_DEM_ONLY = Application.Parameter(
'useHighResolutionDemOnly',
public_name='useHighResolutionDemOnly',
default=False,
type=int,
mandatory=False,
doc=(
"""If True and a dem is not specified in input, it will only
download the SRTM highest resolution dem if it is available
and fill the missing portion with null values (typically -32767)."""
)
)
DEM_FILENAME = Application.Parameter(
'demFilename',
public_name='demFilename',
default='',
type=str,
mandatory=False,
doc="Filename of the Digital Elevation Model (DEM)"
)
GEOCODE_DEM_FILENAME = Application.Parameter(
'geocodeDemFilename',
public_name='geocode demfilename',
default='',
type=str,
mandatory=False,
doc='Filename of the DEM for geocoding')
GEOCODE_BOX = Application.Parameter(
'geocode_bbox',
public_name='geocode bounding box',
default = None,
container=list,
type=float,
doc='Bounding box for geocoding - South, North, West, East in degrees'
)
PICKLE_DUMPER_DIR = Application.Parameter(
'pickleDumpDir',
public_name='pickle dump directory',
default='PICKLE',
type=str,
mandatory=False,
doc=(
"If steps is used, the directory in which to store pickle objects."
)
)
PICKLE_LOAD_DIR = Application.Parameter(
'pickleLoadDir',
public_name='pickle load directory',
default='PICKLE',
type=str,
mandatory=False,
doc=(
"If steps is used, the directory from which to retrieve pickle objects."
)
)
RENDERER = Application.Parameter(
'renderer',
public_name='renderer',
default='xml',
type=str,
mandatory=True,
doc=(
"Format in which the data is serialized when using steps. Options are xml (default) or pickle."
))
NUMBER_AZIMUTH_LOOKS = Application.Parameter('numberAzimuthLooks',
public_name='azimuth looks',
default=7,
type=int,
mandatory=False,
doc='')
NUMBER_RANGE_LOOKS = Application.Parameter('numberRangeLooks',
public_name='range looks',
default=19,
type=int,
mandatory=False,
doc=''
)
FILTER_STRENGTH = Application.Parameter('filterStrength',
public_name='filter strength',
default=0.5,
type=float,
mandatory=False,
doc='')
OFFSET_SNR_THRESHOLD = Application.Parameter('offsetSNRThreshold',
public_name = 'offset SNR threshold',
default=8.0,
type=float,
mandatory = False,
doc = 'Offset SNR threshold')
####New parameters for multi-swath
USE_VIRTUAL_FILES = Application.Parameter('useVirtualFiles',
public_name = 'use virtual files',
default=True,
type=bool,
mandatory=False,
doc = 'Use virtual files when possible to save space')
SWATHS = Application.Parameter('swaths',
public_name = 'swaths',
default = [],
type=int,
container=list,
mandatory=False,
doc = 'Swaths to process')
DO_INSAR = Application.Parameter('doInSAR',
public_name = 'do interferogram',
default = True,
type = bool,
doc = 'Perform interferometry. Set to false to skip insar steps.')
GEOCODE_LIST = Application.Parameter(
'geocode_list',
public_name='geocode list',
default = None,
container=list,
type=str,
doc = "List of products to geocode."
)
WINDOW_SIZE_WIDTH = Application.Parameter(
'winwidth',
public_name='Ampcor window width',
default=64,
type=int,
mandatory=False,
doc='Ampcor main window size width. Used in runDenseOffsets.'
)
WINDOW_SIZE_HEIGHT = Application.Parameter(
'winhgt',
public_name='Ampcor window height',
default=64,
type=int,
mandatory=False,
doc='Ampcor main window size height. Used in runDenseOffsets.')
SEARCH_WINDOW_WIDTH = Application.Parameter(
'srcwidth',
public_name='Ampcor search window width',
default=20,
type=int,
mandatory=False,
doc='Ampcor search window size width. Used in runDenseOffsets.'
)
SEARCH_WINDOW_HEIGHT = Application.Parameter(
'srchgt',
public_name='Ampcor search window height',
default=20,
type=int,
mandatory=False,
doc='Ampcor search window size height. Used in runDenseOffsets.'
)
SKIP_SAMPLE_ACROSS = Application.Parameter(
'skipwidth',
public_name='Ampcor skip width',
default=32,
type=int,
mandatory=False,
doc='Ampcor skip across width. Used in runDenseOffsets.'
)
SKIP_SAMPLE_DOWN = Application.Parameter(
'skiphgt',
public_name='Ampcor skip height',
default=32,
type=int,
mandatory=False,
doc='Ampcor skip down height. Used in runDenseOffsets.'
)
OFFSET_MARGIN = Application.Parameter(
'margin',
public_name='Ampcor margin',
default=50,
type=int,
mandatory=False,
doc='Ampcor margin offset. Used in runDenseOffsets.'
)
OVERSAMPLING_FACTOR = Application.Parameter(
'oversample',
public_name='Ampcor oversampling factor',
default=32,
type=int,
mandatory=False,
doc='Ampcor oversampling factor. Used in runDenseOffsets.'
)
ACROSS_GROSS_OFFSET = Application.Parameter(
'rgshift',
public_name='Range shift',
default=0,
type=int,
mandatory=False,
doc='Ampcor gross offset across. Used in runDenseOffsets.'
)
DOWN_GROSS_OFFSET = Application.Parameter(
'azshift',
public_name='Azimuth shift',
default=0,
type=int,
mandatory=False,
doc='Ampcor gross offset down. Used in runDenseOffsets.'
)
DENSE_OFFSET_SNR_THRESHOLD = Application.Parameter(
'dense_offset_snr_thresh',
public_name='SNR Threshold factor',
default=None,
type=float,
mandatory=False,
doc='SNR Threshold factor used in filtering offset field objects.')
FILTER_NULL = Application.Parameter(
'filt_null',
public_name='Filter NULL factor',
default=-10000.,
type=float,
mandatory=False,
doc='NULL factor to use in filtering offset fields to avoid numpy type issues.'
)
FILTER_WIN_SIZE = Application.Parameter(
'filt_size',
public_name='Filter window size',
default=5,
type=int,
mandatory=False,
doc='Window size for median_filter.'
)
OFFSET_GEOCODE_LIST = Application.Parameter(
'off_geocode_list',
public_name='offset geocode list',
default=None,
container=list,
type=str,
mandatory=False,
doc='List of offset-specific files to geocode.'
)
USE_GPU = Application.Parameter(
'useGPU',
public_name='use GPU',
default=False,
type=bool,
mandatory=False,
doc='Allow App to use GPU when available')
#Facility declarations
MASTER = Application.Facility(
'master',
public_name='Master',
module='isceobj.Sensor.ScanSAR',
factory='createSensor',
args=(SENSOR_NAME, 'master'),
mandatory=True,
doc="Master raw data component"
)
SLAVE = Application.Facility(
'slave',
public_name='Slave',
module='isceobj.Sensor.ScanSAR',
factory='createSensor',
args=(SENSOR_NAME,'slave'),
mandatory=True,
doc="Slave raw data component"
)
DEM_STITCHER = Application.Facility(
'demStitcher',
public_name='demStitcher',
module='iscesys.DataManager',
factory='createManager',
args=('dem1','iscestitcher',),
mandatory=False,
doc="Object that based on the frame bounding boxes creates a DEM"
)
RUN_UNWRAPPER = Application.Facility(
'runUnwrapper',
public_name='Run unwrapper',
module='isceobj.ScansarProc',
factory='createUnwrapper',
args=(SELF(), DO_UNWRAP, UNWRAPPER_NAME),
mandatory=False,
doc="Unwrapping module"
)
RUN_UNWRAP_2STAGE = Application.Facility(
'runUnwrap2Stage',
public_name='Run unwrapper 2 Stage',
module='isceobj.ScansarProc',
factory='createUnwrap2Stage',
args=(SELF(), DO_UNWRAP_2STAGE, UNWRAPPER_NAME),
mandatory=False,
doc="Unwrapping module"
)
_INSAR = Application.Facility(
'_insar',
public_name='scansarproc',
module='isceobj.ScansarProc',
factory='createScansarProc',
args = ('scansarAppContext',isceobj.createCatalog('scansarProc')),
mandatory=False,
doc="ScansarProc object"
)
## Common interface for all insar applications.
class ScansarInSAR(Application):
family = 'scansarinsar'
## Define Class parameters in this list
parameter_list = (SENSOR_NAME,
UNWRAPPER_NAME,
DEM_FILENAME,
GEOCODE_DEM_FILENAME,
BURST_OVERLAP_THRESHOLD,
NUMBER_AZIMUTH_LOOKS,
NUMBER_RANGE_LOOKS,
FILTER_STRENGTH,
OFFSET_SNR_THRESHOLD,
DO_INSAR,
DO_UNWRAP,
USE_HIGH_RESOLUTION_DEM_ONLY,
GEOCODE_BOX,
PICKLE_DUMPER_DIR,
PICKLE_LOAD_DIR,
RENDERER,
DO_UNWRAP_2STAGE,
UNWRAPPER_2STAGE_NAME,
SOLVER_2STAGE,
GEOCODE_LIST,
USE_VIRTUAL_FILES,
SWATHS,
WINDOW_SIZE_HEIGHT,
WINDOW_SIZE_WIDTH,
SEARCH_WINDOW_HEIGHT,
SEARCH_WINDOW_WIDTH,
SKIP_SAMPLE_ACROSS,
SKIP_SAMPLE_DOWN,
OFFSET_MARGIN,
OVERSAMPLING_FACTOR,
ACROSS_GROSS_OFFSET,
DOWN_GROSS_OFFSET,
DENSE_OFFSET_SNR_THRESHOLD,
FILTER_NULL,
FILTER_WIN_SIZE,
OFFSET_GEOCODE_LIST,
USE_GPU)
facility_list = (MASTER,
SLAVE,
DEM_STITCHER,
RUN_UNWRAPPER,
RUN_UNWRAP_2STAGE,
_INSAR)
_pickleObj = "_insar"
def __init__(self, family='', name='',cmdline=None):
import isceobj
from isceobj.ScansarProc import ScansarProc
from iscesys.StdOEL.StdOELPy import create_writer
super().__init__(
family=family if family else self.__class__.family, name=name,
cmdline=cmdline)
self._stdWriter = create_writer("log", "", True, filename="scansarinsar.log")
self._add_methods()
self._insarProcFact = ScansarProc
return None
def Usage(self):
print("Usages: ")
print("scansarApp.py <input-file.xml>")
print("scansarApp.py --steps")
print("scansarApp.py --help")
print("scansarApp.py --help --steps")
def _init(self):
message = (
("ISCE VERSION = %s, RELEASE_SVN_REVISION = %s,"+
"RELEASE_DATE = %s, CURRENT_SVN_REVISION = %s") %
(isce.__version__,
isce.release_svn_revision,
isce.release_date,
isce.svn_revision)
)
logger.info(message)
print(message)
return None
def _configure(self):
self.insar.procDoc._addItem("ISCE_VERSION",
"Release: %s, svn-%s, %s. Current svn-%s" %
(isce.release_version, isce.release_svn_revision,
isce.release_date, isce.svn_revision
),
["insarProc"]
)
#Ensure consistency in geocode_list maintained by insarApp and
#InsarProc. If it is configured in both places, the one in insarApp
#will be used. It is complicated to try to merge the two lists
#because InsarProc permits the user to change the name of the files
#and the linkage between filename and filetype is lost by the time
#geocode_list is fully configured. In order to safely change file
#names and also specify the geocode_list, then insarApp should not
#be given a geocode_list from the user.
if(self.geocode_list is None):
#if not provided by the user use the list from InsarProc
self.geocode_list = self.insar.geocode_list
else:
#if geocode_list defined here, then give it to InsarProc
#for consistency between insarApp and InsarProc and warn the user
#check if the two geocode_lists differ in content
g_count = 0
for g in self.geocode_list:
if g not in self.insar.geocode_list:
g_count += 1
#warn if there are any differences in content
if g_count > 0:
print()
logger.warn((
"Some filenames in insarApp.geocode_list configuration "+
"are different from those in InsarProc. Using names given"+
" to insarApp."))
print("insarApp.geocode_list = {}".format(self.geocode_list))
print(("InsarProc.geocode_list = {}".format(
self.insar.geocode_list)))
self.insar.geocode_list = self.geocode_list
if (self.off_geocode_list is None):
self.off_geocode_list = self.insar.off_geocode_list
else:
g_count = 0
for g in self.off_geocode_list:
if g not in self.insar.off_geocode_list:
g_count += 1
if g_count > 0:
self.insar.off_geocode_list = self.geocode_list
return None
@property
def insar(self):
return self._insar
@insar.setter
def insar(self, value):
self._insar = value
return None
@property
def procDoc(self):
return self.insar.procDoc
@procDoc.setter
def procDoc(self):
raise AttributeError(
"Can not assign to .insar.procDoc-- but you hit all its other stuff"
)
def _finalize(self):
pass
def help(self):
from isceobj.Sensor.ScanSAR import SENSORS
print(self.__doc__)
lsensors = list(SENSORS.keys())
lsensors.sort()
print("The currently supported sensors are: ", lsensors)
return None
def help_steps(self):
print(self.__doc__)
print("A description of the individual steps can be found in the README file")
print("and also in the ISCE.pdf document")
return
def renderProcDoc(self):
self.procDoc.renderXml()
def startup(self):
self.help()
self._insar.timeStart = time.time()
def endup(self):
self.renderProcDoc()
self._insar.timeEnd = time.time()
logger.info("Total Time: %i seconds" %
(self._insar.timeEnd-self._insar.timeStart))
return None
## Add instance attribute RunWrapper functions, which emulate methods.
def _add_methods(self):
self.runPreprocessor = ScansarProc.createPreprocessor(self)
self.runCommonRangeSpectra = ScansarProc.createCommonRangeSpectra(self)
self.runEqualizeSlcs = ScansarProc.createEqualizeSlcs(self)
self.runEstimateBurstSync = ScansarProc.createEstimateBurstSync(self)
# self.runComputeBaseline = ScansarProc.createComputeBaseline(self)
# self.verifyDEM = ScansarProc.createVerifyDEM(self)
# self.verifyGeocodeDEM = ScansarProc.createVerifyGeocodeDEM(self)
# self.runTopo = ScansarProc.createTopo(self)
# self.runSubsetOverlaps = ScansarProc.createSubsetOverlaps(self)
# self.runCoarseOffsets = ScansarProc.createCoarseOffsets(self)
# self.runCoarseResamp = ScansarProc.createCoarseResamp(self)
# self.runOverlapIfg = ScansarProc.createOverlapIfg(self)
# self.runPrepESD = ScansarProc.createPrepESD(self)
# self.runESD = ScansarProc.createESD(self)
# self.runRangeCoreg = ScansarProc.createRangeCoreg(self)
# self.runFineOffsets = ScansarProc.createFineOffsets(self)
# self.runFineResamp = ScansarProc.createFineResamp(self)
# self.runBurstIfg = ScansarProc.createBurstIfg(self)
# self.runMergeBursts = ScansarProc.createMergeBursts(self)
# self.runFilter = ScansarProc.createFilter(self)
# self.runGeocode = ScansarProc.createGeocode(self)
# self.runDenseOffsets = ScansarProc.createDenseOffsets(self)
# self.runOffsetFilter = ScansarProc.createOffsetFilter(self)
return None
def _steps(self):
self.step('startup', func=self.startup,
doc=("Print a helpful message and "+
"set the startTime of processing")
)
# Run a preprocessor for the two sets of frames
self.step('preprocess',
func=self.runPreprocessor,
doc=(
"""Preprocess the master and slave sensor data to raw images"""
)
)
# Run common range spectra filtering
self.step('commonrangespectra',
func=self.runCommonRangeSpectra,
doc=("""Filter images to common range spectra"""))
#Run image equalization to make pixels same size
self.step('equalizeslcs',
func=self.runEqualizeSlcs,
doc=("""Make pixel sizes the same"""))
#Run estimation of burst sync
self.step('estimateburstsync',
func=self.runEstimateBurstSync,
doc=("""Estimate amount of burst sync"""))
# Compute baselines and estimate common bursts
#self.step('computeBaselines',
# func=self.runComputeBaseline,
# doc=(
# """Compute baseline and number of common bursts"""
# )
# )
# Verify whether the DEM was initialized properly. If not, download
# a DEM
#self.step('verifyDEM', func=self.verifyDEM)
##Run topo for each bursts
#self.step('topo', func=self.runTopo)
##Run subset overlaps
#self.step('subsetoverlaps', func=self.runSubsetOverlaps)
##Run coarse offsets
#self.step('coarseoffsets', func=self.runCoarseOffsets)
####Run coarse resamp
#self.step('coarseresamp', func=self.runCoarseResamp)
####Run overlap ifgs
#self.step('overlapifg', func=self.runOverlapIfg)
###Run prepare ESD inputs
#self.step('prepesd', func=self.runPrepESD)
###Run ESD
#self.step('esd', func=self.runESD)
###Run range coregistration
#self.step('rangecoreg', func=self.runRangeCoreg)
###Estimate fine offsets
#self.step('fineoffsets', func=self.runFineOffsets)
###Resample slave bursts
#self.step('fineresamp', func=self.runFineResamp)
####Create burst interferograms
#self.step('burstifg', func=self.runBurstIfg)
###Merge burst products into a single file
#self.step('mergebursts', func=self.runMergeBursts)
###Filter the interferogram
#self.step('filter', func=self.runFilter)
# Unwrap ?
#self.step('unwrap', func=self.runUnwrapper)
# Conditional 2 stage unwrapping
#self.step('unwrap2stage', func=self.runUnwrap2Stage,
# args=(self.unwrapper_2stage_name, self.solver_2stage))
# Geocode
#self.step('geocode', func=self.runGeocode,
# args=(self.geocode_list, self.do_unwrap, self.geocode_bbox))
# Dense offsets
#self.step('denseoffsets', func=self.runDenseOffsets)
#Filter offsets
#self.step('filteroffsets', func=self.runOffsetFilter)
#Geocode offsets
#self.step('geocodeoffsets', func=self.runGeocode,
# args=(self.off_geocode_list, False, self.geocode_bbox, True))
# self.step('endup', func=self.endup)
return None
## Main has the common start to both insarApp and dpmApp.
def main(self):
self.help()
timeStart= time.time()
# Run a preprocessor for the two sets of frames
self.runPreprocessor()
#Filter to common range spectra
self.runCommonRangeSpectra()
#Make pixels the same size
self.runEqualizeSlcs()
#Estimate amount of burst sync
self.runEstimateBurstSync()
#Compute baselines and common bursts
#self.runComputeBaseline()
#Verify whether user defined a dem component. If not, then download
# SRTM DEM.
#self.verifyDEM()
##Run topo for each burst
#self.runTopo()
##Run subset overlaps
#self.runSubsetOverlaps()
##Run coarse offsets
#self.runCoarseOffsets()
##Run coarse resamp
#self.runCoarseResamp()
##Run ifg
#self.runOverlapIfg()
##Prepare for ESD
#self.runPrepESD()
#Run ESD
#self.runESD()
###Estimate range misregistration
#self.runRangeCoreg()
###Estimate fine offsets
#self.runFineOffsets()
###Resample slave bursts
#self.runFineResamp()
###Create burst interferograms
#self.runBurstIfg()
####Merge bursts into single files
#self.runMergeBursts()
###Filter the interferogram
#self.runFilter()
#add water mask to coherence and interferogram
#self.runMaskImages()
# Unwrap ?
#self.runUnwrapper()
# 2Stage Unwrapping
#self.runUnwrap2Stage(self.unwrapper_2stage_name, self.solver_2stage)
# Geocode
#self.runGeocode(self.geocode_list, self.do_unwrap, self.geocode_bbox)
#Dense offsets
#self.runDenseOffsets()
#Filter offsets
#self.runOffsetFilter()
#Geocode offsets
#self.runGeocode(self.off_geocode_list, False, self.geocode_bbox, True)
timeEnd = time.time()
logger.info("Total Time: %i seconds" %(timeEnd - timeStart))
self.renderProcDoc()
return None
if __name__ == "__main__":
import sys
insar = ScansarInSAR(name="scansarApp")
insar.configure()
insar.run()

136
applications/stitcher.py Executable file
View File

@ -0,0 +1,136 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import isce
import logging
import logging.config
from iscesys.Component.Application import Application
from iscesys.Component.Component import Component
import os
STITCHER = Component.Parameter('_stitcher',
public_name='stitcher',
default = 'version3',
type = str,
mandatory = False,
doc = "Use as argument for the stitcher factory. Supported old version 2 or new version 3 SRTM")
class Stitcher(Application):
def main(self):
# prevent from deleting local files
if(self.demStitcher._useLocalDirectory):
self.demStitcher._keepAfterFailed = True
self.demStitcher._keepDems = True
# is a metadata file is created set the right type
if(self.demStitcher._meta == 'xml'):
self.demStitcher.setCreateXmlMetadata(True)
elif(self.demStitcher._meta == 'rsc'):
self.demStitcher.setCreateRscMetadata(True)
# check for the action to be performed
if(self.demStitcher._action == 'stitch'):
if(self.demStitcher._bbox):
lat = self.demStitcher._bbox[0:2]
lon = self.demStitcher._bbox[2:4]
if (self.demStitcher._outputFile is None):
self.demStitcher._outputFile = self.demStitcher.defaultName(self.demStitcher._bbox)
if not(self.demStitcher.stitchDems(lat,lon,self.demStitcher._source,self.demStitcher._outputFile,self.demStitcher._downloadDir, \
keep=self.demStitcher._keepDems)):
print('Could not create a stitched DEM. Some tiles are missing')
else:
if(self.demStitcher._correct):
width = self.demStitcher.getDemWidth(lon,self.demStitcher._source)
self.demStitcher.correct()
#self.demStitcher.correct(self.demStitcher._output,self.demStitcher._source,width,min(lat[0],lat[1]),min(lon[0],lon[1]))
else:
print('Error. The --bbox (or -b) option must be specified when --action stitch is used')
raise ValueError
elif(self.demStitcher._action == 'download'):
if(self.demStitcher._bbox):
lat = self.demStitcher._bbox[0:2]
lon = self.demStitcher._bbox[2:4]
self.demStitcher.getDemsInBox(lat,lon,self.demStitcher._source,self.demStitcher._downloadDir)
#can make the bbox and pairs mutually esclusive if replace the if below with elif
if(self.demStitcher._pairs):
self.demStitcher.downloadFilesFromList(self.demStitcher._pairs[::2],self.demStitcher._pairs[1::2],self.demStitcher._source,self.demStitcher._downloadDir)
if(not (self.demStitcher._bbox or self.demStitcher._pairs)):
print('Error. Either the --bbox (-b) or the --pairs (-p) options must be specified when --action download is used')
raise ValueError
else:
print('Unrecognized action -a or --action',self.demStitcher._action)
return
if(self.demStitcher._report):
for k,v in list(self.demStitcher._downloadReport.items()):
print(k,'=',v)
def _facilities(self):
"""
Define the user configurable facilities for this application.
"""
self.demStitcher = self.facility(
'demStitcher',
public_name='demStitcher',
module='contrib.demUtils',
factory='createDemStitcher',
args=(self.stitcher,'iscestitcher',),
mandatory=False,
doc=(
"Object that based on the frame bounding boxes creates a DEM"
)
)
def Usage(self):
print("\nUsage: stitcher.py input.xml\n")
print("NOTE: if you don't want to store your password in a file you can run it as\n" +\
"'stitcher.py input.xml sticher.demStitcher.username=yourUsername\n" +\
"sticher.demStitcher.password=yourPassword'\n\n" )
family = 'stitcher'
parameter_list = (STITCHER,)
@property
def stitcher(self):
return self._stitcher
@stitcher.setter
def stitcher(self,stitcher):
self._stitcher = stitcher
def __init__(self,family = '', name = ''):
super(Stitcher, self).__init__(family if family else self.__class__.family, name=name)
if __name__ == "__main__":
import sys
ds = Stitcher()
ds.configure()
ds.run()

989
applications/stripmapApp.py Executable file
View File

@ -0,0 +1,989 @@
#!/usr/bin/env python3
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright by California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Heresh Fattahi
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import print_function
import time
import os
import sys
import logging
import logging.config
import isce
import isceobj
import iscesys
from iscesys.Component.Application import Application
from iscesys.Compatibility import Compatibility
from iscesys.Component.Configurable import SELF
import isceobj.StripmapProc as StripmapProc
from isceobj.Scene.Frame import FrameMixin
from isceobj.Util.decorators import use_api
logging.config.fileConfig(
os.path.join(os.environ['ISCE_HOME'], 'defaults', 'logging',
'logging.conf')
)
logger = logging.getLogger('isce.insar')
SENSOR_NAME = Application.Parameter(
'sensorName',
public_name='sensor name',
default = None,
type = str,
mandatory = False,
doc = 'Sensor name for both master and slave')
MASTER_SENSOR_NAME = Application.Parameter(
'masterSensorName',
public_name='master sensor name',
default = None,
type=str,
mandatory = True,
doc = "Master sensor name if mixing sensors")
SLAVE_SENSOR_NAME = Application.Parameter(
'slaveSensorName',
public_name='slave sensor name',
default = None,
type=str,
mandatory = True,
doc = "Slave sensor name if mixing sensors")
CORRELATION_METHOD = Application.Parameter(
'correlation_method',
public_name='correlation_method',
default='cchz_wave',
type=str,
mandatory=False,
doc=(
"""Select coherence estimation method:
cchz=cchz_wave
phase_gradient=phase gradient"""
)
)
MASTER_DOPPLER_METHOD = Application.Parameter(
'masterDopplerMethod',
public_name='master doppler method',
default=None,
type=str, mandatory=False,
doc= "Doppler calculation method.Choices: 'useDOPIQ', 'useDefault'."
)
SLAVE_DOPPLER_METHOD = Application.Parameter(
'slaveDopplerMethod',
public_name='slave doppler method',
default=None,
type=str, mandatory=False,
doc="Doppler calculation method. Choices: 'useDOPIQ','useDefault'.")
UNWRAPPER_NAME = Application.Parameter(
'unwrapper_name',
public_name='unwrapper name',
default='grass',
type=str,
mandatory=False,
doc="Unwrapping method to use. To be used in combination with UNWRAP."
)
DO_UNWRAP = Application.Parameter(
'do_unwrap',
public_name='do unwrap',
default=True,
type=bool,
mandatory=False,
doc="True if unwrapping is desired. To be unsed in combination with UNWRAPPER_NAME."
)
DO_UNWRAP_2STAGE = Application.Parameter(
'do_unwrap_2stage',
public_name='do unwrap 2 stage',
default=False,
type=bool,
mandatory=False,
doc="True if unwrapping is desired. To be unsed in combination with UNWRAPPER_NAME."
)
UNWRAPPER_2STAGE_NAME = Application.Parameter(
'unwrapper_2stage_name',
public_name='unwrapper 2stage name',
default='REDARC0',
type=str,
mandatory=False,
doc="2 Stage Unwrapping method to use. Available: MCF, REDARC0, REDARC1, REDARC2"
)
SOLVER_2STAGE = Application.Parameter(
'solver_2stage',
public_name='SOLVER_2STAGE',
default='pulp',
type=str,
mandatory=False,
doc='Linear Programming Solver for 2Stage; Options: pulp, gurobi, glpk; Used only for Redundant Arcs'
)
USE_HIGH_RESOLUTION_DEM_ONLY = Application.Parameter(
'useHighResolutionDemOnly',
public_name='useHighResolutionDemOnly',
default=False,
type=int,
mandatory=False,
doc=(
"""If True and a dem is not specified in input, it will only
download the SRTM highest resolution dem if it is available
and fill the missing portion with null values (typically -32767)."""
)
)
DEM_FILENAME = Application.Parameter(
'demFilename',
public_name='demFilename',
default='',
type=str,
mandatory=False,
doc="Filename of the DEM init file"
)
REGION_OF_INTEREST = Application.Parameter(
'regionOfInterest',
public_name = 'regionOfInterest',
default = None,
container = list,
type = float,
doc = 'Region of interest - South, North, West, East in degrees')
GEOCODE_BOX = Application.Parameter(
'geocode_bbox',
public_name='geocode bounding box',
default = None,
container=list,
type=float,
doc='Bounding box for geocoding - South, North, West, East in degrees'
)
GEO_POSTING = Application.Parameter(
'geoPosting',
public_name='geoPosting',
default=None,
type=float,
mandatory=False,
doc=(
"Output posting for geocoded images in degrees (latitude = longitude)"
)
)
POSTING = Application.Parameter(
'posting',
public_name='posting',
default=30,
type=int,
mandatory=False,
doc="posting for interferogram")
NUMBER_RANGE_LOOKS = Application.Parameter(
'numberRangeLooks',
public_name='range looks',
default=None,
type=int,
mandatory=False,
doc='Number of range looks'
)
NUMBER_AZIMUTH_LOOKS = Application.Parameter(
'numberAzimuthLooks',
public_name='azimuth looks',
default=None,
type=int,
mandatory=False,
doc='Number of azimuth looks'
)
FILTER_STRENGTH = Application.Parameter('filterStrength',
public_name='filter strength',
default=0.5,
type=float,
mandatory=False,
doc='')
DO_RUBBERSHEETING = Application.Parameter('doRubbersheeting',
public_name='do rubbersheeting',
default=False,
type=bool,
mandatory=False,
doc='')
RUBBERSHEET_SNR_THRESHOLD = Application.Parameter('rubberSheetSNRThreshold',
public_name='rubber sheet SNR Threshold',
default = 5.0,
type = float,
mandatory = False,
doc='')
RUBBERSHEET_FILTER_SIZE = Application.Parameter('rubberSheetFilterSize',
public_name='rubber sheet filter size',
default = 8,
type = int,
mandatory = False,
doc = '')
DO_DENSEOFFSETS = Application.Parameter('doDenseOffsets',
public_name='do denseoffsets',
default=False,
type=bool,
mandatory=False,
doc='')
DENSE_WINDOW_WIDTH = Application.Parameter('denseWindowWidth',
public_name='dense window width',
default=64,
type = int,
mandatory = False,
doc = '')
DENSE_WINDOW_HEIGHT = Application.Parameter('denseWindowHeight',
public_name='dense window height',
default=64,
type = int,
mandatory = False,
doc = '')
DENSE_SEARCH_WIDTH = Application.Parameter('denseSearchWidth',
public_name='dense search width',
default=20,
type = int,
mandatory = False,
doc = '')
DENSE_SEARCH_HEIGHT = Application.Parameter('denseSearchHeight',
public_name='dense search height',
default=20,
type = int,
mandatory = False,
doc = '')
DENSE_SKIP_WIDTH = Application.Parameter('denseSkipWidth',
public_name='dense skip width',
default=32,
type = int,
mandatory = False,
doc = '')
DENSE_SKIP_HEIGHT = Application.Parameter('denseSkipHeight',
public_name='dense skip height',
default=32,
type = int,
mandatory = False,
doc = '')
DO_SPLIT_SPECTRUM = Application.Parameter('doSplitSpectrum',
public_name='do split spectrum',
default = False,
type = bool,
mandatory = False,
doc = '')
DO_DISPERSIVE = Application.Parameter('doDispersive',
public_name='do dispersive',
default=False,
type=bool,
mandatory=False,
doc='')
GEOCODE_LIST = Application.Parameter(
'geocode_list',
public_name='geocode list',
default = None,
container=list,
type=str,
doc = "List of products to geocode."
)
OFFSET_GEOCODE_LIST = Application.Parameter(
'off_geocode_list',
public_name='offset geocode list',
default=None,
container=list,
mandatory=False,
doc='List of offset-specific files to geocode')
HEIGHT_RANGE = Application.Parameter(
'heightRange',
public_name = 'height range',
default = None,
container = list,
type = float,
doc = 'Altitude range in scene for cropping')
PICKLE_DUMPER_DIR = Application.Parameter(
'pickleDumpDir',
public_name='pickle dump directory',
default='PICKLE',
type=str,
mandatory=False,
doc=(
"If steps is used, the directory in which to store pickle objects."
)
)
PICKLE_LOAD_DIR = Application.Parameter(
'pickleLoadDir',
public_name='pickle load directory',
default='PICKLE',
type=str,
mandatory=False,
doc=(
"If steps is used, the directory from which to retrieve pickle objects."
)
)
RENDERER = Application.Parameter(
'renderer',
public_name='renderer',
default='xml',
type=str,
mandatory=True,
doc=(
"Format in which the data is serialized when using steps. Options are xml (default) or pickle."
)
)
DISPERSIVE_FILTER_KERNEL_XSIZE = Application.Parameter('kernel_x_size',
public_name='dispersive filter kernel x-size',
default=800,
type=float,
mandatory=False,
doc='kernel x-size for the Gaussian low-pass filtering of the dispersive and non-disperive phase')
DISPERSIVE_FILTER_KERNEL_YSIZE = Application.Parameter('kernel_y_size',
public_name='dispersive filter kernel y-size',
default=800,
type=float,
mandatory=False,
doc='kernel y-size for the Gaussian low-pass filtering of the dispersive and non-disperive phase')
DISPERSIVE_FILTER_KERNEL_SIGMA_X = Application.Parameter('kernel_sigma_x',
public_name='dispersive filter kernel sigma_x',
default=100,
type=float,
mandatory=False,
doc='kernel sigma_x for the Gaussian low-pass filtering of the dispersive and non-disperive phase')
DISPERSIVE_FILTER_KERNEL_SIGMA_Y = Application.Parameter('kernel_sigma_y',
public_name='dispersive filter kernel sigma_y',
default=100,
type=float,
mandatory=False,
doc='kernel sigma_y for the Gaussian low-pass filtering of the dispersive and non-disperive phase')
DISPERSIVE_FILTER_KERNEL_ROTATION = Application.Parameter('kernel_rotation',
public_name='dispersive filter kernel rotation',
default=0.0,
type=float,
mandatory=False,
doc='kernel rotation angle for the Gaussian low-pass filtering of the dispersive and non-disperive phase')
DISPERSIVE_FILTER_ITERATION_NUMBER = Application.Parameter('dispersive_filter_iterations',
public_name='dispersive filter number of iterations',
default=5,
type=int,
mandatory=False,
doc='number of iterations for the iterative low-pass filtering of the dispersive and non-disperive phase')
DISPERSIVE_FILTER_MASK_TYPE = Application.Parameter('dispersive_filter_mask_type',
public_name='dispersive filter mask type',
default="connected_components",
type=str,
mandatory=False,
doc='The type of mask for the iterative low-pass filtering of the estimated dispersive phase. If method is coherence, then a mask based on coherence files of low-band and sub-band interferograms is generated using the mask coherence thresold which can be also setup. If method is connected_components, then mask is formed based on connected component files with non zero values. If method is phase, then pixels with zero phase values in unwrapped sub-band interferograms are masked out.')
DISPERSIVE_FILTER_COHERENCE_THRESHOLD = Application.Parameter('dispersive_filter_coherence_threshold',
public_name='dispersive filter coherence threshold',
default=0.5,
type=float,
mandatory=False,
doc='Coherence threshold to generate a mask file which gets used in the iterative filtering of the dispersive and non-disperive phase')
#Facility declarations
MASTER = Application.Facility(
'master',
public_name='Master',
module='isceobj.StripmapProc.Sensor',
factory='createSensor',
args=(SENSOR_NAME, MASTER_SENSOR_NAME, 'master'),
mandatory=False,
doc="Master raw data component"
)
SLAVE = Application.Facility(
'slave',
public_name='Slave',
module='isceobj.StripmapProc.Sensor',
factory='createSensor',
args=(SENSOR_NAME, SLAVE_SENSOR_NAME,'slave'),
mandatory=False,
doc="Slave raw data component"
)
DEM_STITCHER = Application.Facility(
'demStitcher',
public_name='demStitcher',
module='iscesys.DataManager',
factory='createManager',
args=('dem1','iscestitcher',),
mandatory=False,
doc="Object that based on the frame bounding boxes creates a DEM"
)
RUN_UNWRAPPER = Application.Facility(
'runUnwrapper',
public_name='Run unwrapper',
module='isceobj.StripmapProc',
factory='createUnwrapper',
args=(SELF(), DO_UNWRAP, UNWRAPPER_NAME),
mandatory=False,
doc="Unwrapping module"
)
RUN_UNWRAP_2STAGE = Application.Facility(
'runUnwrap2Stage',
public_name='Run unwrapper 2 Stage',
module='isceobj.TopsProc',
factory='createUnwrap2Stage',
args=(SELF(), DO_UNWRAP_2STAGE, UNWRAPPER_NAME),
mandatory=False,
doc="Unwrapping module"
)
_INSAR = Application.Facility(
'_insar',
public_name='insar',
module='isceobj.StripmapProc',
factory='createStripmapProc',
args = ('stripmapAppContext',isceobj.createCatalog('stripmapProc')),
mandatory=False,
doc="InsarProc object"
)
## Common interface for stripmap insar applications.
class _RoiBase(Application, FrameMixin):
family = 'insar'
## Define Class parameters in this list
parameter_list = (SENSOR_NAME,
MASTER_SENSOR_NAME,
SLAVE_SENSOR_NAME,
FILTER_STRENGTH,
CORRELATION_METHOD,
MASTER_DOPPLER_METHOD,
SLAVE_DOPPLER_METHOD,
UNWRAPPER_NAME,
DO_UNWRAP,
DO_UNWRAP_2STAGE,
UNWRAPPER_2STAGE_NAME,
SOLVER_2STAGE,
USE_HIGH_RESOLUTION_DEM_ONLY,
DEM_FILENAME,
GEO_POSTING,
POSTING,
NUMBER_RANGE_LOOKS,
NUMBER_AZIMUTH_LOOKS,
GEOCODE_LIST,
OFFSET_GEOCODE_LIST,
GEOCODE_BOX,
REGION_OF_INTEREST,
HEIGHT_RANGE,
DO_RUBBERSHEETING,
RUBBERSHEET_SNR_THRESHOLD,
RUBBERSHEET_FILTER_SIZE,
DO_DENSEOFFSETS,
DENSE_WINDOW_WIDTH,
DENSE_WINDOW_HEIGHT,
DENSE_SEARCH_WIDTH,
DENSE_SEARCH_HEIGHT,
DENSE_SKIP_WIDTH,
DENSE_SKIP_HEIGHT,
DO_SPLIT_SPECTRUM,
PICKLE_DUMPER_DIR,
PICKLE_LOAD_DIR,
RENDERER,
DO_DISPERSIVE,
DISPERSIVE_FILTER_KERNEL_XSIZE,
DISPERSIVE_FILTER_KERNEL_YSIZE,
DISPERSIVE_FILTER_KERNEL_SIGMA_X,
DISPERSIVE_FILTER_KERNEL_SIGMA_Y,
DISPERSIVE_FILTER_KERNEL_ROTATION,
DISPERSIVE_FILTER_ITERATION_NUMBER,
DISPERSIVE_FILTER_MASK_TYPE,
DISPERSIVE_FILTER_COHERENCE_THRESHOLD)
facility_list = (MASTER,
SLAVE,
DEM_STITCHER,
RUN_UNWRAPPER,
RUN_UNWRAP_2STAGE,
_INSAR)
_pickleObj = "_insar"
def __init__(self, family='', name='',cmdline=None):
import isceobj
super().__init__(family=family, name=name,
cmdline=cmdline)
from isceobj.StripmapProc import StripmapProc
from iscesys.StdOEL.StdOELPy import create_writer
self._stdWriter = create_writer("log", "", True, filename="roi.log")
self._add_methods()
self._insarProcFact = StripmapProc
self.timeStart = None
return None
def Usage(self):
print("Usages: ")
print("stripmapApp.py <input-file.xml>")
print("stripmapApp.py --steps")
print("stripmapApp.py --help")
print("stripmapApp.py --help --steps")
def _init(self):
message = (
("ISCE VERSION = %s, RELEASE_SVN_REVISION = %s,"+
"RELEASE_DATE = %s, CURRENT_SVN_REVISION = %s") %
(isce.__version__,
isce.release_svn_revision,
isce.release_date,
isce.svn_revision)
)
logger.info(message)
print(message)
return None
## You need this to use the FrameMixin
@property
def frame(self):
return self.insar.frame
def _configure(self):
self.insar.procDoc._addItem("ISCE_VERSION",
"Release: %s, svn-%s, %s. Current svn-%s" %
(isce.release_version, isce.release_svn_revision,
isce.release_date, isce.svn_revision
),
["stripmapProc"]
)
#Ensure consistency in geocode_list maintained by insarApp and
#InsarProc. If it is configured in both places, the one in insarApp
#will be used. It is complicated to try to merge the two lists
#because InsarProc permits the user to change the name of the files
#and the linkage between filename and filetype is lost by the time
#geocode_list is fully configured. In order to safely change file
#names and also specify the geocode_list, then insarApp should not
#be given a geocode_list from the user.
if(self.geocode_list is not None):
#if geocode_list defined here, then give it to InsarProc
#for consistency between insarApp and InsarProc and warn the user
#check if the two geocode_lists differ in content
g_count = 0
for g in self.geocode_list:
if g not in self.insar.geocode_list:
g_count += 1
#warn if there are any differences in content
if g_count > 0:
print()
logger.warn((
"Some filenames in stripmapApp.geocode_list configuration "+
"are different from those in StripmapProc. Using names given"+
" to stripmapApp."))
print("stripmapApp.geocode_list = {}".format(self.geocode_list))
else:
self.geocode_list = self.insar.geocode_list
if (self.off_geocode_list is None):
self.off_geocode_list = self.insar.off_geocode_list
else:
g_count = 0
for g in self.off_geocode_list:
if g not in self.insar.off_geocode_list:
g_count += 1
if g_count > 0:
self.off_geocode_list = self.insar.off_geocode_list
return None
@property
def insar(self):
return self._insar
@insar.setter
def insar(self, value):
self._insar = value
return None
@property
def procDoc(self):
return self.insar.procDoc
@procDoc.setter
def procDoc(self):
raise AttributeError(
"Can not assign to .insar.procDoc-- but you hit all its other stuff"
)
def _finalize(self):
pass
def help(self):
from isceobj.Sensor import SENSORS
print(self.__doc__)
lsensors = list(SENSORS.keys())
lsensors.sort()
print("The currently supported sensors are: ", lsensors)
return None
def help_steps(self):
print(self.__doc__)
print("A description of the individual steps can be found in the README file")
print("and also in the ISCE.pdf document")
return
def renderProcDoc(self):
self.procDoc.renderXml()
def startup(self):
self.help()
self._insar.timeStart = time.time()
def endup(self):
self.renderProcDoc()
self._insar.timeEnd = time.time()
if hasattr(self._insar, 'timeStart'):
logger.info("Total Time: %i seconds" %
(self._insar.timeEnd-self._insar.timeStart))
return None
## Add instance attribute RunWrapper functions, which emulate methods.
def _add_methods(self):
self.runPreprocessor = StripmapProc.createPreprocessor(self)
self.runFormSLC = StripmapProc.createFormSLC(self)
self.runCrop = StripmapProc.createCrop(self)
self.runSplitSpectrum = StripmapProc.createSplitSpectrum(self)
self.runTopo = StripmapProc.createTopo(self)
self.runGeo2rdr = StripmapProc.createGeo2rdr(self)
self.runResampleSlc = StripmapProc.createResampleSlc(self)
self.runRefineSlaveTiming = StripmapProc.createRefineSlaveTiming(self)
self.runDenseOffsets = StripmapProc.createDenseOffsets(self)
self.runRubbersheet = StripmapProc.createRubbersheet(self)
self.runResampleSubbandSlc = StripmapProc.createResampleSubbandSlc(self)
self.runInterferogram = StripmapProc.createInterferogram(self)
self.runFilter = StripmapProc.createFilter(self)
self.runDispersive = StripmapProc.createDispersive(self)
self.verifyDEM = StripmapProc.createVerifyDEM(self)
self.runGeocode = StripmapProc.createGeocode(self)
return None
def _steps(self):
self.step('startup', func=self.startup,
doc=("Print a helpful message and "+
"set the startTime of processing")
)
# Run a preprocessor for the two sets of frames
self.step('preprocess',
func=self.runPreprocessor,
doc=(
"""Preprocess the master and slave sensor data to raw images"""
)
)
self.step('cropraw',
func = self.runCrop,
args=(True,))
self.step('formslc', func=self.runFormSLC)
self.step('cropslc', func=self.runCrop,
args=(False,))
# Verify whether the DEM was initialized properly. If not, download
# a DEM
self.step('verifyDEM', func=self.verifyDEM)
self.step('topo', func=self.runTopo)
self.step('geo2rdr', func=self.runGeo2rdr)
self.step('coarse_resample', func=self.runResampleSlc,
args=('coarse',))
self.step('misregistration', func=self.runRefineSlaveTiming)
self.step('refined_resample', func=self.runResampleSlc,
args=('refined',))
self.step('dense_offsets', func=self.runDenseOffsets)
self.step('rubber_sheet', func=self.runRubbersheet)
self.step('fine_resample', func=self.runResampleSlc,
args=('fine',))
self.step('split_range_spectrum', func=self.runSplitSpectrum)
self.step('sub_band_resample', func=self.runResampleSubbandSlc,
args=(True,))
self.step('interferogram', func=self.runInterferogram)
self.step('sub_band_interferogram', func=self.runInterferogram,
args=("sub",))
self.step('filter', func=self.runFilter,
args=(self.filterStrength,))
self.step('filter_low_band', func=self.runFilter,
args=(self.filterStrength,"low",))
self.step('filter_high_band', func=self.runFilter,
args=(self.filterStrength,"high",))
self.step('unwrap', func=self.runUnwrapper)
self.step('unwrap_low_band', func=self.runUnwrapper, args=("low",))
self.step('unwrap_high_band', func=self.runUnwrapper, args=("high",))
self.step('ionosphere', func=self.runDispersive)
self.step('geocode', func=self.runGeocode,
args=(self.geocode_list, self.geocode_bbox))
self.step('geocodeoffsets', func=self.runGeocode,
args=(self.off_geocode_list, self.geocode_bbox, True))
return None
## Main has the common start to both insarApp and dpmApp.
#@use_api
def main(self):
self.timeStart = time.time()
self.help()
# Run a preprocessor for the two sets of frames
self.runPreprocessor()
#Crop raw data if desired
self.runCrop(True)
self.runFormSLC()
self.runCrop(False)
#Verify whether user defined a dem component. If not, then download
# SRTM DEM.
self.verifyDEM()
# run topo (mapping from radar to geo coordinates)
self.runTopo()
# run geo2rdr (mapping from geo to radar coordinates)
self.runGeo2rdr()
# resampling using only geometry offsets
self.runResampleSlc('coarse')
# refine geometry offsets using offsets computed by cross correlation
self.runRefineSlaveTiming()
# resampling using refined offsets
self.runResampleSlc('refined')
# run dense offsets
self.runDenseOffsets()
# adding the azimuth offsets computed from cross correlation to geometry offsets
self.runRubbersheet()
# resampling using rubbersheeted offsets
# which include geometry + constant range + constant azimuth
# + dense azimuth offsets
self.runResampleSlc('fine')
#run split range spectrum
self.runSplitSpectrum()
self.runResampleSubbandSlc(misreg=True)
# forming the interferogram
self.runInterferogram()
self.runInterferogram(igramSpectrum = "sub")
# Filtering and estimating coherence
self.runFilter(self.filterStrength)
self.runFilter(self.filterStrength, igramSpectrum = "low")
self.runFilter(self.filterStrength, igramSpectrum = "high")
# unwrapping
self.runUnwrapper()
self.runUnwrapper(igramSpectrum = "low")
self.runUnwrapper(igramSpectrum = "high")
self.runDispersive()
self.runGeocode(self.geocode_list, self.geocode_bbox)
self.runGeocode(self.geocode_list, self.geocode_bbox, True)
self.timeEnd = time.time()
logger.info("Total Time: %i seconds" %(self.timeEnd - self.timeStart))
self.renderProcDoc()
return None
class Insar(_RoiBase):
"""
Insar Application:
Implements InSAR processing flow for a pair of scenes from
sensor raw data to geocoded, flattened interferograms.
"""
family = "insar"
def __init__(self, family='',name='',cmdline=None):
#to allow inheritance with different family name use the locally
#defined only if the subclass (if any) does not specify one
super().__init__(
family=family if family else self.__class__.family, name=name,
cmdline=cmdline)
def Usage(self):
print("Usages: ")
print("stripmapApp.py <input-file.xml>")
print("stripmapApp.py --steps")
print("stripmapApp.py --help")
print("stripmapApp.py --help --steps")
## extends _InsarBase_steps, but not in the same was as main
def _steps(self):
super()._steps()
# Geocode
#self.step('geocode', func=self.runGeocode,
# args=(self.geocode_list, self.unwrap, self.geocode_bbox))
self.step('endup', func=self.endup)
return None
## main() extends _InsarBase.main()
def main(self):
super().main()
print("self.timeStart = {}".format(self.timeStart))
# self.runCorrect()
#self.runRgoffset()
# Cull offoutliers
#self.iterate_runOffoutliers()
self.runResampleSlc()
#self.runResamp_only()
self.runRefineSlaveTiming()
#self.insar.topoIntImage=self.insar.resampOnlyImage
#self.runTopo()
# self.runCorrect()
# Coherence ?
#self.runCoherence(method=self.correlation_method)
# Filter ?
self.runFilter(self.filterStrength)
# Unwrap ?
self.runUnwrapper()
# Geocode
#self.runGeocode(self.geocode_list, self.unwrap, self.geocode_bbox)
timeEnd = time.time()
logger.info("Total Time: %i seconds" %(timeEnd - self.timeStart))
self.renderProcDoc()
return None
if __name__ == "__main__":
#make an instance of Insar class named 'stripmapApp'
insar = Insar(name="stripmapApp")
#configure the insar application
insar.configure()
#invoke the base class run method, which returns status
status = insar.run()
#inform Python of the status of the run to return to the shell
raise SystemExit(status)

1048
applications/topsApp.py Executable file

File diff suppressed because it is too large Load Diff

338
applications/topsOffsetApp.py Executable file
View File

@ -0,0 +1,338 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2016 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Joshua Cohen
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import time
import os
import sys
import logging
import logging.config
import isce
import isceobj
from isceobj import TopsProc
from isce.applications.topsApp import TopsInSAR
from iscesys.Component.Application import Application
from isceobj.Util.decorators import use_api
logging.config.fileConfig(
os.path.join(os.environ['ISCE_HOME'], 'defaults', 'logging',
'logging.conf')
)
logger = logging.getLogger('isce.insar')
WINDOW_SIZE_WIDTH = Application.Parameter(
'winwidth',
public_name='Ampcor window width',
default=32,
type=int,
mandatory=False,
doc='Ampcor main window size width. Used in runDenseOffsets.'
)
WINDOW_SIZE_HEIGHT = Application.Parameter(
'winhgt',
public_name='Ampcor window height',
default=32,
type=int,
mandatory=False,
doc='Ampcor main window size height. Used in runDenseOffsets.'
)
SEARCH_WINDOW_WIDTH = Application.Parameter(
'srcwidth',
public_name='Ampcor search window width',
default=20,
type=int,
mandatory=False,
doc='Ampcor search window size width. Used in runDenseOffsets.'
)
SEARCH_WINDOW_HEIGHT = Application.Parameter(
'srchgt',
public_name='Ampcor search window height',
default=20,
type=int,
mandatory=False,
doc='Ampcor search window size height. Used in runDenseOffsets.'
)
SKIP_SAMPLE_ACROSS = Application.Parameter(
'skipwidth',
public_name='Ampcor skip width',
default=16,
type=int,
mandatory=False,
doc='Ampcor skip across width. Used in runDenseOffsets.'
)
SKIP_SAMPLE_DOWN = Application.Parameter(
'skiphgt',
public_name='Ampcor skip height',
default=16,
type=int,
mandatory=False,
doc='Ampcor skip down height. Used in runDenseOffsets.'
)
OFFSET_MARGIN = Application.Parameter(
'margin',
public_name='Ampcor margin',
default=50,
type=int,
mandatory=False,
doc='Ampcor margin offset. Used in runDenseOffsets.'
)
OVERSAMPLING_FACTOR = Application.Parameter(
'oversample',
public_name='Ampcor oversampling factor',
default=32,
type=int,
mandatory=False,
doc='Ampcor oversampling factor. Used in runDenseOffsets.'
)
ACROSS_GROSS_OFFSET = Application.Parameter(
'rgshift',
public_name='Range shift',
default=0,
type=int,
mandatory=False,
doc='Ampcor gross offset across. Used in runDenseOffsets.'
)
DOWN_GROSS_OFFSET = Application.Parameter(
'azshift',
public_name='Azimuth shift',
default=0,
type=int,
mandatory=False,
doc='Ampcor gross offset down. Used in runDenseOffsets.'
)
OFFSET_SCALING_FACTOR = Application.Parameter(
'scale_factor',
public_name='Offset scaling factor',
default=1.0,
type=float,
mandatory=False,
doc='Offset field unit scaling factor (1.0 default is pixel)'
)
OFFSET_WIDTH = Application.Parameter(
'offset_width',
public_name='Offset image nCols',
default=None,
type=int,
mandatory=False,
doc='Number of columns in the final offset field (calculated in DenseAmpcor).'
)
OFFSET_LENGTH = Application.Parameter(
'offset_length',
public_name='Offset image nRows',
default=None,
type=int,
mandatory=False,
doc='Number of rows in the final offset field (calculated in DenseAmpcor).'
)
OFFSET_TOP = Application.Parameter(
'offset_top',
public_name='Top offset location',
default=None,
type=int,
mandatory=False,
doc='Ampcor-calculated top offset location. Overridden by workflow.'
)
OFFSET_LEFT = Application.Parameter(
'offset_left',
public_name='Left offset location',
default=None,
type=int,
mandatory=False,
doc='Ampcor-calculated left offset location. Overridden by workflow.'
)
SNR_THRESHOLD = Application.Parameter(
'snr_thresh',
public_name='SNR Threshold factor',
default=None,
type=float,
mandatory=False,
doc='SNR Threshold factor used in filtering offset field objects.'
)
FILTER_NULL = Application.Parameter(
'filt_null',
public_name='Filter NULL factor',
default=-10000.,
type=float,
mandatory=False,
doc='NULL factor to use in filtering offset fields to avoid numpy type issues.'
)
FILTER_WIN_SIZE = Application.Parameter(
'filt_size',
public_name='Filter window size',
default=5,
type=int,
mandatory=False,
doc='Window size for median_filter.'
)
OFFSET_OUTPUT_FILE = Application.Parameter(
'offsetfile',
public_name='Offset filename',
default='dense_offsets',
type=None,
mandatory=False,
doc='Filename for gross dense offsets BIL. Used in runDenseOffsets.'
)
FILT_OFFSET_OUTPUT_FILE = Application.Parameter(
'filt_offsetfile',
public_name='Filtered offset filename',
default='filt_dense_offsets',
type=None,
mandatory=False,
doc='Filename for filtered dense offsets BIL.'
)
OFFSET_MODE = Application.Parameter(
'off_mode',
public_name='Is offset mode',
default=True,
type=bool,
mandatory=False,
doc='Application-specific parameter to indicate whether running topsApp or topsOffsetApp.'
)
OFFSET_GEOCODE_LIST = Application.Parameter(
'off_geocode_list',
public_name='offset geocode list',
default=None,
container=list,
type=str,
mandatory=False,
doc='List of offset-specific files to geocode.'
)
#Basically extends the TopsInSAR class
class TopsOffset(TopsInSAR):
# Pull TopsInSAR's parameter/facility lists
parameter_list = TopsInSAR.parameter_list + ( \
WINDOW_SIZE_WIDTH,
WINDOW_SIZE_HEIGHT,
SEARCH_WINDOW_WIDTH,
SEARCH_WINDOW_HEIGHT,
SKIP_SAMPLE_ACROSS,
SKIP_SAMPLE_DOWN,
OFFSET_MARGIN,
OVERSAMPLING_FACTOR,
ACROSS_GROSS_OFFSET,
DOWN_GROSS_OFFSET,
OFFSET_SCALING_FACTOR,
OFFSET_WIDTH,
OFFSET_LENGTH,
OFFSET_TOP,
OFFSET_LEFT,
SNR_THRESHOLD,
FILTER_NULL,
FILTER_WIN_SIZE,
OFFSET_OUTPUT_FILE,
FILT_OFFSET_OUTPUT_FILE,
OFFSET_MODE,
OFFSET_GEOCODE_LIST)
facility_list = TopsInSAR.facility_list
family = 'topsinsar'
_pickleObj = '_insar'
def __init__(self, family='', name='',cmdline=None):
super().__init__(family=family if family else self.__class__.family, name=name,
cmdline=cmdline)
self._add_methods()
@use_api
def main(self):
timeStart = time.time()
#self._steps()
self.runMergeSLCs()
self.runDenseOffsets()
self.runCropOffsetGeo()
self.runOffsetFilter()
self.runOffsetGeocode()
timeEnd = time.time()
print('Total Time: %i seconds' % (timeEnd-timeStart))
return None
def _add_methods(self):
self.verifyDEM = TopsProc.createVerifyDEM(self) ### NOTE: Not independently called, needed for
self.runGeocode = TopsProc.createGeocode(self) ### runGeocode.py
self.runMergeSLCs = TopsProc.createMergeSLCs(self)
self.runDenseOffsets = TopsProc.createDenseOffsets(self)
self.runCropOffsetGeo = TopsProc.createCropOffsetGeo(self)
self.runOffsetFilter = TopsProc.createOffsetFilter(self)
self.runOffsetGeocode = TopsProc.createOffsetGeocode(self)
return None
def _steps(self):
self.step('startup', func=self.startup,
doc=('Print a helpful message and'+
'set the startTime of processing')
)
self.step('mergeSLCs', func=self.runMergeSLCs)
self.step('denseOffsets', func=self.runDenseOffsets)
self.step('cropOffsetGeo', func=self.runCropOffsetGeo)
self.step('offsetFilter', func=self.runOffsetFilter)
self.step('offsetGeocode', func=self.runOffsetGeocode)
return None
if __name__ == "__main__":
topsOffset = TopsOffset(name="topsOffsetApp")
topsOffset.configure()
topsOffset.run()

102
applications/upsampleDem.py Executable file
View File

@ -0,0 +1,102 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2013 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Piyush Agram
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
import logging
import sys
import isce
import argparse
from contrib.demUtils.UpsampleDem import UpsampleDem
from iscesys.Parsers.FileParserFactory import createFileParser
from isceobj.Image import createDemImage
class customArgparseFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter):
'''
For better help message that also shows the defaults.
'''
pass
def cmdLineParse():
'''
Command Line Parser.
'''
parser = argparse.ArgumentParser(description='Oversample DEM by integer factor.',
formatter_class=customArgparseFormatter,
epilog = '''
Example:
upsampleDem.py -i input.dem -o output.dem -f 4 4
This oversamples the input dem in both lat and lon by a factor of 4.''')
parser.add_argument('-i','--input', type=str, required=True, help='Input ISCE DEM with a corresponding .xml file.', dest='infile')
parser.add_argument('-o','--output',type=str, default=None, help='Output ISCE DEM with a corresponding .xml file.', dest='outfile')
parser.add_argument('-m', '--method', type=str, default='BIQUINTIC', help='Interpolation method out of Akima / Biquintic. Default: biquintic.', dest='method')
parser.add_argument('-f','--factor',type=int, nargs='+', required=True, help='Oversampling factor in lat and lon (or a single value for both).', dest='factor')
values = parser.parse_args()
if len(values.factor) > 2:
raise Exception('Factor should be a single number or a list of two. Undefined input for -f or --factor : '+str(values.factor))
elif len(values.factor) == 1:
values.factor = [values.factor[0], values.factor[0]]
return values
if __name__ == "__main__":
inps = cmdLineParse()
if inps.infile.endswith('.xml'):
inFileXml = inps.infile
inFile = os.path.splitext(inps.infile)[0]
else:
inFile = inps.infile
inFileXml = inps.infile + '.xml'
if inps.outfile.endswith('.xml'):
outFile = os.path.splitext(inps.outfile)[0]
else:
outFile = inps.outfile
parser = createFileParser('xml')
prop, fac, misc = parser.parse(inFileXml)
inImage = createDemImage()
inImage.init(prop,fac,misc)
inImage.filename = inFile
inImage.createImage()
upsampObj = UpsampleDem()
upsampObj.method = inps.method
upsampObj.setOutputFilename(outFile)
upsampObj.upsampledem(demImage=inImage, yFactor=inps.factor[0], xFactor=inps.factor[1])

82
applications/viewMetadata.py Executable file
View File

@ -0,0 +1,82 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Walter Szeliga
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
import logging
import logging.config
logging.config.fileConfig(os.path.join(os.environ['ISCE_HOME'], 'defaults',
'logging', 'logging.conf'))
from iscesys.Compatibility import Compatibility
Compatibility.checkPythonVersion()
from iscesys.Component.FactoryInit import FactoryInit
from isceobj.Renderer.XmlRenderer import XmlRenderer
class viewMetadataApp(FactoryInit):
def main(self):
self.logger.info('Parsing Metadata')
self.sensorObj.extractImage()
frame = self.sensorObj.getFrame()
instrument = frame.getInstrument()
platform = instrument.getPlatform()
orbit = frame.getOrbit()
attitude = frame.getAttitude()
print(platform)
print(instrument)
print(frame)
print(orbit)
for sv in orbit:
print(sv)
print(attitude)
for sv in attitude:
print(sv)
self.logger.info('Rendering Metadata')
self.renderer.setComponent(frame)
self.renderer.render()
def __init__(self,arglist):
FactoryInit.__init__(self)
self.initFactory(arglist)
self.logger = logging.getLogger('isce.viewMetadata')
self.sensorObj = self.getComponent('Sensor')
self.renderer = self.getComponent('XmlRenderer')
if __name__ == "__main__":
import sys
if (len(sys.argv) < 2):
print("Usage:%s <xml-parameter file>" % sys.argv[0])
sys.exit(1)
runObj = viewMetadataApp(sys.argv[1:])
runObj.main()

137
applications/waterMask.py Executable file
View File

@ -0,0 +1,137 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import print_function
import isce
import sys
import os
import argparse
from contrib.demUtils.WaterMask import MaskStitcher
import isceobj
def main():
#if not argument provided force the --help flag
if(len(sys.argv) == 1):
sys.argv.append('-h')
# Use the epilog to add usege eamples
epilog = 'Usage examples:\n\n'
epilog += 'mask.py -a stitch -i dem.xml -r -n your_username -w your_password -u https://aria-dav.jpl.nasa.gov/repository/products \n\n'
epilog += 'mask.py -a download -i dem.xml \n\n'
epilog += 'mask.py -a stitch -i dem.xml -k -r -l\n'
#set the formatter_class=argparse.RawDescriptionHelpFormatter othewise it splits the epilog lines with its own default format
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,epilog=epilog)
parser.add_argument('-a', '--action', type = str, default = 'stitch', dest = 'action', help = 'Possible actions: stitch or download (default: %(default)s). ')
parser.add_argument('-m', '--meta', type = str, default = 'xml', dest = 'meta', help = 'What type of metadata file is created. Possible values: \
xml or rsc (default: %(default)s)')
parser.add_argument('-i', '--input', type=str, required=True, dest='indem', help='Input DEM for which the land water mask is desired.')
parser.add_argument('-k', '--keep', action = 'store_true', dest = 'keep', help = 'If the option is present then the single files used for stitching are kept. If -l or --local is specified than the flag is automatically set (default: %(default)s)')
parser.add_argument('-r', '--report', action = 'store_true', dest = 'report', help = 'If the option is present then failed and succeeded downloads are printed (default: %(default)s)')
parser.add_argument('-l', '--local', action = 'store_true', dest = 'local', help = 'If the option is present then use the files that are in the location \
specified by --dir. If not present --dir indicates the directory where the files are downloaded (default: %(default)s)')
parser.add_argument('-d', '--dir', type = str, dest = 'dir', default = './', help = 'If used in conjunction with --local it specifies the location where the DEMs are located \
otherwise it specifies the directory where the DEMs are downloaded and the stitched DEM is generated (default: %(default)s)')
parser.add_argument('-o', '--output', type = str, dest = 'output', default = None, help = 'Name of the output file to be created in --dir. If not provided the system generates one based on the bbox extremes')
parser.add_argument('-n', '--uname', type = str, dest = 'uname', default = None, help = 'User name if using a server that requires authentication')
parser.add_argument('-w', '--password', type = str, dest = 'password', default = None, help = 'Password if using a server that requires authentication')
parser.add_argument('-u', '--url', type = str, dest = 'url', default = None, help = 'Part of the url where the DEM files are located. The actual location must be \
the one specified by --url plus /srtm/version2_1/SRTM(1,3)')
args = parser.parse_args()
#first get the url,uname and password since are needed in the constructor
ds = MaskStitcher()
ds.configure()
if(args.url):
ds.setUrl(args.url)
ds.setUsername(args.uname)
ds.setPassword(args.password)
ds._keepAfterFailed = True
#avoid to accidentally remove local file if -k is forgotten
#if one wants can remove them manually
if(args.local):
args.keep = True
if(args.meta == 'xml'):
ds.setCreateXmlMetadata(True)
elif(args.meta == 'rsc'):
ds.setCreateRscMetadata(True)
ds.setUseLocalDirectory(args.local)
####Parse input DEM xml to get bbox
inimg = isceobj.createDemImage()
inimg.load(args.indem + '.xml')
north = inimg.coord2.coordStart
south = north + inimg.coord2.coordDelta * (inimg.length-1)
west = inimg.coord1.coordStart
east = west + inimg.coord1.coordDelta * (inimg.width-1)
bbox = [south,north,west,east]
ds.setWidth(inimg.width)
ds.setLength(inimg.length)
ds.setFirstLatitude(north)
ds.setFirstLongitude(west)
ds.setLastLatitude(south)
ds.setLastLongitude(east)
if(args.action == 'stitch'):
lat = bbox[0:2]
lon = bbox[2:4]
if (args.output is None):
args.output = ds.defaultName(bbox)
if not(ds.stitchMasks(lat,lon,args.output,args.dir,keep=args.keep)):
print('Some tiles are missing. Maybe ok')
elif(args.action == 'download'):
lat = bbox[0:2]
lon = bbox[2:4]
ds.getMasksInBox(lat,lon,args.dir)
else:
print('Unrecognized action -a or --action',args.action)
return
if(args.report):
for k,v in ds._downloadReport.items():
print(k,'=',v)
if __name__ == '__main__':
sys.exit(main())

60
applications/wbd.py Executable file
View File

@ -0,0 +1,60 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Eric Gurrola
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import sys
import isce
from isceobj.InsarProc.runCreateWbdMask import runCreateWbdMask
class INSAR:
def __init__(self):
self.applyWaterMask = True
self.wbdImage = None
class SELF:
def __init__(me, snwe):
me.geocode_bbox = snwe
me.insar = INSAR()
class INFO:
def __init__(self, snwe):
self.extremes = snwe
def getExtremes(x):
return self.extremes
if __name__=="__main__":
if len(sys.argv) < 5:
print("Usage: wbd.py s n w e")
print("where s, n, w, e are latitude, longitude bounds in degrees")
sys.exit(0)
snwe = list(map(float,sys.argv[1:]))
self = SELF(snwe)
info = INFO(None)
runCreateWbdMask(self,info)

111
applications/wbdStitcher.py Executable file
View File

@ -0,0 +1,111 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import isce
import logging
import logging.config
from iscesys.Component.Application import Application
from iscesys.Component.Component import Component
from contrib.demUtils.SWBDStitcher import SWBDStitcher
import os
STITCHER = Application.Facility(
'_stitcher',
public_name='wbd stitcher',
module='contrib.demUtils',
factory='createSWBDStitcher',
args=('awbdstitcher',),
mandatory=True,
doc="Water body stitcher"
)
class Stitcher(Application):
def main(self):
# prevent from deliting local files
if(self._stitcher._useLocalDirectory):
self._stitcher._keepAfterFailed = True
self._stitcher._keepWbds = True
# is a metadata file is created set the right type
if(self._stitcher._meta == 'xml'):
self._stitcher.setCreateXmlMetadata(True)
# check for the action to be performed
if(self._stitcher._action == 'stitch'):
if(self._stitcher._bbox):
lat = self._stitcher._bbox[0:2]
lon = self._stitcher._bbox[2:4]
if (self._stitcher._outputFile is None):
self._stitcher._outputFile = self._stitcher.defaultName(self._stitcher._bbox)
if not(self._stitcher.stitchWbd(lat,lon,self._stitcher._outputFile,self._stitcher._downloadDir, \
keep=self._stitcher._keepWbds)):
print('Could not create a stitched water body mask. Some tiles are missing')
else:
print('Error. The "bbox" attribute must be specified when the action is "stitch"')
raise ValueError
elif(self._stitcher._action == 'download'):
if(self._stitcher._bbox):
lat = self._stitcher._bbox[0:2]
lon = self._stitcher._bbox[2:4]
self._stitcher.getWbdsInBox(lat,lon,self._stitcher._downloadDir)
else:
print('Unrecognized action ',self._stitcher._action)
return
if(self._stitcher._report):
for k,v in list(self._stitcher._downloadReport.items()):
print(k,'=',v)
def Usage(self):
print("\nUsage: wbdStitcher.py input.xml\n")
facility_list = (STITCHER,)
@property
def stitcher(self):
return self._stitcher
@stitcher.setter
def stitcher(self,stitcher):
self._stitcher = stitcher
family = 'wbdstitcher'
def __init__(self,family = '', name = ''):
super(Stitcher, self).__init__(family if family else self.__class__.family, name=name)
if __name__ == "__main__":
import sys
ds = Stitcher('wbdstitcher')
ds.configure()
ds.run()

46
applications/wisdomGenerator.py Executable file
View File

@ -0,0 +1,46 @@
#!/usr/bin/env python3
import sys
import argparse
import os
def main():
args = parse()
wisdom0 = 'wisdom0'
wisdom1 = 'wisdom1'
which = 0
for t in args.type:
for p in args.place:
for d in args.direction:
size = args.sizes[0]
while size <= args.sizes[1]:
if which == 0:
if args.action == 'new':
append = ''
elif args.action == 'append':
append = '-w ' + args.file
else:
print('Error. Unrecognized action',args.action)
raise Exception
else:
append = '-w wisdom' + str(which%2)
command = 'fftwf-wisdom -n ' + append + ' -o wisdom' + str((which+1)%2) + ' ' + t + p + d + str(size)
print("command = ", command)
os.system(command)
#print(command)
size *= 2
which += 1
os.system('mv wisdom' + str(which%2) + ' ' + args.file)
os.system('rm wisdom' + str((which+1)%2))
def parse():
parser = argparse.ArgumentParser()
parser.add_argument('-a', '--action', type = str, default = 'new', dest = 'action', help = 'What to do: new create a new wisdom file, appends it appends from the -f.')
parser.add_argument('-f', '--file', type = str, default = 'isce_wisdom.txt', dest = 'file', help = 'File name for wisdom file.')
parser.add_argument('-t', '--type', type = str, default = 'cr', dest = 'type', help = 'Type of fftw data c = complex r = real.')
parser.add_argument('-p', '--place', type = str, default = 'io', dest = 'place', help = 'Type of fftw place i = in place o = out of place.')
parser.add_argument('-d', '--direction', type = str, default = 'fb', dest = 'direction', help = 'Type of fftw direction f = forward b = backward.')
parser.add_argument('-s', '--sizes', type = int,nargs = '+', default = [32,65536], dest = 'sizes', help = 'Min and max.')
return parser.parse_args()
if __name__ == '__main__':
sys.exit(main())

907
applications/xmlGenerator.py Executable file
View File

@ -0,0 +1,907 @@
#!/usr/bin/env python3
"""
The main code. This code will look at the command line arguments. If
an invalid number of arguments are given, it will return an error.
Otherwise, it will read the commandline arguments. If one argument
is given, the code will assume the class name is the same as the
module name, and try to import the class. Otherwise, it will import
the given class from the given module and try to make an instance
of it.
This code will first try to run ._parameters and ._facilities
method of the instance. Then, it will check the dictionaryOfVariables
of the Insar class to see what components may be required. If it is
not empty, it will make a GUI with the following components:
- Label to indicate the component name, and whether or not its optional
- An entry box for the user to input the value for the component
- Buttons for each facility to allow user to
change the component of each one
- A Save button to save the component values, as well as the components
of the facilities that the user has saved
- A button to switch between saving a single xml file or saving
the xml file using multiple xml files
- A Reset all button, which resets all the inputted data in program
- A button to allow the user to use an existing xml file to change
data
- A quit button to quit the GUI
Global Variables Used: parameters, dictionaryOfFacilities, facilityButtons,
facilityDirs, classInstance, description, allParams,
singleFile, directory, facilityParams
"""
import sys
import os
from StringIO import StringIO
import Tkinter as tk
import tkFileDialog, tkMessageBox, tkFont
import xml.etree.ElementTree as ElementTree
import isce
from iscesys.Compatibility import Compatibility
Compatibility.checkPythonVersion()
#from insarApp import Insar
import traceback
from xml.parsers.expat import ExpatError
"""
Global Definitions:
classInstance - The instance of Insar that is created. This is the instance
which has the dictionaryOfVariables and dictionaryOfFacilities
attributes.
allParams - A dictionary of dictionaries containing all the parameters that
have been set so far.
parameters - a list containing class instances of class parameter, used to
access the user entry and the name and whether or not it is
optional in a clean manner.
description - a description of variables for parameters
facilityParams - a list containing instances of class parameter, used
to access the user entry for the facility's parameter
more easily, similar to global variable parameters.
dictionaryOfFaciliites - the dictionaryOfFacilities, contains the names
of all the facilities, as well as its factorymodule,
which is the path to the module containing its
factoryname, which creates an instance of the
facility
facilitiyButtons - The buttons, which causes a GUI for the facility to pop up
when pressed. They are disabled when a facility GUI is
already present.
facilityDirs - A dictionary containing the locations that the
user saved the xml file for each key, which is the
facility name.
root2 - The Tk instance for the second GUI, whcih should be the
GUI for the facility's parameters.
rootName - The name that the component in the xml is saved under.
This value is either the name of a facility or 'insarApp'.
directory - The directory at which the most recent file was saved.
singleFile - A boolean which indicates whether or not to save
the final XML file as a single file or multiple XML in
catalog format.
"""
class RefactorWarning(DeprecationWarning):
"""put in to alert uses that the code needs to be refactored.
Take out the raising if you don't like it"""
pass
class parameter:
"""Class parameter used to keep track of a parameter and its related objects
Class Members:
key: The name of the parameter
text: The text widget used for inputting data of this parameter
optional: Indicates whether or not this parameter is optional
attrib: The name this parameter has as an Insar class attribute
"""
def __init__(self, key=None, text=None, optional=None, attrib = None):
self.key = key
self.text = text
self.optional = optional
self.attrib = attrib
def indent(elem, level=0):
"""Indent an XML ElementTree"""
i = "\n" + level*" "
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + " "
if not elem.tail or not elem.tail.strip():
elem.tail = i
for elem in elem:
indent(elem, level+1)
if not elem.tail or not elem.tail.strip():
elem.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
## Creates the Input XML file given the user's inputs.
## If the user has missed a mandatory field in the current level GUI,
## this will cause a pop-up box to appear and tell the user to
## fill in the mandatory fields. Otherwise, it will ask the
## user for a directory to save the xml file in and create the
## xml file given their inputs. If making the final xml file,
## i.e the input file for the insarApp, it will also add any
## directories created by using a catalog.
##
## global variables used - directory, facilityDirs, facilityButtons,
## singleFile, allParams
def createInputXML(parameters, rootName):
"""Creates the Input XML File given the user inputs
Arguments:
parameters - A list of parameters to be inputted into the xml file
rootName - The name of the root
"""
# Get necessary global variables
global directory
global facilityDirs
global facilityButtons
global facilityRequired
global singleFile
global allParams
# Checks if any of the manadatory fields are blank.
for param in parameters:
if(not(param.optional) and param.text.get()==''):
tkMessageBox.showerror('ERROR!', 'Mandatory Field(s) is blank!')
return False
# If rootName is insarApp, and it is in multi file XML mode,
# then the user should have, by either loading an XML which is
# in that form or creating multiple files, a file for each facility.
if(rootName == 'insarApp' and not singleFile):
for x in zip(facilityButtons,facilityRequired):
button = x[0]
req = x[1]
try:
if(facilityDirs[button.cget('text')]=='' and req):
raise KeyError
except KeyError:
tkMessageBox.showerror('ERROR!',
'Facility parameters not saved in a file for:\n' +
button.cget('text'))
return False
# If rootName is insarApp and it is in single file XML mode,
# then the user should have, by either loading an XML file or
# by inputting and saving, have data for each facility.
elif(rootName == 'insarApp' and singleFile):
for x in zip(facilityButtons,facilityRequired):
button = x[0]
req = x[1]
try:
if(allParams[button.cget('text')] == {} and req):
raise KeyError
except KeyError:
tkMessageBox.showerror('ERROR!',
'Facility parameters not set in:\n' +
button.cget('text'))
return False
# Get a directory from the user to save in if we are in multi file XML
# mode and/or is saving the insarApp input file.
if(not singleFile or rootName == 'insarApp'):
directory = tkFileDialog.asksaveasfilename(initialfile=rootName+'.xml',
title="Choose where to save:",
defaultextension='.xml',
filetypes=[('xml files', '.xml')])
if(not directory):
return False
else:
# Create the input xml file using ElementTree.
top = ElementTree.Element(rootName)
top.text='\n'
root = ElementTree.SubElement(top,'component', {'name':rootName})
for param in parameters:
if(param.text.get()!=''):
property = ElementTree.SubElement(root,'property', {'name':param.key})
value = ElementTree.SubElement(property,'value')
value.text = param.text.get()
# If this is the insarApp input file, we must put the
# directory of all the input xml files for the facilities
if(rootName == 'insarApp'):
# If we are in sigleFile mode, write all the parameters
# into the file that we were writing to.
if singleFile:
for key in allParams.keys():
if allParams[key]:
facility = ElementTree.SubElement(root, 'component', {'name':key})
for paramKey in allParams[key].keys():
if allParams[key][paramKey]:
param = ElementTree.SubElement(facility, 'property',
{'name':paramKey})
value = ElementTree.SubElement(param, 'value')
value.text = allParams[key][paramKey]
# Otherwise, write the directory of each facility into
# the file that we were writing to.
else:
for key in facilityDirs.keys():
if facilityDirs[key]:
property = ElementTree.SubElement(root, 'component', {'name':key})
catalog = ElementTree.SubElement(property, 'catalog')
catalog.text = facilityDirs[key]
# Write the file using ElementTree
# If the file we are saving is the insarApp input file,
# we want insarApp tag on top of it. Otherwise, just
# put the data in to the xml file
if(rootName == 'insarApp'):
tempTree = ElementTree.ElementTree(root)
indent(tempTree.getroot())
tree = ElementTree.ElementTree(top)
else:
tree = ElementTree.ElementTree(root)
indent(tree.getroot())
tree.write(directory)
# Since the user is saving a facility in the single file XML mode,
# save the values in the global variable allParams
else:
allParams[rootName] = {}
for param in parameters:
allParams[rootName][param.key] = param.text.get()
return True
## Creates the input XML for a toplevel GUI, which
## should be for the facility's components. After
## saving the XML file, it will exit the toplevel
## GUI and save the directory that it was saved to
## in a dictionary with the key as the name of the
## facility.
##
## global variables used - facilityComponents, dir, rootName, facilityDirs
def facilityInputXML():
"""Creates an XML file for a facility's parameters"""
global facilityParams
global directory
global rootName
global facilityDirs
# Create the XML using the facilityParameters
# and the rootName, which was set as the facility name
# when the facility GUI was made
if(createInputXML(facilityParams, rootName)):
facilityQuit()
if(directory):
facilityDirs[rootName] = directory
return
## Creates the input XML for insarApp, which is
## at the root.
def componentInputXML():
"""Creates an XML file for the InsarApp"""
global parameters
global facilityDirs
createInputXML(parameters, 'insarApp')
###The event that is called when a facilityButton is
## pressed by the user. When the button is pressed,
## the code will first try to create an instance of
## the class using the argument given in the
## dictionaryOfFacilities and the method given in it.
## If it fails, it will return an error
## message, indicating a matching argument for the method
## was not found. If it succeeds, it will disable the facility
## buttons, since we can only have one other GUI open at once.
## Then, it will also disable the inputs to the components,
## since those should not be changed, since the facility could
## depend on the values. It will then proceed to make
## a GUI with entries for each component found in the
## attribute dictionaryOfVariables of the instance.
def facilityEvent(event):
"""Creates a pop-up GUI for inputting facility parameters"""
# Load all the global variables used in this function
global parameters
global dictionaryOfFacilities
global facilityButtons
global facilityParams
global rootName
global root2
global classInstance
global singleFile
global allParams
global facilityDocs
# Find which facility button the user pressed
# through its text, and set it as the rootName
text = event.widget.cget('text')
rootName = text
# Initiate instance as None
instance = None
# Initiate a StringIO and set it as stdout to
# catch any error messages the factory
# method produces
temp = sys.stdout
errorStr = StringIO('')
sys.stdout = errorStr
# Call the parameters method to restore the
# default value of facilities
try:
classInstance._parameters()
except:
pass
for param in parameters:
if param.text.get():
# exec 'classInstance.' + param.attrib + '= \'' + param.text.get() + '\''
setattr(classInstance, param.attrib, eval('\'' + param.text.get() + '\''))
pass
pass
try:
classInstance._facilities()
except:
pass
# Try to use the arguments in the dictionaryOfFacilities
# to instantiate an instance of the facility
try:
args = dictionaryOfFacilities[text]['args']
kwargs = dictionaryOfFacilities[text]['kwargs']
# May need to be modified if a factory takes
# the None argument
modified = ['']*len(args)
for i in range(0, len(args)):
if(args[i] == None):
modified[i] = 'None'
else:
modified[i] = args[i]
pass
pass
modified = tuple(modified)
# raise RefactorWarning("refactor with appy built-in")
instance = eval(
dictionaryOfFacilities[text]['factoryname']+'(*' + modified.__str__() + ', **' +
kwargs.__str__() + ')'
)
except Exception as e:
traceback.print_exc(file=sys.stdout)
tkMessageBox.showerror('ERROR!', 'Unknown error occurred:\n'+errorStr.getvalue()+'\n%s' %e)
return None
# If the instance is still none, this means
# that an error message was produced, and
# that it failed to make an instance.
# Print out the error message
# produced, which is contained in the StringIO
sys.stdout = temp
if instance is None:
tkMessageBox.showerror('ERROR!', 'Bad argument for: ' +
dictionaryOfFacilities[text]['factoryname'] +
'\n' + errorStr.getvalue())
return
# Try to run the ._parameters() and ._facilities()
# methods of the instance, and then get its
# dictionaryOfVariables
try:
instance._parameters()
except:
pass
try:
instance._facilities()
except:
pass
dictionaryOfVariables = None
try:
dictionaryOfVariables = instance.dictionaryOfVariables
except:
pass
# Check if the dictionaryOfVariables is empty or does not exist
if (dictionaryOfVariables is None or dictionaryOfVariables == {}):
# Create a Popup Error message
sys.stdout = sys.stderr
tkMessageBox.showerror('ERROR!', 'DictionaryOfVariables for ' +
text + ' is empty! Nothing to do...')
return
# Disable all the facilityButtons b/c multiple facility
# GUI's are not supported
for button in facilityButtons:
button.config(state='disabled')
for param in parameters:
param.text.config(state='disabled')
XMLButton.config(state='disabled')
# Create the new facility GUI
root2 = tk.Toplevel()
root2.protocol("WM_DELETE_WINDOW",facilityQuit)
root2.title('Facility '+text+ ' Component Editor')
tempFont = ('Times New Roman', 14)
# Create a font with underlines
uFont = tkFont.Font(family='Times New Roman', size=14, underline=True)
# First column gives the name
nameLabel = tk.Label(root2, text='Name (Click a name for help)', font=uFont)
# Second column allows user to input values for each attribute
valueLabel = tk.Label(root2, text='Value', font=uFont)
# The third column is for units
unitsLabel = tk.Label(root2, text='Units', font=uFont)
# The fourth column indicates to users whether or not an
# attribute is optional or mandatory.
requiredLabel = tk.Label(root2, text='Optional/Mandatory', font=uFont)
# Put each label in respective locations
nameLabel.grid(row=0, column=0)
valueLabel.grid(row=0, column=1)
unitsLabel.grid(row=0, column=2)
requiredLabel.grid(row=0, column=3)
r = 1
# Reset facilityParams, since we are using a new
# facility
facilityParams = []
try:
units = instance.unitsOfVariables
except:
pass
try:
facilityDocs = instance.descriptionOfVariables
except:
pass
for key in dictionaryOfVariables.keys():
label = tk.Label(root2, text=key)
label.grid(row=r, column=0)
if(dictionaryOfVariables[key][2].lower() == 'optional'):
opt = tk.Label(root2, text='Optional', fg='green')
facilityParams.append(parameter(key, tk.Entry(root2), True))
else:
opt = tk.Label(root2, text='Mandatory', fg='red')
facilityParams.append(parameter(key, tk.Entry(root2), False))
try:
label = tk.Label(root2, text=units[key])
label.grid(row=r, column=2)
except:
pass
button = tk.Button(root2, text=key, width=25)
button.bind('<ButtonRelease>', facilityHelp)
button.grid(row=r, column=0)
opt.grid(row=r, column=3)
facilityParams[r-1].text.grid(row=r, column=1)
r = r + 1
# Put the known arguments into the entry boxes before outputting
# them, and also check for any "trash" values inside the dictionary
# that could occur from loading an xml file with incorrect facility
# parameters
temp = {}
temp[text] = {}
for param in facilityParams:
try:
param.text.insert(0, allParams[text][param.key])
temp[text][param.key] = allParams[text][param.key]
except:
pass
allParams[text] = temp[text]
# Create a quit and save button, as well as a dir button so
# that the user can load a directory and use that as their
# facility XML file
quitButton = tk.Button(root2, text='Quit', command=facilityQuit)
saveButton = tk.Button(root2, text='Save', command=facilityInputXML)
dirButton = tk.Button(root2, text='Use An Existing\n XML File',
command=getFacilityDirectory)
quitButton.grid(row=r, column=2)
saveButton.grid(row=r, column=1)
dirButton.grid(row=r, column=0)
root2.mainloop()
def facilityHelp(event):
"""Creates help documentation for the facility GUI"""
global facilityDocs
text = event.widget.cget('text')
if(text in facilityDocs.keys() and facilityDocs[text] != ''):
tkMessageBox.showinfo(text+' documentation:', description[text])
else:
tkMessageBox.showerror('Documentation Not Found!', 'There is no documentation\nfor this parameter')
## This method is called when the button for using an already existing
## XML file is clicked on the facility GUI. The method tries to open
## the xml file given, and stores the data in the global variable
## allParams, as well as populate them in the GUI's entry boxes.
##
## Global Variables Used: rootName, facilityDirs, facilityParams
def getFacilityDirectory():
"""Gets the directory for the xml used for the facility's parameter"""
global rootName
global facilityDirs
global facilityParams
directory = tkFileDialog.askopenfilename(title='Locate Your XML File for '
+ rootName, defaultextension='.xml',
filetypes=[('xml files', '.xml')])
if(directory):
try:
tree = ElementTree.parse(directory)
value = ''
name = ''
for property in tree.findall('property'):
name = property.attrib['name']
value = property.find('value').text
for param in facilityParams:
if param.key == name:
param.text.delete(0, tk.END)
param.text.insert(0, value)
allParams[rootName][param.key] = value
name = ''
break
if name != '':
tkMessageBox.showerror('Error!', 'Invalid XML for'+
rootName + ' facility!'
+ '\nParameter ' + name +
' does not exist in this facility!')
return
except ExpatError:
tkMessageBox.showerror('Error!', 'Invalid XML error! XML is ill formed!')
except Exception:
tkMessageBox.showerror('Error!', 'Invalid XML error! XML is ill formed for ' + rootName + '!')
facilityDirs[rootName] = directory
## This is the quit button event for the facility GUI. This
## quits out of the for facility and reenables all the
## buttons for the other facilities and entry boxes for
## the components.
##
## Global Variables Used: facilityButtons, components, root2, XMLButton
def facilityQuit():
"""The button event for Quit button on facility GUI. This destroys the
facility GUI and restores disabled buttons on main GUI."""
root2.destroy()
for button in facilityButtons:
button.config(state='normal')
for param in parameters:
param.text.config(state='normal')
XMLButton.config(state='normal')
def showDoc(event):
"""Shows documentation for the parameter written on the button"""
text = event.widget.cget('text')
if(text in description.keys() and description[text] != ''):
tkMessageBox.showinfo(text+' documentation:', description[text])
else:
tkMessageBox.showerror('Documentation Not Found!', 'There is no documentation\nfor this parameter')
def changeSave(event):
"""Changes the save from single file save to multiple and vice versa"""
global singleFile
global facilityDirs
singleFile = not singleFile
if(singleFile):
event.widget.configure(text='Currently:\nSingle XML File Mode')
facilityDirs = {}
else:
event.widget.configure(text = 'Currently:\nMultiple XML Mode')
return
def loadXML():
"""Loads an XML file for the insarApp and stores the data"""
global parameters
global allParams
global facilityDirs
facilityDirs = {}
# Get the directory from the user
directory = ''
directory = tkFileDialog.askopenfilename(title='Locate Your XML File:',
defaultextension='.xml',
filetypes=[('xml files', '.xml')])
# If the user specified a directory, try loading it
if directory:
try:
# Find the insarApp component which should have all the properties
# and facilities
tree = ElementTree.parse(directory).find('component')
text = ''
name = ''
# First find all the parameters listed in the main GUI
for property in tree.findall('property'):
name = property.attrib['name']
value = property.find('value').text
for param in parameters:
if param.key == name:
param.text.delete(0, tk.END)
param.text.insert(0, value)
name = ''
break
pass
if name:
tkMessageBox.showerror('Error!', 'Invalid xml for these parameters!\n'+
'Parameter ' + name + ' does not exist!')
pass
pass
# Then find the parameters for the facilities
for facility in tree.findall('component'):
exists = False
facilityName = facility.attrib['name']
for button in facilityButtons:
if button.cget('text') == facilityName:
exists = True
pass
pass
if not exists:
tkMessageBox.showerror('Error!', 'Invalid xml error! Facility '
+ facilityName + ' does not exist!')
return None
# Check whether or not the xml is in catalog format or all-in-one
# format
catalog = None
catalog = facility.find('catalog')
allParams[facilityName] = {}
# If there is a catalog, assume that the first component
# contains every parameter of the facility
if catalog is not None:
catalog = catalog.text
facilityDirs[facilityName] = catalog
facilityTree = ElementTree.parse(catalog)
for property in facilityTree.findall('property'):
name = property.attrib['name']
value = property.find('value').text
allParams[facilityName][name] = value
pass
pass
# Otherwise, go through the facility and get the parameters
else:
for property in facility.findall('property'):
name = property.attrib['name']
value = property.find('value').text
allParams[facilityName][name] = value
except IOError:
tkMessageBox.showerror('Error!', 'Invalid XML error! One or more XML does not exist!')
except ExpatError:
tkMessageBox.showerror('Error!', 'Invalid XML error! XML is ill formed!')
except Exception:
tkMessageBox.showerror('Error!', 'Invalid XML error! XML is valid for insarApp!')
return
def reset():
"""After asking the user, resets everything in the code used for writing to an xml"""
global allParams
global facilityDirs
global parameters
global facilityButtons
global root2
# Ask the user if they want to reset everything
answer = tkMessageBox.askyesno("Are you sure?", "Are you sure you want to reset all data?")
if answer:
# Delete all entries in the main GUI
for param in parameters:
param.text.delete(0, tk.END)
# Erase all data stored for writing to XML's
allParams = {}
facilityDirs = {}
# Make sure that all the main GUI buttons are enabled
for button in facilityButtons:
button.configure(state='normal')
facilityDirs[button.cget('text')] = ''
allParams[button.cget('text')] = {}
XMLButton.config(state='normal')
# If there is a facility GUI, get rid of it
try:
root2.destroy()
except:
pass
pass
pass
if __name__ == "__main__":
"""Builds the main GUI for making an XML input for given class"""
# Get the global variable
global parameters
global dictionaryOfFacilities
global facilityButtons
global facilityRequired
global facilityDirs
global classInstance
global description
global allParams
global singleFile
global directory
global facilityParams
parameters = []
facilityParams = []
dictionaryOfFacilities = {}
facilityButtons = []
facilityRequired = []
facilityDirs = {}
root2 = None
rootName = ''
directory = ''
allParams = {}
# Create an instance of Insar to run the _parameters() and
# _facilities() function, if they exist, to create the
# dictionaryOfVariables.
try:
if(len(sys.argv) != 2 and len(sys.argv) != 3):
print("Invalid commandline arguments:")
print("Usage 1, Module and Class have same names: xmlGenerator Module")
print("Usage 2, Module and Class names different: xmlGenerator Module Class")
print("(Module name should not include the '.py')")
sys.exit()
elif(len(sys.argv) == 2):
if 'help' in sys.argv[1]:
print("'Invalid commandline arguments:\nUsage: xmlGenerator [Module (sans '.py'] [Class]")
# raise RefactorWarning("refactor with __import__ built-in")
print("Assuming module name and class name are both, ", sys.argv[1])
exec('from ' + sys.argv[1] + ' import ' + sys.argv[1])
classInstance = eval(sys.argv[1] + '()')
else:
print("importing class %s from module %s" % (sys.argv[1], sys.argv[2]))
# raise RefactorWarning("refactor with __import__ built-in")
exec('from ' + sys.argv[1] + ' import ' + sys.argv[2])
# print sys.argv[2]
classInstance = eval(sys.argv[2] + '()')
pass
pass
except ImportError as e:
print("Invalid arguments!")
print("Either the given module or the given class does not exist,")
print("or you have assumed they both have the same name and they do not.")
sys.exit()
pass
try:
classInstance._parameters()
classInstance._facilities()
except:
pass
dictionaryOfVariables = classInstance.dictionaryOfVariables
try:
dictionaryOfFacilities = classInstance._dictionaryOfFacilities
except:
pass
# If the dictionaryOfVariables is not empty, create
# the GUI
if dictionaryOfVariables:
# Since Frame class does not have scrollbars, use a
# canvas to create a scrollbar in the y direction
root = tk.Tk()
root.title(sys.argv[1] + ' Input XML File Generator')
verticalBar = tk.Scrollbar(root)
verticalBar.grid(row=0, column=1, sticky='N'+'S')
# Create the Canvas, which will have the scroll bar as
# well as the frame. Change the width here to
# change the starting width of the screen.
canvas = tk.Canvas(root,
yscrollcommand=verticalBar.set,
width=1100, height=500)
canvas.grid(row=0, column=0, sticky='N'+'S'+'E'+'W')
verticalBar.config(command=canvas.yview)
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
frame = tk.Frame(canvas)
frame.rowconfigure(1, weight=1)
frame.columnconfigure(1, weight=1)
# Begin creating the GUI involved with input variables
# Create a font with underlines
uFont = tkFont.Font(family='Times New Roman', size=14, underline=True)
# Create a parameters label
paramLabel = tk.Label(frame, text='Parameters:',
font=("Times New Roman", 20, "bold"))
# First column gives the name
nameLabel = tk.Label(frame, text='Name (Click a name for help)', font=uFont)
# Second column allows user to input values for each attribute
valueLabel = tk.Label(frame, text='Value', font=uFont)
# The third column is for units
unitsLabel = tk.Label(frame, text='Units', font=uFont)
# The fourth column indicates to users whether or not an
# attribute is optional or mandatory.
requiredLabel = tk.Label(frame, text='Optional/Mandatory', font=uFont)
# Put each label in respective locations
paramLabel.grid(row=0, column=0)
nameLabel.grid(row=1, column=0, columnspan=2)
valueLabel.grid(row=1, column=2)
unitsLabel.grid(row=1, column=4)
requiredLabel.grid(row=1, column=5)
# Create a variable for the row
r = 2
try:
description = classInstance.descriptionOfVariables
except:
pass
units = {}
try:
units = classInstance.unitsOfVariables
except:
pass
for key in dictionaryOfVariables.keys():
val = dictionaryOfVariables[key]
# Make the label from the keys in the dictionary
# Change the wraplength here for the names if it is too short or long.
# label = tk.Label(frame, text=key, anchor = tk.W, justify=tk.LEFT, wraplength=100)
# label.grid(row=r,column=0)
# Indicate whether the attribute is optional or mandatory
if(val[2].lower() == ('optional')):
required = tk.Label(frame, text='Optional', fg='green')
parameters.append(parameter(key, tk.Entry(frame, width=50), True, val[0]))
else:
required = tk.Label(frame, text='Mandatory', fg='red')
parameters.append(parameter(key, tk.Entry(frame, width=50), False, val[0]))
pass
try:
doc = tk.Button(frame, text=key, anchor = tk.W, justify=tk.LEFT, width=50,
wraplength=348)
doc.bind('<ButtonRelease>', showDoc)
doc.grid(row=r, column=0, columnspan=2)
except:
pass
try:
unit = tk.Label(frame, text=units[key])
unit.grid(row=r, column=2)
except:
pass
required.grid(row=r,column=5)
# Put the Entry in global variable, since it is needed
# for saving inputted values into xml
parameters[r-2].text.grid(row=r,column=2, columnspan=2)
r = r + 1
pass
if dictionaryOfFacilities:
# Add a label indicating that these buttons are facilities
facilityLabel = tk.Label(frame, text='Facilities:',
font=("Times New Roman", 20, "bold"),
justify=tk.LEFT,
anchor=tk.W)
facilityLabel.grid(row=r, column=0)
r = r + 1
x = 0
# Make the buttons to edit facility parameters and import
# the required modules using the factorymodule
for key in dictionaryOfFacilities.keys():
facilityButtons.append(tk.Button(frame, text = key, width=50, justify=tk.LEFT,
anchor=tk.W, wraplength=348))
facilityButtons[x].grid(row=r, column=0, columnspan=2)
facilityButtons[x].bind('<ButtonRelease>', facilityEvent)
facilityDirs[key] = ''
allParams[key] = {}
if dictionaryOfFacilities[key]['mandatory']:
facilityRequired.append(True)
required = tk.Label(frame, text='Mandatory', fg='red')
required.grid(row=r,column=5)
else:
facilityRequired.append(False)
required = tk.Label(frame, text='Optional', fg='green')
required.grid(row=r,column=5)
r = r + 1
x = x + 1
try:
exec ('from ' + dictionaryOfFacilities[key]['factorymodule'] +
' import ' + dictionaryOfFacilities[key]['factoryname'])
raise RefactorWarning("refactor with __import__ built-in")
except:
pass
pass
pass
# Buttons for saving the xml file, using an existing xml file,
# changing the save settings, and quitting out of the program
saveButton = tk.Button(frame, text="Save", command=componentInputXML)
quitButton = tk.Button(frame, text="Quit", command=root.destroy)
resetButton = tk.Button(frame, text='Reset All', command=reset)
# The button for switching between multiple xml mode and single
# mode. The default is multiple XML mode.
singleFile = False
singleFileButton = tk.Button(frame, text='Currently:\nMultiple XML Mode')
singleFileButton.bind('<ButtonRelease>', changeSave)
# The button used to get an existing XML file
XMLButton = tk.Button(frame, text='Use an existing XML File', command=loadXML)
saveButton.grid(row=r+1, column=2)
quitButton.grid(row=r+1, column=3)
resetButton.grid(row=r+1, column=4)
singleFileButton.grid(row=r+1, column=5)
XMLButton.grid(row=r+1, column=1)
# Have the canvas create a window in the top left corner,
# which is the frame with everything on it
canvas.create_window(0, 0, anchor='nw', window=frame)
frame.update_idletasks()
canvas.config(scrollregion=canvas.bbox("all"))
root.mainloop()
else:
tkMessageBox.showerror('ERROR!', 'Dictionary of Variables Empty: Nothing to do')
pass
sys.exit()

63
components/SConscript Normal file
View File

@ -0,0 +1,63 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
import sys
Import('env')
package = 'components'
envcomponents = env.Clone()
envcomponents['PACKAGE'] = package
envcomponents['INSTALL_PATH'] = os.path.join(envcomponents['PRJ_SCONS_INSTALL'],package)
install = envcomponents['INSTALL_PATH']
initFile = '__init__.py'
if not os.path.exists(initFile):
fout = open(initFile,"w")
fout.write("#!/usr/bin/env python3")
fout.close()
listFiles = [initFile]
envcomponents.Install(install,listFiles)
envcomponents.Alias('install',install)
Export('envcomponents')
isceobj = 'isceobj/SConscript'
SConscript(isceobj)
mroipac = 'mroipac/SConscript'
SConscript(mroipac)
iscesys = 'iscesys/SConscript'
SConscript(iscesys)
stdproc = 'stdproc/SConscript'
SConscript(stdproc)
zerodop = 'zerodop/SConscript'
SConscript(zerodop)

1
components/__init__.py Normal file
View File

@ -0,0 +1 @@
#!/usr/bin/env python3

View File

@ -0,0 +1,358 @@
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Walter Szeliga
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import math
import datetime
import logging
from iscesys.Component.Component import Component
from isceobj.Util.decorators import type_check, pickled, logged
## This class stores platform pitch, roll and yaw information.
TIME = Component.Parameter(
'_time',
public_name='TIME',
default=0,
type=datetime.datetime,
mandatory=True,
intent='input',
doc=''
)
PITCH = Component.Parameter(
'_pitch',
public_name='PITCH',
default=0,
type=float,
mandatory=True,
intent='input',
doc=''
)
ROLL = Component.Parameter(
'_roll',
public_name='ROLL',
default=0,
type=float,
mandatory=True,
intent='input',
doc=''
)
YAW = Component.Parameter(
'_yaw',
public_name='YAW',
default=0,
type=float,
mandatory=True,
intent='input',
doc=''
)
class StateVector(Component):
parameter_list = (
TIME,
PITCH,
ROLL,
YAW
)
family = 'attitudestatevector'
def __init__(self,family='',name='', time=None, pitch=None, roll=None, yaw=None):
super(StateVector, self).__init__(family if family else self.__class__.family, name=name)
self._time = time
self._pitch = pitch
self._roll = roll
self._yaw = yaw
return None
def toList(self):
return [self._time.strftime('%Y-%m-%dT%H:%M:%S.%f'),self._pitch,self._roll,self._yaw]
@type_check(datetime.datetime)
def setTime(self, time):
self._time = time
pass
def getTime(self):
return self._time
def setPitch(self, pitch):
self._pitch = pitch
def getPitch(self):
return self._pitch
def setRoll(self, roll):
self._roll = roll
def getRoll(self):
return self._roll
def setYaw(self, yaw):
self._yaw = yaw
def getYaw(self):
return self._yaw
def __str__(self):
retstr = "Time: %s\n"
retlst = (self.time,)
retstr += "Pitch: %s\n"
retlst += (self.pitch,)
retstr += "Roll: %s\n"
retlst += (self.roll,)
retstr += "Yaw: %s\n"
retlst += (self.yaw,)
return retstr % retlst
time = property(getTime, setTime)
pitch = property(getPitch, setPitch)
roll = property(getRoll, setRoll)
yaw = property(getYaw, setYaw)
pass
ATTITUDE_SOURCE = Component.Parameter(
'_attitudeSource',
public_name='ATTITUDE_SOURCE',
default=None,
type=str,
mandatory=False,
intent='input',
doc=''
)
STATE_VECTORS = Component.Parameter(
'_stateVectors',
public_name='STATE_VECTORS',
default=[],
container=list,
type=float,
mandatory=True,
intent='input',
doc=''
)
ATTITUDE_QUALITY = Component.Parameter(
'_attitudeQuality',
public_name='ATTITUDE_QUALITY',
default=None,
type=str,
mandatory=False,
intent='input',
doc=''
)
## This class encapsulates spacecraft attitude information
## The Attitude class consists of a list of StateVector objects
## and provides an iterator over this list.
@pickled
class Attitude(Component):
parameter_list = (
ATTITUDE_SOURCE,
STATE_VECTORS,
ATTITUDE_QUALITY
)
logging_name = 'isce.Attitude'
min_length_for_interpolation = 3
family = 'attitude'
def __init__(self,family='',name=''):
self._minTime = datetime.datetime(year=datetime.MAXYEAR,
month=12,
day=31)
self._maxTime = datetime.datetime(year=datetime.MINYEAR,
month=1,
day=1)
self._last = 0
self.cpStateVectors = []
super(Attitude, self).__init__(family if family else self.__class__.family, name=name)
return None
def adaptToRender(self):
self._cpStateVectors = []
svList = []
for sv in self.stateVectors:
svList.append(sv.toList())
#for some reason the deepcopy failed so adding one vector at the time
self._cpStateVectors.append(sv)
self.stateVectors = svList
def restoreAfterRendering(self):
self.stateVectors = self._cpStateVectors
def initProperties(self,catalog):
if 'state_vectors' in catalog:
st = catalog['state_vectors']
self.stateVectors = []
for ls in st:
self.stateVectors.append(StateVector(time=datetime.datetime.strptime(ls[0],'%Y-%m-%dT%H:%M:%S.%f'),pitch=ls[1],
roll=ls[2],yaw=ls[3]))
catalog.pop('state_vectors')
super().initProperties(catalog)
@property
def stateVectors(self):
return self._stateVectors
@stateVectors.setter
def stateVectors(self,val):
self._stateVectors = val
## A container needs a length.
def __len__(self):
return len(self.stateVectors)
## A container needs a getitem
def __getitem__(self, index):
return self.stateVectors[index]
def __setitem__(self, *args):
raise TypeError("'%s' object does not support item assignment" %
self.__class__.__name__
)
def __delitem__(self, *args):
raise TypeError("'%s' object does not support item deletion"
%self.__class__.__name__)
def __iter__(self):
return self
def next(self):
if self._last < len(self):
result = self.stateVectors[self._last]
self._last += 1
return result
raise StopIteration()
def setAttitudeQuality(self, qual):
self._attitudeQuality = qual
def getAttitudeQuality(self):
return self._attitudeQuality
def setAttitudeSource(self, source):
self._attitudeSource = source
def getAttitudeSource(self):
return self._attitudeSource
@type_check(StateVector)
def addStateVector(self, vec):
self._stateVectors.append(vec)
# Reset the minimum and maximum time bounds if necessary
if (vec.time < self._minTime): self._minTime = vec.time
if (vec.time > self._maxTime): self._maxTime = vec.time
pass
#TODO This needs to be fixed to work with scalar pitch, roll and yaw data
#TODO- use Utils/geo/charts and let numpy do the work (JEB).
def interpolate(self, time):
if len(self) < self.min_length_for_interpolation:
message = ("Fewer than %d state vectors present in attitude, "+
"cannot interpolate" % self.min_length_for_interpolation
)
self.logger.error(
message
)
return None
if not self._inRange(time):
message = (
"Time stamp (%s) falls outside of the interpolation interval"+
"[%s:%s]"
) % (time, self._minTime, self._maxTime)
raise ValueError(message)
pitch = 0.0
roll = 0.0
yaw = 0.0
for sv1 in self.stateVectors:
tmp=1.0
for sv2 in self.stateVectors:
if sv1.time == sv2.time:
continue
numerator = float(self._timeDeltaToSeconds(sv2.time-time))
denominator = float(
self._timeDeltaToSeconds(sv2.time - sv1.time)
)
tmp *= numerator/denominator
pass
pitch += sv1.pitch*tmp
roll += sv1.roll*tmp
yaw += sv1.yaw*tmp
pass
return StateVector(name='asv', time=time, pitch=pitch, roll=roll, yaw=yaw)
def _inRange(self, time):
"""Check whether a given time stamp is within the range of values for
an orbit"""
return self._minTime <= time <= self._maxTime
@type_check(datetime.timedelta)
def _timeDeltaToSeconds(self, td):
return (
td.microseconds +
(td.seconds + td.days * 24.0 * 3600) * 10**6
) / 10**6
def __str__(self):
retstr = "Attitude Source: %s\n"
retlst = (self.attitudeSource,)
retstr += "Attitude Quality: %s\n"
retlst += (self.attitudeQuality,)
return retstr % retlst
attitudeQuality = property(getAttitudeQuality, setAttitudeQuality)
attitudeSource = property(getAttitudeSource, setAttitudeSource)
pass
def createAttitude():
return Attitude()

View File

@ -0,0 +1,49 @@
#!/usr/bin/env python
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
Import('envisceobj')
envAttitude = envisceobj.Clone()
project = 'Attitude'
package = envAttitude['PACKAGE']
envAttitude['PROJECT'] = project
Export('envAttitude')
install = os.path.join(envAttitude['PRJ_SCONS_INSTALL'],package,project)
helpList,installHelp = envAttitude['HELP_BUILDER'](envAttitude,'__init__.py',install)
envAttitude.Install(installHelp,helpList)
envAttitude.Alias('install',installHelp)
initFile = '__init__.py'
listFiles = ['Attitude.py',initFile]
envAttitude.Install(install,listFiles)
envAttitude.Alias('install',install)

View File

@ -0,0 +1,11 @@
#!/usr/bin/env python3
def createAttitude(name=''):
from .Attitude import Attitude
return Attitude(name)
def getFactoriesInfo():
return {'Attitude':
{
'factory':'createAttitude'
}
}

View File

@ -0,0 +1,323 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2011 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Eric Gurrola
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os, errno, itertools
from .OrderedDict import OrderedDict
from io import StringIO
HEADER = "\n%s\n %%s\n%s\n" % ("#"*100, '-'*100)
FOOTER = "#"*100
MAX_LIST_SIZE = 20
class Catalog(OrderedDict):
# This bigArrayNum variable is used to ensure that big array files are
# unique on disk. Some components that use the Catalog class are used
# multiple times.
bigArrayNum = 0
def __init__(self, name, nodePath=None):
OrderedDict.__init__(self)
self.name = name
if nodePath is None:
self.fullName = name
else:
self.fullName = '.'.join(nodePath)
return
def __eq__(self, other):
if len(self) != len(other):
return False
for other_k, other_v in other.items():
try:
self_v = self[other_k]
except KeyError as e:
return False
if not (self_v == other_v):
return False
return True
def addItem(self, key, value, node):
"""
Adds given key/value pair to the specified node. If the node does not
exist, it is created.
"""
nodePath = node.split('.')
self._addItem(key, value, nodePath)
def hasNode(self, node):
"""
Indicates whether a node exists in this catalog (such as "foo.bar.baz")
"""
if not isinstance(node,str):
raise TypeError("'node' must be a string")
nodeList = node.split('.')
return self._hasNodes(nodeList)
def _hasNodes(self, nodeList):
catalog = self
for node in nodeList:
if (node not in catalog) or (not isinstance(catalog[node], Catalog)):
return False
catalog = catalog[node]
return True
def addAllFromCatalog(self, otherCatalog):
"""Adds all the entries from the other catalog into this catalog."""
if not isinstance(otherCatalog, Catalog):
raise TypeError("'otherCatalog' must be of type Catalog")
self._addAllFromCatalog(otherCatalog, [])
def _addAllFromCatalog(self, otherCatalog, nodePath):
for k, v in otherCatalog.items():
if isinstance(v, Catalog):
nodePath.append(v.name)
self._addAllFromCatalog(v, nodePath)
nodePath.pop()
else:
self._addItem(k, v, nodePath)
def addInputsFrom(self, obj, node):
"""
Given an object, attempts to import its dictionaryOfVariables attribute
into this catalog under the given node.
"""
if not hasattr(obj, 'dictionaryOfVariables'):
raise AttributeError(
"The object of type {} ".format(obj.__class__.__name__)
+ "does not have a dictionaryOfVariables attribute!")
nodePath = node.split('.')
for k, v in obj.dictionaryOfVariables.items():
#check for new and old style dictionaryOfVariables
try:
attr = v['attrname']
#only dump input or inoutput
if(v['type'] == 'component' or v['intent'] == 'output'):
continue
except Exception:
attr = v[0].replace('self.', '', 1)
self._addItem(k, getattr(obj, attr), nodePath)
if 'constants' in iter(list(obj.__dict__.keys())):
for k, v in list(obj.constants.items()):
self._addItem(k, v, nodePath)
def addOutputsFrom(self, obj, node):
"""
Given an object, attempts to import its dictionaryOfOutputVariables
attribute into this catalog under the given node.
"""
if not hasattr(obj, 'dictionaryOfOutputVariables'):
#it's probably the new type of dictionary
for k, v in obj.dictionaryOfVariables.items():
nodePath = node.split('.')
#check for new and old style dictionaryOfVariables
try:
attr = v['attrname']
#only dump output or inoutput
if(v['intent'] == 'input'):
continue
except Exception:
continue
self._addItem(k, getattr(obj, attr), nodePath)
else:
#old style/. To be removed once everything is turned into a Configurable
nodePath = node.split('.')
for k, v in obj.dictionaryOfOutputVariables.items():
attr = v.replace('self.', '', 1)
self._addItem(k, getattr(obj, attr), nodePath)
def _addItem(self, key, value, nodePath):
catalog = self
partialPath = []
for node in nodePath:
partialPath.append(node)
# Instantiate a new catalog if the node does not already exist
if node not in catalog:
catalog[node] = Catalog(node, partialPath)
catalog = catalog[node]
# Just record the file info if this value is actually a large array
catalog[key] = self._dumpValueIfBigArray(key, value, nodePath)
def _dumpValueIfBigArray(self, key, v, nodePath):
"""Checks to see if the value is a list greater than the defined length threshhold. If so,
dump the array to a file and return a string value indictating the file name. Otherwise,
return the normal value."""
if self._isLargeList(v):
# Make the catalog directory if it doesn't already exist
try:
os.makedirs('catalog')
except OSError as e:
if e.errno != errno.EEXIST:
print("Couldn't create directory, 'catalog'! Please check your permissions.")
raise
fileName = 'catalog/%s.%s.%03i' % ('.'.join(nodePath), key, Catalog.bigArrayNum)
Catalog.bigArrayNum += 1
f = open(fileName, 'w')
self.writeArray(f, v)
f.close()
v = fileName
return v
def writeArray(self, file, array):
"""Attempts to output arrays in a tabular format as neatly as possible. It tries
to determine whether or not it needs to transpose an array based on if an array is
multidimensional and if each sub-array is longer than the main array."""
# The arrya is guaranteed to be > 0 by the caller of this method
multiDim = isinstance(array[0], list) or isinstance(array[0], tuple)
# 'transpose' the array if each element array is longer than the main array
# this isn't fool proof and might produce incorrect results for short multi-dim
# arrays, but it work in practice
if multiDim and len(array[0]) > len(array):
array = zip(*array)
for e in array:
if multiDim:
e = '\t'.join(str(x) for x in e)
else:
e = str(e)
file.write("%s\n" % e)
def _isLargeList(self, l):
"""This handles the fact that a list might contain lists. It returns True if the list
itself or any of its sublists are longer than MAX_LIST_SIZE. If 'l' is not a list,
False is returned. This method does assume that all sublists will be the same size."""
while (isinstance(l, list) or isinstance(l, tuple)) and len(l) > 0:
if len(l) > MAX_LIST_SIZE:
return True
l = l[0]
return False
def printToLog(self, logger, title):
"""Prints this catalog to the given logger, one entry per line.
Example output line: foo.bar = 1"""
file = StringIO()
file.write(HEADER % title)
self._printToLog(file, self)
file.write(FOOTER)
logger.info(file.getvalue())
def _printToLog(self, file, catalog):
for k in sorted(catalog.keys()):
v = catalog[k]
if isinstance(v, Catalog):
self._printToLog(file, v)
else:
file.write("%s.%s = %s\n" % (catalog.fullName, k, str(v)))
def renderXml(self, file=None, nodeTag=None, elementTag=None):
if not file:
file = self.fullName+'.xml'
adict = {self.fullName:self}
# from isceobj.XmlUtil import xmlUtils as xmlu
dict_to_xml(adict,file,nodeTag=nodeTag,elementTag=elementTag)
import xml.etree.ElementTree as ET
from collections import UserDict
def dict_to_xml(adict,file,nodeTag=None,elementTag=None):
a = ET.Element(nodeTag) # something to hang nodes on
a = dict_to_et(a,adict,nodeTag,elementTag)
et = a.getchildren()[0]
indent(et)
tree = ET.ElementTree(et)
tree.write(file)
def space_repl(key):
return key.replace(' ','_')
def slash_repl(key):
return key.replace('/','_dirslash_')
def key_clean(key):
return slash_repl(space_repl(key))
def dict_to_et(node,adict,nodeTag,elementTag):
for key, val in adict.items():
if isinstance(val,UserDict) or isinstance(val,dict):
if nodeTag:
subnode = ET.Element(nodeTag)
node.append(subnode)
name = ET.Element('name')
subnode.append(name)
name.text = key_clean(str(key))
else:
subnode = ET.Element(key_clean(str(key)))
node.append(subnode)
subnode = dict_to_et(subnode,val,nodeTag,elementTag)
else:
if elementTag:
subnode = ET.Element(elementTag)
node.append(subnode)
name = ET.Element('name')
subnode.append(name)
name.text = key_clean(str(key))
value = ET.Element('value')
subnode.append(value)
value.text = str(val).replace('\n', '\\n')
else:
lmnt = ET.Element(key_clean(str(key)))
node.append(lmnt)
lmnt.text = str(val).replace('\n', '\\n')
return node
def indent(elem, depth = None,last = None):
if depth == None:
depth = [0]
if last == None:
last = False
tab = ' '*4
if(len(elem)):
depth[0] += 1
elem.text = '\n' + (depth[0])*tab
lenEl = len(elem)
lastCp = False
for i in range(lenEl):
if(i == lenEl - 1):
lastCp = True
indent(elem[i],depth,lastCp)
if(not last):
elem.tail = '\n' + (depth[0])*tab
else:
depth[0] -= 1
elem.tail = '\n' + (depth[0])*tab
else:
if(not last):
elem.tail = '\n' + (depth[0])*tab
else:
depth[0] -= 1
elem.tail = '\n' + (depth[0])*tab

View File

@ -0,0 +1,103 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2011 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Eric Gurrola
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from collections import UserDict
class OrderedDict(UserDict):
def __init__(self, adict = None):
self._keys = []
UserDict.__init__(self, adict)
def __delitem__(self, key):
UserDict.__delitem__(self, key)
self._keys.remove(key)
def __setitem__(self, key, item):
UserDict.__setitem__(self, key, item)
if key not in self._keys: self._keys.append(key)
def clear(self):
UserDict.clear(self)
self._keys = []
def copy(self):
adict = UserDict.copy(self)
adict._keys = self._keys[:]
return adict
def items(self):
return zip(self._keys, self.values())
def keys(self):
return self._keys
def popitem(self):
try:
key = self._keys[-1]
except IndexError:
raise KeyError('dictionary is empty')
val = self[key]
del self[key]
return (key, val)
def setdefault(self, key, failobj = None):
UserDict.setdefault(self, key, failobj)
if key not in self._keys: self._keys.append(key)
def update(self, adict):
UserDict.update(self, adict)
for key in adict.keys():
if key not in self._keys: self._keys.append(key)
def values(self):
return map(self.get, self._keys)
if __name__ == '__main__':
# d = {'file':{'filename':'test.slc','dataType':'BANDED','interleavingScheme':'BIP','NUM_BANDS':2,'BAND_TYPES':{'BAND1':'REAL4','BAND2':'REAL4'},'width':1024,'length':2048}}
d = OrderedDdict()
d['file'] = OrderedDict()
d['file']['filename']='test.slc'
d['file']['dataType'] = 'BANDED'
d['file']['interleavingScheme'] = 'BIP'
d['file']['NUM_BANDS'] = 2
d['file']['BAND_TYPES'] = OrderedDict()
d['file']['BAND_TYPES']['BAND1'] = 'REAL4'
d['file']['BAND_TYPES']['BAND2'] = 'REAL4'
d['file']['width'] = 1024
d['file']['length'] = 2048
from isceobj.XmlUtil.xmlUtils import dict_to_xml
dict_to_xml(d,'test123.xml')

View File

@ -0,0 +1,44 @@
#! /usr/bin/env python
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2011 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Eric Gurrola
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#!/usr/bin/env python
import os
Import('envisceobj')
package = envisceobj['PACKAGE']
project = 'Catalog'
install = os.path.join(envisceobj['PRJ_SCONS_INSTALL'],package,project)
listFiles = ['Catalog.py','OrderedDict.py','__init__.py']
envisceobj.Install(install,listFiles)
envisceobj.Alias('install',install)

View File

@ -0,0 +1,71 @@
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2011 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Eric Gurrola
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def createCatalog(name):
from .Catalog import Catalog
return Catalog(name)
def createOrderedDict():
from OrderedDict import OrderedDict
return OrderedDict
def recordInputs(mainCatalog, obj, node, logger, title):
"""This is merely a convenience method to create a new catalog, add all the
inputs from the given object, print the catalog, and then import the
catalog in the main catalog. It returns the created catalog."""
catalog = createCatalog(mainCatalog.name)
catalog.addInputsFrom(obj, node + ".inputs")
catalog.printToLog(logger, title + " - Inputs")
mainCatalog.addAllFromCatalog(catalog)
return catalog
def recordOutputs(mainCatalog, obj, node, logger, title):
"""This is merely a convenience method to create a new catalog, add all the
outputs from the given object, print the catalog, and then import the
catalog in the main catalog. It returns the created catalog."""
catalog = createCatalog(mainCatalog.name)
catalog.addOutputsFrom(obj, node + ".outputs")
catalog.printToLog(logger, title + " - Outputs")
mainCatalog.addAllFromCatalog(catalog)
return catalog
def recordInputsAndOutputs(mainCatalog, obj, node, logger, title):
"""This is a short-hand for using both recordInputs and recordOutputs"""
recordInputs(mainCatalog, obj, node, logger, title)
recordOutputs(mainCatalog, obj, node, logger, title)
def testInputsChanged(startCatalog, node, obj):
endCatalog = createCatalog(startCatalog.name)
endCatalog.addInputsFrom(obj, node + ".inputs")
if not (startCatalog == endCatalog):
import sys
print("The inputs changed.")
sys.exit(1)

View File

@ -0,0 +1,50 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Authors: Giangi Sacco, Eric Belz
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"""Docstring"""
Version = "$Revision: 876$"
# $Source$
from iscesys.Compatibility import Compatibility
from isceobj.Planet.Planet import Planet
from isceobj.Planet.AstronomicalHandbook import c as SPEED_OF_LIGHT
EARTH = Planet(pname='Earth')
EarthGM = EARTH.GM
EarthSpinRate = EARTH.spin
EarthMajorSemiAxis = EARTH.ellipsoid.a
EarthEccentricitySquared = EARTH.ellipsoid.e2
def nu2lambda(nu):
return SPEED_OF_LIGHT/nu
def lambda2nu(lambda_):
return SPEED_OF_LIGHT/lambda_

View File

@ -0,0 +1,46 @@
#!/usr/bin/env python
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
Import('envisceobj')
envConstants = envisceobj.Clone()
project = 'Constants'
package = envConstants['PACKAGE']
envConstants['PROJECT'] = project
Export('envConstants')
install = os.path.join(envConstants['PRJ_SCONS_INSTALL'],package,project)
initFile = '__init__.py'
listFiles = ['Constants.py',initFile]
envConstants.Install(install,listFiles)
envConstants.Alias('install',install)

View File

@ -0,0 +1,38 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2008 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from .Constants import (
EarthGM, EarthSpinRate, EarthMajorSemiAxis, EarthEccentricitySquared,
SPEED_OF_LIGHT, nu2lambda, lambda2nu
)

View File

@ -0,0 +1,334 @@
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import print_function
import sys
import logging
import os
import math
from iscesys.Component.Component import Component, Port
from iscesys.Compatibility import Compatibility
from isceobj.Doppler import calc_dop
import isceobj
from isceobj.Util.decorators import pickled, logged, port
HEADER = Component.Parameter(
'header',
public_name='HEADER',
default=None,
type=int,
mandatory=True,
intent='input',
doc=''
)
FIRST_LINE = Component.Parameter(
'firstLine',
public_name='FIRST_LINE',
default=None,
type=int,
mandatory=True,
intent='input',
doc=''
)
QOFFSET = Component.Parameter(
'Qoffset',
public_name='QOFFSET',
default=None,
type=float,
mandatory=True,
intent='input',
doc=''
)
WIDTH = Component.Parameter(
'width',
public_name='WIDTH',
default=None,
type=int,
mandatory=True,
intent='input',
doc=''
)
LAST_LINE = Component.Parameter(
'lastLine',
public_name='LAST_LINE',
default=None,
type=int,
mandatory=True,
intent='input',
doc=''
)
IOFFSET = Component.Parameter(
'Ioffset',
public_name='IOFFSET',
default=None,
type=float,
mandatory=True,
intent='input',
doc=''
)
RAW_FILENAME = Component.Parameter(
'rawFilename',
public_name='RAW_FILENAME',
default='',
type=str,
mandatory=False,
intent='input',
doc=''
)
RNG_DOPPLER = Component.Parameter(
'rngDoppler',
public_name='RNG_DOPPLER',
default=[],
type=float,
mandatory=False,
intent='output',
doc=''
)
FD = Component.Parameter(
'fd',
public_name='FD',
default=None,
type=float,
mandatory=False,
intent='output',
doc=''
)
@pickled
class Calc_dop(Component):
parameter_list = (
HEADER,
FIRST_LINE,
QOFFSET,
WIDTH,
LAST_LINE,
IOFFSET,
RAW_FILENAME
)
logging_name = 'isceobj.Doppler.Calc_dop'
family = 'calc_dop'
@logged
def __init__(self,family='',name=''):
super(Calc_dop, self).__init__(family if family else self.__class__.family, name=name)
self.dim1_rngDoppler = None
self.quadratic = {} #insarapp
self.coeff_list = None #roiapp
self.initOptionalAndMandatoryLists()
self.createPorts()
return None
def createPorts(self):
instrumentPort = Port(name="instrument",
method=self.addInstrument,
doc=(
"An object that has getPulseRepetitionFrequency() and "+
"getInPhaseValue() methods"
))
framePort = Port(name="frame",
method=self.addFrame,
doc=(
"An object that has getNumberOfSamples() and " +
" etNumberOfLines() methods")
)
imagePort = Port(name="image",
method=self.addImage,
doc=(
"An object that has getXmin() and getXmax() methods"
)
)
self.inputPorts.add(instrumentPort)
self.inputPorts.add(framePort)
self.inputPorts.add(imagePort)
return None
def calculateDoppler(self, rawImage=None):
self.activateInputPorts()
rawCreatedHere = False
if rawImage is None:
self.rawImage = self.createRawImage()
rawCreateHere = True
else:
self.rawImage = rawImage
pass
rawAccessor = self.rawImage.getImagePointer()
self.setDefaults()
self.rngDoppler = [0]*int((self.width - self.header)/2)
self.allocateArrays()
self.setState()
calc_dop.calc_dop_Py(rawAccessor)
self.getState()
self.deallocateArrays()
if rawCreatedHere:
self.rawImage.finalizeImage()
pass
return None
def createRawImage(self):
# Check file name
width = self.width
objRaw = isceobj.createRawImage()
objRaw.initImage(self.rawFilename, 'read', width)
objRaw.createImage()
return objRaw
def fitDoppler(self):
#no fit is done. just keeping common interface with DopIQ
self.quadratic['a'] = self.fd # for now use only zero order term
self.quadratic['b'] = 0
self.quadratic['c'] = 0
self.coeff_list = [self.fd,0.,0.]
def setDefaults(self):
if self.firstLine is None:
self.firstLine = 100
self.logger.info('Variable FIRST_LINE has been set equal the defualt value %i' % (self.firstLine))
if self.lastLine is None:
self.lastLine = self.rawImage.getLength() - 200
self.logger.info('Variable LAST_LINE has been set equal the default value imageLength - 200 = %i' % (self.lastLine))
if self.header is None:
self.header = 0
self.logger.info('Variable HEADER has been set equal the default value %i' % (self.header))
@port('__complex__')
def addInstrument(self):
z = complex(self.instrument)
self.Ioffset, self.Qoffset = (z.real, z.imag)
@port('numberOfLines')
def addFrame(self):
self.numberOfLines = self.frame.numberOfLines
pass
@port(None)
def addImage(self):
self.rawFilename = self.image.getFilename()
self.header = self.image.getXmin()
self.width = self.image.getXmax() - self.header
return None
def setState(self):
calc_dop.setHeader_Py(int(self.header))
calc_dop.setWidth_Py(int(self.width))
calc_dop.setLastLine_Py(int(self.lastLine))
calc_dop.setFirstLine_Py(int(self.firstLine))
calc_dop.setIoffset_Py(float(self.Ioffset))
calc_dop.setQoffset_Py(float(self.Qoffset))
return None
def setFilename(self, var):
self.rawFilename = var
def setHeader(self, var):
self.header = int(var)
return
def setWidth(self, var):
self.width = int(var)
return
def setLastLine(self, var):
self.lastLine = int(var)
return
def setFirstLine(self, var):
self.firstLine = int(var)
return
def setIoffset(self, var):
self.Ioffset = float(var)
return
def setQoffset(self, var):
self.Qoffset = float(var)
return
def getState(self):
self.rngDoppler = calc_dop.getRngDoppler_Py(self.dim1_rngDoppler)
self.fd = calc_dop.getDoppler_Py()
return
def getRngDoppler(self):
return self.rngDoppler
def getDoppler(self):
return self.fd
def allocateArrays(self):
if self.dim1_rngDoppler is None:
self.dim1_rngDoppler = len(self.rngDoppler)
pass
if not self.dim1_rngDoppler:
print("Error. Trying to allocate zero size array")
raise Exception
calc_dop.allocate_rngDoppler_Py(self.dim1_rngDoppler)
return
def deallocateArrays(self):
calc_dop.deallocate_rngDoppler_Py()
return
pass

View File

@ -0,0 +1,72 @@
#!usr/bin/env python
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2013 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Piyush Agram
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import print_function
import sys
import numpy as np
from iscesys.Component.Component import Component, Port
class DefaultDopp(Component):
def calculateDoppler(self):
print('Using default doppler values for sensor: %s'%(self._sensor.__class__.__name__))
self.activateInputPorts()
pass
def fitDoppler(self):
pass
def addSensor(self):
sensor = self._inputPorts.getPort('sensor').getObject()
self._sensor = sensor
if (sensor):
self.quadratic = sensor.extractDoppler() #insarapp
self.coeff_list = sensor.frame._dopplerVsPixel #roiApp
self.prf = sensor.frame.getInstrument().getPulseRepetitionFrequency()
logging_name = 'DefaultDopp'
def __init__(self):
super(DefaultDopp, self).__init__()
self._sensor = None
self.quadratic = {}
self.coeff_list = None
self.prf = None
return None
def createPorts(self):
sensorPort = Port(name='sensor',method=self.addSensor)
self._inputPorts.add(sensorPort)
return None
if __name__ == '__main__':
pass

View File

@ -0,0 +1,249 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Walter Szeliga
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from iscesys.Component.Component import Component
PRF = Component.Parameter('prf',
public_name='prf',
default=None,
type=float,
mandatory=True,
doc = 'The pulse repetition frequency [Hz]')
AMBIGUITY = Component.Parameter('ambiguity',
public_name='ambiguity',
default=0,
type=float,
mandatory=False,
doc = 'The integer ambiguity of the Doppler centroid')
FRACTIONAL_CENTROID = Component.Parameter('fractionalCentroid',
public_name='fractionalCentroid',
default=0,
type=float,
mandatory=False,
intent='output',
doc = 'The fractional part of the Doppler centroid [Hz/PRF]')
LINEAR_TERM = Component.Parameter('linearTerm',
public_name='linearTerm',
default=0,
type=float,
mandatory=False,
intent='output',
doc = 'The linear term in the Doppler vs. range polynomical [Hz/PRF]')
QUADRATIC_TERM = Component.Parameter('quadraticTerm',
public_name='quadraticTerm',
default=0,
type=float,
mandatory=False,
intent='output',
doc = 'Quadratic Term')
CUBIC_TERM = Component.Parameter('cubicTerm',
public_name='cubicTerm',
default=0,
type=float,
mandatory=False,
intent='output',
doc = 'cubicTerm The cubic term in the Doppler vs. range polynomical [Hz/PRF]')
COEFS = Component.Parameter('coefs',
public_name='coefs',
default=[],
container=list,
type=float,
mandatory=False,
intent='output',
doc = 'List of the doppler coefficients')
class Doppler(Component):
family = 'doppler'
parameter_list = (
PRF,
AMBIGUITY,
FRACTIONAL_CENTROID,
LINEAR_TERM,
QUADRATIC_TERM,
CUBIC_TERM,
COEFS
)
def __init__(self,family=None,name=None,prf=0):
super(Doppler, self).__init__(
family=family if family else self.__class__.family, name=name)
"""A class to hold Doppler polynomial coefficients.
@note The polynomial is expected to be referenced to range bin.
@param prf The pulse repetition frequency [Hz]
@param ambigutiy The integer ambiguity of the Doppler centroid
@param fractionalCentroid The fractional part of the Doppler centroid
[Hz/PRF]
@param linearTerm The linear term in the Doppler vs. range polynomical
[Hz/PRF]
@param quadraticTerm The quadratic term in the Doppler vs. range
polynomical [Hz/PRF]
@param cubicTerm The cubic term in the Doppler vs. range polynomical
[Hz/PRF]
"""
self.prf = prf
self.numCoefs = 4
return
def getDopplerCoefficients(self,inHz=False):
"""Get the Doppler polynomial coefficients as a function of range,
optionally scaled by the PRF.
@param inHz (\a boolean) True if the returned coefficients should
have units of Hz, False if the "units" should be Hz/PRF
@return the Doppler polynomial coefficients as a function of range.
"""
coef = [self.ambiguity+self.fractionalCentroid]
coef += self.coefs[1:]
if inHz:
coef = [x*self.prf for x in coef]
return coef
def setDopplerCoefficients(self, coef, ambiguity=0, inHz=False):
"""Set the Doppler polynomial coefficients as a function of range.
@param coef a list containing the cubic polynomial Doppler
coefficients as a function of range
@param ambiguity (\a int) the absolute Doppler ambiguity
@param inHz (\a boolean) True if the Doppler coefficients have units
of Hz, False if the "units" are Hz/PRF
"""
self.coefs = coef #for code that handles higher order polynomials
#while continuing to support code that uses the quadratic
self.numCoefs = len(coef)
if inHz and (self.prf != 0.0):
coef = [x/self.prf for x in coef]
self.coefs = [x/self.prf for x in self.coefs]
self.fractionalCentroid = coef[0] - self.ambiguity
self.linearTerm = coef[1]
self.quadraticTerm = coef[2]
self.cubicTerm = coef[3]
def average(self, *others):
"""Average my Doppler with other Doppler objects"""
from operator import truediv
n = 1 + len(others)
prfSum = self.prf
coefSum = self.getDopplerCoefficients(inHz=True)
for e in others:
prfSum += e.prf
otherCoef = e.getDopplerCoefficients(inHz=True)
for i in range(self.numCoefs): coefSum[i] += otherCoef[i]
prf = truediv(prfSum, n)
coef = [truediv(coefSum[i], n) for i in range(self.numCoefs)]
averageDoppler = self.__class__(prf=prf)
averageDoppler.setDopplerCoefficients(coef, inHz=True)
return averageDoppler
def evaluate(self, rangeBin=0, inHz=False):
"""Calculate the Doppler in a particular range bin by evaluating the
Doppler polynomial."""
dop = (
(self.ambiguity + self.fractionalCentroid) +
self.linearTerm*rangeBin +
self.quadraticTerm*rangeBin**2 + self.cubicTerm*rangeBin**3
)
if inHz:
dop = dop*self.prf
return dop
## An obvious overload?
def __call__(self, rangeBin=0, inHz=False):
return self.evaluate(rangeBin=rangeBin, inHz=inHz)
## Convert to a standard numpy.poly1d object
def poly1d(self, inHz=False):
from numpy import poly1d, array
if inHz:
factor = 1./self.prf
variable = 'Hz'
else:
factor = 1.
variable = 'PRF'
return poly1d(array([
self.cubicTerm,
self.quadraticTerm,
self.linearTerm,
(self.ambiguity + self.fractionalCentroid)
]) * factor, variable=variable)
def __getstate__(self):
d = dict(self.__dict__)
return d
def __setstate__(self,d):
self.__dict__.update(d)
#For backwards compatibility with old PICKLE files that do not
#contain the coefs attribute and contain named coefficients only.
if not hasattr(self, 'coefs'):
coef = [self.ambiguity+self.fractionalCentroid,
self.linearTerm,
self.quadraticTerm,
self.cubicTerm]
self.coefs = coef
return
def __str__(self):
retstr = "PRF: %s\n"
retlst = (self.prf,)
retstr += "Ambiguity: %s\n"
retlst += (self.ambiguity,)
retstr += "Centroid: %s\n"
retlst += (self.fractionalCentroid,)
retstr += "Linear Term: %s\n"
retlst += (self.linearTerm,)
retstr += "Quadratic Term: %s\n"
retlst += (self.quadraticTerm,)
retstr += "Cubic Term: %s\n"
retlst += (self.cubicTerm,)
retstr += "All coefficients: %r\n"
retlst += (self.coefs,)
return retstr % retlst

View File

@ -0,0 +1,33 @@
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Giangi Sacco
# NASA Jet Propulsion Laboratory
# California Institute of Technology
# (C) 2009 All Rights Reserved
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#!/usr/bin/env python
import os
Import('envisceobj')
envDoppler = envisceobj.Clone()
package = envDoppler['PACKAGE']
project = 'Doppler'
envDoppler['PROJECT'] = project
install = os.path.join(envDoppler['PRJ_SCONS_INSTALL'],package,project)
listFiles = ['Doppler.py','__init__.py','Calc_dop.py','DefaultDopp.py']
helpList,installHelp = envDoppler['HELP_BUILDER'](envDoppler,'__init__.py',install)
envDoppler.Install(installHelp,helpList)
envDoppler.Alias('install',installHelp)
envDoppler.Install(install,listFiles)
envDoppler.Alias('install',install)
Export('envDoppler')
bindingsScons = 'bindings/SConscript'
SConscript(bindingsScons,variant_dir = envDoppler['PRJ_SCONS_BUILD'] + '/' + package + '/' + project + '/bindings')
includeScons = 'include/SConscript'
SConscript(includeScons)
srcScons = 'src/SConscript'
SConscript(srcScons,variant_dir = envDoppler['PRJ_SCONS_BUILD'] + '/' + package + '/' + project + '/src')

View File

@ -0,0 +1,95 @@
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Authors: Walter Szeliga, Eric Gurrola
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import print_function
__all__ = ('createDoppler',)
def useDefault(name=None):
if name:
instance = None
else:
import isceobj.Doppler.DefaultDopp
instance = DefaultDopp.DefaultDopp()
return instance
def useDOPIQ(name=None):
if name:
instance = None
else:
import mroipac.dopiq.DopIQ
instance = mroipac.dopiq.DopIQ.DopIQ()
return instance
def useCalcDop(name=None):
if name:
instance = None
else:
import isceobj.Doppler.Calc_dop
instance = isceobj.Doppler.Calc_dop.Calc_dop()
return instance
def useDoppler(name=None):
if name:
instance = None
else:
import mroipac.doppler.Doppler
instance = mroipac.doppler.Doppler.Doppler()
return instance
doppler_facilities = {'USEDOPIQ' : useDOPIQ,
'USECALCDOP' : useCalcDop,
'USEDOPPLER' : useDoppler,
'USEDEFAULT': useDefault}
def getFactoriesInfo():
"""
Returns a dictionary with information on how to create an object Doppler from its factory
"""
return {'Doppler':
{'args':
{
'doppler':{'value':list(doppler_facilities.keys()),'type':'str'}
},
'factory':'createDoppler'
}
}
def createDoppler(doppler=None, name=None):
if doppler.upper() in doppler_facilities.keys():
instance = doppler_facilities[doppler.upper()](name)
else:
instance = None
print(
"Doppler calculation method not recognized. Valid methods: ",
doppler_facilities.keys())
return instance

View File

@ -0,0 +1,47 @@
#!/usr/bin/env python
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
Import('envDoppler')
package = envDoppler['PACKAGE']
project = envDoppler['PROJECT']
install = envDoppler['PRJ_SCONS_INSTALL'] + '/' + package + '/' + project
build = envDoppler['PRJ_SCONS_BUILD'] + '/' + package + '/' + project
libList = ['calc_dop','utilLib','DataAccessor','InterleavedAccessor']
envDoppler.PrependUnique(LIBS = libList)
module = envDoppler.LoadableModule(target = 'calc_dop.abi3.so', source = 'calc_dopmodule.cpp')
envDoppler.Install(install,module)
envDoppler.Alias('install',install)
envDoppler.Install(build,module)
envDoppler.Alias('build',build)

View File

@ -0,0 +1,189 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// United States Government Sponsorship acknowledged. This software is subject to
// U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
// (No [Export] License Required except when exporting to an embargoed country,
// end user, or in support of a prohibited end use). By downloading this software,
// the user agrees to comply with all applicable U.S. export laws and regulations.
// The user has the responsibility to obtain export licenses, or other export
// authority as may be required before exporting this software to any 'EAR99'
// embargoed foreign country or citizen of those countries.
//
// Author: Giangi Sacco
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <Python.h>
#include "calc_dopmodule.h"
#include <cmath>
#include <sstream>
#include <iostream>
#include <string>
#include <stdint.h>
#include <vector>
using namespace std;
static const char * const __doc__ = "module for calc_dop.F";
PyModuleDef moduledef = {
// header
PyModuleDef_HEAD_INIT,
// name of the module
"calc_dop",
// module documentation string
__doc__,
// size of the per-interpreter state of the module;
// -1 if this state is global
-1,
calc_dop_methods,
};
// initialization function for the module
// *must* be called PyInit_calc_dop
PyMODINIT_FUNC
PyInit_calc_dop()
{
// create the module using moduledef struct defined above
PyObject * module = PyModule_Create(&moduledef);
// check whether module creation succeeded and raise an exception if not
if (!module) {
return module;
}
// otherwise, we have an initialized module
// and return the newly created module
return module;
}
PyObject * allocate_rngDoppler_C(PyObject* self, PyObject* args)
{
int dim1 = 0;
if(!PyArg_ParseTuple(args, "i", &dim1))
{
return NULL;
}
allocate_rngDoppler_f(&dim1);
return Py_BuildValue("i", 0);
}
PyObject * deallocate_rngDoppler_C(PyObject* self, PyObject* args)
{
deallocate_rngDoppler_f();
return Py_BuildValue("i", 0);
}
PyObject * calc_dop_C(PyObject* self, PyObject* args)
{
uint64_t var0;
if(!PyArg_ParseTuple(args, "K",&var0))
{
return NULL;
}
calc_dop_f(&var0);
return Py_BuildValue("i", 0);
}
PyObject * setHeader_C(PyObject* self, PyObject* args)
{
int var;
if(!PyArg_ParseTuple(args, "i", &var))
{
return NULL;
}
setHeader_f(&var);
return Py_BuildValue("i", 0);
}
PyObject * setWidth_C(PyObject* self, PyObject* args)
{
int var;
if(!PyArg_ParseTuple(args, "i", &var))
{
return NULL;
}
setWidth_f(&var);
return Py_BuildValue("i", 0);
}
PyObject * setLastLine_C(PyObject* self, PyObject* args)
{
int var;
if(!PyArg_ParseTuple(args, "i", &var))
{
return NULL;
}
setLastLine_f(&var);
return Py_BuildValue("i", 0);
}
PyObject * setFirstLine_C(PyObject* self, PyObject* args)
{
int var;
if(!PyArg_ParseTuple(args, "i", &var))
{
return NULL;
}
setFirstLine_f(&var);
return Py_BuildValue("i", 0);
}
PyObject * setIoffset_C(PyObject* self, PyObject* args)
{
double var;
if(!PyArg_ParseTuple(args, "d", &var))
{
return NULL;
}
setIoffset_f(&var);
return Py_BuildValue("i", 0);
}
PyObject * setQoffset_C(PyObject* self, PyObject* args)
{
double var;
if(!PyArg_ParseTuple(args, "d", &var))
{
return NULL;
}
setQoffset_f(&var);
return Py_BuildValue("i", 0);
}
PyObject * getRngDoppler_C(PyObject* self, PyObject* args)
{
int dim1 = 0;
if(!PyArg_ParseTuple(args, "i", &dim1))
{
return NULL;
}
PyObject * list = PyList_New(dim1);
double * vectorV = new double[dim1];
getRngDoppler_f(vectorV, &dim1);
for(int i = 0; i < dim1; ++i)
{
PyObject * listEl = PyFloat_FromDouble((double) vectorV[i]);
if(listEl == NULL)
{
cout << "Error in file " << __FILE__ << " at line " << __LINE__ <<
". Cannot set list element" << endl;
exit(1);
}
PyList_SetItem(list,i, listEl);
}
delete [] vectorV;
return Py_BuildValue("N",list);
}
PyObject * getDoppler_C(PyObject* self, PyObject* args)
{
double var;
getDoppler_f(&var);
return Py_BuildValue("d",var);
}

View File

@ -0,0 +1,43 @@
#!/usr/bin/env python
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
Import('envDoppler')
package = envDoppler['PACKAGE']
project = envDoppler['PROJECT']
build = envDoppler['PRJ_SCONS_BUILD'] + '/' + package + '/' + project + '/include'
envDoppler.AppendUnique(CPPPATH = [build])
listFiles = ['calc_dopmodule.h','calc_dopmoduleFortTrans.h']
envDoppler.Install(build,listFiles)
envDoppler.Alias('build',build)

View File

@ -0,0 +1,80 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// United States Government Sponsorship acknowledged. This software is subject to
// U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
// (No [Export] License Required except when exporting to an embargoed country,
// end user, or in support of a prohibited end use). By downloading this software,
// the user agrees to comply with all applicable U.S. export laws and regulations.
// The user has the responsibility to obtain export licenses, or other export
// authority as may be required before exporting this software to any 'EAR99'
// embargoed foreign country or citizen of those countries.
//
// Author: Giangi Sacco
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifndef calc_dopmodule_h
#define calc_dopmodule_h
#include <Python.h>
#include <stdint.h>
#include "calc_dopmoduleFortTrans.h"
extern "C"
{
void calc_dop_f(uint64_t *);
PyObject * calc_dop_C(PyObject *, PyObject *);
void setHeader_f(int *);
PyObject * setHeader_C(PyObject *, PyObject *);
void setWidth_f(int *);
PyObject * setWidth_C(PyObject *, PyObject *);
void setLastLine_f(int *);
PyObject * setLastLine_C(PyObject *, PyObject *);
void setFirstLine_f(int *);
PyObject * setFirstLine_C(PyObject *, PyObject *);
void setIoffset_f(double *);
PyObject * setIoffset_C(PyObject *, PyObject *);
void setQoffset_f(double *);
PyObject * setQoffset_C(PyObject *, PyObject *);
void getRngDoppler_f(double *, int *);
void allocate_rngDoppler_f(int *);
void deallocate_rngDoppler_f();
PyObject * allocate_rngDoppler_C(PyObject *, PyObject *);
PyObject * deallocate_rngDoppler_C(PyObject *, PyObject *);
PyObject * getRngDoppler_C(PyObject *, PyObject *);
void getDoppler_f(double *);
PyObject * getDoppler_C(PyObject *, PyObject *);
}
static PyMethodDef calc_dop_methods[] =
{
{"calc_dop_Py", calc_dop_C, METH_VARARGS, " "},
{"setHeader_Py", setHeader_C, METH_VARARGS, " "},
{"setWidth_Py", setWidth_C, METH_VARARGS, " "},
{"setLastLine_Py", setLastLine_C, METH_VARARGS, " "},
{"setFirstLine_Py", setFirstLine_C, METH_VARARGS, " "},
{"setIoffset_Py", setIoffset_C, METH_VARARGS, " "},
{"setQoffset_Py", setQoffset_C, METH_VARARGS, " "},
{"allocate_rngDoppler_Py", allocate_rngDoppler_C, METH_VARARGS, " "},
{"deallocate_rngDoppler_Py", deallocate_rngDoppler_C, METH_VARARGS, " "},
{"getRngDoppler_Py", getRngDoppler_C, METH_VARARGS, " "},
{"getDoppler_Py", getDoppler_C, METH_VARARGS, " "},
{NULL, NULL, 0, NULL}
};
#endif //calc_dopmodule_h

View File

@ -0,0 +1,55 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// United States Government Sponsorship acknowledged. This software is subject to
// U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
// (No [Export] License Required except when exporting to an embargoed country,
// end user, or in support of a prohibited end use). By downloading this software,
// the user agrees to comply with all applicable U.S. export laws and regulations.
// The user has the responsibility to obtain export licenses, or other export
// authority as may be required before exporting this software to any 'EAR99'
// embargoed foreign country or citizen of those countries.
//
// Author: Giangi Sacco
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifndef calc_dopmoduleFortTrans_h
#define calc_dopmoduleFortTrans_h
#if defined(NEEDS_F77_TRANSLATION)
#if defined(F77EXTERNS_LOWERCASE_TRAILINGBAR)
#define allocate_rngDoppler_f allocate_rngdoppler_
#define calc_dop_f calc_dop_
#define deallocate_rngDoppler_f deallocate_rngdoppler_
#define getDoppler_f getdoppler_
#define getRngDoppler_f getrngdoppler_
#define setFirstLine_f setfirstline_
#define setHeader_f setheader_
#define setIoffset_f setioffset_
#define setLastLine_f setlastline_
#define setQoffset_f setqoffset_
#define setWidth_f setwidth_
#else
#error Unknown translation for FORTRAN external symbols
#endif
#endif
#endif //calc_dopmoduleFortTrans_h

View File

@ -0,0 +1,41 @@
#!/usr/bin/env python
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import os
Import('envDoppler')
build = envDoppler['PRJ_LIB_DIR']
listFiles = ['calc_dop.f90','calc_dopState.F','calc_dopSetState.F','calc_dopAllocateDeallocate.F','calc_dopGetState.F']
lib = envDoppler.Library(target = 'calc_dop', source = listFiles)
envDoppler.Install(build,lib)
envDoppler.Alias('build',build)

View File

@ -0,0 +1,47 @@
subroutine calc_dop(imgAccessor)
use calc_dopState
use fortranUtils
implicit none
! return Doppler in fraction of PRF
character*60 file,buf
integer k,i,eof,pixels
real*8 prf
integer*8 imgAccessor
complex, dimension(:),allocatable :: bi,ai,ab
character, dimension(:),allocatable :: bytes_line
real*8 pi
pi = getPi()
pixels = (width-header)/2
allocate(bytes_line(width))
allocate(ai(pixels),bi(pixels),ab(pixels))
! read the first line
call initSequentialAccessor(imgAccessor,first_line)
call getLineSequential(imgAccessor,bytes_line,eof)
ai = (/(cmplx(ichar(bytes_line(header+2*i+1))-Ioffset,&
ichar(bytes_line(header+2*(i+1)))-Qoffset),i=0,pixels-1)/)
ab = cmplx(0.,0.)
do i = first_line+1,last_line
call getLineSequential(imgAccessor,bytes_line,eof)
bi = (/(cmplx(ichar(bytes_line(header+2*k+1))-Ioffset,&
ichar(bytes_line(header+2*(k+1)))-Qoffset),k=0,pixels-1)/)
ab = ab + conjg(ai)*bi
ai = bi
enddo
fd = sum(atan2(imag(ab),real(ab))/(2.d0*pi))/dble(pixels)
! write pixel dependent doppler to file
do i = 1,pixels
rngDoppler(i) = atan2(imag(ab(i)),real(ab(i)))/(2d0*pi)
enddo
! close files
deallocate(bytes_line,ai,bi,ab)
end

View File

@ -0,0 +1,44 @@
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
! You may obtain a copy of the License at
!
! http://www.apache.org/licenses/LICENSE-2.0
!
! Unless required by applicable law or agreed to in writing, software
! distributed under the License is distributed on an "AS IS" BASIS,
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! See the License for the specific language governing permissions and
! limitations under the License.
!
! United States Government Sponsorship acknowledged. This software is subject to
! U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
! (No [Export] License Required except when exporting to an embargoed country,
! end user, or in support of a prohibited end use). By downloading this software,
! the user agrees to comply with all applicable U.S. export laws and regulations.
! The user has the responsibility to obtain export licenses, or other export
! authority as may be required before exporting this software to any 'EAR99'
! embargoed foreign country or citizen of those countries.
!
! Author: Giangi Sacco
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine allocate_rngDoppler(dim1)
use calc_dopState
implicit none
integer dim1
dim1_rngDoppler = dim1
allocate(rngDoppler(dim1))
end
subroutine deallocate_rngDoppler()
use calc_dopState
deallocate(rngDoppler)
end

View File

@ -0,0 +1,48 @@
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
! You may obtain a copy of the License at
!
! http://www.apache.org/licenses/LICENSE-2.0
!
! Unless required by applicable law or agreed to in writing, software
! distributed under the License is distributed on an "AS IS" BASIS,
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! See the License for the specific language governing permissions and
! limitations under the License.
!
! United States Government Sponsorship acknowledged. This software is subject to
! U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
! (No [Export] License Required except when exporting to an embargoed country,
! end user, or in support of a prohibited end use). By downloading this software,
! the user agrees to comply with all applicable U.S. export laws and regulations.
! The user has the responsibility to obtain export licenses, or other export
! authority as may be required before exporting this software to any 'EAR99'
! embargoed foreign country or citizen of those countries.
!
! Author: Giangi Sacco
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine getRngDoppler(array1d,dim1)
use calc_dopState
implicit none
integer dim1,i
double precision, dimension(dim1):: array1d
do i = 1, dim1
array1d(i) = rngDoppler(i)
enddo
end
subroutine getDoppler(varInt)
use calc_dopState
implicit none
double precision varInt
varInt = fd
end

View File

@ -0,0 +1,73 @@
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
! You may obtain a copy of the License at
!
! http://www.apache.org/licenses/LICENSE-2.0
!
! Unless required by applicable law or agreed to in writing, software
! distributed under the License is distributed on an "AS IS" BASIS,
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! See the License for the specific language governing permissions and
! limitations under the License.
!
! United States Government Sponsorship acknowledged. This software is subject to
! U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
! (No [Export] License Required except when exporting to an embargoed country,
! end user, or in support of a prohibited end use). By downloading this software,
! the user agrees to comply with all applicable U.S. export laws and regulations.
! The user has the responsibility to obtain export licenses, or other export
! authority as may be required before exporting this software to any 'EAR99'
! embargoed foreign country or citizen of those countries.
!
! Author: Giangi Sacco
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine setHeader(varInt)
use calc_dopState
implicit none
integer varInt
header = varInt
end
subroutine setWidth(varInt)
use calc_dopState
implicit none
integer varInt
width = varInt
end
subroutine setLastLine(varInt)
use calc_dopState
implicit none
integer varInt
last_line = varInt
end
subroutine setFirstLine(varInt)
use calc_dopState
implicit none
integer varInt
first_line = varInt
end
subroutine setIoffset(varInt)
use calc_dopState
implicit none
double precision varInt
Ioffset = varInt
end
subroutine setQoffset(varInt)
use calc_dopState
implicit none
double precision varInt
Qoffset = varInt
end

View File

@ -0,0 +1,42 @@
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
! You may obtain a copy of the License at
!
! http://www.apache.org/licenses/LICENSE-2.0
!
! Unless required by applicable law or agreed to in writing, software
! distributed under the License is distributed on an "AS IS" BASIS,
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! See the License for the specific language governing permissions and
! limitations under the License.
!
! United States Government Sponsorship acknowledged. This software is subject to
! U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
! (No [Export] License Required except when exporting to an embargoed country,
! end user, or in support of a prohibited end use). By downloading this software,
! the user agrees to comply with all applicable U.S. export laws and regulations.
! The user has the responsibility to obtain export licenses, or other export
! authority as may be required before exporting this software to any 'EAR99'
! embargoed foreign country or citizen of those countries.
!
! Author: Giangi Sacco
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
module calc_dopState
integer header
integer width
integer last_line
integer first_line
double precision Ioffset
double precision Qoffset
double precision, allocatable, dimension(:) :: rngDoppler
integer dim1_rngDoppler
double precision fd
end module

View File

@ -0,0 +1,90 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Walter Szeliga
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import logging
from iscesys.Component.Component import Component
from isceobj.Filter import filter
from isceobj.Util.decorators import pickled, logged
## An decorator.object_wrapper style decoration, just for filter.
def filter_wrap(func):
#2013-06-04 Kosal: new_method takes only *args
#then we reorder and add new elements to argument list
def new_method(self, *args):
args = list(args)
filterWidth = args[0]
filterHeight = args[1]
other_args = args[2:]
new_args = [ self.inFile, self.outFile, self.width, self.length, filterWidth, filterHeight ]
new_args.extend(other_args)
return func(self, *new_args)
#Kosal
return new_method
@pickled
class Filter(Component):
"""A class for spatial filters"""
logging_name = "isce.Filter"
@logged
def __init__(self, inFile=None, outFile=None, width=None, length=None):
raw_input = ("In Filter")
super(Filter, self).__init__()
self.inFile = inFile
self.outFile = outFile
self.width = width
self.length = length
return None
#2013-05-04 Kosal: added only *args as input parameters for functions below
#so that they can be called twice with different arguments
#first when called inside FR
#and then when called by decorator.
#C functions are just called with arguments and not returned.
#logger is transferred inside FR._filterFaradayRotation
@filter_wrap
def meanFilter(self, *args):
#should be first called with: filterWidth, filterHeight
filter.meanFilter_Py(*args)
@filter_wrap
def gaussianFilter(self, *args):
#should be first called with: filterWidth, filterHeight, sigma
filter.gaussianFilter_Py(*args)
@filter_wrap
def medianFilter(self,filterWidth,filterHeight):
#should be first called with: filterWidth, filterHeight
filter.medianFilter_Py(*args)

View File

@ -0,0 +1,26 @@
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Giangi Sacco
# NASA Jet Propulsion Laboratory
# California Institute of Technology
# (C) 2009 All Rights Reserved
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#!/usr/bin/env python
import os
Import('envisceobj')
envFilter = envisceobj.Clone()
package = envisceobj['PACKAGE']
project = 'Filter'
envFilter['PROJECT'] = project
install = os.path.join(envisceobj['PRJ_SCONS_INSTALL'],package,project)
listFiles = ['Filter.py','__init__.py']
envisceobj.Install(install,listFiles)
envisceobj.Alias('install',install)
Export('envFilter')
SConscript('bindings/SConscript',variant_dir=os.path.join(envFilter['PRJ_SCONS_BUILD'],package,project,'bindings'))
SConscript('include/SConscript')
SConscript('src/SConscript',variant_dir=os.path.join(envFilter['PRJ_SCONS_BUILD'],package,project,'src'))

View File

View File

@ -0,0 +1,12 @@
#!/usr/bin/env python
import os
Import('envFilter')
package = envFilter['PACKAGE']
project = 'Filter'
install = os.path.join(envFilter['PRJ_SCONS_INSTALL'],package,project)
libList = ['filter','gomp']
envFilter.PrependUnique(LIBS = libList)
filtermodule = envFilter.LoadableModule(target = 'filter.abi3.so', source = 'filtermodule.cpp', parse_flags='-fopenmp')
envFilter.Install(install,filtermodule)
envFilter.Alias('install',install)

View File

@ -0,0 +1,119 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// United States Government Sponsorship acknowledged. This software is subject to
// U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
// (No [Export] License Required except when exporting to an embargoed country,
// end user, or in support of a prohibited end use). By downloading this software,
// the user agrees to comply with all applicable U.S. export laws and regulations.
// The user has the responsibility to obtain export licenses, or other export
// authority as may be required before exporting this software to any 'EAR99'
// embargoed foreign country or citizen of those countries.
//
// Author: Giangi Sacco
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <Python.h>
#include "filtermodule.h"
// A C++ extension is required for this code since
// ctypes does not currently allow interfacing with C++ code
// (name-mangling and all).
static const char * __doc__ = "module for filter.F";
PyModuleDef moduledef = {
// header
PyModuleDef_HEAD_INIT,
// name of the module
"filter",
// module documentation string
__doc__,
// size of the per-interpreter state of the module;
// -1 if this state is global
-1,
filter_methods,
};
// initialization function for the module
// *must* be called PyInit_filter
PyMODINIT_FUNC
PyInit_filter()
{
// create the module using moduledef struct defined above
PyObject * module = PyModule_Create(&moduledef);
// check whether module creation succeeded and raise an exception if not
if (!module) {
return module;
}
// otherwise, we have an initialized module
// and return the newly created module
return module;
}
PyObject *meanFilter_C(PyObject *self, PyObject *args)
{
char *inFile,*outFile;
int status,filterWidth,filterHeight,imageWidth,imageHeight;
if(!PyArg_ParseTuple(args, "ssiiii", &inFile, &outFile, &imageWidth,
&imageHeight,&filterWidth,&filterHeight))
{
return NULL;
}
status = meanFilterPhase(inFile, outFile, imageWidth, imageHeight,
filterWidth,filterHeight);
return Py_BuildValue("i",0);
}
PyObject *gaussianFilter_C(PyObject *self, PyObject *args)
{
char *inFile,*outFile;
int status,filterWidth,filterHeight,imageWidth,imageHeight;
double sigma;
if(!PyArg_ParseTuple(args, "ssiiiid", &inFile, &outFile, &imageWidth,
&imageHeight,&filterWidth,&filterHeight,&sigma))
{
return NULL;
}
status = gaussianFilterPhase(inFile, outFile, imageWidth, imageHeight,
filterWidth,filterHeight,sigma);
return Py_BuildValue("i",0);
}
PyObject *medianFilter_C(PyObject *self, PyObject *args)
{
char *inFile,*outFile;
int status,filterWidth,filterHeight,imageWidth,imageHeight;
if(!PyArg_ParseTuple(args, "ssiiii", &inFile, &outFile, &imageWidth,
&imageHeight,&filterWidth,&filterHeight))
{
return NULL;
}
status = medianFilterPhase(inFile, outFile, imageWidth, imageHeight,
filterWidth, filterHeight);
return Py_BuildValue("i",0);
}

View File

@ -0,0 +1,9 @@
#include "Filter.hh"
class EdgeFilter: public Filter
{
private:
void setup();
public:
EdgeFilter(int width, int height);
};

View File

@ -0,0 +1,27 @@
#ifndef FILTER_HH
#define FILTER_HH 1
class Filter
{
protected:
int width;
int height;
double scale;
double offset;
double *filter;
void setWidth(int width);
void setHeight(int height);
void setValue(int x, int y, double value);
public:
Filter(int width, int height);
~Filter();
int getWidth();
int getHeight();
double getScale();
double getOffset();
double getValue(int x, int y);
void setScale(double scale);
void setOffset(double offset);
};
#endif

View File

@ -0,0 +1,12 @@
#include "Filter.hh"
class GaussianFilter: public Filter
{
private:
double sigma2;
void setup();
double G(double x, double y);
public:
GaussianFilter(int width, int height);
GaussianFilter(int width, int height,double sigma2);
};

View File

@ -0,0 +1,132 @@
#include <sys/types.h>
#include <sys/stat.h>
#ifdef sun
#include <fcntl.h>
#else
#include <sys/fcntl.h>
#include <unistd.h>
#endif
#include <sys/mman.h>
#include <iostream>
#include <string>
template <typename T>
class Image
{
private:
int width;
int height;
char *filename;
int openFlags;
int mapFlags;
int fd;
T *image;
void createMap();
void testCoordinates(int x, int y);
public:
Image(char *filename, const char *mode, int width, int height);
~Image();
int getHeight();
int getWidth();
T getValue(int x, int y);
void setValue(int x, int y, T val);
};
template <typename T>
Image<T>::Image(char *filename,const char *mode,int width,int height)
{
this->filename = filename;
this->width = width;
this->height = height;
std::string read = "r";
std::string write = "w";
// Convert the mode to an oflag for open and a flag for mmap
if (read.compare(mode) == 0)
{
this->openFlags = O_RDONLY;
this->mapFlags = PROT_READ;
}
else if (write.compare(mode) == 0)
{
this->openFlags = (O_RDWR | O_CREAT);
this->mapFlags = (PROT_READ | PROT_WRITE);
}
try {
this->createMap();
} catch (const char *e) {
std::cerr << e << std::endl;
}
}
template <typename T>
Image<T>::~Image()
{
size_t size = (size_t)(this->width*this->height*sizeof(T));
munmap(this->image,size);
close(this->fd);
}
template <typename T>
int Image<T>::getWidth()
{
return this->width;
}
template <typename T>
int Image<T>::getHeight()
{
return this->height;
}
template <typename T>
void Image<T>::createMap()
{
size_t size = (size_t)(this->width*this->height*sizeof(T));
// If we are creating this image for the first time, we need to "create" space
// for it on the drive
if ( this->openFlags == (O_RDWR | O_CREAT) )
{
this->fd = open(this->filename, this->openFlags, (mode_t)0600);
int status = ftruncate(this->fd,size);
if (status == -1) {throw "Unable to create file";}
}
else
{
this->fd = open(this->filename, this->openFlags);
}
this->image = (T *)mmap(0, size, this->mapFlags, MAP_SHARED, this->fd,0);
if (this->image == MAP_FAILED)
{
throw "Memory mapping failed";
}
}
template <typename T>
T Image<T>::getValue(int x, int y)
{
this->testCoordinates(x,y);
return this->image[y*this->width + x];
}
template <typename T>
void Image<T>::setValue(int x, int y, T val)
{
this->testCoordinates(x,y);
this->image[y*this->width + x] = val;
}
template <typename T>
void Image<T>::testCoordinates(int x, int y)
{
if (x > this->width)
{
throw "X coordinate out of bounds";
}
if (y > this->height)
{
throw "Y coordinate out of bounds";
}
}

View File

@ -0,0 +1,7 @@
#include "Filter.hh"
class MeanFilter: public Filter
{
public:
MeanFilter(int width, int height);
};

View File

@ -0,0 +1,12 @@
#!/usr/bin/env python
import os
Import('envFilter')
package = envFilter['PACKAGE']
project = 'Filter'
build = os.path.join(envFilter['PRJ_SCONS_BUILD'],package,project,'include')
envFilter.AppendUnique(CPPPATH = [build])
listFiles = ['filtermodule.h','header.h','Filter.hh','MeanFilter.hh','GaussianFilter.hh','Image.hh']
envFilter.Install(build,listFiles)
envFilter.Alias('install',build)

View File

@ -0,0 +1,62 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// United States Government Sponsorship acknowledged. This software is subject to
// U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
// (No [Export] License Required except when exporting to an embargoed country,
// end user, or in support of a prohibited end use). By downloading this software,
// the user agrees to comply with all applicable U.S. export laws and regulations.
// The user has the responsibility to obtain export licenses, or other export
// authority as may be required before exporting this software to any 'EAR99'
// embargoed foreign country or citizen of those countries.
//
// Author: Giangi Sacco
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifndef filtermodule_h
#define filtermodule_h 1
#include <Python.h>
#include <complex>
#include "Image.hh"
#include "Filter.hh"
#include "header.h"
int meanFilterPhase(char *inFile, char *outFile, int imageWidth,
int imageHeight,int filterWidth,int filterHeight);
int gaussianFilterPhase(char *inFile, char *outFile, int imageWidth,
int imageHeight,int filterWidth,int filterHeight,double sigma);
int medianFilterPhase(char *inFile, char *outFile, int imageWidth,
int imageHeight,int filterWidth,int filterHeight);
extern "C"
{
PyObject *meanFilter_C(PyObject *self,PyObject *args);
PyObject *gaussianFilter_C(PyObject *self,PyObject *args);
PyObject *medianFilter_C(PyObject *self,PyObject *args);
}
static PyMethodDef filter_methods[] =
{
{"meanFilter_Py",meanFilter_C,METH_VARARGS," "},
{"gaussianFilter_Py",gaussianFilter_C,METH_VARARGS," "},
{"medianFilter_Py",medianFilter_C,METH_VARARGS," "},
{NULL,NULL,0,NULL}
};
#endif

View File

@ -0,0 +1,2 @@
void cpxPhaseFilter(Image<std::complex<float> > *image, Image<std::complex<float> > *result, Filter *filter);
void medianPhaseFilter(Image<std::complex<float> > *image, Image<std::complex<float> > *result, int filterWidth, int filterHeight);

View File

@ -0,0 +1,33 @@
#include <cmath>
#include "EdgeFilter.hh"
EdgeFilter::EdgeFilter(int width, int height) : Filter(width,height)
{
if ((this->width%2 == 0) || (this->height%2 == 0))
{
throw "Edge Filter dimensions must be odd\n";
}
this->setup();
}
void
EdgeFilter::setup()
{
int x;
int halfX, halfY;
double sum = 0.0;
halfX = floor(width/2);
halfY = floor(height/2);
// Construct an Edge Filter
for(x=0;x<halfX;x++)
{
this->setValue(x,halfY,-1.0);
sum += -1.0;
}
this->setValue(halfX,halfY,-sum);
this->setScale(1.0);
this->setOffset(0.0);
}

View File

@ -0,0 +1,31 @@
#include "Filter.hh"
Filter::Filter(int width, int height)
{
if ((width <= 0) || (height <= 0)) { throw "Filter dimensions must be positive";}
this->width = width;
this->height = height;
this->filter = new double[width*height];
}
Filter::~Filter()
{
delete [] this->filter;
}
void Filter::setWidth(int width) { this->width = width; }
void Filter::setHeight(int height) { this->height = height; }
void Filter::setScale(double scale) { this->scale = scale; }
void Filter::setOffset(double offset) { this->offset = offset; }
void Filter::setValue(int x, int y, double value) { this->filter[y*width + x] = value; }
int Filter::getWidth() { return this->width; }
int Filter::getHeight() { return this->height; }
double Filter::getScale() { return this->scale; }
double Filter::getOffset() { return this->offset; }
double
Filter::getValue(int x, int y)
{
return this->filter[y*width + x];
}

View File

@ -0,0 +1,43 @@
#include <iostream>
#include <cmath>
#include "GaussianFilter.hh"
GaussianFilter::GaussianFilter(int width, int height) : Filter(width,height)
{
this->sigma2 = 1.0;
this->setup();
}
GaussianFilter::GaussianFilter(int width, int height, double sigma2) : Filter(width,height)
{
this->sigma2 = sigma2;
this->setup();
}
void
GaussianFilter::setup()
{
int x,y;
double sum = 0.0;
for(x=0;x<this->width;x++)
{
double filterX = (x-floor(this->width/2.0));
for(y=0;y<this->height;y++)
{
double filterY = (floor(this->height/2.0)-y);
double val = this->G(filterX,filterY);
sum += val;
this->setValue(x,y,val);
}
}
this->setScale(1.0/sum);
this->setOffset(0.0);
}
double
GaussianFilter::G(double x, double y)
{
return exp(-(x*x + y*y)/(2.0*this->sigma2))/(2.0*M_PI*this->sigma2);
}

View File

@ -0,0 +1,18 @@
#include "MeanFilter.hh"
MeanFilter::MeanFilter(int width, int height) : Filter(width,height)
{
int x,y;
// Construct a Mean Filter
for(x=0;x<this->width;x++)
{
for(y=0;y<this->height;y++)
{
this->setValue(x,y,1.0);
}
}
this->setScale(1.0/(width*height));
this->setOffset(0.0);
}

View File

@ -0,0 +1,10 @@
import os
Import('envFilter')
package = envFilter['PACKAGE']
project = envFilter['PROJECT']
install = envFilter['PRJ_LIB_DIR']
listFiles = ['Filter.cpp','MeanFilter.cpp','GaussianFilter.cpp','cpxPhaseFilter.cpp','filterPhase.cpp','medianFilter.cpp']
lib = envFilter.Library(target = 'filter', source = listFiles, parse_flags='-fopenmp')
envFilter.Install(install,lib)
envFilter.Alias('install',install)

View File

@ -0,0 +1,36 @@
#include <complex>
#include "Image.hh"
#include "Filter.hh"
void
cpxPhaseFilter(Image<std::complex<float> > *image, Image<std::complex<float> > *result, Filter *filter)
{
int x,y,filterX,filterY;
int imageWidth = image->getWidth();
int imageHeight = image->getHeight();
int w = imageWidth;
int h = imageHeight;
#pragma omp parallel for private(x,y,filterX,filterY) shared(image,filter,result)
for (x=0;x<w;x++)
{
for (y=0;y<h;y++)
{
float phase = 0.0;
for (filterX=0;filterX<filter->getWidth();filterX++)
{
for (filterY=0;filterY<filter->getHeight();filterY++)
{
int imageX = (x-filter->getWidth()/2 + filterX + w) % w;
int imageY = (y-filter->getHeight()/2 + filterY + h) % h;
std::complex<float> cpx = image->getValue(imageX,imageY);
phase += arg(cpx) * filter->getValue(filterX,filterY);
}
}
float mag = abs(image->getValue(x,y));
float arg = filter->getScale()*phase + filter->getOffset();
std::complex<float> ans = std::polar(mag,arg);
result->setValue(x,y,ans);
}
}
}

View File

@ -0,0 +1,53 @@
#include <complex>
#include "Image.hh"
#include "MeanFilter.hh"
#include "GaussianFilter.hh"
#include "header.h"
// This is an interface layer between Python and the C++ object creation
int
meanFilterPhase(char *inFile, char *outFile, int imageWidth, int imageHeight, int filterWidth, int filterHeight)
{
MeanFilter *filter = new MeanFilter(filterWidth,filterHeight);
Image<std::complex<float> > *inImage = new Image<std::complex<float> >(inFile,"r",imageWidth,imageHeight);
Image<std::complex<float> > *outImage = new Image<std::complex<float> >(outFile,"w",imageWidth,imageHeight);
cpxPhaseFilter(inImage,outImage,filter);
delete filter;
delete inImage;
delete outImage;
return 1;
}
int
gaussianFilterPhase(char *inFile, char *outFile, int imageWidth, int imageHeight, int filterWidth, int filterHeight, double sigma)
{
GaussianFilter *filter = new GaussianFilter(filterWidth,filterHeight,sigma);
Image<std::complex<float> > *inImage = new Image<std::complex<float> >(inFile,"r",imageWidth,imageHeight);
Image<std::complex<float> > *outImage = new Image<std::complex<float> >(outFile,"w",imageWidth,imageHeight);
cpxPhaseFilter(inImage,outImage,filter);
delete filter;
delete inImage;
delete outImage;
return 1;
}
int
medianFilterPhase(char *inFile, char *outFile, int imageWidth, int imageHeight, int filterWidth, int filterHeight)
{
Image<std::complex<float> > *inImage = new Image<std::complex<float> >(inFile,"r",imageWidth,imageHeight);
Image<std::complex<float> > *outImage = new Image<std::complex<float> >(outFile,"w",imageWidth,imageHeight);
medianPhaseFilter(inImage,outImage,filterWidth,filterHeight);
delete inImage;
delete outImage;
return 1;
}

View File

@ -0,0 +1,68 @@
#include <cmath>
#include <cstdlib>
#include <complex>
#include "Image.hh"
int compare(const void *a, const void *b);
void
medianPhaseFilter(Image<std::complex<float> > *image, Image<std::complex<float> > *result, int filterWidth, int filterHeight)
{
int x,y,filterX,filterY;
int imageWidth = image->getWidth();
int imageHeight = image->getHeight();
int w = imageWidth;
int h = imageHeight;
float phase[filterWidth*filterHeight];
#pragma omp parallel for private(x,y,filterX,filterY,phase) shared(image,result)
for (x=0;x<w;x++)
{
for (y=0;y<h;y++)
{
int n = 0;
for (filterX=0;filterX<filterWidth;filterX++)
{
for (filterY=0;filterY<filterHeight;filterY++)
{
int imageX = (x-filterWidth/2 + filterX + w) % w;
int imageY = (y-filterHeight/2 + filterY + h) % h;
std::complex<float> cpx = image->getValue(imageX,imageY);
phase[n] = arg(cpx);
n++;
}
}
//heapsort(phase, filterWidth*filterHeight, sizeof(float), compare);
qsort(phase, filterWidth*filterHeight, sizeof(float), compare);
float carg;
// Calculate the median
if ((filterWidth*filterHeight) % 2 == 1)
{
carg = phase[filterWidth*filterHeight/2];
}
else if (filterWidth >= 2)
{
carg = (phase[filterWidth*filterHeight/2] + phase[filterWidth*filterHeight/2 + 1])/2;
}
float mag = abs(image->getValue(x,y));
std::complex<float> ans = std::polar(mag,carg);
result->setValue(x,y,ans);
}
}
}
int
compare(const void *a, const void *b)
{
// First, convert the void pointer to a pointer of known type
const float *fa = (const float *)a;
const float *fb = (const float *)b;
// Then, dereference the pointers and return their difference
// if this difference is negative, then b is larger than a
// if this differene is positive, then a is larger than b
return (int)(*fa - *fb);
}

View File

@ -0,0 +1,121 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import print_function
import sys
import os
import math
import logging
from iscesys.Compatibility import Compatibility
Compatibility.checkPythonVersion()
from .Image import Image
from iscesys.Component.Component import Component
##
# This class allows the creation of a AmpImage object. The parameters that need to be set are
#\verbatim
#WIDTH: width of the image in units of the DATA_TYPE. Mandatory.
#FILE_NAME: name of the file containing the image. Mandatory.
#DATA_TYPE: data type used to store the image. The naming convention is the one adopted by numpy (see LineAccessor class). Optional. Default value 'BYTE'.
#ACCESS_MODE: access mode of the file such as 'read', 'write' etc. See LineAccessor class for all possible values. Mandatory.
#SCHEME: the interleaving scheme adopted for the image. Could be BIL (band interleaved by line), BIP (band intereleaved by pixel) and BSQ (band sequential). Optional. BIP set by default.
#CASTER: define the type of caster. For example DoubleToFloat reads the image data as double but puts it into a buffer that is of float type. Optional. If not provided casting is not performed.
#\endverbatim
#Since the AmpImage class inherits the Image.Image, the methods of initialization described in the Component package can be used.
#Moreover each parameter can be set with the corresponding accessor method setParameter() (see the class member methods).
#@see DataAccessor.Image.
#@see Component.Component.
NUMBER_BANDS = Component.Parameter('bands',
public_name='NUMBER_BANDS',
default=2,
type=int,
mandatory=False,
doc='Number of image bands.')
DATA_TYPE = Component.Parameter('dataType',
public_name='DATA_TYPE',
default='float',
type=str,
mandatory=True,
doc='Image data type.')
IMAGE_TYPE = Component.Parameter('imageType',
public_name='IMAGE_TYPE',
default='amp',
type=str,
mandatory=False,
private=True,
doc='Image type used for displaying.')
class AmpImage(Image):
parameter_list = (
NUMBER_BANDS,
DATA_TYPE,
IMAGE_TYPE
)
def createImage(self):
self.checkInitialization()
Image.createImage(self)
def updateParameters(self):
self.extendParameterList(Image,AmpImage)
super(AmpImage,self).updateParameters()
family ='ampimage'
def __init__(self,family = '', name = ''):
self.parameter_list = self.parameter_list + super(Image,self).parameter_list
self.updateParameters()
super(AmpImage, self).__init__(family if family else self.__class__.family, name=name)
self.initOptionalAndMandatoryLists()
self.addDescription('Amplitude image. Two bands image interleaved by pixel. Each band correspond to the amplitude of a given image.')
self.logger = logging.getLogger('isce.isceobj.Image.AmpImage')
return
def __getstate__(self):
d = dict(self.__dict__)
del d['logger']
return d
def __setstate__(self,d):
self.__dict__.update(d)
self.logger = logging.getLogger('isce.isceobj.Image.AmpImage')
return
#end class

View File

@ -0,0 +1,127 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import print_function
import sys
import os
import math
import logging
from iscesys.Compatibility import Compatibility
Compatibility.checkPythonVersion()
from .Image import Image
from iscesys.Component.Component import Component
##
# This class allows the creation of a BILImage object. The parameters that need to be set are
#\verbatim
#WIDTH: width of the image in units of the DATA_TYPE. Mandatory.
#FILE_NAME: name of the file containing the image. Mandatory.
#DATA_TYPE: data type used to store the image. The naming convention is the one adopted by numpy (see LineAccessor class). Optional. Default value 'BYTE'.
#ACCESS_MODE: access mode of the file such as 'read', 'write' etc. See LineAccessor class for all possible values. Mandatory.
#SCHEME: the interleaving scheme adopted for the image. Could be BIL (band interleaved by line), BIP (band intereleaved by pixel) and BSQ (band sequential). Optional. BIP set by default.
#CASTER: define the type of caster. For example DoubleToFloat reads the image data as double but puts it into a buffer that is of float type. Optional. If not provided casting is not performed.
#\endverbatim
#Since the BILImage class inherits the Image.Image, the methods of initialization described in the Component package can be used.
#Moreover each parameter can be set with the corresponding accessor method setParameter() (see the class member methods).
#@see DataAccessor.Image.
#@see Component.Component.
NUMBER_BANDS = Component.Parameter('bands',
public_name='NUMBER_BANDS',
default=2,
type=int,
mandatory=False,
doc='Number of image bands.')
DATA_TYPE = Component.Parameter('dataType',
public_name='DATA_TYPE',
default='float',
type=str,
mandatory=True,
doc='Image data type.')
IMAGE_TYPE = Component.Parameter('imageType',
public_name='IMAGE_TYPE',
default='bil',
type=str,
mandatory=False,
private=True,
doc='Image type used for displaying.')
SCHEME = Component.Parameter('scheme',
public_name='SCHEME',
default='BIL',
type=str,
mandatory=False,
doc='Interleaving scheme of the image.')
class BILImage(Image):
parameter_list = (
NUMBER_BANDS,
DATA_TYPE,
IMAGE_TYPE,
SCHEME
)
def createImage(self):
self.checkInitialization()
Image.createImage(self)
def updateParameters(self):
self.extendParameterList(Image,BILImage)
super(BILImage,self).updateParameters()
family ='bilimage'
def __init__(self,family = '', name = ''):
self.updateParameters()
super(BILImage, self).__init__(family if family else self.__class__.family, name=name)
self.initOptionalAndMandatoryLists()
self.logger = logging.getLogger('isce.Image.BILImage')
return
def __getstate__(self):
d = dict(self.__dict__)
del d['logger']
return d
def __setstate__(self,d):
self.__dict__.update(d)
self.logger = logging.getLogger('isce.Image.BILImage')
return
#end class

View File

@ -0,0 +1,138 @@
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import print_function
import sys
import os
import math
import logging
from iscesys.Compatibility import Compatibility
Compatibility.checkPythonVersion()
from .Image import Image
from iscesys.Component.Component import Component
##
# This class allows the creation of a DemImage object. The parameters that need to be set are
#\verbatim
#WIDTH: width of the image in units of the DATA_TYPE. Mandatory.
#FILE_NAME: name of the file containing the image. Mandatory.
#DATA_TYPE: data type used to store the image. The naming convention is the one adopted by numpy (see LineAccessor class). Optional. Default value 'BYTE'.
#ACCESS_MODE: access mode of the file such as 'read', 'write' etc. See LineAccessor class for all possible values. Mandatory.
#FIRST_LATITUDE: first latitude of the DEM image.
#FIRST_LONGITUDE: first longitude of the DEM image.
#DELTA_LATITUDE: separation in latitude between two pixels.
#DELTA_LONGITUDE: separation in longitude between two pixels.
#SCHEME: the interleaving scheme adopted for the image. Could be BIL (band interleaved by line), BIP (band intereleaved by pixel) and BSQ (band sequential). Optional. BIP set by default.
#CASTER: define the type of caster. For example DoubleToFloat reads the image data as double but puts it into a buffer that is of float type. Optional. If not provided casting is not performed.
#\endverbatim
#Since the DemImage class inherits the Image.Image, the methods of initialization described in the Component package can be used.
#Moreover each parameter can be set with the corresponding accessor method setParameter() (see the class member methods).
#@see DataAccessor.Image.
#@see Component.Component.
REFERENCE = Component.Parameter('reference',
public_name='REFERENCE',
default='EGM96',
type=str,
mandatory=False,
doc='Geodetic datum')
DATA_TYPE = Component.Parameter('dataType',
public_name='DATA_TYPE',
default='short',
type=str,
mandatory=True,
doc='Image data type.')
IMAGE_TYPE = Component.Parameter('imageType',
public_name='IMAGE_TYPE',
default='dem',
type=str,
mandatory=False,
private=True,
doc='Image type used for displaying.')
class DemImage(Image):
parameter_list = (
REFERENCE,
DATA_TYPE,
IMAGE_TYPE
)
def createImage(self):
# self.checkInitialization()
Image.createImage(self)
def updateParameters(self):
self.extendParameterList(Image,DemImage)
super(DemImage,self).updateParameters()
family = "demimage"
def __init__(self,family='',name=''):
self.updateParameters()
super(DemImage, self).__init__(family if family else self.__class__.family, name=name)
self.initOptionalAndMandatoryLists()
self.logger = logging.getLogger('isce.Image.DemImageBase')
return
def getsnwe(self):
'''Return the bounding box.'''
lats = [self.firstLatitude, self.firstLatitude + (self.length-1)*self.deltaLatitude]
lons = [self.firstLongitude, self.firstLongitude + (self.width-1)*self.deltaLongitude]
snwe = [min(lats), max(lats), min(lons), max(lons)]
return snwe
def __getstate__(self):
d = dict(self.__dict__)
del d['logger']
return d
def __setstate__(self,d):
self.__dict__.update(d)
self.logger = logging.getLogger('isce.Image.DemImageBase')
return
#end class

819
components/isceobj/Image/Image.py Executable file
View File

@ -0,0 +1,819 @@
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Giangi Sacco
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import print_function
import sys
import os
import math
import logging
import contextlib
from iscesys.Dumpers.XmlDumper import XmlDumper
from iscesys.Component.Configurable import Configurable
from iscesys.ImageApi.DataAccessorPy import DataAccessor
from iscesys.ImageApi import CasterFactory as CF
from iscesys.DictUtils.DictUtils import DictUtils as DU
from isceobj.Util import key_of_same_content
from isceobj.Util.decorators import pickled, logged
from iscesys.Component.Component import Component
import numpy as np
from isceobj.Util.decorators import use_api
# # \namespace ::isce.components.isceobj.Image Base class for Image API
# # This is the default copy list-- it is not a class attribute because the
# # I decided the class wwas too big-- but that's strictly subjective.
ATTRIBUTES = ('bands', 'scheme', 'caster', 'width', 'filename', 'byteOrder',
'dataType', 'xmin', 'xmax', 'numberGoodBytes', 'firstLatitude',
'firstLongitude', 'deltaLatitude', 'deltaLongitude')
# # Map various byte order codes to Image's.
ENDIAN = {'l':'l', 'L':'l', '<':'l', 'little':'l', 'Little':'l',
'b':'b', 'B':'b', '>':'b', 'big':'b', 'Big':'b'}
# long could be machine dependent
sizeLong = DataAccessor.getTypeSizeS('LONG')
TO_NUMPY = {'BYTE':'i1', 'SHORT':'i2', 'INT':'i4', 'LONG':'i' + str(sizeLong), 'FLOAT':'f4', 'DOUBLE':'f8',
'CFLOAT':'c8', 'CDOUBLE':'c16'}
BYTE_ORDER = Component.Parameter('byteOrder',
public_name='BYTE_ORDER',
default=sys.byteorder[0].lower(),
type=str,
mandatory=False,
doc='Endianness of the image.')
WIDTH = Component.Parameter('width',
public_name='WIDTH',
default=None,
type=int,
mandatory=False,
private=True,
doc='Image width')
LENGTH = Component.Parameter('length',
public_name='LENGTH',
default=None,
type=int,
mandatory=False,
private=True,
doc='Image length')
SCHEME = Component.Parameter('scheme',
public_name='SCHEME',
default='BIP',
type=str,
mandatory=False,
doc='Interleaving scheme of the image.')
CASTER = Component.Parameter('caster',
public_name='CASTER',
default='',
type=str,
mandatory=False,
private=True,
doc='Type of conversion to be performed from input '
+ 'source to output source. Being input or output source will depend on the type of operations performed (read or write)')
NUMBER_BANDS = Component.Parameter('bands',
public_name='NUMBER_BANDS',
default=1,
type=int,
mandatory=False,
doc='Number of image bands.')
'''
COORD1 = Component.Parameter('coord1',
public_name='COORD1',
default=None,
type=int,
mandatory=True,
doc='Horizontal coordinate.')
COORD2 = Component.Parameter('coord2',
public_name='COORD2',
default=None,
type=int,
mandatory=True,
doc='Vertical coordinate.')
'''
DATA_TYPE = Component.Parameter('dataType',
public_name='DATA_TYPE',
default='',
type=str,
mandatory=True,
doc='Image data type.')
IMAGE_TYPE = Component.Parameter('imageType',
public_name='IMAGE_TYPE',
default='',
type=str,
mandatory=False,
private=True,
doc='Image type used for displaying.')
FILE_NAME = Component.Parameter('filename',
public_name='FILE_NAME',
default='',
type=str,
mandatory=True,
doc='Name of the image file.')
EXTRA_FILE_NAME = Component.Parameter('_extraFilename',
public_name='EXTRA_FILE_NAME',
default='',
type=str,
private=True,
mandatory=False,
doc='For example name of vrt metadata.')
ACCESS_MODE = Component.Parameter('accessMode',
public_name='ACCESS_MODE',
default='',
type=str,
mandatory=True,
doc='Image access mode.')
DESCRIPTION = Component.Parameter('description',
public_name='DESCRIPTION',
default='',
type=str,
mandatory=False,
private=True,
doc='Image description')
XMIN = Component.Parameter('xmin',
public_name='XMIN',
default=None,
type=float,
mandatory=False,
private=True,
doc='Minimum range value')
XMAX = Component.Parameter('xmax',
public_name='XMAX',
default=None,
type=float,
mandatory=False,
private=True,
doc='Maximum range value')
ISCE_VERSION = Component.Parameter('isce_version',
public_name='ISCE_VERSION',
default=None,
type=str,
mandatory=False,
private=True,
doc='Information about the isce release version.')
COORD1 = Component.Facility(
'coord1',
public_name='Coordinate1',
module='isceobj.Image',
factory='createCoordinate',
args=(),
mandatory=True,
doc='First coordinate of a 2D image (width).'
)
COORD2 = Component.Facility(
'coord2',
public_name='Coordinate2',
module='isceobj.Image',
factory='createCoordinate',
args=(),
mandatory=True,
doc='Second coordinate of a 2D image (length).'
)
@pickled
class Image(DataAccessor, Configurable):
logging_name = 'isce.isceobj.Image.Image'
parameter_list = (
BYTE_ORDER,
SCHEME,
CASTER,
NUMBER_BANDS,
WIDTH,
LENGTH,
DATA_TYPE,
IMAGE_TYPE,
FILE_NAME,
EXTRA_FILE_NAME,
ACCESS_MODE,
DESCRIPTION,
XMIN,
XMAX,
ISCE_VERSION
)
facility_list = (
COORD1,
COORD2
)
family = 'image'
def __init__(self, family='', name=''):
# There is an hack to set the first latitude and longitude (see setters) so coord1 and 2
# need to be defined when calling Configurable.__init__ which will try to call the setters
self.catalog = {}
self.descriptionOfVariables = {}
self.descriptionOfFacilities = {}
self._dictionaryOfFacilities = {}
self.typeOfVariables = {}
self.unitsOfVariables = {}
self.dictionaryOfOutputVariables = {}
self.dictionaryOfVariables = {}
self.mandatoryVariables = []
self.optionalVariables = []
# since we hacked the with to call coord1 the facilities need to be defined when calling
# Configurable.__init__
self._facilities()
self.updateParameters()
DataAccessor.__init__(self)
Configurable.__init__(self, family if family else self.__class__.family, name=name)
self._instanceInit()
self._isFinalized = False
return None
# To facilitate the use of numpy to manipulate isce images
def toNumpyDataType(self):
return TO_NUMPY[self.dataType.upper()]
def updateParameters(self):
self.extendParameterList(Configurable, Image)
super(Image, self).updateParameters()
# # New usage is: image.copy_attribute(image', *args), replacing:
# # ImageUtil.ImageUtil.ImageUtil.copyAttributes(image, image', *args)
def copy_attributes(self, other, *args):
for item in args or ATTRIBUTES:
try:
setattr(other, item, getattr(self, item))
except AttributeError:
pass
return other
# Why reinventing the wheel when there is deepcopy
# # This method makes a new image sub-class object that are copies of
# # existing ones.
def copy(self, access_mode=None):
obj_new = self.copy_attributes(self.__class__())
if access_mode:
obj_new.setAccessMode(access_mode)
obj_new.createImage()
return obj_new
def clone(self, access_mode=None):
import copy
obj_new = copy.deepcopy(self)
if access_mode:
obj_new.setAccessMode(access_mode)
return obj_new
# # Call the copy method, as a context manager
@contextlib.contextmanager
def ccopy(self, access_mode=None):
result = self.copy(access_mode=access_mode)
yield result
result.finalizeImage()
pass
# # creates a DataAccessor.DataAccessor instance. If the parameters tagged
# # as mandatory are not set, an exception is thrown.
def createImage(self):
self.createAccessor()
da = self.getAccessor()
###Intercept for GDAL
if self.methodSelector() != 'api':
return None
try:
fsize = os.path.getsize(self.filename)
except OSError:
print("File", self.filename, "not found")
raise OSError
size = self.getTypeSize()
if(fsize != self.width * self.length * size * self.bands):
print("Image.py::createImage():Size on disk and size computed from metadata for file", \
self.filename, "do not match")
sys.exit(1)
self._isFinalized = False
return None
def memMap(self, mode='r', band=None):
if self.scheme.lower() == 'bil':
immap = np.memmap(self.filename, self.toNumpyDataType(), mode,
shape=(self.coord2.coordSize , self.bands, self.coord1.coordSize))
if band is not None:
immap = immap[:, band, :]
elif self.scheme.lower() == 'bip':
immap = np.memmap(self.filename, self.toNumpyDataType(), mode,
shape=(self.coord2.coordSize, self.coord1.coordSize, self.bands))
if band is not None:
immap = immap[:, :, band]
elif self.scheme.lower() == 'bsq':
immap = np.memmap(self.filename, self.toNumpyDataType(), mode,
shape=(self.bands, self.coord2.coordSize, self.coord1.coordSize))
if band is not None:
immap = immap[band, :, :]
return immap
def asMemMap(self, filename):
if self.scheme.lower() == 'bil':
immap = np.memmap(filename, self.toNumpyDataType(), 'w+',
shape=(self.coord2.coordSize , self.bands, self.coord1.coordSize))
elif self.scheme.lower() == 'bip':
immap = np.memmap(filename, self.toNumpyDataType(), 'w+',
shape=(self.coord2.coordSize, self.coord1.coordSize, self.bands))
elif self.scheme.lower() == 'bsq':
immap = np.memmap(filename, self.toNumpyDataType(), 'w+',
shape=(self.bands, self.coord2.coordSize, self.coord1.coordSize))
return immap
# intercept the dump method and the adaptToRender to make sure the the coor2.coordSize is set.
# the assignment does the trick
@use_api
def dump(self, filename):
self.length = self.length
super(Image, self).dump(filename)
self.renderVRT()
@use_api
def adaptToRender(self):
self.length = self.length
'''
##
# Initialize the image instance from an xml file
def load(self,filename):
from iscesys.Parsers.FileParserFactory import createFileParser
parser = createFileParser('xml')
#get the properties from the file
prop, fac, misc = parser.parse(filename)
self.init(prop,fac,misc)
'''
@use_api
def renderHdr(self, outfile=None):
from datetime import datetime
from isceobj.XmlUtil import xmlUtils as xml
from isce import release_version, release_svn_revision, release_date, svn_revision
odProp = xml.OrderedDict()
odFact = xml.OrderedDict()
odMisc = xml.OrderedDict()
# hack since the length is normally not set but obtained from the file
# size, before rendering make sure that coord1.size is set to length
self.coord2.coordSize = self.length
self.renderToDictionary(self, odProp, odFact, odMisc)
# remove key,value pair with empty value (except if value is zero)
DU.cleanDictionary(odProp)
DU.cleanDictionary(odFact)
DU.cleanDictionary(odMisc)
odProp['ISCE_VERSION'] = "Release: %s, svn-%s, %s. Current: svn-%s." % \
(release_version, release_svn_revision, release_date, svn_revision)
outfile = outfile if outfile else self.getFilename() + '.xml'
firstTag = 'imageFile'
XD = XmlDumper()
XD.dump(outfile, odProp, odFact, odMisc, firstTag)
self.renderVRT()
return None
# This method renders an ENVI HDR file similar to the XML file.
def renderEnviHDR(self):
'''
Renders a bare minimum ENVI HDR file, that can be used to directly ingest the outputs into
a GIS package.
'''
typeMap = { 'BYTE' : 1,
'SHORT' : 2,
'INT' : 3,
'LONG' : 14,
'FLOAT' : 4,
'DOUBLE' : 5,
'CFLOAT' : 6,
'CDOUBLE': 9 }
orderMap = {'L' : 0,
'B' : 1}
tempstring = """ENVI
description = {{Data product generated using ISCE}}
samples = {0}
lines = {1}
bands = {2}
header offset = 0
file type = ENVI Standard
data type = {3}
interleave = {4}
byte order = {5}
"""
map_infostr = """coordinate system string = {{GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137, 298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.0174532925199433]]}}
map_info = {{Geographic Lat/Lon, 1.0, 1.0, {0}, {1}, {2}, {3}, WGS-84, units=Degrees}}"""
flag = False
try:
if (self.coord1.coordStart == 0.) and \
(self.coord2.coordStart == 0.) and \
(self.coord1.coordDelta == 1.) and \
(self.coord2.coordDelta == 1.):
flag = True
except:
pass
outfile = self.getFilename() + '.hdr'
outstr = tempstring.format(self.width, self.length,
self.bands, typeMap[self.dataType.upper()],
self.scheme.lower(),
orderMap[ENDIAN[self.byteOrder].upper()])
if not flag:
outstr += map_infostr.format(self.coord1.coordStart,
self.coord2.coordStart,
self.coord1.coordDelta,
-self.coord2.coordDelta)
with open(outfile, 'w') as f:
f.write(outstr)
return
# This method renders and ENVI HDR file similar to the XML file.
def renderVRT(self, outfile=None):
'''
Renders a bare minimum ENVI HDR file, that can be used to directly ingest the outputs into a GIS package.
'''
import xml.etree.ElementTree as ET
typeMap = { 'BYTE' : 'Byte',
'SHORT' : 'Int16',
'CIQBYTE': 'Int16',
'INT' : 'Int32',
'FLOAT' : 'Float32',
'DOUBLE' : 'Float64',
'CFLOAT' : 'CFloat32',
'CDOUBLE': 'CFloat64'}
sizeMap = {'BYTE' : 1,
'SHORT' : 2,
'CIQBYTE': 2,
'INT' : 4,
'FLOAT' : 4,
'DOUBLE': 8,
'CFLOAT' : 8,
'CDOUBLE' : 16}
orderMap = {'L' : 'LSB',
'B' : 'MSB'}
def indentXML(elem, depth=None, last=None):
if depth == None:
depth = [0]
if last == None:
last = False
tab = ' ' * 4
if(len(elem)):
depth[0] += 1
elem.text = '\n' + (depth[0]) * tab
lenEl = len(elem)
lastCp = False
for i in range(lenEl):
if(i == lenEl - 1):
lastCp = True
indentXML(elem[i], depth, lastCp)
if(not last):
elem.tail = '\n' + (depth[0]) * tab
else:
depth[0] -= 1
elem.tail = '\n' + (depth[0]) * tab
else:
if(not last):
elem.tail = '\n' + (depth[0]) * tab
else:
depth[0] -= 1
elem.tail = '\n' + (depth[0]) * tab
return
srs = "EPSG:4326"
flag = False
try:
if (self.coord1.coordStart == 0.) and \
(self.coord2.coordStart == 0.) and \
(self.coord1.coordDelta == 1.) and \
(self.coord2.coordDelta == 1.):
flag = True
except:
pass
if not outfile:
outfile = self.getFilename() + '.vrt'
root = ET.Element('VRTDataset')
root.attrib['rasterXSize'] = str(self.width)
root.attrib['rasterYSize'] = str(self.length)
if not flag:
print('Writing geotrans to VRT for {0}'.format(self.filename))
ET.SubElement(root, 'SRS').text = "EPSG:4326"
gtstr = "{0}, {1}, 0.0, {2}, 0.0, {3}".format(self.coord1.coordStart,
self.coord1.coordDelta,
self.coord2.coordStart,
self.coord2.coordDelta)
ET.SubElement(root, 'GeoTransform').text = gtstr
nbytes = sizeMap[self.dataType.upper()]
for band in range(self.bands):
broot = ET.Element('VRTRasterBand')
broot.attrib['dataType'] = typeMap[self.dataType.upper()]
broot.attrib['band'] = str(band + 1)
broot.attrib['subClass'] = "VRTRawRasterBand"
elem = ET.SubElement(broot, 'SourceFilename')
elem.attrib['relativeToVRT'] = "1"
elem.text = os.path.basename(self.getFilename())
ET.SubElement(broot, 'ByteOrder').text = orderMap[ENDIAN[self.byteOrder].upper()]
if self.scheme.upper() == 'BIL':
ET.SubElement(broot, 'ImageOffset').text = str(band * self.width * nbytes)
ET.SubElement(broot, 'PixelOffset').text = str(nbytes)
ET.SubElement(broot, 'LineOffset').text = str(self.bands * self.width * nbytes)
elif self.scheme.upper() == 'BIP':
ET.SubElement(broot, 'ImageOffset').text = str(band * nbytes)
ET.SubElement(broot, 'PixelOffset').text = str(self.bands * nbytes)
ET.SubElement(broot, 'LineOffset').text = str(self.bands * self.width * nbytes)
elif self.scheme.upper() == 'BSQ':
ET.SubElement(broot, 'ImageOffset').text = str(band * self.width * self.length * nbytes)
ET.SubElement(broot, 'PixelOffset').text = str(nbytes)
ET.SubElement(broot, 'LineOffset').text = str(self.width * nbytes)
root.append(broot)
indentXML(root)
tree = ET.ElementTree(root)
tree.write(outfile, encoding='unicode')
return
# #
# This method initialize the Image.
# @param filename \c string the file name associated with the image.
# @param accessmode \c string access mode of the file.
# @param bands \c int number of bands of the interleaving scheme.
# @param type \c string data type used to store the data.
# @param width \c int width of the image.
# @param scheme \c string interleaving scheme.
# @param caster \c string type of caster (ex. 'DoubleToFloat').
def initImage(self, filename, accessmode, width,
type=None, bands=None, scheme=None, caster=None):
self.initAccessor(filename, accessmode, width, type, bands, scheme, caster)
# # This method gets the pointer associated to the DataAccessor.DataAccessor
# # object created.
# @return \c pointer pointer to the underlying DataAccessor.DataAccessor
# # object.
def getImagePointer(self):
return self.getAccessor()
# # gets the string describing the image for the user
# #@return \c text description string describing the image in English for
# # the user
def getDescription(self):
return self.description
# # This method appends the string describing the image for the user create
# # a list.
# #@param doc \c text description string describing the image in English for
# # the user
def addDescription(self, doc):
if self.description == '':
self.description = [doc]
elif isinstance(self.description, list):
self.description.append(doc)
# # This method gets the length associated to the DataAccessor.DataAccessor
# # object created.
# # @return \c int length of the underlying DataAccessor.DataAccessor object.
@use_api
def getLength(self):
if not self.coord2.coordSize:
self.coord2.coordSize = self.getFileLength()
return self.coord2.coordSize
# Always call this function if createImage() was previously invoked.
# It deletes the pointer to the object, closes the file associated with
# the object, frees memory.
def finalizeImage(self):
if not self._isFinalized:
self.finalizeAccessor()
self._isFinalized = True
def setImageType(self, val):
self.imageType = str(val)
def setLength(self, val):
# needed because the __init__ calls self.lenth = None which calls this
# function and the casting would fail. with time possibly need to
# refactor all the image API with better inheritance
if val is not None:
self.coord2.coordSize = int(val)
def getWidth(self):
return self.coord1.coordSize
def setWidth(self, val):
# see getLength
if val is not None:
width = int(val)
self.coord1.coordSize = width
# self.width = width
# DataAccessor.setWidth(self, width)
def setXmin(self, val):
# see getLength
if not val is None:
xmin = val
self.coord1.coordStart = xmin
def getXmin(self):
return self.coord1.coordStart
def setXmax(self, val):
# see getLength
if not val is None:
xmax = val
self.coord1.coordEnd = xmax
def getXmax(self):
return self.coord1.coordEnd
def setByteOrder(self, byteOrder):
try:
b0 = ENDIAN[byteOrder]
except KeyError:
self.logger.error(
self.__class__.__name__ +
".setByteOorder got a bad argument:" +
str(byteOrder)
)
raise ValueError(str(byteOrder) +
" is not a valid byte ordering, e.g.\n" +
str(ENDIAN.keys()))
self.byteOrder = b0
return None
# # Set the caster type if needed
# @param accessMode \c string access mode of the file. Can be 'read' or 'write'
# @param dataType \c string is the dataType from or to the caster writes or reads.
def setCaster(self, accessMode, dataType):
self.accessMode = accessMode
if(accessMode == 'read'):
self.caster = CF.getCaster(self.dataType, dataType)
elif(accessMode == 'write'):
self.caster = CF.getCaster(dataType, self.dataType)
else:
print('Unrecorgnized access mode', accessMode)
raise ValueError
@property
def extraFilename(self):
return self._extraFilename
@extraFilename.setter
def extraFilename(self,val):
self._extraFilename = val
def setFirstLatitude(self, val):
self.coord2.coordStart = val
def setFirstLongitude(self, val):
self.coord1.coordStart = val
def setDeltaLatitude(self, val):
self.coord2.coordDelta = val
def setDeltaLongitude(self, val):
self.coord1.coordDelta = val
def getFirstLatitude(self):
return self.coord2.coordStart
def getFirstLongitude(self):
return self.coord1.coordStart
def getDeltaLatitude(self):
return self.coord2.coordDelta
def getDeltaLongitude(self):
return self.coord1.coordDelta
def getImageType(self):
return self.imageType
def getByteOrder(self):
return self.byteOrder
def getProduct(self):
return self.product
def setProduct(self, val):
self.product = val
'''
def _facilities(self):
self.coord1 = self.facility('coord1',public_name='Coordinate1',module='isceobj.Image',factory='createCoordinate',mandatory=True,doc='First coordinate of a 2D image (witdh).')
self.coord2 = self.facility('coord2',public_name='Coordinate2',module='isceobj.Image',factory='createCoordinate',mandatory=True,doc='Second coordinate of a 2D image (length).')
'''
firstLatitude = property(getFirstLatitude, setFirstLatitude)
firstLongitude = property(getFirstLongitude, setFirstLongitude)
deltaLatitude = property(getDeltaLatitude, setDeltaLatitude)
deltaLongitude = property(getDeltaLongitude, setDeltaLongitude)
width = property(getWidth, setWidth)
length = property(getLength, setLength)
xmin = property(getXmin, setXmin)
xmax = property(getXmax, setXmax)
pass
class ImageCoordinate(Configurable):
family = 'imagecoordinate'
def __init__(self, family='', name=''):
# # Call super with class name
Configurable.__init__(self, family if family else self.__class__.family, name=name)
self.coordDescription = ''
self._parameters()
return None
@property
def coordStart(self):
return self._coordStart
@coordStart.setter
def coordStart(self, val):
self._coordStart = val
@property
def coordEnd(self):
if self._coordEnd is None and self._coordSize is not None:
self._coordEnd = self._coordStart + self._coordSize * self._coordDelta
return self._coordEnd
@coordEnd.setter
def coordEnd(self, val):
self._coordEnd = val
@property
def coordSize(self):
return self._coordSize
@coordSize.setter
def coordSize(self, val):
self._coordSize = val
@property
def coordDelta(self):
return self._coordDelta
@coordDelta.setter
def coordDelta(self, val):
self._coordDelta = val
def _parameters(self):
self._coordStart = self.parameter('coordStart', public_name='startingValue', default=0, units='',
type=float, mandatory=False,
doc="Starting value of the coordinate.")
self._coordEnd = self.parameter('coordEnd', public_name='endingValue', default=None, units='',
type=float, mandatory=False,
doc="Starting value of the coordinate.")
self._coordDelta = self.parameter('coordDelta', public_name='delta', default=1, units='',
type=float, mandatory=False,
doc="Coordinate quantization.")
self._coordSize = self.parameter('coordSize', public_name='size', default=None,
type=int,
mandatory=False,
private=True,
doc="Coordinate size.")
pass

Some files were not shown because too many files have changed in this diff Show More