https://www.reproducibility.org/wiki2020/api.php?action=feedcontributions&user=Jenningsjwj&feedformat=atomMadagascar - User contributions [en]2024-03-29T15:45:50ZUser contributionsMediaWiki 1.34.0https://www.reproducibility.org/wiki2020/index.php?title=Houston_2010&diff=1269Houston 20102010-06-28T18:03:29Z<p>Jenningsjwj: add Jennings bio</p>
<hr />
<div>[[Image:PTTC.jpg|left|link=http://www.beg.utexas.edu/pttc/workshops.htm ]]<br />
<br />
[[Image:BEG.png|left|link=http://www.beg.utexas.edu/ ]]<br />
<br />
[[Image:Fotolia_3744441_XS.jpg|center]]<br />
<br />
&nbsp;<br />
<br />
<center><big>'''Madagascar School on Reproducible Computational Geophysics and Hands-On Workshop'''<br><br />
Sponsored by [http://www.beg.utexas.edu/pttc/workshops.htm PTTC Texas/SE New Mexico Region]</big></center><br />
<br />
&nbsp;<br />
<br />
==Program==<br />
<br />
{| align="center" border="1" cellpadding="5" cellspacing="0" <br />
! colspan="3" style="background:#ffdead;" | Day 1: Friday, July 23<br />
|-<br />
| 9:00-10:30<br />
! colspan="2" | Introduction (Sergey Fomel)<br />
|-<br />
|<br />
| colspan="2" | <br />
The Madagascar project has been in public existence for four years. Madagascar provides a complete environment for organizing one's research, from new software development to running computational experiments to publishing the experimental results in papers and reports, archiving them for future usage, and sharing them with colleagues and sponsors. The introductory presentation will describe the history of the project, the Madagascar components and design principles, and the future development goals. <br />
|-<br />
| 10:30-10:45<br />
! colspan="2" style="background:#efefef;" | break<br />
|-<br />
| 10:45-12:15<br />
! colspan="2" | Workflows in SCons and automatic testing (Jim Jennings)<br />
|-<br />
|<br />
| colspan="2" | <br />
The rich and well-documented Python syntax used in SConstruct files provides great flexibility when coding Madagascar SCons workflows. In the first part of this module a few geostatistical workflows will be presented to illustrate some useful techniques.<br />
<br />
Two important components of the Madagascar design goals are reproducibility and regression testing. In the second part of this module our progress towards these goals will be discussed and some of the built-in tools for automatic testing will be presented.<br />
|-<br />
|<br />
| colspan="2" |<br />
<br />
|-<br />
| 12:15-1:15<br />
! colspan="2" style="background:#efefef;" | Lunch<br />
|-<br />
| 1:15-2:45<br />
! colspan="2" | Seismic finite-difference modeling and migration example (Paul Sava)<br />
|-<br />
|<br />
| colspan="2" | <br />
The theoretical part of this module provides an overview of reverse-time imaging methodology applied to wavefield seismic data. The main technique discussed is reverse-time migration with emphasis on modern imaging conditions which enable migration velocity analysis and amplitude-versus-angle analysis. The applied part demonstrates this technique on a complex geologic model using Madagascar codes in a fully reproducible setup.<br />
|-<br />
| 2:45-3:00<br />
! colspan="2" style="background:#efefef;" | break<br />
|-<br />
| 3:00-4:30<br />
! colspan="2" | Discussion<br />
|-<br />
|<br />
| colspan="2" |<br />
Open Q&A session and discussions on the future development of Madagascar<br />
|-<br />
| 5:30-8:00<br />
! colspan="2" style="background:#ccff99;" | Dinner and Madagascar 1.0 celebration<br />
|-<br />
|}<br />
<br />
&nbsp;<br />
<br />
{| align="center" border="1" cellpadding="5" cellspacing="0" <br />
! colspan="3" style="background:#ffdead;" | Day 2: Saturday, July 24<br />
|-<br />
| 9:00-10:30<br />
! colspan="2" | Programming with Madagascar (Tariq Alkhalifah)<br />
|-<br />
|<br />
| colspan="2" | <br />
<br />
|-<br />
| 10:30-10:45<br />
! colspan="2" style="background:#efefef;" | break<br />
|-<br />
| 10:45-11:15<br />
! colspan="2" | Vplot graphics language - past, present, and future (Joe Dellinger)<br />
|-<br />
|<br />
| colspan="2" |<br />
<br />
<br />
|-<br />
| 11:15-12:15<br />
! colspan="2" | Plotting and high-performance computing with Madagascar (Vladimir Bashkardin)<br />
|-<br />
|<br />
| colspan="2" |<br />
<br />
|-<br />
| 12:15-1:15<br />
! colspan="2" style="background:#efefef;" | Lunch<br />
|-<br />
| 1:15-2:45<br />
! colspan="2" | Seismic field data processing example (Ioan Vlad)<br />
|-<br />
|<br />
| colspan="2" | <br />
<br />
|-<br />
| 2:45-3:00<br />
! colspan="2" style="background:#efefef;" | break<br />
|-<br />
| 3:00-4:30<br />
! colspan="2" | Discussion<br />
|-<br />
|<br />
| colspan="2" |<br />
Open Q&A session and discussions on the future development of Madagascar<br />
|-<br />
|}<br />
<br />
== Location ==<br />
<br />
[[Image:HRC.png|right]]<br />
<br />
The University of Texas at Austin<br><br />
Bureau of Economic Geology<br><br />
[http://www.beg.utexas.edu/info/hrc_facil.php Houston Research Center]<br />
<br />
'''Address'''<br />
* 11611 West Little York Rd<br />
* Houston, Texas 77041, USA<br />
* [http://www.beg.utexas.edu/info/pdf/Directions_to_HRC.pdf Driving directions]<br />
<br />
<br clear=all/><br />
<br />
== Registration ==<br />
<br />
Register by filling the [http://www.beg.utexas.edu/pttc/madagascar.php Registration Form].<br />
<br />
The registration cost is $300 and includes morning refreshments, lunch, Friday dinner, and instructor handouts. <br />
<br />
The registration is '''<font color="red">free for graduate students</font>'''. If you are a graduate student, please e-mail<br />
[mailto:pttc@beg.utexas.edu pttc@beg.utexas.edu] to obtain a discount code.<br />
<br />
== Speaker biographies ==<br />
<br />
* '''Tariq Alkhalifah''' https://sites.google.com/a/kaust.edu.sa/tariq/ <br />
* '''Vladimir Bashkardin''' is currently a PhD student in geophysics at The University of Texas at Austin. Before joining the research group of Dr. Sergey Fomel at UT Austin, he worked as a software engineer for Paradigm (former Paradigm Geophysical) with specialization in seismic data visualization and interpretation. He also was a part-time lecturer at Gubkin Oil and Gas University (Moscow, Russia), an industry-oriented school from which he holds a degree in exploration geophysics.<br />
* '''Joe Dellinger''' graduated with a PhD in Geophysics from the Stanford Exploration Project in 1991 and currently works for BP in Houston, specializing in anisotropy and multicomponent seismology. Joe has often provided advice to the SEG (much of it unsolicited) on how they should best advance into the brave new online/digital world, for which he was awarded Life Membership in 2001. Joe currently is the editor of the Software and Algorithms section of GEOPHYSICS, and maintains the accompanying software and data website. http://software.seg.org<br />
* '''Sergey Fomel''' has been working at the Bureau of Economic Geology at the University of Texas at Austin since 2002 and currently has an Associate Professor appointment, jointly with the Department of Geological Sciences. He received a Ph.D. in Geophysics from Stanford University in 2001 and worked previously at the Institute of Geophysics in Novosibirsk, Russia, and the Lawrence Berkeley National Laboratory. Sergey started work on Madagascar (at that time named RSF for Regularly Sampled Format) in 2003. http://www.beg.utexas.edu/fomel/<br />
* '''Jim Jennings''' currently works for Shell International Exploration and Production in Houston Texas as a company consultant on carbonate reservoir modeling, but he contributes to Madagascar as a hobby and will be participating in the workshop on his own time. Before joining Shell in 2007 he worked for 23 years at the Bureau of Economic Geology, Arco, and BP. Jim has a PhD in Petroleum Engineering from Texas A&M University (1983), was chairman for an SPE reprint volume on Advances in Reservoir Characterization (2006), and was a Distinguished Lecturer for the AAPG (2008-2009). http://www.aapg.org/education/dist_lect/jennings.cfm<br />
* '''Paul Sava''' http://newton.mines.edu/paul/home.php<br />
* '''Ioan "Nick" Vlad'''</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Houston_2010&diff=1265Houston 20102010-06-26T14:12:39Z<p>Jenningsjwj: remove Shell association from Jennings</p>
<hr />
<div>[[Image:PTTC.jpg|left|link=http://www.beg.utexas.edu/pttc/workshops.htm ]]<br />
<br />
[[Image:BEG.png|left|link=http://www.beg.utexas.edu/ ]]<br />
<br />
[[Image:Fotolia_3744441_XS.jpg|center]]<br />
<br />
&nbsp;<br />
<br />
<center><big>'''Madagascar School on Reproducible Computational Geophysics and Hands-On Workshop'''<br><br />
Sponsored by [http://www.beg.utexas.edu/pttc/workshops.htm PTTC Texas/SE New Mexico Region]</big></center><br />
<br />
&nbsp;<br />
<br />
==Program==<br />
<br />
{| align="center" border="1" cellpadding="5" cellspacing="0" <br />
! colspan="3" style="background:#ffdead;" | Day 1: Friday, July 23<br />
|-<br />
| 9:00-10:30<br />
! colspan="2" | Introduction (Sergey Fomel)<br />
|-<br />
|<br />
| colspan="2" | <br />
The Madagascar project has been in public existence for four years. Madagascar provides a complete environment for organizing one's research, from new software development to running computational experiments to publishing the experimental results in papers and reports, archiving them for future usage, and sharing them with colleagues and sponsors. The introductory presentation will describe the history of the project, the Madagascar components and design principles, and the future development goals. <br />
|-<br />
| 10:30-10:45<br />
! colspan="2" style="background:#efefef;" | break<br />
|-<br />
| 10:45-12:15<br />
! colspan="2" | Workflows in SCons and automatic testing (Jim Jennings)<br />
|-<br />
|<br />
| colspan="2" | <br />
The rich and well-documented Python syntax used in SConstruct files provides great flexibility when coding Madagascar SCons workflows. In the first part of this module a few geostatistical workflows will be presented to illustrate some useful techniques.<br />
<br />
Two important components of the Madagascar design goals are reproducibility and regression testing. In the second part of this module our progress towards these goals will be discussed and some of the built-in tools for automatic testing will be presented.<br />
|-<br />
|<br />
| colspan="2" |<br />
<br />
|-<br />
| 12:15-1:15<br />
! colspan="2" style="background:#efefef;" | Lunch<br />
|-<br />
| 1:15-2:45<br />
! colspan="2" | Seismic finite-difference modeling and migration example (Paul Sava)<br />
|-<br />
|<br />
| colspan="2" | <br />
The theoretical part of this module provides an overview of reverse-time imaging methodology applied to wavefield seismic data. The main technique discussed is reverse-time migration with emphasis on modern imaging conditions which enable migration velocity analysis and amplitude-versus-angle analysis. The applied part demonstrates this technique on a complex geologic model using Madagascar codes in a fully reproducible setup.<br />
|-<br />
| 2:45-3:00<br />
! colspan="2" style="background:#efefef;" | break<br />
|-<br />
| 3:00-4:30<br />
! colspan="2" | Discussion<br />
|-<br />
|<br />
| colspan="2" |<br />
Open Q&A session and discussions on the future development of Madagascar<br />
|-<br />
| 5:30-8:00<br />
! colspan="2" style="background:#ccff99;" | Dinner and Madagascar 1.0 celebration<br />
|-<br />
|}<br />
<br />
&nbsp;<br />
<br />
{| align="center" border="1" cellpadding="5" cellspacing="0" <br />
! colspan="3" style="background:#ffdead;" | Day 2: Saturday, July 24<br />
|-<br />
| 9:00-10:30<br />
! colspan="2" | Programming with Madagascar (Tariq Alkhalifah)<br />
|-<br />
|<br />
| colspan="2" | <br />
<br />
|-<br />
| 10:30-10:45<br />
! colspan="2" style="background:#efefef;" | break<br />
|-<br />
| 10:45-11:15<br />
! colspan="2" | Vplot graphics language - past, present, and future (Joe Dellinger)<br />
|-<br />
|<br />
| colspan="2" |<br />
<br />
<br />
|-<br />
| 11:15-12:15<br />
! colspan="2" | Plotting and high-performance computing with Madagascar (Vladimir Bashkardin)<br />
|-<br />
|<br />
| colspan="2" |<br />
<br />
|-<br />
| 12:15-1:15<br />
! colspan="2" style="background:#efefef;" | Lunch<br />
|-<br />
| 1:15-2:45<br />
! colspan="2" | Seismic field data processing example (Ioan Vlad)<br />
|-<br />
|<br />
| colspan="2" | <br />
<br />
|-<br />
| 2:45-3:00<br />
! colspan="2" style="background:#efefef;" | break<br />
|-<br />
| 3:00-4:30<br />
! colspan="2" | Discussion<br />
|-<br />
|<br />
| colspan="2" |<br />
Open Q&A session and discussions on the future development of Madagascar<br />
|-<br />
|}<br />
<br />
== Location ==<br />
<br />
[[Image:HRC.png|right]]<br />
<br />
The University of Texas at Austin<br><br />
Bureau of Economic Geology<br><br />
[http://www.beg.utexas.edu/info/hrc_facil.php Houston Research Center]<br />
<br />
'''Address'''<br />
* 11611 West Little York Rd<br />
* Houston, Texas 77041, USA<br />
* [http://www.beg.utexas.edu/info/pdf/Directions_to_HRC.pdf Driving directions]<br />
<br />
<br clear=all/><br />
<br />
== Registration ==<br />
<br />
Register by filling the [http://www.beg.utexas.edu/pttc/madagascar.php Registration Form].<br />
<br />
The registration cost is $300 and includes morning refreshments, lunch, Friday dinner, and instructor handouts. <br />
<br />
The registration is '''<font color="red">free for graduate students</font>'''. If you are a graduate student, please e-mail<br />
[mailto:pttc@beg.utexas.edu pttc@beg.utexas.edu] to obtain a discount code.<br />
<br />
== Instructors ==<br />
<br />
* [https://sites.google.com/a/kaust.edu.sa/tariq/ Tariq Alkhalifah] (KAUST)<br />
* Vladimir Bashkardin (University of Texas at Austin)<br />
* Joseph Dellinger (BP)<br />
* [http://www.beg.utexas.edu/fomel/ Sergey Fomel] (University of Texas at Austin)<br />
* [http://www.aapg.org/education/dist_lect/jennings.cfm Jim Jennings]<br />
* [http://newton.mines.edu/paul/home.php Paul Sava] (Colorado School of Mines)<br />
* Ioan Vlad (Statoil)</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Houston_2010&diff=1264Houston 20102010-06-26T14:10:06Z<p>Jenningsjwj: add text for Jennings presentation</p>
<hr />
<div>[[Image:PTTC.jpg|left|link=http://www.beg.utexas.edu/pttc/workshops.htm ]]<br />
<br />
[[Image:BEG.png|left|link=http://www.beg.utexas.edu/ ]]<br />
<br />
[[Image:Fotolia_3744441_XS.jpg|center]]<br />
<br />
&nbsp;<br />
<br />
<center><big>'''Madagascar School on Reproducible Computational Geophysics and Hands-On Workshop'''<br><br />
Sponsored by [http://www.beg.utexas.edu/pttc/workshops.htm PTTC Texas/SE New Mexico Region]</big></center><br />
<br />
&nbsp;<br />
<br />
==Program==<br />
<br />
{| align="center" border="1" cellpadding="5" cellspacing="0" <br />
! colspan="3" style="background:#ffdead;" | Day 1: Friday, July 23<br />
|-<br />
| 9:00-10:30<br />
! colspan="2" | Introduction (Sergey Fomel)<br />
|-<br />
|<br />
| colspan="2" | <br />
The Madagascar project has been in public existence for four years. Madagascar provides a complete environment for organizing one's research, from new software development to running computational experiments to publishing the experimental results in papers and reports, archiving them for future usage, and sharing them with colleagues and sponsors. The introductory presentation will describe the history of the project, the Madagascar components and design principles, and the future development goals. <br />
|-<br />
| 10:30-10:45<br />
! colspan="2" style="background:#efefef;" | break<br />
|-<br />
| 10:45-12:15<br />
! colspan="2" | Workflows in SCons and automatic testing (Jim Jennings)<br />
|-<br />
|<br />
| colspan="2" | <br />
The rich and well-documented Python syntax used in SConstruct files provides great flexibility when coding Madagascar SCons workflows. In the first part of this module a few geostatistical workflows will be presented to illustrate some useful techniques.<br />
<br />
Two important components of the Madagascar design goals are reproducibility and regression testing. In the second part of this module our progress towards these goals will be discussed and some of the built-in tools for automatic testing will be presented.<br />
|-<br />
|<br />
| colspan="2" |<br />
<br />
|-<br />
| 12:15-1:15<br />
! colspan="2" style="background:#efefef;" | Lunch<br />
|-<br />
| 1:15-2:45<br />
! colspan="2" | Seismic finite-difference modeling and migration example (Paul Sava)<br />
|-<br />
|<br />
| colspan="2" | <br />
The theoretical part of this module provides an overview of reverse-time imaging methodology applied to wavefield seismic data. The main technique discussed is reverse-time migration with emphasis on modern imaging conditions which enable migration velocity analysis and amplitude-versus-angle analysis. The applied part demonstrates this technique on a complex geologic model using Madagascar codes in a fully reproducible setup.<br />
|-<br />
| 2:45-3:00<br />
! colspan="2" style="background:#efefef;" | break<br />
|-<br />
| 3:00-4:30<br />
! colspan="2" | Discussion<br />
|-<br />
|<br />
| colspan="2" |<br />
Open Q&A session and discussions on the future development of Madagascar<br />
|-<br />
| 5:30-8:00<br />
! colspan="2" style="background:#ccff99;" | Dinner and Madagascar 1.0 celebration<br />
|-<br />
|}<br />
<br />
&nbsp;<br />
<br />
{| align="center" border="1" cellpadding="5" cellspacing="0" <br />
! colspan="3" style="background:#ffdead;" | Day 2: Saturday, July 24<br />
|-<br />
| 9:00-10:30<br />
! colspan="2" | Programming with Madagascar (Tariq Alkhalifah)<br />
|-<br />
|<br />
| colspan="2" | <br />
<br />
|-<br />
| 10:30-10:45<br />
! colspan="2" style="background:#efefef;" | break<br />
|-<br />
| 10:45-11:15<br />
! colspan="2" | Vplot graphics language - past, present, and future (Joe Dellinger)<br />
|-<br />
|<br />
| colspan="2" |<br />
<br />
<br />
|-<br />
| 11:15-12:15<br />
! colspan="2" | Plotting and high-performance computing with Madagascar (Vladimir Bashkardin)<br />
|-<br />
|<br />
| colspan="2" |<br />
<br />
|-<br />
| 12:15-1:15<br />
! colspan="2" style="background:#efefef;" | Lunch<br />
|-<br />
| 1:15-2:45<br />
! colspan="2" | Seismic field data processing example (Ioan Vlad)<br />
|-<br />
|<br />
| colspan="2" | <br />
<br />
|-<br />
| 2:45-3:00<br />
! colspan="2" style="background:#efefef;" | break<br />
|-<br />
| 3:00-4:30<br />
! colspan="2" | Discussion<br />
|-<br />
|<br />
| colspan="2" |<br />
Open Q&A session and discussions on the future development of Madagascar<br />
|-<br />
|}<br />
<br />
== Location ==<br />
<br />
[[Image:HRC.png|right]]<br />
<br />
The University of Texas at Austin<br><br />
Bureau of Economic Geology<br><br />
[http://www.beg.utexas.edu/info/hrc_facil.php Houston Research Center]<br />
<br />
'''Address'''<br />
* 11611 West Little York Rd<br />
* Houston, Texas 77041, USA<br />
* [http://www.beg.utexas.edu/info/pdf/Directions_to_HRC.pdf Driving directions]<br />
<br />
<br clear=all/><br />
<br />
== Registration ==<br />
<br />
Register by filling the [http://www.beg.utexas.edu/pttc/madagascar.php Registration Form].<br />
<br />
The registration cost is $300 and includes morning refreshments, lunch, Friday dinner, and instructor handouts. <br />
<br />
The registration is '''<font color="red">free for graduate students</font>'''. If you are a graduate student, please e-mail<br />
[mailto:pttc@beg.utexas.edu pttc@beg.utexas.edu] to obtain a discount code.<br />
<br />
== Instructors ==<br />
<br />
* [https://sites.google.com/a/kaust.edu.sa/tariq/ Tariq Alkhalifah] (KAUST)<br />
* Vladimir Bashkardin (University of Texas at Austin)<br />
* Joseph Dellinger (BP)<br />
* [http://www.beg.utexas.edu/fomel/ Sergey Fomel] (University of Texas at Austin)<br />
* [http://www.aapg.org/education/dist_lect/jennings.cfm Jim Jennings] (Shell)<br />
* [http://newton.mines.edu/paul/home.php Paul Sava] (Colorado School of Mines)<br />
* Ioan Vlad (Statoil)</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Automatic_Testing&diff=1201Automatic Testing2010-06-19T18:57:26Z<p>Jenningsjwj: /* Quick Test */</p>
<hr />
<div>==Quick Test==<br />
<br />
To run a "quick" test run this command from <tt>$RSFSRC</tt>:<br />
<br />
<bash>admin/quick_test.csh</bash><br />
<br />
This script currently (June 19, 2010) runs a set of 147 examples in <tt>$RSFSRC/book</tt> that make 4GB of total data. They run in about 2 minutes total on a 2.4 GHz Intel Core 2 Duo MacBook when nothing needs to be updated, and 15 minutes when everything is rebuilt from scratch. Your mileage will vary.<br />
<br />
Seven of the 147 examples do not pass all the tests on my system, perhaps because of bugs not yet found :-( These examples are:<br />
<br />
# book/gee/mda/levint<br />
# book/jsg/lpf/lpf<br />
# book/sep/bspl/plane3<br />
# book/sep/pwd/alias<br />
# book/sep/pwd/hole<br />
# book/sep/pwd/signoi<br />
# book/sep/stack/miginv<br />
<br />
Your mileage will probably vary on this as well. Indeed, I will be curious to see how the tests work on your system (hint, hint :-) Post your testing report on rsf-devel.<br />
<br />
==Testing Scripts==<br />
<br />
The following commands use [http://www.ahay.org/RSF/sfbooklist.html sfbooklist] and [http://www.ahay.org/RSF/sffiglist.html sffiglist]. Run them from <tt>$RSFSRC</tt>.<br />
<br />
# List all the examples in <tt>book</tt> that use <tt><program></tt><pre>sfbooklist uses=<program> list=filter book</pre><br />
# rebuild all the examples in <tt>book</tt> that use <tt><program></tt><pre>sfbooklist uses=<program> list=filter command=scons book</pre><br />
# Compare the newly generated figs with the corresponding reference figs stored in <tt>$RSFFIGS</tt> (defaulted to <tt>$RSFROOT/share/figs</tt>)<pre>sfbooklist uses=<program> list=filter command="sffiglist rsftest=y list=none" book</pre><br />
# Display any figs that are different from their <tt>$RSFFIGS</tt> counterparts<pre>sfbooklist uses=<program> list=filter command="sffiglist rsftest=y list=none show=diff" book</pre></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Automatic_Testing&diff=1200Automatic Testing2010-06-19T18:44:09Z<p>Jenningsjwj: </p>
<hr />
<div>==Quick Test==<br />
<br />
To run a "quick" test run this command from <tt>$RSFSRC</tt>:<br />
<br />
<bash>admin/quick_test.csh</bash><br />
<br />
This script currently (June 19, 2010) runs a set of 147 examples make 4GB of total data. They run in about 2 minutes total on a 2.4 GHz Intel Core 2 Duo MacBook when nothing needs to be updated, and 15 minutes when everything is rebuilt from scratch. Your mileage will vary.<br />
<br />
Seven of the 147 examples do not pass all the tests on my system, perhaps because of bugs not yet found :-( These examples are:<br />
<br />
# book/gee/mda/levint<br />
# book/jsg/lpf/lpf<br />
# book/sep/bspl/plane3<br />
# book/sep/pwd/alias<br />
# book/sep/pwd/hole<br />
# book/sep/pwd/signoi<br />
# book/sep/stack/miginv<br />
<br />
Your mileage will probably vary on this as well. Indeed, I will be curious to see how the tests work on your system (hint, hint :-) Post your testing report on rsf-devel.<br />
<br />
==Testing Scripts==<br />
<br />
The following commands use [http://www.ahay.org/RSF/sfbooklist.html sfbooklist] and [http://www.ahay.org/RSF/sffiglist.html sffiglist]. Run them from <tt>$RSFSRC</tt>.<br />
<br />
# List all the examples in <tt>book</tt> that use <tt><program></tt><pre>sfbooklist uses=<program> list=filter book</pre><br />
# rebuild all the examples in <tt>book</tt> that use <tt><program></tt><pre>sfbooklist uses=<program> list=filter command=scons book</pre><br />
# Compare the newly generated figs with the corresponding reference figs stored in <tt>$RSFFIGS</tt> (defaulted to <tt>$RSFROOT/share/figs</tt>)<pre>sfbooklist uses=<program> list=filter command="sffiglist rsftest=y list=none" book</pre><br />
# Display any figs that are different from their <tt>$RSFFIGS</tt> counterparts<pre>sfbooklist uses=<program> list=filter command="sffiglist rsftest=y list=none show=diff" book</pre></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Automatic_Testing&diff=1199Automatic Testing2010-06-19T18:42:23Z<p>Jenningsjwj: /* Quick Test */</p>
<hr />
<div>==Quick Test==<br />
<br />
To run a "quick" test run this command from <tt>$RSFSRC</tt>:<br />
<br />
<bash>admin/quick_test.csh</bash><br />
<br />
This script currently (June 19, 2010) runs a set of 147 examples make 4GB of total data. They run in about 2 minutes total on a 2.4 GHz Intel Core 2 Duo MacBook when nothing needs to be updated, and 15 minutes when everything is rebuilt from scratch. Your mileage will vary.<br />
<br />
Seven of the 147 examples do not pass all the tests on my system, perhaps because of bugs not yet found :-( These examples are:<br />
<br />
book/gee/mda/levint<br />
book/jsg/lpf/lpf<br />
book/sep/bspl/plane3<br />
book/sep/pwd/alias<br />
book/sep/pwd/hole<br />
book/sep/pwd/signoi<br />
book/sep/stack/miginv<br />
<br />
Your mileage will probably vary on this as well. Indeed, I will be curious to see how the tests work on your system (hint, hint :-) Post your testing report on rsf-devel.<br />
<br />
==Testing Scripts==<br />
<br />
The following commands use [http://www.ahay.org/RSF/sfbooklist.html sfbooklist] and [http://www.ahay.org/RSF/sffiglist.html sffiglist]. Run them from <tt>$RSFSRC</tt>.<br />
<br />
# List all the examples in <tt>book</tt> that use <tt><program></tt><pre>sfbooklist uses=<program> list=filter book</pre><br />
# rebuild all the examples in <tt>book</tt> that use <tt><program></tt><pre>sfbooklist uses=<program> list=filter command=scons book</pre><br />
# Compare the newly generated figs with the corresponding reference figs stored in <tt>$RSFFIGS</tt> (defaulted to <tt>$RSFROOT/share/figs</tt>)<pre>sfbooklist uses=<program> list=filter command="sffiglist rsftest=y list=none" book</pre><br />
# Display any figs that are different from their <tt>$RSFFIGS</tt> counterparts<pre>sfbooklist uses=<program> list=filter command="sffiglist rsftest=y list=none show=diff" book</pre></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Automatic_Testing&diff=1198Automatic Testing2010-06-19T18:39:12Z<p>Jenningsjwj: </p>
<hr />
<div>==Quick Test==<br />
<br />
To run a "quick" test run this command from <tt>$RSFSRC</tt>:<br />
<br />
<bash>admin/quick_test.csh</bash><br />
<br />
The set of 147 examples make 4GB of total data. They run in about 2 minutes total on my system when nothing needs to be updated, and 15 minutes when everything is rebuilt from scratch. Your mileage will vary.<br />
<br />
Seven of the 147 examples do not pass all the tests on my system, perhaps because of bugs not yet found :-( These examples are:<br />
<br />
book/gee/mda/levint<br />
book/jsg/lpf/lpf<br />
book/sep/bspl/plane3<br />
book/sep/pwd/alias<br />
book/sep/pwd/hole<br />
book/sep/pwd/signoi<br />
book/sep/stack/miginv<br />
<br />
Your mileage will probably vary on this as well. Indeed, I will be curious to see how the tests work on your system (hint, hint :-)<br />
<br />
<br />
==Testing Scripts==<br />
<br />
The following commands use [http://www.ahay.org/RSF/sfbooklist.html sfbooklist] and [http://www.ahay.org/RSF/sffiglist.html sffiglist]. Run them from <tt>$RSFSRC</tt>.<br />
<br />
# List all the examples in <tt>book</tt> that use <tt><program></tt><pre>sfbooklist uses=<program> list=filter book</pre><br />
# rebuild all the examples in <tt>book</tt> that use <tt><program></tt><pre>sfbooklist uses=<program> list=filter command=scons book</pre><br />
# Compare the newly generated figs with the corresponding reference figs stored in <tt>$RSFFIGS</tt> (defaulted to <tt>$RSFROOT/share/figs</tt>)<pre>sfbooklist uses=<program> list=filter command="sffiglist rsftest=y list=none" book</pre><br />
# Display any figs that are different from their <tt>$RSFFIGS</tt> counterparts<pre>sfbooklist uses=<program> list=filter command="sffiglist rsftest=y list=none show=diff" book</pre></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Automatic_Testing&diff=1197Automatic Testing2010-06-19T18:36:14Z<p>Jenningsjwj: /* Testing Scripts */</p>
<hr />
<div>==Quick Test==<br />
<br />
==Testing Scripts==<br />
<br />
The following commands use [http://www.ahay.org/RSF/sfbooklist.html sfbooklist] and [http://www.ahay.org/RSF/sffiglist.html sffiglist]. Run them from <tt>$RSFSRC</tt>.<br />
<br />
# List all the examples in <tt>book</tt> that use <tt><program></tt><pre>sfbooklist uses=<program> list=filter book</pre><br />
# rebuild all the examples in <tt>book</tt> that use <tt><program></tt><pre>sfbooklist uses=<program> list=filter command=scons book</pre><br />
# Compare the newly generated figs with the corresponding reference figs stored in <tt>$RSFFIGS</tt> (defaulted to <tt>$RSFROOT/share/figs</tt>)<pre>sfbooklist uses=<program> list=filter command="sffiglist rsftest=y list=none" book</pre><br />
# Display any figs that are different from their <tt>$RSFFIGS</tt> counterparts<pre>sfbooklist uses=<program> list=filter command="sffiglist rsftest=y list=none show=diff" book</pre></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Automatic_Testing&diff=1196Automatic Testing2010-06-19T18:35:12Z<p>Jenningsjwj: </p>
<hr />
<div>==Quick Test==<br />
<br />
==Testing Scripts==<br />
<br />
The following commands use [http://www.ahay.org/RSF/sfbooklist.html sfbooklist] and [http://www.ahay.org/RSF/sffiglist.html sffiglist]. Run them from <tt>$RSFSRC</tt>.<br />
<br />
# List all the examples in <tt>book</tt> that use <tt><program></tt><pre>sfbooklist uses=<program> list=filter book</pre><br />
# rebuild all the examples in <tt>book</tt> that use <tt><program></tt><pre>sfbooklist uses=<program> list=filter command=scons book</pre><br />
# Compare the newly generated figs with the corresponding reference figs stored in <tt>$RSFFIGS</tt> (defaulted to <tt>$RSFROOT/share/figs</tt>)<pre> sfbooklist uses=<program> list=filter command="sffiglist rsftest=y list=none" book</pre><br />
# Display any figs that are different from their <tt>$RSFFIGS</tt> counterparts<pre>sfbooklist uses=<program> list=filter command="sffiglist rsftest=y list=none show=diff" book</pre></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1195Advanced Installation2010-06-19T02:41:41Z<p>Jenningsjwj: /* Keeping locked figures separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<bash><br />
ln -s path_to_my_programs $RSFSRC/user/my_programs<br />
</bash><br />
The additional instructions above for "multi-user installs" are for the case where the other users do not have write access to RSFSRC. However, if you have full write access and only want to keep the programs in a separate place the link is the only thing you need.<br />
<br />
==Keeping recipes separate==<br />
Computational recipes written in Python and imported by the SConstruct file of a workflow are normally stored in RSFSRC/book/Recipes. The install process copies these recipes to a directory like $RSFROOT/lib/python2.5/site-packages/rsf/recipes and adds this directory to your PYTHONPATH so that Python can find them.<br />
<br />
However, you can put you own recipes anywhere you want. You only have to add that place to your PYTHONPATH like this (bash):<br />
<bash><br />
export PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
Or like this (csh):<br />
<bash><br />
setenv PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
<br />
==Keeping examples separate==<br />
Madagascar's public collection of example workflows are stored in RSFSRC/book, but you can put your private workflows anywhere you want. No special instructions are required.<br />
<br />
However, Madagascar assumes that the workflows are organized into a three-level book/chapter/section directory hierarchy when it creates a directory tree for the data and locked figures associated with your workflow. It is not required, but it might be easier to find the data and locked figures if you put your workflows in a three-level directory tree something like this: path_to_my_book/chapter/section/SConstruct.<br />
<br />
==Keeping data separate==<br />
The location of the data portion of your *.rsf files is controlled by your DATAPATH environment variable. However, you may want to keep the data for your private workflows in a different place, or several different places, than the data created by the public examples in RSFSRC/book. The way to do that is to temporarily change the DATAPATH variable in the SConstruct ''before'' importing rsf.proj like this:<br />
<python><br />
import os<br />
os.environ['DATAPATH'] = 'path_to_my_private_data'<br />
<br />
from rsf.proj import *<br />
</python><br />
<br />
==Keeping locked figures separate==<br />
The command "scons lock" in the directory of a workflow will store a "locked" copy of your figures for regression testing. Normally these figures are stored in the location pointed to by your RSFFIGS variable, and that is where the figures from the figures repository should be stored for testing in RSFSRC/book.<br />
<br />
However, you may want to keep your private figures in a different place. The way to do that is to temporarily change the RSFFIGS variable in the SConstruct ''before'' importing rsf.proj like this:<br />
<python><br />
import os<br />
os.environ['RSFFIGS'] = 'path_to_my_private_figures'<br />
<br />
from rsf.proj import *<br />
</python><br />
If you also create a RSFALTFIGS environment variable pointing to path_to_my_private_figures, then the testing script sffiglist will automatically test your figures against those in RSFALTFIGS when the sffiglist command is executed from a location outside of RSFSRC/book.<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1194Advanced Installation2010-06-19T02:38:10Z<p>Jenningsjwj: /* Keeping locked figures separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<bash><br />
ln -s path_to_my_programs $RSFSRC/user/my_programs<br />
</bash><br />
The additional instructions above for "multi-user installs" are for the case where the other users do not have write access to RSFSRC. However, if you have full write access and only want to keep the programs in a separate place the link is the only thing you need.<br />
<br />
==Keeping recipes separate==<br />
Computational recipes written in Python and imported by the SConstruct file of a workflow are normally stored in RSFSRC/book/Recipes. The install process copies these recipes to a directory like $RSFROOT/lib/python2.5/site-packages/rsf/recipes and adds this directory to your PYTHONPATH so that Python can find them.<br />
<br />
However, you can put you own recipes anywhere you want. You only have to add that place to your PYTHONPATH like this (bash):<br />
<bash><br />
export PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
Or like this (csh):<br />
<bash><br />
setenv PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
<br />
==Keeping examples separate==<br />
Madagascar's public collection of example workflows are stored in RSFSRC/book, but you can put your private workflows anywhere you want. No special instructions are required.<br />
<br />
However, Madagascar assumes that the workflows are organized into a three-level book/chapter/section directory hierarchy when it creates a directory tree for the data and locked figures associated with your workflow. It is not required, but it might be easier to find the data and locked figures if you put your workflows in a three-level directory tree something like this: path_to_my_book/chapter/section/SConstruct.<br />
<br />
==Keeping data separate==<br />
The location of the data portion of your *.rsf files is controlled by your DATAPATH environment variable. However, you may want to keep the data for your private workflows in a different place, or several different places, than the data created by the public examples in RSFSRC/book. The way to do that is to temporarily change the DATAPATH variable in the SConstruct ''before'' importing rsf.proj like this:<br />
<python><br />
import os<br />
os.environ['DATAPATH'] = 'path_to_my_private_data'<br />
<br />
from rsf.proj import *<br />
</python><br />
<br />
==Keeping locked figures separate==<br />
The command "scons lock" in the directory of a workflow will store a "locked" copy of your figures for regression testing. Normally these figures are stored in the location pointed to by your RSFFIGS variable, and that is where the figures from the figures repository should be stored for testing in RSFSRC/book.<br />
<br />
However, you may want to keep your private figures in a different place. The way to do that is to temporarily change the RSFFIGS variable in the SConstruct ''before'' importing rsf.proj like this:<br />
<python><br />
import os<br />
os.environ['RSFFIGS'] = 'path_to_my_private_figures'<br />
<br />
from rsf.proj import *<br />
</python><br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1193Advanced Installation2010-06-19T02:35:12Z<p>Jenningsjwj: /* Keeping locked figures separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<bash><br />
ln -s path_to_my_programs $RSFSRC/user/my_programs<br />
</bash><br />
The additional instructions above for "multi-user installs" are for the case where the other users do not have write access to RSFSRC. However, if you have full write access and only want to keep the programs in a separate place the link is the only thing you need.<br />
<br />
==Keeping recipes separate==<br />
Computational recipes written in Python and imported by the SConstruct file of a workflow are normally stored in RSFSRC/book/Recipes. The install process copies these recipes to a directory like $RSFROOT/lib/python2.5/site-packages/rsf/recipes and adds this directory to your PYTHONPATH so that Python can find them.<br />
<br />
However, you can put you own recipes anywhere you want. You only have to add that place to your PYTHONPATH like this (bash):<br />
<bash><br />
export PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
Or like this (csh):<br />
<bash><br />
setenv PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
<br />
==Keeping examples separate==<br />
Madagascar's public collection of example workflows are stored in RSFSRC/book, but you can put your private workflows anywhere you want. No special instructions are required.<br />
<br />
However, Madagascar assumes that the workflows are organized into a three-level book/chapter/section directory hierarchy when it creates a directory tree for the data and locked figures associated with your workflow. It is not required, but it might be easier to find the data and locked figures if you put your workflows in a three-level directory tree something like this: path_to_my_book/chapter/section/SConstruct.<br />
<br />
==Keeping data separate==<br />
The location of the data portion of your *.rsf files is controlled by your DATAPATH environment variable. However, you may want to keep the data for your private workflows in a different place, or several different places, than the data created by the public examples in RSFSRC/book. The way to do that is to temporarily change the DATAPATH variable in the SConstruct ''before'' importing rsf.proj like this:<br />
<python><br />
import os<br />
os.environ['DATAPATH'] = 'path_to_my_private_data'<br />
<br />
from rsf.proj import *<br />
</python><br />
<br />
==Keeping locked figures separate==<br />
The command "scons lock" in the directory of a workflow will store a "locked" copy<br />
<br />
The location of the data portion of your *.rsf files is controlled by your DATAPATH environment variable. However, you may want to keep the data for your private workflows in a different place, or several different places, than the data created by the public examples in RSFSRC/book. The way to do that is to temporarily change the DATAPATH variable in the SConstruct ''before'' importing rsf.proj like this:<br />
<python><br />
import os<br />
os.environ['RSFFIGS'] = 'path_to_my_private_figures'<br />
<br />
from rsf.proj import *<br />
</python><br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1192Advanced Installation2010-06-19T02:31:37Z<p>Jenningsjwj: /* Keeping data separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<bash><br />
ln -s path_to_my_programs $RSFSRC/user/my_programs<br />
</bash><br />
The additional instructions above for "multi-user installs" are for the case where the other users do not have write access to RSFSRC. However, if you have full write access and only want to keep the programs in a separate place the link is the only thing you need.<br />
<br />
==Keeping recipes separate==<br />
Computational recipes written in Python and imported by the SConstruct file of a workflow are normally stored in RSFSRC/book/Recipes. The install process copies these recipes to a directory like $RSFROOT/lib/python2.5/site-packages/rsf/recipes and adds this directory to your PYTHONPATH so that Python can find them.<br />
<br />
However, you can put you own recipes anywhere you want. You only have to add that place to your PYTHONPATH like this (bash):<br />
<bash><br />
export PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
Or like this (csh):<br />
<bash><br />
setenv PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
<br />
==Keeping examples separate==<br />
Madagascar's public collection of example workflows are stored in RSFSRC/book, but you can put your private workflows anywhere you want. No special instructions are required.<br />
<br />
However, Madagascar assumes that the workflows are organized into a three-level book/chapter/section directory hierarchy when it creates a directory tree for the data and locked figures associated with your workflow. It is not required, but it might be easier to find the data and locked figures if you put your workflows in a three-level directory tree something like this: path_to_my_book/chapter/section/SConstruct.<br />
<br />
==Keeping data separate==<br />
The location of the data portion of your *.rsf files is controlled by your DATAPATH environment variable. However, you may want to keep the data for your private workflows in a different place, or several different places, than the data created by the public examples in RSFSRC/book. The way to do that is to temporarily change the DATAPATH variable in the SConstruct ''before'' importing rsf.proj like this:<br />
<python><br />
import os<br />
os.environ['DATAPATH'] = 'path_to_my_private_data'<br />
<br />
from rsf.proj import *<br />
</python><br />
<br />
==Keeping locked figures separate==<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1191Advanced Installation2010-06-19T02:27:34Z<p>Jenningsjwj: /* Keeping data separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<bash><br />
ln -s path_to_my_programs $RSFSRC/user/my_programs<br />
</bash><br />
The additional instructions above for "multi-user installs" are for the case where the other users do not have write access to RSFSRC. However, if you have full write access and only want to keep the programs in a separate place the link is the only thing you need.<br />
<br />
==Keeping recipes separate==<br />
Computational recipes written in Python and imported by the SConstruct file of a workflow are normally stored in RSFSRC/book/Recipes. The install process copies these recipes to a directory like $RSFROOT/lib/python2.5/site-packages/rsf/recipes and adds this directory to your PYTHONPATH so that Python can find them.<br />
<br />
However, you can put you own recipes anywhere you want. You only have to add that place to your PYTHONPATH like this (bash):<br />
<bash><br />
export PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
Or like this (csh):<br />
<bash><br />
setenv PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
<br />
==Keeping examples separate==<br />
Madagascar's public collection of example workflows are stored in RSFSRC/book, but you can put your private workflows anywhere you want. No special instructions are required.<br />
<br />
However, Madagascar assumes that the workflows are organized into a three-level book/chapter/section directory hierarchy when it creates a directory tree for the data and locked figures associated with your workflow. It is not required, but it might be easier to find the data and locked figures if you put your workflows in a three-level directory tree something like this: path_to_my_book/chapter/section/SConstruct.<br />
<br />
==Keeping data separate==<br />
<python><br />
import os<br />
os.environ['DATAPATH'] = 'path_to_my_private_data'<br />
<br />
from rsf.proj import *<br />
</python><br />
<br />
==Keeping locked figures separate==<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1190Advanced Installation2010-06-19T02:20:44Z<p>Jenningsjwj: /* Keeping examples separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<bash><br />
ln -s path_to_my_programs $RSFSRC/user/my_programs<br />
</bash><br />
The additional instructions above for "multi-user installs" are for the case where the other users do not have write access to RSFSRC. However, if you have full write access and only want to keep the programs in a separate place the link is the only thing you need.<br />
<br />
==Keeping recipes separate==<br />
Computational recipes written in Python and imported by the SConstruct file of a workflow are normally stored in RSFSRC/book/Recipes. The install process copies these recipes to a directory like $RSFROOT/lib/python2.5/site-packages/rsf/recipes and adds this directory to your PYTHONPATH so that Python can find them.<br />
<br />
However, you can put you own recipes anywhere you want. You only have to add that place to your PYTHONPATH like this (bash):<br />
<bash><br />
export PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
Or like this (csh):<br />
<bash><br />
setenv PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
<br />
==Keeping examples separate==<br />
Madagascar's public collection of example workflows are stored in RSFSRC/book, but you can put your private workflows anywhere you want. No special instructions are required.<br />
<br />
However, Madagascar assumes that the workflows are organized into a three-level book/chapter/section directory hierarchy when it creates a directory tree for the data and locked figures associated with your workflow. It is not required, but it might be easier to find the data and locked figures if you put your workflows in a three-level directory tree something like this: path_to_my_book/chapter/section/SConstruct.<br />
<br />
==Keeping data separate==<br />
<br />
==Keeping locked figures separate==<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1189Advanced Installation2010-06-19T02:10:29Z<p>Jenningsjwj: /* Keeping recipes separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<bash><br />
ln -s path_to_my_programs $RSFSRC/user/my_programs<br />
</bash><br />
The additional instructions above for "multi-user installs" are for the case where the other users do not have write access to RSFSRC. However, if you have full write access and only want to keep the programs in a separate place the link is the only thing you need.<br />
<br />
==Keeping recipes separate==<br />
Computational recipes written in Python and imported by the SConstruct file of a workflow are normally stored in RSFSRC/book/Recipes. The install process copies these recipes to a directory like $RSFROOT/lib/python2.5/site-packages/rsf/recipes and adds this directory to your PYTHONPATH so that Python can find them.<br />
<br />
However, you can put you own recipes anywhere you want. You only have to add that place to your PYTHONPATH like this (bash):<br />
<bash><br />
export PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
Or like this (csh):<br />
<bash><br />
setenv PYTHONPATH=${PYTHONPATH}:path_to_my_recipes<br />
</bash><br />
<br />
==Keeping examples separate==<br />
<br />
==Keeping data separate==<br />
<br />
==Keeping locked figures separate==<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1188Advanced Installation2010-06-19T02:07:37Z<p>Jenningsjwj: /* Keeping your stuff separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<bash><br />
ln -s path_to_my_programs $RSFSRC/user/my_programs<br />
</bash><br />
The additional instructions above for "multi-user installs" are for the case where the other users do not have write access to RSFSRC. However, if you have full write access and only want to keep the programs in a separate place the link is the only thing you need.<br />
<br />
==Keeping recipes separate==<br />
Computational recipes written in Python and imported by the SConstruct file of a workflow are normally stored in RSFSRC/book/Recipes. The install process copies these recipes to a directory like $RSFROOT/lib/python2.5/site-packages/rsf/recipes and adds this directory to your PYTHONPATH so that Python can find them.<br />
<br />
However, you can put you own recipes anywhere you want. You only have to add that place to your PYTHONPATH like this (bash):<br />
<bash><br />
export PYTHONPATH=$RSFROOT/lib/python2.5/site-packages:${PYTHONPATH}<br />
</bash><br />
Or like this (csh):<br />
<bash><br />
setenv PYTHONPATH $RSFROOT/lib/python2.5/site-packages:${PYTHONPATH}<br />
</bash><br />
==Keeping examples separate==<br />
<br />
==Keeping data separate==<br />
<br />
==Keeping locked figures separate==<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1187Advanced Installation2010-06-19T02:06:49Z<p>Jenningsjwj: /* Keeping your stuff separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<bash><br />
ln -s path_to_my_programs $RSFSRC/user/my_programs<br />
</bash><br />
The additional instructions above for "multi-user installs" are for the case where the other users do not have write access to RSFSRC. However, if you have full write access and only want to keep the programs in a separate place the link is the only thing you need.<br />
<br />
==Keeping recipes separate==<br />
Computational recipes written in Python and imported by the SConstruct file of a workflow are normally stored in RSFSRC/book/Recipes. The install process copies these recipes to a directory like $RSFROOT/lib/python2.5/site-packages/rsf/recipes and adds this directory to your PYTHONPATH so that Python can find them.<br />
<br />
However, you can put you own recipes anywhere you want. You only have to add that place to your PYTHONPATH like this (bash):<br />
<bash><br />
export PYTHONPATH=$RSFROOT/lib/python2.5/site-packages:${PYTHONPATH}<br />
</bash><br />
Or like this (csh):<br />
<csh><br />
setenv PYTHONPATH $RSFROOT/lib/python2.5/site-packages:${PYTHONPATH}<br />
==Keeping examples separate==<br />
</csh><br />
==Keeping data separate==<br />
<br />
==Keeping locked figures separate==<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1186Advanced Installation2010-06-19T02:05:59Z<p>Jenningsjwj: /* Keeping your stuff separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<bash><br />
ln -s path_to_my_programs $RSFSRC/user/my_programs<br />
</bash><br />
The additional instructions above for "multi-user installs" are for the case where the other users do not have write access to RSFSRC. However, if you have full write access and only want to keep the programs in a separate place the link is the only thing you need.<br />
<br />
==Keeping recipes separate==<br />
Computational recipes written in Python and imported by the SConstruct file of a workflow are normally stored in RSFSRC/book/Recipes. The install process copies these recipes to a directory like $RSFROOT/lib/python2.5/site-packages/rsf/recipes and adds this directory to your PYTHONPATH so that Python can find them.<br />
<br />
However, you can put you own recipes anywhere you want. You only have to add that place to your PYTHONPATH like this (bash):<br />
<bash><br />
export PYTHONPATH=$RSFROOT/lib/python2.5/site-packages:${PYTHONPATH}<br />
<bash><br />
Or like this (csh):<br />
<csh><br />
setenv PYTHONPATH $RSFROOT/lib/python2.5/site-packages:${PYTHONPATH}<br />
==Keeping examples separate==<br />
<csh><br />
==Keeping data separate==<br />
<br />
==Keeping locked figures separate==<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1185Advanced Installation2010-06-19T02:02:39Z<p>Jenningsjwj: /* Keeping recipes separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<bash><br />
ln -s path_to_my_programs $RSFSRC/user/my_programs<br />
</bash><br />
The additional instructions above for "multi-user installs" are for the case where the other users do not have write access to RSFSRC. However, if you have full write access and only want to keep the programs in a separate place the link is the only thing you need.<br />
<br />
==Keeping recipes separate==<br />
Computational recipes written in Python and imported by the SConstruct file of a workflow are normally stored in RSFSRC/book/Recipes. The install process copies these recipes to a directory like $RSFROOT/lib/python2.5/site-packages/rsf/recipes and adds this directory to your PYTHONPATH so that Python can find them.<br />
<br />
However, you can put you own recipes anywhere you want. You only have to add that place to your PYTHONPATH like this:<br />
<br />
==Keeping examples separate==<br />
<br />
==Keeping data separate==<br />
<br />
==Keeping locked figures separate==<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1184Advanced Installation2010-06-19T01:54:41Z<p>Jenningsjwj: /* Keeping programs separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<bash><br />
ln -s path_to_my_programs $RSFSRC/user/my_programs<br />
</bash><br />
The additional instructions above for "multi-user installs" are for the case where the other users do not have write access to RSFSRC. However, if you have full write access and only want to keep the programs in a separate place the link is the only thing you need.<br />
<br />
==Keeping recipes separate==<br />
<br />
==Keeping examples separate==<br />
<br />
==Keeping data separate==<br />
<br />
==Keeping locked figures separate==<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1183Advanced Installation2010-06-19T01:49:46Z<p>Jenningsjwj: /* Keeping programs separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
User programs are ordinarily kept in a subdirectory of RSFSRC/user. However, if you want to keep your programs separate all you have to do is put your subdirectory somewhere else and make a link to it in RSFSRC/user:<br />
<br />
==Keeping recipes separate==<br />
<br />
==Keeping examples separate==<br />
<br />
==Keeping data separate==<br />
<br />
==Keeping locked figures separate==<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1182Advanced Installation2010-06-18T02:31:23Z<p>Jenningsjwj: /* Keeping your stuff separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
==Keeping programs separate==<br />
<br />
==Keeping recipes separate==<br />
<br />
==Keeping examples separate==<br />
<br />
==Keeping data separate==<br />
<br />
==Keeping locked figures separate==<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1181Advanced Installation2010-06-18T02:29:10Z<p>Jenningsjwj: /* Keeping your stuff separate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
A user may add his own programs and recipes to the Madagascar system. He may also create his own computational examples, data, and locked figures for testing. All of these components can be placed in their default locations, but it is not necessary to make them public. To keep these items private simply do not add them to the repository.<br />
<br />
However, it might be desirable to keep these components in separate places. For example, if you keep your private programs in RSFSRC/user you will have to remember to make a copy somewhere else if you ever want to delete the Madagascar installation to perform a fresh install. Yup, I deleted all my programs that way once. Good thing I had a back up! Fortunately, it is easy to keep each of these components in a separate place if desired.<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1180Advanced Installation2010-06-18T02:19:38Z<p>Jenningsjwj: </p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1179Advanced Installation2010-06-18T02:18:58Z<p>Jenningsjwj: /* Keeping your stuff seperate */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff separate=<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=1178Advanced Installation2010-06-18T02:18:19Z<p>Jenningsjwj: </p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation.<br />
<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
For future documentation writers: the environment variables read by Madagascar that have not been documented below can be found by running the script <tt>$RSFSRC/admin/find_env_var.py</tt>. If the script does not exist or does not work, a summary of all environment variable calls can be obtained by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar core==<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>RSF_CLUSTER</tt>: used by <tt>pscons</tt><br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
If you have many kinds of systems to maintain, with multiple versions of Madagascar, and users have more than one shell, you may find it easy to outsource the complex logic to the easy-to-debug Python, i.e.:<br />
<br />
<bash><br />
export RSFROOT=`$M8R_SETUP/get_rsfroot.py`<br />
export PYTHONPATH=`$M8R_SETUP/edit_pythonpath.py`<br />
export PATH=`$M8R_SETUP/edit_path.py`<br />
</bash><br />
<br />
and similarly for (t)csh. The Python scripts determine the operating system and its version, determine the machine name, and simply print to stdout the desired string.<br />
<br />
==Eclipse + Pydev==<br />
If you use [http://eclipse.org/ Eclipse] with [http://pydev.org/ Pydev], [http://pydev.org/manual_101_interpreter.html#id2 configure the interpreter] by adding <tt>$RSFROOT/lib</tt> to the <tt>PYTHONPATH</tt> for your chosen interpreter.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but in January 2010 only Fedora 11 and 12 are actively maintained. Thus, in January 2010 Madagascar was not attempting to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support. An application of the above guidelines to some Linux distributions follows:<br />
<br />
'''Support info'''<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Distribution<br />
! style="background:#ffdead;" | Life Cycle<br />
! style="background:#ffdead;" | Supported versions<br />
|-<br />
| CentOS/RHEL<br />
| [https://www.redhat.com/security/updates/errata/ 7 years]<br />
| <br />
* 3 until 2010-10-22<br />
* 4 until 2012-02-15 or until SCons stable drops support for Python 2.3, whichever comes first.<br />
* 5 until 2014-03-14, or until SCons stable version ceases to support Python 2.4, whichever comes first. <br />
|-<br />
| Fedora<br />
| [http://fedoraproject.org/wiki/LifeCycle Release X maintained until one month after the release of X+2]<br />
| <br />
* 11 until end of June 2010<br />
* 12 until end of December 2010<br />
|-<br />
| Ubuntu<br />
| [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Releases every 6 mo, maintained for 1.5 yrs; LTS versions every 2 yrs, maintained for 5 yrs]<br />
| <br />
* 6.06 LTS Server until end of June 2011<br />
* 8.04 LTS Desktop until end of April 2011 <br />
* 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* 9.04 until end of October 2010 <br />
* 9.10 until end of April 2011 <br />
|-<br />
| Debian<br />
| [http://wiki.debian.org/DebianLenny Usually: stable releases every 1.5 yrs, release X maintained 1 yr after release X+1]<br />
| 5 (Lenny) until its end of life, or until SCons stops supporting Python 2.5, whatever comes sooner.<br />
|- <br />
| openSUSE<br />
| [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases Lifetime of 2 years]<br />
| <br />
* 11.0 until 2010-06-30<br />
* 11.1 until 2010-12-31<br />
* 11.2 until 2011-11-30<br />
|}<br />
<br />
==Ubuntu==<br />
<br />
In '''Ubuntu 10.04 ''Lucid Lynx''''', you can install all of Madagascar's dependencies by running <br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libgd2-xpm-dev libglew1.5-dev libjpeg62-dev libx11-dev \<br />
libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units libblas-dev \<br />
libcairo2-dev libavcodec-dev libplplot-dev <br />
</pre><br />
<br />
In the previous version (9.04) the corresponding command is<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libgd2-xpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
Earlier versions may work with<br />
<pre><br />
sudo apt-get install mesa-libGL-devel g++ g77 libc6-dev libgd2-xpm-dev libglew-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy libtiff4-dev scons units <br />
</pre><br />
<br />
If working with the development version, you will also need <tt>subversion</tt>.<br />
<br />
==Fedora 11, 12==<br />
<br />
Dependency package names, sorted by Linux distribution and m8r feature they provide. Packages that are not included in the standard distro repositories are hyperlinked to their providers. The tables below cover build dependencies. <br />
<br />
''Note: In the future, we should distinguish the subset of runtime dependencies (necessary to run already-compiled binaries installed through a package manager)''<br />
<br />
''Note: In the future, it should be possible for the configuration scripts to output the dependency tables below, so that they are guaranteed to be in synch with a given m8r version''<br />
<br />
'''Minimal install ("Core"), publishing and development'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Core<br />
! style="background:#ffdead;" | LaTeX<br />
! style="background:#ffdead;" | Development version<br />
! style="background:#ffdead;" | C++ API<br />
! style="background:#ffdead;" | F77 API, F90 API<br />
! style="background:#ffdead;" | Python API<br />
! style="background:#ffdead;" | Java API<br />
! style="background:#ffdead;" | Octave API<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| binutils, gcc, glibc-headers, scons<br />
| texlive-latex<br />
| subversion<br />
| gcc-c++<br />
| gcc-gfortran<br />
| numpy, python, swig<br />
| Java (Sun's? IcedTea?), [http://inside.mines.edu/~dhale/jtk/ Mines JTK]<br />
| octave, octave-devel<br />
|}<br />
<br />
'''Numerical and file manipulation utilities'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | OpenMP<br />
! style="background:#ffdead;" | MPI<br />
! style="background:#ffdead;" | BLAS/ATLAS<br />
! style="background:#ffdead;" | SciPy<br />
! style="background:#ffdead;" | pyct (?)<br />
! style="background:#ffdead;" | sfunits<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| libgomp<br />
| openmpi, openmpi-devel, openmpi-libs<br />
| blas, blas-devel, atlas, atlas-devel<br />
| scipy<br />
| pyct<br />
| units<br />
|}<br />
<br />
'''Graphics and visualization'''<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
|<br />
! style="background:#ffdead;" | Some sort of movies?<br />
! style="background:#ffdead;" | TIFF output<br />
! style="background:#ffdead;" | JPEG output<br />
! style="background:#ffdead;" | PLplot graphics<br />
! style="background:#ffdead;" | OpenGL graphics<br />
! style="background:#ffdead;" | X11 graphics<br />
! style="background:#ffdead;" | ppm (?)<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| ffmpeg-devel<br />
| libtiff-devel<br />
| libjpeg-devel<br />
| plplot-devel<br />
| mesa-libGL-devel, freeglut, freeglut-devel<br />
| libXaw-devel<br />
| netpbm-devel<br />
|}<br />
<br />
'''Command to install all dependencies present in the public repositories'''<br />
<br />
Usually package management software will not install again a package that is already installed, so it should be safe to copy and paste the command below to a command line (remember to delete newlines):<br />
<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! style="background:#ffdead;" | Fedora 11, 12<br />
| yum -y install binutils gcc glibc-headers scons texlive-latex subversion gcc-c++ gcc-gfortran numpy python swig octave octave-devel libgomp openmpi openmpi-devel openmpi-libs blas blas-devel atlas atlas-devel scipy pyct units ffmpeg-devel libtiff-devel libjpeg-devel plplot-devel mesa-libGL-devel freeglut freeglut-devel libXaw-devel netpbm-devel<br />
|}<br />
<br />
==CentOS 3, 4, 5==<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list.<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 5==<br />
Specific dependencies:<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source. The <tt>libXaw7-dev</tt> package might be a dependency for <tt>xtpen</tt> (was in Debian 4.0)<br />
<br />
==openSUSE 11.*==<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Yellow Dog Linux 6.1 on Sony PlayStation 3==<br />
See [http://www.reproducibility.org/rsflog/uploads/Friday_Seminar_Madagascar_on_PS3.ppt W. Burnett's guide (PowerPoint)]<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. <br />
<br />
If you want to install a development version of Madagascar, the following might help. <br />
# <b>C compiler</b> for Mac OS X. You can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Other sources are:<br />
#* [http://www.macports.org/ MacPorts], an easy-to-use system for compiling, installing, and upgrading open-source software on Mac OS X.<br />
#* [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>MacPorts</b> or <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>MacPorts</b> and <b>Fink</b> provide an easy way to install it with commands <tt>sudo port install texlive</tt> or <tt>sudo fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Keeping your stuff seperate=<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Download&diff=1127Download2010-05-03T20:03:24Z<p>Jenningsjwj: /* Precompiled binary packages */</p>
<hr />
<div>[[Image:Fotolia_2043821_XS.jpg|right|]]<br />
You can choose to download either the latest stable release, or the current development version (frequently updated).<br />
<br />
==Stable release==<br />
<br />
===Precompiled binary packages===<br />
<br />
A Mac OS X precompiled binary package of the latest Madagascar stable release is available for Intel Macs at [https://sourceforge.net/project/showfiles.php?group_id=162909 Sourceforge]. Download a disk image file, mount the disk image if it does not mount automatically, launch the installer package inside the disk image, and follow the instructions. Additional instructions can be found in the ReadMe file.<br />
<br />
The Mac OS X Madagascar package installs the main programs, documentation files, includes files, and libraries in /usr/local/rsf. You will be asked for an administrator password. The collection of Madagascar examples included with the source code release is not yet included with this package, but that may change so check back here occasionally for updates.<br />
<br />
===Source code distribution===<br />
<br />
[https://sourceforge.net/project/showfiles.php?group_id=162909 Download the source code distribution securely from Sourceforge], then unpack the directory with <br />
<pre>gunzip < madagascar-*.tar.gz | tar xvf -</pre><br />
or <br />
<pre>bunzip2 < madagascar-*.tar.bz2 | tar xvf -</pre><br />
The <tt>bz2</tt> file is a bit smaller, but takes longer to unpack. <br />
<br />
Next, follow [[Installation|Installation instructions]] to install.<br />
<br />
==Current development version==<br />
<br />
You need to have a [http://subversion.tigris.org/ Subversion client] (<tt>svn</tt>) installed. To download the directory with the Madagascar source code, run the following command:<br />
<pre><br />
svn co <nowiki>https://rsf.svn.sourceforge.net/svnroot/rsf/trunk</nowiki> RSFSRC<br />
</pre><br />
Replace <tt>RSFSRC</tt> with the path where you want to put the Madagascar source code.<br />
<br />
Next, follow [[Installation|Installation instructions]] to install.<br />
<br />
You can also [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/ browse the Subversion repository].<br />
<br />
===Updating===<br />
<br />
To update the Madagascar source code on your computer with the changes made by developers, <tt>cd</tt> to the directory where you placed the sources and run<br />
<pre><br />
svn update<br />
</pre><br />
<br />
===Troubleshooting===<br />
<br />
*If, after running the <tt>svn co...</tt> command, nothing happens, no message, no return to the command line: you may be behind a proxy. This is especially likely if your computer is on a corporate Intranet. To get past a proxy, you need to tell Subversion: (1) The IP number or URL of the proxy and (2) the port that will allow <tt>svn</tt> through &ndash; most likely 80, the standard HTTP port. Open your <tt>~/.subversion/servers</tt> file in a text editor. If this file does not exist, running any <tt>svn</tt> command (even an unsuccessful one, like the one above) will automatically create the file. In the <tt>[global]</tt> section, add the following lines, with your own proxy URL and port names instead of the dummy ones below: <br />
<pre>http-proxy-host = www-proxy.yourcompany.com<br />
http-proxy-port = 80<br />
</pre> Now your <tt>svn</tt> commands should work. You can find more details [http://subversion.tigris.org/faq.html#proxy in the Subversion documentation]. It would also be a good idea to set in your <tt>.bashrc</tt> or <tt>.cshrc</tt> the environment variable <tt>HTTP_PROXY</tt> to your adaptation of <pre>http://www-proxy.yourcompany.com:80</pre> so that input datasets for reproducible figures can be downloaded automatically when you need them.<br />
<br />
*If you get a "is already a working copy for a different URL" error, this means you have an existing directory downloaded from another server. Run <tt>svn switch --relocate</tt> to switch servers.<br />
<br />
*If you are using an old Linux distribution (e.g. RedHat 9), the version of Subversion included with your distribution may need to be updated to handle the secure URL (<nowiki>https://</nowiki>). If <tt>svn</tt> complains about an "unrecognized URL scheme" (and you've given it the correctly formatted URL), then you need to update it.<br />
<br />
*If you are behind a firewall, you may need to set up more variables in your file <tt>~/.subversion/servers</tt> (check with your IT support for all the required variables to get past the proxy) as for example<br />
<pre><br />
[global]<br />
http-proxy-host = proxy-host-company.site.corp <br />
http-proxy-port = 1111<br />
http-proxy-username = Yourusernameforproxy<br />
http-proxy-password = Yourpasswordforproxy <br />
</pre> <br />
It would be a good idea then to protect your file <tt>~/.subversion/servers</tt> from being read by others.<br />
<br />
==Other packages==<br />
There are two other packages that might be useful in conjunction with RSF:<br />
===Reproducible figures===<br />
<br />
*Using Subversion, run <pre> svn co https://rsf.svn.sourceforge.net/svnroot/rsf/figs &#36;RSFROOT/figs </pre> <br />
This installs a wide collection of about 2500 reproducible figures. It may take a long time to download and more than 4 Gb of disk space.<br />
The figures are preserved with the purpose of regression testing whenever the software or the environment change.<br />
<br />
You can reproduce the figures (excluding those generated with proprietary data or additional software) by running <tt>scons lock</tt> in individual project directories or by going to <tt>RSF/book</tt> and running<br />
<pre><br />
sftour sftour sftour scons lock<br />
</pre><br />
<br />
===L<sup>A</sup>TEX package===<br />
<br />
[[SEGTeX]] is a LaTeX package for geophysical publications. It can be used with madagascar for writing [[Reproducible Documents|reproducible papers]].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=932Advanced Installation2009-08-14T13:06:47Z<p>Jenningsjwj: /* Used by the Madagascar core */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation. If you cannot get <tt>mkoctfile</tt> installed, but still want some limited functionality of this API, specifying <tt>APIFORCE=y</tt> during the configuration.<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
==Used by the Madagascar core==<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFFIGS || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
<br />
For future documentation writers: the environment variables read by Madagascar can be found by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>APIFORCE</tt>: If <tt>APIFORCE=y</tt>, those API components that do not have dependencies will be nevertheless installed. This is the case of scripts in interpreted languages which call standalone Madagascar programs. This option is provided for allowing a limited functionality to those who cannot install dependencies, while not annoying those who may want specifically to NOT have an API installed because of namespace conflicts or other reasons.<br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but currently only Fedora 9 and 10 are actively maintained. Thus, Madagascar does not attempt to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support.<br />
<br />
==Ubuntu 6.06-9.04==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, and considering the [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Ubuntu Life Cycle], Madagascar will attempt to support:<br />
* Ubuntu 6.06 LTS Server until end of June 2011 or until SCons stops supporting Python 2.4, whichever comes sooner<br />
* Ubuntu 8.04 LTS Desktop until end of April 2011 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 8.10 until end of April 2010 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 9.04 until end of October 2010 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 9.10 until end of April 2011 or until SCons stops supporting its Python version, whichever comes sooner<br />
<br />
You can install all of Madagascar's dependencies by running<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libg2-noxpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy scons units <br />
</pre><br />
<br />
If working with the development version, you will need <tt>subversion</tt> to download and update it.<br />
<br />
Ubuntu 9.04 changes:<br />
* Package <tt>g77</tt> (dependency for Fortran API in earlier versions of Ubuntu) does not seem to be present in the repositories, replaced with <tt>gfortran</tt><br />
* Package <tt>mesa-libGL-devel</tt> (dependency of OpenGL in earlier versions of Ubuntu) does not seem to be present in the repositories, replaced with <tt>freeglut3-dev</tt><br />
* Package <tt>libglew-dev</tt> (dependency of GLEW in earlier versions of Ubuntu) does not seem to be present in the repositories, replaced with <tt>libglew1.5-dev</tt><br />
<br />
==Fedora 10, 11==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, Madagascar will attempt to support the last two versions of Fedora (currently 10 and 11). Considering the [http://fedoraproject.org/wiki/LifeCycle Fedora Life Cycle] (release X maintained until one month after the release of X+2) and the [http://fedoraproject.org/wiki/Releases/12/Schedule Fedora 12 schedule], Fedora 10 should be dropped and Fedora 12 should be supported starting with 2009-12-03.<br />
<br />
You can install the common dependencies for both the stable version and the development one, by typing as root:<br />
<pre><br />
yum -y install atlas atlas-devel binutils blas blas-devel freeglut freeglut-devel gcc \<br />
gcc-c++ gcc-gfortran glibc-headers libjpeg-devel libXaw-devel netpbm-devel numpy octave \<br />
octave-devel scipy scons swig texlive units <br />
</pre><br />
Packages that are already installed will be ignored.<br />
<br />
To install LaTeX for building papers and books, you need <tt>texlive-latex</tt> .<br />
<br />
If you are using the development version, you also need the <tt>subversion</tt> package. If you are installing on a multicore machine, you will get a speedup if you install <tt>libgomp</tt>.<br />
<br />
==CentOS 3, 4, 5==<br />
Given that CentOS is a clone of RHEL, it is expected it will have the same lifecycle (7 years of support after release), CentOS 5 should be supported by Madagascar until 2014-03-14, or until SCons stable version ceases to support Python 2.4 &ndash; whichever comes first. CentOS 4 should be supported until 2012-02-15 or until SCons stable drops support for 2.3. CentOS 3 should be supported until 2010-10-22 or until SCons stable drops support for Python 2.2, whichever comes first.<br />
<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list .<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 4, 5==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, Madagascar will attempt to support Debian 4 until it stops being supported by its developers (end 2009-beg. 2010), and Debian 5 until it stops being supported by the Debian project or SCons stops supporting Python 2.5, whatever comes sooner.<br />
<br />
Specific dependencies:<br />
* Debian 4.0 ("Etch"): In order to build xtpen (for displaying .vpl images) you will need the <tt>libXaw7-dev</tt> package.<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source.<br />
<br />
==openSUSE 11.0, 11.1==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, and given that [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases have a lifetime of 2 years], Madagascar should theoretically attempt to support openSUSE 10.3 until 2009-10-31, openSUSE 11.0 until 2010-06-30, and openSUSE 11.1 until 2010-12-31. In practice, due to limited resources, installation has only been verified on openSUSE 11.0 and 11.1.<br />
<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. If you want to install a development version of Madagascar, the following might help. <br />
<br />
# <b>C compiler</b> for Mac OS X. One can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Another way is to use [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>Fink</b> provides a easy way to install it with the command <tt>fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Guide_to_madagascar_programs&diff=931Guide to madagascar programs2009-08-14T03:03:41Z<p>Jenningsjwj: /* sffiglist */</p>
<hr />
<div><center><font size="-1">''This page was created from the LaTeX source in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/rsf/rsf/prog.tex?view=markup book/rsf/rsf/prog.tex] using [[latex2wiki]]''</font></center><br />
<br />
This guide introduces some of the most used <tt>madagascar</tt> programs and illustrates their usage with examples.<br />
=Main programs=<br />
The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/ system/main] in the Madagascar distribution. The "main" programs perform general-purpose operations on RSF hypercubes regardless of the data dimensionality or physical dimensions.<br />
<br />
==sfadd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Add, multiply, or divide RSF datasets.<br />
|-<br />
! colspan="4" | sfadd > out.rsf scale= add= sqrt= abs= log= exp= mode= [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | The various operations, if selected, occur in the following order:<br><br>(1) Take absolute value, abs=<br>(2) Add a scalar, add=<br>(3) Take the natural logarithm, log=<br>(4) Take the square root, sqrt=<br>(5) Multiply by a scalar, scale=<br>(6) Compute the base-e exponential, exp=<br>(7) Add, multiply, or divide the data sets, mode=<br><br>sfadd operates on integer, float, or complex data, but all the input<br>and output files must be of the same data type.<br><br>An alternative to sfadd is sfmath, which is more versatile, but may be<br>less efficient.<br />
|-<br />
| ''bools '' || '''abs=''' || || If true take absolute value [nin]<br />
|-<br />
| ''floats '' || '''add=''' || || Scalar values to add to each dataset [nin]<br />
|-<br />
| ''bools '' || '''exp=''' || || If true compute exponential [nin]<br />
|-<br />
| ''bools '' || '''log=''' || || If true take logarithm [nin]<br />
|-<br />
| ''string '' || '''mode=''' || || 'a' means add (default), <br> 'p' or 'm' means multiply, <br> 'd' means divide<br />
|-<br />
| ''floats '' || '''scale=''' || || Scalar values to multiply each dataset with [nin]<br />
|-<br />
| ''bools '' || '''sqrt=''' || || If true take square root [nin]<br />
|}<br />
<br />
<tt>sfadd</tt> is useful for combining (adding, dividing, or<br />
multiplying) several datasets. What if you want to subtract two<br />
datasets? Easy. Use the <tt>scale</tt> parameter as follows:<br />
<pre><br />
bash&#36; sfadd data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfadd < data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
The same task can be accomplished with the more general <tt>sfmath</tt> program:<br />
<pre><br />
bash&#36; sfmath one=data1.rsf two=data2.rsf output='one-two' > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfmath < data1.rsf two=data2.rsf output='input-two' > diff.rsf<br />
</pre><br />
In both cases, the size and shape of <tt>data1.rsf</tt> and<br />
<tt>data2.rsf</tt> hypercubes should be the same, and a warning<br />
message is printed out if the the axis sampling parameters (such as<br />
<tt>o1</tt> or <tt>d1</tt>) in these files are different.<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/add.c?view=markup system/main/add.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
/* find number of input files */<br />
if (isatty(fileno(stdin))) { <br />
/* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Collect input files in the <tt>in</tt> array from all command-line<br />
parameters that don't contain an "<tt>=</tt>" sign. The total number<br />
of input files in <tt>nin</tt>.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) continue; <br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
/* nin = no of input files*/<br />
</c><br />
<br />
A helper function <tt>check_compat</tt> checks the compatibility of<br />
input files.<br />
<c><br />
static void <br />
check_compat (sf_datatype type /* data type */, <br />
size_t nin /* number of files */, <br />
sf_file* in /* input files [nin] */, <br />
int dim /* file dimensionality */, <br />
const int* n /* dimensions [dim] */)<br />
/* Check that the input files are compatible. <br />
Issue error for type mismatch or size mismatch.<br />
Issue warning for grid parameters mismatch. */<br />
{<br />
int ni, id;<br />
size_t i;<br />
float d, di, o, oi;<br />
char key[3];<br />
const float tol=1.e-5; /* tolerance for comparison */<br />
<br />
for (i=1; i < nin; i++) {<br />
if (sf_gettype(in[i]) != type) <br />
sf_error ("type mismatch: need %d",type);<br />
for (id=1; id <= dim; id++) {<br />
(void) snprintf(key,3,"n%d",id);<br />
if (!sf_histint(in[i],key,&ni) || ni != n[id-1])<br />
sf_error("%s mismatch: need %d",key,n[id-1]);<br />
(void) snprintf(key,3,"d%d",id);<br />
if (sf_histfloat(in[0],key,&d)) {<br />
if (!sf_histfloat(in[i],key,&di) || <br />
(fabsf(di-d) > tol*fabsf(d)))<br />
sf_warning("%s mismatch: need %g",key,d);<br />
} else {<br />
d = 1.;<br />
}<br />
(void) snprintf(key,3,"o%d",id);<br />
if (sf_histfloat(in[0],key,&o) && <br />
(!sf_histfloat(in[i],key,&oi) || <br />
(fabsf(oi-o) > tol*fabsf(d))))<br />
sf_warning("%s mismatch: need %g",key,o);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
Finally, we enter the main loop, where input data are getting read<br />
buffer by buffer and combined in the total product depending on the<br />
data type.<br />
<c><br />
for (nbuf /= sf_esize(in[0]); nsiz > 0; nsiz -= nbuf) {<br />
if (nbuf > nsiz) nbuf=nsiz;<br />
<br />
for (j=0; j < nin; j++) {<br />
collect = (bool) (j != 0);<br />
switch(type) {<br />
case SF_FLOAT:<br />
sf_floatread((float*) bufi,<br />
nbuf,<br />
in[j]); <br />
add_float(collect, <br />
nbuf,<br />
(float*) buf,<br />
(const float*) bufi, <br />
cmode, <br />
scale[j], <br />
add[j], <br />
abs_flag[j], <br />
log_flag[j], <br />
sqrt_flag[j], <br />
exp_flag[j]);<br />
break;<br />
</c><br />
<br />
The data combination program for floating point numbers is<br />
<tt>add_float</tt>. <br />
<c><br />
static void add_float (bool collect, /* if collect */<br />
size_t nbuf, /* buffer size */<br />
float* buf, /* output [nbuf] */<br />
const float* bufi, /* input [nbuf] */ <br />
char cmode, /* operation */<br />
float scale, /* scale factor */<br />
float add, /* add factor */<br />
bool abs_flag, /* if abs */<br />
bool log_flag, /* if log */<br />
bool sqrt_flag, /* if sqrt */<br />
bool exp_flag /* if exp */)<br />
/* Add floating point numbers */<br />
{<br />
size_t j;<br />
float f;<br />
<br />
for (j=0; j < nbuf; j++) {<br />
f = bufi[j];<br />
if (abs_flag) f = fabsf(f);<br />
f += add;<br />
if (log_flag) f = logf(f);<br />
if (sqrt_flag) f = sqrtf(f);<br />
if (1. != scale) f *= scale;<br />
if (exp_flag) f = expf(f);<br />
if (collect) {<br />
switch (cmode) {<br />
case 'p': /* product */<br />
case 'm': /* multiply */<br />
buf[j] *= f;<br />
break;<br />
case 'd': /* delete */<br />
if (f != 0.) buf[j] /= f;<br />
break;<br />
default: /* add */<br />
buf[j] += f;<br />
break;<br />
}<br />
} else {<br />
buf[j] = f;<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display dataset attributes.<br />
|-<br />
! colspan="4" | sfattr < in.rsf want=<br />
|-<br />
| colspan="4" | <br>Sample output from "sfspike n1=100 | sfbandpass fhi=60 | sfattr"<br>******************************************* <br>rms = 0.992354 <br>mean value = 0.987576 <br>2-norm value = 9.92354 <br>variance = 0.00955481 <br>standard deviation = 0.0977487 <br>maximum value = 1.12735 at 97 <br>minimum value = 0.151392 at 100 <br>number of nonzero samples = 100 <br>total number of samples = 100 <br>******************************************* <br><br>rms = sqrt[ sum(data^2) / n ]<br>mean = sum(data) / n<br>norm = sum(abs(data)^lval)^(1/lval)<br>variance = [ sum(data^2) - n*mean^2 ] / [ n-1 ]<br>standard deviation = sqrt [ variance ]<br />
|-<br />
| ''int '' || '''lval=2''' || || norm option, lval is a non-negative integer, computes the vector lval-norm<br />
|-<br />
| ''string '' || '''want=''' || || 'all'(default),'rms','mean','norm','var','std','max','min','nonzero','samples','short' <br />
:want= 'rms' displays the root mean square<br />
:want= 'norm' displays the square norm, otherwise specified by lval.<br />
:want= 'var' displays the variance<br />
:want= 'std' displays the standard deviation<br />
:want= 'nonzero' displays number of nonzero samples<br />
:want= 'samples' displays total number of samples<br />
:want= 'short' displays a short one-line version<br />
|}<br />
<br />
<br />
<tt>sfattr</tt> is a useful diagnostic program. It reports certain<br />
statistical values for an RSF dataset: RMS (root-mean-square)<br />
amplitude, mean value, vector norm value, variance, standard deviation,<br />
maximum and minimum values, number of nonzero samples, and the total<br />
number of samples.<br />
If we denote data values as <math>d_i</math> for <math>i=0,1,2,\ldots,n</math>, then the RMS<br />
value is <math>\sqrt{\frac{1}{n}\,\sum\limits_{i=0}^n d_i^2}</math>, the mean<br />
value is <math>\frac{1}{n}\,\sum\limits_{i=0}^n d_i</math>, the <math>L_2</math>-norm value<br />
is <math>\sqrt{\sum\limits_{i=0}^n d_i^2}</math>, the variance is<br />
<math>\frac{1}{n-1}\,\left[\sum\limits_{i=0}^n d_i^2 - \frac{1}{n}\left(\sum\limits_{i=0}^n d_i\right)^2\right]</math>, and the standard<br />
deviation is the square root of the variance. Using <tt>sfattr</tt><br />
is a quick way to see the distribution of data values and check it for anomalies.<br />
<br />
The output can be parsed using utilities such as <tt>awk</tt>, to extract only a numeric value for feeding it as a parameter value into a command line interface. Notice the backticks in the example below:<br />
<bash><br />
sfgrey <vel.rsf allpos=y bias=`sfattr <vel.rsf want=min | awk '{print $4}'` | xtpen<br />
</bash><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/attr.c?view=markup system/main/attr.c]====<br />
<br />
Computations start by finding the input data (<tt>in</tt>) size<br />
(<tt>nsiz</tt>) and dimensions (<tt>dim</tt>).<br />
<c><br />
dim = (size_t) sf_filedims (in,n);<br />
for (nsiz=1, i=0; i < dim; i++) {<br />
nsiz *= n[i];<br />
}<br />
</c><br />
<br />
<br />
In the main loop, we read the input data buffer by buffer.<br />
<c><br />
for (nleft=nsiz; nleft > 0; nleft -= nbuf) {<br />
nbuf = (bufsiz < nleft)? bufsiz: nleft;<br />
switch (type) {<br />
case SF_FLOAT: <br />
sf_floatread((float*) buf,nbuf,in);<br />
break;<br />
case SF_INT:<br />
sf_intread((int*) buf,nbuf,in);<br />
break;<br />
case SF_COMPLEX:<br />
sf_complexread((sf_complex*) buf,nbuf,in);<br />
break;<br />
case SF_UCHAR:<br />
sf_ucharread((unsigned char*) buf,nbuf,in);<br />
break;<br />
case SF_CHAR:<br />
default:<br />
sf_charread(buf,nbuf,in);<br />
break;<br />
}<br />
</c><br />
<br />
<br />
The data attributes are accumulated in corresponding double-precision<br />
variables. <br />
<c><br />
fsum += f;<br />
fsqr += f*f;<br />
</c><br />
<br />
<br />
Finally, the attributes are reduced and printed out.<br />
<c><br />
fmean = fsum/nsiz;<br />
if (lval==2) fnorm = sqrt(fsqr);<br />
else if (lval==0) fnorm = nsiz-nzero;<br />
else fnorm = pow(flval,1./lval);<br />
frms = sqrt(fsqr/nsiz);<br />
if (nsiz > 1) fvar = (fsqr-nsiz*fmean*fmean)/(nsiz-1);<br />
else fvar = 0.0;<br />
fstd = sqrt(fvar);<br />
</c><br />
<br />
<c><br />
if(NULL==want || 0==strcmp(want,"rms"))<br />
printf("rms = %g \n",(float) frms);<br />
if(NULL==want || 0==strcmp(want,"mean"))<br />
printf("mean value = %g \n",(float) fmean);<br />
if(NULL==want || 0==strcmp(want,"norm"))<br />
printf("%d-norm value = %g \n",lval,(float) fnorm);<br />
if(NULL==want || 0==strcmp(want,"var"))<br />
printf("variance = %g \n",(float) fvar);<br />
if(NULL==want || 0==strcmp(want,"std"))<br />
printf("standard deviation = %g \n",(float) fstd);<br />
</c><br />
<br />
==sfcat==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Concatenate datasets. <br />
|-<br />
! colspan="4" | sfcat > out.rsf space= axis=3 nspace=(int) (ni/(20*nin) + 1) [<file0.rsf] file1.rsf file2.rsf ... <br />
|-<br />
| colspan="4" | sfmerge inserts additional space between merged data.<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis being merged<br />
|-<br />
| ''int '' || '''nspace=(int) (ni/(20*nin) + 1)''' || || if space=y, number of traces to insert<br />
|-<br />
| ''bool '' || '''space=''' || [y/n] || Insert additional space.<br />
:y is default for sfmerge, n is default for sfcat<br />
|}<br />
<br />
<br />
<tt>sfcat</tt> and <tt>sfmerge</tt> concatenate two or more files<br />
together along a particular axis. It is the same program, only<br />
<tt>sfcat</tt> has the default <tt>space=n</tt> and <tt>sfmerge</tt><br />
has the default <tt>space=y</tt>.<br />
Example of <tt>sfcat</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcat one.rsf one.rsf axis=1 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=4 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
12 elements 48 bytes<br />
</pre><br />
Example of <tt>sfmerge</tt>:<br />
<pre><br />
bash$ sfmerge one.rsf one.rsf axis=2 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=7 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
14 elements 56 bytes<br />
</pre><br />
In this case, an extra empty trace is inserted between the two merged files.<br />
The axes that are not being merged are checked for consistency:<br />
<pre><br />
bash$ sfcat one.rsf two.rsf > three.rsf<br />
sfcat: n2 mismatch: need 3<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cat.c?view=markup system/main/cat.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
in = (sf_file*) sf_alloc ((size_t) argc,sizeof(sf_file));<br />
<br />
if (!sf_stdin()) { /* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Everything on the command line that does not contain a "=" sign is<br />
treated as a file name, and the corresponding file object is added to the list.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) <br />
continue; /* not a file */<br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
</c><br />
<br />
As explained above, if the <tt>space=</tt> parameter is not set, it is<br />
inferred from the program name: <tt>sfmerge</tt> corresponds to<br />
<tt>space=y</tt> and <tt>sfcat</tt> corresponds to <tt>space=n</tt>.<br />
<c><br />
if (!sf_getbool("space",&space)) {<br />
/* Insert additional space.<br />
y is default for sfmerge, n is default for sfcat */<br />
prog = sf_getprog();<br />
if (NULL != strstr (prog, "merge")) {<br />
space = true;<br />
} else if (NULL != strstr (prog, "cat")) {<br />
space = false;<br />
} else {<br />
sf_warning("%s is neither merge nor cat,"<br />
" assume merge",prog);<br />
space = true;<br />
}<br />
}<br />
</c><br />
<br />
Find the axis for the merging (from the command line <tt>axis=</tt><br />
argument) and figure out two sizes: <tt>n1</tt> for everything after<br />
the axis and <tt>n2</tt> for everything before the axis.<br />
<c><br />
n1=1;<br />
n2=1;<br />
for (i=1; i <= dim; i++) {<br />
if (i < axis) n1 *= n[i-1];<br />
else if (i > axis) n2 *= n[i-1];<br />
}<br />
</c><br />
<br />
In the output, the selected axis will get extended.<br />
<c><br />
/* figure out the length of extended axis */<br />
ni = 0;<br />
for (j=0; j < nin; j++) {<br />
ni += naxis[j];<br />
}<br />
<br />
if (space) {<br />
if (!sf_getint("nspace",&nspace)) <br />
nspace = (int) (ni/(20*nin) + 1);<br />
/* if space=y, number of traces to insert */ <br />
ni += nspace*(nin-1);<br />
} <br />
<br />
(void) snprintf(key,3,"n%d",axis);<br />
sf_putint(out,key,(int) ni);<br />
</c><br />
<br />
The rest is simple: loop through the datasets reading and writing the<br />
data in buffer-size chunks and adding extra empty chunks if<br />
<tt>space=y</tt>.<br />
<c><br />
for (i2=0; i2 < n2; i2++) {<br />
for (j=0; j < nin; j++) {<br />
for (ni = n1*naxis[j]*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charread (buf,nbuf,in[j]);<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
if (!space || j == nin-1) continue;<br />
/* Add spaces */<br />
memset(buf,0,BUFSIZ);<br />
for (ni = n1*nspace*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfcmplx==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a complex dataset from its real and imaginary parts.<br />
|-<br />
! colspan="4" | sfcmplx > cmplx.rsf real.rsf imag.rsf<br />
|-<br />
| colspan="4" | There has to be only two input files specified and no additional parameters.<br />
|}<br />
<br />
<br />
<tt>sfcmplx</tt> simply creates a complex dataset from its real and<br />
imaginary parts. The reverse operation can be accomplished with<br />
<tt>sfreal</tt> and <tt>sfimag</tt>.<br />
Example of <tt>sfcmplx</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcmplx one.rsf one.rsf > cmplx.rsf<br />
bash$ sfin cmplx.rsf<br />
cmplx.rsf:<br />
in="/tmp/cmplx.rsf@"<br />
esize=8 type=complex form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 48 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cmplx.c?view=markup system/main/cmplx.c]====<br />
The program flow is simple. First, get the names of the input files.<br />
<c><br />
/* the first two non-parameters are real and imaginary files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == real) {<br />
real = sf_input (argv[i]);<br />
} else {<br />
imag = sf_input (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == imag) {<br />
if (NULL == real) sf_error ("not enough input");<br />
/* if only one input, real is in stdin */<br />
imag = real;<br />
real = sf_input("in");<br />
}<br />
</c><br />
<br />
The main part of the program reads the real and imaginary parts buffer by buffer and assembles and writes out the complex input. <br />
<c><br />
for (nleft= (size_t) (rsize*resize); nleft > 0; nleft -= nbuf) {<br />
nbuf = (BUFSIZ < nleft)? BUFSIZ: nleft;<br />
sf_charread(rbuf,nbuf,real);<br />
sf_charread(ibuf,nbuf,imag);<br />
for (i=0; i < nbuf; i += resize) {<br />
memcpy(cbuf+2*i, rbuf+i,(size_t) resize);<br />
memcpy(cbuf+2*i+resize,ibuf+i,(size_t) resize);<br />
}<br />
sf_charwrite(cbuf,2*nbuf,cmplx);<br />
}<br />
</c><br />
<br />
==sfconjgrad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic conjugate-gradient solver for linear inversion <br />
|-<br />
! colspan="4" | sfconjgrad < dat.rsf mod=mod.rsf > to.rsf < from.rsf > out.rsf niter=1<br />
|-<br />
| ''int '' || '''niter=1''' || || number of iterations<br />
|}<br />
<br />
<tt>sfconjgrad</tt> is a generic program for least-squares linear<br />
inversion with the [http://en.wikipedia.org/wiki/Conjugate_gradient_method conjugate-gradient method]. Suppose you have an<br />
executable program <tt><prog></tt> that takes an RSF file from the<br />
standard input and produces an RSF file in the standard output. It may<br />
take any number of additional parameters but one of them must be<br />
<tt>adj=</tt> that sets the forward (<tt>adj=0</tt>) or adjoint<br />
(<tt>adj=1</tt>) operations. The program <tt><prog></tt> is typically<br />
an RSF program but it could be anything (a script, a multiprocessor<br />
MPI program, etc.) as long as it implements a linear operator<br />
<math>\mathbf{L}</math> and its adjoint. There are no restrictions on the data<br />
size or shape. You can easily test the adjointness with<br />
<tt>sfdottest</tt>. The <tt>sfconjgrad</tt> program searches for a<br />
vector <math>\mathbf{m}</math> that minimizes the least-square misfit <br />
<math>\|\mathbf{d - L\,m}\|^2</math> for the given input data vector <math>\mathbf{d}</math>. <br />
<br />
The pseudocode for <tt>sfconjgrad</tt> is given at the end of the [http://www.reproducibility.org/RSF/book/gee/lsq/paper.pdf "Model fitting with least squares" chapter] of ''Imaging Estimation by Example'' by Jon Claerbout, with the earliest form published in [http://sepwww.stanford.edu/data/media/public/oldreports/sep48/48_25.pdf "Conjugate Gradient Tutorial"] (SEP-48, 1986, same author). A simple toy implementation with a small matrix shows that this is algorithm produces the same steps as the algorithm described in equations 45-49 of [http://www.cs.cmu.edu/~quake-papers/painless-conjugate-gradient.pdf "An introduction to the Conjugate Gradient Method Without the Agonizing Pain"] by J.R. Shewchuk, 1994, when the equation <math>A^T A x = A^T b</math> (in Shewchuk's notation) is solved. Multiplying with the transpose ensures a correct solution even when matrix A is square but not symmetric, or not square at all. The program [http://www.reproducibility.org/RSF/sfcconjgrad.html sfcconjgrad] implements this algorithm for the case when inputs are complex.<br />
<br />
Here is an example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
The <tt>sfdottest</tt> program can perform the dot product test to<br />
check that the adjoint mode works correctly.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=5.28394<br />
sfdottest: L'[d]*m=5.28394<br />
</pre><br />
Your numbers may be different because <tt>sfdottest</tt> generates new<br />
random input on each run.<br />
Next, let us make some random data with <tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfnoise seed=2005 rep=y < vec.rsf > dat.rsf<br />
</pre><br />
and try to invert the filtering operation using <tt>sfconjgrad</tt>:<br />
<pre><br />
bash$ sfconjgrad sfhelicon filt=flt.rsf lag=lag.rsf \<br />
mod=vec.rsf < dat.rsf > mod.rsf niter=10<br />
sfconjgrad: iter 1 of 10<br />
sfconjgrad: grad=3253.65<br />
sfconjgrad: iter 2 of 10<br />
sfconjgrad: grad=289.421<br />
sfconjgrad: iter 3 of 10<br />
sfconjgrad: grad=92.3481<br />
sfconjgrad: iter 4 of 10<br />
sfconjgrad: grad=36.9417<br />
sfconjgrad: iter 5 of 10<br />
sfconjgrad: grad=18.7228<br />
sfconjgrad: iter 6 of 10<br />
sfconjgrad: grad=11.1794<br />
sfconjgrad: iter 7 of 10<br />
sfconjgrad: grad=7.26941<br />
sfconjgrad: iter 8 of 10<br />
sfconjgrad: grad=5.15945<br />
sfconjgrad: iter 9 of 10<br />
sfconjgrad: grad=4.23055<br />
sfconjgrad: iter 10 of 10<br />
sfconjgrad: grad=3.57495<br />
</pre><br />
The output shows that, in 10 iterations, the norm of the gradient vector decreases by almost 1000. <br />
We can check the residual misfit before<br />
<pre><br />
bash$ < dat.rsf sfattr want=norm<br />
norm value = 49.7801<br />
</pre><br />
and after<br />
<pre><br />
bash$ sfhelicon filt=flt.rsf lag=lag.rsf < mod.rsf | \<br />
sfadd scale=1,-1 dat.rsf | sfattr want=norm<br />
norm value = 5.73563<br />
</pre><br />
In 10 iterations, the misfit decreased by an order of magnitude. The<br />
result can be improved by running the program for more iterations.<br />
<br />
An equivalent implementation for complex-valued inputs is [http://www.reproducibility.org/RSF/sfcconjgrad.html sfcconjgrad]. A simple, lightweight Python implementation can be found in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/fomels/conjgrad.py?view=markup $RSFROOT/lib/conjgrad.py].<br />
<br />
==sfcp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Copy or move a dataset.<br />
|-<br />
! colspan="4" | sfcp in.rsf out.rsf<br />
|-<br />
| colspan="4" | sfcp - copy, sfmv - move.<br>Mimics standard Unix commands.<br />
|}<br />
<br />
<br />
The <tt>sfcp</tt> and <tt>sfmv</tt> command imitate the Unix<br />
<tt>cp</tt> and <tt>mv</tt> commands and serve for copying and moving<br />
RSF files. Example:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcp one.rsf two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cp.c?view=markup system/main/cp.c]====<br />
First, we look for the two first command-line arguments that don't<br />
have the "=" character in them and consider them as the names of the<br />
input and the output files. <br />
<c><br />
/* the first two non-parameters are in and out files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == in) {<br />
infile = argv[i];<br />
in = sf_input (infile);<br />
} else {<br />
out = sf_output (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == in || NULL == out)<br />
sf_error ("not enough input");<br />
</c><br />
<br />
Next, we use library functions <font color="#cd4b19">sf_cp</font> and <font color="#cd4b19">sf_rm</font> to do the actual work.<br />
<c><br />
sf_cp(in,out);<br />
if (NULL != strstr (sf_getprog(),"mv")) <br />
sf_rm(infile,false,false,false);<br />
</c><br />
<br />
==sfcut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of the dataset. <br />
|-<br />
! colspan="4" | sfcut < in.rsf > out.rsf verb=n [j1=1 j2=1 ... f1=0 f2=0 ... n1=n1 n2=n2 ... max1= max2= ... min1= min2= ...]<br />
|-<br />
| colspan="4" | jN defines the jump in N-th dimension<br>fN is the window start<br>nN is the window size<br>minN and maxN is the maximum and minimum in N-th dimension<br><br>Reverse of window. <br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
The <tt>sfcut</tt> command is related to <tt>sfwindow</tt> and has the same<br />
set of arguments only instead of extracting the selected window, it fills it<br />
with zeroes. The size of the input data is preserved. <br />
Examples:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > in.rsf<br />
bash$ < in.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < in.rsf sfcut n1=2 f1=1 n2=3 f2=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 0 0 1 1<br />
15: 1 0 0 1 1<br />
20: 1 0 0 1 1<br />
bash$ < in.rsf sfcut j1=2 | sfdisfil<br />
0: 0 1 0 1 0<br />
5: 0 1 0 1 0<br />
10: 0 1 0 1 0<br />
15: 0 1 0 1 0<br />
20: 0 1 0 1 0<br />
</pre><br />
<br />
==sfdd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert between different formats. <br />
|-<br />
! colspan="4" | sfdd < in.rsf > out.rsf line=8 form= type= format=<br />
|-<br />
| ''string '' || '''form=''' || || ascii, native, xdr<br />
|-<br />
| ''string '' || '''format=''' || || Element format (for conversion to ASCII)<br />
|-<br />
| ''int '' || '''line=8''' || || Number of numbers per line (for conversion to ASCII)<br />
|-<br />
| ''string '' || '''type=''' || || int, float, complex<br />
|}<br />
<br />
<br />
The <tt>sfdd</tt> program is used to change either the form (<tt>ascii</tt>,<br />
<tt>xdr</tt>, <tt>native</tt>) or the type (<tt>complex</tt>, <tt>float</tt>,<br />
<tt>int</tt>, <tt>char</tt>) of the input dataset. <br />
In the example below, we create a plain text (ASCII) file with numbers and<br />
then use <tt>sfdd</tt> to generate an RSF file in <tt>xdr</tt> form with<br />
<tt>complex</tt> numbers. <br />
<pre><br />
bash$ cat test.txt<br />
1 2 3 4 5 6<br />
bash$ echo n1=6 data_format=ascii_int in=test.txt > test.rsf<br />
bash$ sfin test.rsf<br />
test.rsf:<br />
in="test.txt"<br />
esize=0 type=int form=ascii<br />
n1=6 d1=? o1=?<br />
6 elements<br />
bash$ sfdd < test.rsf form=xdr type=complex > test2.rsf<br />
bash$ sfin test2.rsf<br />
test2.rsf:<br />
in="/tmp/test2.rsf@"<br />
esize=8 type=complex form=xdr<br />
n1=3 d1=? o1=?<br />
3 elements 24 bytes<br />
bash$ sfdisfil < test2.rsf<br />
0: 1, 2i 3, 4i 5, 6i<br />
</pre><br />
To learn more about the RSF data format, consult the [[Format| guide to RSF format]].<br />
<br />
==sfdisfil==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Print out data values.<br />
|-<br />
! colspan="4" | sfdisfil < in.rsf number=y col=0 format= header= trailer=<br />
|-<br />
| colspan="4" | <br>Alternatively, use sfdd and convert to ASCII form.<br />
|-<br />
| ''int '' || '''col=0''' || || Number of columns.<br />
:The default depends on the data type:<br />
:10 for int and char,<br />
:5 for float,<br />
:3 for complex<br />
|-<br />
| ''string '' || '''format=''' || || Format for numbers (printf-style).<br />
:The default depends on the data type:<br> "%4d " for int and char,<br> "%13.4g" for float,<br> "%10.4g,%10.4gi" for complex<br />
|-<br />
| ''string '' || '''header=''' || || Optional header string to output before data<br />
|-<br />
| ''bool '' || '''number=y''' || [y/n] || If number the elements<br />
|-<br />
| ''string '' || '''trailer=''' || || Optional trailer string to output after data<br />
|}<br />
<br />
<br />
The <tt>sfdisfil</tt> program simply dumps the data contents to the standard<br />
output in a text form. It is used mostly for debugging purposes to quickly<br />
examine RSF files. Here is an example:<br />
<pre><br />
bash$ sfmath o1=0 d1=2 n1=12 output=x1 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
10: 20 22<br />
</pre><br />
The output format is easily configurable.<br />
<pre><br />
bash$ < test.rsf sfdisfil col=6 number=n format="<br />
0.0 2.0 4.0 6.0 8.0 10.0<br />
12.0 14.0 16.0 18.0 20.0 22.0<br />
</pre><br />
Along with <tt>sfdd</tt>, <tt>sfdisfil</tt> provides a simple way to convert<br />
RSF data to an ASCII form.<br />
<br />
==sfdottest==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic dot-product test for linear operators with adjoints <br />
|-<br />
! colspan="4" | sfdottest mod=mod.rsf dat=dat.rsf > pip.rsf<br />
|}<br />
<br />
<br />
<tt>sfdottest</tt> is a generic dot-product test program for testing<br />
linear operators. Suppose there is an executable program<br />
<tt><prog></tt> that takes an RSF file from the standard input and<br />
produces an RSF file in the standard output. It may take any number of<br />
additional parameters but one of them must be <tt>adj=</tt> that sets<br />
the forward (<tt>adj=0</tt>) or adjoint (<tt>adj=1</tt>) operations.<br />
The program <tt><prog></tt> is typically an RSF program but it could<br />
be anything (a script, a multiprocessor MPI program, etc.) as long as<br />
it implements a linear operator <math>\mathbf{L}</math> and its adjoint<br />
<math>\mathbf{L}^T</math>. The <tt>sfdottest</tt> program is testing the equality<br />
<center><math><br />
d^T\,L\,m = m^T\,L^T\,d<br />
</math></center><br />
by using random vectors <math>\mathbf{m}</math> and <math>\mathbf{d}</math>. You can invoke it with<br />
<pre><br />
bash$ sfdottest <prog> [optional aruments] mod=mod.rsf dat=dat.rsf<br />
</pre><br />
where <tt>mod.rsf</tt> and <tt>dat.rsf</tt> are RSF files that<br />
represent vectors from the model and data spaces. Pay attention to the <br />
dimension and size of these vectors! If the program does not respond<br />
for a very long time, it is quite possible that the dimension and size<br />
of the vectors are inconsistent with the requirement of the program to be<br />
tested. <tt>sfdottest</tt><br />
does not create any temporary files and does not have any restrictive<br />
limitations on the size of the vectors.<br />
Here is an example. We first setup a vector with 100 elements using<br />
<tt>sfspike</tt> and then run <tt>sfdottest</tt> to test the<br />
<tt>sfcausint</tt> program. <tt>sfcausint</tt> implements a linear<br />
operator of causal integration and its adjoint, the anti-causal<br />
integration.<br />
<pre><br />
bash$ sfspike n1=100 > vec.rsf<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1410.2<br />
sfdottest: L'[d]*m=1410.2<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1165.87<br />
sfdottest: L'[d]*m=1165.87<br />
</pre><br />
The numbers are different on subsequent runs because of changing<br />
seed in the random number generator.<br />
Here is a somewhat more complicated example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
Now the <tt>sfdottest</tt> program can perform the dot product test.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=8.97375<br />
sfdottest: L'[d]*m=8.97375<br />
</pre><br />
Here is the same program tested in the inverse filtering mode:<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf inv=y<br />
sfdottest: L[m]*d=15.0222<br />
sfdottest: L'[d]*m=15.0222<br />
</pre><br />
<br />
==sfget==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Output parameters from the header.<br />
|-<br />
! colspan="4" | sfget < in.rsf parform=y par1 par2 ...<br />
|-<br />
| ''bool '' || '''parform=y''' || [y/n] || If y, print out parameter=value. If n, print out value.<br />
|}<br />
<br />
<br />
The <tt>sfget</tt> program extracts a parameter value from an RSF file. It is<br />
useful mostly for scripting. Here is, for example, a quick calculation of the<br />
maximum value on the first axis in an RSF dataset (the output of<br />
<tt>sfspike</tt>) using the standard Unix <tt>bc</tt> calculator.<br />
<pre><br />
bash$ ( sfspike n1=100 | sfget n1 d1 o1; echo "o1+(n1-1)*d1" ) | bc<br />
.396<br />
</pre><br />
See also <tt>sfput</tt>.<br />
<br />
<br />
<br />
==sfheadercut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheadercut mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array of size n2.<br />
|}<br />
<br />
<br />
<tt>sfheadercut</tt> is close to <tt>sfheaderwindow</tt> but instead<br />
of windowing the dataset, it fills the traces specified by the header<br />
mask with zeroes. The size of the input data is preserved.<br />
Here is an example of using <tt>sfheaderwindow</tt> for <br />
zeroing every other trace in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a mask with alternating ones and zeros using<br />
<tt>sfinterleave</tt>.<br />
<pre><br />
bash$ sfspike n1=5 mag=1 | sfdd type=int > ones.rsf<br />
bash$ sfspike n1=5 mag=0 | sfdd type=int > zeros.rsf<br />
bash$ sfinterleave axis=1 ones.rsf zeros.rsf > mask.rsf<br />
bash$ sfdisfil < mask.rsf<br />
0: 1 0 1 0 1 0 1 0 1 0<br />
</pre><br />
Finally, <tt>sfheadercut</tt> zeros the input traces.<br />
<pre><br />
bash$ sfheadercut < input.rsf mask=mask.rsf > output.rsf<br />
bash$ sfdisfil < output.rsf <br />
0: 1 1 1 1 1<br />
5: 0 0 0 0 0<br />
10: 3 3 3 3 3<br />
15: 0 0 0 0 0<br />
20: 5 5 5 5 5<br />
25: 0 0 0 0 0<br />
30: 7 7 7 7 7<br />
35: 0 0 0 0 0<br />
40: 9 9 9 9 9<br />
45: 0 0 0 0 0<br />
</pre><br />
<br />
<br />
<br />
==sfheadersort==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Sort a dataset according to a header key. <br />
|-<br />
! colspan="4" | sfheadersort < in.rsf > out.rsf head=<br />
|-<br />
| ''string '' || '''head=''' || || header file<br />
|}<br />
<br />
<br />
<tt>sfheadersort</tt> is used to sort traces in the input file<br />
according to trace header information. <br />
Here is an example of using<br />
<tt>sfheadersort</tt> for randomly shuffling traces in the input<br />
file. First, let us create an input file with seven traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=7 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7 <br />
</pre><br />
Next, we can create a random file with seven header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=7 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: 0.05256 -0.2879 0.1487 0.4097 0.1548<br />
5: 0.4501 0.2836<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally, we<br />
apply <tt>sfheadersort</tt> to shuffle the input traces.<br />
<pre><br />
bash$ < input.rsf sfheadersort head=random.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 1 1 1 1 1<br />
10: 3 3 3 3 3<br />
15: 5 5 5 5 5<br />
20: 7 7 7 7 7<br />
25: 4 4 4 4 4<br />
30: 6 6 6 6 6<br />
</pre><br />
As expected, the order of traces in the output file corresponds to the<br />
order of values in the header. Thanks to the separation between<br />
headers and data, the operation of <tt>sfheadersort</tt> is optimally<br />
efficient. It first sorts the headers and only then accesses the data,<br />
reading each data trace only once.<br />
<br />
==sfheaderwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheaderwindow mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array os size n2, windowed is n1xm2,<br>where m2 is the number of nonzero elements in mask.<br />
|}<br />
<br />
<br />
<tt>sfheaderwindow</tt> is used to window traces in the input file<br />
according to trace header information. <br />
Here is an example of using <tt>sfheaderwindow</tt> for randomly<br />
selecting part of the traces in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a random file with ten header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=10 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: -0.005768 0.02258 -0.04331 -0.4129 -0.3909<br />
5: -0.03582 0.4595 -0.3326 0.498 -0.3517<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally,<br />
we apply <tt>sfheaderwindow</tt> to window the input traces selecting<br />
only those for which the header is greater than zero.<br />
<pre><br />
bash$ < random.rsf sfmask min=0 > mask.rsf<br />
bash$ < mask.rsf sfdisfil<br />
0: 0 1 0 0 0 0 1 0 1 0<br />
bash$ < input.rsf sfheaderwindow mask=mask.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 7 7 7 7 7<br />
10: 9 9 9 9 9<br />
</pre><br />
In this case, only three traces are selected for the output. Thanks to<br />
the separation between headers and data, the operation of<br />
<tt>sfheaderwindow</tt> is optimally efficient. <br />
<br />
==sfin==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display basic information about RSF files.<br />
|-<br />
! colspan="4" | sfin info=y check=2. trail=y file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | n1,n2,... are data dimensions<br>o1,o2,... are axis origins<br>d1,d2,... are axis sampling intervals<br>label1,label2,... are axis labels<br>unit1,unit2,... are axis units<br />
|-<br />
| ''float '' || '''check=2.''' || || Portion of the data (in Mb) to check for zero values.<br />
|-<br />
| ''bool '' || '''info=y''' || [y/n] || If n, only display the name of the data file.<br />
|-<br />
| ''bool '' || '''trail=y''' || [y/n] || If n, skip trailing dimensions of one<br />
|}<br />
<br />
<br />
<tt>sfin</tt> is one of the most useful programs for operating with<br />
RSF files. It produces quick information on the file hypercube<br />
dimensions and checks the consistency of the associated data file.<br />
Here is an example. Let us create an RSF file and examine it with <tt>sfin</tt>.<br />
<pre><br />
bash$ sfspike n1=100 n2=20 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=100 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
2000 elements 8000 bytes<br />
</pre><br />
<tt>sfin</tt> reports the following information:<br />
<br />
*location of the data file (<tt>/tmp/spike.rsf\@</tt>) <br />
*element size (4 bytes) <br />
*element type (floating point) <br />
*element form (native) <br />
*hypercube dimensions (100 by 20) <br />
*axes scale (0.004 and 0.1) <br />
*axes origin (0 and 0) <br />
*axes labels <br />
*axes units <br />
*total number of elements <br />
*total number of bytes in the data file <br />
Suppose that the file got corrupted by a buggy program and reports<br />
incorrect dimensions. The <tt>sfin</tt> program should be able to<br />
catch the discrepancy.<br />
<pre><br />
bash$ echo n2=100 >> spike.rsf<br />
bash$ sfin spike.rsf > /dev/null<br />
sfin: Actually 8000 bytes, 20% of expected.<br />
</pre><br />
<tt>sfin</tt> also checks the first records in the file for zeros. <br />
<pre><br />
bash$ sfspike n1=100 n2=100 k2=99 > spike2.rsf<br />
bash$ sfin spike2.rsf >/dev/null<br />
sfin: The first 32768 bytes are all zeros<br />
</pre><br />
The number of bytes to check is adjustable<br />
<pre><br />
bash$ sfin spike2.rsf check=0.01 >/dev/null<br />
sfin: The first 16384 bytes are all zeros<br />
</pre><br />
You can also output only the location of the data file. This is<br />
sometimes handy in scripts.<br />
<pre><br />
bash$ sfin spike.rsf spike2.rsf info=n<br />
/tmp/spike.rsf@ /tmp/spike2.rsf@<br />
</pre><br />
An alternative is to use <tt>sfget</tt>, as follows:<br />
<pre><br />
bash$ sfget parform=n in < spike.rsf<br />
/tmp/spike.rsf@<br />
</pre><br />
<br />
==sfinterleave==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Combine several datasets by interleaving.<br />
|-<br />
! colspan="4" | sfinterleave > out.rsf axis=3 [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis for interleaving<br />
|}<br />
<br />
<br />
<tt>sfinterleave</tt> combines two or more datasets by interleaving them on one<br />
of the axes. Here is a quick example:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ sfscale < one.rsf dscale=2 > two.rsf<br />
bash$ sfdisfil < two.rsf<br />
0: 2 2 2 2 2<br />
5: 2 2 2 2 2<br />
10: 2 2 2 2 2<br />
15: 2 2 2 2 2<br />
20: 2 2 2 2 2<br />
bash$ sfinterleave one.rsf two.rsf axis=1 | sfdisfil<br />
0: 1 2 1 2 1<br />
5: 2 1 2 1 2<br />
10: 1 2 1 2 1<br />
15: 2 1 2 1 2<br />
20: 1 2 1 2 1<br />
25: 2 1 2 1 2<br />
30: 1 2 1 2 1<br />
35: 2 1 2 1 2<br />
40: 1 2 1 2 1<br />
45: 2 1 2 1 2<br />
bash$ sfinterleave < one.rsf two.rsf axis=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 1 1 1 1 1<br />
15: 2 2 2 2 2<br />
20: 1 1 1 1 1<br />
25: 2 2 2 2 2<br />
30: 1 1 1 1 1<br />
35: 2 2 2 2 2<br />
40: 1 1 1 1 1<br />
45: 2 2 2 2 2<br />
</pre><br />
<br />
==sfmask==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a mask.<br />
|-<br />
! colspan="4" | sfmask < in.rsf > out.rsf min=-FLT_MAX max=+FLT_MAX<br />
|-<br />
| colspan="4" | <br>Mask is an integer data with ones and zeros. <br>Ones correspond to input values between min and max.<br><br>The output can be used with sfheaderwindow.<br />
|-<br />
| ''float '' || '''max=+FLT_MAX''' || || maximum header value<br />
|-<br />
| ''float '' || '''min=-FLT_MAX''' || || minimum header value<br />
|}<br />
<br />
<br />
<tt>sfmask</tt> creates an integer output of ones and zeros comparing<br />
the values of the input data to specified <tt>min=</tt> and<br />
<tt>max=</tt> parameters. It is useful for <tt>sfheaderwindow</tt> and<br />
in many other applications. Here is a quick example:<br />
<pre><br />
bash$ sfmath n1=10 output="sin(x1)" > sin.rsf<br />
bash$ < sin.rsf sfdisfil<br />
0: 0 0.8415 0.9093 0.1411 -0.7568<br />
5: -0.9589 -0.2794 0.657 0.9894 0.4121<br />
bash$ < sin.rsf sfmask min=-0.5 max=0.5 | sfdisfil<br />
0: 1 0 0 1 0 0 1 0 0 1<br />
</pre><br />
<br />
==sfmath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations on data files.<br />
|-<br />
! colspan="4" | sfmath > out.rsf type= unit= output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs, conj (for complex data).<br> <br>sfmath will work on float or complex data, but all the input and output<br>files must be of the same data type.<br><br>An alternative to sfmath is sfadd, which may be more efficient, but is<br>less versatile.<br><br>Examples:<br><br>sfmath x=file1.rsf y=file2.rsf power=file3.rsf output='sin((x+2*y)^power)' > out.rsf<br>sfmath < file1.rsf tau=file2.rsf output='exp(tau*input)' > out.rsf<br>sfmath n1=100 type=complex output="exp(I*x1)" > out.rsf<br><br>See also: sfheadermath.<br />
|-<br />
| ''string '' || '''output=''' || || Mathematical description of the output<br />
|-<br />
| ''string '' || '''type=''' || || output data type [float,complex]<br />
|-<br />
| ''string '' || '''unit=''' || || <br />
|}<br />
<br />
<tt>sfmath</tt> is a versatile program for mathematical operations<br />
with RSF files. It can operate with several input file, all of the<br />
same dimensions and data type. The data type can be real (floating<br />
point) or complex. Here is an example that demonstrates several<br />
features of <tt>sfmath</tt>.<br />
<pre><br />
bash$ sfmath n1=629 d1=0.01 o1=0 n2=40 d2=1 o2=5 \<br />
output="x2*(8+sin(6*x1+x2/10))" > rad.rsf<br />
bash$ < rad.rsf sfrtoc | sfmath output="input*exp(I*x1)" > rose.rsf<br />
bash$ < rose.rsf sfgraph title=Rose screenratio=1 wantaxis=n | sfpen<br />
</pre><br />
The first line creates a 2-D dataset that consists of 40 traces 600<br />
samples each. The values of the data are computed with the formula<br />
<font color="#cd4b19">"x2*(8+sin(6*x1+x2/10))"</font>, where <tt>x1</tt> refers to the<br />
coordinate on the first axis, and <tt>x2</tt> is the coordinate of the<br />
second axis. In the second line, we convert the data from real to<br />
complex using <tt>sfrtoc</tt> and produce a complex dataset using<br />
formula <font color="#cd4b19">"input*exp(I*x1)"</font>, where <tt>input</tt> refers to the<br />
input file. Finally, we plot the complex data as a collection of<br />
parametric curves using <tt>sfgraph</tt> and display the result using<br />
<tt>sfpen</tt>. The plot appearing on your screen should look similar<br />
to the figure.<br />
[[Image:rose.png|frame|center|This figure was created with <tt>sfmath</tt>.]]<br />
One possible alternative to the second line above is<br />
<pre><br />
bash$ < rad.rsf sfmath output=x1 > ang.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*cos(a)" > cos.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*sin(a)" > sin.rsf<br />
bash$ sfcmplx cos.rsf sin.rsf > rose.rsf<br />
</pre><br />
Here we refer to input files by names (<tt>r</tt> and <tt>a</tt>) and combine the names in a formula.<br />
<br />
==sfpad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Pad a dataset with zeros.<br />
|-<br />
! colspan="4" | sfpad < in.rsf > out.rsf [beg1= beg2= ... end1= end2=... | n1= n2 = ... | n1out= n2out= ...]<br />
|-<br />
| colspan="4" | begN specifies the number of zeros to add before the beginning of axis N.<br>endN specifies the number of zeros to add after the end of axis N.<br><br>Alternatively:<br><br>nN or nNout specify the output length of axis N, padding occurs at the end.<br>nN and nNout are equivalent.<br />
|}<br />
<br />
<br />
<tt>pad</tt> increases the dimensions of the input dataset by padding<br />
the data with zeroes. Here are some simple examples.<br />
<pre><br />
bash$ sfspike n1=5 n2=3 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
bash$ < one.rsf sfpad n2=5 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 0 0 0 0 0<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfpad beg2=2 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 0 0 0 0<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < one.rsf sfpad beg2=1 end2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfwindow n1=3 | sfpad n1=5 n2=5 beg1=1 beg2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 1 1 1 0<br />
10: 0 1 1 1 0<br />
15: 0 1 1 1 0<br />
20: 0 0 0 0 0<br />
</pre><br />
You can use <tt>sfcat</tt> to pad data with values other than zeroes.<br />
<br />
==sfput==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Input parameters into a header. <br />
|-<br />
! colspan="4" | sfput < in.rsf > out.rsf<br />
|}<br />
<br />
<br />
<tt>sfput</tt> is a very simple program. It simply appends parameters<br />
from the command line to the output RSF file. One can achieve similar<br />
results with editing by hand or with standard Unix utilities like<br />
<tt>sed</tt> and <tt>echo</tt>. <tt>sfput</tt> is sometimes more<br />
convenient because it handles input/output operations similarly to<br />
other regular RSF programs.<br />
<pre><br />
bash$ sfspike n1=10 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
10 elements 40 bytes<br />
bash$ sfput < spike.rsf d1=25 label1=Depth unit1=m > spike2.rsf<br />
bash$ sfin spike2.rsf<br />
spike2.rsf:<br />
in="/tmp/spike2.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=25 o1=0 label1="Depth" unit1="m"<br />
10 elements 40 bytes<br />
</pre><br />
<br />
==sfreal==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extract real (sfreal) or imaginary (sfimag) part of a complex dataset. <br />
|-<br />
! colspan="4" | sfreal < cmplx.rsf > real.rsf<br />
|}<br />
<br />
<br />
<tt>sfreal</tt> extracts the real part of a complex type dataset. The<br />
imaginary part can be extracted with <tt>sfimag</tt>, an the real<br />
and imaginary part can be combined together with <tt>sfcmplx</tt>.<br />
Here is a simple example. Let us first create a complex dataset <br />
with <tt>sfmath</tt><br />
<pre><br />
bash$ sfmath n1=10 type=complex output="(2+I)*x1" > cmplx.rsf<br />
bash$ fdisfil < cmplx.rsf<br />
0: 0, 0i 2, 1i 4, 2i<br />
3: 6, 3i 8, 4i 10, 5i<br />
6: 12, 6i 14, 7i 16, 8i<br />
9: 18, 9i<br />
</pre><br />
Extracting the real part with <tt>sfreal</tt>:<br />
<pre><br />
bash$ sfreal < cmplx.rsf | sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
</pre><br />
Extracting the imaginary part with <tt>sfimag</tt>:<br />
<pre><br />
bash$ sfimag < cmplx.rsf | sfdisfil<br />
0: 0 1 2 3 4<br />
5: 5 6 7 8 9<br />
</pre><br />
<br />
==sfreverse==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Reverse one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfreverse < in.rsf > out.rsf which=-1 verb=false memsize=sf_memsize() opt=<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''opt=''' || || If y, change o and d parameters on the reversed axis;<br />
:if i, don't change o and d<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|-<br />
| ''int '' || '''which=-1''' || || Which axis to reverse.<br />
:To reverse a given axis, start with 0,<br />
:add 1 to number to reverse n1 dimension,<br />
:add 2 to number to reverse n2 dimension,<br />
:add 4 to number to reverse n3 dimension, etc.<br />
:Thus, which=7 would reverse the first three dimensions,<br />
:which=5 just n1 and n3, etc.<br />
:which=0 will just pass the input on through unchanged.<br />
|}<br />
Here is an example of using <tt>sfreverse</tt>. First, let us create a<br />
2-D dataset.<br />
<pre><br />
bash$ sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Reversing the first axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 | sfdisfil<br />
0: 4 3 2 1 0<br />
5: 5 4 3 2 1<br />
10: 6 5 4 3 2<br />
</pre><br />
Reversing the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=2 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
Reversing both the first and the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=3 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
As you can see, the <tt>which=</tt> parameter controls the axes that are<br />
being reversed by encoding them into one number.<br />
When an axis is reversed, what happens with its axis origin and<br />
sampling parameters? This behavior is controlled by <tt>opt=</tt>. In<br />
our example,<br />
<pre><br />
bash$ < test.rsf sfget n1 o1 d1<br />
n1=5<br />
o1=0<br />
d1=1<br />
bash$ < test.rsf sfreverse which=1 | sfget o1 d1<br />
o1=4<br />
d1=-1<br />
</pre><br />
The default behavior (equivalent to <tt>opt=y</tt>) puts the origin<br />
<tt>o1</tt> at the end of the axis and reverses the sampling parameter<br />
<tt>d1</tt>. Using <tt>opt=n</tt> preserves the sampling but reverses<br />
the origin.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=n | sfget o1 d1<br />
o1=-4<br />
d1=1<br />
</pre><br />
Using <tt>opt=i</tt> preserves both the sampling and the origin while<br />
reversing the axis.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=i | sfget o1 d1<br />
o1=0<br />
d1=1<br />
</pre><br />
One of the three possible behaviors may be desirable depending on the<br />
application.<br />
<br />
==sfrm==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Remove RSF files together with their data.<br />
|-<br />
! colspan="4" | sfrm file1.rsf [file2.rsf ...] [-i] [-v] [-f] <br />
|-<br />
| colspan="4" | Mimics the standard Unix rm command.<br><br>See also: sfmv, sfcp.<br />
|}<br />
<br />
<tt>sfrm</tt> is a program for removing RSF files. Its arguments mimic<br />
the arguments of the standard Unix <tt>rm</tt> utility: <tt>-v</tt><br />
for verbosity, <tt>-i</tt> for interactive inquiry, <tt>-f</tt> for<br />
force removal of suspicious files. Unlike the Unix <tt>rm</tt>,<br />
<tt>sfrm</tt> removes both the RSF header files and the binary files<br />
that the headers point to. <br />
Example:<br />
<pre><br />
bash&#36; sfspike n1=10 > spike.rsf datapath=./<br />
bash&#36; sfget in < spike.rsf<br />
in=./spike.rsf@<br />
bash&#36; ls spike*<br />
spike.rsf spike.rsf@<br />
bash&#36; sfrm -v spike.rsf<br />
sfrm: sf_rm: Removing header spike.rsf<br />
sfrm: sf_rm: Removing data ./spike.rsf@<br />
bash&#36; ls spike*<br />
ls: No match.<br />
</pre><br />
==sfrotate==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Rotate a portion of one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfrotate < in.rsf > out.rsf verb=n memsize=sf_memsize() rot#=(0,0,...)<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''rot#=(0,0,...)''' || || length of #-th axis that is moved to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<tt>sfrotate</tt> modifies the input dataset by splitting it into<br />
parts and putting the parts back in a different order. Here is a quick example.<br />
<pre><br />
bash&#36; sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Rotating the first axis by putting the last two columns in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=2 | sfdisfil<br />
0: 3 4 0 1 2<br />
5: 4 5 1 2 3<br />
10: 5 6 2 3 4<br />
</pre><br />
Rotating the second axis by putting the last row in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot2=1 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 0 1 2 3 4<br />
10: 1 2 3 4 5<br />
</pre><br />
Rotating both the first and the second axis:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=3 rot2=1 | sfdisfil<br />
0: 4 5 6 2 3<br />
5: 2 3 4 0 1<br />
10: 3 4 5 1 2<br />
</pre><br />
The transformation is shown schematically in Figure~(fig:rotate).<br />
[[Image:rotate.png|frame|center|Schematic transformation of data with <tt>sfrotate</tt>.]]<br />
<br />
==sfrtoc==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert real data to complex (by adding zero imaginary part).<br />
|-<br />
! colspan="4" | sfrtoc < real.rsf > cmplx.rsf<br />
|-<br />
| colspan="4" | <br>See also: sfcmplx<br />
|}<br />
The input to <tt>sfrtoc</tt> can be any <tt>type=float</tt> dataset:<br />
<pre><br />
bash$ sfspike n1=10 n2=20 n3=30 >real.rsf<br />
bash$ sfin real.rsf<br />
real.rsf:<br />
in="/var/tmp/real.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
</pre><br />
The output dataset will have <tt>type=complex</tt>, and its binary will be twice the size of the input:<br />
<pre><br />
bash$ <real.rsf sfrtoc >complex.rsf<br />
bash$ sfin complex.rsf <br />
complex.rsf:<br />
in="/var/tmp/complex.rsf@"<br />
esize=8 type=complex form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 48000 bytes<br />
</pre><br />
<br />
==sfscale==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Scale data.<br />
|-<br />
! colspan="4" | sfscale < in.rsf > out.rsf axis=0 rscale=0. dscale=1.<br />
|-<br />
| colspan="4" | <br>To scale by a constant factor, you can also use sfmath or sfheadermath.<br />
|-<br />
| ''int '' || '''axis=0''' || || Scale by maximum in the dimensions up to this axis.<br />
|-<br />
| ''float '' || '''dscale=1.''' || || Scale by this factor (works if rscale=0)<br />
|-<br />
| ''float '' || '''rscale=0.''' || || Scale by this factor.<br />
|}<br />
<tt>sfscale</tt> scales the input dataset by a factor. Here<br />
are some simple examples. First, let us create a test dataset.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil <br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Scale every data point by 2:<br />
<pre><br />
bash&#36; < test.rsf sfscale dscale=2 | sfdisfil<br />
0: 2 4 6 8 10<br />
5: 4 8 12 16 20<br />
10: 6 12 18 24 30<br />
</pre><br />
Divide every trace by its maximum value:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=1 | sfdisfil<br />
0: 0.2 0.4 0.6 0.8 1<br />
5: 0.2 0.4 0.6 0.8 1<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
Divide by the maximum value in the whole 2-D dataset:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=2 | sfdisfil<br />
0: 0.06667 0.1333 0.2 0.2667 0.3333<br />
5: 0.1333 0.2667 0.4 0.5333 0.6667<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
The <tt>rscale=</tt> parameter is synonymous to <tt>dscale=</tt> except<br />
when it is equal to zero. With <tt>sfscale dscale=0</tt>, the dataset gets<br />
multiplied by zero. If using <tt>rscale=0</tt>, the other parameters are<br />
used to define scaling. Thus, <tt>sfscale rscale=0 axis=1</tt> is<br />
equivalent to <tt>sfscale axis=1</tt>, and <tt>sfscale rscale=0</tt><br />
is equivalent to <tt>sfscale dscale=1</tt>.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
==sfspike==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate simple data: spikes, boxes, planes, constants.<br />
|-<br />
! colspan="4" | sfspike > spike.rsf mag= nsp=1 k#=[0,...] l#=[k1,k2,...] p#=[0,...] n#= o#=(0,...) d#=(0.004,0.1,0.1,...) label#=(Time,Distance,Distance,...) unit#=[s,km,km,...] title=<br />
|-<br />
| ''float '' || '''d#=(0.004,0.1,0.1,...)''' || || sampling on #-th axis<br />
|-<br />
| ''ints '' || '''k#=[0,...]''' || || spike starting position [nsp]<br />
|-<br />
| ''ints '' || '''l#=[k1,k2,...]''' || || spike ending position [nsp]<br />
|-<br />
| ''string '' || '''label#=(Time,Distance,Distance,...)''' || || label on #-th axis<br />
|-<br />
| ''floats '' || '''mag=''' || || spike magnitudes [nsp]<br />
|-<br />
| ''int '' || '''n#=''' || || dimension of #-th axis<br />
|-<br />
| ''int '' || '''nsp=1''' || || Number of spikes<br />
|-<br />
| ''float '' || '''o#=(0,...)''' || || origin on #-th axis<br />
|-<br />
| ''floats '' || '''p#=[0,...]''' || || spike inclination (in samples) [nsp]<br />
|-<br />
| ''string '' || '''title=''' || || title for plots<br />
|-<br />
| ''string '' || '''unit#=[s,km,km,...]''' || || unit on #-th axis<br />
|}<br />
This is the program for creating a RSF hypercube out of nothing. Calling <tt>sfspike</tt> without specifying the k# or l# parameters will result in a volume filled with values specified by <tt>mag</tt>. To get a file full of 1's, just give <tt>sfspike</tt> the axis values that running <tt>sfin</tt> on your desired output would produce. I.e. if you run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" > out.rsf<br />
</pre><br />
you will obtain the following file:<br />
<pre><br />
bash$ sfin out.rsf<br />
out.rsf:<br />
in="/var/tmp/out.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
300 elements 1200 bytes<br />
</pre><br />
To create a "flat reflector" in the file above, run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5> out2.rsf<br />
</pre><br />
Notice that the values for <tt>k</tt> and <tt>l</tt> are in samples, not in the physical units of the respective axes. The result can be visualised with <br />
<pre><br />
< out2.rsf sfgrey pclip=100 wantscalebar=y title="Illustration of k,l parameters" | xtpen<br />
</pre><br />
which produces the following plot:<br />
<br />
[[Image:sfspike_fig1.png]]<br />
<br />
The <tt>p</tt> parameters can be used to create slanted lines/planes. Specifying <tt>p2=1</tt> means that for each lateral step, the spike will be shifted down with 1 sample. Below is the command and the corresponding graphical output it creates:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=1 |\<br />
sfgrey pclip=100 wantscalebar=y title="Effect of p2=1" | xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig2.png]]<br />
<br />
Sfspike also supports negative and non-integer p values:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=-0.15 |\<br />
sfgrey pclip=100 wantscalebar=y allpos=y color=h title="Effect of p2=-0.15" |xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig3.png]]<br />
<br />
When <tt>nsp</tt> is greater than the number of values for <tt>k</tt> and <tt>l</tt> parameters, the extra spikes will be piled on top of the last one, increasing its amplitude. Look at the amplitude of the last event in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=3 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
and in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=5 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
(pictures coming soon). This feature can easily cause a bug when the number of events is large and they have not been properly counted, or when a new spike was added on a list but <tt>nsp</tt> was not updated.<br />
<br />
==sfspray==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extend a dataset by duplicating in the specified axis dimension.<br />
|-<br />
! colspan="4" | sfspray < in.rsf > out.rsf axis=2 n= d= o= label= unit=<br />
|-<br />
| colspan="4" | This operation is adjoint to sfstack.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to spray<br />
|-<br />
| ''float '' || '''d=''' || || Sampling of the newly created dimension<br />
|-<br />
| ''string '' || '''label=''' || || Label of the newly created dimension<br />
|-<br />
| ''int '' || '''n=''' || || Size of the newly created dimension<br />
|-<br />
| ''float '' || '''o=''' || || Origin of the newly created dimension<br />
|-<br />
| ''string '' || '''unit=''' || || Units of the newly created dimension<br />
|}<br />
<br />
<tt>sfspray</tt> extends the input hypercube by replicating the data<br />
in one of the dimensions. The output dataset acquires one additional<br />
dimension. Here is an example:<br />
Start with a 2-D dataset<br />
<pre><br />
bash&#36; sfmath n1=5 n2=2 output=x1+x2 > test.rsf<br />
bash&#36; sfin test.rsf<br />
test.rsf:<br />
in="/var/tmp/test.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
10 elements 40 bytes<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
</pre><br />
Extend the data in the second dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=2 n=3 > test2.rsf<br />
bash&#36; sfin test2.rsf<br />
test2.rsf:<br />
in="/var/tmp/test2.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=3 d2=1 o2=0 <br />
n3=2 d3=1 o3=0 <br />
30 elements 120 bytes<br />
bash&#36; < test2.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 0 1 2 3 4<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
20: 1 2 3 4 5<br />
25: 1 2 3 4 5<br />
</pre><br />
The output is three-dimensional, with traces from the original<br />
data duplicated along the second axis.<br />
Extend the data in the third dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=3 n=2 > test3.rsf<br />
bash&#36; sfin test3.rsf<br />
test3.rsf:<br />
in="/var/tmp/test3.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
n3=2 d3=? o3=? <br />
20 elements 80 bytes<br />
bash&#36; < test3.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
</pre><br />
The output is also three-dimensional, with the original data replicated<br />
along the third axis.<br />
<br />
==sfstack==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stack a dataset over one of the dimensions.<br />
|-<br />
! colspan="4" | sfstack < in.rsf > out.rsf axis=2 rms=n norm=y min=n max=n<br />
|-<br />
| colspan="4" | <br>This operation is adjoint to sfspray.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to stack<br />
|-<br />
| ''bool '' || '''max=n''' || [y/n] || If y, find maximum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''min=n''' || [y/n] || If y, find minimum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || If y, normalize by fold.<br />
|-<br />
| ''bool '' || '''rms=n''' || [y/n] || If y, compute the root-mean-square instead of stack.<br />
|}<br />
While <tt>sfspray</tt> adds a dimension to a hypercube,<br />
<tt>sfstack</tt> effectively removes one of the dimensions by stacking<br />
over it. Here are some examples:<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
bash&#36; < test.rsf sfstack axis=2 | sfdisfil<br />
0: 1.5 2 3 4 5<br />
bash&#36; < test.rsf sfstack axis=1 | sfdisfil<br />
0: 2.5 3 4<br />
</pre><br />
Why is the first value not 1 (in the first case) or 2 (in the second<br />
case)? By default, <tt>sfstack</tt> normalizes the stack by the fold<br />
(the number of non-zero entries). To avoid normalization, use<br />
<tt>norm=n</tt>, as follows:<br />
<pre><br />
bash&#36; < test.rsf sfstack norm=n | sfdisfil <br />
0: 3 6 9 12 15<br />
</pre><br />
<tt>sfstack</tt> can also compute root-mean-square values as <br />
well as minimum and maximum values.<br />
<pre><br />
bash&#36; < test.rsf sfstack rms=y | sfdisfil<br />
0: 1.581 2.16 3.109 4.082 5.066<br />
bash&#36; < test.rsf sfstack min=y | sfdisfil<br />
0: 0 1 2 3 4<br />
bash&#36; < test.rsf sfstack axis=1 max=y | sfdisfil <br />
0: 4 5 6<br />
</pre><br />
<br />
==sftransp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Transpose two axes in a dataset. <br />
|-<br />
! colspan="4" | sftransp < in.rsf > out.rsf memsize=sf_memsize() plane=<br />
|-<br />
| colspan="4" | <br>If you get a "Cannot allocate memory" error, give the program a<br>memsize=1 command-line parameter to force out-of-core operation.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''plane=''' || || Two-digit number with axes to transpose. The default is 12<br />
|}<br />
<br />
The <tt>sftransp</tt> program transposes the input hypercube<br />
exchanging the two axes specified by the <b>plane=</b> parameter. <br />
<pre><br />
bash&#36; sfspike n1=10 n2=20 n3=30 > orig123.rsf<br />
bash&#36; sfin orig123.rsf <br />
orig123.rsf:<br />
in="/var/tmp/orig123.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=23 >out132.rsf<br />
bash&#36; sfin out132.rsf <br />
out132.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=20 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=13 >out321.rsf<br />
bash&#36; sfin out321.rsf <br />
out321.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=30 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=10 d3=0.004 o3=0 label3="Time" unit3="s" <br />
6000 elements 24000 bytes<br />
</pre><br />
<tt>sftransp</tt> tries to fit the dataset in memory to transpose it<br />
there but, if not enough memory is available, it performs a slower<br />
transpose out of core using disk operations. You can control the<br />
amount of available memory using the <b>memsize=</b> parameter or<br />
the <b>RSFMEMSIZE</b> environmental variable.<br />
<br />
==sfwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a portion of the dataset. <br />
|-<br />
! colspan="4" | sfwindow < in.rsf > out.rsf verb=n squeeze=y j#=(1,...) d#=(d1,d2,...) f#=(0,...) min#=(o1,o2,,...) n#=(0,...) max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)<br />
|-<br />
| ''float '' || '''d#=(d1,d2,...)''' || || sampling in #-th dimension<br />
|-<br />
| ''int '' || '''f#=(0,...)''' || || window start in #-th dimension<br />
|-<br />
| ''int '' || '''j#=(1,...)''' || || jump in #-th dimension<br />
|-<br />
| ''float '' || '''max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)''' || || maximum in #-th dimension<br />
|-<br />
| ''float '' || '''min#=(o1,o2,,...)''' || || minimum in #-th dimension<br />
|-<br />
| ''int '' || '''n#=(0,...)''' || || window size in #-th dimension<br />
|-<br />
| ''bool '' || '''squeeze=y''' || [y/n] || if y, squeeze dimensions equal to 1 to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
<b>sfwindow</b> is used to window a portion of the dataset. Here is<br />
a quick example: Start by creating some data.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Now window the first two rows:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n2=2 | sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
</pre><br />
Window the first three columns:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n1=3 | sfdisfil<br />
0: 1 2 3 2 4<br />
5: 6 3 6 9<br />
</pre><br />
Window the middle row:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f2=1 n2=1 | sfdisfil<br />
0: 2 4 6 8 10<br />
</pre><br />
You can interpret the <b>f#</b> and <b>n#</b> parameters as<br />
meaning "skip that many rows/columns" and "select that many<br />
rows/columns" correspondingly. Window the middle point in the dataset:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f1=2 n1=1 f2=1 n2=1 | sfdisfil<br />
0: 6<br />
</pre><br />
Window every other column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=2 | sfdisfil<br />
0: 1 3 5 2 6<br />
5: 10 3 9 15<br />
</pre><br />
Window every third column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=3 | sfdisfil<br />
0: 1 4 2 8 3<br />
5: 12<br />
</pre><br />
Alternatively, <b>sfwindow</b> can use the minimum and maximum<br />
parameters to select a window. In the following example, we are<br />
creating a dataset with <b>sfspike</b> and then windowing a portion of it<br />
between 1 and 2 seconds in time and sampled at 8 miliseconds.<br />
<pre><br />
bash&#36; sfspike n1=1000 n2=10 > spike.rsf <br />
bash&#36; sfin spike.rsf<br />
spike.rsf:<br />
in="/var/tmp/spike.rsf@"<br />
esize=4 type=float form=native <br />
n1=1000 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10000 elements 40000 bytes<br />
bash&#36; < spike.rsf sfwindow min1=1 max1=2 d1=0.008 > window.rsf<br />
bash&#36; sfin window.rsf<br />
window.rsf:<br />
in="/var/tmp/window.rsf@"<br />
esize=4 type=float form=native <br />
n1=126 d1=0.008 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
1260 elements 5040 bytes<br />
</pre><br />
By default, <b>sfwindow</b> "squeezes" the hypercube dimensions<br />
that are equal to one toward the end of the dataset. Here is an<br />
example of taking a time slice:<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=1 d2=0.004 o2=1 label2="Time" unit2="s" <br />
10 elements 40 bytes<br />
</pre><br />
You can change this behavior by specifying <b>squeeze=n</b>.<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 squeeze=n > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=1 d1=0.004 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10 elements 40 bytes<br />
</pre><br />
<br />
=Seismic programs=<br />
Programs in this category are specific for operations on seismic data. The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/seismic/ system/seismic] in the Madagascar distribution.<br />
<br />
==sfheaderattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Integer header attributes. <br />
|-<br />
! colspan="4" | sfheaderattr < head.rsf<br />
|-<br />
| colspan="4" | <br>Only nonzero values are reported.<br />
|}<br />
<br />
The <tt>sfheaderattr</tt> examines the contents of a trace header file,<br />
typically generated by <tt>sfsegyread</tt>. In the example below, we examine<br />
trace headers in the output of <tt>suplane</tt>, a program from Seismic Unix.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
bash$ sfheaderattr < tfile.rsf<br />
*******************************************<br />
71 headers, 32 traces<br />
key[0]="tracl" min[0]=1 max[31]=32 mean=16.5<br />
key[1]="tracr" min[0]=1 max[31]=32 mean=16.5<br />
key[11]="offset" min[0]=400 max[31]=400 mean=400<br />
key[38]="ns" min[0]=64 max[31]=64 mean=64<br />
key[39]="dt" min[0]=4000 max[31]=4000 mean=4000<br />
*******************************************<br />
</pre><br />
For different standard keywords, a minimum, maximum, and mean values<br />
are reported unless they are identically zero. This quick inspection<br />
can help in identifying meaningful keywords set in the data. The input<br />
data type must be <tt>int</tt>.<br />
<br />
==sfheadermath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations, possibly on header keys. <br />
|-<br />
! colspan="4" | sfheadermath < in.rsf > out.rsf memsize=sf_memsize() output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs<br><br>See also sfmath. <br><br>An addition operation can be performed by sfstack.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''output=''' || || Describes the output in a mathematical notation.<br />
|}<br />
<tt>sfheadermath</tt> is a versatile program for mathematical<br />
operations on rows of the input file. If the input file is an<br />
<tt>n1</tt> by <tt>n2</tt> matrix, the output will be a <tt>1</tt> by<br />
<tt>n2</tt> matrix that contains one row made out of mathematical<br />
operations on the other rows. <tt>sfheadermath</tt> can identify a row<br />
by number or by a standard SEGY keyword. The latter is useful for<br />
processing headers extracted from SEGY or SU files.<br />
Here is an example. First, we create an SU file with <tt>suplane</tt> and convert it to RSF using <tt>sfsegyread</tt>.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
</pre><br />
The trace header information is saved in <tt>tfile.rsf</tt>. It<br />
contains 71 headers for 32 traces in integer format.<br />
<pre><br />
bash$ sfin tfile.rsf<br />
tfile.rsf:<br />
in="/tmp/tfile.rsf@"<br />
esize=4 type=int form=native<br />
n1=71 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
2272 elements 9088 bytes<br />
</pre><br />
Next, we will convert <tt>tfile.rsf</tt> to a floating-point format<br />
and run <tt>sfheadermath</tt> to create a new header.<br />
<pre><br />
bash$ < tfile.rsf sfdd type=float | \<br />
sfheadermath myheader=1 output="sqrt(myheader+(2+10*offset^2))" > new.rsf<br />
bash$ sfin new.rsf<br />
new.rsf:<br />
in="/tmp/new.rsf@"<br />
esize=4 type=float form=native<br />
n1=1 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
32 elements 128 bytes<br />
</pre><br />
We defined "myheader" as being the row number 1 in the input (note<br />
that numbering starts with 0) and combined it with "offset", which<br />
is a standard SEGY keyword that denotes row number 11 (see the output<br />
of <tt>sfheaderattr</tt> above.) A variety of mathematical expressions<br />
can be defined in the <tt>output=</tt> string. The expression<br />
processing engine is shared with <tt>sfmath</tt>.<br />
<br />
==sfsegyheader==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Make a trace header file for segywrite.<br />
|-<br />
! colspan="4" | sfsegyheader < in.rsf > out.rsf n1= d1=<br />
|-<br />
| colspan="4" | <br> Use the output for tfile= argument in segywrite.<br />
|-<br />
| ''float '' || '''d1=''' || || trace sampling<br />
|-<br />
| ''int '' || '''n1=''' || || number of samples in a trace<br />
|}<br />
<br />
==sfsegyread==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert a SEG-Y or SU dataset to RSF.<br />
|-<br />
! colspan="4" | sfsegyread mask=msk.rsf > out.rsf tfile=hdr.rsf verb=false su=false format=sf_segyformat (bhead) ns=sf_segyns (bhead) endian= tape= read= hfile= bfile= mask= tfile=<br />
|-<br />
| colspan="4" | <br>Data headers and trace headers are separated from the data.<br><br>Defined SEG-Y trace header key names and byte offsets:<br><br>tracl: trace sequence number within line 0<br><br>tracr: trace sequence number within reel 4<br><br>fldr: field record number 8 <br><br>tracf: trace number within field record 12 <br><br>ep: energy source point number 16 <br><br>cdp: CDP ensemble number 20 <br><br>cdpt: trace number within CDP ensemble 24 <br><br>trid: trace identification code:<br>1 = seismic data<br>2 = dead<br>3 = dummy<br>4 = time break<br>5 = uphole<br>6 = sweep<br>7 = timing<br>8 = water break<br>9---, N = optional use (N = 32,767) 28 <br><br>nvs: number of vertically summed traces 30 <br><br>nhs: number of horizontally summed traces 32 <br><br>duse: data use:<br>1 = production<br>2 = test 34<br><br>offset: distance from source point to receiver<br>group (negative if opposite to direction<br>in which the line was shot) 36 <br><br>gelev: receiver group elevation from sea level<br>(above sea level is positive) 40 <br><br>selev: source elevation from sea level<br>(above sea level is positive) 44 <br><br>sdepth: source depth (positive) 48 <br><br>gdel: datum elevation at receiver group 52 <br><br>sdel: datum elevation at source 56 <br><br>swdep: water depth at source 60 <br><br>gwdep: water depth at receiver group 64 <br><br>scalel: scale factor for previous 7 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 68 <br><br>scalco: scale factor for next 4 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 70 <br><br>sx: X source coordinate 72 <br><br>sy: Y source coordinate 76 <br><br>gx: X group coordinate 80 <br><br>gy: Y group coordinate 84 <br><br>counit: coordinate units code:<br>for previoius four entries<br>1 = length (meters or feet)<br>2 = seconds of arc (in this case, the<br>X values are unsigned intitude and the Y values<br>are latitude, a positive value designates<br>the number of seconds east of Greenwich<br>or north of the equator 88 <br><br>wevel: weathering velocity 90 <br><br>swevel: subweathering velocity 92 <br><br>sut: uphole time at source 94 <br><br>gut: uphole time at receiver group 96 <br><br>sstat: source static correction 98 <br><br>gstat: group static correction 100 <br><br>tstat: total static applied 102 <br><br>laga: lag time A, time in ms between end of 240-<br>byte trace identification header and time<br>break, positive if time break occurs after<br>end of header, time break is defined as<br>the initiation pulse which maybe recorded<br>on an auxiliary trace or as otherwise<br>specified by the recording system 104 <br><br>lagb: lag time B, time in ms between the time<br>break and the initiation time of the energy source,<br>may be positive or negative 106 <br><br>delrt: delay recording time, time in ms between<br>initiation time of energy source and time<br>when recording of data samples begins<br>(for deep water work if recording does not<br>start at zero time) 108 <br><br>muts: mute time--start 110 <br><br>mute: mute time--end 112 <br><br>ns: number of samples in this trace 114 <br><br>dt: sample interval, in micro-seconds 116 <br><br>gain: gain type of field instruments code:<br>1 = fixed<br>2 = binary<br>3 = floating point<br>4 ---- N = optional use 118 <br><br>igc: instrument gain constant 120 <br><br>igi: instrument early or initial gain 122 <br><br>corr: correlated:<br>1 = no<br>2 = yes 124 <br><br>sfs: sweep frequency at start 126 <br><br>sfe: sweep frequency at end 128 <br><br>slen: sweep length in ms 130 <br><br>styp: sweep type code:<br>1 = linear<br>2 = cos-squared<br>3 = other 132 <br><br>stas: sweep trace length at start in ms 134 <br><br>stae: sweep trace length at end in ms 136 <br><br>tatyp: taper type: 1=linear, 2=cos^2, 3=other 138 <br><br>afilf: alias filter frequency if used 140 <br><br>afils: alias filter slope 142 <br><br>nofilf: notch filter frequency if used 144 <br><br>nofils: notch filter slope 146 <br><br>lcf: low cut frequency if used 148 <br><br>hcf: high cut frequncy if used 150 <br><br>lcs: low cut slope 152 <br><br>hcs: high cut slope 154 <br><br>year: year data recorded 156 <br><br>day: day of year 158 <br><br>hour: hour of day (24 hour clock) 160 <br><br>minute: minute of hour 162 <br><br>sec: second of minute 164 <br><br>timbas: time basis code:<br>1 = local<br>2 = GMT<br>3 = other 166 <br><br>trwf: trace weighting factor, defined as 1/2^N<br>volts for the least sigificant bit 168 <br><br>grnors: geophone group number of roll switch<br>position one 170 <br><br>grnofr: geophone group number of trace one within<br>original field record 172 <br><br>grnlof: geophone group number of last trace within<br>original field record 174 <br><br>gaps: gap size (total number of groups dropped) 176 <br><br>otrav: overtravel taper code:<br>1 = down (or behind)<br>2 = up (or ahead)<br />
|-<br />
| ''string '' || '''bfile=''' || || output binary data header file<br />
|-<br />
| ''bool '' || '''endian=''' || [y/n] || big/little endian flag, the default is estimated automatically<br />
|-<br />
| ''int '' || '''format=sf_segyformat (bhead)''' || [1,2,3,5] || Data format. The default is taken from binary header.<br />
:1 is IBM floating point<br />
:2 is 4-byte integer<br />
:3 is 2-byte integer<br />
:5 is IEEE floating point<br />
|-<br />
| ''string '' || '''hfile=''' || || output text data header file<br />
|-<br />
| ''string '' || '''mask=''' || || optional header mask for reading only selected traces<br />
|-<br />
| ''int '' || '''ns=sf_segyns (bhead)''' || || Number of samples. The default is taken from binary header<br />
|-<br />
| ''string '' || '''read=''' || || what to read: h - header, d - data, b - both (default)<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if input is SU, n if input is SEGY<br />
|-<br />
| ''bool '' || '''suxdr=n''' || [y/n] || y, SU has XDR support<br />
|-<br />
| ''string '' || '''tape=''' || || <br />
|-<br />
| ''string '' || '''tfile=''' || || output trace header file<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
The SEG Y format is an [http://en.wikipedia.org/wiki/Open_standard open standard] for the exchange of geophysical data. It is controlled by the non-profit [http://www.seg.org/SEGportalWEBproject/portals/SEG_Online.portal?_nfpb=true&_pageLabel=pg_gen_content&Doc_Url=prod/SEG-Publications/Pub-Yearbook/committees.htm SEG Technical Standards Committee]. There are two versions of this standard: [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev0.pdf rev0] (1975)<ref>Barry, K.M., Cavers, D.A., and Kneale, C.W. 1975. Recommended standards for digital tape formats. ''Geophysics'', '''40''', no. 02, 344–352.</ref> and [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf rev1] (2002)<ref>Norris, M.W., Faichney, A.K., ''Eds''. 2001. SEG Y rev1 Data Exchange format. Society of Exploration Geophysicists, Tulsa, OK, 45 pp.</ref>. The implementation in <tt>sfsegyread</tt> is a mixture of rev0 (i.e. no checks for Extended Textual Headers) and rev1 ([http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE floating point format] allowed for trace data samples).<br />
<br />
A SEG-Y file as understood by <tt>sfsegyread</tt> contains a "Reel Identification Header" (3200 bytes in EBCDIC followed by 400 bytes in a binary encoding), followed by a number of "Trace Blocks". Each "Trace Block" contains a 240-byte "Trace Header" (binary) followed by "Trace Data" -- a sequence of <tt>ns</tt> samples. Binary values in both reel headers and trace headers are two's complement integers, either two bytes or four bytes long. There are no floating-point values defined in the headers. Trace Data samples can have various encodings, either floating point or integer, described further down, but they are all big-endian. To convert from SEG-Y to RSF, <tt>sfsegyread</tt> will strip the tape reel EBCDIC header and convert it to ASCII, will extract the reel binary header without changing it, and will put the trace headers into one RSF file, and the traces themselves on another.<br />
<br />
===SEG-Y Trace Headers===<br />
In the SEG-Y standard, only the first 180 bytes of the 240-byte trace header are defined; bytes 181-240 are reserved for non-standard header information, and these locations are increasingly used in modern SEG-Y files and its variants. The standard provides for a total of 71 4-byte and 2-byte predefined header words. These 71 standard words have defined lengths and byte offsets, and only these words and byte locations are read using <tt>segyread</tt> and output to the RSF header file with the <tt>hfile=</tt> option. The user may remap these predefined keywords to a different byte offsets.<br />
<br />
===SU File Format===<br />
An [http://www.cwp.mines.edu/sututor/node22.html SU file] is nothing more than a SEG-Y file without the reel headers, and with the Trace Data samples in the native encoding of the CPU the file was created on (Attention -- limited portability!). So, to convert from SU to RSF, <tt>sfsegyread</tt> will just separate headers and traces into two RSF files. <br />
<br />
===SEG-Y specific parameters===<br />
*<tt>hfile=</tt> specifies the name of the file in which the EBCDIC reel header will be put after conversion to ASCII. If you are certain there is no useful information in it, <tt>hfile=/dev/null</tt> works just fine. If you do not specify anything for this parameter you will get an ASCII file named <tt>header</tt> in the current directory. If you want to quickly preview this header before running <tt>sfsegyread</tt>, use<pre>dd if=input.segy count=40 bs=80 cbs=80 conv=unblock,ascii</pre><br />
*<tt>bfile=</tt> specifies name of the file in which the binary reel header (the 400-bytes thing following the 3600-bytes EBCDIC) will be put without any conversion. The default name is "binary". Unless you have software that knows how to read exactly this special type of file, it will be completely useless, so do <tt>bfile=/dev/null</tt><br />
*<tt>format=</tt> specifies the format in which the trace data samples are in the SEG-Y input file. This is read from the binary reel header of the SEG-Y file. Valid values are 1(IBM floating point), 2 (4-byte integer), 3 (2-byte integer) and 5 (IEEE floating point). If the input file is SU, the format will be assumed to be the native <tt>float</tt> format.<br />
<br />
*<tt>keyname=</tt> specifies the byte offset to remap a header using the trace header key names shown above. For example, if the CDP locations have been placed in bytes 181-184 instead of the standard 21-24, <tt>cdp=180</tt> will remap the trace header to that location. <br />
<br />
===SU-specific parameters===<br />
*<tt>suxdr=</tt> specifies whether the input file was created with a SU package with XDR support enabled. If you have access to the source code of your SU install (try <tt>$CWPROOT/src</tt>), type: <tt>grep 'XDRFLAG =' $CWPROOT/src/Makefile.config</tt> and look at the last uncommented entry. If no value is given for <tt>XDRFLAG</tt>, the package was not compiled with XDR support.<br />
===Common parameters===<br />
*<tt>su=</tt> specifies if the input file is SU or SEG-Y. Default is <tt>su=n</tt> (SEG-Y file).<br />
*<tt>tape=</tt> specifies the input data. Stdin could not be used because <tt>sfsegyread</tt> has to work with tapes, and needs to fseek back and forth through the input file. Thankfully, output is on stdout.<br />
*<tt>read=</tt> specifies what parts of the "Trace Blocks" will be read. It can be <tt>read=t</tt> (only trace data is read), <tt>read=h</tt> (only trace headers are read) or <tt>read=b</tt> (both are read).<br />
*<tt>tfile=</tt> gives the name of the RSF file to which trace headers are written. Obviously, it should be only specified with <tt>read=h</tt> or <tt>read=b</tt>.<br />
*<tt>mask=</tt> is an optional parameter specifying the name of a mask that says which traces will be read. The mask is a 1-D RSF file with integers. The number of samples in the mask is the same as the number of traces in the unmasked SEG-Y. In places corresponding to unwanted traces there should be zeros in the mask.<br />
*<tt>ns=</tt> specifies the number of samples in a trace. For SEG-Y files, the default is taken from the binary reel header, and for SU files, from the header of the first trace. This parameter is however critical enough that a command line override was given for it.<br />
*<tt>verbose=</tt> is the verbosity flag. Can be <tt>y</tt> or <tt>n</tt>.<br />
*<tt>endian=</tt> is a y/n flag (default y), specifying whether to automatically estimate or not if samples in the Trace Data blocks are big-endian or little-endian. Try it if you are in trouble and do not know what else to do, otherwise let the automatic estimation do its job.<br />
<br />
==sfsegywrite==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert an RSF dataset to SEGY or SU.<br />
|-<br />
! colspan="4" | sfsegywrite < in.rsf tfile=hdr.rsf verb=false su=false endian=sf_endian() tape= hfile= bfile=<br />
|-<br />
| colspan="4" | <br>Merges trace headers with data.<br />
|-<br />
| ''string '' || '''bfile=''' || || input binary data header file<br />
|-<br />
| ''bool '' || '''endian=sf_endian()''' || [y/n] || big/little endian flag. The default is estimated automatically<br />
|-<br />
| ''string '' || '''hfile=''' || || input text data header file<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if output is SU, n if output is SEGY<br />
|-<br />
| ''string '' || '''tape=''' || ||<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
Please see <tt>sfsegyread</tt> for a complete description of parameter meanings and background issues. Parameters <tt>bfile</tt> and <tt>hfile</tt> should only be given values when the desired file is SEG-Y (default). The output file is specified by the <tt>tape=</tt> tag.<br />
<br />
=Plotting programs=<br />
The source files for these programs can be found under<br />
[http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/plot/main/ plot/main]<br />
in the Madagascar distribution.<br />
<br />
THIS SECTION IS UNDER CONSTRUCTION<br />
<br />
==sfbox==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Draw a balloon-style label.<br />
|-<br />
! colspan="4" | sfbox lab_color=VP_WHITE lab_fat=0 pscale=1. pointer=y reverse=n lat=0. long=90. angle=0. x0=0. y0=0. scale0=1. xt=2. yt=0. x_oval=0. y_oval=0. boxit=y length= scalet= size=.25 label= > out.vpl<br />
|-<br />
| ''float '' || '''angle=0.''' || || longitude of floating label in 3-D<br />
|-<br />
| ''bool '' || '''boxit=y''' || [y/n] || if y, create a box around text<br />
|-<br />
| ''int '' || '''lab_color=VP_WHITE''' || || label color<br />
|-<br />
| ''int '' || '''lab_fat=0''' || || label fatness<br />
|-<br />
| ''string '' || '''label=''' || || text for label<br />
|-<br />
| ''float '' || '''lat=0.''' || || <br />
|-<br />
| ''float '' || '''length=''' || || normalization for xt and yt<br />
|-<br />
| ''float '' || '''long=90.''' || || latitude and longitude of viewpoint in 3-D<br />
|-<br />
| ''bool '' || '''pointer=y''' || [y/n] || if y, create arrow pointer<br />
|-<br />
| ''float '' || '''pscale=1.''' || || scale factor for width of pointer<br />
|-<br />
| ''bool '' || '''reverse=n''' || [y/n] || <br />
|-<br />
| ''float '' || '''scale0=1.''' || || scale factor for x0 and y0<br />
|-<br />
| ''float '' || '''scalet=''' || || <br />
|-<br />
| ''float '' || '''size=.25''' || || text height in inches<br />
|-<br />
| ''float '' || '''x0=0.''' || || <br />
|-<br />
| ''float '' || '''x_oval=0.''' || || <br />
|-<br />
| ''float '' || '''xt=2.''' || || <br />
|-<br />
| ''float '' || '''y0=0.''' || || position of the pointer tip<br />
|-<br />
| ''float '' || '''y_oval=0.''' || || size of the oval around pointer<br />
|-<br />
| ''float '' || '''yt=0.''' || || relative position of text<br />
|}<br />
==sfcontour==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Contour plot.<br />
|-<br />
! colspan="4" | sfcontour < in.rsf c= min1=o1 min2=o2 max1=o1+(n1-1)*d1 max2=o2+(n2-1)*d2 nc=50 dc= c0= transp=y minval= maxval= allpos=y barlabel= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=y''' || [y/n] || contour positive values only<br />
|-<br />
| ''string '' || '''barlabel=''' || || <br />
|-<br />
| ''floats '' || '''c=''' || || [nc]<br />
|-<br />
| ''float '' || '''c0=''' || || first contour<br />
|-<br />
| ''float '' || '''dc=''' || || contour increment<br />
|-<br />
| ''float '' || '''max1=o1+(n1-1)*d1''' || || <br />
|-<br />
| ''float '' || '''max2=o2+(n2-1)*d2''' || || data window to plot<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''min1=o1''' || || <br />
|-<br />
| ''float '' || '''min2=o2''' || || <br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nc=50''' || || number of contours<br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfdots==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot signal with lollipops.<br />
|-<br />
! colspan="4" | sfdots < in.rsf labels= dots=(n1 <= 130)? 1: 0 seemean=(bool) (n2 <= 30) strings=(bool) (n1 <= 400) connect=1 corners= silk=n gaineach=y labelsz=8 yreverse=n constsep=n seedead=n transp=n xxscale=1. yyscale=1. clip=-1. overlap=0.9 screenratio=VP_SCREEN_RATIO screenht=VP_STANDARD_HEIGHT screenwd=screenhigh / screenratio radius=dd1/3 label1= unit1= title= > plot.vpl<br />
|-<br />
| ''float '' || '''clip=-1.''' || || data clip<br />
|-<br />
| ''int '' || '''connect=1''' || || connection type: 1 - diagonal, 2 - bar, 4 - only for non-zero data<br />
|-<br />
| ''bool '' || '''constsep=n''' || [y/n] || if y, use constant trace separation<br />
|-<br />
| ''int '' || '''corners=''' || || number of polygon corners (default is 6)<br />
|-<br />
| ''int '' || '''dots=(n1 <= 130)? 1: 0''' || || type of dots: 1 - baloon, 0 - no dots, 2 - only for non-zero data<br />
|-<br />
| ''bool '' || '''gaineach=y''' || [y/n] || if y, gain each trace independently<br />
|-<br />
| ''string '' || '''label1=''' || || <br />
|-<br />
| ''strings'' || '''labels=''' || || trace labels [n2]<br />
|-<br />
| ''int '' || '''labelsz=8''' || || label size<br />
|-<br />
| ''float '' || '''overlap=0.9''' || || trace overlap<br />
|-<br />
| ''float '' || '''radius=dd1/3''' || || dot radius<br />
|-<br />
| ''float '' || '''screenht=VP_STANDARD_HEIGHT''' || || screen height<br />
|-<br />
| ''float '' || '''screenratio=VP_SCREEN_RATIO''' || || screen aspect ratio<br />
|-<br />
| ''float '' || '''screenwd=screenhigh / screenratio''' || || screen width<br />
|-<br />
| ''bool '' || '''seedead=n''' || [y/n] || if y, show zero traces<br />
|-<br />
| ''bool '' || '''seemean=(bool) (n2 <= 30)''' || [y/n] || if y, draw axis lines<br />
|-<br />
| ''bool '' || '''silk=n''' || [y/n] || if y, silky plot<br />
|-<br />
| ''bool '' || '''strings=(bool) (n1 <= 400)''' || [y/n] || if y, draw strings<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axis<br />
|-<br />
| ''string '' || '''unit1=''' || || <br />
|-<br />
| ''float '' || '''xxscale=1.''' || || x scaling<br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse y axis<br />
|-<br />
| ''float '' || '''yyscale=1.''' || || y scaling<br />
|}<br />
==sfgraph3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot for surfaces.<br />
|-<br />
! colspan="4" | sfgraph3 < in.rsf orient=1 min= max= point1=0.5 point2=0.5 frame1=0.5*(min+max) frame2=n1-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y > plot.vpl<br />
|-<br />
| ''float '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''float '' || '''frame1=0.5*(min+max)''' || || <br />
|-<br />
| ''int '' || '''frame2=n1-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''max=''' || || maximum function value<br />
|-<br />
| ''float '' || '''min=''' || || minimum function value<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''orient=1''' || || function orientation<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|}<br />
==sfgraph==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Graph plot.<br />
|-<br />
! colspan="4" | sfgraph < in.rsf symbolsz= pclip=100. transp=n symbol= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''pclip=100.''' || || clip percentile<br />
|-<br />
| ''string '' || '''symbol=''' || || if set, plot with symbols instead of lines<br />
|-<br />
| ''floats '' || '''symbolsz=''' || || symbol size (default is 2) [n2]<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfgrey3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot.<br />
|-<br />
! colspan="4" | sfgrey3 < in.rsf point1=0.5 point2=0.5 frame1=0 frame2=n2-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y scalebar=n minval= maxval= barreverse=n nreserve=8 bar= color= > plot.vpl<br />
|-<br />
| colspan="4" | Requires an "unsigned char" input (the output of sfbyte).<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''int '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''int '' || '''frame1=0''' || || <br />
|-<br />
| ''int '' || '''frame2=n2-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || if y, draw scalebar<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
for sfgrey and sfgrey3. Examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfgrey==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate raster plot.<br />
|-<br />
! colspan="4" | sfgrey < in.rsf > out.rsf bar=bar.rsf transp=y yreverse=y xreverse=n gpow= phalf= clip= pclip= gainstep=0.5+n1/256. allpos=n bias=0. polarity=n verb=n scalebar=n minval= maxval= barreverse=n wantframenum=(bool) (n3 > 1) nreserve=8 gainpanel= bar= color= > (plot.vpl | char.rsf)<br />
|-<br />
| colspan="4" | Can input char values.<br>If called "byte", outputs char values.<br><br>Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=n''' || [y/n] || if y, assume positive data<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=''' || || <br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''string '' || '''gainpanel=''' || || gain reference: 'a' for all, 'e' for each, or number<br />
|-<br />
| ''int '' || '''gainstep=0.5+n1/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=''' || || <br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''pclip=''' || || data clip percentile (default is 99)<br />
|-<br />
| ''float '' || '''phalf=''' || || percentage for estimating gpow<br />
|-<br />
| ''bool '' || '''polarity=n''' || [y/n] || if y, reverse polarity (white is high by default)<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the display axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''bool '' || '''wantframenum=(bool) (n3 > 1)''' || [y/n] || if y, display third axis position in the corner<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''bool '' || '''yreverse=y''' || [y/n] || if y, reverse the vertical axis<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
and examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfplas==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Assembler - convert ascii to vplot. <br />
|-<br />
! colspan="4" | sfplas<br />
|}<br />
==sfpldb==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Debugger - convert vplot to ascii. <br />
|-<br />
! colspan="4" | sfpldb<br />
|}<br />
==sfplotrays==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot rays.<br />
|-<br />
! colspan="4" | sfplotrays frame=frame.rsf nt=n1*n2 jr=1 frame= < rays.rsf > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''string '' || '''frame=''' || || <br />
|-<br />
| ''int '' || '''jr=1''' || || skip rays<br />
|-<br />
| ''int '' || '''nt=n1*n2''' || || maximum ray length<br />
|}<br />
==sfthplot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Hidden-line surface plot.<br />
|-<br />
! colspan="4" | sfthplot < in.rsf uflag=y dflag=y alpha=45. titlsz=9 axissz=6 plotfat=0 titlefat=2 axisfat=2 plotcolup=VP_YELLOW plotcoldn=VP_RED axis=y axis1=y axis2=y axis3=y clip=0. pclip=100. gainstep=0.5+nx/256. bias=0. dclip=1. norm=y xc=1.5 zc=3 ratio=5. zmax= zmin= sz=6. label#= unit#= tpow=0 epow=0 gpow=1 title= > plot.vpl<br />
|-<br />
| ''float '' || '''alpha=45.''' || || apparent angle in degrees, |alpha| < 89<br />
|-<br />
| ''bool '' || '''axis=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis1=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis2=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis3=y''' || [y/n] || plot axis<br />
|-<br />
| ''int '' || '''axisfat=2''' || || axes fatness<br />
|-<br />
| ''int '' || '''axissz=6''' || || axes size<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip<br />
|-<br />
| ''float '' || '''dclip=1.''' || || change the clip: clip *= dclip<br />
|-<br />
| ''bool '' || '''dflag=y''' || [y/n] || if y, plot down side of the surface<br />
|-<br />
| ''float '' || '''epow=0''' || || exponential gain<br />
|-<br />
| ''int '' || '''gainstep=0.5+nx/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=1''' || || power gain<br />
|-<br />
| ''string '' || '''label#=''' || || label on #-th axis<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || normalize by the clip<br />
|-<br />
| ''float '' || '''pclip=100.''' || || data clip percentile<br />
|-<br />
| ''int '' || '''plotcoldn=VP_RED''' || || color of the lower side<br />
|-<br />
| ''int '' || '''plotcolup=VP_YELLOW''' || || color of the upper side<br />
|-<br />
| ''int '' || '''plotfat=0''' || || line fatness<br />
|-<br />
| ''float '' || '''ratio=5.''' || || plot adjustment<br />
|-<br />
| ''float '' || '''sz=6.''' || || vertical scale<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''int '' || '''titlefat=2''' || || title fatness<br />
|-<br />
| ''int '' || '''titlsz=9''' || || title size<br />
|-<br />
| ''string '' || '''tpow=0''' || || time power gain<br />
|-<br />
| ''bool '' || '''uflag=y''' || [y/n] || if y, plot upper side of the surface<br />
|-<br />
| ''string '' || '''unit#=''' || || unit on #-th axis<br />
|-<br />
| ''float '' || '''xc=1.5''' || || <br />
|-<br />
| ''float '' || '''zc=3''' || || lower left corner of the plot<br />
|-<br />
| ''float '' || '''zmax=''' || || <br />
|-<br />
| ''float '' || '''zmin=''' || || <br />
|}<br />
==sfwiggle==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot data with wiggly traces. <br />
|-<br />
! colspan="4" | sfwiggle < in.rsf xpos=xpos.rsf xmax= xmin= poly=n fatp=1 xmask=1 ymask=1 pclip=98. zplot=0.75 clip=0. seemean=n verb=n transp=n yreverse=n xreverse=n xpos= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip (estimated from pclip by default<br />
|-<br />
| ''int '' || '''fatp=1''' || || <br />
|-<br />
| ''float '' || '''pclip=98.''' || || clip percentile<br />
|-<br />
| ''bool '' || '''poly=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''seemean=n''' || [y/n] || if y, plot mean lines of traces<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''int '' || '''xmask=1''' || || <br />
|-<br />
| ''float '' || '''xmax=''' || || maximum trace position (if using xpos)<br />
|-<br />
| ''float '' || '''xmin=''' || || minimum trace position (if using xpos)<br />
|-<br />
| ''string '' || '''xpos=''' || || optional header file with trace positions<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''int '' || '''ymask=1''' || || <br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse the vertical axis<br />
|-<br />
| ''float '' || '''zplot=0.75''' || || <br />
|}<br />
<br />
=filt/imag programs=<br />
==sfremap1==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 1-D ENO interpolation. <br />
|-<br />
! colspan="4" | sfremap1 < in.rsf > out.rsf pattern=pattern.rsf n1=n1 d1=d1 o1=o1 order=3<br />
|-<br />
| ''float '' || '''d1=d1''' || || Output sampling<br />
|-<br />
| ''int '' || '''n1=n1''' || || Number of output samples<br />
|-<br />
| ''float '' || '''o1=o1''' || || Output origin<br />
|-<br />
| ''int '' || '''order=3''' || || Interpolation order<br />
|-<br />
| ''string '' || '''pattern=''' || || auxiliary input file name<br />
|}<br />
To give an example of usage, we will create an input for <tt>sfremap1</tt> with:<br />
<pre><br />
sfmath n1=11 n2=11 d1=1 d2=1 o1=-5 o2=-5 output="x1*x1+x2*x2" > inp2remap1.rsf<br />
</pre><br />
Let us interpolate the data across both dimensions, then display it:<br />
<pre><br />
&lt; inp2remap1.rsf sfremap1 n1=1001 d1=0.01 | sftransp | \<br />
sfremap1 n1=1001 d1=0.01 | sftransp | sfgrey allpos=y | xtpen<br />
</pre><br />
The comparison with the uninterpolated data ( <tt>&lt; inp2remap1.rsf sfgrey allpos=y | xtpen</tt> ) is quite telling.<br />
<br />
=filt/proc programs=<br />
==sfstretch==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stretch of the time axis. <br />
|-<br />
! colspan="4" | sfstretch < in.rsf > out.rsf datum=dat.rsf inv=n dens=1 v0= half=y delay= tdelay= hdelay= nout=dens*n1 extend=4 mute=0 maxstr=0 rule=<br />
|-<br />
| ''file '' || '''datum=''' || || auxiliary input file name<br />
|-<br />
| ''float '' || '''delay=''' || || time delay for rule=lmo<br />
|-<br />
| ''int '' || '''dens=1''' || || axis stretching factor<br />
|-<br />
| ''int '' || '''extend=4''' || || trace extension<br />
|-<br />
| ''bool '' || '''half=y''' || [y/n] || if y, the second axis is half-offset instead of full offset<br />
|-<br />
| ''float '' || '''hdelay=''' || || offset delay for rule=rad<br />
|-<br />
| ''bool '' || '''inv=n''' || [y/n] || if y, do inverse stretching<br />
|-<br />
| ''float '' || '''maxstr=0''' || || maximum stretch<br />
|-<br />
| ''int '' || '''mute=0''' || || tapering size<br />
|-<br />
| ''int '' || '''nout=dens*n1''' || || output axis length (if inv=n)<br />
|-<br />
| ''string '' || '''rule=''' || || Stretch rule:<br />
:n - normal moveout (nmostretch), default<br />
:l - linear moveout (lmostretch)<br />
:L - logarithmic stretch (logstretch)<br />
:2 - t^2 stretch (t2stretch)<br />
:c - t^2 chebyshev stretch (t2chebstretch)<br />
:r - radial moveout (radstretch)<br />
:d - datuming (datstretch)<br />
|-<br />
| ''float '' || '''tdelay=''' || || time delay for rule=rad<br />
|-<br />
| ''float '' || '''v0=''' || || moveout velocity<br />
|}<br />
<br />
<tt>sfstretch rule=d</tt> (aka <tt>sfdatstretch</tt>) can be used to apply statics. Here is a synthetic example, courtesy of Alessandro Frigeri:<br />
<pre><br />
# generate a dataset with 'flat' signals<br />
sfmath n1=200 n2=100 output="sin(0.5*x1)" type=float > scan.rsf<br />
<br />
# generate a sinusoidal elevation correction<br />
sfmath n1=100 output="3*sin(x1)" type=float > statics.rsf<br />
<br />
# apply statics, producing a 'wavy' output.<br />
sfstretch < scan.rsf > out.rsf datum=statics.rsf rule=d<br />
</pre><br />
<br />
=user/ivlad programs=<br />
==sfprep4plot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Resamples a 2-D dataset to the desired picture resolution, with antialias<br />
|-<br />
! colspan="4" | sfprep4plot inp= out= verb=n h=none w=none unit= ppi= prar=y<br />
|-<br />
| colspan="4" | Only one of the h and w parameters needs to be specified.<br>If prar=n, no action will be taken on axis for which h/w was not specified<br>If prar=y and only one par (h or w) is specified, the picture will scale<br>along both axes until it is of the specified dimension.<br />
|-<br />
| ''int '' || '''h=none''' || || output height<br />
|-<br />
| ''string '' || '''inp=''' || || input file<br />
|-<br />
| ''string '' || '''out=''' || || output file<br />
|-<br />
| ''int '' || '''ppi=''' || || output resolution (px/in). Necessary when unit!=px<br />
|-<br />
| ''bool '' || '''prar=y''' || [y/n] || if y, PReserve Aspect Ratio of input<br />
|-<br />
| ''string '' || '''unit=''' || || unit of h and w. Can be: px(default), mm, cm, in<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || if y, print system commands, outputs<br />
|-<br />
| ''int '' || '''w=none''' || || output width<br />
|}<br />
For a figure that does not need the aspect ratio preserved,<br />
and needs to fill a 1280x1024 projector display:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=1280 h=1024 prar=n<br />
</pre><br />
For a print figure that has to fit in a 6x8in box<br />
at a resolution of 250 dpi, preserving the aspect ratio:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=6 h=8 unit=in ppi=250<br />
</pre><br />
A comparison of images before and after the application of <tt>sfprep4plot</tt>, courtesy of Joachim Mispel, is shown below:<br />
<br />
[[Image:sf_prep4plot.jpg]]<br />
<br />
=user/jennings programs=<br />
==sfsizes==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display the size of RSF files.<br />
|-<br />
! colspan="4" | sfsizes files=y human=n file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | Prints the element size, number of elements, and number of bytes<br>for a list of RSF files. Non-RSF files are ignored.<br />
|-<br />
| ''bool '' || '''files=y''' || [y/n] || If y, print size of each file. If n, print only total.<br />
|-<br />
| ''bool '' || '''human=n''' || [y/n] || If y, print human-readable file size. If n, print byte count.<br />
|}<br />
<br />
<br />
This program computes the "theoretical" size in bytes of the data fork of RSF files. The actual space occupied on disk may be different and machine dependent due to disk blocking factors, etc. This theoretical array size should be reproducible. It is also fast because the program only reads the RSF headers files, not the actual data.<br />
<br />
For example, to get the total size of all RSF files in a directory, in human readable format, without listing each file:<br />
<pre><br />
sfsizes files=n human=y *.rsf<br />
</pre><br />
This will also work because sfsizes simply skips any non-RSF file:<br />
<pre><br />
sfsizes files=n human=y *<br />
</pre><br />
==sffiglist==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Compare Vplot files in Fig and Lock directories<br />
|-<br />
! colspan="4" | sffiglist figdir= lockdir= list= show=<br />
|-<br />
| colspan="4" |<br />
Parameter '''figdir''' is path to Fig directory, default is ./Fig.<br />
<br />
<br>Parameter '''lockdir''' is path to Lock directory:<br />
<br> If '''figdir''' is in $RSFSRC/book/[book]/[chapter]/[section],<br />
<br> then default '''lockdir''' is $RSFFIGS/[book]/[chapter]/[section].<br />
<br> If '''figdir''' is not in $RSFSRC/book/[book]/[chapter]/[section],<br />
<br> then default '''lockdir''' is $RSFALTFIGS/[book]/[chapter]/[section].<br />
<br />
<br>Parameter '''list''' controls files to list, default is all.<br />
<br>Parameter '''show''' controls files to flip with sfpen, default is none.<br />
<br />
<br>'''list|show''' = none (No files, print only summary.)<br />
<br>'''list|show''' = diff (Files that are different, determined by sfvplotdiff.)<br />
<br>'''list|show''' = miss (Files missing from figdir or lockdir, and different files.)<br />
<br>'''list|show''' = all (All files.)<br />
<br />
<br>File list codes:<br />
<br>space indicates files that are the same.<br />
<br> - indicates file in lockdir that is missing from figdir.<br />
<br> + indicates extra file in figdir that is missing from lockdir.<br />
<br>number is return code from sfvplotdiff indicating different files.<br />
|-<br />
| ''string '' || '''figdir=''' || || fig directory, default = ./Fig<br />
|-<br />
| ''string '' || '''list=''' || || how much to list [none,diff,miss,all], default = all<br />
|-<br />
| ''string '' || '''lockdir=''' || || lock directory, default = lock counterpart of figdir<br />
|-<br />
| ''string '' || '''show=''' || || how much to show [none,diff,miss,all], default = none<br />
|}<br />
<br />
<br />
This tool lists Vplot files in "Fig" and "Lock" directories and compares them using sfvplotdiff.<br />
<br />
The Fig directory defaults to ./Fig and the Lock directory defaults to the <br />
corresponding directory where "scons lock" puts things, but either <br />
default can be overridden with the user parameters '''figdir''' and '''lockdir''' so that, for example, <br />
files in two different Fig directories can be compared.<br />
<br />
The default for the Lock directory has some logic to look in $RSFFIGS <br />
when Fig is in $RSFSRC/book, or to look in $RSFALTFIGS when Fig is not <br />
in $RSFSRC/book because I like to keep two different Lock directories: <br />
one for stuff in book and another for my own stuff that is not in <br />
book. However, I tried to make the code default to reasonable things <br />
if any of these environment variables are not defined.<br />
<br />
The tool gives a summary count of files that are the same, files that <br />
are different, files in Fig that are missing from Lock, and files in <br />
Lock that are missing from Fig.<br />
<br />
The parameters '''list''' (default=all) and '''show''' (default=none) control which files are listed or "flipped" with sfpen. The file listing indicates which files are the same, which are different, and which are missing from Fig or Lock.<br />
<br />
For example, to list all the Vplot files in Fig and Lock:<br />
<pre><br />
sffiglist list=all<br />
</pre><br />
To list all Vplot files and flip only files that are different:<br />
<pre><br />
sffiglist list=all show=diff<br />
</pre><br />
<br />
=user/psava programs=<br />
==sfsrmig3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 3-D S/R migration with extended SSF<br />
|-<br />
! colspan="4" | sfsrmig3 slo=Fs_s.rsf sls=Fs_r.rsf < Fw_s.rsf rwf=Fw_r.rsf > Fi.rsf cig=Fc.rsf ompchunk=1 ompnth=0 verb=y eps=0.01 twoway=n nrmax=1 dtmax=0.004 pmx=0 pmy=0 tmx=0 tmy=0 vpvs=1. hsym=n nht=1 oht=0 dht=0.1 nht=1 oht=0 dht=0.1 hsym=n nhh=1 ohh=0 dhh=0.1 nha=180 oha=0 dha=2.0 nhb=180 ohb=0 dhb=2.0 itype=<br />
|-<br />
| ''file '' || '''cig=''' || || auxiliary output file name<br />
|-<br />
| ''float '' || '''dha=2.0''' || ||<br />
|-<br />
| ''float '' || '''dhb=2.0''' || ||<br />
|-<br />
| ''float '' || '''dhh=0.1''' || ||<br />
|-<br />
| ''float '' || '''dht=0.1''' || ||<br />
|-<br />
| ''float '' || '''dtmax=0.004''' || || max time error<br />
|-<br />
| ''float '' || '''eps=0.01''' || || stability parameter<br />
|-<br />
| ''bool '' || '''hsym=n''' || [y/n] ||<br />
|-<br />
| ''string '' || '''itype=''' || || imaging condition type<br />
:o = zero lag (default)<br />
:e = extended<br />
:x = space-lags<br />
:h = space-lags magnitude<br />
:t = time-lag<br />
|-<br />
| ''int '' || '''nha=180''' || ||<br />
|-<br />
| ''int '' || '''nhb=180''' || ||<br />
|-<br />
| ''int '' || '''nhh=1''' || ||<br />
|-<br />
| ''int '' || '''nht=1''' || ||<br />
|-<br />
| ''int '' || '''nrmax=1''' || || max number of refs<br />
|-<br />
| ''float '' || '''oha=0''' || ||<br />
|-<br />
| ''float '' || '''ohb=0''' || ||<br />
|-<br />
| ''float '' || '''ohh=0''' || ||<br />
|-<br />
| ''float '' || '''oht=0''' || ||<br />
|-<br />
| ''int '' || '''ompchunk=1''' || || OpenMP data chunk size<br />
|-<br />
| ''int '' || '''ompnth=0''' || || OpenMP available threads<br />
|-<br />
| ''int '' || '''pmx=0''' || || padding on x<br />
|-<br />
| ''int '' || '''pmy=0''' || || padding on y<br />
|-<br />
| ''file '' || '''rwf=''' || || auxiliary input file name<br />
|-<br />
| ''file '' || '''slo=''' || || auxiliary input file name<br />
|-<br />
| ''string '' || '''sls=''' || || auxiliary input file name<br />
|-<br />
| ''int '' || '''tmx=0''' || || taper on x<br />
|-<br />
| ''int '' || '''tmy=0''' || || taper on y<br />
|-<br />
| ''bool '' || '''twoway=n''' || [y/n] || two-way traveltime<br />
|-<br />
| ''bool '' || '''verb=y''' || [y/n] || verbosity flag<br />
|-<br />
| ''float '' || '''vpvs=1.''' || || Vp/Vs ratio<br />
|}<br />
<br />
This program performs 3-D and 2-D shot-record (a.k.a. shot-profile) migration with an extended Split-Step Fourier (SSF) extrapolator with multiple reference velocities (hence "extended"). It takes as input a shot wavefield (<tt>stdin</tt>), receiver wavefield (<tt>rwf=</tt>) and slowness model (<tt>slo=</tt>). Outputs are an image (<tt>stdout</tt>) and a cube of Common Image Gathers (<tt>cig=</tt>). An important parameter is <tt>nrmax</tt>, the number of reference velocities. Its default value is 1, but for reasonable results it should be 5 or so. It is also good to specify nonzero taper values (<tt>tmx</tt> and, for 3-D, <tt>tmy</tt> as well). The values of padding parameters <tt>pmx</tt> and <tt>pmy</tt> are split in two by the program, i.e. if your data x axis is 501-points long, specify pmx=11 to get a value of 512 that will result in fast Fourier Transforms. <br />
<br />
The program will also migrate converted-wave data if a file with the S-wave slowness model (<tt>sls=</tt>) is provided.<br />
<br />
The <tt>vpvs</tt> parameter is only used when <tt>itype=h</tt>. Do not specify a <tt>vpvs</tt> value unless you know really well what you are doing.<br />
<br />
===Usage example===<br />
The commands below, slightly modified from [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/data/sigsbee/ptest/SConstruct?revision=3993&view=markup RSFSRC/book/data/sigsbee/ptest], show how to prepare the [http://www.reproducibility.org/RSF/book/data/sigsbee Sigsbee 2A] data and velocity for migration.<br />
<br />
Convert input data (shots) from SEG-Y to RSF:<br />
<bash><br />
sfsegyread tape=sigsbee2a_nfs.segy tfile=tdata.rsf hfile=/dev/null bfile=/dev/null > ddata.rsf<br />
</bash><br />
Convert trace headers to float (required by <tt>sfheadermath</tt>):<br />
<bash><br />
< tdata.rsf sfdd type=float > trchdr.rsf<br />
</bash><br />
Shot positions:<br />
<bash><br />
< trchdr.rsf sfheadermath output="fldr + 10925/150" | sfwindow squeeze=y > tsi.rsf<br />
</bash><br />
Extract offset positions from the trace header files, eliminate length-1 axis, scale, create a header for binning (required by <tt>sfintbin</tt>):<br />
<bash><br />
< trchdr.rsf sfheadermath output="offset" |\<br />
sfwindow squeeze=y |\<br />
sfmath output="input/75" |\<br />
sfcat axis=2 space=n tsi.rsf |\<br />
sftransp |\<br />
sfdd type=int > tos.rsf<br />
</bash><br />
Binning and muting:<br />
<bash><br />
< ddata.rsf sfintbin head=tos.rsf xkey=0 ykey=1 |\<br />
sfput label1=Time unit1=s d2=0.075 o2=0.0 label2=hx d3=0.150 o3=10.925 label3=sx |\<br />
sfmutter half=false t0=1.0 v0=6.0 |\<br />
sfput d2=0.02286 o2=0 unit2=km d3=0.04572 o3=3.32994 unit3=km > shots.rsf<br />
</bash><br />
Keeping only 20 shots so that this 1-node job will not take forever, FFT-ing, decimating frequency slices (same as shortening the time axis), and creating y and hy axes of length 1:<br />
<bash><br />
< shots.rsf sfwindow n3=20 f3=10 j3=20 |\<br />
sffft1 |\<br />
sfwindow n1=200 min1=1 j1=3 |\<br />
sfspray axis=3 n=1 o=0 d=1 label=hy |\<br />
sfspray axis=5 n=1 o=0 d=1 label=sy > rfft.rsf<br />
</bash><br />
The dimensions of the cube thus created are:<br />
<pre><br />
$ sfin rfft.rsf trail=n<br />
rfft.rsf:<br />
in="/var/tmp/rfft.rsf@"<br />
esize=8 type=complex form=native<br />
n1=200 d1=0.25 o1=1 label1="Frequency" unit1="Hz"<br />
n2=348 d2=0.02286 o2=0 label2="hx" unit2="km"<br />
n3=1 d3=1 o3=0 label3="hy" unit3="km"<br />
n4=20 d4=0.9144 o4=3.78714 label4="sx" unit4="km"<br />
1392000 elements 11136000 bytes<br />
</pre><br />
Create the source wavelet (limited to the same frequency band as the data) and Fourier transform it:<br />
<bash><br />
sfspike k1=1 n1=1500 d1=0.008 |\<br />
sfbandpass flo=15 fhi=25 |\<br />
sffft1 |\<br />
sfwindow n1=200 min1=1 j1=3 |\<br />
sfput label1=freq > sfft.rsf<br />
</bash><br />
This creates a frequency-domain wavelet:<br />
<pre><br />
$ sfin sfft.rsf<br />
sfft.rsf:<br />
in="/var/tmp/sfft.rsf@"<br />
esize=8 type=complex form=native<br />
n1=200 d1=0.25 o1=1 label1="freq" unit1="Hz"<br />
200 elements 1600 bytes<br />
</pre><br />
Create "synched" source and receiver wavefields with <tt>srsyn</tt> from wavelet and data frequency slices. Basically both the receiver and shot frequency slices are "placed" at the right location and padded with zeros up to the dimension of the x axis specified below.<br />
<bash><br />
< rfft.rsf sfsrsyn nx=1067 dx=0.02286 ox=3.05562 wav=sfft.rsf swf=swav.rsf > rwav.rsf<br />
</bash><br />
This creates frequency slices ready for migration for both source and receiver, only axis 1 (frequency) must become axis 3, for both datasets:<br />
<bash><br />
< swav.rsf sftransp plane=12 | sftransp plane=23 > stra.rsf<br />
</bash><br />
<bash><br />
< rwav.rsf sftransp plane=12 | sftransp plane=23 > rtra.rsf<br />
</bash><br />
This creates a surface receiver wavefield ready for input to migration. Axis 4 is shot number. The values of axis 4 are arbitrary because each shot has been padded with zeros so that it covers the entire velocity model. Therefore the aperture of the downward continuation for each shot will be as large as the survey.<br />
<pre><br />
sfin trail=n rtra.rsf<br />
rtra.rsf:<br />
in="/var/tmp/rtra.rsf@"<br />
esize=8 type=complex form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=200 d3=0.25 o3=1 label3="w" unit3="Hz"<br />
n4=20 d4=1 o4=0 label4="e" unit4="km"<br />
4268000 elements 34144000 bytes<br />
</pre><br />
Convert the velocity model from SEG-Y to RSF, decimate, convert from feet to km, transpose, convert to slowness and insert an additional axis:<br />
<bash><br />
sfsegyread tape=sigsbee2a_migvel.sgy tfile=/dev/null hfile=/dev/null bfile=/dev/null |\<br />
sfput o1=0 d1=0.00762 label1=z unit1=km o2=3.05562 d2=0.01143 label2=x unit2=km |\<br />
sfwindow j1=4 j2=2 |\<br />
sfscale rscale=0.0003048 |\<br />
sftransp |\<br />
sfmath output="1/input" |\<br />
sfspray axis=2 n=1 d=1 o=0 |\<br />
sfput label2=y > slow.rsf<br />
</bash><br />
This creates a slowness file ready for input to migration, with an x axis identical to the x axis of the wavefield files:<br />
<pre><br />
$ sfin slow.rsf<br />
slow.rsf:<br />
in="/var/tmp/slow.rsf@"<br />
esize=4 type=float form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=301 d3=0.03048 o3=0 label3="z" unit3="km"<br />
321167 elements 1284668 bytes<br />
</pre><br />
Finally, the migration command (for a 4-processor machine, hence the <tt>ompnth</tt> value). We choose not to compute any image gathers (<tt>itype=o</tt>), but due to the construction of the program we still have to explicitly assign the <tt>cig</tt> tag, or else a RSF file with the name of the tag and no rsf extension will be created:<br />
<bash><br />
< stra.rsf sfsrmig3 nrmax=20 dtmax=5e-05 eps=0.01 verb=y ompnth=4 \<br />
tmx=16 rwf=rtra.rsf slo=slow.rsf itype=o cig=/dev/null > img.rsf<br />
</bash><br />
The migration of 20 shots takes approximately 3 hours on a 4-processor machine (1 shot=9 minutes). Without the frequency slice decimation by a factor of 3 and the depth axis decimation by a factor of 4, it would have taken twelve times as much. The resulting image has a y axis of length 1:<br />
<pre><br />
$ sfin img.rsf trail=n<br />
img.rsf:<br />
in="/var/tmp/img.rsf@"<br />
esize=4 type=float form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=301 d3=0.03048 o3=0 label3="z" unit3="km"<br />
321167 elements 1284668 bytes<br />
</pre><br />
To properly visualize the image, we need to eliminate the axis of length 1, then transpose the x and z axes to their natural position:<br />
<bash><br />
<img.rsf sfwindow squeeze=y | sftransp | sfgrey > img.vpl<br />
</bash><br />
<br />
=References=<br />
<references/></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Guide_to_madagascar_programs&diff=930Guide to madagascar programs2009-08-14T03:00:52Z<p>Jenningsjwj: /* sffiglist */</p>
<hr />
<div><center><font size="-1">''This page was created from the LaTeX source in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/rsf/rsf/prog.tex?view=markup book/rsf/rsf/prog.tex] using [[latex2wiki]]''</font></center><br />
<br />
This guide introduces some of the most used <tt>madagascar</tt> programs and illustrates their usage with examples.<br />
=Main programs=<br />
The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/ system/main] in the Madagascar distribution. The "main" programs perform general-purpose operations on RSF hypercubes regardless of the data dimensionality or physical dimensions.<br />
<br />
==sfadd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Add, multiply, or divide RSF datasets.<br />
|-<br />
! colspan="4" | sfadd > out.rsf scale= add= sqrt= abs= log= exp= mode= [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | The various operations, if selected, occur in the following order:<br><br>(1) Take absolute value, abs=<br>(2) Add a scalar, add=<br>(3) Take the natural logarithm, log=<br>(4) Take the square root, sqrt=<br>(5) Multiply by a scalar, scale=<br>(6) Compute the base-e exponential, exp=<br>(7) Add, multiply, or divide the data sets, mode=<br><br>sfadd operates on integer, float, or complex data, but all the input<br>and output files must be of the same data type.<br><br>An alternative to sfadd is sfmath, which is more versatile, but may be<br>less efficient.<br />
|-<br />
| ''bools '' || '''abs=''' || || If true take absolute value [nin]<br />
|-<br />
| ''floats '' || '''add=''' || || Scalar values to add to each dataset [nin]<br />
|-<br />
| ''bools '' || '''exp=''' || || If true compute exponential [nin]<br />
|-<br />
| ''bools '' || '''log=''' || || If true take logarithm [nin]<br />
|-<br />
| ''string '' || '''mode=''' || || 'a' means add (default), <br> 'p' or 'm' means multiply, <br> 'd' means divide<br />
|-<br />
| ''floats '' || '''scale=''' || || Scalar values to multiply each dataset with [nin]<br />
|-<br />
| ''bools '' || '''sqrt=''' || || If true take square root [nin]<br />
|}<br />
<br />
<tt>sfadd</tt> is useful for combining (adding, dividing, or<br />
multiplying) several datasets. What if you want to subtract two<br />
datasets? Easy. Use the <tt>scale</tt> parameter as follows:<br />
<pre><br />
bash&#36; sfadd data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfadd < data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
The same task can be accomplished with the more general <tt>sfmath</tt> program:<br />
<pre><br />
bash&#36; sfmath one=data1.rsf two=data2.rsf output='one-two' > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfmath < data1.rsf two=data2.rsf output='input-two' > diff.rsf<br />
</pre><br />
In both cases, the size and shape of <tt>data1.rsf</tt> and<br />
<tt>data2.rsf</tt> hypercubes should be the same, and a warning<br />
message is printed out if the the axis sampling parameters (such as<br />
<tt>o1</tt> or <tt>d1</tt>) in these files are different.<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/add.c?view=markup system/main/add.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
/* find number of input files */<br />
if (isatty(fileno(stdin))) { <br />
/* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Collect input files in the <tt>in</tt> array from all command-line<br />
parameters that don't contain an "<tt>=</tt>" sign. The total number<br />
of input files in <tt>nin</tt>.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) continue; <br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
/* nin = no of input files*/<br />
</c><br />
<br />
A helper function <tt>check_compat</tt> checks the compatibility of<br />
input files.<br />
<c><br />
static void <br />
check_compat (sf_datatype type /* data type */, <br />
size_t nin /* number of files */, <br />
sf_file* in /* input files [nin] */, <br />
int dim /* file dimensionality */, <br />
const int* n /* dimensions [dim] */)<br />
/* Check that the input files are compatible. <br />
Issue error for type mismatch or size mismatch.<br />
Issue warning for grid parameters mismatch. */<br />
{<br />
int ni, id;<br />
size_t i;<br />
float d, di, o, oi;<br />
char key[3];<br />
const float tol=1.e-5; /* tolerance for comparison */<br />
<br />
for (i=1; i < nin; i++) {<br />
if (sf_gettype(in[i]) != type) <br />
sf_error ("type mismatch: need %d",type);<br />
for (id=1; id <= dim; id++) {<br />
(void) snprintf(key,3,"n%d",id);<br />
if (!sf_histint(in[i],key,&ni) || ni != n[id-1])<br />
sf_error("%s mismatch: need %d",key,n[id-1]);<br />
(void) snprintf(key,3,"d%d",id);<br />
if (sf_histfloat(in[0],key,&d)) {<br />
if (!sf_histfloat(in[i],key,&di) || <br />
(fabsf(di-d) > tol*fabsf(d)))<br />
sf_warning("%s mismatch: need %g",key,d);<br />
} else {<br />
d = 1.;<br />
}<br />
(void) snprintf(key,3,"o%d",id);<br />
if (sf_histfloat(in[0],key,&o) && <br />
(!sf_histfloat(in[i],key,&oi) || <br />
(fabsf(oi-o) > tol*fabsf(d))))<br />
sf_warning("%s mismatch: need %g",key,o);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
Finally, we enter the main loop, where input data are getting read<br />
buffer by buffer and combined in the total product depending on the<br />
data type.<br />
<c><br />
for (nbuf /= sf_esize(in[0]); nsiz > 0; nsiz -= nbuf) {<br />
if (nbuf > nsiz) nbuf=nsiz;<br />
<br />
for (j=0; j < nin; j++) {<br />
collect = (bool) (j != 0);<br />
switch(type) {<br />
case SF_FLOAT:<br />
sf_floatread((float*) bufi,<br />
nbuf,<br />
in[j]); <br />
add_float(collect, <br />
nbuf,<br />
(float*) buf,<br />
(const float*) bufi, <br />
cmode, <br />
scale[j], <br />
add[j], <br />
abs_flag[j], <br />
log_flag[j], <br />
sqrt_flag[j], <br />
exp_flag[j]);<br />
break;<br />
</c><br />
<br />
The data combination program for floating point numbers is<br />
<tt>add_float</tt>. <br />
<c><br />
static void add_float (bool collect, /* if collect */<br />
size_t nbuf, /* buffer size */<br />
float* buf, /* output [nbuf] */<br />
const float* bufi, /* input [nbuf] */ <br />
char cmode, /* operation */<br />
float scale, /* scale factor */<br />
float add, /* add factor */<br />
bool abs_flag, /* if abs */<br />
bool log_flag, /* if log */<br />
bool sqrt_flag, /* if sqrt */<br />
bool exp_flag /* if exp */)<br />
/* Add floating point numbers */<br />
{<br />
size_t j;<br />
float f;<br />
<br />
for (j=0; j < nbuf; j++) {<br />
f = bufi[j];<br />
if (abs_flag) f = fabsf(f);<br />
f += add;<br />
if (log_flag) f = logf(f);<br />
if (sqrt_flag) f = sqrtf(f);<br />
if (1. != scale) f *= scale;<br />
if (exp_flag) f = expf(f);<br />
if (collect) {<br />
switch (cmode) {<br />
case 'p': /* product */<br />
case 'm': /* multiply */<br />
buf[j] *= f;<br />
break;<br />
case 'd': /* delete */<br />
if (f != 0.) buf[j] /= f;<br />
break;<br />
default: /* add */<br />
buf[j] += f;<br />
break;<br />
}<br />
} else {<br />
buf[j] = f;<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display dataset attributes.<br />
|-<br />
! colspan="4" | sfattr < in.rsf want=<br />
|-<br />
| colspan="4" | <br>Sample output from "sfspike n1=100 | sfbandpass fhi=60 | sfattr"<br>******************************************* <br>rms = 0.992354 <br>mean value = 0.987576 <br>2-norm value = 9.92354 <br>variance = 0.00955481 <br>standard deviation = 0.0977487 <br>maximum value = 1.12735 at 97 <br>minimum value = 0.151392 at 100 <br>number of nonzero samples = 100 <br>total number of samples = 100 <br>******************************************* <br><br>rms = sqrt[ sum(data^2) / n ]<br>mean = sum(data) / n<br>norm = sum(abs(data)^lval)^(1/lval)<br>variance = [ sum(data^2) - n*mean^2 ] / [ n-1 ]<br>standard deviation = sqrt [ variance ]<br />
|-<br />
| ''int '' || '''lval=2''' || || norm option, lval is a non-negative integer, computes the vector lval-norm<br />
|-<br />
| ''string '' || '''want=''' || || 'all'(default),'rms','mean','norm','var','std','max','min','nonzero','samples','short' <br />
:want= 'rms' displays the root mean square<br />
:want= 'norm' displays the square norm, otherwise specified by lval.<br />
:want= 'var' displays the variance<br />
:want= 'std' displays the standard deviation<br />
:want= 'nonzero' displays number of nonzero samples<br />
:want= 'samples' displays total number of samples<br />
:want= 'short' displays a short one-line version<br />
|}<br />
<br />
<br />
<tt>sfattr</tt> is a useful diagnostic program. It reports certain<br />
statistical values for an RSF dataset: RMS (root-mean-square)<br />
amplitude, mean value, vector norm value, variance, standard deviation,<br />
maximum and minimum values, number of nonzero samples, and the total<br />
number of samples.<br />
If we denote data values as <math>d_i</math> for <math>i=0,1,2,\ldots,n</math>, then the RMS<br />
value is <math>\sqrt{\frac{1}{n}\,\sum\limits_{i=0}^n d_i^2}</math>, the mean<br />
value is <math>\frac{1}{n}\,\sum\limits_{i=0}^n d_i</math>, the <math>L_2</math>-norm value<br />
is <math>\sqrt{\sum\limits_{i=0}^n d_i^2}</math>, the variance is<br />
<math>\frac{1}{n-1}\,\left[\sum\limits_{i=0}^n d_i^2 - \frac{1}{n}\left(\sum\limits_{i=0}^n d_i\right)^2\right]</math>, and the standard<br />
deviation is the square root of the variance. Using <tt>sfattr</tt><br />
is a quick way to see the distribution of data values and check it for anomalies.<br />
<br />
The output can be parsed using utilities such as <tt>awk</tt>, to extract only a numeric value for feeding it as a parameter value into a command line interface. Notice the backticks in the example below:<br />
<bash><br />
sfgrey <vel.rsf allpos=y bias=`sfattr <vel.rsf want=min | awk '{print $4}'` | xtpen<br />
</bash><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/attr.c?view=markup system/main/attr.c]====<br />
<br />
Computations start by finding the input data (<tt>in</tt>) size<br />
(<tt>nsiz</tt>) and dimensions (<tt>dim</tt>).<br />
<c><br />
dim = (size_t) sf_filedims (in,n);<br />
for (nsiz=1, i=0; i < dim; i++) {<br />
nsiz *= n[i];<br />
}<br />
</c><br />
<br />
<br />
In the main loop, we read the input data buffer by buffer.<br />
<c><br />
for (nleft=nsiz; nleft > 0; nleft -= nbuf) {<br />
nbuf = (bufsiz < nleft)? bufsiz: nleft;<br />
switch (type) {<br />
case SF_FLOAT: <br />
sf_floatread((float*) buf,nbuf,in);<br />
break;<br />
case SF_INT:<br />
sf_intread((int*) buf,nbuf,in);<br />
break;<br />
case SF_COMPLEX:<br />
sf_complexread((sf_complex*) buf,nbuf,in);<br />
break;<br />
case SF_UCHAR:<br />
sf_ucharread((unsigned char*) buf,nbuf,in);<br />
break;<br />
case SF_CHAR:<br />
default:<br />
sf_charread(buf,nbuf,in);<br />
break;<br />
}<br />
</c><br />
<br />
<br />
The data attributes are accumulated in corresponding double-precision<br />
variables. <br />
<c><br />
fsum += f;<br />
fsqr += f*f;<br />
</c><br />
<br />
<br />
Finally, the attributes are reduced and printed out.<br />
<c><br />
fmean = fsum/nsiz;<br />
if (lval==2) fnorm = sqrt(fsqr);<br />
else if (lval==0) fnorm = nsiz-nzero;<br />
else fnorm = pow(flval,1./lval);<br />
frms = sqrt(fsqr/nsiz);<br />
if (nsiz > 1) fvar = (fsqr-nsiz*fmean*fmean)/(nsiz-1);<br />
else fvar = 0.0;<br />
fstd = sqrt(fvar);<br />
</c><br />
<br />
<c><br />
if(NULL==want || 0==strcmp(want,"rms"))<br />
printf("rms = %g \n",(float) frms);<br />
if(NULL==want || 0==strcmp(want,"mean"))<br />
printf("mean value = %g \n",(float) fmean);<br />
if(NULL==want || 0==strcmp(want,"norm"))<br />
printf("%d-norm value = %g \n",lval,(float) fnorm);<br />
if(NULL==want || 0==strcmp(want,"var"))<br />
printf("variance = %g \n",(float) fvar);<br />
if(NULL==want || 0==strcmp(want,"std"))<br />
printf("standard deviation = %g \n",(float) fstd);<br />
</c><br />
<br />
==sfcat==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Concatenate datasets. <br />
|-<br />
! colspan="4" | sfcat > out.rsf space= axis=3 nspace=(int) (ni/(20*nin) + 1) [<file0.rsf] file1.rsf file2.rsf ... <br />
|-<br />
| colspan="4" | sfmerge inserts additional space between merged data.<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis being merged<br />
|-<br />
| ''int '' || '''nspace=(int) (ni/(20*nin) + 1)''' || || if space=y, number of traces to insert<br />
|-<br />
| ''bool '' || '''space=''' || [y/n] || Insert additional space.<br />
:y is default for sfmerge, n is default for sfcat<br />
|}<br />
<br />
<br />
<tt>sfcat</tt> and <tt>sfmerge</tt> concatenate two or more files<br />
together along a particular axis. It is the same program, only<br />
<tt>sfcat</tt> has the default <tt>space=n</tt> and <tt>sfmerge</tt><br />
has the default <tt>space=y</tt>.<br />
Example of <tt>sfcat</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcat one.rsf one.rsf axis=1 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=4 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
12 elements 48 bytes<br />
</pre><br />
Example of <tt>sfmerge</tt>:<br />
<pre><br />
bash$ sfmerge one.rsf one.rsf axis=2 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=7 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
14 elements 56 bytes<br />
</pre><br />
In this case, an extra empty trace is inserted between the two merged files.<br />
The axes that are not being merged are checked for consistency:<br />
<pre><br />
bash$ sfcat one.rsf two.rsf > three.rsf<br />
sfcat: n2 mismatch: need 3<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cat.c?view=markup system/main/cat.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
in = (sf_file*) sf_alloc ((size_t) argc,sizeof(sf_file));<br />
<br />
if (!sf_stdin()) { /* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Everything on the command line that does not contain a "=" sign is<br />
treated as a file name, and the corresponding file object is added to the list.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) <br />
continue; /* not a file */<br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
</c><br />
<br />
As explained above, if the <tt>space=</tt> parameter is not set, it is<br />
inferred from the program name: <tt>sfmerge</tt> corresponds to<br />
<tt>space=y</tt> and <tt>sfcat</tt> corresponds to <tt>space=n</tt>.<br />
<c><br />
if (!sf_getbool("space",&space)) {<br />
/* Insert additional space.<br />
y is default for sfmerge, n is default for sfcat */<br />
prog = sf_getprog();<br />
if (NULL != strstr (prog, "merge")) {<br />
space = true;<br />
} else if (NULL != strstr (prog, "cat")) {<br />
space = false;<br />
} else {<br />
sf_warning("%s is neither merge nor cat,"<br />
" assume merge",prog);<br />
space = true;<br />
}<br />
}<br />
</c><br />
<br />
Find the axis for the merging (from the command line <tt>axis=</tt><br />
argument) and figure out two sizes: <tt>n1</tt> for everything after<br />
the axis and <tt>n2</tt> for everything before the axis.<br />
<c><br />
n1=1;<br />
n2=1;<br />
for (i=1; i <= dim; i++) {<br />
if (i < axis) n1 *= n[i-1];<br />
else if (i > axis) n2 *= n[i-1];<br />
}<br />
</c><br />
<br />
In the output, the selected axis will get extended.<br />
<c><br />
/* figure out the length of extended axis */<br />
ni = 0;<br />
for (j=0; j < nin; j++) {<br />
ni += naxis[j];<br />
}<br />
<br />
if (space) {<br />
if (!sf_getint("nspace",&nspace)) <br />
nspace = (int) (ni/(20*nin) + 1);<br />
/* if space=y, number of traces to insert */ <br />
ni += nspace*(nin-1);<br />
} <br />
<br />
(void) snprintf(key,3,"n%d",axis);<br />
sf_putint(out,key,(int) ni);<br />
</c><br />
<br />
The rest is simple: loop through the datasets reading and writing the<br />
data in buffer-size chunks and adding extra empty chunks if<br />
<tt>space=y</tt>.<br />
<c><br />
for (i2=0; i2 < n2; i2++) {<br />
for (j=0; j < nin; j++) {<br />
for (ni = n1*naxis[j]*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charread (buf,nbuf,in[j]);<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
if (!space || j == nin-1) continue;<br />
/* Add spaces */<br />
memset(buf,0,BUFSIZ);<br />
for (ni = n1*nspace*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfcmplx==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a complex dataset from its real and imaginary parts.<br />
|-<br />
! colspan="4" | sfcmplx > cmplx.rsf real.rsf imag.rsf<br />
|-<br />
| colspan="4" | There has to be only two input files specified and no additional parameters.<br />
|}<br />
<br />
<br />
<tt>sfcmplx</tt> simply creates a complex dataset from its real and<br />
imaginary parts. The reverse operation can be accomplished with<br />
<tt>sfreal</tt> and <tt>sfimag</tt>.<br />
Example of <tt>sfcmplx</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcmplx one.rsf one.rsf > cmplx.rsf<br />
bash$ sfin cmplx.rsf<br />
cmplx.rsf:<br />
in="/tmp/cmplx.rsf@"<br />
esize=8 type=complex form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 48 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cmplx.c?view=markup system/main/cmplx.c]====<br />
The program flow is simple. First, get the names of the input files.<br />
<c><br />
/* the first two non-parameters are real and imaginary files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == real) {<br />
real = sf_input (argv[i]);<br />
} else {<br />
imag = sf_input (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == imag) {<br />
if (NULL == real) sf_error ("not enough input");<br />
/* if only one input, real is in stdin */<br />
imag = real;<br />
real = sf_input("in");<br />
}<br />
</c><br />
<br />
The main part of the program reads the real and imaginary parts buffer by buffer and assembles and writes out the complex input. <br />
<c><br />
for (nleft= (size_t) (rsize*resize); nleft > 0; nleft -= nbuf) {<br />
nbuf = (BUFSIZ < nleft)? BUFSIZ: nleft;<br />
sf_charread(rbuf,nbuf,real);<br />
sf_charread(ibuf,nbuf,imag);<br />
for (i=0; i < nbuf; i += resize) {<br />
memcpy(cbuf+2*i, rbuf+i,(size_t) resize);<br />
memcpy(cbuf+2*i+resize,ibuf+i,(size_t) resize);<br />
}<br />
sf_charwrite(cbuf,2*nbuf,cmplx);<br />
}<br />
</c><br />
<br />
==sfconjgrad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic conjugate-gradient solver for linear inversion <br />
|-<br />
! colspan="4" | sfconjgrad < dat.rsf mod=mod.rsf > to.rsf < from.rsf > out.rsf niter=1<br />
|-<br />
| ''int '' || '''niter=1''' || || number of iterations<br />
|}<br />
<br />
<tt>sfconjgrad</tt> is a generic program for least-squares linear<br />
inversion with the [http://en.wikipedia.org/wiki/Conjugate_gradient_method conjugate-gradient method]. Suppose you have an<br />
executable program <tt><prog></tt> that takes an RSF file from the<br />
standard input and produces an RSF file in the standard output. It may<br />
take any number of additional parameters but one of them must be<br />
<tt>adj=</tt> that sets the forward (<tt>adj=0</tt>) or adjoint<br />
(<tt>adj=1</tt>) operations. The program <tt><prog></tt> is typically<br />
an RSF program but it could be anything (a script, a multiprocessor<br />
MPI program, etc.) as long as it implements a linear operator<br />
<math>\mathbf{L}</math> and its adjoint. There are no restrictions on the data<br />
size or shape. You can easily test the adjointness with<br />
<tt>sfdottest</tt>. The <tt>sfconjgrad</tt> program searches for a<br />
vector <math>\mathbf{m}</math> that minimizes the least-square misfit <br />
<math>\|\mathbf{d - L\,m}\|^2</math> for the given input data vector <math>\mathbf{d}</math>. <br />
<br />
The pseudocode for <tt>sfconjgrad</tt> is given at the end of the [http://www.reproducibility.org/RSF/book/gee/lsq/paper.pdf "Model fitting with least squares" chapter] of ''Imaging Estimation by Example'' by Jon Claerbout, with the earliest form published in [http://sepwww.stanford.edu/data/media/public/oldreports/sep48/48_25.pdf "Conjugate Gradient Tutorial"] (SEP-48, 1986, same author). A simple toy implementation with a small matrix shows that this is algorithm produces the same steps as the algorithm described in equations 45-49 of [http://www.cs.cmu.edu/~quake-papers/painless-conjugate-gradient.pdf "An introduction to the Conjugate Gradient Method Without the Agonizing Pain"] by J.R. Shewchuk, 1994, when the equation <math>A^T A x = A^T b</math> (in Shewchuk's notation) is solved. Multiplying with the transpose ensures a correct solution even when matrix A is square but not symmetric, or not square at all. The program [http://www.reproducibility.org/RSF/sfcconjgrad.html sfcconjgrad] implements this algorithm for the case when inputs are complex.<br />
<br />
Here is an example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
The <tt>sfdottest</tt> program can perform the dot product test to<br />
check that the adjoint mode works correctly.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=5.28394<br />
sfdottest: L'[d]*m=5.28394<br />
</pre><br />
Your numbers may be different because <tt>sfdottest</tt> generates new<br />
random input on each run.<br />
Next, let us make some random data with <tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfnoise seed=2005 rep=y < vec.rsf > dat.rsf<br />
</pre><br />
and try to invert the filtering operation using <tt>sfconjgrad</tt>:<br />
<pre><br />
bash$ sfconjgrad sfhelicon filt=flt.rsf lag=lag.rsf \<br />
mod=vec.rsf < dat.rsf > mod.rsf niter=10<br />
sfconjgrad: iter 1 of 10<br />
sfconjgrad: grad=3253.65<br />
sfconjgrad: iter 2 of 10<br />
sfconjgrad: grad=289.421<br />
sfconjgrad: iter 3 of 10<br />
sfconjgrad: grad=92.3481<br />
sfconjgrad: iter 4 of 10<br />
sfconjgrad: grad=36.9417<br />
sfconjgrad: iter 5 of 10<br />
sfconjgrad: grad=18.7228<br />
sfconjgrad: iter 6 of 10<br />
sfconjgrad: grad=11.1794<br />
sfconjgrad: iter 7 of 10<br />
sfconjgrad: grad=7.26941<br />
sfconjgrad: iter 8 of 10<br />
sfconjgrad: grad=5.15945<br />
sfconjgrad: iter 9 of 10<br />
sfconjgrad: grad=4.23055<br />
sfconjgrad: iter 10 of 10<br />
sfconjgrad: grad=3.57495<br />
</pre><br />
The output shows that, in 10 iterations, the norm of the gradient vector decreases by almost 1000. <br />
We can check the residual misfit before<br />
<pre><br />
bash$ < dat.rsf sfattr want=norm<br />
norm value = 49.7801<br />
</pre><br />
and after<br />
<pre><br />
bash$ sfhelicon filt=flt.rsf lag=lag.rsf < mod.rsf | \<br />
sfadd scale=1,-1 dat.rsf | sfattr want=norm<br />
norm value = 5.73563<br />
</pre><br />
In 10 iterations, the misfit decreased by an order of magnitude. The<br />
result can be improved by running the program for more iterations.<br />
<br />
An equivalent implementation for complex-valued inputs is [http://www.reproducibility.org/RSF/sfcconjgrad.html sfcconjgrad]. A simple, lightweight Python implementation can be found in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/fomels/conjgrad.py?view=markup $RSFROOT/lib/conjgrad.py].<br />
<br />
==sfcp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Copy or move a dataset.<br />
|-<br />
! colspan="4" | sfcp in.rsf out.rsf<br />
|-<br />
| colspan="4" | sfcp - copy, sfmv - move.<br>Mimics standard Unix commands.<br />
|}<br />
<br />
<br />
The <tt>sfcp</tt> and <tt>sfmv</tt> command imitate the Unix<br />
<tt>cp</tt> and <tt>mv</tt> commands and serve for copying and moving<br />
RSF files. Example:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcp one.rsf two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cp.c?view=markup system/main/cp.c]====<br />
First, we look for the two first command-line arguments that don't<br />
have the "=" character in them and consider them as the names of the<br />
input and the output files. <br />
<c><br />
/* the first two non-parameters are in and out files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == in) {<br />
infile = argv[i];<br />
in = sf_input (infile);<br />
} else {<br />
out = sf_output (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == in || NULL == out)<br />
sf_error ("not enough input");<br />
</c><br />
<br />
Next, we use library functions <font color="#cd4b19">sf_cp</font> and <font color="#cd4b19">sf_rm</font> to do the actual work.<br />
<c><br />
sf_cp(in,out);<br />
if (NULL != strstr (sf_getprog(),"mv")) <br />
sf_rm(infile,false,false,false);<br />
</c><br />
<br />
==sfcut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of the dataset. <br />
|-<br />
! colspan="4" | sfcut < in.rsf > out.rsf verb=n [j1=1 j2=1 ... f1=0 f2=0 ... n1=n1 n2=n2 ... max1= max2= ... min1= min2= ...]<br />
|-<br />
| colspan="4" | jN defines the jump in N-th dimension<br>fN is the window start<br>nN is the window size<br>minN and maxN is the maximum and minimum in N-th dimension<br><br>Reverse of window. <br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
The <tt>sfcut</tt> command is related to <tt>sfwindow</tt> and has the same<br />
set of arguments only instead of extracting the selected window, it fills it<br />
with zeroes. The size of the input data is preserved. <br />
Examples:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > in.rsf<br />
bash$ < in.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < in.rsf sfcut n1=2 f1=1 n2=3 f2=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 0 0 1 1<br />
15: 1 0 0 1 1<br />
20: 1 0 0 1 1<br />
bash$ < in.rsf sfcut j1=2 | sfdisfil<br />
0: 0 1 0 1 0<br />
5: 0 1 0 1 0<br />
10: 0 1 0 1 0<br />
15: 0 1 0 1 0<br />
20: 0 1 0 1 0<br />
</pre><br />
<br />
==sfdd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert between different formats. <br />
|-<br />
! colspan="4" | sfdd < in.rsf > out.rsf line=8 form= type= format=<br />
|-<br />
| ''string '' || '''form=''' || || ascii, native, xdr<br />
|-<br />
| ''string '' || '''format=''' || || Element format (for conversion to ASCII)<br />
|-<br />
| ''int '' || '''line=8''' || || Number of numbers per line (for conversion to ASCII)<br />
|-<br />
| ''string '' || '''type=''' || || int, float, complex<br />
|}<br />
<br />
<br />
The <tt>sfdd</tt> program is used to change either the form (<tt>ascii</tt>,<br />
<tt>xdr</tt>, <tt>native</tt>) or the type (<tt>complex</tt>, <tt>float</tt>,<br />
<tt>int</tt>, <tt>char</tt>) of the input dataset. <br />
In the example below, we create a plain text (ASCII) file with numbers and<br />
then use <tt>sfdd</tt> to generate an RSF file in <tt>xdr</tt> form with<br />
<tt>complex</tt> numbers. <br />
<pre><br />
bash$ cat test.txt<br />
1 2 3 4 5 6<br />
bash$ echo n1=6 data_format=ascii_int in=test.txt > test.rsf<br />
bash$ sfin test.rsf<br />
test.rsf:<br />
in="test.txt"<br />
esize=0 type=int form=ascii<br />
n1=6 d1=? o1=?<br />
6 elements<br />
bash$ sfdd < test.rsf form=xdr type=complex > test2.rsf<br />
bash$ sfin test2.rsf<br />
test2.rsf:<br />
in="/tmp/test2.rsf@"<br />
esize=8 type=complex form=xdr<br />
n1=3 d1=? o1=?<br />
3 elements 24 bytes<br />
bash$ sfdisfil < test2.rsf<br />
0: 1, 2i 3, 4i 5, 6i<br />
</pre><br />
To learn more about the RSF data format, consult the [[Format| guide to RSF format]].<br />
<br />
==sfdisfil==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Print out data values.<br />
|-<br />
! colspan="4" | sfdisfil < in.rsf number=y col=0 format= header= trailer=<br />
|-<br />
| colspan="4" | <br>Alternatively, use sfdd and convert to ASCII form.<br />
|-<br />
| ''int '' || '''col=0''' || || Number of columns.<br />
:The default depends on the data type:<br />
:10 for int and char,<br />
:5 for float,<br />
:3 for complex<br />
|-<br />
| ''string '' || '''format=''' || || Format for numbers (printf-style).<br />
:The default depends on the data type:<br> "%4d " for int and char,<br> "%13.4g" for float,<br> "%10.4g,%10.4gi" for complex<br />
|-<br />
| ''string '' || '''header=''' || || Optional header string to output before data<br />
|-<br />
| ''bool '' || '''number=y''' || [y/n] || If number the elements<br />
|-<br />
| ''string '' || '''trailer=''' || || Optional trailer string to output after data<br />
|}<br />
<br />
<br />
The <tt>sfdisfil</tt> program simply dumps the data contents to the standard<br />
output in a text form. It is used mostly for debugging purposes to quickly<br />
examine RSF files. Here is an example:<br />
<pre><br />
bash$ sfmath o1=0 d1=2 n1=12 output=x1 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
10: 20 22<br />
</pre><br />
The output format is easily configurable.<br />
<pre><br />
bash$ < test.rsf sfdisfil col=6 number=n format="<br />
0.0 2.0 4.0 6.0 8.0 10.0<br />
12.0 14.0 16.0 18.0 20.0 22.0<br />
</pre><br />
Along with <tt>sfdd</tt>, <tt>sfdisfil</tt> provides a simple way to convert<br />
RSF data to an ASCII form.<br />
<br />
==sfdottest==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic dot-product test for linear operators with adjoints <br />
|-<br />
! colspan="4" | sfdottest mod=mod.rsf dat=dat.rsf > pip.rsf<br />
|}<br />
<br />
<br />
<tt>sfdottest</tt> is a generic dot-product test program for testing<br />
linear operators. Suppose there is an executable program<br />
<tt><prog></tt> that takes an RSF file from the standard input and<br />
produces an RSF file in the standard output. It may take any number of<br />
additional parameters but one of them must be <tt>adj=</tt> that sets<br />
the forward (<tt>adj=0</tt>) or adjoint (<tt>adj=1</tt>) operations.<br />
The program <tt><prog></tt> is typically an RSF program but it could<br />
be anything (a script, a multiprocessor MPI program, etc.) as long as<br />
it implements a linear operator <math>\mathbf{L}</math> and its adjoint<br />
<math>\mathbf{L}^T</math>. The <tt>sfdottest</tt> program is testing the equality<br />
<center><math><br />
d^T\,L\,m = m^T\,L^T\,d<br />
</math></center><br />
by using random vectors <math>\mathbf{m}</math> and <math>\mathbf{d}</math>. You can invoke it with<br />
<pre><br />
bash$ sfdottest <prog> [optional aruments] mod=mod.rsf dat=dat.rsf<br />
</pre><br />
where <tt>mod.rsf</tt> and <tt>dat.rsf</tt> are RSF files that<br />
represent vectors from the model and data spaces. Pay attention to the <br />
dimension and size of these vectors! If the program does not respond<br />
for a very long time, it is quite possible that the dimension and size<br />
of the vectors are inconsistent with the requirement of the program to be<br />
tested. <tt>sfdottest</tt><br />
does not create any temporary files and does not have any restrictive<br />
limitations on the size of the vectors.<br />
Here is an example. We first setup a vector with 100 elements using<br />
<tt>sfspike</tt> and then run <tt>sfdottest</tt> to test the<br />
<tt>sfcausint</tt> program. <tt>sfcausint</tt> implements a linear<br />
operator of causal integration and its adjoint, the anti-causal<br />
integration.<br />
<pre><br />
bash$ sfspike n1=100 > vec.rsf<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1410.2<br />
sfdottest: L'[d]*m=1410.2<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1165.87<br />
sfdottest: L'[d]*m=1165.87<br />
</pre><br />
The numbers are different on subsequent runs because of changing<br />
seed in the random number generator.<br />
Here is a somewhat more complicated example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
Now the <tt>sfdottest</tt> program can perform the dot product test.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=8.97375<br />
sfdottest: L'[d]*m=8.97375<br />
</pre><br />
Here is the same program tested in the inverse filtering mode:<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf inv=y<br />
sfdottest: L[m]*d=15.0222<br />
sfdottest: L'[d]*m=15.0222<br />
</pre><br />
<br />
==sfget==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Output parameters from the header.<br />
|-<br />
! colspan="4" | sfget < in.rsf parform=y par1 par2 ...<br />
|-<br />
| ''bool '' || '''parform=y''' || [y/n] || If y, print out parameter=value. If n, print out value.<br />
|}<br />
<br />
<br />
The <tt>sfget</tt> program extracts a parameter value from an RSF file. It is<br />
useful mostly for scripting. Here is, for example, a quick calculation of the<br />
maximum value on the first axis in an RSF dataset (the output of<br />
<tt>sfspike</tt>) using the standard Unix <tt>bc</tt> calculator.<br />
<pre><br />
bash$ ( sfspike n1=100 | sfget n1 d1 o1; echo "o1+(n1-1)*d1" ) | bc<br />
.396<br />
</pre><br />
See also <tt>sfput</tt>.<br />
<br />
<br />
<br />
==sfheadercut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheadercut mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array of size n2.<br />
|}<br />
<br />
<br />
<tt>sfheadercut</tt> is close to <tt>sfheaderwindow</tt> but instead<br />
of windowing the dataset, it fills the traces specified by the header<br />
mask with zeroes. The size of the input data is preserved.<br />
Here is an example of using <tt>sfheaderwindow</tt> for <br />
zeroing every other trace in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a mask with alternating ones and zeros using<br />
<tt>sfinterleave</tt>.<br />
<pre><br />
bash$ sfspike n1=5 mag=1 | sfdd type=int > ones.rsf<br />
bash$ sfspike n1=5 mag=0 | sfdd type=int > zeros.rsf<br />
bash$ sfinterleave axis=1 ones.rsf zeros.rsf > mask.rsf<br />
bash$ sfdisfil < mask.rsf<br />
0: 1 0 1 0 1 0 1 0 1 0<br />
</pre><br />
Finally, <tt>sfheadercut</tt> zeros the input traces.<br />
<pre><br />
bash$ sfheadercut < input.rsf mask=mask.rsf > output.rsf<br />
bash$ sfdisfil < output.rsf <br />
0: 1 1 1 1 1<br />
5: 0 0 0 0 0<br />
10: 3 3 3 3 3<br />
15: 0 0 0 0 0<br />
20: 5 5 5 5 5<br />
25: 0 0 0 0 0<br />
30: 7 7 7 7 7<br />
35: 0 0 0 0 0<br />
40: 9 9 9 9 9<br />
45: 0 0 0 0 0<br />
</pre><br />
<br />
<br />
<br />
==sfheadersort==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Sort a dataset according to a header key. <br />
|-<br />
! colspan="4" | sfheadersort < in.rsf > out.rsf head=<br />
|-<br />
| ''string '' || '''head=''' || || header file<br />
|}<br />
<br />
<br />
<tt>sfheadersort</tt> is used to sort traces in the input file<br />
according to trace header information. <br />
Here is an example of using<br />
<tt>sfheadersort</tt> for randomly shuffling traces in the input<br />
file. First, let us create an input file with seven traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=7 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7 <br />
</pre><br />
Next, we can create a random file with seven header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=7 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: 0.05256 -0.2879 0.1487 0.4097 0.1548<br />
5: 0.4501 0.2836<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally, we<br />
apply <tt>sfheadersort</tt> to shuffle the input traces.<br />
<pre><br />
bash$ < input.rsf sfheadersort head=random.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 1 1 1 1 1<br />
10: 3 3 3 3 3<br />
15: 5 5 5 5 5<br />
20: 7 7 7 7 7<br />
25: 4 4 4 4 4<br />
30: 6 6 6 6 6<br />
</pre><br />
As expected, the order of traces in the output file corresponds to the<br />
order of values in the header. Thanks to the separation between<br />
headers and data, the operation of <tt>sfheadersort</tt> is optimally<br />
efficient. It first sorts the headers and only then accesses the data,<br />
reading each data trace only once.<br />
<br />
==sfheaderwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheaderwindow mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array os size n2, windowed is n1xm2,<br>where m2 is the number of nonzero elements in mask.<br />
|}<br />
<br />
<br />
<tt>sfheaderwindow</tt> is used to window traces in the input file<br />
according to trace header information. <br />
Here is an example of using <tt>sfheaderwindow</tt> for randomly<br />
selecting part of the traces in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a random file with ten header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=10 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: -0.005768 0.02258 -0.04331 -0.4129 -0.3909<br />
5: -0.03582 0.4595 -0.3326 0.498 -0.3517<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally,<br />
we apply <tt>sfheaderwindow</tt> to window the input traces selecting<br />
only those for which the header is greater than zero.<br />
<pre><br />
bash$ < random.rsf sfmask min=0 > mask.rsf<br />
bash$ < mask.rsf sfdisfil<br />
0: 0 1 0 0 0 0 1 0 1 0<br />
bash$ < input.rsf sfheaderwindow mask=mask.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 7 7 7 7 7<br />
10: 9 9 9 9 9<br />
</pre><br />
In this case, only three traces are selected for the output. Thanks to<br />
the separation between headers and data, the operation of<br />
<tt>sfheaderwindow</tt> is optimally efficient. <br />
<br />
==sfin==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display basic information about RSF files.<br />
|-<br />
! colspan="4" | sfin info=y check=2. trail=y file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | n1,n2,... are data dimensions<br>o1,o2,... are axis origins<br>d1,d2,... are axis sampling intervals<br>label1,label2,... are axis labels<br>unit1,unit2,... are axis units<br />
|-<br />
| ''float '' || '''check=2.''' || || Portion of the data (in Mb) to check for zero values.<br />
|-<br />
| ''bool '' || '''info=y''' || [y/n] || If n, only display the name of the data file.<br />
|-<br />
| ''bool '' || '''trail=y''' || [y/n] || If n, skip trailing dimensions of one<br />
|}<br />
<br />
<br />
<tt>sfin</tt> is one of the most useful programs for operating with<br />
RSF files. It produces quick information on the file hypercube<br />
dimensions and checks the consistency of the associated data file.<br />
Here is an example. Let us create an RSF file and examine it with <tt>sfin</tt>.<br />
<pre><br />
bash$ sfspike n1=100 n2=20 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=100 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
2000 elements 8000 bytes<br />
</pre><br />
<tt>sfin</tt> reports the following information:<br />
<br />
*location of the data file (<tt>/tmp/spike.rsf\@</tt>) <br />
*element size (4 bytes) <br />
*element type (floating point) <br />
*element form (native) <br />
*hypercube dimensions (100 by 20) <br />
*axes scale (0.004 and 0.1) <br />
*axes origin (0 and 0) <br />
*axes labels <br />
*axes units <br />
*total number of elements <br />
*total number of bytes in the data file <br />
Suppose that the file got corrupted by a buggy program and reports<br />
incorrect dimensions. The <tt>sfin</tt> program should be able to<br />
catch the discrepancy.<br />
<pre><br />
bash$ echo n2=100 >> spike.rsf<br />
bash$ sfin spike.rsf > /dev/null<br />
sfin: Actually 8000 bytes, 20% of expected.<br />
</pre><br />
<tt>sfin</tt> also checks the first records in the file for zeros. <br />
<pre><br />
bash$ sfspike n1=100 n2=100 k2=99 > spike2.rsf<br />
bash$ sfin spike2.rsf >/dev/null<br />
sfin: The first 32768 bytes are all zeros<br />
</pre><br />
The number of bytes to check is adjustable<br />
<pre><br />
bash$ sfin spike2.rsf check=0.01 >/dev/null<br />
sfin: The first 16384 bytes are all zeros<br />
</pre><br />
You can also output only the location of the data file. This is<br />
sometimes handy in scripts.<br />
<pre><br />
bash$ sfin spike.rsf spike2.rsf info=n<br />
/tmp/spike.rsf@ /tmp/spike2.rsf@<br />
</pre><br />
An alternative is to use <tt>sfget</tt>, as follows:<br />
<pre><br />
bash$ sfget parform=n in < spike.rsf<br />
/tmp/spike.rsf@<br />
</pre><br />
<br />
==sfinterleave==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Combine several datasets by interleaving.<br />
|-<br />
! colspan="4" | sfinterleave > out.rsf axis=3 [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis for interleaving<br />
|}<br />
<br />
<br />
<tt>sfinterleave</tt> combines two or more datasets by interleaving them on one<br />
of the axes. Here is a quick example:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ sfscale < one.rsf dscale=2 > two.rsf<br />
bash$ sfdisfil < two.rsf<br />
0: 2 2 2 2 2<br />
5: 2 2 2 2 2<br />
10: 2 2 2 2 2<br />
15: 2 2 2 2 2<br />
20: 2 2 2 2 2<br />
bash$ sfinterleave one.rsf two.rsf axis=1 | sfdisfil<br />
0: 1 2 1 2 1<br />
5: 2 1 2 1 2<br />
10: 1 2 1 2 1<br />
15: 2 1 2 1 2<br />
20: 1 2 1 2 1<br />
25: 2 1 2 1 2<br />
30: 1 2 1 2 1<br />
35: 2 1 2 1 2<br />
40: 1 2 1 2 1<br />
45: 2 1 2 1 2<br />
bash$ sfinterleave < one.rsf two.rsf axis=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 1 1 1 1 1<br />
15: 2 2 2 2 2<br />
20: 1 1 1 1 1<br />
25: 2 2 2 2 2<br />
30: 1 1 1 1 1<br />
35: 2 2 2 2 2<br />
40: 1 1 1 1 1<br />
45: 2 2 2 2 2<br />
</pre><br />
<br />
==sfmask==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a mask.<br />
|-<br />
! colspan="4" | sfmask < in.rsf > out.rsf min=-FLT_MAX max=+FLT_MAX<br />
|-<br />
| colspan="4" | <br>Mask is an integer data with ones and zeros. <br>Ones correspond to input values between min and max.<br><br>The output can be used with sfheaderwindow.<br />
|-<br />
| ''float '' || '''max=+FLT_MAX''' || || maximum header value<br />
|-<br />
| ''float '' || '''min=-FLT_MAX''' || || minimum header value<br />
|}<br />
<br />
<br />
<tt>sfmask</tt> creates an integer output of ones and zeros comparing<br />
the values of the input data to specified <tt>min=</tt> and<br />
<tt>max=</tt> parameters. It is useful for <tt>sfheaderwindow</tt> and<br />
in many other applications. Here is a quick example:<br />
<pre><br />
bash$ sfmath n1=10 output="sin(x1)" > sin.rsf<br />
bash$ < sin.rsf sfdisfil<br />
0: 0 0.8415 0.9093 0.1411 -0.7568<br />
5: -0.9589 -0.2794 0.657 0.9894 0.4121<br />
bash$ < sin.rsf sfmask min=-0.5 max=0.5 | sfdisfil<br />
0: 1 0 0 1 0 0 1 0 0 1<br />
</pre><br />
<br />
==sfmath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations on data files.<br />
|-<br />
! colspan="4" | sfmath > out.rsf type= unit= output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs, conj (for complex data).<br> <br>sfmath will work on float or complex data, but all the input and output<br>files must be of the same data type.<br><br>An alternative to sfmath is sfadd, which may be more efficient, but is<br>less versatile.<br><br>Examples:<br><br>sfmath x=file1.rsf y=file2.rsf power=file3.rsf output='sin((x+2*y)^power)' > out.rsf<br>sfmath < file1.rsf tau=file2.rsf output='exp(tau*input)' > out.rsf<br>sfmath n1=100 type=complex output="exp(I*x1)" > out.rsf<br><br>See also: sfheadermath.<br />
|-<br />
| ''string '' || '''output=''' || || Mathematical description of the output<br />
|-<br />
| ''string '' || '''type=''' || || output data type [float,complex]<br />
|-<br />
| ''string '' || '''unit=''' || || <br />
|}<br />
<br />
<tt>sfmath</tt> is a versatile program for mathematical operations<br />
with RSF files. It can operate with several input file, all of the<br />
same dimensions and data type. The data type can be real (floating<br />
point) or complex. Here is an example that demonstrates several<br />
features of <tt>sfmath</tt>.<br />
<pre><br />
bash$ sfmath n1=629 d1=0.01 o1=0 n2=40 d2=1 o2=5 \<br />
output="x2*(8+sin(6*x1+x2/10))" > rad.rsf<br />
bash$ < rad.rsf sfrtoc | sfmath output="input*exp(I*x1)" > rose.rsf<br />
bash$ < rose.rsf sfgraph title=Rose screenratio=1 wantaxis=n | sfpen<br />
</pre><br />
The first line creates a 2-D dataset that consists of 40 traces 600<br />
samples each. The values of the data are computed with the formula<br />
<font color="#cd4b19">"x2*(8+sin(6*x1+x2/10))"</font>, where <tt>x1</tt> refers to the<br />
coordinate on the first axis, and <tt>x2</tt> is the coordinate of the<br />
second axis. In the second line, we convert the data from real to<br />
complex using <tt>sfrtoc</tt> and produce a complex dataset using<br />
formula <font color="#cd4b19">"input*exp(I*x1)"</font>, where <tt>input</tt> refers to the<br />
input file. Finally, we plot the complex data as a collection of<br />
parametric curves using <tt>sfgraph</tt> and display the result using<br />
<tt>sfpen</tt>. The plot appearing on your screen should look similar<br />
to the figure.<br />
[[Image:rose.png|frame|center|This figure was created with <tt>sfmath</tt>.]]<br />
One possible alternative to the second line above is<br />
<pre><br />
bash$ < rad.rsf sfmath output=x1 > ang.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*cos(a)" > cos.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*sin(a)" > sin.rsf<br />
bash$ sfcmplx cos.rsf sin.rsf > rose.rsf<br />
</pre><br />
Here we refer to input files by names (<tt>r</tt> and <tt>a</tt>) and combine the names in a formula.<br />
<br />
==sfpad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Pad a dataset with zeros.<br />
|-<br />
! colspan="4" | sfpad < in.rsf > out.rsf [beg1= beg2= ... end1= end2=... | n1= n2 = ... | n1out= n2out= ...]<br />
|-<br />
| colspan="4" | begN specifies the number of zeros to add before the beginning of axis N.<br>endN specifies the number of zeros to add after the end of axis N.<br><br>Alternatively:<br><br>nN or nNout specify the output length of axis N, padding occurs at the end.<br>nN and nNout are equivalent.<br />
|}<br />
<br />
<br />
<tt>pad</tt> increases the dimensions of the input dataset by padding<br />
the data with zeroes. Here are some simple examples.<br />
<pre><br />
bash$ sfspike n1=5 n2=3 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
bash$ < one.rsf sfpad n2=5 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 0 0 0 0 0<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfpad beg2=2 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 0 0 0 0<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < one.rsf sfpad beg2=1 end2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfwindow n1=3 | sfpad n1=5 n2=5 beg1=1 beg2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 1 1 1 0<br />
10: 0 1 1 1 0<br />
15: 0 1 1 1 0<br />
20: 0 0 0 0 0<br />
</pre><br />
You can use <tt>sfcat</tt> to pad data with values other than zeroes.<br />
<br />
==sfput==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Input parameters into a header. <br />
|-<br />
! colspan="4" | sfput < in.rsf > out.rsf<br />
|}<br />
<br />
<br />
<tt>sfput</tt> is a very simple program. It simply appends parameters<br />
from the command line to the output RSF file. One can achieve similar<br />
results with editing by hand or with standard Unix utilities like<br />
<tt>sed</tt> and <tt>echo</tt>. <tt>sfput</tt> is sometimes more<br />
convenient because it handles input/output operations similarly to<br />
other regular RSF programs.<br />
<pre><br />
bash$ sfspike n1=10 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
10 elements 40 bytes<br />
bash$ sfput < spike.rsf d1=25 label1=Depth unit1=m > spike2.rsf<br />
bash$ sfin spike2.rsf<br />
spike2.rsf:<br />
in="/tmp/spike2.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=25 o1=0 label1="Depth" unit1="m"<br />
10 elements 40 bytes<br />
</pre><br />
<br />
==sfreal==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extract real (sfreal) or imaginary (sfimag) part of a complex dataset. <br />
|-<br />
! colspan="4" | sfreal < cmplx.rsf > real.rsf<br />
|}<br />
<br />
<br />
<tt>sfreal</tt> extracts the real part of a complex type dataset. The<br />
imaginary part can be extracted with <tt>sfimag</tt>, an the real<br />
and imaginary part can be combined together with <tt>sfcmplx</tt>.<br />
Here is a simple example. Let us first create a complex dataset <br />
with <tt>sfmath</tt><br />
<pre><br />
bash$ sfmath n1=10 type=complex output="(2+I)*x1" > cmplx.rsf<br />
bash$ fdisfil < cmplx.rsf<br />
0: 0, 0i 2, 1i 4, 2i<br />
3: 6, 3i 8, 4i 10, 5i<br />
6: 12, 6i 14, 7i 16, 8i<br />
9: 18, 9i<br />
</pre><br />
Extracting the real part with <tt>sfreal</tt>:<br />
<pre><br />
bash$ sfreal < cmplx.rsf | sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
</pre><br />
Extracting the imaginary part with <tt>sfimag</tt>:<br />
<pre><br />
bash$ sfimag < cmplx.rsf | sfdisfil<br />
0: 0 1 2 3 4<br />
5: 5 6 7 8 9<br />
</pre><br />
<br />
==sfreverse==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Reverse one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfreverse < in.rsf > out.rsf which=-1 verb=false memsize=sf_memsize() opt=<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''opt=''' || || If y, change o and d parameters on the reversed axis;<br />
:if i, don't change o and d<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|-<br />
| ''int '' || '''which=-1''' || || Which axis to reverse.<br />
:To reverse a given axis, start with 0,<br />
:add 1 to number to reverse n1 dimension,<br />
:add 2 to number to reverse n2 dimension,<br />
:add 4 to number to reverse n3 dimension, etc.<br />
:Thus, which=7 would reverse the first three dimensions,<br />
:which=5 just n1 and n3, etc.<br />
:which=0 will just pass the input on through unchanged.<br />
|}<br />
Here is an example of using <tt>sfreverse</tt>. First, let us create a<br />
2-D dataset.<br />
<pre><br />
bash$ sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Reversing the first axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 | sfdisfil<br />
0: 4 3 2 1 0<br />
5: 5 4 3 2 1<br />
10: 6 5 4 3 2<br />
</pre><br />
Reversing the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=2 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
Reversing both the first and the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=3 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
As you can see, the <tt>which=</tt> parameter controls the axes that are<br />
being reversed by encoding them into one number.<br />
When an axis is reversed, what happens with its axis origin and<br />
sampling parameters? This behavior is controlled by <tt>opt=</tt>. In<br />
our example,<br />
<pre><br />
bash$ < test.rsf sfget n1 o1 d1<br />
n1=5<br />
o1=0<br />
d1=1<br />
bash$ < test.rsf sfreverse which=1 | sfget o1 d1<br />
o1=4<br />
d1=-1<br />
</pre><br />
The default behavior (equivalent to <tt>opt=y</tt>) puts the origin<br />
<tt>o1</tt> at the end of the axis and reverses the sampling parameter<br />
<tt>d1</tt>. Using <tt>opt=n</tt> preserves the sampling but reverses<br />
the origin.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=n | sfget o1 d1<br />
o1=-4<br />
d1=1<br />
</pre><br />
Using <tt>opt=i</tt> preserves both the sampling and the origin while<br />
reversing the axis.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=i | sfget o1 d1<br />
o1=0<br />
d1=1<br />
</pre><br />
One of the three possible behaviors may be desirable depending on the<br />
application.<br />
<br />
==sfrm==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Remove RSF files together with their data.<br />
|-<br />
! colspan="4" | sfrm file1.rsf [file2.rsf ...] [-i] [-v] [-f] <br />
|-<br />
| colspan="4" | Mimics the standard Unix rm command.<br><br>See also: sfmv, sfcp.<br />
|}<br />
<br />
<tt>sfrm</tt> is a program for removing RSF files. Its arguments mimic<br />
the arguments of the standard Unix <tt>rm</tt> utility: <tt>-v</tt><br />
for verbosity, <tt>-i</tt> for interactive inquiry, <tt>-f</tt> for<br />
force removal of suspicious files. Unlike the Unix <tt>rm</tt>,<br />
<tt>sfrm</tt> removes both the RSF header files and the binary files<br />
that the headers point to. <br />
Example:<br />
<pre><br />
bash&#36; sfspike n1=10 > spike.rsf datapath=./<br />
bash&#36; sfget in < spike.rsf<br />
in=./spike.rsf@<br />
bash&#36; ls spike*<br />
spike.rsf spike.rsf@<br />
bash&#36; sfrm -v spike.rsf<br />
sfrm: sf_rm: Removing header spike.rsf<br />
sfrm: sf_rm: Removing data ./spike.rsf@<br />
bash&#36; ls spike*<br />
ls: No match.<br />
</pre><br />
==sfrotate==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Rotate a portion of one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfrotate < in.rsf > out.rsf verb=n memsize=sf_memsize() rot#=(0,0,...)<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''rot#=(0,0,...)''' || || length of #-th axis that is moved to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<tt>sfrotate</tt> modifies the input dataset by splitting it into<br />
parts and putting the parts back in a different order. Here is a quick example.<br />
<pre><br />
bash&#36; sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Rotating the first axis by putting the last two columns in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=2 | sfdisfil<br />
0: 3 4 0 1 2<br />
5: 4 5 1 2 3<br />
10: 5 6 2 3 4<br />
</pre><br />
Rotating the second axis by putting the last row in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot2=1 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 0 1 2 3 4<br />
10: 1 2 3 4 5<br />
</pre><br />
Rotating both the first and the second axis:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=3 rot2=1 | sfdisfil<br />
0: 4 5 6 2 3<br />
5: 2 3 4 0 1<br />
10: 3 4 5 1 2<br />
</pre><br />
The transformation is shown schematically in Figure~(fig:rotate).<br />
[[Image:rotate.png|frame|center|Schematic transformation of data with <tt>sfrotate</tt>.]]<br />
<br />
==sfrtoc==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert real data to complex (by adding zero imaginary part).<br />
|-<br />
! colspan="4" | sfrtoc < real.rsf > cmplx.rsf<br />
|-<br />
| colspan="4" | <br>See also: sfcmplx<br />
|}<br />
The input to <tt>sfrtoc</tt> can be any <tt>type=float</tt> dataset:<br />
<pre><br />
bash$ sfspike n1=10 n2=20 n3=30 >real.rsf<br />
bash$ sfin real.rsf<br />
real.rsf:<br />
in="/var/tmp/real.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
</pre><br />
The output dataset will have <tt>type=complex</tt>, and its binary will be twice the size of the input:<br />
<pre><br />
bash$ <real.rsf sfrtoc >complex.rsf<br />
bash$ sfin complex.rsf <br />
complex.rsf:<br />
in="/var/tmp/complex.rsf@"<br />
esize=8 type=complex form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 48000 bytes<br />
</pre><br />
<br />
==sfscale==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Scale data.<br />
|-<br />
! colspan="4" | sfscale < in.rsf > out.rsf axis=0 rscale=0. dscale=1.<br />
|-<br />
| colspan="4" | <br>To scale by a constant factor, you can also use sfmath or sfheadermath.<br />
|-<br />
| ''int '' || '''axis=0''' || || Scale by maximum in the dimensions up to this axis.<br />
|-<br />
| ''float '' || '''dscale=1.''' || || Scale by this factor (works if rscale=0)<br />
|-<br />
| ''float '' || '''rscale=0.''' || || Scale by this factor.<br />
|}<br />
<tt>sfscale</tt> scales the input dataset by a factor. Here<br />
are some simple examples. First, let us create a test dataset.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil <br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Scale every data point by 2:<br />
<pre><br />
bash&#36; < test.rsf sfscale dscale=2 | sfdisfil<br />
0: 2 4 6 8 10<br />
5: 4 8 12 16 20<br />
10: 6 12 18 24 30<br />
</pre><br />
Divide every trace by its maximum value:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=1 | sfdisfil<br />
0: 0.2 0.4 0.6 0.8 1<br />
5: 0.2 0.4 0.6 0.8 1<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
Divide by the maximum value in the whole 2-D dataset:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=2 | sfdisfil<br />
0: 0.06667 0.1333 0.2 0.2667 0.3333<br />
5: 0.1333 0.2667 0.4 0.5333 0.6667<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
The <tt>rscale=</tt> parameter is synonymous to <tt>dscale=</tt> except<br />
when it is equal to zero. With <tt>sfscale dscale=0</tt>, the dataset gets<br />
multiplied by zero. If using <tt>rscale=0</tt>, the other parameters are<br />
used to define scaling. Thus, <tt>sfscale rscale=0 axis=1</tt> is<br />
equivalent to <tt>sfscale axis=1</tt>, and <tt>sfscale rscale=0</tt><br />
is equivalent to <tt>sfscale dscale=1</tt>.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
==sfspike==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate simple data: spikes, boxes, planes, constants.<br />
|-<br />
! colspan="4" | sfspike > spike.rsf mag= nsp=1 k#=[0,...] l#=[k1,k2,...] p#=[0,...] n#= o#=(0,...) d#=(0.004,0.1,0.1,...) label#=(Time,Distance,Distance,...) unit#=[s,km,km,...] title=<br />
|-<br />
| ''float '' || '''d#=(0.004,0.1,0.1,...)''' || || sampling on #-th axis<br />
|-<br />
| ''ints '' || '''k#=[0,...]''' || || spike starting position [nsp]<br />
|-<br />
| ''ints '' || '''l#=[k1,k2,...]''' || || spike ending position [nsp]<br />
|-<br />
| ''string '' || '''label#=(Time,Distance,Distance,...)''' || || label on #-th axis<br />
|-<br />
| ''floats '' || '''mag=''' || || spike magnitudes [nsp]<br />
|-<br />
| ''int '' || '''n#=''' || || dimension of #-th axis<br />
|-<br />
| ''int '' || '''nsp=1''' || || Number of spikes<br />
|-<br />
| ''float '' || '''o#=(0,...)''' || || origin on #-th axis<br />
|-<br />
| ''floats '' || '''p#=[0,...]''' || || spike inclination (in samples) [nsp]<br />
|-<br />
| ''string '' || '''title=''' || || title for plots<br />
|-<br />
| ''string '' || '''unit#=[s,km,km,...]''' || || unit on #-th axis<br />
|}<br />
This is the program for creating a RSF hypercube out of nothing. Calling <tt>sfspike</tt> without specifying the k# or l# parameters will result in a volume filled with values specified by <tt>mag</tt>. To get a file full of 1's, just give <tt>sfspike</tt> the axis values that running <tt>sfin</tt> on your desired output would produce. I.e. if you run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" > out.rsf<br />
</pre><br />
you will obtain the following file:<br />
<pre><br />
bash$ sfin out.rsf<br />
out.rsf:<br />
in="/var/tmp/out.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
300 elements 1200 bytes<br />
</pre><br />
To create a "flat reflector" in the file above, run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5> out2.rsf<br />
</pre><br />
Notice that the values for <tt>k</tt> and <tt>l</tt> are in samples, not in the physical units of the respective axes. The result can be visualised with <br />
<pre><br />
< out2.rsf sfgrey pclip=100 wantscalebar=y title="Illustration of k,l parameters" | xtpen<br />
</pre><br />
which produces the following plot:<br />
<br />
[[Image:sfspike_fig1.png]]<br />
<br />
The <tt>p</tt> parameters can be used to create slanted lines/planes. Specifying <tt>p2=1</tt> means that for each lateral step, the spike will be shifted down with 1 sample. Below is the command and the corresponding graphical output it creates:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=1 |\<br />
sfgrey pclip=100 wantscalebar=y title="Effect of p2=1" | xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig2.png]]<br />
<br />
Sfspike also supports negative and non-integer p values:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=-0.15 |\<br />
sfgrey pclip=100 wantscalebar=y allpos=y color=h title="Effect of p2=-0.15" |xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig3.png]]<br />
<br />
When <tt>nsp</tt> is greater than the number of values for <tt>k</tt> and <tt>l</tt> parameters, the extra spikes will be piled on top of the last one, increasing its amplitude. Look at the amplitude of the last event in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=3 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
and in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=5 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
(pictures coming soon). This feature can easily cause a bug when the number of events is large and they have not been properly counted, or when a new spike was added on a list but <tt>nsp</tt> was not updated.<br />
<br />
==sfspray==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extend a dataset by duplicating in the specified axis dimension.<br />
|-<br />
! colspan="4" | sfspray < in.rsf > out.rsf axis=2 n= d= o= label= unit=<br />
|-<br />
| colspan="4" | This operation is adjoint to sfstack.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to spray<br />
|-<br />
| ''float '' || '''d=''' || || Sampling of the newly created dimension<br />
|-<br />
| ''string '' || '''label=''' || || Label of the newly created dimension<br />
|-<br />
| ''int '' || '''n=''' || || Size of the newly created dimension<br />
|-<br />
| ''float '' || '''o=''' || || Origin of the newly created dimension<br />
|-<br />
| ''string '' || '''unit=''' || || Units of the newly created dimension<br />
|}<br />
<br />
<tt>sfspray</tt> extends the input hypercube by replicating the data<br />
in one of the dimensions. The output dataset acquires one additional<br />
dimension. Here is an example:<br />
Start with a 2-D dataset<br />
<pre><br />
bash&#36; sfmath n1=5 n2=2 output=x1+x2 > test.rsf<br />
bash&#36; sfin test.rsf<br />
test.rsf:<br />
in="/var/tmp/test.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
10 elements 40 bytes<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
</pre><br />
Extend the data in the second dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=2 n=3 > test2.rsf<br />
bash&#36; sfin test2.rsf<br />
test2.rsf:<br />
in="/var/tmp/test2.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=3 d2=1 o2=0 <br />
n3=2 d3=1 o3=0 <br />
30 elements 120 bytes<br />
bash&#36; < test2.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 0 1 2 3 4<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
20: 1 2 3 4 5<br />
25: 1 2 3 4 5<br />
</pre><br />
The output is three-dimensional, with traces from the original<br />
data duplicated along the second axis.<br />
Extend the data in the third dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=3 n=2 > test3.rsf<br />
bash&#36; sfin test3.rsf<br />
test3.rsf:<br />
in="/var/tmp/test3.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
n3=2 d3=? o3=? <br />
20 elements 80 bytes<br />
bash&#36; < test3.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
</pre><br />
The output is also three-dimensional, with the original data replicated<br />
along the third axis.<br />
<br />
==sfstack==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stack a dataset over one of the dimensions.<br />
|-<br />
! colspan="4" | sfstack < in.rsf > out.rsf axis=2 rms=n norm=y min=n max=n<br />
|-<br />
| colspan="4" | <br>This operation is adjoint to sfspray.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to stack<br />
|-<br />
| ''bool '' || '''max=n''' || [y/n] || If y, find maximum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''min=n''' || [y/n] || If y, find minimum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || If y, normalize by fold.<br />
|-<br />
| ''bool '' || '''rms=n''' || [y/n] || If y, compute the root-mean-square instead of stack.<br />
|}<br />
While <tt>sfspray</tt> adds a dimension to a hypercube,<br />
<tt>sfstack</tt> effectively removes one of the dimensions by stacking<br />
over it. Here are some examples:<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
bash&#36; < test.rsf sfstack axis=2 | sfdisfil<br />
0: 1.5 2 3 4 5<br />
bash&#36; < test.rsf sfstack axis=1 | sfdisfil<br />
0: 2.5 3 4<br />
</pre><br />
Why is the first value not 1 (in the first case) or 2 (in the second<br />
case)? By default, <tt>sfstack</tt> normalizes the stack by the fold<br />
(the number of non-zero entries). To avoid normalization, use<br />
<tt>norm=n</tt>, as follows:<br />
<pre><br />
bash&#36; < test.rsf sfstack norm=n | sfdisfil <br />
0: 3 6 9 12 15<br />
</pre><br />
<tt>sfstack</tt> can also compute root-mean-square values as <br />
well as minimum and maximum values.<br />
<pre><br />
bash&#36; < test.rsf sfstack rms=y | sfdisfil<br />
0: 1.581 2.16 3.109 4.082 5.066<br />
bash&#36; < test.rsf sfstack min=y | sfdisfil<br />
0: 0 1 2 3 4<br />
bash&#36; < test.rsf sfstack axis=1 max=y | sfdisfil <br />
0: 4 5 6<br />
</pre><br />
<br />
==sftransp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Transpose two axes in a dataset. <br />
|-<br />
! colspan="4" | sftransp < in.rsf > out.rsf memsize=sf_memsize() plane=<br />
|-<br />
| colspan="4" | <br>If you get a "Cannot allocate memory" error, give the program a<br>memsize=1 command-line parameter to force out-of-core operation.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''plane=''' || || Two-digit number with axes to transpose. The default is 12<br />
|}<br />
<br />
The <tt>sftransp</tt> program transposes the input hypercube<br />
exchanging the two axes specified by the <b>plane=</b> parameter. <br />
<pre><br />
bash&#36; sfspike n1=10 n2=20 n3=30 > orig123.rsf<br />
bash&#36; sfin orig123.rsf <br />
orig123.rsf:<br />
in="/var/tmp/orig123.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=23 >out132.rsf<br />
bash&#36; sfin out132.rsf <br />
out132.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=20 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=13 >out321.rsf<br />
bash&#36; sfin out321.rsf <br />
out321.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=30 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=10 d3=0.004 o3=0 label3="Time" unit3="s" <br />
6000 elements 24000 bytes<br />
</pre><br />
<tt>sftransp</tt> tries to fit the dataset in memory to transpose it<br />
there but, if not enough memory is available, it performs a slower<br />
transpose out of core using disk operations. You can control the<br />
amount of available memory using the <b>memsize=</b> parameter or<br />
the <b>RSFMEMSIZE</b> environmental variable.<br />
<br />
==sfwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a portion of the dataset. <br />
|-<br />
! colspan="4" | sfwindow < in.rsf > out.rsf verb=n squeeze=y j#=(1,...) d#=(d1,d2,...) f#=(0,...) min#=(o1,o2,,...) n#=(0,...) max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)<br />
|-<br />
| ''float '' || '''d#=(d1,d2,...)''' || || sampling in #-th dimension<br />
|-<br />
| ''int '' || '''f#=(0,...)''' || || window start in #-th dimension<br />
|-<br />
| ''int '' || '''j#=(1,...)''' || || jump in #-th dimension<br />
|-<br />
| ''float '' || '''max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)''' || || maximum in #-th dimension<br />
|-<br />
| ''float '' || '''min#=(o1,o2,,...)''' || || minimum in #-th dimension<br />
|-<br />
| ''int '' || '''n#=(0,...)''' || || window size in #-th dimension<br />
|-<br />
| ''bool '' || '''squeeze=y''' || [y/n] || if y, squeeze dimensions equal to 1 to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
<b>sfwindow</b> is used to window a portion of the dataset. Here is<br />
a quick example: Start by creating some data.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Now window the first two rows:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n2=2 | sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
</pre><br />
Window the first three columns:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n1=3 | sfdisfil<br />
0: 1 2 3 2 4<br />
5: 6 3 6 9<br />
</pre><br />
Window the middle row:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f2=1 n2=1 | sfdisfil<br />
0: 2 4 6 8 10<br />
</pre><br />
You can interpret the <b>f#</b> and <b>n#</b> parameters as<br />
meaning "skip that many rows/columns" and "select that many<br />
rows/columns" correspondingly. Window the middle point in the dataset:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f1=2 n1=1 f2=1 n2=1 | sfdisfil<br />
0: 6<br />
</pre><br />
Window every other column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=2 | sfdisfil<br />
0: 1 3 5 2 6<br />
5: 10 3 9 15<br />
</pre><br />
Window every third column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=3 | sfdisfil<br />
0: 1 4 2 8 3<br />
5: 12<br />
</pre><br />
Alternatively, <b>sfwindow</b> can use the minimum and maximum<br />
parameters to select a window. In the following example, we are<br />
creating a dataset with <b>sfspike</b> and then windowing a portion of it<br />
between 1 and 2 seconds in time and sampled at 8 miliseconds.<br />
<pre><br />
bash&#36; sfspike n1=1000 n2=10 > spike.rsf <br />
bash&#36; sfin spike.rsf<br />
spike.rsf:<br />
in="/var/tmp/spike.rsf@"<br />
esize=4 type=float form=native <br />
n1=1000 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10000 elements 40000 bytes<br />
bash&#36; < spike.rsf sfwindow min1=1 max1=2 d1=0.008 > window.rsf<br />
bash&#36; sfin window.rsf<br />
window.rsf:<br />
in="/var/tmp/window.rsf@"<br />
esize=4 type=float form=native <br />
n1=126 d1=0.008 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
1260 elements 5040 bytes<br />
</pre><br />
By default, <b>sfwindow</b> "squeezes" the hypercube dimensions<br />
that are equal to one toward the end of the dataset. Here is an<br />
example of taking a time slice:<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=1 d2=0.004 o2=1 label2="Time" unit2="s" <br />
10 elements 40 bytes<br />
</pre><br />
You can change this behavior by specifying <b>squeeze=n</b>.<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 squeeze=n > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=1 d1=0.004 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10 elements 40 bytes<br />
</pre><br />
<br />
=Seismic programs=<br />
Programs in this category are specific for operations on seismic data. The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/seismic/ system/seismic] in the Madagascar distribution.<br />
<br />
==sfheaderattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Integer header attributes. <br />
|-<br />
! colspan="4" | sfheaderattr < head.rsf<br />
|-<br />
| colspan="4" | <br>Only nonzero values are reported.<br />
|}<br />
<br />
The <tt>sfheaderattr</tt> examines the contents of a trace header file,<br />
typically generated by <tt>sfsegyread</tt>. In the example below, we examine<br />
trace headers in the output of <tt>suplane</tt>, a program from Seismic Unix.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
bash$ sfheaderattr < tfile.rsf<br />
*******************************************<br />
71 headers, 32 traces<br />
key[0]="tracl" min[0]=1 max[31]=32 mean=16.5<br />
key[1]="tracr" min[0]=1 max[31]=32 mean=16.5<br />
key[11]="offset" min[0]=400 max[31]=400 mean=400<br />
key[38]="ns" min[0]=64 max[31]=64 mean=64<br />
key[39]="dt" min[0]=4000 max[31]=4000 mean=4000<br />
*******************************************<br />
</pre><br />
For different standard keywords, a minimum, maximum, and mean values<br />
are reported unless they are identically zero. This quick inspection<br />
can help in identifying meaningful keywords set in the data. The input<br />
data type must be <tt>int</tt>.<br />
<br />
==sfheadermath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations, possibly on header keys. <br />
|-<br />
! colspan="4" | sfheadermath < in.rsf > out.rsf memsize=sf_memsize() output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs<br><br>See also sfmath. <br><br>An addition operation can be performed by sfstack.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''output=''' || || Describes the output in a mathematical notation.<br />
|}<br />
<tt>sfheadermath</tt> is a versatile program for mathematical<br />
operations on rows of the input file. If the input file is an<br />
<tt>n1</tt> by <tt>n2</tt> matrix, the output will be a <tt>1</tt> by<br />
<tt>n2</tt> matrix that contains one row made out of mathematical<br />
operations on the other rows. <tt>sfheadermath</tt> can identify a row<br />
by number or by a standard SEGY keyword. The latter is useful for<br />
processing headers extracted from SEGY or SU files.<br />
Here is an example. First, we create an SU file with <tt>suplane</tt> and convert it to RSF using <tt>sfsegyread</tt>.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
</pre><br />
The trace header information is saved in <tt>tfile.rsf</tt>. It<br />
contains 71 headers for 32 traces in integer format.<br />
<pre><br />
bash$ sfin tfile.rsf<br />
tfile.rsf:<br />
in="/tmp/tfile.rsf@"<br />
esize=4 type=int form=native<br />
n1=71 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
2272 elements 9088 bytes<br />
</pre><br />
Next, we will convert <tt>tfile.rsf</tt> to a floating-point format<br />
and run <tt>sfheadermath</tt> to create a new header.<br />
<pre><br />
bash$ < tfile.rsf sfdd type=float | \<br />
sfheadermath myheader=1 output="sqrt(myheader+(2+10*offset^2))" > new.rsf<br />
bash$ sfin new.rsf<br />
new.rsf:<br />
in="/tmp/new.rsf@"<br />
esize=4 type=float form=native<br />
n1=1 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
32 elements 128 bytes<br />
</pre><br />
We defined "myheader" as being the row number 1 in the input (note<br />
that numbering starts with 0) and combined it with "offset", which<br />
is a standard SEGY keyword that denotes row number 11 (see the output<br />
of <tt>sfheaderattr</tt> above.) A variety of mathematical expressions<br />
can be defined in the <tt>output=</tt> string. The expression<br />
processing engine is shared with <tt>sfmath</tt>.<br />
<br />
==sfsegyheader==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Make a trace header file for segywrite.<br />
|-<br />
! colspan="4" | sfsegyheader < in.rsf > out.rsf n1= d1=<br />
|-<br />
| colspan="4" | <br> Use the output for tfile= argument in segywrite.<br />
|-<br />
| ''float '' || '''d1=''' || || trace sampling<br />
|-<br />
| ''int '' || '''n1=''' || || number of samples in a trace<br />
|}<br />
<br />
==sfsegyread==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert a SEG-Y or SU dataset to RSF.<br />
|-<br />
! colspan="4" | sfsegyread mask=msk.rsf > out.rsf tfile=hdr.rsf verb=false su=false format=sf_segyformat (bhead) ns=sf_segyns (bhead) endian= tape= read= hfile= bfile= mask= tfile=<br />
|-<br />
| colspan="4" | <br>Data headers and trace headers are separated from the data.<br><br>Defined SEG-Y trace header key names and byte offsets:<br><br>tracl: trace sequence number within line 0<br><br>tracr: trace sequence number within reel 4<br><br>fldr: field record number 8 <br><br>tracf: trace number within field record 12 <br><br>ep: energy source point number 16 <br><br>cdp: CDP ensemble number 20 <br><br>cdpt: trace number within CDP ensemble 24 <br><br>trid: trace identification code:<br>1 = seismic data<br>2 = dead<br>3 = dummy<br>4 = time break<br>5 = uphole<br>6 = sweep<br>7 = timing<br>8 = water break<br>9---, N = optional use (N = 32,767) 28 <br><br>nvs: number of vertically summed traces 30 <br><br>nhs: number of horizontally summed traces 32 <br><br>duse: data use:<br>1 = production<br>2 = test 34<br><br>offset: distance from source point to receiver<br>group (negative if opposite to direction<br>in which the line was shot) 36 <br><br>gelev: receiver group elevation from sea level<br>(above sea level is positive) 40 <br><br>selev: source elevation from sea level<br>(above sea level is positive) 44 <br><br>sdepth: source depth (positive) 48 <br><br>gdel: datum elevation at receiver group 52 <br><br>sdel: datum elevation at source 56 <br><br>swdep: water depth at source 60 <br><br>gwdep: water depth at receiver group 64 <br><br>scalel: scale factor for previous 7 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 68 <br><br>scalco: scale factor for next 4 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 70 <br><br>sx: X source coordinate 72 <br><br>sy: Y source coordinate 76 <br><br>gx: X group coordinate 80 <br><br>gy: Y group coordinate 84 <br><br>counit: coordinate units code:<br>for previoius four entries<br>1 = length (meters or feet)<br>2 = seconds of arc (in this case, the<br>X values are unsigned intitude and the Y values<br>are latitude, a positive value designates<br>the number of seconds east of Greenwich<br>or north of the equator 88 <br><br>wevel: weathering velocity 90 <br><br>swevel: subweathering velocity 92 <br><br>sut: uphole time at source 94 <br><br>gut: uphole time at receiver group 96 <br><br>sstat: source static correction 98 <br><br>gstat: group static correction 100 <br><br>tstat: total static applied 102 <br><br>laga: lag time A, time in ms between end of 240-<br>byte trace identification header and time<br>break, positive if time break occurs after<br>end of header, time break is defined as<br>the initiation pulse which maybe recorded<br>on an auxiliary trace or as otherwise<br>specified by the recording system 104 <br><br>lagb: lag time B, time in ms between the time<br>break and the initiation time of the energy source,<br>may be positive or negative 106 <br><br>delrt: delay recording time, time in ms between<br>initiation time of energy source and time<br>when recording of data samples begins<br>(for deep water work if recording does not<br>start at zero time) 108 <br><br>muts: mute time--start 110 <br><br>mute: mute time--end 112 <br><br>ns: number of samples in this trace 114 <br><br>dt: sample interval, in micro-seconds 116 <br><br>gain: gain type of field instruments code:<br>1 = fixed<br>2 = binary<br>3 = floating point<br>4 ---- N = optional use 118 <br><br>igc: instrument gain constant 120 <br><br>igi: instrument early or initial gain 122 <br><br>corr: correlated:<br>1 = no<br>2 = yes 124 <br><br>sfs: sweep frequency at start 126 <br><br>sfe: sweep frequency at end 128 <br><br>slen: sweep length in ms 130 <br><br>styp: sweep type code:<br>1 = linear<br>2 = cos-squared<br>3 = other 132 <br><br>stas: sweep trace length at start in ms 134 <br><br>stae: sweep trace length at end in ms 136 <br><br>tatyp: taper type: 1=linear, 2=cos^2, 3=other 138 <br><br>afilf: alias filter frequency if used 140 <br><br>afils: alias filter slope 142 <br><br>nofilf: notch filter frequency if used 144 <br><br>nofils: notch filter slope 146 <br><br>lcf: low cut frequency if used 148 <br><br>hcf: high cut frequncy if used 150 <br><br>lcs: low cut slope 152 <br><br>hcs: high cut slope 154 <br><br>year: year data recorded 156 <br><br>day: day of year 158 <br><br>hour: hour of day (24 hour clock) 160 <br><br>minute: minute of hour 162 <br><br>sec: second of minute 164 <br><br>timbas: time basis code:<br>1 = local<br>2 = GMT<br>3 = other 166 <br><br>trwf: trace weighting factor, defined as 1/2^N<br>volts for the least sigificant bit 168 <br><br>grnors: geophone group number of roll switch<br>position one 170 <br><br>grnofr: geophone group number of trace one within<br>original field record 172 <br><br>grnlof: geophone group number of last trace within<br>original field record 174 <br><br>gaps: gap size (total number of groups dropped) 176 <br><br>otrav: overtravel taper code:<br>1 = down (or behind)<br>2 = up (or ahead)<br />
|-<br />
| ''string '' || '''bfile=''' || || output binary data header file<br />
|-<br />
| ''bool '' || '''endian=''' || [y/n] || big/little endian flag, the default is estimated automatically<br />
|-<br />
| ''int '' || '''format=sf_segyformat (bhead)''' || [1,2,3,5] || Data format. The default is taken from binary header.<br />
:1 is IBM floating point<br />
:2 is 4-byte integer<br />
:3 is 2-byte integer<br />
:5 is IEEE floating point<br />
|-<br />
| ''string '' || '''hfile=''' || || output text data header file<br />
|-<br />
| ''string '' || '''mask=''' || || optional header mask for reading only selected traces<br />
|-<br />
| ''int '' || '''ns=sf_segyns (bhead)''' || || Number of samples. The default is taken from binary header<br />
|-<br />
| ''string '' || '''read=''' || || what to read: h - header, d - data, b - both (default)<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if input is SU, n if input is SEGY<br />
|-<br />
| ''bool '' || '''suxdr=n''' || [y/n] || y, SU has XDR support<br />
|-<br />
| ''string '' || '''tape=''' || || <br />
|-<br />
| ''string '' || '''tfile=''' || || output trace header file<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
The SEG Y format is an [http://en.wikipedia.org/wiki/Open_standard open standard] for the exchange of geophysical data. It is controlled by the non-profit [http://www.seg.org/SEGportalWEBproject/portals/SEG_Online.portal?_nfpb=true&_pageLabel=pg_gen_content&Doc_Url=prod/SEG-Publications/Pub-Yearbook/committees.htm SEG Technical Standards Committee]. There are two versions of this standard: [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev0.pdf rev0] (1975)<ref>Barry, K.M., Cavers, D.A., and Kneale, C.W. 1975. Recommended standards for digital tape formats. ''Geophysics'', '''40''', no. 02, 344–352.</ref> and [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf rev1] (2002)<ref>Norris, M.W., Faichney, A.K., ''Eds''. 2001. SEG Y rev1 Data Exchange format. Society of Exploration Geophysicists, Tulsa, OK, 45 pp.</ref>. The implementation in <tt>sfsegyread</tt> is a mixture of rev0 (i.e. no checks for Extended Textual Headers) and rev1 ([http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE floating point format] allowed for trace data samples).<br />
<br />
A SEG-Y file as understood by <tt>sfsegyread</tt> contains a "Reel Identification Header" (3200 bytes in EBCDIC followed by 400 bytes in a binary encoding), followed by a number of "Trace Blocks". Each "Trace Block" contains a 240-byte "Trace Header" (binary) followed by "Trace Data" -- a sequence of <tt>ns</tt> samples. Binary values in both reel headers and trace headers are two's complement integers, either two bytes or four bytes long. There are no floating-point values defined in the headers. Trace Data samples can have various encodings, either floating point or integer, described further down, but they are all big-endian. To convert from SEG-Y to RSF, <tt>sfsegyread</tt> will strip the tape reel EBCDIC header and convert it to ASCII, will extract the reel binary header without changing it, and will put the trace headers into one RSF file, and the traces themselves on another.<br />
<br />
===SEG-Y Trace Headers===<br />
In the SEG-Y standard, only the first 180 bytes of the 240-byte trace header are defined; bytes 181-240 are reserved for non-standard header information, and these locations are increasingly used in modern SEG-Y files and its variants. The standard provides for a total of 71 4-byte and 2-byte predefined header words. These 71 standard words have defined lengths and byte offsets, and only these words and byte locations are read using <tt>segyread</tt> and output to the RSF header file with the <tt>hfile=</tt> option. The user may remap these predefined keywords to a different byte offsets.<br />
<br />
===SU File Format===<br />
An [http://www.cwp.mines.edu/sututor/node22.html SU file] is nothing more than a SEG-Y file without the reel headers, and with the Trace Data samples in the native encoding of the CPU the file was created on (Attention -- limited portability!). So, to convert from SU to RSF, <tt>sfsegyread</tt> will just separate headers and traces into two RSF files. <br />
<br />
===SEG-Y specific parameters===<br />
*<tt>hfile=</tt> specifies the name of the file in which the EBCDIC reel header will be put after conversion to ASCII. If you are certain there is no useful information in it, <tt>hfile=/dev/null</tt> works just fine. If you do not specify anything for this parameter you will get an ASCII file named <tt>header</tt> in the current directory. If you want to quickly preview this header before running <tt>sfsegyread</tt>, use<pre>dd if=input.segy count=40 bs=80 cbs=80 conv=unblock,ascii</pre><br />
*<tt>bfile=</tt> specifies name of the file in which the binary reel header (the 400-bytes thing following the 3600-bytes EBCDIC) will be put without any conversion. The default name is "binary". Unless you have software that knows how to read exactly this special type of file, it will be completely useless, so do <tt>bfile=/dev/null</tt><br />
*<tt>format=</tt> specifies the format in which the trace data samples are in the SEG-Y input file. This is read from the binary reel header of the SEG-Y file. Valid values are 1(IBM floating point), 2 (4-byte integer), 3 (2-byte integer) and 5 (IEEE floating point). If the input file is SU, the format will be assumed to be the native <tt>float</tt> format.<br />
<br />
*<tt>keyname=</tt> specifies the byte offset to remap a header using the trace header key names shown above. For example, if the CDP locations have been placed in bytes 181-184 instead of the standard 21-24, <tt>cdp=180</tt> will remap the trace header to that location. <br />
<br />
===SU-specific parameters===<br />
*<tt>suxdr=</tt> specifies whether the input file was created with a SU package with XDR support enabled. If you have access to the source code of your SU install (try <tt>$CWPROOT/src</tt>), type: <tt>grep 'XDRFLAG =' $CWPROOT/src/Makefile.config</tt> and look at the last uncommented entry. If no value is given for <tt>XDRFLAG</tt>, the package was not compiled with XDR support.<br />
===Common parameters===<br />
*<tt>su=</tt> specifies if the input file is SU or SEG-Y. Default is <tt>su=n</tt> (SEG-Y file).<br />
*<tt>tape=</tt> specifies the input data. Stdin could not be used because <tt>sfsegyread</tt> has to work with tapes, and needs to fseek back and forth through the input file. Thankfully, output is on stdout.<br />
*<tt>read=</tt> specifies what parts of the "Trace Blocks" will be read. It can be <tt>read=t</tt> (only trace data is read), <tt>read=h</tt> (only trace headers are read) or <tt>read=b</tt> (both are read).<br />
*<tt>tfile=</tt> gives the name of the RSF file to which trace headers are written. Obviously, it should be only specified with <tt>read=h</tt> or <tt>read=b</tt>.<br />
*<tt>mask=</tt> is an optional parameter specifying the name of a mask that says which traces will be read. The mask is a 1-D RSF file with integers. The number of samples in the mask is the same as the number of traces in the unmasked SEG-Y. In places corresponding to unwanted traces there should be zeros in the mask.<br />
*<tt>ns=</tt> specifies the number of samples in a trace. For SEG-Y files, the default is taken from the binary reel header, and for SU files, from the header of the first trace. This parameter is however critical enough that a command line override was given for it.<br />
*<tt>verbose=</tt> is the verbosity flag. Can be <tt>y</tt> or <tt>n</tt>.<br />
*<tt>endian=</tt> is a y/n flag (default y), specifying whether to automatically estimate or not if samples in the Trace Data blocks are big-endian or little-endian. Try it if you are in trouble and do not know what else to do, otherwise let the automatic estimation do its job.<br />
<br />
==sfsegywrite==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert an RSF dataset to SEGY or SU.<br />
|-<br />
! colspan="4" | sfsegywrite < in.rsf tfile=hdr.rsf verb=false su=false endian=sf_endian() tape= hfile= bfile=<br />
|-<br />
| colspan="4" | <br>Merges trace headers with data.<br />
|-<br />
| ''string '' || '''bfile=''' || || input binary data header file<br />
|-<br />
| ''bool '' || '''endian=sf_endian()''' || [y/n] || big/little endian flag. The default is estimated automatically<br />
|-<br />
| ''string '' || '''hfile=''' || || input text data header file<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if output is SU, n if output is SEGY<br />
|-<br />
| ''string '' || '''tape=''' || ||<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
Please see <tt>sfsegyread</tt> for a complete description of parameter meanings and background issues. Parameters <tt>bfile</tt> and <tt>hfile</tt> should only be given values when the desired file is SEG-Y (default). The output file is specified by the <tt>tape=</tt> tag.<br />
<br />
=Plotting programs=<br />
The source files for these programs can be found under<br />
[http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/plot/main/ plot/main]<br />
in the Madagascar distribution.<br />
<br />
THIS SECTION IS UNDER CONSTRUCTION<br />
<br />
==sfbox==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Draw a balloon-style label.<br />
|-<br />
! colspan="4" | sfbox lab_color=VP_WHITE lab_fat=0 pscale=1. pointer=y reverse=n lat=0. long=90. angle=0. x0=0. y0=0. scale0=1. xt=2. yt=0. x_oval=0. y_oval=0. boxit=y length= scalet= size=.25 label= > out.vpl<br />
|-<br />
| ''float '' || '''angle=0.''' || || longitude of floating label in 3-D<br />
|-<br />
| ''bool '' || '''boxit=y''' || [y/n] || if y, create a box around text<br />
|-<br />
| ''int '' || '''lab_color=VP_WHITE''' || || label color<br />
|-<br />
| ''int '' || '''lab_fat=0''' || || label fatness<br />
|-<br />
| ''string '' || '''label=''' || || text for label<br />
|-<br />
| ''float '' || '''lat=0.''' || || <br />
|-<br />
| ''float '' || '''length=''' || || normalization for xt and yt<br />
|-<br />
| ''float '' || '''long=90.''' || || latitude and longitude of viewpoint in 3-D<br />
|-<br />
| ''bool '' || '''pointer=y''' || [y/n] || if y, create arrow pointer<br />
|-<br />
| ''float '' || '''pscale=1.''' || || scale factor for width of pointer<br />
|-<br />
| ''bool '' || '''reverse=n''' || [y/n] || <br />
|-<br />
| ''float '' || '''scale0=1.''' || || scale factor for x0 and y0<br />
|-<br />
| ''float '' || '''scalet=''' || || <br />
|-<br />
| ''float '' || '''size=.25''' || || text height in inches<br />
|-<br />
| ''float '' || '''x0=0.''' || || <br />
|-<br />
| ''float '' || '''x_oval=0.''' || || <br />
|-<br />
| ''float '' || '''xt=2.''' || || <br />
|-<br />
| ''float '' || '''y0=0.''' || || position of the pointer tip<br />
|-<br />
| ''float '' || '''y_oval=0.''' || || size of the oval around pointer<br />
|-<br />
| ''float '' || '''yt=0.''' || || relative position of text<br />
|}<br />
==sfcontour==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Contour plot.<br />
|-<br />
! colspan="4" | sfcontour < in.rsf c= min1=o1 min2=o2 max1=o1+(n1-1)*d1 max2=o2+(n2-1)*d2 nc=50 dc= c0= transp=y minval= maxval= allpos=y barlabel= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=y''' || [y/n] || contour positive values only<br />
|-<br />
| ''string '' || '''barlabel=''' || || <br />
|-<br />
| ''floats '' || '''c=''' || || [nc]<br />
|-<br />
| ''float '' || '''c0=''' || || first contour<br />
|-<br />
| ''float '' || '''dc=''' || || contour increment<br />
|-<br />
| ''float '' || '''max1=o1+(n1-1)*d1''' || || <br />
|-<br />
| ''float '' || '''max2=o2+(n2-1)*d2''' || || data window to plot<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''min1=o1''' || || <br />
|-<br />
| ''float '' || '''min2=o2''' || || <br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nc=50''' || || number of contours<br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfdots==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot signal with lollipops.<br />
|-<br />
! colspan="4" | sfdots < in.rsf labels= dots=(n1 <= 130)? 1: 0 seemean=(bool) (n2 <= 30) strings=(bool) (n1 <= 400) connect=1 corners= silk=n gaineach=y labelsz=8 yreverse=n constsep=n seedead=n transp=n xxscale=1. yyscale=1. clip=-1. overlap=0.9 screenratio=VP_SCREEN_RATIO screenht=VP_STANDARD_HEIGHT screenwd=screenhigh / screenratio radius=dd1/3 label1= unit1= title= > plot.vpl<br />
|-<br />
| ''float '' || '''clip=-1.''' || || data clip<br />
|-<br />
| ''int '' || '''connect=1''' || || connection type: 1 - diagonal, 2 - bar, 4 - only for non-zero data<br />
|-<br />
| ''bool '' || '''constsep=n''' || [y/n] || if y, use constant trace separation<br />
|-<br />
| ''int '' || '''corners=''' || || number of polygon corners (default is 6)<br />
|-<br />
| ''int '' || '''dots=(n1 <= 130)? 1: 0''' || || type of dots: 1 - baloon, 0 - no dots, 2 - only for non-zero data<br />
|-<br />
| ''bool '' || '''gaineach=y''' || [y/n] || if y, gain each trace independently<br />
|-<br />
| ''string '' || '''label1=''' || || <br />
|-<br />
| ''strings'' || '''labels=''' || || trace labels [n2]<br />
|-<br />
| ''int '' || '''labelsz=8''' || || label size<br />
|-<br />
| ''float '' || '''overlap=0.9''' || || trace overlap<br />
|-<br />
| ''float '' || '''radius=dd1/3''' || || dot radius<br />
|-<br />
| ''float '' || '''screenht=VP_STANDARD_HEIGHT''' || || screen height<br />
|-<br />
| ''float '' || '''screenratio=VP_SCREEN_RATIO''' || || screen aspect ratio<br />
|-<br />
| ''float '' || '''screenwd=screenhigh / screenratio''' || || screen width<br />
|-<br />
| ''bool '' || '''seedead=n''' || [y/n] || if y, show zero traces<br />
|-<br />
| ''bool '' || '''seemean=(bool) (n2 <= 30)''' || [y/n] || if y, draw axis lines<br />
|-<br />
| ''bool '' || '''silk=n''' || [y/n] || if y, silky plot<br />
|-<br />
| ''bool '' || '''strings=(bool) (n1 <= 400)''' || [y/n] || if y, draw strings<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axis<br />
|-<br />
| ''string '' || '''unit1=''' || || <br />
|-<br />
| ''float '' || '''xxscale=1.''' || || x scaling<br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse y axis<br />
|-<br />
| ''float '' || '''yyscale=1.''' || || y scaling<br />
|}<br />
==sfgraph3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot for surfaces.<br />
|-<br />
! colspan="4" | sfgraph3 < in.rsf orient=1 min= max= point1=0.5 point2=0.5 frame1=0.5*(min+max) frame2=n1-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y > plot.vpl<br />
|-<br />
| ''float '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''float '' || '''frame1=0.5*(min+max)''' || || <br />
|-<br />
| ''int '' || '''frame2=n1-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''max=''' || || maximum function value<br />
|-<br />
| ''float '' || '''min=''' || || minimum function value<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''orient=1''' || || function orientation<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|}<br />
==sfgraph==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Graph plot.<br />
|-<br />
! colspan="4" | sfgraph < in.rsf symbolsz= pclip=100. transp=n symbol= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''pclip=100.''' || || clip percentile<br />
|-<br />
| ''string '' || '''symbol=''' || || if set, plot with symbols instead of lines<br />
|-<br />
| ''floats '' || '''symbolsz=''' || || symbol size (default is 2) [n2]<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfgrey3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot.<br />
|-<br />
! colspan="4" | sfgrey3 < in.rsf point1=0.5 point2=0.5 frame1=0 frame2=n2-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y scalebar=n minval= maxval= barreverse=n nreserve=8 bar= color= > plot.vpl<br />
|-<br />
| colspan="4" | Requires an "unsigned char" input (the output of sfbyte).<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''int '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''int '' || '''frame1=0''' || || <br />
|-<br />
| ''int '' || '''frame2=n2-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || if y, draw scalebar<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
for sfgrey and sfgrey3. Examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfgrey==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate raster plot.<br />
|-<br />
! colspan="4" | sfgrey < in.rsf > out.rsf bar=bar.rsf transp=y yreverse=y xreverse=n gpow= phalf= clip= pclip= gainstep=0.5+n1/256. allpos=n bias=0. polarity=n verb=n scalebar=n minval= maxval= barreverse=n wantframenum=(bool) (n3 > 1) nreserve=8 gainpanel= bar= color= > (plot.vpl | char.rsf)<br />
|-<br />
| colspan="4" | Can input char values.<br>If called "byte", outputs char values.<br><br>Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=n''' || [y/n] || if y, assume positive data<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=''' || || <br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''string '' || '''gainpanel=''' || || gain reference: 'a' for all, 'e' for each, or number<br />
|-<br />
| ''int '' || '''gainstep=0.5+n1/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=''' || || <br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''pclip=''' || || data clip percentile (default is 99)<br />
|-<br />
| ''float '' || '''phalf=''' || || percentage for estimating gpow<br />
|-<br />
| ''bool '' || '''polarity=n''' || [y/n] || if y, reverse polarity (white is high by default)<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the display axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''bool '' || '''wantframenum=(bool) (n3 > 1)''' || [y/n] || if y, display third axis position in the corner<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''bool '' || '''yreverse=y''' || [y/n] || if y, reverse the vertical axis<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
and examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfplas==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Assembler - convert ascii to vplot. <br />
|-<br />
! colspan="4" | sfplas<br />
|}<br />
==sfpldb==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Debugger - convert vplot to ascii. <br />
|-<br />
! colspan="4" | sfpldb<br />
|}<br />
==sfplotrays==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot rays.<br />
|-<br />
! colspan="4" | sfplotrays frame=frame.rsf nt=n1*n2 jr=1 frame= < rays.rsf > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''string '' || '''frame=''' || || <br />
|-<br />
| ''int '' || '''jr=1''' || || skip rays<br />
|-<br />
| ''int '' || '''nt=n1*n2''' || || maximum ray length<br />
|}<br />
==sfthplot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Hidden-line surface plot.<br />
|-<br />
! colspan="4" | sfthplot < in.rsf uflag=y dflag=y alpha=45. titlsz=9 axissz=6 plotfat=0 titlefat=2 axisfat=2 plotcolup=VP_YELLOW plotcoldn=VP_RED axis=y axis1=y axis2=y axis3=y clip=0. pclip=100. gainstep=0.5+nx/256. bias=0. dclip=1. norm=y xc=1.5 zc=3 ratio=5. zmax= zmin= sz=6. label#= unit#= tpow=0 epow=0 gpow=1 title= > plot.vpl<br />
|-<br />
| ''float '' || '''alpha=45.''' || || apparent angle in degrees, |alpha| < 89<br />
|-<br />
| ''bool '' || '''axis=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis1=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis2=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis3=y''' || [y/n] || plot axis<br />
|-<br />
| ''int '' || '''axisfat=2''' || || axes fatness<br />
|-<br />
| ''int '' || '''axissz=6''' || || axes size<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip<br />
|-<br />
| ''float '' || '''dclip=1.''' || || change the clip: clip *= dclip<br />
|-<br />
| ''bool '' || '''dflag=y''' || [y/n] || if y, plot down side of the surface<br />
|-<br />
| ''float '' || '''epow=0''' || || exponential gain<br />
|-<br />
| ''int '' || '''gainstep=0.5+nx/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=1''' || || power gain<br />
|-<br />
| ''string '' || '''label#=''' || || label on #-th axis<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || normalize by the clip<br />
|-<br />
| ''float '' || '''pclip=100.''' || || data clip percentile<br />
|-<br />
| ''int '' || '''plotcoldn=VP_RED''' || || color of the lower side<br />
|-<br />
| ''int '' || '''plotcolup=VP_YELLOW''' || || color of the upper side<br />
|-<br />
| ''int '' || '''plotfat=0''' || || line fatness<br />
|-<br />
| ''float '' || '''ratio=5.''' || || plot adjustment<br />
|-<br />
| ''float '' || '''sz=6.''' || || vertical scale<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''int '' || '''titlefat=2''' || || title fatness<br />
|-<br />
| ''int '' || '''titlsz=9''' || || title size<br />
|-<br />
| ''string '' || '''tpow=0''' || || time power gain<br />
|-<br />
| ''bool '' || '''uflag=y''' || [y/n] || if y, plot upper side of the surface<br />
|-<br />
| ''string '' || '''unit#=''' || || unit on #-th axis<br />
|-<br />
| ''float '' || '''xc=1.5''' || || <br />
|-<br />
| ''float '' || '''zc=3''' || || lower left corner of the plot<br />
|-<br />
| ''float '' || '''zmax=''' || || <br />
|-<br />
| ''float '' || '''zmin=''' || || <br />
|}<br />
==sfwiggle==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot data with wiggly traces. <br />
|-<br />
! colspan="4" | sfwiggle < in.rsf xpos=xpos.rsf xmax= xmin= poly=n fatp=1 xmask=1 ymask=1 pclip=98. zplot=0.75 clip=0. seemean=n verb=n transp=n yreverse=n xreverse=n xpos= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip (estimated from pclip by default<br />
|-<br />
| ''int '' || '''fatp=1''' || || <br />
|-<br />
| ''float '' || '''pclip=98.''' || || clip percentile<br />
|-<br />
| ''bool '' || '''poly=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''seemean=n''' || [y/n] || if y, plot mean lines of traces<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''int '' || '''xmask=1''' || || <br />
|-<br />
| ''float '' || '''xmax=''' || || maximum trace position (if using xpos)<br />
|-<br />
| ''float '' || '''xmin=''' || || minimum trace position (if using xpos)<br />
|-<br />
| ''string '' || '''xpos=''' || || optional header file with trace positions<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''int '' || '''ymask=1''' || || <br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse the vertical axis<br />
|-<br />
| ''float '' || '''zplot=0.75''' || || <br />
|}<br />
<br />
=filt/imag programs=<br />
==sfremap1==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 1-D ENO interpolation. <br />
|-<br />
! colspan="4" | sfremap1 < in.rsf > out.rsf pattern=pattern.rsf n1=n1 d1=d1 o1=o1 order=3<br />
|-<br />
| ''float '' || '''d1=d1''' || || Output sampling<br />
|-<br />
| ''int '' || '''n1=n1''' || || Number of output samples<br />
|-<br />
| ''float '' || '''o1=o1''' || || Output origin<br />
|-<br />
| ''int '' || '''order=3''' || || Interpolation order<br />
|-<br />
| ''string '' || '''pattern=''' || || auxiliary input file name<br />
|}<br />
To give an example of usage, we will create an input for <tt>sfremap1</tt> with:<br />
<pre><br />
sfmath n1=11 n2=11 d1=1 d2=1 o1=-5 o2=-5 output="x1*x1+x2*x2" > inp2remap1.rsf<br />
</pre><br />
Let us interpolate the data across both dimensions, then display it:<br />
<pre><br />
&lt; inp2remap1.rsf sfremap1 n1=1001 d1=0.01 | sftransp | \<br />
sfremap1 n1=1001 d1=0.01 | sftransp | sfgrey allpos=y | xtpen<br />
</pre><br />
The comparison with the uninterpolated data ( <tt>&lt; inp2remap1.rsf sfgrey allpos=y | xtpen</tt> ) is quite telling.<br />
<br />
=filt/proc programs=<br />
==sfstretch==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stretch of the time axis. <br />
|-<br />
! colspan="4" | sfstretch < in.rsf > out.rsf datum=dat.rsf inv=n dens=1 v0= half=y delay= tdelay= hdelay= nout=dens*n1 extend=4 mute=0 maxstr=0 rule=<br />
|-<br />
| ''file '' || '''datum=''' || || auxiliary input file name<br />
|-<br />
| ''float '' || '''delay=''' || || time delay for rule=lmo<br />
|-<br />
| ''int '' || '''dens=1''' || || axis stretching factor<br />
|-<br />
| ''int '' || '''extend=4''' || || trace extension<br />
|-<br />
| ''bool '' || '''half=y''' || [y/n] || if y, the second axis is half-offset instead of full offset<br />
|-<br />
| ''float '' || '''hdelay=''' || || offset delay for rule=rad<br />
|-<br />
| ''bool '' || '''inv=n''' || [y/n] || if y, do inverse stretching<br />
|-<br />
| ''float '' || '''maxstr=0''' || || maximum stretch<br />
|-<br />
| ''int '' || '''mute=0''' || || tapering size<br />
|-<br />
| ''int '' || '''nout=dens*n1''' || || output axis length (if inv=n)<br />
|-<br />
| ''string '' || '''rule=''' || || Stretch rule:<br />
:n - normal moveout (nmostretch), default<br />
:l - linear moveout (lmostretch)<br />
:L - logarithmic stretch (logstretch)<br />
:2 - t^2 stretch (t2stretch)<br />
:c - t^2 chebyshev stretch (t2chebstretch)<br />
:r - radial moveout (radstretch)<br />
:d - datuming (datstretch)<br />
|-<br />
| ''float '' || '''tdelay=''' || || time delay for rule=rad<br />
|-<br />
| ''float '' || '''v0=''' || || moveout velocity<br />
|}<br />
<br />
<tt>sfstretch rule=d</tt> (aka <tt>sfdatstretch</tt>) can be used to apply statics. Here is a synthetic example, courtesy of Alessandro Frigeri:<br />
<pre><br />
# generate a dataset with 'flat' signals<br />
sfmath n1=200 n2=100 output="sin(0.5*x1)" type=float > scan.rsf<br />
<br />
# generate a sinusoidal elevation correction<br />
sfmath n1=100 output="3*sin(x1)" type=float > statics.rsf<br />
<br />
# apply statics, producing a 'wavy' output.<br />
sfstretch < scan.rsf > out.rsf datum=statics.rsf rule=d<br />
</pre><br />
<br />
=user/ivlad programs=<br />
==sfprep4plot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Resamples a 2-D dataset to the desired picture resolution, with antialias<br />
|-<br />
! colspan="4" | sfprep4plot inp= out= verb=n h=none w=none unit= ppi= prar=y<br />
|-<br />
| colspan="4" | Only one of the h and w parameters needs to be specified.<br>If prar=n, no action will be taken on axis for which h/w was not specified<br>If prar=y and only one par (h or w) is specified, the picture will scale<br>along both axes until it is of the specified dimension.<br />
|-<br />
| ''int '' || '''h=none''' || || output height<br />
|-<br />
| ''string '' || '''inp=''' || || input file<br />
|-<br />
| ''string '' || '''out=''' || || output file<br />
|-<br />
| ''int '' || '''ppi=''' || || output resolution (px/in). Necessary when unit!=px<br />
|-<br />
| ''bool '' || '''prar=y''' || [y/n] || if y, PReserve Aspect Ratio of input<br />
|-<br />
| ''string '' || '''unit=''' || || unit of h and w. Can be: px(default), mm, cm, in<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || if y, print system commands, outputs<br />
|-<br />
| ''int '' || '''w=none''' || || output width<br />
|}<br />
For a figure that does not need the aspect ratio preserved,<br />
and needs to fill a 1280x1024 projector display:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=1280 h=1024 prar=n<br />
</pre><br />
For a print figure that has to fit in a 6x8in box<br />
at a resolution of 250 dpi, preserving the aspect ratio:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=6 h=8 unit=in ppi=250<br />
</pre><br />
A comparison of images before and after the application of <tt>sfprep4plot</tt>, courtesy of Joachim Mispel, is shown below:<br />
<br />
[[Image:sf_prep4plot.jpg]]<br />
<br />
=user/jennings programs=<br />
==sfsizes==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display the size of RSF files.<br />
|-<br />
! colspan="4" | sfsizes files=y human=n file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | Prints the element size, number of elements, and number of bytes<br>for a list of RSF files. Non-RSF files are ignored.<br />
|-<br />
| ''bool '' || '''files=y''' || [y/n] || If y, print size of each file. If n, print only total.<br />
|-<br />
| ''bool '' || '''human=n''' || [y/n] || If y, print human-readable file size. If n, print byte count.<br />
|}<br />
<br />
<br />
This program computes the "theoretical" size in bytes of the data fork of RSF files. The actual space occupied on disk may be different and machine dependent due to disk blocking factors, etc. This theoretical array size should be reproducible. It is also fast because the program only reads the RSF headers files, not the actual data.<br />
<br />
For example, to get the total size of all RSF files in a directory, in human readable format, without listing each file:<br />
<pre><br />
sfsizes files=n human=y *.rsf<br />
</pre><br />
This will also work because sfsizes simply skips any non-RSF file:<br />
<pre><br />
sfsizes files=n human=y *<br />
</pre><br />
==sffiglist==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Compare Vplot files in Fig and Lock directories<br />
|-<br />
! colspan="4" | sffiglist figdir= lockdir= list= show=<br />
|-<br />
| colspan="4" |<br />
Parameter '''figdir''' is path to Fig directory, default is ./Fig.<br />
<br />
<br>Parameter '''lockdir''' is path to Lock directory:<br />
<br> If '''figdir''' is in $RSFSRC/book/[book]/[chapter]/[section],<br />
<br> then default '''lockdir''' is $RSFFIGS/[book]/[chapter]/[section].<br />
<br> If '''figdir''' is not in $RSFSRC/book/[book]/[chapter]/[section],<br />
<br> then default '''lockdir''' is $RSFALTFIGS/[book]/[chapter]/[section].<br />
<br />
<br>Parameter '''list''' controls files to list, default is all.<br />
<br>Parameter '''show''' controls files to flip with sfpen, default is none.<br />
<br />
<br>'''list|show''' = none (No files, print only summary.)<br />
<br>'''list|show''' = diff (Files that are different, determined by sfvplotdiff.)<br />
<br>'''list|show''' = miss (Files missing from figdir or lockdir, and different files.)<br />
<br>'''list|show''' = all (All files.)<br />
<br />
<br>File list codes:<br />
<br>space indicates files that are the same.<br />
<br> - indicates file in lockdir that is missing from figdir.<br />
<br> + indicates extra file in figdir that is missing from lockdir.<br />
<br>number is return code from sfvplotdiff indicating different files.<br />
|-<br />
| ''string '' || '''figdir=''' || || fig directory, default = ./Fig<br />
|-<br />
| ''string '' || '''list=''' || || how much to list [none,diff,miss,all], default = all<br />
|-<br />
| ''string '' || '''lockdir=''' || || lock directory, default = lock counterpart of figdir<br />
|-<br />
| ''string '' || '''show=''' || || how much to show [none,diff,miss,all], default = none<br />
|}<br />
<br />
<br />
This tool lists Vplot files in "Fig" and "Lock" directories and compares them using sfvplotdiff.<br />
<br />
The Fig directory defaults to ./Fig and the Lock directory defaults to the <br />
corresponding directory where "scons lock" puts things, but either <br />
default can be overridden with the user parameters '''figdir''' and '''lockdir''' so that, for example, <br />
files in two different Fig directories can be compared.<br />
<br />
The default for the Lock directory has some logic to look in $RSFFIGS <br />
when Fig is in $RSFSRC/book, or to look in $RSFALTFIGS when Fig is not <br />
in $RSFSRC/book because I like to keep two different Lock directories: <br />
one for stuff in book and another for my own stuff that is not in <br />
book. However, I tried to make the code default to reasonable things <br />
if any of these environment variables are not defined.<br />
<br />
The tool gives a summary count of files that are the same, files that <br />
are different, files in Fig that are missing from Lock, and files in <br />
Lock that are missing from Fig.<br />
<br />
The parameters '''list''' (default=all) and '''show''' (default=none) control which files are listed or "flipped" with sfpen.<br />
<br />
For example, to list all the Vplot files in Fig and Lock:<br />
<pre><br />
sffiglist list=all<br />
</pre><br />
To list all Vplot files and flip only files that are different:<br />
<pre><br />
sffiglist list=all show=diff<br />
</pre><br />
<br />
=user/psava programs=<br />
==sfsrmig3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 3-D S/R migration with extended SSF<br />
|-<br />
! colspan="4" | sfsrmig3 slo=Fs_s.rsf sls=Fs_r.rsf < Fw_s.rsf rwf=Fw_r.rsf > Fi.rsf cig=Fc.rsf ompchunk=1 ompnth=0 verb=y eps=0.01 twoway=n nrmax=1 dtmax=0.004 pmx=0 pmy=0 tmx=0 tmy=0 vpvs=1. hsym=n nht=1 oht=0 dht=0.1 nht=1 oht=0 dht=0.1 hsym=n nhh=1 ohh=0 dhh=0.1 nha=180 oha=0 dha=2.0 nhb=180 ohb=0 dhb=2.0 itype=<br />
|-<br />
| ''file '' || '''cig=''' || || auxiliary output file name<br />
|-<br />
| ''float '' || '''dha=2.0''' || ||<br />
|-<br />
| ''float '' || '''dhb=2.0''' || ||<br />
|-<br />
| ''float '' || '''dhh=0.1''' || ||<br />
|-<br />
| ''float '' || '''dht=0.1''' || ||<br />
|-<br />
| ''float '' || '''dtmax=0.004''' || || max time error<br />
|-<br />
| ''float '' || '''eps=0.01''' || || stability parameter<br />
|-<br />
| ''bool '' || '''hsym=n''' || [y/n] ||<br />
|-<br />
| ''string '' || '''itype=''' || || imaging condition type<br />
:o = zero lag (default)<br />
:e = extended<br />
:x = space-lags<br />
:h = space-lags magnitude<br />
:t = time-lag<br />
|-<br />
| ''int '' || '''nha=180''' || ||<br />
|-<br />
| ''int '' || '''nhb=180''' || ||<br />
|-<br />
| ''int '' || '''nhh=1''' || ||<br />
|-<br />
| ''int '' || '''nht=1''' || ||<br />
|-<br />
| ''int '' || '''nrmax=1''' || || max number of refs<br />
|-<br />
| ''float '' || '''oha=0''' || ||<br />
|-<br />
| ''float '' || '''ohb=0''' || ||<br />
|-<br />
| ''float '' || '''ohh=0''' || ||<br />
|-<br />
| ''float '' || '''oht=0''' || ||<br />
|-<br />
| ''int '' || '''ompchunk=1''' || || OpenMP data chunk size<br />
|-<br />
| ''int '' || '''ompnth=0''' || || OpenMP available threads<br />
|-<br />
| ''int '' || '''pmx=0''' || || padding on x<br />
|-<br />
| ''int '' || '''pmy=0''' || || padding on y<br />
|-<br />
| ''file '' || '''rwf=''' || || auxiliary input file name<br />
|-<br />
| ''file '' || '''slo=''' || || auxiliary input file name<br />
|-<br />
| ''string '' || '''sls=''' || || auxiliary input file name<br />
|-<br />
| ''int '' || '''tmx=0''' || || taper on x<br />
|-<br />
| ''int '' || '''tmy=0''' || || taper on y<br />
|-<br />
| ''bool '' || '''twoway=n''' || [y/n] || two-way traveltime<br />
|-<br />
| ''bool '' || '''verb=y''' || [y/n] || verbosity flag<br />
|-<br />
| ''float '' || '''vpvs=1.''' || || Vp/Vs ratio<br />
|}<br />
<br />
This program performs 3-D and 2-D shot-record (a.k.a. shot-profile) migration with an extended Split-Step Fourier (SSF) extrapolator with multiple reference velocities (hence "extended"). It takes as input a shot wavefield (<tt>stdin</tt>), receiver wavefield (<tt>rwf=</tt>) and slowness model (<tt>slo=</tt>). Outputs are an image (<tt>stdout</tt>) and a cube of Common Image Gathers (<tt>cig=</tt>). An important parameter is <tt>nrmax</tt>, the number of reference velocities. Its default value is 1, but for reasonable results it should be 5 or so. It is also good to specify nonzero taper values (<tt>tmx</tt> and, for 3-D, <tt>tmy</tt> as well). The values of padding parameters <tt>pmx</tt> and <tt>pmy</tt> are split in two by the program, i.e. if your data x axis is 501-points long, specify pmx=11 to get a value of 512 that will result in fast Fourier Transforms. <br />
<br />
The program will also migrate converted-wave data if a file with the S-wave slowness model (<tt>sls=</tt>) is provided.<br />
<br />
The <tt>vpvs</tt> parameter is only used when <tt>itype=h</tt>. Do not specify a <tt>vpvs</tt> value unless you know really well what you are doing.<br />
<br />
===Usage example===<br />
The commands below, slightly modified from [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/data/sigsbee/ptest/SConstruct?revision=3993&view=markup RSFSRC/book/data/sigsbee/ptest], show how to prepare the [http://www.reproducibility.org/RSF/book/data/sigsbee Sigsbee 2A] data and velocity for migration.<br />
<br />
Convert input data (shots) from SEG-Y to RSF:<br />
<bash><br />
sfsegyread tape=sigsbee2a_nfs.segy tfile=tdata.rsf hfile=/dev/null bfile=/dev/null > ddata.rsf<br />
</bash><br />
Convert trace headers to float (required by <tt>sfheadermath</tt>):<br />
<bash><br />
< tdata.rsf sfdd type=float > trchdr.rsf<br />
</bash><br />
Shot positions:<br />
<bash><br />
< trchdr.rsf sfheadermath output="fldr + 10925/150" | sfwindow squeeze=y > tsi.rsf<br />
</bash><br />
Extract offset positions from the trace header files, eliminate length-1 axis, scale, create a header for binning (required by <tt>sfintbin</tt>):<br />
<bash><br />
< trchdr.rsf sfheadermath output="offset" |\<br />
sfwindow squeeze=y |\<br />
sfmath output="input/75" |\<br />
sfcat axis=2 space=n tsi.rsf |\<br />
sftransp |\<br />
sfdd type=int > tos.rsf<br />
</bash><br />
Binning and muting:<br />
<bash><br />
< ddata.rsf sfintbin head=tos.rsf xkey=0 ykey=1 |\<br />
sfput label1=Time unit1=s d2=0.075 o2=0.0 label2=hx d3=0.150 o3=10.925 label3=sx |\<br />
sfmutter half=false t0=1.0 v0=6.0 |\<br />
sfput d2=0.02286 o2=0 unit2=km d3=0.04572 o3=3.32994 unit3=km > shots.rsf<br />
</bash><br />
Keeping only 20 shots so that this 1-node job will not take forever, FFT-ing, decimating frequency slices (same as shortening the time axis), and creating y and hy axes of length 1:<br />
<bash><br />
< shots.rsf sfwindow n3=20 f3=10 j3=20 |\<br />
sffft1 |\<br />
sfwindow n1=200 min1=1 j1=3 |\<br />
sfspray axis=3 n=1 o=0 d=1 label=hy |\<br />
sfspray axis=5 n=1 o=0 d=1 label=sy > rfft.rsf<br />
</bash><br />
The dimensions of the cube thus created are:<br />
<pre><br />
$ sfin rfft.rsf trail=n<br />
rfft.rsf:<br />
in="/var/tmp/rfft.rsf@"<br />
esize=8 type=complex form=native<br />
n1=200 d1=0.25 o1=1 label1="Frequency" unit1="Hz"<br />
n2=348 d2=0.02286 o2=0 label2="hx" unit2="km"<br />
n3=1 d3=1 o3=0 label3="hy" unit3="km"<br />
n4=20 d4=0.9144 o4=3.78714 label4="sx" unit4="km"<br />
1392000 elements 11136000 bytes<br />
</pre><br />
Create the source wavelet (limited to the same frequency band as the data) and Fourier transform it:<br />
<bash><br />
sfspike k1=1 n1=1500 d1=0.008 |\<br />
sfbandpass flo=15 fhi=25 |\<br />
sffft1 |\<br />
sfwindow n1=200 min1=1 j1=3 |\<br />
sfput label1=freq > sfft.rsf<br />
</bash><br />
This creates a frequency-domain wavelet:<br />
<pre><br />
$ sfin sfft.rsf<br />
sfft.rsf:<br />
in="/var/tmp/sfft.rsf@"<br />
esize=8 type=complex form=native<br />
n1=200 d1=0.25 o1=1 label1="freq" unit1="Hz"<br />
200 elements 1600 bytes<br />
</pre><br />
Create "synched" source and receiver wavefields with <tt>srsyn</tt> from wavelet and data frequency slices. Basically both the receiver and shot frequency slices are "placed" at the right location and padded with zeros up to the dimension of the x axis specified below.<br />
<bash><br />
< rfft.rsf sfsrsyn nx=1067 dx=0.02286 ox=3.05562 wav=sfft.rsf swf=swav.rsf > rwav.rsf<br />
</bash><br />
This creates frequency slices ready for migration for both source and receiver, only axis 1 (frequency) must become axis 3, for both datasets:<br />
<bash><br />
< swav.rsf sftransp plane=12 | sftransp plane=23 > stra.rsf<br />
</bash><br />
<bash><br />
< rwav.rsf sftransp plane=12 | sftransp plane=23 > rtra.rsf<br />
</bash><br />
This creates a surface receiver wavefield ready for input to migration. Axis 4 is shot number. The values of axis 4 are arbitrary because each shot has been padded with zeros so that it covers the entire velocity model. Therefore the aperture of the downward continuation for each shot will be as large as the survey.<br />
<pre><br />
sfin trail=n rtra.rsf<br />
rtra.rsf:<br />
in="/var/tmp/rtra.rsf@"<br />
esize=8 type=complex form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=200 d3=0.25 o3=1 label3="w" unit3="Hz"<br />
n4=20 d4=1 o4=0 label4="e" unit4="km"<br />
4268000 elements 34144000 bytes<br />
</pre><br />
Convert the velocity model from SEG-Y to RSF, decimate, convert from feet to km, transpose, convert to slowness and insert an additional axis:<br />
<bash><br />
sfsegyread tape=sigsbee2a_migvel.sgy tfile=/dev/null hfile=/dev/null bfile=/dev/null |\<br />
sfput o1=0 d1=0.00762 label1=z unit1=km o2=3.05562 d2=0.01143 label2=x unit2=km |\<br />
sfwindow j1=4 j2=2 |\<br />
sfscale rscale=0.0003048 |\<br />
sftransp |\<br />
sfmath output="1/input" |\<br />
sfspray axis=2 n=1 d=1 o=0 |\<br />
sfput label2=y > slow.rsf<br />
</bash><br />
This creates a slowness file ready for input to migration, with an x axis identical to the x axis of the wavefield files:<br />
<pre><br />
$ sfin slow.rsf<br />
slow.rsf:<br />
in="/var/tmp/slow.rsf@"<br />
esize=4 type=float form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=301 d3=0.03048 o3=0 label3="z" unit3="km"<br />
321167 elements 1284668 bytes<br />
</pre><br />
Finally, the migration command (for a 4-processor machine, hence the <tt>ompnth</tt> value). We choose not to compute any image gathers (<tt>itype=o</tt>), but due to the construction of the program we still have to explicitly assign the <tt>cig</tt> tag, or else a RSF file with the name of the tag and no rsf extension will be created:<br />
<bash><br />
< stra.rsf sfsrmig3 nrmax=20 dtmax=5e-05 eps=0.01 verb=y ompnth=4 \<br />
tmx=16 rwf=rtra.rsf slo=slow.rsf itype=o cig=/dev/null > img.rsf<br />
</bash><br />
The migration of 20 shots takes approximately 3 hours on a 4-processor machine (1 shot=9 minutes). Without the frequency slice decimation by a factor of 3 and the depth axis decimation by a factor of 4, it would have taken twelve times as much. The resulting image has a y axis of length 1:<br />
<pre><br />
$ sfin img.rsf trail=n<br />
img.rsf:<br />
in="/var/tmp/img.rsf@"<br />
esize=4 type=float form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=301 d3=0.03048 o3=0 label3="z" unit3="km"<br />
321167 elements 1284668 bytes<br />
</pre><br />
To properly visualize the image, we need to eliminate the axis of length 1, then transpose the x and z axes to their natural position:<br />
<bash><br />
<img.rsf sfwindow squeeze=y | sftransp | sfgrey > img.vpl<br />
</bash><br />
<br />
=References=<br />
<references/></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Guide_to_madagascar_programs&diff=929Guide to madagascar programs2009-08-14T02:38:47Z<p>Jenningsjwj: /* sffiglist */</p>
<hr />
<div><center><font size="-1">''This page was created from the LaTeX source in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/rsf/rsf/prog.tex?view=markup book/rsf/rsf/prog.tex] using [[latex2wiki]]''</font></center><br />
<br />
This guide introduces some of the most used <tt>madagascar</tt> programs and illustrates their usage with examples.<br />
=Main programs=<br />
The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/ system/main] in the Madagascar distribution. The "main" programs perform general-purpose operations on RSF hypercubes regardless of the data dimensionality or physical dimensions.<br />
<br />
==sfadd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Add, multiply, or divide RSF datasets.<br />
|-<br />
! colspan="4" | sfadd > out.rsf scale= add= sqrt= abs= log= exp= mode= [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | The various operations, if selected, occur in the following order:<br><br>(1) Take absolute value, abs=<br>(2) Add a scalar, add=<br>(3) Take the natural logarithm, log=<br>(4) Take the square root, sqrt=<br>(5) Multiply by a scalar, scale=<br>(6) Compute the base-e exponential, exp=<br>(7) Add, multiply, or divide the data sets, mode=<br><br>sfadd operates on integer, float, or complex data, but all the input<br>and output files must be of the same data type.<br><br>An alternative to sfadd is sfmath, which is more versatile, but may be<br>less efficient.<br />
|-<br />
| ''bools '' || '''abs=''' || || If true take absolute value [nin]<br />
|-<br />
| ''floats '' || '''add=''' || || Scalar values to add to each dataset [nin]<br />
|-<br />
| ''bools '' || '''exp=''' || || If true compute exponential [nin]<br />
|-<br />
| ''bools '' || '''log=''' || || If true take logarithm [nin]<br />
|-<br />
| ''string '' || '''mode=''' || || 'a' means add (default), <br> 'p' or 'm' means multiply, <br> 'd' means divide<br />
|-<br />
| ''floats '' || '''scale=''' || || Scalar values to multiply each dataset with [nin]<br />
|-<br />
| ''bools '' || '''sqrt=''' || || If true take square root [nin]<br />
|}<br />
<br />
<tt>sfadd</tt> is useful for combining (adding, dividing, or<br />
multiplying) several datasets. What if you want to subtract two<br />
datasets? Easy. Use the <tt>scale</tt> parameter as follows:<br />
<pre><br />
bash&#36; sfadd data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfadd < data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
The same task can be accomplished with the more general <tt>sfmath</tt> program:<br />
<pre><br />
bash&#36; sfmath one=data1.rsf two=data2.rsf output='one-two' > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfmath < data1.rsf two=data2.rsf output='input-two' > diff.rsf<br />
</pre><br />
In both cases, the size and shape of <tt>data1.rsf</tt> and<br />
<tt>data2.rsf</tt> hypercubes should be the same, and a warning<br />
message is printed out if the the axis sampling parameters (such as<br />
<tt>o1</tt> or <tt>d1</tt>) in these files are different.<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/add.c?view=markup system/main/add.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
/* find number of input files */<br />
if (isatty(fileno(stdin))) { <br />
/* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Collect input files in the <tt>in</tt> array from all command-line<br />
parameters that don't contain an "<tt>=</tt>" sign. The total number<br />
of input files in <tt>nin</tt>.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) continue; <br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
/* nin = no of input files*/<br />
</c><br />
<br />
A helper function <tt>check_compat</tt> checks the compatibility of<br />
input files.<br />
<c><br />
static void <br />
check_compat (sf_datatype type /* data type */, <br />
size_t nin /* number of files */, <br />
sf_file* in /* input files [nin] */, <br />
int dim /* file dimensionality */, <br />
const int* n /* dimensions [dim] */)<br />
/* Check that the input files are compatible. <br />
Issue error for type mismatch or size mismatch.<br />
Issue warning for grid parameters mismatch. */<br />
{<br />
int ni, id;<br />
size_t i;<br />
float d, di, o, oi;<br />
char key[3];<br />
const float tol=1.e-5; /* tolerance for comparison */<br />
<br />
for (i=1; i < nin; i++) {<br />
if (sf_gettype(in[i]) != type) <br />
sf_error ("type mismatch: need %d",type);<br />
for (id=1; id <= dim; id++) {<br />
(void) snprintf(key,3,"n%d",id);<br />
if (!sf_histint(in[i],key,&ni) || ni != n[id-1])<br />
sf_error("%s mismatch: need %d",key,n[id-1]);<br />
(void) snprintf(key,3,"d%d",id);<br />
if (sf_histfloat(in[0],key,&d)) {<br />
if (!sf_histfloat(in[i],key,&di) || <br />
(fabsf(di-d) > tol*fabsf(d)))<br />
sf_warning("%s mismatch: need %g",key,d);<br />
} else {<br />
d = 1.;<br />
}<br />
(void) snprintf(key,3,"o%d",id);<br />
if (sf_histfloat(in[0],key,&o) && <br />
(!sf_histfloat(in[i],key,&oi) || <br />
(fabsf(oi-o) > tol*fabsf(d))))<br />
sf_warning("%s mismatch: need %g",key,o);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
Finally, we enter the main loop, where input data are getting read<br />
buffer by buffer and combined in the total product depending on the<br />
data type.<br />
<c><br />
for (nbuf /= sf_esize(in[0]); nsiz > 0; nsiz -= nbuf) {<br />
if (nbuf > nsiz) nbuf=nsiz;<br />
<br />
for (j=0; j < nin; j++) {<br />
collect = (bool) (j != 0);<br />
switch(type) {<br />
case SF_FLOAT:<br />
sf_floatread((float*) bufi,<br />
nbuf,<br />
in[j]); <br />
add_float(collect, <br />
nbuf,<br />
(float*) buf,<br />
(const float*) bufi, <br />
cmode, <br />
scale[j], <br />
add[j], <br />
abs_flag[j], <br />
log_flag[j], <br />
sqrt_flag[j], <br />
exp_flag[j]);<br />
break;<br />
</c><br />
<br />
The data combination program for floating point numbers is<br />
<tt>add_float</tt>. <br />
<c><br />
static void add_float (bool collect, /* if collect */<br />
size_t nbuf, /* buffer size */<br />
float* buf, /* output [nbuf] */<br />
const float* bufi, /* input [nbuf] */ <br />
char cmode, /* operation */<br />
float scale, /* scale factor */<br />
float add, /* add factor */<br />
bool abs_flag, /* if abs */<br />
bool log_flag, /* if log */<br />
bool sqrt_flag, /* if sqrt */<br />
bool exp_flag /* if exp */)<br />
/* Add floating point numbers */<br />
{<br />
size_t j;<br />
float f;<br />
<br />
for (j=0; j < nbuf; j++) {<br />
f = bufi[j];<br />
if (abs_flag) f = fabsf(f);<br />
f += add;<br />
if (log_flag) f = logf(f);<br />
if (sqrt_flag) f = sqrtf(f);<br />
if (1. != scale) f *= scale;<br />
if (exp_flag) f = expf(f);<br />
if (collect) {<br />
switch (cmode) {<br />
case 'p': /* product */<br />
case 'm': /* multiply */<br />
buf[j] *= f;<br />
break;<br />
case 'd': /* delete */<br />
if (f != 0.) buf[j] /= f;<br />
break;<br />
default: /* add */<br />
buf[j] += f;<br />
break;<br />
}<br />
} else {<br />
buf[j] = f;<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display dataset attributes.<br />
|-<br />
! colspan="4" | sfattr < in.rsf want=<br />
|-<br />
| colspan="4" | <br>Sample output from "sfspike n1=100 | sfbandpass fhi=60 | sfattr"<br>******************************************* <br>rms = 0.992354 <br>mean value = 0.987576 <br>2-norm value = 9.92354 <br>variance = 0.00955481 <br>standard deviation = 0.0977487 <br>maximum value = 1.12735 at 97 <br>minimum value = 0.151392 at 100 <br>number of nonzero samples = 100 <br>total number of samples = 100 <br>******************************************* <br><br>rms = sqrt[ sum(data^2) / n ]<br>mean = sum(data) / n<br>norm = sum(abs(data)^lval)^(1/lval)<br>variance = [ sum(data^2) - n*mean^2 ] / [ n-1 ]<br>standard deviation = sqrt [ variance ]<br />
|-<br />
| ''int '' || '''lval=2''' || || norm option, lval is a non-negative integer, computes the vector lval-norm<br />
|-<br />
| ''string '' || '''want=''' || || 'all'(default),'rms','mean','norm','var','std','max','min','nonzero','samples','short' <br />
:want= 'rms' displays the root mean square<br />
:want= 'norm' displays the square norm, otherwise specified by lval.<br />
:want= 'var' displays the variance<br />
:want= 'std' displays the standard deviation<br />
:want= 'nonzero' displays number of nonzero samples<br />
:want= 'samples' displays total number of samples<br />
:want= 'short' displays a short one-line version<br />
|}<br />
<br />
<br />
<tt>sfattr</tt> is a useful diagnostic program. It reports certain<br />
statistical values for an RSF dataset: RMS (root-mean-square)<br />
amplitude, mean value, vector norm value, variance, standard deviation,<br />
maximum and minimum values, number of nonzero samples, and the total<br />
number of samples.<br />
If we denote data values as <math>d_i</math> for <math>i=0,1,2,\ldots,n</math>, then the RMS<br />
value is <math>\sqrt{\frac{1}{n}\,\sum\limits_{i=0}^n d_i^2}</math>, the mean<br />
value is <math>\frac{1}{n}\,\sum\limits_{i=0}^n d_i</math>, the <math>L_2</math>-norm value<br />
is <math>\sqrt{\sum\limits_{i=0}^n d_i^2}</math>, the variance is<br />
<math>\frac{1}{n-1}\,\left[\sum\limits_{i=0}^n d_i^2 - \frac{1}{n}\left(\sum\limits_{i=0}^n d_i\right)^2\right]</math>, and the standard<br />
deviation is the square root of the variance. Using <tt>sfattr</tt><br />
is a quick way to see the distribution of data values and check it for anomalies.<br />
<br />
The output can be parsed using utilities such as <tt>awk</tt>, to extract only a numeric value for feeding it as a parameter value into a command line interface. Notice the backticks in the example below:<br />
<bash><br />
sfgrey <vel.rsf allpos=y bias=`sfattr <vel.rsf want=min | awk '{print $4}'` | xtpen<br />
</bash><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/attr.c?view=markup system/main/attr.c]====<br />
<br />
Computations start by finding the input data (<tt>in</tt>) size<br />
(<tt>nsiz</tt>) and dimensions (<tt>dim</tt>).<br />
<c><br />
dim = (size_t) sf_filedims (in,n);<br />
for (nsiz=1, i=0; i < dim; i++) {<br />
nsiz *= n[i];<br />
}<br />
</c><br />
<br />
<br />
In the main loop, we read the input data buffer by buffer.<br />
<c><br />
for (nleft=nsiz; nleft > 0; nleft -= nbuf) {<br />
nbuf = (bufsiz < nleft)? bufsiz: nleft;<br />
switch (type) {<br />
case SF_FLOAT: <br />
sf_floatread((float*) buf,nbuf,in);<br />
break;<br />
case SF_INT:<br />
sf_intread((int*) buf,nbuf,in);<br />
break;<br />
case SF_COMPLEX:<br />
sf_complexread((sf_complex*) buf,nbuf,in);<br />
break;<br />
case SF_UCHAR:<br />
sf_ucharread((unsigned char*) buf,nbuf,in);<br />
break;<br />
case SF_CHAR:<br />
default:<br />
sf_charread(buf,nbuf,in);<br />
break;<br />
}<br />
</c><br />
<br />
<br />
The data attributes are accumulated in corresponding double-precision<br />
variables. <br />
<c><br />
fsum += f;<br />
fsqr += f*f;<br />
</c><br />
<br />
<br />
Finally, the attributes are reduced and printed out.<br />
<c><br />
fmean = fsum/nsiz;<br />
if (lval==2) fnorm = sqrt(fsqr);<br />
else if (lval==0) fnorm = nsiz-nzero;<br />
else fnorm = pow(flval,1./lval);<br />
frms = sqrt(fsqr/nsiz);<br />
if (nsiz > 1) fvar = (fsqr-nsiz*fmean*fmean)/(nsiz-1);<br />
else fvar = 0.0;<br />
fstd = sqrt(fvar);<br />
</c><br />
<br />
<c><br />
if(NULL==want || 0==strcmp(want,"rms"))<br />
printf("rms = %g \n",(float) frms);<br />
if(NULL==want || 0==strcmp(want,"mean"))<br />
printf("mean value = %g \n",(float) fmean);<br />
if(NULL==want || 0==strcmp(want,"norm"))<br />
printf("%d-norm value = %g \n",lval,(float) fnorm);<br />
if(NULL==want || 0==strcmp(want,"var"))<br />
printf("variance = %g \n",(float) fvar);<br />
if(NULL==want || 0==strcmp(want,"std"))<br />
printf("standard deviation = %g \n",(float) fstd);<br />
</c><br />
<br />
==sfcat==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Concatenate datasets. <br />
|-<br />
! colspan="4" | sfcat > out.rsf space= axis=3 nspace=(int) (ni/(20*nin) + 1) [<file0.rsf] file1.rsf file2.rsf ... <br />
|-<br />
| colspan="4" | sfmerge inserts additional space between merged data.<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis being merged<br />
|-<br />
| ''int '' || '''nspace=(int) (ni/(20*nin) + 1)''' || || if space=y, number of traces to insert<br />
|-<br />
| ''bool '' || '''space=''' || [y/n] || Insert additional space.<br />
:y is default for sfmerge, n is default for sfcat<br />
|}<br />
<br />
<br />
<tt>sfcat</tt> and <tt>sfmerge</tt> concatenate two or more files<br />
together along a particular axis. It is the same program, only<br />
<tt>sfcat</tt> has the default <tt>space=n</tt> and <tt>sfmerge</tt><br />
has the default <tt>space=y</tt>.<br />
Example of <tt>sfcat</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcat one.rsf one.rsf axis=1 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=4 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
12 elements 48 bytes<br />
</pre><br />
Example of <tt>sfmerge</tt>:<br />
<pre><br />
bash$ sfmerge one.rsf one.rsf axis=2 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=7 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
14 elements 56 bytes<br />
</pre><br />
In this case, an extra empty trace is inserted between the two merged files.<br />
The axes that are not being merged are checked for consistency:<br />
<pre><br />
bash$ sfcat one.rsf two.rsf > three.rsf<br />
sfcat: n2 mismatch: need 3<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cat.c?view=markup system/main/cat.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
in = (sf_file*) sf_alloc ((size_t) argc,sizeof(sf_file));<br />
<br />
if (!sf_stdin()) { /* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Everything on the command line that does not contain a "=" sign is<br />
treated as a file name, and the corresponding file object is added to the list.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) <br />
continue; /* not a file */<br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
</c><br />
<br />
As explained above, if the <tt>space=</tt> parameter is not set, it is<br />
inferred from the program name: <tt>sfmerge</tt> corresponds to<br />
<tt>space=y</tt> and <tt>sfcat</tt> corresponds to <tt>space=n</tt>.<br />
<c><br />
if (!sf_getbool("space",&space)) {<br />
/* Insert additional space.<br />
y is default for sfmerge, n is default for sfcat */<br />
prog = sf_getprog();<br />
if (NULL != strstr (prog, "merge")) {<br />
space = true;<br />
} else if (NULL != strstr (prog, "cat")) {<br />
space = false;<br />
} else {<br />
sf_warning("%s is neither merge nor cat,"<br />
" assume merge",prog);<br />
space = true;<br />
}<br />
}<br />
</c><br />
<br />
Find the axis for the merging (from the command line <tt>axis=</tt><br />
argument) and figure out two sizes: <tt>n1</tt> for everything after<br />
the axis and <tt>n2</tt> for everything before the axis.<br />
<c><br />
n1=1;<br />
n2=1;<br />
for (i=1; i <= dim; i++) {<br />
if (i < axis) n1 *= n[i-1];<br />
else if (i > axis) n2 *= n[i-1];<br />
}<br />
</c><br />
<br />
In the output, the selected axis will get extended.<br />
<c><br />
/* figure out the length of extended axis */<br />
ni = 0;<br />
for (j=0; j < nin; j++) {<br />
ni += naxis[j];<br />
}<br />
<br />
if (space) {<br />
if (!sf_getint("nspace",&nspace)) <br />
nspace = (int) (ni/(20*nin) + 1);<br />
/* if space=y, number of traces to insert */ <br />
ni += nspace*(nin-1);<br />
} <br />
<br />
(void) snprintf(key,3,"n%d",axis);<br />
sf_putint(out,key,(int) ni);<br />
</c><br />
<br />
The rest is simple: loop through the datasets reading and writing the<br />
data in buffer-size chunks and adding extra empty chunks if<br />
<tt>space=y</tt>.<br />
<c><br />
for (i2=0; i2 < n2; i2++) {<br />
for (j=0; j < nin; j++) {<br />
for (ni = n1*naxis[j]*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charread (buf,nbuf,in[j]);<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
if (!space || j == nin-1) continue;<br />
/* Add spaces */<br />
memset(buf,0,BUFSIZ);<br />
for (ni = n1*nspace*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfcmplx==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a complex dataset from its real and imaginary parts.<br />
|-<br />
! colspan="4" | sfcmplx > cmplx.rsf real.rsf imag.rsf<br />
|-<br />
| colspan="4" | There has to be only two input files specified and no additional parameters.<br />
|}<br />
<br />
<br />
<tt>sfcmplx</tt> simply creates a complex dataset from its real and<br />
imaginary parts. The reverse operation can be accomplished with<br />
<tt>sfreal</tt> and <tt>sfimag</tt>.<br />
Example of <tt>sfcmplx</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcmplx one.rsf one.rsf > cmplx.rsf<br />
bash$ sfin cmplx.rsf<br />
cmplx.rsf:<br />
in="/tmp/cmplx.rsf@"<br />
esize=8 type=complex form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 48 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cmplx.c?view=markup system/main/cmplx.c]====<br />
The program flow is simple. First, get the names of the input files.<br />
<c><br />
/* the first two non-parameters are real and imaginary files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == real) {<br />
real = sf_input (argv[i]);<br />
} else {<br />
imag = sf_input (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == imag) {<br />
if (NULL == real) sf_error ("not enough input");<br />
/* if only one input, real is in stdin */<br />
imag = real;<br />
real = sf_input("in");<br />
}<br />
</c><br />
<br />
The main part of the program reads the real and imaginary parts buffer by buffer and assembles and writes out the complex input. <br />
<c><br />
for (nleft= (size_t) (rsize*resize); nleft > 0; nleft -= nbuf) {<br />
nbuf = (BUFSIZ < nleft)? BUFSIZ: nleft;<br />
sf_charread(rbuf,nbuf,real);<br />
sf_charread(ibuf,nbuf,imag);<br />
for (i=0; i < nbuf; i += resize) {<br />
memcpy(cbuf+2*i, rbuf+i,(size_t) resize);<br />
memcpy(cbuf+2*i+resize,ibuf+i,(size_t) resize);<br />
}<br />
sf_charwrite(cbuf,2*nbuf,cmplx);<br />
}<br />
</c><br />
<br />
==sfconjgrad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic conjugate-gradient solver for linear inversion <br />
|-<br />
! colspan="4" | sfconjgrad < dat.rsf mod=mod.rsf > to.rsf < from.rsf > out.rsf niter=1<br />
|-<br />
| ''int '' || '''niter=1''' || || number of iterations<br />
|}<br />
<br />
<tt>sfconjgrad</tt> is a generic program for least-squares linear<br />
inversion with the [http://en.wikipedia.org/wiki/Conjugate_gradient_method conjugate-gradient method]. Suppose you have an<br />
executable program <tt><prog></tt> that takes an RSF file from the<br />
standard input and produces an RSF file in the standard output. It may<br />
take any number of additional parameters but one of them must be<br />
<tt>adj=</tt> that sets the forward (<tt>adj=0</tt>) or adjoint<br />
(<tt>adj=1</tt>) operations. The program <tt><prog></tt> is typically<br />
an RSF program but it could be anything (a script, a multiprocessor<br />
MPI program, etc.) as long as it implements a linear operator<br />
<math>\mathbf{L}</math> and its adjoint. There are no restrictions on the data<br />
size or shape. You can easily test the adjointness with<br />
<tt>sfdottest</tt>. The <tt>sfconjgrad</tt> program searches for a<br />
vector <math>\mathbf{m}</math> that minimizes the least-square misfit <br />
<math>\|\mathbf{d - L\,m}\|^2</math> for the given input data vector <math>\mathbf{d}</math>. <br />
<br />
The pseudocode for <tt>sfconjgrad</tt> is given at the end of the [http://www.reproducibility.org/RSF/book/gee/lsq/paper.pdf "Model fitting with least squares" chapter] of ''Imaging Estimation by Example'' by Jon Claerbout, with the earliest form published in [http://sepwww.stanford.edu/data/media/public/oldreports/sep48/48_25.pdf "Conjugate Gradient Tutorial"] (SEP-48, 1986, same author). A simple toy implementation with a small matrix shows that this is algorithm produces the same steps as the algorithm described in equations 45-49 of [http://www.cs.cmu.edu/~quake-papers/painless-conjugate-gradient.pdf "An introduction to the Conjugate Gradient Method Without the Agonizing Pain"] by J.R. Shewchuk, 1994, when the equation <math>A^T A x = A^T b</math> (in Shewchuk's notation) is solved. Multiplying with the transpose ensures a correct solution even when matrix A is square but not symmetric, or not square at all. The program [http://www.reproducibility.org/RSF/sfcconjgrad.html sfcconjgrad] implements this algorithm for the case when inputs are complex.<br />
<br />
Here is an example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
The <tt>sfdottest</tt> program can perform the dot product test to<br />
check that the adjoint mode works correctly.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=5.28394<br />
sfdottest: L'[d]*m=5.28394<br />
</pre><br />
Your numbers may be different because <tt>sfdottest</tt> generates new<br />
random input on each run.<br />
Next, let us make some random data with <tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfnoise seed=2005 rep=y < vec.rsf > dat.rsf<br />
</pre><br />
and try to invert the filtering operation using <tt>sfconjgrad</tt>:<br />
<pre><br />
bash$ sfconjgrad sfhelicon filt=flt.rsf lag=lag.rsf \<br />
mod=vec.rsf < dat.rsf > mod.rsf niter=10<br />
sfconjgrad: iter 1 of 10<br />
sfconjgrad: grad=3253.65<br />
sfconjgrad: iter 2 of 10<br />
sfconjgrad: grad=289.421<br />
sfconjgrad: iter 3 of 10<br />
sfconjgrad: grad=92.3481<br />
sfconjgrad: iter 4 of 10<br />
sfconjgrad: grad=36.9417<br />
sfconjgrad: iter 5 of 10<br />
sfconjgrad: grad=18.7228<br />
sfconjgrad: iter 6 of 10<br />
sfconjgrad: grad=11.1794<br />
sfconjgrad: iter 7 of 10<br />
sfconjgrad: grad=7.26941<br />
sfconjgrad: iter 8 of 10<br />
sfconjgrad: grad=5.15945<br />
sfconjgrad: iter 9 of 10<br />
sfconjgrad: grad=4.23055<br />
sfconjgrad: iter 10 of 10<br />
sfconjgrad: grad=3.57495<br />
</pre><br />
The output shows that, in 10 iterations, the norm of the gradient vector decreases by almost 1000. <br />
We can check the residual misfit before<br />
<pre><br />
bash$ < dat.rsf sfattr want=norm<br />
norm value = 49.7801<br />
</pre><br />
and after<br />
<pre><br />
bash$ sfhelicon filt=flt.rsf lag=lag.rsf < mod.rsf | \<br />
sfadd scale=1,-1 dat.rsf | sfattr want=norm<br />
norm value = 5.73563<br />
</pre><br />
In 10 iterations, the misfit decreased by an order of magnitude. The<br />
result can be improved by running the program for more iterations.<br />
<br />
An equivalent implementation for complex-valued inputs is [http://www.reproducibility.org/RSF/sfcconjgrad.html sfcconjgrad]. A simple, lightweight Python implementation can be found in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/fomels/conjgrad.py?view=markup $RSFROOT/lib/conjgrad.py].<br />
<br />
==sfcp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Copy or move a dataset.<br />
|-<br />
! colspan="4" | sfcp in.rsf out.rsf<br />
|-<br />
| colspan="4" | sfcp - copy, sfmv - move.<br>Mimics standard Unix commands.<br />
|}<br />
<br />
<br />
The <tt>sfcp</tt> and <tt>sfmv</tt> command imitate the Unix<br />
<tt>cp</tt> and <tt>mv</tt> commands and serve for copying and moving<br />
RSF files. Example:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcp one.rsf two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cp.c?view=markup system/main/cp.c]====<br />
First, we look for the two first command-line arguments that don't<br />
have the "=" character in them and consider them as the names of the<br />
input and the output files. <br />
<c><br />
/* the first two non-parameters are in and out files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == in) {<br />
infile = argv[i];<br />
in = sf_input (infile);<br />
} else {<br />
out = sf_output (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == in || NULL == out)<br />
sf_error ("not enough input");<br />
</c><br />
<br />
Next, we use library functions <font color="#cd4b19">sf_cp</font> and <font color="#cd4b19">sf_rm</font> to do the actual work.<br />
<c><br />
sf_cp(in,out);<br />
if (NULL != strstr (sf_getprog(),"mv")) <br />
sf_rm(infile,false,false,false);<br />
</c><br />
<br />
==sfcut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of the dataset. <br />
|-<br />
! colspan="4" | sfcut < in.rsf > out.rsf verb=n [j1=1 j2=1 ... f1=0 f2=0 ... n1=n1 n2=n2 ... max1= max2= ... min1= min2= ...]<br />
|-<br />
| colspan="4" | jN defines the jump in N-th dimension<br>fN is the window start<br>nN is the window size<br>minN and maxN is the maximum and minimum in N-th dimension<br><br>Reverse of window. <br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
The <tt>sfcut</tt> command is related to <tt>sfwindow</tt> and has the same<br />
set of arguments only instead of extracting the selected window, it fills it<br />
with zeroes. The size of the input data is preserved. <br />
Examples:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > in.rsf<br />
bash$ < in.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < in.rsf sfcut n1=2 f1=1 n2=3 f2=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 0 0 1 1<br />
15: 1 0 0 1 1<br />
20: 1 0 0 1 1<br />
bash$ < in.rsf sfcut j1=2 | sfdisfil<br />
0: 0 1 0 1 0<br />
5: 0 1 0 1 0<br />
10: 0 1 0 1 0<br />
15: 0 1 0 1 0<br />
20: 0 1 0 1 0<br />
</pre><br />
<br />
==sfdd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert between different formats. <br />
|-<br />
! colspan="4" | sfdd < in.rsf > out.rsf line=8 form= type= format=<br />
|-<br />
| ''string '' || '''form=''' || || ascii, native, xdr<br />
|-<br />
| ''string '' || '''format=''' || || Element format (for conversion to ASCII)<br />
|-<br />
| ''int '' || '''line=8''' || || Number of numbers per line (for conversion to ASCII)<br />
|-<br />
| ''string '' || '''type=''' || || int, float, complex<br />
|}<br />
<br />
<br />
The <tt>sfdd</tt> program is used to change either the form (<tt>ascii</tt>,<br />
<tt>xdr</tt>, <tt>native</tt>) or the type (<tt>complex</tt>, <tt>float</tt>,<br />
<tt>int</tt>, <tt>char</tt>) of the input dataset. <br />
In the example below, we create a plain text (ASCII) file with numbers and<br />
then use <tt>sfdd</tt> to generate an RSF file in <tt>xdr</tt> form with<br />
<tt>complex</tt> numbers. <br />
<pre><br />
bash$ cat test.txt<br />
1 2 3 4 5 6<br />
bash$ echo n1=6 data_format=ascii_int in=test.txt > test.rsf<br />
bash$ sfin test.rsf<br />
test.rsf:<br />
in="test.txt"<br />
esize=0 type=int form=ascii<br />
n1=6 d1=? o1=?<br />
6 elements<br />
bash$ sfdd < test.rsf form=xdr type=complex > test2.rsf<br />
bash$ sfin test2.rsf<br />
test2.rsf:<br />
in="/tmp/test2.rsf@"<br />
esize=8 type=complex form=xdr<br />
n1=3 d1=? o1=?<br />
3 elements 24 bytes<br />
bash$ sfdisfil < test2.rsf<br />
0: 1, 2i 3, 4i 5, 6i<br />
</pre><br />
To learn more about the RSF data format, consult the [[Format| guide to RSF format]].<br />
<br />
==sfdisfil==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Print out data values.<br />
|-<br />
! colspan="4" | sfdisfil < in.rsf number=y col=0 format= header= trailer=<br />
|-<br />
| colspan="4" | <br>Alternatively, use sfdd and convert to ASCII form.<br />
|-<br />
| ''int '' || '''col=0''' || || Number of columns.<br />
:The default depends on the data type:<br />
:10 for int and char,<br />
:5 for float,<br />
:3 for complex<br />
|-<br />
| ''string '' || '''format=''' || || Format for numbers (printf-style).<br />
:The default depends on the data type:<br> "%4d " for int and char,<br> "%13.4g" for float,<br> "%10.4g,%10.4gi" for complex<br />
|-<br />
| ''string '' || '''header=''' || || Optional header string to output before data<br />
|-<br />
| ''bool '' || '''number=y''' || [y/n] || If number the elements<br />
|-<br />
| ''string '' || '''trailer=''' || || Optional trailer string to output after data<br />
|}<br />
<br />
<br />
The <tt>sfdisfil</tt> program simply dumps the data contents to the standard<br />
output in a text form. It is used mostly for debugging purposes to quickly<br />
examine RSF files. Here is an example:<br />
<pre><br />
bash$ sfmath o1=0 d1=2 n1=12 output=x1 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
10: 20 22<br />
</pre><br />
The output format is easily configurable.<br />
<pre><br />
bash$ < test.rsf sfdisfil col=6 number=n format="<br />
0.0 2.0 4.0 6.0 8.0 10.0<br />
12.0 14.0 16.0 18.0 20.0 22.0<br />
</pre><br />
Along with <tt>sfdd</tt>, <tt>sfdisfil</tt> provides a simple way to convert<br />
RSF data to an ASCII form.<br />
<br />
==sfdottest==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic dot-product test for linear operators with adjoints <br />
|-<br />
! colspan="4" | sfdottest mod=mod.rsf dat=dat.rsf > pip.rsf<br />
|}<br />
<br />
<br />
<tt>sfdottest</tt> is a generic dot-product test program for testing<br />
linear operators. Suppose there is an executable program<br />
<tt><prog></tt> that takes an RSF file from the standard input and<br />
produces an RSF file in the standard output. It may take any number of<br />
additional parameters but one of them must be <tt>adj=</tt> that sets<br />
the forward (<tt>adj=0</tt>) or adjoint (<tt>adj=1</tt>) operations.<br />
The program <tt><prog></tt> is typically an RSF program but it could<br />
be anything (a script, a multiprocessor MPI program, etc.) as long as<br />
it implements a linear operator <math>\mathbf{L}</math> and its adjoint<br />
<math>\mathbf{L}^T</math>. The <tt>sfdottest</tt> program is testing the equality<br />
<center><math><br />
d^T\,L\,m = m^T\,L^T\,d<br />
</math></center><br />
by using random vectors <math>\mathbf{m}</math> and <math>\mathbf{d}</math>. You can invoke it with<br />
<pre><br />
bash$ sfdottest <prog> [optional aruments] mod=mod.rsf dat=dat.rsf<br />
</pre><br />
where <tt>mod.rsf</tt> and <tt>dat.rsf</tt> are RSF files that<br />
represent vectors from the model and data spaces. Pay attention to the <br />
dimension and size of these vectors! If the program does not respond<br />
for a very long time, it is quite possible that the dimension and size<br />
of the vectors are inconsistent with the requirement of the program to be<br />
tested. <tt>sfdottest</tt><br />
does not create any temporary files and does not have any restrictive<br />
limitations on the size of the vectors.<br />
Here is an example. We first setup a vector with 100 elements using<br />
<tt>sfspike</tt> and then run <tt>sfdottest</tt> to test the<br />
<tt>sfcausint</tt> program. <tt>sfcausint</tt> implements a linear<br />
operator of causal integration and its adjoint, the anti-causal<br />
integration.<br />
<pre><br />
bash$ sfspike n1=100 > vec.rsf<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1410.2<br />
sfdottest: L'[d]*m=1410.2<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1165.87<br />
sfdottest: L'[d]*m=1165.87<br />
</pre><br />
The numbers are different on subsequent runs because of changing<br />
seed in the random number generator.<br />
Here is a somewhat more complicated example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
Now the <tt>sfdottest</tt> program can perform the dot product test.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=8.97375<br />
sfdottest: L'[d]*m=8.97375<br />
</pre><br />
Here is the same program tested in the inverse filtering mode:<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf inv=y<br />
sfdottest: L[m]*d=15.0222<br />
sfdottest: L'[d]*m=15.0222<br />
</pre><br />
<br />
==sfget==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Output parameters from the header.<br />
|-<br />
! colspan="4" | sfget < in.rsf parform=y par1 par2 ...<br />
|-<br />
| ''bool '' || '''parform=y''' || [y/n] || If y, print out parameter=value. If n, print out value.<br />
|}<br />
<br />
<br />
The <tt>sfget</tt> program extracts a parameter value from an RSF file. It is<br />
useful mostly for scripting. Here is, for example, a quick calculation of the<br />
maximum value on the first axis in an RSF dataset (the output of<br />
<tt>sfspike</tt>) using the standard Unix <tt>bc</tt> calculator.<br />
<pre><br />
bash$ ( sfspike n1=100 | sfget n1 d1 o1; echo "o1+(n1-1)*d1" ) | bc<br />
.396<br />
</pre><br />
See also <tt>sfput</tt>.<br />
<br />
<br />
<br />
==sfheadercut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheadercut mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array of size n2.<br />
|}<br />
<br />
<br />
<tt>sfheadercut</tt> is close to <tt>sfheaderwindow</tt> but instead<br />
of windowing the dataset, it fills the traces specified by the header<br />
mask with zeroes. The size of the input data is preserved.<br />
Here is an example of using <tt>sfheaderwindow</tt> for <br />
zeroing every other trace in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a mask with alternating ones and zeros using<br />
<tt>sfinterleave</tt>.<br />
<pre><br />
bash$ sfspike n1=5 mag=1 | sfdd type=int > ones.rsf<br />
bash$ sfspike n1=5 mag=0 | sfdd type=int > zeros.rsf<br />
bash$ sfinterleave axis=1 ones.rsf zeros.rsf > mask.rsf<br />
bash$ sfdisfil < mask.rsf<br />
0: 1 0 1 0 1 0 1 0 1 0<br />
</pre><br />
Finally, <tt>sfheadercut</tt> zeros the input traces.<br />
<pre><br />
bash$ sfheadercut < input.rsf mask=mask.rsf > output.rsf<br />
bash$ sfdisfil < output.rsf <br />
0: 1 1 1 1 1<br />
5: 0 0 0 0 0<br />
10: 3 3 3 3 3<br />
15: 0 0 0 0 0<br />
20: 5 5 5 5 5<br />
25: 0 0 0 0 0<br />
30: 7 7 7 7 7<br />
35: 0 0 0 0 0<br />
40: 9 9 9 9 9<br />
45: 0 0 0 0 0<br />
</pre><br />
<br />
<br />
<br />
==sfheadersort==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Sort a dataset according to a header key. <br />
|-<br />
! colspan="4" | sfheadersort < in.rsf > out.rsf head=<br />
|-<br />
| ''string '' || '''head=''' || || header file<br />
|}<br />
<br />
<br />
<tt>sfheadersort</tt> is used to sort traces in the input file<br />
according to trace header information. <br />
Here is an example of using<br />
<tt>sfheadersort</tt> for randomly shuffling traces in the input<br />
file. First, let us create an input file with seven traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=7 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7 <br />
</pre><br />
Next, we can create a random file with seven header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=7 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: 0.05256 -0.2879 0.1487 0.4097 0.1548<br />
5: 0.4501 0.2836<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally, we<br />
apply <tt>sfheadersort</tt> to shuffle the input traces.<br />
<pre><br />
bash$ < input.rsf sfheadersort head=random.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 1 1 1 1 1<br />
10: 3 3 3 3 3<br />
15: 5 5 5 5 5<br />
20: 7 7 7 7 7<br />
25: 4 4 4 4 4<br />
30: 6 6 6 6 6<br />
</pre><br />
As expected, the order of traces in the output file corresponds to the<br />
order of values in the header. Thanks to the separation between<br />
headers and data, the operation of <tt>sfheadersort</tt> is optimally<br />
efficient. It first sorts the headers and only then accesses the data,<br />
reading each data trace only once.<br />
<br />
==sfheaderwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheaderwindow mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array os size n2, windowed is n1xm2,<br>where m2 is the number of nonzero elements in mask.<br />
|}<br />
<br />
<br />
<tt>sfheaderwindow</tt> is used to window traces in the input file<br />
according to trace header information. <br />
Here is an example of using <tt>sfheaderwindow</tt> for randomly<br />
selecting part of the traces in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a random file with ten header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=10 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: -0.005768 0.02258 -0.04331 -0.4129 -0.3909<br />
5: -0.03582 0.4595 -0.3326 0.498 -0.3517<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally,<br />
we apply <tt>sfheaderwindow</tt> to window the input traces selecting<br />
only those for which the header is greater than zero.<br />
<pre><br />
bash$ < random.rsf sfmask min=0 > mask.rsf<br />
bash$ < mask.rsf sfdisfil<br />
0: 0 1 0 0 0 0 1 0 1 0<br />
bash$ < input.rsf sfheaderwindow mask=mask.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 7 7 7 7 7<br />
10: 9 9 9 9 9<br />
</pre><br />
In this case, only three traces are selected for the output. Thanks to<br />
the separation between headers and data, the operation of<br />
<tt>sfheaderwindow</tt> is optimally efficient. <br />
<br />
==sfin==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display basic information about RSF files.<br />
|-<br />
! colspan="4" | sfin info=y check=2. trail=y file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | n1,n2,... are data dimensions<br>o1,o2,... are axis origins<br>d1,d2,... are axis sampling intervals<br>label1,label2,... are axis labels<br>unit1,unit2,... are axis units<br />
|-<br />
| ''float '' || '''check=2.''' || || Portion of the data (in Mb) to check for zero values.<br />
|-<br />
| ''bool '' || '''info=y''' || [y/n] || If n, only display the name of the data file.<br />
|-<br />
| ''bool '' || '''trail=y''' || [y/n] || If n, skip trailing dimensions of one<br />
|}<br />
<br />
<br />
<tt>sfin</tt> is one of the most useful programs for operating with<br />
RSF files. It produces quick information on the file hypercube<br />
dimensions and checks the consistency of the associated data file.<br />
Here is an example. Let us create an RSF file and examine it with <tt>sfin</tt>.<br />
<pre><br />
bash$ sfspike n1=100 n2=20 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=100 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
2000 elements 8000 bytes<br />
</pre><br />
<tt>sfin</tt> reports the following information:<br />
<br />
*location of the data file (<tt>/tmp/spike.rsf\@</tt>) <br />
*element size (4 bytes) <br />
*element type (floating point) <br />
*element form (native) <br />
*hypercube dimensions (100 by 20) <br />
*axes scale (0.004 and 0.1) <br />
*axes origin (0 and 0) <br />
*axes labels <br />
*axes units <br />
*total number of elements <br />
*total number of bytes in the data file <br />
Suppose that the file got corrupted by a buggy program and reports<br />
incorrect dimensions. The <tt>sfin</tt> program should be able to<br />
catch the discrepancy.<br />
<pre><br />
bash$ echo n2=100 >> spike.rsf<br />
bash$ sfin spike.rsf > /dev/null<br />
sfin: Actually 8000 bytes, 20% of expected.<br />
</pre><br />
<tt>sfin</tt> also checks the first records in the file for zeros. <br />
<pre><br />
bash$ sfspike n1=100 n2=100 k2=99 > spike2.rsf<br />
bash$ sfin spike2.rsf >/dev/null<br />
sfin: The first 32768 bytes are all zeros<br />
</pre><br />
The number of bytes to check is adjustable<br />
<pre><br />
bash$ sfin spike2.rsf check=0.01 >/dev/null<br />
sfin: The first 16384 bytes are all zeros<br />
</pre><br />
You can also output only the location of the data file. This is<br />
sometimes handy in scripts.<br />
<pre><br />
bash$ sfin spike.rsf spike2.rsf info=n<br />
/tmp/spike.rsf@ /tmp/spike2.rsf@<br />
</pre><br />
An alternative is to use <tt>sfget</tt>, as follows:<br />
<pre><br />
bash$ sfget parform=n in < spike.rsf<br />
/tmp/spike.rsf@<br />
</pre><br />
<br />
==sfinterleave==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Combine several datasets by interleaving.<br />
|-<br />
! colspan="4" | sfinterleave > out.rsf axis=3 [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis for interleaving<br />
|}<br />
<br />
<br />
<tt>sfinterleave</tt> combines two or more datasets by interleaving them on one<br />
of the axes. Here is a quick example:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ sfscale < one.rsf dscale=2 > two.rsf<br />
bash$ sfdisfil < two.rsf<br />
0: 2 2 2 2 2<br />
5: 2 2 2 2 2<br />
10: 2 2 2 2 2<br />
15: 2 2 2 2 2<br />
20: 2 2 2 2 2<br />
bash$ sfinterleave one.rsf two.rsf axis=1 | sfdisfil<br />
0: 1 2 1 2 1<br />
5: 2 1 2 1 2<br />
10: 1 2 1 2 1<br />
15: 2 1 2 1 2<br />
20: 1 2 1 2 1<br />
25: 2 1 2 1 2<br />
30: 1 2 1 2 1<br />
35: 2 1 2 1 2<br />
40: 1 2 1 2 1<br />
45: 2 1 2 1 2<br />
bash$ sfinterleave < one.rsf two.rsf axis=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 1 1 1 1 1<br />
15: 2 2 2 2 2<br />
20: 1 1 1 1 1<br />
25: 2 2 2 2 2<br />
30: 1 1 1 1 1<br />
35: 2 2 2 2 2<br />
40: 1 1 1 1 1<br />
45: 2 2 2 2 2<br />
</pre><br />
<br />
==sfmask==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a mask.<br />
|-<br />
! colspan="4" | sfmask < in.rsf > out.rsf min=-FLT_MAX max=+FLT_MAX<br />
|-<br />
| colspan="4" | <br>Mask is an integer data with ones and zeros. <br>Ones correspond to input values between min and max.<br><br>The output can be used with sfheaderwindow.<br />
|-<br />
| ''float '' || '''max=+FLT_MAX''' || || maximum header value<br />
|-<br />
| ''float '' || '''min=-FLT_MAX''' || || minimum header value<br />
|}<br />
<br />
<br />
<tt>sfmask</tt> creates an integer output of ones and zeros comparing<br />
the values of the input data to specified <tt>min=</tt> and<br />
<tt>max=</tt> parameters. It is useful for <tt>sfheaderwindow</tt> and<br />
in many other applications. Here is a quick example:<br />
<pre><br />
bash$ sfmath n1=10 output="sin(x1)" > sin.rsf<br />
bash$ < sin.rsf sfdisfil<br />
0: 0 0.8415 0.9093 0.1411 -0.7568<br />
5: -0.9589 -0.2794 0.657 0.9894 0.4121<br />
bash$ < sin.rsf sfmask min=-0.5 max=0.5 | sfdisfil<br />
0: 1 0 0 1 0 0 1 0 0 1<br />
</pre><br />
<br />
==sfmath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations on data files.<br />
|-<br />
! colspan="4" | sfmath > out.rsf type= unit= output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs, conj (for complex data).<br> <br>sfmath will work on float or complex data, but all the input and output<br>files must be of the same data type.<br><br>An alternative to sfmath is sfadd, which may be more efficient, but is<br>less versatile.<br><br>Examples:<br><br>sfmath x=file1.rsf y=file2.rsf power=file3.rsf output='sin((x+2*y)^power)' > out.rsf<br>sfmath < file1.rsf tau=file2.rsf output='exp(tau*input)' > out.rsf<br>sfmath n1=100 type=complex output="exp(I*x1)" > out.rsf<br><br>See also: sfheadermath.<br />
|-<br />
| ''string '' || '''output=''' || || Mathematical description of the output<br />
|-<br />
| ''string '' || '''type=''' || || output data type [float,complex]<br />
|-<br />
| ''string '' || '''unit=''' || || <br />
|}<br />
<br />
<tt>sfmath</tt> is a versatile program for mathematical operations<br />
with RSF files. It can operate with several input file, all of the<br />
same dimensions and data type. The data type can be real (floating<br />
point) or complex. Here is an example that demonstrates several<br />
features of <tt>sfmath</tt>.<br />
<pre><br />
bash$ sfmath n1=629 d1=0.01 o1=0 n2=40 d2=1 o2=5 \<br />
output="x2*(8+sin(6*x1+x2/10))" > rad.rsf<br />
bash$ < rad.rsf sfrtoc | sfmath output="input*exp(I*x1)" > rose.rsf<br />
bash$ < rose.rsf sfgraph title=Rose screenratio=1 wantaxis=n | sfpen<br />
</pre><br />
The first line creates a 2-D dataset that consists of 40 traces 600<br />
samples each. The values of the data are computed with the formula<br />
<font color="#cd4b19">"x2*(8+sin(6*x1+x2/10))"</font>, where <tt>x1</tt> refers to the<br />
coordinate on the first axis, and <tt>x2</tt> is the coordinate of the<br />
second axis. In the second line, we convert the data from real to<br />
complex using <tt>sfrtoc</tt> and produce a complex dataset using<br />
formula <font color="#cd4b19">"input*exp(I*x1)"</font>, where <tt>input</tt> refers to the<br />
input file. Finally, we plot the complex data as a collection of<br />
parametric curves using <tt>sfgraph</tt> and display the result using<br />
<tt>sfpen</tt>. The plot appearing on your screen should look similar<br />
to the figure.<br />
[[Image:rose.png|frame|center|This figure was created with <tt>sfmath</tt>.]]<br />
One possible alternative to the second line above is<br />
<pre><br />
bash$ < rad.rsf sfmath output=x1 > ang.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*cos(a)" > cos.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*sin(a)" > sin.rsf<br />
bash$ sfcmplx cos.rsf sin.rsf > rose.rsf<br />
</pre><br />
Here we refer to input files by names (<tt>r</tt> and <tt>a</tt>) and combine the names in a formula.<br />
<br />
==sfpad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Pad a dataset with zeros.<br />
|-<br />
! colspan="4" | sfpad < in.rsf > out.rsf [beg1= beg2= ... end1= end2=... | n1= n2 = ... | n1out= n2out= ...]<br />
|-<br />
| colspan="4" | begN specifies the number of zeros to add before the beginning of axis N.<br>endN specifies the number of zeros to add after the end of axis N.<br><br>Alternatively:<br><br>nN or nNout specify the output length of axis N, padding occurs at the end.<br>nN and nNout are equivalent.<br />
|}<br />
<br />
<br />
<tt>pad</tt> increases the dimensions of the input dataset by padding<br />
the data with zeroes. Here are some simple examples.<br />
<pre><br />
bash$ sfspike n1=5 n2=3 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
bash$ < one.rsf sfpad n2=5 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 0 0 0 0 0<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfpad beg2=2 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 0 0 0 0<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < one.rsf sfpad beg2=1 end2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfwindow n1=3 | sfpad n1=5 n2=5 beg1=1 beg2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 1 1 1 0<br />
10: 0 1 1 1 0<br />
15: 0 1 1 1 0<br />
20: 0 0 0 0 0<br />
</pre><br />
You can use <tt>sfcat</tt> to pad data with values other than zeroes.<br />
<br />
==sfput==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Input parameters into a header. <br />
|-<br />
! colspan="4" | sfput < in.rsf > out.rsf<br />
|}<br />
<br />
<br />
<tt>sfput</tt> is a very simple program. It simply appends parameters<br />
from the command line to the output RSF file. One can achieve similar<br />
results with editing by hand or with standard Unix utilities like<br />
<tt>sed</tt> and <tt>echo</tt>. <tt>sfput</tt> is sometimes more<br />
convenient because it handles input/output operations similarly to<br />
other regular RSF programs.<br />
<pre><br />
bash$ sfspike n1=10 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
10 elements 40 bytes<br />
bash$ sfput < spike.rsf d1=25 label1=Depth unit1=m > spike2.rsf<br />
bash$ sfin spike2.rsf<br />
spike2.rsf:<br />
in="/tmp/spike2.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=25 o1=0 label1="Depth" unit1="m"<br />
10 elements 40 bytes<br />
</pre><br />
<br />
==sfreal==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extract real (sfreal) or imaginary (sfimag) part of a complex dataset. <br />
|-<br />
! colspan="4" | sfreal < cmplx.rsf > real.rsf<br />
|}<br />
<br />
<br />
<tt>sfreal</tt> extracts the real part of a complex type dataset. The<br />
imaginary part can be extracted with <tt>sfimag</tt>, an the real<br />
and imaginary part can be combined together with <tt>sfcmplx</tt>.<br />
Here is a simple example. Let us first create a complex dataset <br />
with <tt>sfmath</tt><br />
<pre><br />
bash$ sfmath n1=10 type=complex output="(2+I)*x1" > cmplx.rsf<br />
bash$ fdisfil < cmplx.rsf<br />
0: 0, 0i 2, 1i 4, 2i<br />
3: 6, 3i 8, 4i 10, 5i<br />
6: 12, 6i 14, 7i 16, 8i<br />
9: 18, 9i<br />
</pre><br />
Extracting the real part with <tt>sfreal</tt>:<br />
<pre><br />
bash$ sfreal < cmplx.rsf | sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
</pre><br />
Extracting the imaginary part with <tt>sfimag</tt>:<br />
<pre><br />
bash$ sfimag < cmplx.rsf | sfdisfil<br />
0: 0 1 2 3 4<br />
5: 5 6 7 8 9<br />
</pre><br />
<br />
==sfreverse==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Reverse one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfreverse < in.rsf > out.rsf which=-1 verb=false memsize=sf_memsize() opt=<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''opt=''' || || If y, change o and d parameters on the reversed axis;<br />
:if i, don't change o and d<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|-<br />
| ''int '' || '''which=-1''' || || Which axis to reverse.<br />
:To reverse a given axis, start with 0,<br />
:add 1 to number to reverse n1 dimension,<br />
:add 2 to number to reverse n2 dimension,<br />
:add 4 to number to reverse n3 dimension, etc.<br />
:Thus, which=7 would reverse the first three dimensions,<br />
:which=5 just n1 and n3, etc.<br />
:which=0 will just pass the input on through unchanged.<br />
|}<br />
Here is an example of using <tt>sfreverse</tt>. First, let us create a<br />
2-D dataset.<br />
<pre><br />
bash$ sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Reversing the first axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 | sfdisfil<br />
0: 4 3 2 1 0<br />
5: 5 4 3 2 1<br />
10: 6 5 4 3 2<br />
</pre><br />
Reversing the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=2 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
Reversing both the first and the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=3 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
As you can see, the <tt>which=</tt> parameter controls the axes that are<br />
being reversed by encoding them into one number.<br />
When an axis is reversed, what happens with its axis origin and<br />
sampling parameters? This behavior is controlled by <tt>opt=</tt>. In<br />
our example,<br />
<pre><br />
bash$ < test.rsf sfget n1 o1 d1<br />
n1=5<br />
o1=0<br />
d1=1<br />
bash$ < test.rsf sfreverse which=1 | sfget o1 d1<br />
o1=4<br />
d1=-1<br />
</pre><br />
The default behavior (equivalent to <tt>opt=y</tt>) puts the origin<br />
<tt>o1</tt> at the end of the axis and reverses the sampling parameter<br />
<tt>d1</tt>. Using <tt>opt=n</tt> preserves the sampling but reverses<br />
the origin.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=n | sfget o1 d1<br />
o1=-4<br />
d1=1<br />
</pre><br />
Using <tt>opt=i</tt> preserves both the sampling and the origin while<br />
reversing the axis.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=i | sfget o1 d1<br />
o1=0<br />
d1=1<br />
</pre><br />
One of the three possible behaviors may be desirable depending on the<br />
application.<br />
<br />
==sfrm==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Remove RSF files together with their data.<br />
|-<br />
! colspan="4" | sfrm file1.rsf [file2.rsf ...] [-i] [-v] [-f] <br />
|-<br />
| colspan="4" | Mimics the standard Unix rm command.<br><br>See also: sfmv, sfcp.<br />
|}<br />
<br />
<tt>sfrm</tt> is a program for removing RSF files. Its arguments mimic<br />
the arguments of the standard Unix <tt>rm</tt> utility: <tt>-v</tt><br />
for verbosity, <tt>-i</tt> for interactive inquiry, <tt>-f</tt> for<br />
force removal of suspicious files. Unlike the Unix <tt>rm</tt>,<br />
<tt>sfrm</tt> removes both the RSF header files and the binary files<br />
that the headers point to. <br />
Example:<br />
<pre><br />
bash&#36; sfspike n1=10 > spike.rsf datapath=./<br />
bash&#36; sfget in < spike.rsf<br />
in=./spike.rsf@<br />
bash&#36; ls spike*<br />
spike.rsf spike.rsf@<br />
bash&#36; sfrm -v spike.rsf<br />
sfrm: sf_rm: Removing header spike.rsf<br />
sfrm: sf_rm: Removing data ./spike.rsf@<br />
bash&#36; ls spike*<br />
ls: No match.<br />
</pre><br />
==sfrotate==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Rotate a portion of one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfrotate < in.rsf > out.rsf verb=n memsize=sf_memsize() rot#=(0,0,...)<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''rot#=(0,0,...)''' || || length of #-th axis that is moved to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<tt>sfrotate</tt> modifies the input dataset by splitting it into<br />
parts and putting the parts back in a different order. Here is a quick example.<br />
<pre><br />
bash&#36; sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Rotating the first axis by putting the last two columns in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=2 | sfdisfil<br />
0: 3 4 0 1 2<br />
5: 4 5 1 2 3<br />
10: 5 6 2 3 4<br />
</pre><br />
Rotating the second axis by putting the last row in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot2=1 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 0 1 2 3 4<br />
10: 1 2 3 4 5<br />
</pre><br />
Rotating both the first and the second axis:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=3 rot2=1 | sfdisfil<br />
0: 4 5 6 2 3<br />
5: 2 3 4 0 1<br />
10: 3 4 5 1 2<br />
</pre><br />
The transformation is shown schematically in Figure~(fig:rotate).<br />
[[Image:rotate.png|frame|center|Schematic transformation of data with <tt>sfrotate</tt>.]]<br />
<br />
==sfrtoc==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert real data to complex (by adding zero imaginary part).<br />
|-<br />
! colspan="4" | sfrtoc < real.rsf > cmplx.rsf<br />
|-<br />
| colspan="4" | <br>See also: sfcmplx<br />
|}<br />
The input to <tt>sfrtoc</tt> can be any <tt>type=float</tt> dataset:<br />
<pre><br />
bash$ sfspike n1=10 n2=20 n3=30 >real.rsf<br />
bash$ sfin real.rsf<br />
real.rsf:<br />
in="/var/tmp/real.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
</pre><br />
The output dataset will have <tt>type=complex</tt>, and its binary will be twice the size of the input:<br />
<pre><br />
bash$ <real.rsf sfrtoc >complex.rsf<br />
bash$ sfin complex.rsf <br />
complex.rsf:<br />
in="/var/tmp/complex.rsf@"<br />
esize=8 type=complex form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 48000 bytes<br />
</pre><br />
<br />
==sfscale==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Scale data.<br />
|-<br />
! colspan="4" | sfscale < in.rsf > out.rsf axis=0 rscale=0. dscale=1.<br />
|-<br />
| colspan="4" | <br>To scale by a constant factor, you can also use sfmath or sfheadermath.<br />
|-<br />
| ''int '' || '''axis=0''' || || Scale by maximum in the dimensions up to this axis.<br />
|-<br />
| ''float '' || '''dscale=1.''' || || Scale by this factor (works if rscale=0)<br />
|-<br />
| ''float '' || '''rscale=0.''' || || Scale by this factor.<br />
|}<br />
<tt>sfscale</tt> scales the input dataset by a factor. Here<br />
are some simple examples. First, let us create a test dataset.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil <br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Scale every data point by 2:<br />
<pre><br />
bash&#36; < test.rsf sfscale dscale=2 | sfdisfil<br />
0: 2 4 6 8 10<br />
5: 4 8 12 16 20<br />
10: 6 12 18 24 30<br />
</pre><br />
Divide every trace by its maximum value:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=1 | sfdisfil<br />
0: 0.2 0.4 0.6 0.8 1<br />
5: 0.2 0.4 0.6 0.8 1<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
Divide by the maximum value in the whole 2-D dataset:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=2 | sfdisfil<br />
0: 0.06667 0.1333 0.2 0.2667 0.3333<br />
5: 0.1333 0.2667 0.4 0.5333 0.6667<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
The <tt>rscale=</tt> parameter is synonymous to <tt>dscale=</tt> except<br />
when it is equal to zero. With <tt>sfscale dscale=0</tt>, the dataset gets<br />
multiplied by zero. If using <tt>rscale=0</tt>, the other parameters are<br />
used to define scaling. Thus, <tt>sfscale rscale=0 axis=1</tt> is<br />
equivalent to <tt>sfscale axis=1</tt>, and <tt>sfscale rscale=0</tt><br />
is equivalent to <tt>sfscale dscale=1</tt>.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
==sfspike==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate simple data: spikes, boxes, planes, constants.<br />
|-<br />
! colspan="4" | sfspike > spike.rsf mag= nsp=1 k#=[0,...] l#=[k1,k2,...] p#=[0,...] n#= o#=(0,...) d#=(0.004,0.1,0.1,...) label#=(Time,Distance,Distance,...) unit#=[s,km,km,...] title=<br />
|-<br />
| ''float '' || '''d#=(0.004,0.1,0.1,...)''' || || sampling on #-th axis<br />
|-<br />
| ''ints '' || '''k#=[0,...]''' || || spike starting position [nsp]<br />
|-<br />
| ''ints '' || '''l#=[k1,k2,...]''' || || spike ending position [nsp]<br />
|-<br />
| ''string '' || '''label#=(Time,Distance,Distance,...)''' || || label on #-th axis<br />
|-<br />
| ''floats '' || '''mag=''' || || spike magnitudes [nsp]<br />
|-<br />
| ''int '' || '''n#=''' || || dimension of #-th axis<br />
|-<br />
| ''int '' || '''nsp=1''' || || Number of spikes<br />
|-<br />
| ''float '' || '''o#=(0,...)''' || || origin on #-th axis<br />
|-<br />
| ''floats '' || '''p#=[0,...]''' || || spike inclination (in samples) [nsp]<br />
|-<br />
| ''string '' || '''title=''' || || title for plots<br />
|-<br />
| ''string '' || '''unit#=[s,km,km,...]''' || || unit on #-th axis<br />
|}<br />
This is the program for creating a RSF hypercube out of nothing. Calling <tt>sfspike</tt> without specifying the k# or l# parameters will result in a volume filled with values specified by <tt>mag</tt>. To get a file full of 1's, just give <tt>sfspike</tt> the axis values that running <tt>sfin</tt> on your desired output would produce. I.e. if you run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" > out.rsf<br />
</pre><br />
you will obtain the following file:<br />
<pre><br />
bash$ sfin out.rsf<br />
out.rsf:<br />
in="/var/tmp/out.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
300 elements 1200 bytes<br />
</pre><br />
To create a "flat reflector" in the file above, run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5> out2.rsf<br />
</pre><br />
Notice that the values for <tt>k</tt> and <tt>l</tt> are in samples, not in the physical units of the respective axes. The result can be visualised with <br />
<pre><br />
< out2.rsf sfgrey pclip=100 wantscalebar=y title="Illustration of k,l parameters" | xtpen<br />
</pre><br />
which produces the following plot:<br />
<br />
[[Image:sfspike_fig1.png]]<br />
<br />
The <tt>p</tt> parameters can be used to create slanted lines/planes. Specifying <tt>p2=1</tt> means that for each lateral step, the spike will be shifted down with 1 sample. Below is the command and the corresponding graphical output it creates:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=1 |\<br />
sfgrey pclip=100 wantscalebar=y title="Effect of p2=1" | xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig2.png]]<br />
<br />
Sfspike also supports negative and non-integer p values:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=-0.15 |\<br />
sfgrey pclip=100 wantscalebar=y allpos=y color=h title="Effect of p2=-0.15" |xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig3.png]]<br />
<br />
When <tt>nsp</tt> is greater than the number of values for <tt>k</tt> and <tt>l</tt> parameters, the extra spikes will be piled on top of the last one, increasing its amplitude. Look at the amplitude of the last event in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=3 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
and in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=5 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
(pictures coming soon). This feature can easily cause a bug when the number of events is large and they have not been properly counted, or when a new spike was added on a list but <tt>nsp</tt> was not updated.<br />
<br />
==sfspray==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extend a dataset by duplicating in the specified axis dimension.<br />
|-<br />
! colspan="4" | sfspray < in.rsf > out.rsf axis=2 n= d= o= label= unit=<br />
|-<br />
| colspan="4" | This operation is adjoint to sfstack.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to spray<br />
|-<br />
| ''float '' || '''d=''' || || Sampling of the newly created dimension<br />
|-<br />
| ''string '' || '''label=''' || || Label of the newly created dimension<br />
|-<br />
| ''int '' || '''n=''' || || Size of the newly created dimension<br />
|-<br />
| ''float '' || '''o=''' || || Origin of the newly created dimension<br />
|-<br />
| ''string '' || '''unit=''' || || Units of the newly created dimension<br />
|}<br />
<br />
<tt>sfspray</tt> extends the input hypercube by replicating the data<br />
in one of the dimensions. The output dataset acquires one additional<br />
dimension. Here is an example:<br />
Start with a 2-D dataset<br />
<pre><br />
bash&#36; sfmath n1=5 n2=2 output=x1+x2 > test.rsf<br />
bash&#36; sfin test.rsf<br />
test.rsf:<br />
in="/var/tmp/test.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
10 elements 40 bytes<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
</pre><br />
Extend the data in the second dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=2 n=3 > test2.rsf<br />
bash&#36; sfin test2.rsf<br />
test2.rsf:<br />
in="/var/tmp/test2.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=3 d2=1 o2=0 <br />
n3=2 d3=1 o3=0 <br />
30 elements 120 bytes<br />
bash&#36; < test2.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 0 1 2 3 4<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
20: 1 2 3 4 5<br />
25: 1 2 3 4 5<br />
</pre><br />
The output is three-dimensional, with traces from the original<br />
data duplicated along the second axis.<br />
Extend the data in the third dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=3 n=2 > test3.rsf<br />
bash&#36; sfin test3.rsf<br />
test3.rsf:<br />
in="/var/tmp/test3.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
n3=2 d3=? o3=? <br />
20 elements 80 bytes<br />
bash&#36; < test3.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
</pre><br />
The output is also three-dimensional, with the original data replicated<br />
along the third axis.<br />
<br />
==sfstack==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stack a dataset over one of the dimensions.<br />
|-<br />
! colspan="4" | sfstack < in.rsf > out.rsf axis=2 rms=n norm=y min=n max=n<br />
|-<br />
| colspan="4" | <br>This operation is adjoint to sfspray.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to stack<br />
|-<br />
| ''bool '' || '''max=n''' || [y/n] || If y, find maximum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''min=n''' || [y/n] || If y, find minimum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || If y, normalize by fold.<br />
|-<br />
| ''bool '' || '''rms=n''' || [y/n] || If y, compute the root-mean-square instead of stack.<br />
|}<br />
While <tt>sfspray</tt> adds a dimension to a hypercube,<br />
<tt>sfstack</tt> effectively removes one of the dimensions by stacking<br />
over it. Here are some examples:<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
bash&#36; < test.rsf sfstack axis=2 | sfdisfil<br />
0: 1.5 2 3 4 5<br />
bash&#36; < test.rsf sfstack axis=1 | sfdisfil<br />
0: 2.5 3 4<br />
</pre><br />
Why is the first value not 1 (in the first case) or 2 (in the second<br />
case)? By default, <tt>sfstack</tt> normalizes the stack by the fold<br />
(the number of non-zero entries). To avoid normalization, use<br />
<tt>norm=n</tt>, as follows:<br />
<pre><br />
bash&#36; < test.rsf sfstack norm=n | sfdisfil <br />
0: 3 6 9 12 15<br />
</pre><br />
<tt>sfstack</tt> can also compute root-mean-square values as <br />
well as minimum and maximum values.<br />
<pre><br />
bash&#36; < test.rsf sfstack rms=y | sfdisfil<br />
0: 1.581 2.16 3.109 4.082 5.066<br />
bash&#36; < test.rsf sfstack min=y | sfdisfil<br />
0: 0 1 2 3 4<br />
bash&#36; < test.rsf sfstack axis=1 max=y | sfdisfil <br />
0: 4 5 6<br />
</pre><br />
<br />
==sftransp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Transpose two axes in a dataset. <br />
|-<br />
! colspan="4" | sftransp < in.rsf > out.rsf memsize=sf_memsize() plane=<br />
|-<br />
| colspan="4" | <br>If you get a "Cannot allocate memory" error, give the program a<br>memsize=1 command-line parameter to force out-of-core operation.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''plane=''' || || Two-digit number with axes to transpose. The default is 12<br />
|}<br />
<br />
The <tt>sftransp</tt> program transposes the input hypercube<br />
exchanging the two axes specified by the <b>plane=</b> parameter. <br />
<pre><br />
bash&#36; sfspike n1=10 n2=20 n3=30 > orig123.rsf<br />
bash&#36; sfin orig123.rsf <br />
orig123.rsf:<br />
in="/var/tmp/orig123.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=23 >out132.rsf<br />
bash&#36; sfin out132.rsf <br />
out132.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=20 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=13 >out321.rsf<br />
bash&#36; sfin out321.rsf <br />
out321.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=30 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=10 d3=0.004 o3=0 label3="Time" unit3="s" <br />
6000 elements 24000 bytes<br />
</pre><br />
<tt>sftransp</tt> tries to fit the dataset in memory to transpose it<br />
there but, if not enough memory is available, it performs a slower<br />
transpose out of core using disk operations. You can control the<br />
amount of available memory using the <b>memsize=</b> parameter or<br />
the <b>RSFMEMSIZE</b> environmental variable.<br />
<br />
==sfwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a portion of the dataset. <br />
|-<br />
! colspan="4" | sfwindow < in.rsf > out.rsf verb=n squeeze=y j#=(1,...) d#=(d1,d2,...) f#=(0,...) min#=(o1,o2,,...) n#=(0,...) max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)<br />
|-<br />
| ''float '' || '''d#=(d1,d2,...)''' || || sampling in #-th dimension<br />
|-<br />
| ''int '' || '''f#=(0,...)''' || || window start in #-th dimension<br />
|-<br />
| ''int '' || '''j#=(1,...)''' || || jump in #-th dimension<br />
|-<br />
| ''float '' || '''max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)''' || || maximum in #-th dimension<br />
|-<br />
| ''float '' || '''min#=(o1,o2,,...)''' || || minimum in #-th dimension<br />
|-<br />
| ''int '' || '''n#=(0,...)''' || || window size in #-th dimension<br />
|-<br />
| ''bool '' || '''squeeze=y''' || [y/n] || if y, squeeze dimensions equal to 1 to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
<b>sfwindow</b> is used to window a portion of the dataset. Here is<br />
a quick example: Start by creating some data.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Now window the first two rows:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n2=2 | sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
</pre><br />
Window the first three columns:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n1=3 | sfdisfil<br />
0: 1 2 3 2 4<br />
5: 6 3 6 9<br />
</pre><br />
Window the middle row:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f2=1 n2=1 | sfdisfil<br />
0: 2 4 6 8 10<br />
</pre><br />
You can interpret the <b>f#</b> and <b>n#</b> parameters as<br />
meaning "skip that many rows/columns" and "select that many<br />
rows/columns" correspondingly. Window the middle point in the dataset:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f1=2 n1=1 f2=1 n2=1 | sfdisfil<br />
0: 6<br />
</pre><br />
Window every other column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=2 | sfdisfil<br />
0: 1 3 5 2 6<br />
5: 10 3 9 15<br />
</pre><br />
Window every third column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=3 | sfdisfil<br />
0: 1 4 2 8 3<br />
5: 12<br />
</pre><br />
Alternatively, <b>sfwindow</b> can use the minimum and maximum<br />
parameters to select a window. In the following example, we are<br />
creating a dataset with <b>sfspike</b> and then windowing a portion of it<br />
between 1 and 2 seconds in time and sampled at 8 miliseconds.<br />
<pre><br />
bash&#36; sfspike n1=1000 n2=10 > spike.rsf <br />
bash&#36; sfin spike.rsf<br />
spike.rsf:<br />
in="/var/tmp/spike.rsf@"<br />
esize=4 type=float form=native <br />
n1=1000 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10000 elements 40000 bytes<br />
bash&#36; < spike.rsf sfwindow min1=1 max1=2 d1=0.008 > window.rsf<br />
bash&#36; sfin window.rsf<br />
window.rsf:<br />
in="/var/tmp/window.rsf@"<br />
esize=4 type=float form=native <br />
n1=126 d1=0.008 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
1260 elements 5040 bytes<br />
</pre><br />
By default, <b>sfwindow</b> "squeezes" the hypercube dimensions<br />
that are equal to one toward the end of the dataset. Here is an<br />
example of taking a time slice:<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=1 d2=0.004 o2=1 label2="Time" unit2="s" <br />
10 elements 40 bytes<br />
</pre><br />
You can change this behavior by specifying <b>squeeze=n</b>.<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 squeeze=n > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=1 d1=0.004 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10 elements 40 bytes<br />
</pre><br />
<br />
=Seismic programs=<br />
Programs in this category are specific for operations on seismic data. The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/seismic/ system/seismic] in the Madagascar distribution.<br />
<br />
==sfheaderattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Integer header attributes. <br />
|-<br />
! colspan="4" | sfheaderattr < head.rsf<br />
|-<br />
| colspan="4" | <br>Only nonzero values are reported.<br />
|}<br />
<br />
The <tt>sfheaderattr</tt> examines the contents of a trace header file,<br />
typically generated by <tt>sfsegyread</tt>. In the example below, we examine<br />
trace headers in the output of <tt>suplane</tt>, a program from Seismic Unix.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
bash$ sfheaderattr < tfile.rsf<br />
*******************************************<br />
71 headers, 32 traces<br />
key[0]="tracl" min[0]=1 max[31]=32 mean=16.5<br />
key[1]="tracr" min[0]=1 max[31]=32 mean=16.5<br />
key[11]="offset" min[0]=400 max[31]=400 mean=400<br />
key[38]="ns" min[0]=64 max[31]=64 mean=64<br />
key[39]="dt" min[0]=4000 max[31]=4000 mean=4000<br />
*******************************************<br />
</pre><br />
For different standard keywords, a minimum, maximum, and mean values<br />
are reported unless they are identically zero. This quick inspection<br />
can help in identifying meaningful keywords set in the data. The input<br />
data type must be <tt>int</tt>.<br />
<br />
==sfheadermath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations, possibly on header keys. <br />
|-<br />
! colspan="4" | sfheadermath < in.rsf > out.rsf memsize=sf_memsize() output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs<br><br>See also sfmath. <br><br>An addition operation can be performed by sfstack.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''output=''' || || Describes the output in a mathematical notation.<br />
|}<br />
<tt>sfheadermath</tt> is a versatile program for mathematical<br />
operations on rows of the input file. If the input file is an<br />
<tt>n1</tt> by <tt>n2</tt> matrix, the output will be a <tt>1</tt> by<br />
<tt>n2</tt> matrix that contains one row made out of mathematical<br />
operations on the other rows. <tt>sfheadermath</tt> can identify a row<br />
by number or by a standard SEGY keyword. The latter is useful for<br />
processing headers extracted from SEGY or SU files.<br />
Here is an example. First, we create an SU file with <tt>suplane</tt> and convert it to RSF using <tt>sfsegyread</tt>.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
</pre><br />
The trace header information is saved in <tt>tfile.rsf</tt>. It<br />
contains 71 headers for 32 traces in integer format.<br />
<pre><br />
bash$ sfin tfile.rsf<br />
tfile.rsf:<br />
in="/tmp/tfile.rsf@"<br />
esize=4 type=int form=native<br />
n1=71 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
2272 elements 9088 bytes<br />
</pre><br />
Next, we will convert <tt>tfile.rsf</tt> to a floating-point format<br />
and run <tt>sfheadermath</tt> to create a new header.<br />
<pre><br />
bash$ < tfile.rsf sfdd type=float | \<br />
sfheadermath myheader=1 output="sqrt(myheader+(2+10*offset^2))" > new.rsf<br />
bash$ sfin new.rsf<br />
new.rsf:<br />
in="/tmp/new.rsf@"<br />
esize=4 type=float form=native<br />
n1=1 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
32 elements 128 bytes<br />
</pre><br />
We defined "myheader" as being the row number 1 in the input (note<br />
that numbering starts with 0) and combined it with "offset", which<br />
is a standard SEGY keyword that denotes row number 11 (see the output<br />
of <tt>sfheaderattr</tt> above.) A variety of mathematical expressions<br />
can be defined in the <tt>output=</tt> string. The expression<br />
processing engine is shared with <tt>sfmath</tt>.<br />
<br />
==sfsegyheader==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Make a trace header file for segywrite.<br />
|-<br />
! colspan="4" | sfsegyheader < in.rsf > out.rsf n1= d1=<br />
|-<br />
| colspan="4" | <br> Use the output for tfile= argument in segywrite.<br />
|-<br />
| ''float '' || '''d1=''' || || trace sampling<br />
|-<br />
| ''int '' || '''n1=''' || || number of samples in a trace<br />
|}<br />
<br />
==sfsegyread==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert a SEG-Y or SU dataset to RSF.<br />
|-<br />
! colspan="4" | sfsegyread mask=msk.rsf > out.rsf tfile=hdr.rsf verb=false su=false format=sf_segyformat (bhead) ns=sf_segyns (bhead) endian= tape= read= hfile= bfile= mask= tfile=<br />
|-<br />
| colspan="4" | <br>Data headers and trace headers are separated from the data.<br><br>Defined SEG-Y trace header key names and byte offsets:<br><br>tracl: trace sequence number within line 0<br><br>tracr: trace sequence number within reel 4<br><br>fldr: field record number 8 <br><br>tracf: trace number within field record 12 <br><br>ep: energy source point number 16 <br><br>cdp: CDP ensemble number 20 <br><br>cdpt: trace number within CDP ensemble 24 <br><br>trid: trace identification code:<br>1 = seismic data<br>2 = dead<br>3 = dummy<br>4 = time break<br>5 = uphole<br>6 = sweep<br>7 = timing<br>8 = water break<br>9---, N = optional use (N = 32,767) 28 <br><br>nvs: number of vertically summed traces 30 <br><br>nhs: number of horizontally summed traces 32 <br><br>duse: data use:<br>1 = production<br>2 = test 34<br><br>offset: distance from source point to receiver<br>group (negative if opposite to direction<br>in which the line was shot) 36 <br><br>gelev: receiver group elevation from sea level<br>(above sea level is positive) 40 <br><br>selev: source elevation from sea level<br>(above sea level is positive) 44 <br><br>sdepth: source depth (positive) 48 <br><br>gdel: datum elevation at receiver group 52 <br><br>sdel: datum elevation at source 56 <br><br>swdep: water depth at source 60 <br><br>gwdep: water depth at receiver group 64 <br><br>scalel: scale factor for previous 7 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 68 <br><br>scalco: scale factor for next 4 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 70 <br><br>sx: X source coordinate 72 <br><br>sy: Y source coordinate 76 <br><br>gx: X group coordinate 80 <br><br>gy: Y group coordinate 84 <br><br>counit: coordinate units code:<br>for previoius four entries<br>1 = length (meters or feet)<br>2 = seconds of arc (in this case, the<br>X values are unsigned intitude and the Y values<br>are latitude, a positive value designates<br>the number of seconds east of Greenwich<br>or north of the equator 88 <br><br>wevel: weathering velocity 90 <br><br>swevel: subweathering velocity 92 <br><br>sut: uphole time at source 94 <br><br>gut: uphole time at receiver group 96 <br><br>sstat: source static correction 98 <br><br>gstat: group static correction 100 <br><br>tstat: total static applied 102 <br><br>laga: lag time A, time in ms between end of 240-<br>byte trace identification header and time<br>break, positive if time break occurs after<br>end of header, time break is defined as<br>the initiation pulse which maybe recorded<br>on an auxiliary trace or as otherwise<br>specified by the recording system 104 <br><br>lagb: lag time B, time in ms between the time<br>break and the initiation time of the energy source,<br>may be positive or negative 106 <br><br>delrt: delay recording time, time in ms between<br>initiation time of energy source and time<br>when recording of data samples begins<br>(for deep water work if recording does not<br>start at zero time) 108 <br><br>muts: mute time--start 110 <br><br>mute: mute time--end 112 <br><br>ns: number of samples in this trace 114 <br><br>dt: sample interval, in micro-seconds 116 <br><br>gain: gain type of field instruments code:<br>1 = fixed<br>2 = binary<br>3 = floating point<br>4 ---- N = optional use 118 <br><br>igc: instrument gain constant 120 <br><br>igi: instrument early or initial gain 122 <br><br>corr: correlated:<br>1 = no<br>2 = yes 124 <br><br>sfs: sweep frequency at start 126 <br><br>sfe: sweep frequency at end 128 <br><br>slen: sweep length in ms 130 <br><br>styp: sweep type code:<br>1 = linear<br>2 = cos-squared<br>3 = other 132 <br><br>stas: sweep trace length at start in ms 134 <br><br>stae: sweep trace length at end in ms 136 <br><br>tatyp: taper type: 1=linear, 2=cos^2, 3=other 138 <br><br>afilf: alias filter frequency if used 140 <br><br>afils: alias filter slope 142 <br><br>nofilf: notch filter frequency if used 144 <br><br>nofils: notch filter slope 146 <br><br>lcf: low cut frequency if used 148 <br><br>hcf: high cut frequncy if used 150 <br><br>lcs: low cut slope 152 <br><br>hcs: high cut slope 154 <br><br>year: year data recorded 156 <br><br>day: day of year 158 <br><br>hour: hour of day (24 hour clock) 160 <br><br>minute: minute of hour 162 <br><br>sec: second of minute 164 <br><br>timbas: time basis code:<br>1 = local<br>2 = GMT<br>3 = other 166 <br><br>trwf: trace weighting factor, defined as 1/2^N<br>volts for the least sigificant bit 168 <br><br>grnors: geophone group number of roll switch<br>position one 170 <br><br>grnofr: geophone group number of trace one within<br>original field record 172 <br><br>grnlof: geophone group number of last trace within<br>original field record 174 <br><br>gaps: gap size (total number of groups dropped) 176 <br><br>otrav: overtravel taper code:<br>1 = down (or behind)<br>2 = up (or ahead)<br />
|-<br />
| ''string '' || '''bfile=''' || || output binary data header file<br />
|-<br />
| ''bool '' || '''endian=''' || [y/n] || big/little endian flag, the default is estimated automatically<br />
|-<br />
| ''int '' || '''format=sf_segyformat (bhead)''' || [1,2,3,5] || Data format. The default is taken from binary header.<br />
:1 is IBM floating point<br />
:2 is 4-byte integer<br />
:3 is 2-byte integer<br />
:5 is IEEE floating point<br />
|-<br />
| ''string '' || '''hfile=''' || || output text data header file<br />
|-<br />
| ''string '' || '''mask=''' || || optional header mask for reading only selected traces<br />
|-<br />
| ''int '' || '''ns=sf_segyns (bhead)''' || || Number of samples. The default is taken from binary header<br />
|-<br />
| ''string '' || '''read=''' || || what to read: h - header, d - data, b - both (default)<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if input is SU, n if input is SEGY<br />
|-<br />
| ''bool '' || '''suxdr=n''' || [y/n] || y, SU has XDR support<br />
|-<br />
| ''string '' || '''tape=''' || || <br />
|-<br />
| ''string '' || '''tfile=''' || || output trace header file<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
The SEG Y format is an [http://en.wikipedia.org/wiki/Open_standard open standard] for the exchange of geophysical data. It is controlled by the non-profit [http://www.seg.org/SEGportalWEBproject/portals/SEG_Online.portal?_nfpb=true&_pageLabel=pg_gen_content&Doc_Url=prod/SEG-Publications/Pub-Yearbook/committees.htm SEG Technical Standards Committee]. There are two versions of this standard: [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev0.pdf rev0] (1975)<ref>Barry, K.M., Cavers, D.A., and Kneale, C.W. 1975. Recommended standards for digital tape formats. ''Geophysics'', '''40''', no. 02, 344–352.</ref> and [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf rev1] (2002)<ref>Norris, M.W., Faichney, A.K., ''Eds''. 2001. SEG Y rev1 Data Exchange format. Society of Exploration Geophysicists, Tulsa, OK, 45 pp.</ref>. The implementation in <tt>sfsegyread</tt> is a mixture of rev0 (i.e. no checks for Extended Textual Headers) and rev1 ([http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE floating point format] allowed for trace data samples).<br />
<br />
A SEG-Y file as understood by <tt>sfsegyread</tt> contains a "Reel Identification Header" (3200 bytes in EBCDIC followed by 400 bytes in a binary encoding), followed by a number of "Trace Blocks". Each "Trace Block" contains a 240-byte "Trace Header" (binary) followed by "Trace Data" -- a sequence of <tt>ns</tt> samples. Binary values in both reel headers and trace headers are two's complement integers, either two bytes or four bytes long. There are no floating-point values defined in the headers. Trace Data samples can have various encodings, either floating point or integer, described further down, but they are all big-endian. To convert from SEG-Y to RSF, <tt>sfsegyread</tt> will strip the tape reel EBCDIC header and convert it to ASCII, will extract the reel binary header without changing it, and will put the trace headers into one RSF file, and the traces themselves on another.<br />
<br />
===SEG-Y Trace Headers===<br />
In the SEG-Y standard, only the first 180 bytes of the 240-byte trace header are defined; bytes 181-240 are reserved for non-standard header information, and these locations are increasingly used in modern SEG-Y files and its variants. The standard provides for a total of 71 4-byte and 2-byte predefined header words. These 71 standard words have defined lengths and byte offsets, and only these words and byte locations are read using <tt>segyread</tt> and output to the RSF header file with the <tt>hfile=</tt> option. The user may remap these predefined keywords to a different byte offsets.<br />
<br />
===SU File Format===<br />
An [http://www.cwp.mines.edu/sututor/node22.html SU file] is nothing more than a SEG-Y file without the reel headers, and with the Trace Data samples in the native encoding of the CPU the file was created on (Attention -- limited portability!). So, to convert from SU to RSF, <tt>sfsegyread</tt> will just separate headers and traces into two RSF files. <br />
<br />
===SEG-Y specific parameters===<br />
*<tt>hfile=</tt> specifies the name of the file in which the EBCDIC reel header will be put after conversion to ASCII. If you are certain there is no useful information in it, <tt>hfile=/dev/null</tt> works just fine. If you do not specify anything for this parameter you will get an ASCII file named <tt>header</tt> in the current directory. If you want to quickly preview this header before running <tt>sfsegyread</tt>, use<pre>dd if=input.segy count=40 bs=80 cbs=80 conv=unblock,ascii</pre><br />
*<tt>bfile=</tt> specifies name of the file in which the binary reel header (the 400-bytes thing following the 3600-bytes EBCDIC) will be put without any conversion. The default name is "binary". Unless you have software that knows how to read exactly this special type of file, it will be completely useless, so do <tt>bfile=/dev/null</tt><br />
*<tt>format=</tt> specifies the format in which the trace data samples are in the SEG-Y input file. This is read from the binary reel header of the SEG-Y file. Valid values are 1(IBM floating point), 2 (4-byte integer), 3 (2-byte integer) and 5 (IEEE floating point). If the input file is SU, the format will be assumed to be the native <tt>float</tt> format.<br />
<br />
*<tt>keyname=</tt> specifies the byte offset to remap a header using the trace header key names shown above. For example, if the CDP locations have been placed in bytes 181-184 instead of the standard 21-24, <tt>cdp=180</tt> will remap the trace header to that location. <br />
<br />
===SU-specific parameters===<br />
*<tt>suxdr=</tt> specifies whether the input file was created with a SU package with XDR support enabled. If you have access to the source code of your SU install (try <tt>$CWPROOT/src</tt>), type: <tt>grep 'XDRFLAG =' $CWPROOT/src/Makefile.config</tt> and look at the last uncommented entry. If no value is given for <tt>XDRFLAG</tt>, the package was not compiled with XDR support.<br />
===Common parameters===<br />
*<tt>su=</tt> specifies if the input file is SU or SEG-Y. Default is <tt>su=n</tt> (SEG-Y file).<br />
*<tt>tape=</tt> specifies the input data. Stdin could not be used because <tt>sfsegyread</tt> has to work with tapes, and needs to fseek back and forth through the input file. Thankfully, output is on stdout.<br />
*<tt>read=</tt> specifies what parts of the "Trace Blocks" will be read. It can be <tt>read=t</tt> (only trace data is read), <tt>read=h</tt> (only trace headers are read) or <tt>read=b</tt> (both are read).<br />
*<tt>tfile=</tt> gives the name of the RSF file to which trace headers are written. Obviously, it should be only specified with <tt>read=h</tt> or <tt>read=b</tt>.<br />
*<tt>mask=</tt> is an optional parameter specifying the name of a mask that says which traces will be read. The mask is a 1-D RSF file with integers. The number of samples in the mask is the same as the number of traces in the unmasked SEG-Y. In places corresponding to unwanted traces there should be zeros in the mask.<br />
*<tt>ns=</tt> specifies the number of samples in a trace. For SEG-Y files, the default is taken from the binary reel header, and for SU files, from the header of the first trace. This parameter is however critical enough that a command line override was given for it.<br />
*<tt>verbose=</tt> is the verbosity flag. Can be <tt>y</tt> or <tt>n</tt>.<br />
*<tt>endian=</tt> is a y/n flag (default y), specifying whether to automatically estimate or not if samples in the Trace Data blocks are big-endian or little-endian. Try it if you are in trouble and do not know what else to do, otherwise let the automatic estimation do its job.<br />
<br />
==sfsegywrite==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert an RSF dataset to SEGY or SU.<br />
|-<br />
! colspan="4" | sfsegywrite < in.rsf tfile=hdr.rsf verb=false su=false endian=sf_endian() tape= hfile= bfile=<br />
|-<br />
| colspan="4" | <br>Merges trace headers with data.<br />
|-<br />
| ''string '' || '''bfile=''' || || input binary data header file<br />
|-<br />
| ''bool '' || '''endian=sf_endian()''' || [y/n] || big/little endian flag. The default is estimated automatically<br />
|-<br />
| ''string '' || '''hfile=''' || || input text data header file<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if output is SU, n if output is SEGY<br />
|-<br />
| ''string '' || '''tape=''' || ||<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
Please see <tt>sfsegyread</tt> for a complete description of parameter meanings and background issues. Parameters <tt>bfile</tt> and <tt>hfile</tt> should only be given values when the desired file is SEG-Y (default). The output file is specified by the <tt>tape=</tt> tag.<br />
<br />
=Plotting programs=<br />
The source files for these programs can be found under<br />
[http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/plot/main/ plot/main]<br />
in the Madagascar distribution.<br />
<br />
THIS SECTION IS UNDER CONSTRUCTION<br />
<br />
==sfbox==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Draw a balloon-style label.<br />
|-<br />
! colspan="4" | sfbox lab_color=VP_WHITE lab_fat=0 pscale=1. pointer=y reverse=n lat=0. long=90. angle=0. x0=0. y0=0. scale0=1. xt=2. yt=0. x_oval=0. y_oval=0. boxit=y length= scalet= size=.25 label= > out.vpl<br />
|-<br />
| ''float '' || '''angle=0.''' || || longitude of floating label in 3-D<br />
|-<br />
| ''bool '' || '''boxit=y''' || [y/n] || if y, create a box around text<br />
|-<br />
| ''int '' || '''lab_color=VP_WHITE''' || || label color<br />
|-<br />
| ''int '' || '''lab_fat=0''' || || label fatness<br />
|-<br />
| ''string '' || '''label=''' || || text for label<br />
|-<br />
| ''float '' || '''lat=0.''' || || <br />
|-<br />
| ''float '' || '''length=''' || || normalization for xt and yt<br />
|-<br />
| ''float '' || '''long=90.''' || || latitude and longitude of viewpoint in 3-D<br />
|-<br />
| ''bool '' || '''pointer=y''' || [y/n] || if y, create arrow pointer<br />
|-<br />
| ''float '' || '''pscale=1.''' || || scale factor for width of pointer<br />
|-<br />
| ''bool '' || '''reverse=n''' || [y/n] || <br />
|-<br />
| ''float '' || '''scale0=1.''' || || scale factor for x0 and y0<br />
|-<br />
| ''float '' || '''scalet=''' || || <br />
|-<br />
| ''float '' || '''size=.25''' || || text height in inches<br />
|-<br />
| ''float '' || '''x0=0.''' || || <br />
|-<br />
| ''float '' || '''x_oval=0.''' || || <br />
|-<br />
| ''float '' || '''xt=2.''' || || <br />
|-<br />
| ''float '' || '''y0=0.''' || || position of the pointer tip<br />
|-<br />
| ''float '' || '''y_oval=0.''' || || size of the oval around pointer<br />
|-<br />
| ''float '' || '''yt=0.''' || || relative position of text<br />
|}<br />
==sfcontour==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Contour plot.<br />
|-<br />
! colspan="4" | sfcontour < in.rsf c= min1=o1 min2=o2 max1=o1+(n1-1)*d1 max2=o2+(n2-1)*d2 nc=50 dc= c0= transp=y minval= maxval= allpos=y barlabel= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=y''' || [y/n] || contour positive values only<br />
|-<br />
| ''string '' || '''barlabel=''' || || <br />
|-<br />
| ''floats '' || '''c=''' || || [nc]<br />
|-<br />
| ''float '' || '''c0=''' || || first contour<br />
|-<br />
| ''float '' || '''dc=''' || || contour increment<br />
|-<br />
| ''float '' || '''max1=o1+(n1-1)*d1''' || || <br />
|-<br />
| ''float '' || '''max2=o2+(n2-1)*d2''' || || data window to plot<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''min1=o1''' || || <br />
|-<br />
| ''float '' || '''min2=o2''' || || <br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nc=50''' || || number of contours<br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfdots==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot signal with lollipops.<br />
|-<br />
! colspan="4" | sfdots < in.rsf labels= dots=(n1 <= 130)? 1: 0 seemean=(bool) (n2 <= 30) strings=(bool) (n1 <= 400) connect=1 corners= silk=n gaineach=y labelsz=8 yreverse=n constsep=n seedead=n transp=n xxscale=1. yyscale=1. clip=-1. overlap=0.9 screenratio=VP_SCREEN_RATIO screenht=VP_STANDARD_HEIGHT screenwd=screenhigh / screenratio radius=dd1/3 label1= unit1= title= > plot.vpl<br />
|-<br />
| ''float '' || '''clip=-1.''' || || data clip<br />
|-<br />
| ''int '' || '''connect=1''' || || connection type: 1 - diagonal, 2 - bar, 4 - only for non-zero data<br />
|-<br />
| ''bool '' || '''constsep=n''' || [y/n] || if y, use constant trace separation<br />
|-<br />
| ''int '' || '''corners=''' || || number of polygon corners (default is 6)<br />
|-<br />
| ''int '' || '''dots=(n1 <= 130)? 1: 0''' || || type of dots: 1 - baloon, 0 - no dots, 2 - only for non-zero data<br />
|-<br />
| ''bool '' || '''gaineach=y''' || [y/n] || if y, gain each trace independently<br />
|-<br />
| ''string '' || '''label1=''' || || <br />
|-<br />
| ''strings'' || '''labels=''' || || trace labels [n2]<br />
|-<br />
| ''int '' || '''labelsz=8''' || || label size<br />
|-<br />
| ''float '' || '''overlap=0.9''' || || trace overlap<br />
|-<br />
| ''float '' || '''radius=dd1/3''' || || dot radius<br />
|-<br />
| ''float '' || '''screenht=VP_STANDARD_HEIGHT''' || || screen height<br />
|-<br />
| ''float '' || '''screenratio=VP_SCREEN_RATIO''' || || screen aspect ratio<br />
|-<br />
| ''float '' || '''screenwd=screenhigh / screenratio''' || || screen width<br />
|-<br />
| ''bool '' || '''seedead=n''' || [y/n] || if y, show zero traces<br />
|-<br />
| ''bool '' || '''seemean=(bool) (n2 <= 30)''' || [y/n] || if y, draw axis lines<br />
|-<br />
| ''bool '' || '''silk=n''' || [y/n] || if y, silky plot<br />
|-<br />
| ''bool '' || '''strings=(bool) (n1 <= 400)''' || [y/n] || if y, draw strings<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axis<br />
|-<br />
| ''string '' || '''unit1=''' || || <br />
|-<br />
| ''float '' || '''xxscale=1.''' || || x scaling<br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse y axis<br />
|-<br />
| ''float '' || '''yyscale=1.''' || || y scaling<br />
|}<br />
==sfgraph3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot for surfaces.<br />
|-<br />
! colspan="4" | sfgraph3 < in.rsf orient=1 min= max= point1=0.5 point2=0.5 frame1=0.5*(min+max) frame2=n1-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y > plot.vpl<br />
|-<br />
| ''float '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''float '' || '''frame1=0.5*(min+max)''' || || <br />
|-<br />
| ''int '' || '''frame2=n1-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''max=''' || || maximum function value<br />
|-<br />
| ''float '' || '''min=''' || || minimum function value<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''orient=1''' || || function orientation<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|}<br />
==sfgraph==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Graph plot.<br />
|-<br />
! colspan="4" | sfgraph < in.rsf symbolsz= pclip=100. transp=n symbol= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''pclip=100.''' || || clip percentile<br />
|-<br />
| ''string '' || '''symbol=''' || || if set, plot with symbols instead of lines<br />
|-<br />
| ''floats '' || '''symbolsz=''' || || symbol size (default is 2) [n2]<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfgrey3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot.<br />
|-<br />
! colspan="4" | sfgrey3 < in.rsf point1=0.5 point2=0.5 frame1=0 frame2=n2-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y scalebar=n minval= maxval= barreverse=n nreserve=8 bar= color= > plot.vpl<br />
|-<br />
| colspan="4" | Requires an "unsigned char" input (the output of sfbyte).<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''int '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''int '' || '''frame1=0''' || || <br />
|-<br />
| ''int '' || '''frame2=n2-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || if y, draw scalebar<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
for sfgrey and sfgrey3. Examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfgrey==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate raster plot.<br />
|-<br />
! colspan="4" | sfgrey < in.rsf > out.rsf bar=bar.rsf transp=y yreverse=y xreverse=n gpow= phalf= clip= pclip= gainstep=0.5+n1/256. allpos=n bias=0. polarity=n verb=n scalebar=n minval= maxval= barreverse=n wantframenum=(bool) (n3 > 1) nreserve=8 gainpanel= bar= color= > (plot.vpl | char.rsf)<br />
|-<br />
| colspan="4" | Can input char values.<br>If called "byte", outputs char values.<br><br>Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=n''' || [y/n] || if y, assume positive data<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=''' || || <br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''string '' || '''gainpanel=''' || || gain reference: 'a' for all, 'e' for each, or number<br />
|-<br />
| ''int '' || '''gainstep=0.5+n1/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=''' || || <br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''pclip=''' || || data clip percentile (default is 99)<br />
|-<br />
| ''float '' || '''phalf=''' || || percentage for estimating gpow<br />
|-<br />
| ''bool '' || '''polarity=n''' || [y/n] || if y, reverse polarity (white is high by default)<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the display axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''bool '' || '''wantframenum=(bool) (n3 > 1)''' || [y/n] || if y, display third axis position in the corner<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''bool '' || '''yreverse=y''' || [y/n] || if y, reverse the vertical axis<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
and examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfplas==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Assembler - convert ascii to vplot. <br />
|-<br />
! colspan="4" | sfplas<br />
|}<br />
==sfpldb==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Debugger - convert vplot to ascii. <br />
|-<br />
! colspan="4" | sfpldb<br />
|}<br />
==sfplotrays==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot rays.<br />
|-<br />
! colspan="4" | sfplotrays frame=frame.rsf nt=n1*n2 jr=1 frame= < rays.rsf > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''string '' || '''frame=''' || || <br />
|-<br />
| ''int '' || '''jr=1''' || || skip rays<br />
|-<br />
| ''int '' || '''nt=n1*n2''' || || maximum ray length<br />
|}<br />
==sfthplot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Hidden-line surface plot.<br />
|-<br />
! colspan="4" | sfthplot < in.rsf uflag=y dflag=y alpha=45. titlsz=9 axissz=6 plotfat=0 titlefat=2 axisfat=2 plotcolup=VP_YELLOW plotcoldn=VP_RED axis=y axis1=y axis2=y axis3=y clip=0. pclip=100. gainstep=0.5+nx/256. bias=0. dclip=1. norm=y xc=1.5 zc=3 ratio=5. zmax= zmin= sz=6. label#= unit#= tpow=0 epow=0 gpow=1 title= > plot.vpl<br />
|-<br />
| ''float '' || '''alpha=45.''' || || apparent angle in degrees, |alpha| < 89<br />
|-<br />
| ''bool '' || '''axis=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis1=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis2=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis3=y''' || [y/n] || plot axis<br />
|-<br />
| ''int '' || '''axisfat=2''' || || axes fatness<br />
|-<br />
| ''int '' || '''axissz=6''' || || axes size<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip<br />
|-<br />
| ''float '' || '''dclip=1.''' || || change the clip: clip *= dclip<br />
|-<br />
| ''bool '' || '''dflag=y''' || [y/n] || if y, plot down side of the surface<br />
|-<br />
| ''float '' || '''epow=0''' || || exponential gain<br />
|-<br />
| ''int '' || '''gainstep=0.5+nx/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=1''' || || power gain<br />
|-<br />
| ''string '' || '''label#=''' || || label on #-th axis<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || normalize by the clip<br />
|-<br />
| ''float '' || '''pclip=100.''' || || data clip percentile<br />
|-<br />
| ''int '' || '''plotcoldn=VP_RED''' || || color of the lower side<br />
|-<br />
| ''int '' || '''plotcolup=VP_YELLOW''' || || color of the upper side<br />
|-<br />
| ''int '' || '''plotfat=0''' || || line fatness<br />
|-<br />
| ''float '' || '''ratio=5.''' || || plot adjustment<br />
|-<br />
| ''float '' || '''sz=6.''' || || vertical scale<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''int '' || '''titlefat=2''' || || title fatness<br />
|-<br />
| ''int '' || '''titlsz=9''' || || title size<br />
|-<br />
| ''string '' || '''tpow=0''' || || time power gain<br />
|-<br />
| ''bool '' || '''uflag=y''' || [y/n] || if y, plot upper side of the surface<br />
|-<br />
| ''string '' || '''unit#=''' || || unit on #-th axis<br />
|-<br />
| ''float '' || '''xc=1.5''' || || <br />
|-<br />
| ''float '' || '''zc=3''' || || lower left corner of the plot<br />
|-<br />
| ''float '' || '''zmax=''' || || <br />
|-<br />
| ''float '' || '''zmin=''' || || <br />
|}<br />
==sfwiggle==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot data with wiggly traces. <br />
|-<br />
! colspan="4" | sfwiggle < in.rsf xpos=xpos.rsf xmax= xmin= poly=n fatp=1 xmask=1 ymask=1 pclip=98. zplot=0.75 clip=0. seemean=n verb=n transp=n yreverse=n xreverse=n xpos= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip (estimated from pclip by default<br />
|-<br />
| ''int '' || '''fatp=1''' || || <br />
|-<br />
| ''float '' || '''pclip=98.''' || || clip percentile<br />
|-<br />
| ''bool '' || '''poly=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''seemean=n''' || [y/n] || if y, plot mean lines of traces<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''int '' || '''xmask=1''' || || <br />
|-<br />
| ''float '' || '''xmax=''' || || maximum trace position (if using xpos)<br />
|-<br />
| ''float '' || '''xmin=''' || || minimum trace position (if using xpos)<br />
|-<br />
| ''string '' || '''xpos=''' || || optional header file with trace positions<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''int '' || '''ymask=1''' || || <br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse the vertical axis<br />
|-<br />
| ''float '' || '''zplot=0.75''' || || <br />
|}<br />
<br />
=filt/imag programs=<br />
==sfremap1==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 1-D ENO interpolation. <br />
|-<br />
! colspan="4" | sfremap1 < in.rsf > out.rsf pattern=pattern.rsf n1=n1 d1=d1 o1=o1 order=3<br />
|-<br />
| ''float '' || '''d1=d1''' || || Output sampling<br />
|-<br />
| ''int '' || '''n1=n1''' || || Number of output samples<br />
|-<br />
| ''float '' || '''o1=o1''' || || Output origin<br />
|-<br />
| ''int '' || '''order=3''' || || Interpolation order<br />
|-<br />
| ''string '' || '''pattern=''' || || auxiliary input file name<br />
|}<br />
To give an example of usage, we will create an input for <tt>sfremap1</tt> with:<br />
<pre><br />
sfmath n1=11 n2=11 d1=1 d2=1 o1=-5 o2=-5 output="x1*x1+x2*x2" > inp2remap1.rsf<br />
</pre><br />
Let us interpolate the data across both dimensions, then display it:<br />
<pre><br />
&lt; inp2remap1.rsf sfremap1 n1=1001 d1=0.01 | sftransp | \<br />
sfremap1 n1=1001 d1=0.01 | sftransp | sfgrey allpos=y | xtpen<br />
</pre><br />
The comparison with the uninterpolated data ( <tt>&lt; inp2remap1.rsf sfgrey allpos=y | xtpen</tt> ) is quite telling.<br />
<br />
=filt/proc programs=<br />
==sfstretch==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stretch of the time axis. <br />
|-<br />
! colspan="4" | sfstretch < in.rsf > out.rsf datum=dat.rsf inv=n dens=1 v0= half=y delay= tdelay= hdelay= nout=dens*n1 extend=4 mute=0 maxstr=0 rule=<br />
|-<br />
| ''file '' || '''datum=''' || || auxiliary input file name<br />
|-<br />
| ''float '' || '''delay=''' || || time delay for rule=lmo<br />
|-<br />
| ''int '' || '''dens=1''' || || axis stretching factor<br />
|-<br />
| ''int '' || '''extend=4''' || || trace extension<br />
|-<br />
| ''bool '' || '''half=y''' || [y/n] || if y, the second axis is half-offset instead of full offset<br />
|-<br />
| ''float '' || '''hdelay=''' || || offset delay for rule=rad<br />
|-<br />
| ''bool '' || '''inv=n''' || [y/n] || if y, do inverse stretching<br />
|-<br />
| ''float '' || '''maxstr=0''' || || maximum stretch<br />
|-<br />
| ''int '' || '''mute=0''' || || tapering size<br />
|-<br />
| ''int '' || '''nout=dens*n1''' || || output axis length (if inv=n)<br />
|-<br />
| ''string '' || '''rule=''' || || Stretch rule:<br />
:n - normal moveout (nmostretch), default<br />
:l - linear moveout (lmostretch)<br />
:L - logarithmic stretch (logstretch)<br />
:2 - t^2 stretch (t2stretch)<br />
:c - t^2 chebyshev stretch (t2chebstretch)<br />
:r - radial moveout (radstretch)<br />
:d - datuming (datstretch)<br />
|-<br />
| ''float '' || '''tdelay=''' || || time delay for rule=rad<br />
|-<br />
| ''float '' || '''v0=''' || || moveout velocity<br />
|}<br />
<br />
<tt>sfstretch rule=d</tt> (aka <tt>sfdatstretch</tt>) can be used to apply statics. Here is a synthetic example, courtesy of Alessandro Frigeri:<br />
<pre><br />
# generate a dataset with 'flat' signals<br />
sfmath n1=200 n2=100 output="sin(0.5*x1)" type=float > scan.rsf<br />
<br />
# generate a sinusoidal elevation correction<br />
sfmath n1=100 output="3*sin(x1)" type=float > statics.rsf<br />
<br />
# apply statics, producing a 'wavy' output.<br />
sfstretch < scan.rsf > out.rsf datum=statics.rsf rule=d<br />
</pre><br />
<br />
=user/ivlad programs=<br />
==sfprep4plot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Resamples a 2-D dataset to the desired picture resolution, with antialias<br />
|-<br />
! colspan="4" | sfprep4plot inp= out= verb=n h=none w=none unit= ppi= prar=y<br />
|-<br />
| colspan="4" | Only one of the h and w parameters needs to be specified.<br>If prar=n, no action will be taken on axis for which h/w was not specified<br>If prar=y and only one par (h or w) is specified, the picture will scale<br>along both axes until it is of the specified dimension.<br />
|-<br />
| ''int '' || '''h=none''' || || output height<br />
|-<br />
| ''string '' || '''inp=''' || || input file<br />
|-<br />
| ''string '' || '''out=''' || || output file<br />
|-<br />
| ''int '' || '''ppi=''' || || output resolution (px/in). Necessary when unit!=px<br />
|-<br />
| ''bool '' || '''prar=y''' || [y/n] || if y, PReserve Aspect Ratio of input<br />
|-<br />
| ''string '' || '''unit=''' || || unit of h and w. Can be: px(default), mm, cm, in<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || if y, print system commands, outputs<br />
|-<br />
| ''int '' || '''w=none''' || || output width<br />
|}<br />
For a figure that does not need the aspect ratio preserved,<br />
and needs to fill a 1280x1024 projector display:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=1280 h=1024 prar=n<br />
</pre><br />
For a print figure that has to fit in a 6x8in box<br />
at a resolution of 250 dpi, preserving the aspect ratio:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=6 h=8 unit=in ppi=250<br />
</pre><br />
A comparison of images before and after the application of <tt>sfprep4plot</tt>, courtesy of Joachim Mispel, is shown below:<br />
<br />
[[Image:sf_prep4plot.jpg]]<br />
<br />
=user/jennings programs=<br />
==sfsizes==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display the size of RSF files.<br />
|-<br />
! colspan="4" | sfsizes files=y human=n file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | Prints the element size, number of elements, and number of bytes<br>for a list of RSF files. Non-RSF files are ignored.<br />
|-<br />
| ''bool '' || '''files=y''' || [y/n] || If y, print size of each file. If n, print only total.<br />
|-<br />
| ''bool '' || '''human=n''' || [y/n] || If y, print human-readable file size. If n, print byte count.<br />
|}<br />
<br />
<br />
This program computes the "theoretical" size in bytes of the data fork of RSF files. The actual space occupied on disk may be different and machine dependent due to disk blocking factors, etc. This theoretical array size should be reproducible. It is also fast because the program only reads the RSF headers files, not the actual data.<br />
<br />
For example, to get the total size of all RSF files in a directory, in human readable format, without listing each file:<br />
<pre><br />
sfsizes files=n human=y *.rsf<br />
</pre><br />
This will also work because sfsizes simply skips any non-RSF file:<br />
<pre><br />
sfsizes files=n human=y *<br />
</pre><br />
==sffiglist==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Compare Vplot files in Fig and Lock directories<br />
|-<br />
! colspan="4" | sffiglist figdir= lockdir= list= show=<br />
|-<br />
| colspan="4" | Parameter figdir is path to Fig directory, default is ./Fig.<br>Parameter lockdir is path to Lock directory:<br> If figdir is in $RSFSRC/book/[book]/[chapter]/[section],<br> then default lockdir is $RSFFIGS/[book]/[chapter]/[section].<br> If figdir is not in $RSFSRC/book/[book]/[chapter]/[section],<br> then default lockdir is $RSFALTFIGS/[book]/[chapter]/[section].<br><br>Parameter list controls files to list, default is all.<br>Parameter show controls files to flip with sfpen, default is none.<br><br>list|show = none No files, print only summary.<br>list|show = diff Files that are different, determined by sfvplotdiff.<br>list|show = miss Files missing from figdir or lockdir, and different files.<br>list|show = all All files.<br><br>File list codes:<br><br>space indicates files that are the same.<br> - indicates file in lockdir that is missing from figdir.<br> + indicates extra file in figdir that is missing from lockdir.<br>number is return code from sfvplotdiff indicating different files.<br />
|-<br />
| ''string '' || '''figdir=''' || || fig directory, default = ./Fig<br />
|-<br />
| ''string '' || '''list=''' || || how much to list [none,diff,miss,all], default = all<br />
|-<br />
| ''string '' || '''lockdir=''' || || lock directory, default = lock counterpart of figdir<br />
|-<br />
| ''string '' || '''show=''' || || how much to show [none,diff,miss,all], default = none<br />
|}<br />
<br />
<br />
This program computes the "theoretical" size in bytes of the data fork of RSF files. The actual space occupied on disk may be different and machine dependent due to disk blocking factors, etc. This theoretical array size should be reproducible. It is also fast because the program only reads the RSF headers files, not the actual data.<br />
<br />
For example, to get the total size of all RSF files in a directory, in human readable format, without listing each file:<br />
<pre><br />
sfsizes files=n human=y *.rsf<br />
</pre><br />
This will also work because sfsizes simply skips any non-RSF file:<br />
<pre><br />
sfsizes files=n human=y *<br />
</pre><br />
<br />
=user/psava programs=<br />
==sfsrmig3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 3-D S/R migration with extended SSF<br />
|-<br />
! colspan="4" | sfsrmig3 slo=Fs_s.rsf sls=Fs_r.rsf < Fw_s.rsf rwf=Fw_r.rsf > Fi.rsf cig=Fc.rsf ompchunk=1 ompnth=0 verb=y eps=0.01 twoway=n nrmax=1 dtmax=0.004 pmx=0 pmy=0 tmx=0 tmy=0 vpvs=1. hsym=n nht=1 oht=0 dht=0.1 nht=1 oht=0 dht=0.1 hsym=n nhh=1 ohh=0 dhh=0.1 nha=180 oha=0 dha=2.0 nhb=180 ohb=0 dhb=2.0 itype=<br />
|-<br />
| ''file '' || '''cig=''' || || auxiliary output file name<br />
|-<br />
| ''float '' || '''dha=2.0''' || ||<br />
|-<br />
| ''float '' || '''dhb=2.0''' || ||<br />
|-<br />
| ''float '' || '''dhh=0.1''' || ||<br />
|-<br />
| ''float '' || '''dht=0.1''' || ||<br />
|-<br />
| ''float '' || '''dtmax=0.004''' || || max time error<br />
|-<br />
| ''float '' || '''eps=0.01''' || || stability parameter<br />
|-<br />
| ''bool '' || '''hsym=n''' || [y/n] ||<br />
|-<br />
| ''string '' || '''itype=''' || || imaging condition type<br />
:o = zero lag (default)<br />
:e = extended<br />
:x = space-lags<br />
:h = space-lags magnitude<br />
:t = time-lag<br />
|-<br />
| ''int '' || '''nha=180''' || ||<br />
|-<br />
| ''int '' || '''nhb=180''' || ||<br />
|-<br />
| ''int '' || '''nhh=1''' || ||<br />
|-<br />
| ''int '' || '''nht=1''' || ||<br />
|-<br />
| ''int '' || '''nrmax=1''' || || max number of refs<br />
|-<br />
| ''float '' || '''oha=0''' || ||<br />
|-<br />
| ''float '' || '''ohb=0''' || ||<br />
|-<br />
| ''float '' || '''ohh=0''' || ||<br />
|-<br />
| ''float '' || '''oht=0''' || ||<br />
|-<br />
| ''int '' || '''ompchunk=1''' || || OpenMP data chunk size<br />
|-<br />
| ''int '' || '''ompnth=0''' || || OpenMP available threads<br />
|-<br />
| ''int '' || '''pmx=0''' || || padding on x<br />
|-<br />
| ''int '' || '''pmy=0''' || || padding on y<br />
|-<br />
| ''file '' || '''rwf=''' || || auxiliary input file name<br />
|-<br />
| ''file '' || '''slo=''' || || auxiliary input file name<br />
|-<br />
| ''string '' || '''sls=''' || || auxiliary input file name<br />
|-<br />
| ''int '' || '''tmx=0''' || || taper on x<br />
|-<br />
| ''int '' || '''tmy=0''' || || taper on y<br />
|-<br />
| ''bool '' || '''twoway=n''' || [y/n] || two-way traveltime<br />
|-<br />
| ''bool '' || '''verb=y''' || [y/n] || verbosity flag<br />
|-<br />
| ''float '' || '''vpvs=1.''' || || Vp/Vs ratio<br />
|}<br />
<br />
This program performs 3-D and 2-D shot-record (a.k.a. shot-profile) migration with an extended Split-Step Fourier (SSF) extrapolator with multiple reference velocities (hence "extended"). It takes as input a shot wavefield (<tt>stdin</tt>), receiver wavefield (<tt>rwf=</tt>) and slowness model (<tt>slo=</tt>). Outputs are an image (<tt>stdout</tt>) and a cube of Common Image Gathers (<tt>cig=</tt>). An important parameter is <tt>nrmax</tt>, the number of reference velocities. Its default value is 1, but for reasonable results it should be 5 or so. It is also good to specify nonzero taper values (<tt>tmx</tt> and, for 3-D, <tt>tmy</tt> as well). The values of padding parameters <tt>pmx</tt> and <tt>pmy</tt> are split in two by the program, i.e. if your data x axis is 501-points long, specify pmx=11 to get a value of 512 that will result in fast Fourier Transforms. <br />
<br />
The program will also migrate converted-wave data if a file with the S-wave slowness model (<tt>sls=</tt>) is provided.<br />
<br />
The <tt>vpvs</tt> parameter is only used when <tt>itype=h</tt>. Do not specify a <tt>vpvs</tt> value unless you know really well what you are doing.<br />
<br />
===Usage example===<br />
The commands below, slightly modified from [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/data/sigsbee/ptest/SConstruct?revision=3993&view=markup RSFSRC/book/data/sigsbee/ptest], show how to prepare the [http://www.reproducibility.org/RSF/book/data/sigsbee Sigsbee 2A] data and velocity for migration.<br />
<br />
Convert input data (shots) from SEG-Y to RSF:<br />
<bash><br />
sfsegyread tape=sigsbee2a_nfs.segy tfile=tdata.rsf hfile=/dev/null bfile=/dev/null > ddata.rsf<br />
</bash><br />
Convert trace headers to float (required by <tt>sfheadermath</tt>):<br />
<bash><br />
< tdata.rsf sfdd type=float > trchdr.rsf<br />
</bash><br />
Shot positions:<br />
<bash><br />
< trchdr.rsf sfheadermath output="fldr + 10925/150" | sfwindow squeeze=y > tsi.rsf<br />
</bash><br />
Extract offset positions from the trace header files, eliminate length-1 axis, scale, create a header for binning (required by <tt>sfintbin</tt>):<br />
<bash><br />
< trchdr.rsf sfheadermath output="offset" |\<br />
sfwindow squeeze=y |\<br />
sfmath output="input/75" |\<br />
sfcat axis=2 space=n tsi.rsf |\<br />
sftransp |\<br />
sfdd type=int > tos.rsf<br />
</bash><br />
Binning and muting:<br />
<bash><br />
< ddata.rsf sfintbin head=tos.rsf xkey=0 ykey=1 |\<br />
sfput label1=Time unit1=s d2=0.075 o2=0.0 label2=hx d3=0.150 o3=10.925 label3=sx |\<br />
sfmutter half=false t0=1.0 v0=6.0 |\<br />
sfput d2=0.02286 o2=0 unit2=km d3=0.04572 o3=3.32994 unit3=km > shots.rsf<br />
</bash><br />
Keeping only 20 shots so that this 1-node job will not take forever, FFT-ing, decimating frequency slices (same as shortening the time axis), and creating y and hy axes of length 1:<br />
<bash><br />
< shots.rsf sfwindow n3=20 f3=10 j3=20 |\<br />
sffft1 |\<br />
sfwindow n1=200 min1=1 j1=3 |\<br />
sfspray axis=3 n=1 o=0 d=1 label=hy |\<br />
sfspray axis=5 n=1 o=0 d=1 label=sy > rfft.rsf<br />
</bash><br />
The dimensions of the cube thus created are:<br />
<pre><br />
$ sfin rfft.rsf trail=n<br />
rfft.rsf:<br />
in="/var/tmp/rfft.rsf@"<br />
esize=8 type=complex form=native<br />
n1=200 d1=0.25 o1=1 label1="Frequency" unit1="Hz"<br />
n2=348 d2=0.02286 o2=0 label2="hx" unit2="km"<br />
n3=1 d3=1 o3=0 label3="hy" unit3="km"<br />
n4=20 d4=0.9144 o4=3.78714 label4="sx" unit4="km"<br />
1392000 elements 11136000 bytes<br />
</pre><br />
Create the source wavelet (limited to the same frequency band as the data) and Fourier transform it:<br />
<bash><br />
sfspike k1=1 n1=1500 d1=0.008 |\<br />
sfbandpass flo=15 fhi=25 |\<br />
sffft1 |\<br />
sfwindow n1=200 min1=1 j1=3 |\<br />
sfput label1=freq > sfft.rsf<br />
</bash><br />
This creates a frequency-domain wavelet:<br />
<pre><br />
$ sfin sfft.rsf<br />
sfft.rsf:<br />
in="/var/tmp/sfft.rsf@"<br />
esize=8 type=complex form=native<br />
n1=200 d1=0.25 o1=1 label1="freq" unit1="Hz"<br />
200 elements 1600 bytes<br />
</pre><br />
Create "synched" source and receiver wavefields with <tt>srsyn</tt> from wavelet and data frequency slices. Basically both the receiver and shot frequency slices are "placed" at the right location and padded with zeros up to the dimension of the x axis specified below.<br />
<bash><br />
< rfft.rsf sfsrsyn nx=1067 dx=0.02286 ox=3.05562 wav=sfft.rsf swf=swav.rsf > rwav.rsf<br />
</bash><br />
This creates frequency slices ready for migration for both source and receiver, only axis 1 (frequency) must become axis 3, for both datasets:<br />
<bash><br />
< swav.rsf sftransp plane=12 | sftransp plane=23 > stra.rsf<br />
</bash><br />
<bash><br />
< rwav.rsf sftransp plane=12 | sftransp plane=23 > rtra.rsf<br />
</bash><br />
This creates a surface receiver wavefield ready for input to migration. Axis 4 is shot number. The values of axis 4 are arbitrary because each shot has been padded with zeros so that it covers the entire velocity model. Therefore the aperture of the downward continuation for each shot will be as large as the survey.<br />
<pre><br />
sfin trail=n rtra.rsf<br />
rtra.rsf:<br />
in="/var/tmp/rtra.rsf@"<br />
esize=8 type=complex form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=200 d3=0.25 o3=1 label3="w" unit3="Hz"<br />
n4=20 d4=1 o4=0 label4="e" unit4="km"<br />
4268000 elements 34144000 bytes<br />
</pre><br />
Convert the velocity model from SEG-Y to RSF, decimate, convert from feet to km, transpose, convert to slowness and insert an additional axis:<br />
<bash><br />
sfsegyread tape=sigsbee2a_migvel.sgy tfile=/dev/null hfile=/dev/null bfile=/dev/null |\<br />
sfput o1=0 d1=0.00762 label1=z unit1=km o2=3.05562 d2=0.01143 label2=x unit2=km |\<br />
sfwindow j1=4 j2=2 |\<br />
sfscale rscale=0.0003048 |\<br />
sftransp |\<br />
sfmath output="1/input" |\<br />
sfspray axis=2 n=1 d=1 o=0 |\<br />
sfput label2=y > slow.rsf<br />
</bash><br />
This creates a slowness file ready for input to migration, with an x axis identical to the x axis of the wavefield files:<br />
<pre><br />
$ sfin slow.rsf<br />
slow.rsf:<br />
in="/var/tmp/slow.rsf@"<br />
esize=4 type=float form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=301 d3=0.03048 o3=0 label3="z" unit3="km"<br />
321167 elements 1284668 bytes<br />
</pre><br />
Finally, the migration command (for a 4-processor machine, hence the <tt>ompnth</tt> value). We choose not to compute any image gathers (<tt>itype=o</tt>), but due to the construction of the program we still have to explicitly assign the <tt>cig</tt> tag, or else a RSF file with the name of the tag and no rsf extension will be created:<br />
<bash><br />
< stra.rsf sfsrmig3 nrmax=20 dtmax=5e-05 eps=0.01 verb=y ompnth=4 \<br />
tmx=16 rwf=rtra.rsf slo=slow.rsf itype=o cig=/dev/null > img.rsf<br />
</bash><br />
The migration of 20 shots takes approximately 3 hours on a 4-processor machine (1 shot=9 minutes). Without the frequency slice decimation by a factor of 3 and the depth axis decimation by a factor of 4, it would have taken twelve times as much. The resulting image has a y axis of length 1:<br />
<pre><br />
$ sfin img.rsf trail=n<br />
img.rsf:<br />
in="/var/tmp/img.rsf@"<br />
esize=4 type=float form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=301 d3=0.03048 o3=0 label3="z" unit3="km"<br />
321167 elements 1284668 bytes<br />
</pre><br />
To properly visualize the image, we need to eliminate the axis of length 1, then transpose the x and z axes to their natural position:<br />
<bash><br />
<img.rsf sfwindow squeeze=y | sftransp | sfgrey > img.vpl<br />
</bash><br />
<br />
=References=<br />
<references/></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Guide_to_madagascar_programs&diff=928Guide to madagascar programs2009-08-14T02:36:40Z<p>Jenningsjwj: /* sfsizes */</p>
<hr />
<div><center><font size="-1">''This page was created from the LaTeX source in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/rsf/rsf/prog.tex?view=markup book/rsf/rsf/prog.tex] using [[latex2wiki]]''</font></center><br />
<br />
This guide introduces some of the most used <tt>madagascar</tt> programs and illustrates their usage with examples.<br />
=Main programs=<br />
The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/ system/main] in the Madagascar distribution. The "main" programs perform general-purpose operations on RSF hypercubes regardless of the data dimensionality or physical dimensions.<br />
<br />
==sfadd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Add, multiply, or divide RSF datasets.<br />
|-<br />
! colspan="4" | sfadd > out.rsf scale= add= sqrt= abs= log= exp= mode= [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | The various operations, if selected, occur in the following order:<br><br>(1) Take absolute value, abs=<br>(2) Add a scalar, add=<br>(3) Take the natural logarithm, log=<br>(4) Take the square root, sqrt=<br>(5) Multiply by a scalar, scale=<br>(6) Compute the base-e exponential, exp=<br>(7) Add, multiply, or divide the data sets, mode=<br><br>sfadd operates on integer, float, or complex data, but all the input<br>and output files must be of the same data type.<br><br>An alternative to sfadd is sfmath, which is more versatile, but may be<br>less efficient.<br />
|-<br />
| ''bools '' || '''abs=''' || || If true take absolute value [nin]<br />
|-<br />
| ''floats '' || '''add=''' || || Scalar values to add to each dataset [nin]<br />
|-<br />
| ''bools '' || '''exp=''' || || If true compute exponential [nin]<br />
|-<br />
| ''bools '' || '''log=''' || || If true take logarithm [nin]<br />
|-<br />
| ''string '' || '''mode=''' || || 'a' means add (default), <br> 'p' or 'm' means multiply, <br> 'd' means divide<br />
|-<br />
| ''floats '' || '''scale=''' || || Scalar values to multiply each dataset with [nin]<br />
|-<br />
| ''bools '' || '''sqrt=''' || || If true take square root [nin]<br />
|}<br />
<br />
<tt>sfadd</tt> is useful for combining (adding, dividing, or<br />
multiplying) several datasets. What if you want to subtract two<br />
datasets? Easy. Use the <tt>scale</tt> parameter as follows:<br />
<pre><br />
bash&#36; sfadd data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfadd < data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
The same task can be accomplished with the more general <tt>sfmath</tt> program:<br />
<pre><br />
bash&#36; sfmath one=data1.rsf two=data2.rsf output='one-two' > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfmath < data1.rsf two=data2.rsf output='input-two' > diff.rsf<br />
</pre><br />
In both cases, the size and shape of <tt>data1.rsf</tt> and<br />
<tt>data2.rsf</tt> hypercubes should be the same, and a warning<br />
message is printed out if the the axis sampling parameters (such as<br />
<tt>o1</tt> or <tt>d1</tt>) in these files are different.<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/add.c?view=markup system/main/add.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
/* find number of input files */<br />
if (isatty(fileno(stdin))) { <br />
/* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Collect input files in the <tt>in</tt> array from all command-line<br />
parameters that don't contain an "<tt>=</tt>" sign. The total number<br />
of input files in <tt>nin</tt>.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) continue; <br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
/* nin = no of input files*/<br />
</c><br />
<br />
A helper function <tt>check_compat</tt> checks the compatibility of<br />
input files.<br />
<c><br />
static void <br />
check_compat (sf_datatype type /* data type */, <br />
size_t nin /* number of files */, <br />
sf_file* in /* input files [nin] */, <br />
int dim /* file dimensionality */, <br />
const int* n /* dimensions [dim] */)<br />
/* Check that the input files are compatible. <br />
Issue error for type mismatch or size mismatch.<br />
Issue warning for grid parameters mismatch. */<br />
{<br />
int ni, id;<br />
size_t i;<br />
float d, di, o, oi;<br />
char key[3];<br />
const float tol=1.e-5; /* tolerance for comparison */<br />
<br />
for (i=1; i < nin; i++) {<br />
if (sf_gettype(in[i]) != type) <br />
sf_error ("type mismatch: need %d",type);<br />
for (id=1; id <= dim; id++) {<br />
(void) snprintf(key,3,"n%d",id);<br />
if (!sf_histint(in[i],key,&ni) || ni != n[id-1])<br />
sf_error("%s mismatch: need %d",key,n[id-1]);<br />
(void) snprintf(key,3,"d%d",id);<br />
if (sf_histfloat(in[0],key,&d)) {<br />
if (!sf_histfloat(in[i],key,&di) || <br />
(fabsf(di-d) > tol*fabsf(d)))<br />
sf_warning("%s mismatch: need %g",key,d);<br />
} else {<br />
d = 1.;<br />
}<br />
(void) snprintf(key,3,"o%d",id);<br />
if (sf_histfloat(in[0],key,&o) && <br />
(!sf_histfloat(in[i],key,&oi) || <br />
(fabsf(oi-o) > tol*fabsf(d))))<br />
sf_warning("%s mismatch: need %g",key,o);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
Finally, we enter the main loop, where input data are getting read<br />
buffer by buffer and combined in the total product depending on the<br />
data type.<br />
<c><br />
for (nbuf /= sf_esize(in[0]); nsiz > 0; nsiz -= nbuf) {<br />
if (nbuf > nsiz) nbuf=nsiz;<br />
<br />
for (j=0; j < nin; j++) {<br />
collect = (bool) (j != 0);<br />
switch(type) {<br />
case SF_FLOAT:<br />
sf_floatread((float*) bufi,<br />
nbuf,<br />
in[j]); <br />
add_float(collect, <br />
nbuf,<br />
(float*) buf,<br />
(const float*) bufi, <br />
cmode, <br />
scale[j], <br />
add[j], <br />
abs_flag[j], <br />
log_flag[j], <br />
sqrt_flag[j], <br />
exp_flag[j]);<br />
break;<br />
</c><br />
<br />
The data combination program for floating point numbers is<br />
<tt>add_float</tt>. <br />
<c><br />
static void add_float (bool collect, /* if collect */<br />
size_t nbuf, /* buffer size */<br />
float* buf, /* output [nbuf] */<br />
const float* bufi, /* input [nbuf] */ <br />
char cmode, /* operation */<br />
float scale, /* scale factor */<br />
float add, /* add factor */<br />
bool abs_flag, /* if abs */<br />
bool log_flag, /* if log */<br />
bool sqrt_flag, /* if sqrt */<br />
bool exp_flag /* if exp */)<br />
/* Add floating point numbers */<br />
{<br />
size_t j;<br />
float f;<br />
<br />
for (j=0; j < nbuf; j++) {<br />
f = bufi[j];<br />
if (abs_flag) f = fabsf(f);<br />
f += add;<br />
if (log_flag) f = logf(f);<br />
if (sqrt_flag) f = sqrtf(f);<br />
if (1. != scale) f *= scale;<br />
if (exp_flag) f = expf(f);<br />
if (collect) {<br />
switch (cmode) {<br />
case 'p': /* product */<br />
case 'm': /* multiply */<br />
buf[j] *= f;<br />
break;<br />
case 'd': /* delete */<br />
if (f != 0.) buf[j] /= f;<br />
break;<br />
default: /* add */<br />
buf[j] += f;<br />
break;<br />
}<br />
} else {<br />
buf[j] = f;<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display dataset attributes.<br />
|-<br />
! colspan="4" | sfattr < in.rsf want=<br />
|-<br />
| colspan="4" | <br>Sample output from "sfspike n1=100 | sfbandpass fhi=60 | sfattr"<br>******************************************* <br>rms = 0.992354 <br>mean value = 0.987576 <br>2-norm value = 9.92354 <br>variance = 0.00955481 <br>standard deviation = 0.0977487 <br>maximum value = 1.12735 at 97 <br>minimum value = 0.151392 at 100 <br>number of nonzero samples = 100 <br>total number of samples = 100 <br>******************************************* <br><br>rms = sqrt[ sum(data^2) / n ]<br>mean = sum(data) / n<br>norm = sum(abs(data)^lval)^(1/lval)<br>variance = [ sum(data^2) - n*mean^2 ] / [ n-1 ]<br>standard deviation = sqrt [ variance ]<br />
|-<br />
| ''int '' || '''lval=2''' || || norm option, lval is a non-negative integer, computes the vector lval-norm<br />
|-<br />
| ''string '' || '''want=''' || || 'all'(default),'rms','mean','norm','var','std','max','min','nonzero','samples','short' <br />
:want= 'rms' displays the root mean square<br />
:want= 'norm' displays the square norm, otherwise specified by lval.<br />
:want= 'var' displays the variance<br />
:want= 'std' displays the standard deviation<br />
:want= 'nonzero' displays number of nonzero samples<br />
:want= 'samples' displays total number of samples<br />
:want= 'short' displays a short one-line version<br />
|}<br />
<br />
<br />
<tt>sfattr</tt> is a useful diagnostic program. It reports certain<br />
statistical values for an RSF dataset: RMS (root-mean-square)<br />
amplitude, mean value, vector norm value, variance, standard deviation,<br />
maximum and minimum values, number of nonzero samples, and the total<br />
number of samples.<br />
If we denote data values as <math>d_i</math> for <math>i=0,1,2,\ldots,n</math>, then the RMS<br />
value is <math>\sqrt{\frac{1}{n}\,\sum\limits_{i=0}^n d_i^2}</math>, the mean<br />
value is <math>\frac{1}{n}\,\sum\limits_{i=0}^n d_i</math>, the <math>L_2</math>-norm value<br />
is <math>\sqrt{\sum\limits_{i=0}^n d_i^2}</math>, the variance is<br />
<math>\frac{1}{n-1}\,\left[\sum\limits_{i=0}^n d_i^2 - \frac{1}{n}\left(\sum\limits_{i=0}^n d_i\right)^2\right]</math>, and the standard<br />
deviation is the square root of the variance. Using <tt>sfattr</tt><br />
is a quick way to see the distribution of data values and check it for anomalies.<br />
<br />
The output can be parsed using utilities such as <tt>awk</tt>, to extract only a numeric value for feeding it as a parameter value into a command line interface. Notice the backticks in the example below:<br />
<bash><br />
sfgrey <vel.rsf allpos=y bias=`sfattr <vel.rsf want=min | awk '{print $4}'` | xtpen<br />
</bash><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/attr.c?view=markup system/main/attr.c]====<br />
<br />
Computations start by finding the input data (<tt>in</tt>) size<br />
(<tt>nsiz</tt>) and dimensions (<tt>dim</tt>).<br />
<c><br />
dim = (size_t) sf_filedims (in,n);<br />
for (nsiz=1, i=0; i < dim; i++) {<br />
nsiz *= n[i];<br />
}<br />
</c><br />
<br />
<br />
In the main loop, we read the input data buffer by buffer.<br />
<c><br />
for (nleft=nsiz; nleft > 0; nleft -= nbuf) {<br />
nbuf = (bufsiz < nleft)? bufsiz: nleft;<br />
switch (type) {<br />
case SF_FLOAT: <br />
sf_floatread((float*) buf,nbuf,in);<br />
break;<br />
case SF_INT:<br />
sf_intread((int*) buf,nbuf,in);<br />
break;<br />
case SF_COMPLEX:<br />
sf_complexread((sf_complex*) buf,nbuf,in);<br />
break;<br />
case SF_UCHAR:<br />
sf_ucharread((unsigned char*) buf,nbuf,in);<br />
break;<br />
case SF_CHAR:<br />
default:<br />
sf_charread(buf,nbuf,in);<br />
break;<br />
}<br />
</c><br />
<br />
<br />
The data attributes are accumulated in corresponding double-precision<br />
variables. <br />
<c><br />
fsum += f;<br />
fsqr += f*f;<br />
</c><br />
<br />
<br />
Finally, the attributes are reduced and printed out.<br />
<c><br />
fmean = fsum/nsiz;<br />
if (lval==2) fnorm = sqrt(fsqr);<br />
else if (lval==0) fnorm = nsiz-nzero;<br />
else fnorm = pow(flval,1./lval);<br />
frms = sqrt(fsqr/nsiz);<br />
if (nsiz > 1) fvar = (fsqr-nsiz*fmean*fmean)/(nsiz-1);<br />
else fvar = 0.0;<br />
fstd = sqrt(fvar);<br />
</c><br />
<br />
<c><br />
if(NULL==want || 0==strcmp(want,"rms"))<br />
printf("rms = %g \n",(float) frms);<br />
if(NULL==want || 0==strcmp(want,"mean"))<br />
printf("mean value = %g \n",(float) fmean);<br />
if(NULL==want || 0==strcmp(want,"norm"))<br />
printf("%d-norm value = %g \n",lval,(float) fnorm);<br />
if(NULL==want || 0==strcmp(want,"var"))<br />
printf("variance = %g \n",(float) fvar);<br />
if(NULL==want || 0==strcmp(want,"std"))<br />
printf("standard deviation = %g \n",(float) fstd);<br />
</c><br />
<br />
==sfcat==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Concatenate datasets. <br />
|-<br />
! colspan="4" | sfcat > out.rsf space= axis=3 nspace=(int) (ni/(20*nin) + 1) [<file0.rsf] file1.rsf file2.rsf ... <br />
|-<br />
| colspan="4" | sfmerge inserts additional space between merged data.<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis being merged<br />
|-<br />
| ''int '' || '''nspace=(int) (ni/(20*nin) + 1)''' || || if space=y, number of traces to insert<br />
|-<br />
| ''bool '' || '''space=''' || [y/n] || Insert additional space.<br />
:y is default for sfmerge, n is default for sfcat<br />
|}<br />
<br />
<br />
<tt>sfcat</tt> and <tt>sfmerge</tt> concatenate two or more files<br />
together along a particular axis. It is the same program, only<br />
<tt>sfcat</tt> has the default <tt>space=n</tt> and <tt>sfmerge</tt><br />
has the default <tt>space=y</tt>.<br />
Example of <tt>sfcat</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcat one.rsf one.rsf axis=1 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=4 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
12 elements 48 bytes<br />
</pre><br />
Example of <tt>sfmerge</tt>:<br />
<pre><br />
bash$ sfmerge one.rsf one.rsf axis=2 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=7 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
14 elements 56 bytes<br />
</pre><br />
In this case, an extra empty trace is inserted between the two merged files.<br />
The axes that are not being merged are checked for consistency:<br />
<pre><br />
bash$ sfcat one.rsf two.rsf > three.rsf<br />
sfcat: n2 mismatch: need 3<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cat.c?view=markup system/main/cat.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
in = (sf_file*) sf_alloc ((size_t) argc,sizeof(sf_file));<br />
<br />
if (!sf_stdin()) { /* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Everything on the command line that does not contain a "=" sign is<br />
treated as a file name, and the corresponding file object is added to the list.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) <br />
continue; /* not a file */<br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
</c><br />
<br />
As explained above, if the <tt>space=</tt> parameter is not set, it is<br />
inferred from the program name: <tt>sfmerge</tt> corresponds to<br />
<tt>space=y</tt> and <tt>sfcat</tt> corresponds to <tt>space=n</tt>.<br />
<c><br />
if (!sf_getbool("space",&space)) {<br />
/* Insert additional space.<br />
y is default for sfmerge, n is default for sfcat */<br />
prog = sf_getprog();<br />
if (NULL != strstr (prog, "merge")) {<br />
space = true;<br />
} else if (NULL != strstr (prog, "cat")) {<br />
space = false;<br />
} else {<br />
sf_warning("%s is neither merge nor cat,"<br />
" assume merge",prog);<br />
space = true;<br />
}<br />
}<br />
</c><br />
<br />
Find the axis for the merging (from the command line <tt>axis=</tt><br />
argument) and figure out two sizes: <tt>n1</tt> for everything after<br />
the axis and <tt>n2</tt> for everything before the axis.<br />
<c><br />
n1=1;<br />
n2=1;<br />
for (i=1; i <= dim; i++) {<br />
if (i < axis) n1 *= n[i-1];<br />
else if (i > axis) n2 *= n[i-1];<br />
}<br />
</c><br />
<br />
In the output, the selected axis will get extended.<br />
<c><br />
/* figure out the length of extended axis */<br />
ni = 0;<br />
for (j=0; j < nin; j++) {<br />
ni += naxis[j];<br />
}<br />
<br />
if (space) {<br />
if (!sf_getint("nspace",&nspace)) <br />
nspace = (int) (ni/(20*nin) + 1);<br />
/* if space=y, number of traces to insert */ <br />
ni += nspace*(nin-1);<br />
} <br />
<br />
(void) snprintf(key,3,"n%d",axis);<br />
sf_putint(out,key,(int) ni);<br />
</c><br />
<br />
The rest is simple: loop through the datasets reading and writing the<br />
data in buffer-size chunks and adding extra empty chunks if<br />
<tt>space=y</tt>.<br />
<c><br />
for (i2=0; i2 < n2; i2++) {<br />
for (j=0; j < nin; j++) {<br />
for (ni = n1*naxis[j]*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charread (buf,nbuf,in[j]);<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
if (!space || j == nin-1) continue;<br />
/* Add spaces */<br />
memset(buf,0,BUFSIZ);<br />
for (ni = n1*nspace*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfcmplx==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a complex dataset from its real and imaginary parts.<br />
|-<br />
! colspan="4" | sfcmplx > cmplx.rsf real.rsf imag.rsf<br />
|-<br />
| colspan="4" | There has to be only two input files specified and no additional parameters.<br />
|}<br />
<br />
<br />
<tt>sfcmplx</tt> simply creates a complex dataset from its real and<br />
imaginary parts. The reverse operation can be accomplished with<br />
<tt>sfreal</tt> and <tt>sfimag</tt>.<br />
Example of <tt>sfcmplx</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcmplx one.rsf one.rsf > cmplx.rsf<br />
bash$ sfin cmplx.rsf<br />
cmplx.rsf:<br />
in="/tmp/cmplx.rsf@"<br />
esize=8 type=complex form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 48 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cmplx.c?view=markup system/main/cmplx.c]====<br />
The program flow is simple. First, get the names of the input files.<br />
<c><br />
/* the first two non-parameters are real and imaginary files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == real) {<br />
real = sf_input (argv[i]);<br />
} else {<br />
imag = sf_input (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == imag) {<br />
if (NULL == real) sf_error ("not enough input");<br />
/* if only one input, real is in stdin */<br />
imag = real;<br />
real = sf_input("in");<br />
}<br />
</c><br />
<br />
The main part of the program reads the real and imaginary parts buffer by buffer and assembles and writes out the complex input. <br />
<c><br />
for (nleft= (size_t) (rsize*resize); nleft > 0; nleft -= nbuf) {<br />
nbuf = (BUFSIZ < nleft)? BUFSIZ: nleft;<br />
sf_charread(rbuf,nbuf,real);<br />
sf_charread(ibuf,nbuf,imag);<br />
for (i=0; i < nbuf; i += resize) {<br />
memcpy(cbuf+2*i, rbuf+i,(size_t) resize);<br />
memcpy(cbuf+2*i+resize,ibuf+i,(size_t) resize);<br />
}<br />
sf_charwrite(cbuf,2*nbuf,cmplx);<br />
}<br />
</c><br />
<br />
==sfconjgrad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic conjugate-gradient solver for linear inversion <br />
|-<br />
! colspan="4" | sfconjgrad < dat.rsf mod=mod.rsf > to.rsf < from.rsf > out.rsf niter=1<br />
|-<br />
| ''int '' || '''niter=1''' || || number of iterations<br />
|}<br />
<br />
<tt>sfconjgrad</tt> is a generic program for least-squares linear<br />
inversion with the [http://en.wikipedia.org/wiki/Conjugate_gradient_method conjugate-gradient method]. Suppose you have an<br />
executable program <tt><prog></tt> that takes an RSF file from the<br />
standard input and produces an RSF file in the standard output. It may<br />
take any number of additional parameters but one of them must be<br />
<tt>adj=</tt> that sets the forward (<tt>adj=0</tt>) or adjoint<br />
(<tt>adj=1</tt>) operations. The program <tt><prog></tt> is typically<br />
an RSF program but it could be anything (a script, a multiprocessor<br />
MPI program, etc.) as long as it implements a linear operator<br />
<math>\mathbf{L}</math> and its adjoint. There are no restrictions on the data<br />
size or shape. You can easily test the adjointness with<br />
<tt>sfdottest</tt>. The <tt>sfconjgrad</tt> program searches for a<br />
vector <math>\mathbf{m}</math> that minimizes the least-square misfit <br />
<math>\|\mathbf{d - L\,m}\|^2</math> for the given input data vector <math>\mathbf{d}</math>. <br />
<br />
The pseudocode for <tt>sfconjgrad</tt> is given at the end of the [http://www.reproducibility.org/RSF/book/gee/lsq/paper.pdf "Model fitting with least squares" chapter] of ''Imaging Estimation by Example'' by Jon Claerbout, with the earliest form published in [http://sepwww.stanford.edu/data/media/public/oldreports/sep48/48_25.pdf "Conjugate Gradient Tutorial"] (SEP-48, 1986, same author). A simple toy implementation with a small matrix shows that this is algorithm produces the same steps as the algorithm described in equations 45-49 of [http://www.cs.cmu.edu/~quake-papers/painless-conjugate-gradient.pdf "An introduction to the Conjugate Gradient Method Without the Agonizing Pain"] by J.R. Shewchuk, 1994, when the equation <math>A^T A x = A^T b</math> (in Shewchuk's notation) is solved. Multiplying with the transpose ensures a correct solution even when matrix A is square but not symmetric, or not square at all. The program [http://www.reproducibility.org/RSF/sfcconjgrad.html sfcconjgrad] implements this algorithm for the case when inputs are complex.<br />
<br />
Here is an example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
The <tt>sfdottest</tt> program can perform the dot product test to<br />
check that the adjoint mode works correctly.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=5.28394<br />
sfdottest: L'[d]*m=5.28394<br />
</pre><br />
Your numbers may be different because <tt>sfdottest</tt> generates new<br />
random input on each run.<br />
Next, let us make some random data with <tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfnoise seed=2005 rep=y < vec.rsf > dat.rsf<br />
</pre><br />
and try to invert the filtering operation using <tt>sfconjgrad</tt>:<br />
<pre><br />
bash$ sfconjgrad sfhelicon filt=flt.rsf lag=lag.rsf \<br />
mod=vec.rsf < dat.rsf > mod.rsf niter=10<br />
sfconjgrad: iter 1 of 10<br />
sfconjgrad: grad=3253.65<br />
sfconjgrad: iter 2 of 10<br />
sfconjgrad: grad=289.421<br />
sfconjgrad: iter 3 of 10<br />
sfconjgrad: grad=92.3481<br />
sfconjgrad: iter 4 of 10<br />
sfconjgrad: grad=36.9417<br />
sfconjgrad: iter 5 of 10<br />
sfconjgrad: grad=18.7228<br />
sfconjgrad: iter 6 of 10<br />
sfconjgrad: grad=11.1794<br />
sfconjgrad: iter 7 of 10<br />
sfconjgrad: grad=7.26941<br />
sfconjgrad: iter 8 of 10<br />
sfconjgrad: grad=5.15945<br />
sfconjgrad: iter 9 of 10<br />
sfconjgrad: grad=4.23055<br />
sfconjgrad: iter 10 of 10<br />
sfconjgrad: grad=3.57495<br />
</pre><br />
The output shows that, in 10 iterations, the norm of the gradient vector decreases by almost 1000. <br />
We can check the residual misfit before<br />
<pre><br />
bash$ < dat.rsf sfattr want=norm<br />
norm value = 49.7801<br />
</pre><br />
and after<br />
<pre><br />
bash$ sfhelicon filt=flt.rsf lag=lag.rsf < mod.rsf | \<br />
sfadd scale=1,-1 dat.rsf | sfattr want=norm<br />
norm value = 5.73563<br />
</pre><br />
In 10 iterations, the misfit decreased by an order of magnitude. The<br />
result can be improved by running the program for more iterations.<br />
<br />
An equivalent implementation for complex-valued inputs is [http://www.reproducibility.org/RSF/sfcconjgrad.html sfcconjgrad]. A simple, lightweight Python implementation can be found in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/fomels/conjgrad.py?view=markup $RSFROOT/lib/conjgrad.py].<br />
<br />
==sfcp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Copy or move a dataset.<br />
|-<br />
! colspan="4" | sfcp in.rsf out.rsf<br />
|-<br />
| colspan="4" | sfcp - copy, sfmv - move.<br>Mimics standard Unix commands.<br />
|}<br />
<br />
<br />
The <tt>sfcp</tt> and <tt>sfmv</tt> command imitate the Unix<br />
<tt>cp</tt> and <tt>mv</tt> commands and serve for copying and moving<br />
RSF files. Example:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcp one.rsf two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cp.c?view=markup system/main/cp.c]====<br />
First, we look for the two first command-line arguments that don't<br />
have the "=" character in them and consider them as the names of the<br />
input and the output files. <br />
<c><br />
/* the first two non-parameters are in and out files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == in) {<br />
infile = argv[i];<br />
in = sf_input (infile);<br />
} else {<br />
out = sf_output (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == in || NULL == out)<br />
sf_error ("not enough input");<br />
</c><br />
<br />
Next, we use library functions <font color="#cd4b19">sf_cp</font> and <font color="#cd4b19">sf_rm</font> to do the actual work.<br />
<c><br />
sf_cp(in,out);<br />
if (NULL != strstr (sf_getprog(),"mv")) <br />
sf_rm(infile,false,false,false);<br />
</c><br />
<br />
==sfcut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of the dataset. <br />
|-<br />
! colspan="4" | sfcut < in.rsf > out.rsf verb=n [j1=1 j2=1 ... f1=0 f2=0 ... n1=n1 n2=n2 ... max1= max2= ... min1= min2= ...]<br />
|-<br />
| colspan="4" | jN defines the jump in N-th dimension<br>fN is the window start<br>nN is the window size<br>minN and maxN is the maximum and minimum in N-th dimension<br><br>Reverse of window. <br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
The <tt>sfcut</tt> command is related to <tt>sfwindow</tt> and has the same<br />
set of arguments only instead of extracting the selected window, it fills it<br />
with zeroes. The size of the input data is preserved. <br />
Examples:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > in.rsf<br />
bash$ < in.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < in.rsf sfcut n1=2 f1=1 n2=3 f2=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 0 0 1 1<br />
15: 1 0 0 1 1<br />
20: 1 0 0 1 1<br />
bash$ < in.rsf sfcut j1=2 | sfdisfil<br />
0: 0 1 0 1 0<br />
5: 0 1 0 1 0<br />
10: 0 1 0 1 0<br />
15: 0 1 0 1 0<br />
20: 0 1 0 1 0<br />
</pre><br />
<br />
==sfdd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert between different formats. <br />
|-<br />
! colspan="4" | sfdd < in.rsf > out.rsf line=8 form= type= format=<br />
|-<br />
| ''string '' || '''form=''' || || ascii, native, xdr<br />
|-<br />
| ''string '' || '''format=''' || || Element format (for conversion to ASCII)<br />
|-<br />
| ''int '' || '''line=8''' || || Number of numbers per line (for conversion to ASCII)<br />
|-<br />
| ''string '' || '''type=''' || || int, float, complex<br />
|}<br />
<br />
<br />
The <tt>sfdd</tt> program is used to change either the form (<tt>ascii</tt>,<br />
<tt>xdr</tt>, <tt>native</tt>) or the type (<tt>complex</tt>, <tt>float</tt>,<br />
<tt>int</tt>, <tt>char</tt>) of the input dataset. <br />
In the example below, we create a plain text (ASCII) file with numbers and<br />
then use <tt>sfdd</tt> to generate an RSF file in <tt>xdr</tt> form with<br />
<tt>complex</tt> numbers. <br />
<pre><br />
bash$ cat test.txt<br />
1 2 3 4 5 6<br />
bash$ echo n1=6 data_format=ascii_int in=test.txt > test.rsf<br />
bash$ sfin test.rsf<br />
test.rsf:<br />
in="test.txt"<br />
esize=0 type=int form=ascii<br />
n1=6 d1=? o1=?<br />
6 elements<br />
bash$ sfdd < test.rsf form=xdr type=complex > test2.rsf<br />
bash$ sfin test2.rsf<br />
test2.rsf:<br />
in="/tmp/test2.rsf@"<br />
esize=8 type=complex form=xdr<br />
n1=3 d1=? o1=?<br />
3 elements 24 bytes<br />
bash$ sfdisfil < test2.rsf<br />
0: 1, 2i 3, 4i 5, 6i<br />
</pre><br />
To learn more about the RSF data format, consult the [[Format| guide to RSF format]].<br />
<br />
==sfdisfil==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Print out data values.<br />
|-<br />
! colspan="4" | sfdisfil < in.rsf number=y col=0 format= header= trailer=<br />
|-<br />
| colspan="4" | <br>Alternatively, use sfdd and convert to ASCII form.<br />
|-<br />
| ''int '' || '''col=0''' || || Number of columns.<br />
:The default depends on the data type:<br />
:10 for int and char,<br />
:5 for float,<br />
:3 for complex<br />
|-<br />
| ''string '' || '''format=''' || || Format for numbers (printf-style).<br />
:The default depends on the data type:<br> "%4d " for int and char,<br> "%13.4g" for float,<br> "%10.4g,%10.4gi" for complex<br />
|-<br />
| ''string '' || '''header=''' || || Optional header string to output before data<br />
|-<br />
| ''bool '' || '''number=y''' || [y/n] || If number the elements<br />
|-<br />
| ''string '' || '''trailer=''' || || Optional trailer string to output after data<br />
|}<br />
<br />
<br />
The <tt>sfdisfil</tt> program simply dumps the data contents to the standard<br />
output in a text form. It is used mostly for debugging purposes to quickly<br />
examine RSF files. Here is an example:<br />
<pre><br />
bash$ sfmath o1=0 d1=2 n1=12 output=x1 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
10: 20 22<br />
</pre><br />
The output format is easily configurable.<br />
<pre><br />
bash$ < test.rsf sfdisfil col=6 number=n format="<br />
0.0 2.0 4.0 6.0 8.0 10.0<br />
12.0 14.0 16.0 18.0 20.0 22.0<br />
</pre><br />
Along with <tt>sfdd</tt>, <tt>sfdisfil</tt> provides a simple way to convert<br />
RSF data to an ASCII form.<br />
<br />
==sfdottest==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic dot-product test for linear operators with adjoints <br />
|-<br />
! colspan="4" | sfdottest mod=mod.rsf dat=dat.rsf > pip.rsf<br />
|}<br />
<br />
<br />
<tt>sfdottest</tt> is a generic dot-product test program for testing<br />
linear operators. Suppose there is an executable program<br />
<tt><prog></tt> that takes an RSF file from the standard input and<br />
produces an RSF file in the standard output. It may take any number of<br />
additional parameters but one of them must be <tt>adj=</tt> that sets<br />
the forward (<tt>adj=0</tt>) or adjoint (<tt>adj=1</tt>) operations.<br />
The program <tt><prog></tt> is typically an RSF program but it could<br />
be anything (a script, a multiprocessor MPI program, etc.) as long as<br />
it implements a linear operator <math>\mathbf{L}</math> and its adjoint<br />
<math>\mathbf{L}^T</math>. The <tt>sfdottest</tt> program is testing the equality<br />
<center><math><br />
d^T\,L\,m = m^T\,L^T\,d<br />
</math></center><br />
by using random vectors <math>\mathbf{m}</math> and <math>\mathbf{d}</math>. You can invoke it with<br />
<pre><br />
bash$ sfdottest <prog> [optional aruments] mod=mod.rsf dat=dat.rsf<br />
</pre><br />
where <tt>mod.rsf</tt> and <tt>dat.rsf</tt> are RSF files that<br />
represent vectors from the model and data spaces. Pay attention to the <br />
dimension and size of these vectors! If the program does not respond<br />
for a very long time, it is quite possible that the dimension and size<br />
of the vectors are inconsistent with the requirement of the program to be<br />
tested. <tt>sfdottest</tt><br />
does not create any temporary files and does not have any restrictive<br />
limitations on the size of the vectors.<br />
Here is an example. We first setup a vector with 100 elements using<br />
<tt>sfspike</tt> and then run <tt>sfdottest</tt> to test the<br />
<tt>sfcausint</tt> program. <tt>sfcausint</tt> implements a linear<br />
operator of causal integration and its adjoint, the anti-causal<br />
integration.<br />
<pre><br />
bash$ sfspike n1=100 > vec.rsf<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1410.2<br />
sfdottest: L'[d]*m=1410.2<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1165.87<br />
sfdottest: L'[d]*m=1165.87<br />
</pre><br />
The numbers are different on subsequent runs because of changing<br />
seed in the random number generator.<br />
Here is a somewhat more complicated example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
Now the <tt>sfdottest</tt> program can perform the dot product test.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=8.97375<br />
sfdottest: L'[d]*m=8.97375<br />
</pre><br />
Here is the same program tested in the inverse filtering mode:<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf inv=y<br />
sfdottest: L[m]*d=15.0222<br />
sfdottest: L'[d]*m=15.0222<br />
</pre><br />
<br />
==sfget==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Output parameters from the header.<br />
|-<br />
! colspan="4" | sfget < in.rsf parform=y par1 par2 ...<br />
|-<br />
| ''bool '' || '''parform=y''' || [y/n] || If y, print out parameter=value. If n, print out value.<br />
|}<br />
<br />
<br />
The <tt>sfget</tt> program extracts a parameter value from an RSF file. It is<br />
useful mostly for scripting. Here is, for example, a quick calculation of the<br />
maximum value on the first axis in an RSF dataset (the output of<br />
<tt>sfspike</tt>) using the standard Unix <tt>bc</tt> calculator.<br />
<pre><br />
bash$ ( sfspike n1=100 | sfget n1 d1 o1; echo "o1+(n1-1)*d1" ) | bc<br />
.396<br />
</pre><br />
See also <tt>sfput</tt>.<br />
<br />
<br />
<br />
==sfheadercut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheadercut mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array of size n2.<br />
|}<br />
<br />
<br />
<tt>sfheadercut</tt> is close to <tt>sfheaderwindow</tt> but instead<br />
of windowing the dataset, it fills the traces specified by the header<br />
mask with zeroes. The size of the input data is preserved.<br />
Here is an example of using <tt>sfheaderwindow</tt> for <br />
zeroing every other trace in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a mask with alternating ones and zeros using<br />
<tt>sfinterleave</tt>.<br />
<pre><br />
bash$ sfspike n1=5 mag=1 | sfdd type=int > ones.rsf<br />
bash$ sfspike n1=5 mag=0 | sfdd type=int > zeros.rsf<br />
bash$ sfinterleave axis=1 ones.rsf zeros.rsf > mask.rsf<br />
bash$ sfdisfil < mask.rsf<br />
0: 1 0 1 0 1 0 1 0 1 0<br />
</pre><br />
Finally, <tt>sfheadercut</tt> zeros the input traces.<br />
<pre><br />
bash$ sfheadercut < input.rsf mask=mask.rsf > output.rsf<br />
bash$ sfdisfil < output.rsf <br />
0: 1 1 1 1 1<br />
5: 0 0 0 0 0<br />
10: 3 3 3 3 3<br />
15: 0 0 0 0 0<br />
20: 5 5 5 5 5<br />
25: 0 0 0 0 0<br />
30: 7 7 7 7 7<br />
35: 0 0 0 0 0<br />
40: 9 9 9 9 9<br />
45: 0 0 0 0 0<br />
</pre><br />
<br />
<br />
<br />
==sfheadersort==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Sort a dataset according to a header key. <br />
|-<br />
! colspan="4" | sfheadersort < in.rsf > out.rsf head=<br />
|-<br />
| ''string '' || '''head=''' || || header file<br />
|}<br />
<br />
<br />
<tt>sfheadersort</tt> is used to sort traces in the input file<br />
according to trace header information. <br />
Here is an example of using<br />
<tt>sfheadersort</tt> for randomly shuffling traces in the input<br />
file. First, let us create an input file with seven traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=7 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7 <br />
</pre><br />
Next, we can create a random file with seven header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=7 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: 0.05256 -0.2879 0.1487 0.4097 0.1548<br />
5: 0.4501 0.2836<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally, we<br />
apply <tt>sfheadersort</tt> to shuffle the input traces.<br />
<pre><br />
bash$ < input.rsf sfheadersort head=random.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 1 1 1 1 1<br />
10: 3 3 3 3 3<br />
15: 5 5 5 5 5<br />
20: 7 7 7 7 7<br />
25: 4 4 4 4 4<br />
30: 6 6 6 6 6<br />
</pre><br />
As expected, the order of traces in the output file corresponds to the<br />
order of values in the header. Thanks to the separation between<br />
headers and data, the operation of <tt>sfheadersort</tt> is optimally<br />
efficient. It first sorts the headers and only then accesses the data,<br />
reading each data trace only once.<br />
<br />
==sfheaderwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheaderwindow mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array os size n2, windowed is n1xm2,<br>where m2 is the number of nonzero elements in mask.<br />
|}<br />
<br />
<br />
<tt>sfheaderwindow</tt> is used to window traces in the input file<br />
according to trace header information. <br />
Here is an example of using <tt>sfheaderwindow</tt> for randomly<br />
selecting part of the traces in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a random file with ten header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=10 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: -0.005768 0.02258 -0.04331 -0.4129 -0.3909<br />
5: -0.03582 0.4595 -0.3326 0.498 -0.3517<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally,<br />
we apply <tt>sfheaderwindow</tt> to window the input traces selecting<br />
only those for which the header is greater than zero.<br />
<pre><br />
bash$ < random.rsf sfmask min=0 > mask.rsf<br />
bash$ < mask.rsf sfdisfil<br />
0: 0 1 0 0 0 0 1 0 1 0<br />
bash$ < input.rsf sfheaderwindow mask=mask.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 7 7 7 7 7<br />
10: 9 9 9 9 9<br />
</pre><br />
In this case, only three traces are selected for the output. Thanks to<br />
the separation between headers and data, the operation of<br />
<tt>sfheaderwindow</tt> is optimally efficient. <br />
<br />
==sfin==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display basic information about RSF files.<br />
|-<br />
! colspan="4" | sfin info=y check=2. trail=y file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | n1,n2,... are data dimensions<br>o1,o2,... are axis origins<br>d1,d2,... are axis sampling intervals<br>label1,label2,... are axis labels<br>unit1,unit2,... are axis units<br />
|-<br />
| ''float '' || '''check=2.''' || || Portion of the data (in Mb) to check for zero values.<br />
|-<br />
| ''bool '' || '''info=y''' || [y/n] || If n, only display the name of the data file.<br />
|-<br />
| ''bool '' || '''trail=y''' || [y/n] || If n, skip trailing dimensions of one<br />
|}<br />
<br />
<br />
<tt>sfin</tt> is one of the most useful programs for operating with<br />
RSF files. It produces quick information on the file hypercube<br />
dimensions and checks the consistency of the associated data file.<br />
Here is an example. Let us create an RSF file and examine it with <tt>sfin</tt>.<br />
<pre><br />
bash$ sfspike n1=100 n2=20 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=100 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
2000 elements 8000 bytes<br />
</pre><br />
<tt>sfin</tt> reports the following information:<br />
<br />
*location of the data file (<tt>/tmp/spike.rsf\@</tt>) <br />
*element size (4 bytes) <br />
*element type (floating point) <br />
*element form (native) <br />
*hypercube dimensions (100 by 20) <br />
*axes scale (0.004 and 0.1) <br />
*axes origin (0 and 0) <br />
*axes labels <br />
*axes units <br />
*total number of elements <br />
*total number of bytes in the data file <br />
Suppose that the file got corrupted by a buggy program and reports<br />
incorrect dimensions. The <tt>sfin</tt> program should be able to<br />
catch the discrepancy.<br />
<pre><br />
bash$ echo n2=100 >> spike.rsf<br />
bash$ sfin spike.rsf > /dev/null<br />
sfin: Actually 8000 bytes, 20% of expected.<br />
</pre><br />
<tt>sfin</tt> also checks the first records in the file for zeros. <br />
<pre><br />
bash$ sfspike n1=100 n2=100 k2=99 > spike2.rsf<br />
bash$ sfin spike2.rsf >/dev/null<br />
sfin: The first 32768 bytes are all zeros<br />
</pre><br />
The number of bytes to check is adjustable<br />
<pre><br />
bash$ sfin spike2.rsf check=0.01 >/dev/null<br />
sfin: The first 16384 bytes are all zeros<br />
</pre><br />
You can also output only the location of the data file. This is<br />
sometimes handy in scripts.<br />
<pre><br />
bash$ sfin spike.rsf spike2.rsf info=n<br />
/tmp/spike.rsf@ /tmp/spike2.rsf@<br />
</pre><br />
An alternative is to use <tt>sfget</tt>, as follows:<br />
<pre><br />
bash$ sfget parform=n in < spike.rsf<br />
/tmp/spike.rsf@<br />
</pre><br />
<br />
==sfinterleave==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Combine several datasets by interleaving.<br />
|-<br />
! colspan="4" | sfinterleave > out.rsf axis=3 [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis for interleaving<br />
|}<br />
<br />
<br />
<tt>sfinterleave</tt> combines two or more datasets by interleaving them on one<br />
of the axes. Here is a quick example:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ sfscale < one.rsf dscale=2 > two.rsf<br />
bash$ sfdisfil < two.rsf<br />
0: 2 2 2 2 2<br />
5: 2 2 2 2 2<br />
10: 2 2 2 2 2<br />
15: 2 2 2 2 2<br />
20: 2 2 2 2 2<br />
bash$ sfinterleave one.rsf two.rsf axis=1 | sfdisfil<br />
0: 1 2 1 2 1<br />
5: 2 1 2 1 2<br />
10: 1 2 1 2 1<br />
15: 2 1 2 1 2<br />
20: 1 2 1 2 1<br />
25: 2 1 2 1 2<br />
30: 1 2 1 2 1<br />
35: 2 1 2 1 2<br />
40: 1 2 1 2 1<br />
45: 2 1 2 1 2<br />
bash$ sfinterleave < one.rsf two.rsf axis=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 1 1 1 1 1<br />
15: 2 2 2 2 2<br />
20: 1 1 1 1 1<br />
25: 2 2 2 2 2<br />
30: 1 1 1 1 1<br />
35: 2 2 2 2 2<br />
40: 1 1 1 1 1<br />
45: 2 2 2 2 2<br />
</pre><br />
<br />
==sfmask==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a mask.<br />
|-<br />
! colspan="4" | sfmask < in.rsf > out.rsf min=-FLT_MAX max=+FLT_MAX<br />
|-<br />
| colspan="4" | <br>Mask is an integer data with ones and zeros. <br>Ones correspond to input values between min and max.<br><br>The output can be used with sfheaderwindow.<br />
|-<br />
| ''float '' || '''max=+FLT_MAX''' || || maximum header value<br />
|-<br />
| ''float '' || '''min=-FLT_MAX''' || || minimum header value<br />
|}<br />
<br />
<br />
<tt>sfmask</tt> creates an integer output of ones and zeros comparing<br />
the values of the input data to specified <tt>min=</tt> and<br />
<tt>max=</tt> parameters. It is useful for <tt>sfheaderwindow</tt> and<br />
in many other applications. Here is a quick example:<br />
<pre><br />
bash$ sfmath n1=10 output="sin(x1)" > sin.rsf<br />
bash$ < sin.rsf sfdisfil<br />
0: 0 0.8415 0.9093 0.1411 -0.7568<br />
5: -0.9589 -0.2794 0.657 0.9894 0.4121<br />
bash$ < sin.rsf sfmask min=-0.5 max=0.5 | sfdisfil<br />
0: 1 0 0 1 0 0 1 0 0 1<br />
</pre><br />
<br />
==sfmath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations on data files.<br />
|-<br />
! colspan="4" | sfmath > out.rsf type= unit= output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs, conj (for complex data).<br> <br>sfmath will work on float or complex data, but all the input and output<br>files must be of the same data type.<br><br>An alternative to sfmath is sfadd, which may be more efficient, but is<br>less versatile.<br><br>Examples:<br><br>sfmath x=file1.rsf y=file2.rsf power=file3.rsf output='sin((x+2*y)^power)' > out.rsf<br>sfmath < file1.rsf tau=file2.rsf output='exp(tau*input)' > out.rsf<br>sfmath n1=100 type=complex output="exp(I*x1)" > out.rsf<br><br>See also: sfheadermath.<br />
|-<br />
| ''string '' || '''output=''' || || Mathematical description of the output<br />
|-<br />
| ''string '' || '''type=''' || || output data type [float,complex]<br />
|-<br />
| ''string '' || '''unit=''' || || <br />
|}<br />
<br />
<tt>sfmath</tt> is a versatile program for mathematical operations<br />
with RSF files. It can operate with several input file, all of the<br />
same dimensions and data type. The data type can be real (floating<br />
point) or complex. Here is an example that demonstrates several<br />
features of <tt>sfmath</tt>.<br />
<pre><br />
bash$ sfmath n1=629 d1=0.01 o1=0 n2=40 d2=1 o2=5 \<br />
output="x2*(8+sin(6*x1+x2/10))" > rad.rsf<br />
bash$ < rad.rsf sfrtoc | sfmath output="input*exp(I*x1)" > rose.rsf<br />
bash$ < rose.rsf sfgraph title=Rose screenratio=1 wantaxis=n | sfpen<br />
</pre><br />
The first line creates a 2-D dataset that consists of 40 traces 600<br />
samples each. The values of the data are computed with the formula<br />
<font color="#cd4b19">"x2*(8+sin(6*x1+x2/10))"</font>, where <tt>x1</tt> refers to the<br />
coordinate on the first axis, and <tt>x2</tt> is the coordinate of the<br />
second axis. In the second line, we convert the data from real to<br />
complex using <tt>sfrtoc</tt> and produce a complex dataset using<br />
formula <font color="#cd4b19">"input*exp(I*x1)"</font>, where <tt>input</tt> refers to the<br />
input file. Finally, we plot the complex data as a collection of<br />
parametric curves using <tt>sfgraph</tt> and display the result using<br />
<tt>sfpen</tt>. The plot appearing on your screen should look similar<br />
to the figure.<br />
[[Image:rose.png|frame|center|This figure was created with <tt>sfmath</tt>.]]<br />
One possible alternative to the second line above is<br />
<pre><br />
bash$ < rad.rsf sfmath output=x1 > ang.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*cos(a)" > cos.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*sin(a)" > sin.rsf<br />
bash$ sfcmplx cos.rsf sin.rsf > rose.rsf<br />
</pre><br />
Here we refer to input files by names (<tt>r</tt> and <tt>a</tt>) and combine the names in a formula.<br />
<br />
==sfpad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Pad a dataset with zeros.<br />
|-<br />
! colspan="4" | sfpad < in.rsf > out.rsf [beg1= beg2= ... end1= end2=... | n1= n2 = ... | n1out= n2out= ...]<br />
|-<br />
| colspan="4" | begN specifies the number of zeros to add before the beginning of axis N.<br>endN specifies the number of zeros to add after the end of axis N.<br><br>Alternatively:<br><br>nN or nNout specify the output length of axis N, padding occurs at the end.<br>nN and nNout are equivalent.<br />
|}<br />
<br />
<br />
<tt>pad</tt> increases the dimensions of the input dataset by padding<br />
the data with zeroes. Here are some simple examples.<br />
<pre><br />
bash$ sfspike n1=5 n2=3 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
bash$ < one.rsf sfpad n2=5 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 0 0 0 0 0<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfpad beg2=2 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 0 0 0 0<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < one.rsf sfpad beg2=1 end2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfwindow n1=3 | sfpad n1=5 n2=5 beg1=1 beg2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 1 1 1 0<br />
10: 0 1 1 1 0<br />
15: 0 1 1 1 0<br />
20: 0 0 0 0 0<br />
</pre><br />
You can use <tt>sfcat</tt> to pad data with values other than zeroes.<br />
<br />
==sfput==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Input parameters into a header. <br />
|-<br />
! colspan="4" | sfput < in.rsf > out.rsf<br />
|}<br />
<br />
<br />
<tt>sfput</tt> is a very simple program. It simply appends parameters<br />
from the command line to the output RSF file. One can achieve similar<br />
results with editing by hand or with standard Unix utilities like<br />
<tt>sed</tt> and <tt>echo</tt>. <tt>sfput</tt> is sometimes more<br />
convenient because it handles input/output operations similarly to<br />
other regular RSF programs.<br />
<pre><br />
bash$ sfspike n1=10 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
10 elements 40 bytes<br />
bash$ sfput < spike.rsf d1=25 label1=Depth unit1=m > spike2.rsf<br />
bash$ sfin spike2.rsf<br />
spike2.rsf:<br />
in="/tmp/spike2.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=25 o1=0 label1="Depth" unit1="m"<br />
10 elements 40 bytes<br />
</pre><br />
<br />
==sfreal==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extract real (sfreal) or imaginary (sfimag) part of a complex dataset. <br />
|-<br />
! colspan="4" | sfreal < cmplx.rsf > real.rsf<br />
|}<br />
<br />
<br />
<tt>sfreal</tt> extracts the real part of a complex type dataset. The<br />
imaginary part can be extracted with <tt>sfimag</tt>, an the real<br />
and imaginary part can be combined together with <tt>sfcmplx</tt>.<br />
Here is a simple example. Let us first create a complex dataset <br />
with <tt>sfmath</tt><br />
<pre><br />
bash$ sfmath n1=10 type=complex output="(2+I)*x1" > cmplx.rsf<br />
bash$ fdisfil < cmplx.rsf<br />
0: 0, 0i 2, 1i 4, 2i<br />
3: 6, 3i 8, 4i 10, 5i<br />
6: 12, 6i 14, 7i 16, 8i<br />
9: 18, 9i<br />
</pre><br />
Extracting the real part with <tt>sfreal</tt>:<br />
<pre><br />
bash$ sfreal < cmplx.rsf | sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
</pre><br />
Extracting the imaginary part with <tt>sfimag</tt>:<br />
<pre><br />
bash$ sfimag < cmplx.rsf | sfdisfil<br />
0: 0 1 2 3 4<br />
5: 5 6 7 8 9<br />
</pre><br />
<br />
==sfreverse==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Reverse one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfreverse < in.rsf > out.rsf which=-1 verb=false memsize=sf_memsize() opt=<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''opt=''' || || If y, change o and d parameters on the reversed axis;<br />
:if i, don't change o and d<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|-<br />
| ''int '' || '''which=-1''' || || Which axis to reverse.<br />
:To reverse a given axis, start with 0,<br />
:add 1 to number to reverse n1 dimension,<br />
:add 2 to number to reverse n2 dimension,<br />
:add 4 to number to reverse n3 dimension, etc.<br />
:Thus, which=7 would reverse the first three dimensions,<br />
:which=5 just n1 and n3, etc.<br />
:which=0 will just pass the input on through unchanged.<br />
|}<br />
Here is an example of using <tt>sfreverse</tt>. First, let us create a<br />
2-D dataset.<br />
<pre><br />
bash$ sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Reversing the first axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 | sfdisfil<br />
0: 4 3 2 1 0<br />
5: 5 4 3 2 1<br />
10: 6 5 4 3 2<br />
</pre><br />
Reversing the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=2 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
Reversing both the first and the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=3 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
As you can see, the <tt>which=</tt> parameter controls the axes that are<br />
being reversed by encoding them into one number.<br />
When an axis is reversed, what happens with its axis origin and<br />
sampling parameters? This behavior is controlled by <tt>opt=</tt>. In<br />
our example,<br />
<pre><br />
bash$ < test.rsf sfget n1 o1 d1<br />
n1=5<br />
o1=0<br />
d1=1<br />
bash$ < test.rsf sfreverse which=1 | sfget o1 d1<br />
o1=4<br />
d1=-1<br />
</pre><br />
The default behavior (equivalent to <tt>opt=y</tt>) puts the origin<br />
<tt>o1</tt> at the end of the axis and reverses the sampling parameter<br />
<tt>d1</tt>. Using <tt>opt=n</tt> preserves the sampling but reverses<br />
the origin.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=n | sfget o1 d1<br />
o1=-4<br />
d1=1<br />
</pre><br />
Using <tt>opt=i</tt> preserves both the sampling and the origin while<br />
reversing the axis.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=i | sfget o1 d1<br />
o1=0<br />
d1=1<br />
</pre><br />
One of the three possible behaviors may be desirable depending on the<br />
application.<br />
<br />
==sfrm==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Remove RSF files together with their data.<br />
|-<br />
! colspan="4" | sfrm file1.rsf [file2.rsf ...] [-i] [-v] [-f] <br />
|-<br />
| colspan="4" | Mimics the standard Unix rm command.<br><br>See also: sfmv, sfcp.<br />
|}<br />
<br />
<tt>sfrm</tt> is a program for removing RSF files. Its arguments mimic<br />
the arguments of the standard Unix <tt>rm</tt> utility: <tt>-v</tt><br />
for verbosity, <tt>-i</tt> for interactive inquiry, <tt>-f</tt> for<br />
force removal of suspicious files. Unlike the Unix <tt>rm</tt>,<br />
<tt>sfrm</tt> removes both the RSF header files and the binary files<br />
that the headers point to. <br />
Example:<br />
<pre><br />
bash&#36; sfspike n1=10 > spike.rsf datapath=./<br />
bash&#36; sfget in < spike.rsf<br />
in=./spike.rsf@<br />
bash&#36; ls spike*<br />
spike.rsf spike.rsf@<br />
bash&#36; sfrm -v spike.rsf<br />
sfrm: sf_rm: Removing header spike.rsf<br />
sfrm: sf_rm: Removing data ./spike.rsf@<br />
bash&#36; ls spike*<br />
ls: No match.<br />
</pre><br />
==sfrotate==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Rotate a portion of one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfrotate < in.rsf > out.rsf verb=n memsize=sf_memsize() rot#=(0,0,...)<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''rot#=(0,0,...)''' || || length of #-th axis that is moved to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<tt>sfrotate</tt> modifies the input dataset by splitting it into<br />
parts and putting the parts back in a different order. Here is a quick example.<br />
<pre><br />
bash&#36; sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Rotating the first axis by putting the last two columns in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=2 | sfdisfil<br />
0: 3 4 0 1 2<br />
5: 4 5 1 2 3<br />
10: 5 6 2 3 4<br />
</pre><br />
Rotating the second axis by putting the last row in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot2=1 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 0 1 2 3 4<br />
10: 1 2 3 4 5<br />
</pre><br />
Rotating both the first and the second axis:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=3 rot2=1 | sfdisfil<br />
0: 4 5 6 2 3<br />
5: 2 3 4 0 1<br />
10: 3 4 5 1 2<br />
</pre><br />
The transformation is shown schematically in Figure~(fig:rotate).<br />
[[Image:rotate.png|frame|center|Schematic transformation of data with <tt>sfrotate</tt>.]]<br />
<br />
==sfrtoc==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert real data to complex (by adding zero imaginary part).<br />
|-<br />
! colspan="4" | sfrtoc < real.rsf > cmplx.rsf<br />
|-<br />
| colspan="4" | <br>See also: sfcmplx<br />
|}<br />
The input to <tt>sfrtoc</tt> can be any <tt>type=float</tt> dataset:<br />
<pre><br />
bash$ sfspike n1=10 n2=20 n3=30 >real.rsf<br />
bash$ sfin real.rsf<br />
real.rsf:<br />
in="/var/tmp/real.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
</pre><br />
The output dataset will have <tt>type=complex</tt>, and its binary will be twice the size of the input:<br />
<pre><br />
bash$ <real.rsf sfrtoc >complex.rsf<br />
bash$ sfin complex.rsf <br />
complex.rsf:<br />
in="/var/tmp/complex.rsf@"<br />
esize=8 type=complex form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 48000 bytes<br />
</pre><br />
<br />
==sfscale==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Scale data.<br />
|-<br />
! colspan="4" | sfscale < in.rsf > out.rsf axis=0 rscale=0. dscale=1.<br />
|-<br />
| colspan="4" | <br>To scale by a constant factor, you can also use sfmath or sfheadermath.<br />
|-<br />
| ''int '' || '''axis=0''' || || Scale by maximum in the dimensions up to this axis.<br />
|-<br />
| ''float '' || '''dscale=1.''' || || Scale by this factor (works if rscale=0)<br />
|-<br />
| ''float '' || '''rscale=0.''' || || Scale by this factor.<br />
|}<br />
<tt>sfscale</tt> scales the input dataset by a factor. Here<br />
are some simple examples. First, let us create a test dataset.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil <br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Scale every data point by 2:<br />
<pre><br />
bash&#36; < test.rsf sfscale dscale=2 | sfdisfil<br />
0: 2 4 6 8 10<br />
5: 4 8 12 16 20<br />
10: 6 12 18 24 30<br />
</pre><br />
Divide every trace by its maximum value:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=1 | sfdisfil<br />
0: 0.2 0.4 0.6 0.8 1<br />
5: 0.2 0.4 0.6 0.8 1<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
Divide by the maximum value in the whole 2-D dataset:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=2 | sfdisfil<br />
0: 0.06667 0.1333 0.2 0.2667 0.3333<br />
5: 0.1333 0.2667 0.4 0.5333 0.6667<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
The <tt>rscale=</tt> parameter is synonymous to <tt>dscale=</tt> except<br />
when it is equal to zero. With <tt>sfscale dscale=0</tt>, the dataset gets<br />
multiplied by zero. If using <tt>rscale=0</tt>, the other parameters are<br />
used to define scaling. Thus, <tt>sfscale rscale=0 axis=1</tt> is<br />
equivalent to <tt>sfscale axis=1</tt>, and <tt>sfscale rscale=0</tt><br />
is equivalent to <tt>sfscale dscale=1</tt>.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
==sfspike==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate simple data: spikes, boxes, planes, constants.<br />
|-<br />
! colspan="4" | sfspike > spike.rsf mag= nsp=1 k#=[0,...] l#=[k1,k2,...] p#=[0,...] n#= o#=(0,...) d#=(0.004,0.1,0.1,...) label#=(Time,Distance,Distance,...) unit#=[s,km,km,...] title=<br />
|-<br />
| ''float '' || '''d#=(0.004,0.1,0.1,...)''' || || sampling on #-th axis<br />
|-<br />
| ''ints '' || '''k#=[0,...]''' || || spike starting position [nsp]<br />
|-<br />
| ''ints '' || '''l#=[k1,k2,...]''' || || spike ending position [nsp]<br />
|-<br />
| ''string '' || '''label#=(Time,Distance,Distance,...)''' || || label on #-th axis<br />
|-<br />
| ''floats '' || '''mag=''' || || spike magnitudes [nsp]<br />
|-<br />
| ''int '' || '''n#=''' || || dimension of #-th axis<br />
|-<br />
| ''int '' || '''nsp=1''' || || Number of spikes<br />
|-<br />
| ''float '' || '''o#=(0,...)''' || || origin on #-th axis<br />
|-<br />
| ''floats '' || '''p#=[0,...]''' || || spike inclination (in samples) [nsp]<br />
|-<br />
| ''string '' || '''title=''' || || title for plots<br />
|-<br />
| ''string '' || '''unit#=[s,km,km,...]''' || || unit on #-th axis<br />
|}<br />
This is the program for creating a RSF hypercube out of nothing. Calling <tt>sfspike</tt> without specifying the k# or l# parameters will result in a volume filled with values specified by <tt>mag</tt>. To get a file full of 1's, just give <tt>sfspike</tt> the axis values that running <tt>sfin</tt> on your desired output would produce. I.e. if you run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" > out.rsf<br />
</pre><br />
you will obtain the following file:<br />
<pre><br />
bash$ sfin out.rsf<br />
out.rsf:<br />
in="/var/tmp/out.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
300 elements 1200 bytes<br />
</pre><br />
To create a "flat reflector" in the file above, run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5> out2.rsf<br />
</pre><br />
Notice that the values for <tt>k</tt> and <tt>l</tt> are in samples, not in the physical units of the respective axes. The result can be visualised with <br />
<pre><br />
< out2.rsf sfgrey pclip=100 wantscalebar=y title="Illustration of k,l parameters" | xtpen<br />
</pre><br />
which produces the following plot:<br />
<br />
[[Image:sfspike_fig1.png]]<br />
<br />
The <tt>p</tt> parameters can be used to create slanted lines/planes. Specifying <tt>p2=1</tt> means that for each lateral step, the spike will be shifted down with 1 sample. Below is the command and the corresponding graphical output it creates:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=1 |\<br />
sfgrey pclip=100 wantscalebar=y title="Effect of p2=1" | xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig2.png]]<br />
<br />
Sfspike also supports negative and non-integer p values:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=-0.15 |\<br />
sfgrey pclip=100 wantscalebar=y allpos=y color=h title="Effect of p2=-0.15" |xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig3.png]]<br />
<br />
When <tt>nsp</tt> is greater than the number of values for <tt>k</tt> and <tt>l</tt> parameters, the extra spikes will be piled on top of the last one, increasing its amplitude. Look at the amplitude of the last event in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=3 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
and in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=5 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
(pictures coming soon). This feature can easily cause a bug when the number of events is large and they have not been properly counted, or when a new spike was added on a list but <tt>nsp</tt> was not updated.<br />
<br />
==sfspray==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extend a dataset by duplicating in the specified axis dimension.<br />
|-<br />
! colspan="4" | sfspray < in.rsf > out.rsf axis=2 n= d= o= label= unit=<br />
|-<br />
| colspan="4" | This operation is adjoint to sfstack.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to spray<br />
|-<br />
| ''float '' || '''d=''' || || Sampling of the newly created dimension<br />
|-<br />
| ''string '' || '''label=''' || || Label of the newly created dimension<br />
|-<br />
| ''int '' || '''n=''' || || Size of the newly created dimension<br />
|-<br />
| ''float '' || '''o=''' || || Origin of the newly created dimension<br />
|-<br />
| ''string '' || '''unit=''' || || Units of the newly created dimension<br />
|}<br />
<br />
<tt>sfspray</tt> extends the input hypercube by replicating the data<br />
in one of the dimensions. The output dataset acquires one additional<br />
dimension. Here is an example:<br />
Start with a 2-D dataset<br />
<pre><br />
bash&#36; sfmath n1=5 n2=2 output=x1+x2 > test.rsf<br />
bash&#36; sfin test.rsf<br />
test.rsf:<br />
in="/var/tmp/test.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
10 elements 40 bytes<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
</pre><br />
Extend the data in the second dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=2 n=3 > test2.rsf<br />
bash&#36; sfin test2.rsf<br />
test2.rsf:<br />
in="/var/tmp/test2.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=3 d2=1 o2=0 <br />
n3=2 d3=1 o3=0 <br />
30 elements 120 bytes<br />
bash&#36; < test2.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 0 1 2 3 4<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
20: 1 2 3 4 5<br />
25: 1 2 3 4 5<br />
</pre><br />
The output is three-dimensional, with traces from the original<br />
data duplicated along the second axis.<br />
Extend the data in the third dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=3 n=2 > test3.rsf<br />
bash&#36; sfin test3.rsf<br />
test3.rsf:<br />
in="/var/tmp/test3.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
n3=2 d3=? o3=? <br />
20 elements 80 bytes<br />
bash&#36; < test3.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
</pre><br />
The output is also three-dimensional, with the original data replicated<br />
along the third axis.<br />
<br />
==sfstack==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stack a dataset over one of the dimensions.<br />
|-<br />
! colspan="4" | sfstack < in.rsf > out.rsf axis=2 rms=n norm=y min=n max=n<br />
|-<br />
| colspan="4" | <br>This operation is adjoint to sfspray.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to stack<br />
|-<br />
| ''bool '' || '''max=n''' || [y/n] || If y, find maximum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''min=n''' || [y/n] || If y, find minimum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || If y, normalize by fold.<br />
|-<br />
| ''bool '' || '''rms=n''' || [y/n] || If y, compute the root-mean-square instead of stack.<br />
|}<br />
While <tt>sfspray</tt> adds a dimension to a hypercube,<br />
<tt>sfstack</tt> effectively removes one of the dimensions by stacking<br />
over it. Here are some examples:<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
bash&#36; < test.rsf sfstack axis=2 | sfdisfil<br />
0: 1.5 2 3 4 5<br />
bash&#36; < test.rsf sfstack axis=1 | sfdisfil<br />
0: 2.5 3 4<br />
</pre><br />
Why is the first value not 1 (in the first case) or 2 (in the second<br />
case)? By default, <tt>sfstack</tt> normalizes the stack by the fold<br />
(the number of non-zero entries). To avoid normalization, use<br />
<tt>norm=n</tt>, as follows:<br />
<pre><br />
bash&#36; < test.rsf sfstack norm=n | sfdisfil <br />
0: 3 6 9 12 15<br />
</pre><br />
<tt>sfstack</tt> can also compute root-mean-square values as <br />
well as minimum and maximum values.<br />
<pre><br />
bash&#36; < test.rsf sfstack rms=y | sfdisfil<br />
0: 1.581 2.16 3.109 4.082 5.066<br />
bash&#36; < test.rsf sfstack min=y | sfdisfil<br />
0: 0 1 2 3 4<br />
bash&#36; < test.rsf sfstack axis=1 max=y | sfdisfil <br />
0: 4 5 6<br />
</pre><br />
<br />
==sftransp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Transpose two axes in a dataset. <br />
|-<br />
! colspan="4" | sftransp < in.rsf > out.rsf memsize=sf_memsize() plane=<br />
|-<br />
| colspan="4" | <br>If you get a "Cannot allocate memory" error, give the program a<br>memsize=1 command-line parameter to force out-of-core operation.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''plane=''' || || Two-digit number with axes to transpose. The default is 12<br />
|}<br />
<br />
The <tt>sftransp</tt> program transposes the input hypercube<br />
exchanging the two axes specified by the <b>plane=</b> parameter. <br />
<pre><br />
bash&#36; sfspike n1=10 n2=20 n3=30 > orig123.rsf<br />
bash&#36; sfin orig123.rsf <br />
orig123.rsf:<br />
in="/var/tmp/orig123.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=23 >out132.rsf<br />
bash&#36; sfin out132.rsf <br />
out132.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=20 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=13 >out321.rsf<br />
bash&#36; sfin out321.rsf <br />
out321.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=30 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=10 d3=0.004 o3=0 label3="Time" unit3="s" <br />
6000 elements 24000 bytes<br />
</pre><br />
<tt>sftransp</tt> tries to fit the dataset in memory to transpose it<br />
there but, if not enough memory is available, it performs a slower<br />
transpose out of core using disk operations. You can control the<br />
amount of available memory using the <b>memsize=</b> parameter or<br />
the <b>RSFMEMSIZE</b> environmental variable.<br />
<br />
==sfwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a portion of the dataset. <br />
|-<br />
! colspan="4" | sfwindow < in.rsf > out.rsf verb=n squeeze=y j#=(1,...) d#=(d1,d2,...) f#=(0,...) min#=(o1,o2,,...) n#=(0,...) max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)<br />
|-<br />
| ''float '' || '''d#=(d1,d2,...)''' || || sampling in #-th dimension<br />
|-<br />
| ''int '' || '''f#=(0,...)''' || || window start in #-th dimension<br />
|-<br />
| ''int '' || '''j#=(1,...)''' || || jump in #-th dimension<br />
|-<br />
| ''float '' || '''max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)''' || || maximum in #-th dimension<br />
|-<br />
| ''float '' || '''min#=(o1,o2,,...)''' || || minimum in #-th dimension<br />
|-<br />
| ''int '' || '''n#=(0,...)''' || || window size in #-th dimension<br />
|-<br />
| ''bool '' || '''squeeze=y''' || [y/n] || if y, squeeze dimensions equal to 1 to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
<b>sfwindow</b> is used to window a portion of the dataset. Here is<br />
a quick example: Start by creating some data.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Now window the first two rows:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n2=2 | sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
</pre><br />
Window the first three columns:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n1=3 | sfdisfil<br />
0: 1 2 3 2 4<br />
5: 6 3 6 9<br />
</pre><br />
Window the middle row:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f2=1 n2=1 | sfdisfil<br />
0: 2 4 6 8 10<br />
</pre><br />
You can interpret the <b>f#</b> and <b>n#</b> parameters as<br />
meaning "skip that many rows/columns" and "select that many<br />
rows/columns" correspondingly. Window the middle point in the dataset:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f1=2 n1=1 f2=1 n2=1 | sfdisfil<br />
0: 6<br />
</pre><br />
Window every other column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=2 | sfdisfil<br />
0: 1 3 5 2 6<br />
5: 10 3 9 15<br />
</pre><br />
Window every third column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=3 | sfdisfil<br />
0: 1 4 2 8 3<br />
5: 12<br />
</pre><br />
Alternatively, <b>sfwindow</b> can use the minimum and maximum<br />
parameters to select a window. In the following example, we are<br />
creating a dataset with <b>sfspike</b> and then windowing a portion of it<br />
between 1 and 2 seconds in time and sampled at 8 miliseconds.<br />
<pre><br />
bash&#36; sfspike n1=1000 n2=10 > spike.rsf <br />
bash&#36; sfin spike.rsf<br />
spike.rsf:<br />
in="/var/tmp/spike.rsf@"<br />
esize=4 type=float form=native <br />
n1=1000 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10000 elements 40000 bytes<br />
bash&#36; < spike.rsf sfwindow min1=1 max1=2 d1=0.008 > window.rsf<br />
bash&#36; sfin window.rsf<br />
window.rsf:<br />
in="/var/tmp/window.rsf@"<br />
esize=4 type=float form=native <br />
n1=126 d1=0.008 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
1260 elements 5040 bytes<br />
</pre><br />
By default, <b>sfwindow</b> "squeezes" the hypercube dimensions<br />
that are equal to one toward the end of the dataset. Here is an<br />
example of taking a time slice:<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=1 d2=0.004 o2=1 label2="Time" unit2="s" <br />
10 elements 40 bytes<br />
</pre><br />
You can change this behavior by specifying <b>squeeze=n</b>.<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 squeeze=n > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=1 d1=0.004 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10 elements 40 bytes<br />
</pre><br />
<br />
=Seismic programs=<br />
Programs in this category are specific for operations on seismic data. The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/seismic/ system/seismic] in the Madagascar distribution.<br />
<br />
==sfheaderattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Integer header attributes. <br />
|-<br />
! colspan="4" | sfheaderattr < head.rsf<br />
|-<br />
| colspan="4" | <br>Only nonzero values are reported.<br />
|}<br />
<br />
The <tt>sfheaderattr</tt> examines the contents of a trace header file,<br />
typically generated by <tt>sfsegyread</tt>. In the example below, we examine<br />
trace headers in the output of <tt>suplane</tt>, a program from Seismic Unix.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
bash$ sfheaderattr < tfile.rsf<br />
*******************************************<br />
71 headers, 32 traces<br />
key[0]="tracl" min[0]=1 max[31]=32 mean=16.5<br />
key[1]="tracr" min[0]=1 max[31]=32 mean=16.5<br />
key[11]="offset" min[0]=400 max[31]=400 mean=400<br />
key[38]="ns" min[0]=64 max[31]=64 mean=64<br />
key[39]="dt" min[0]=4000 max[31]=4000 mean=4000<br />
*******************************************<br />
</pre><br />
For different standard keywords, a minimum, maximum, and mean values<br />
are reported unless they are identically zero. This quick inspection<br />
can help in identifying meaningful keywords set in the data. The input<br />
data type must be <tt>int</tt>.<br />
<br />
==sfheadermath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations, possibly on header keys. <br />
|-<br />
! colspan="4" | sfheadermath < in.rsf > out.rsf memsize=sf_memsize() output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs<br><br>See also sfmath. <br><br>An addition operation can be performed by sfstack.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''output=''' || || Describes the output in a mathematical notation.<br />
|}<br />
<tt>sfheadermath</tt> is a versatile program for mathematical<br />
operations on rows of the input file. If the input file is an<br />
<tt>n1</tt> by <tt>n2</tt> matrix, the output will be a <tt>1</tt> by<br />
<tt>n2</tt> matrix that contains one row made out of mathematical<br />
operations on the other rows. <tt>sfheadermath</tt> can identify a row<br />
by number or by a standard SEGY keyword. The latter is useful for<br />
processing headers extracted from SEGY or SU files.<br />
Here is an example. First, we create an SU file with <tt>suplane</tt> and convert it to RSF using <tt>sfsegyread</tt>.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
</pre><br />
The trace header information is saved in <tt>tfile.rsf</tt>. It<br />
contains 71 headers for 32 traces in integer format.<br />
<pre><br />
bash$ sfin tfile.rsf<br />
tfile.rsf:<br />
in="/tmp/tfile.rsf@"<br />
esize=4 type=int form=native<br />
n1=71 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
2272 elements 9088 bytes<br />
</pre><br />
Next, we will convert <tt>tfile.rsf</tt> to a floating-point format<br />
and run <tt>sfheadermath</tt> to create a new header.<br />
<pre><br />
bash$ < tfile.rsf sfdd type=float | \<br />
sfheadermath myheader=1 output="sqrt(myheader+(2+10*offset^2))" > new.rsf<br />
bash$ sfin new.rsf<br />
new.rsf:<br />
in="/tmp/new.rsf@"<br />
esize=4 type=float form=native<br />
n1=1 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
32 elements 128 bytes<br />
</pre><br />
We defined "myheader" as being the row number 1 in the input (note<br />
that numbering starts with 0) and combined it with "offset", which<br />
is a standard SEGY keyword that denotes row number 11 (see the output<br />
of <tt>sfheaderattr</tt> above.) A variety of mathematical expressions<br />
can be defined in the <tt>output=</tt> string. The expression<br />
processing engine is shared with <tt>sfmath</tt>.<br />
<br />
==sfsegyheader==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Make a trace header file for segywrite.<br />
|-<br />
! colspan="4" | sfsegyheader < in.rsf > out.rsf n1= d1=<br />
|-<br />
| colspan="4" | <br> Use the output for tfile= argument in segywrite.<br />
|-<br />
| ''float '' || '''d1=''' || || trace sampling<br />
|-<br />
| ''int '' || '''n1=''' || || number of samples in a trace<br />
|}<br />
<br />
==sfsegyread==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert a SEG-Y or SU dataset to RSF.<br />
|-<br />
! colspan="4" | sfsegyread mask=msk.rsf > out.rsf tfile=hdr.rsf verb=false su=false format=sf_segyformat (bhead) ns=sf_segyns (bhead) endian= tape= read= hfile= bfile= mask= tfile=<br />
|-<br />
| colspan="4" | <br>Data headers and trace headers are separated from the data.<br><br>Defined SEG-Y trace header key names and byte offsets:<br><br>tracl: trace sequence number within line 0<br><br>tracr: trace sequence number within reel 4<br><br>fldr: field record number 8 <br><br>tracf: trace number within field record 12 <br><br>ep: energy source point number 16 <br><br>cdp: CDP ensemble number 20 <br><br>cdpt: trace number within CDP ensemble 24 <br><br>trid: trace identification code:<br>1 = seismic data<br>2 = dead<br>3 = dummy<br>4 = time break<br>5 = uphole<br>6 = sweep<br>7 = timing<br>8 = water break<br>9---, N = optional use (N = 32,767) 28 <br><br>nvs: number of vertically summed traces 30 <br><br>nhs: number of horizontally summed traces 32 <br><br>duse: data use:<br>1 = production<br>2 = test 34<br><br>offset: distance from source point to receiver<br>group (negative if opposite to direction<br>in which the line was shot) 36 <br><br>gelev: receiver group elevation from sea level<br>(above sea level is positive) 40 <br><br>selev: source elevation from sea level<br>(above sea level is positive) 44 <br><br>sdepth: source depth (positive) 48 <br><br>gdel: datum elevation at receiver group 52 <br><br>sdel: datum elevation at source 56 <br><br>swdep: water depth at source 60 <br><br>gwdep: water depth at receiver group 64 <br><br>scalel: scale factor for previous 7 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 68 <br><br>scalco: scale factor for next 4 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 70 <br><br>sx: X source coordinate 72 <br><br>sy: Y source coordinate 76 <br><br>gx: X group coordinate 80 <br><br>gy: Y group coordinate 84 <br><br>counit: coordinate units code:<br>for previoius four entries<br>1 = length (meters or feet)<br>2 = seconds of arc (in this case, the<br>X values are unsigned intitude and the Y values<br>are latitude, a positive value designates<br>the number of seconds east of Greenwich<br>or north of the equator 88 <br><br>wevel: weathering velocity 90 <br><br>swevel: subweathering velocity 92 <br><br>sut: uphole time at source 94 <br><br>gut: uphole time at receiver group 96 <br><br>sstat: source static correction 98 <br><br>gstat: group static correction 100 <br><br>tstat: total static applied 102 <br><br>laga: lag time A, time in ms between end of 240-<br>byte trace identification header and time<br>break, positive if time break occurs after<br>end of header, time break is defined as<br>the initiation pulse which maybe recorded<br>on an auxiliary trace or as otherwise<br>specified by the recording system 104 <br><br>lagb: lag time B, time in ms between the time<br>break and the initiation time of the energy source,<br>may be positive or negative 106 <br><br>delrt: delay recording time, time in ms between<br>initiation time of energy source and time<br>when recording of data samples begins<br>(for deep water work if recording does not<br>start at zero time) 108 <br><br>muts: mute time--start 110 <br><br>mute: mute time--end 112 <br><br>ns: number of samples in this trace 114 <br><br>dt: sample interval, in micro-seconds 116 <br><br>gain: gain type of field instruments code:<br>1 = fixed<br>2 = binary<br>3 = floating point<br>4 ---- N = optional use 118 <br><br>igc: instrument gain constant 120 <br><br>igi: instrument early or initial gain 122 <br><br>corr: correlated:<br>1 = no<br>2 = yes 124 <br><br>sfs: sweep frequency at start 126 <br><br>sfe: sweep frequency at end 128 <br><br>slen: sweep length in ms 130 <br><br>styp: sweep type code:<br>1 = linear<br>2 = cos-squared<br>3 = other 132 <br><br>stas: sweep trace length at start in ms 134 <br><br>stae: sweep trace length at end in ms 136 <br><br>tatyp: taper type: 1=linear, 2=cos^2, 3=other 138 <br><br>afilf: alias filter frequency if used 140 <br><br>afils: alias filter slope 142 <br><br>nofilf: notch filter frequency if used 144 <br><br>nofils: notch filter slope 146 <br><br>lcf: low cut frequency if used 148 <br><br>hcf: high cut frequncy if used 150 <br><br>lcs: low cut slope 152 <br><br>hcs: high cut slope 154 <br><br>year: year data recorded 156 <br><br>day: day of year 158 <br><br>hour: hour of day (24 hour clock) 160 <br><br>minute: minute of hour 162 <br><br>sec: second of minute 164 <br><br>timbas: time basis code:<br>1 = local<br>2 = GMT<br>3 = other 166 <br><br>trwf: trace weighting factor, defined as 1/2^N<br>volts for the least sigificant bit 168 <br><br>grnors: geophone group number of roll switch<br>position one 170 <br><br>grnofr: geophone group number of trace one within<br>original field record 172 <br><br>grnlof: geophone group number of last trace within<br>original field record 174 <br><br>gaps: gap size (total number of groups dropped) 176 <br><br>otrav: overtravel taper code:<br>1 = down (or behind)<br>2 = up (or ahead)<br />
|-<br />
| ''string '' || '''bfile=''' || || output binary data header file<br />
|-<br />
| ''bool '' || '''endian=''' || [y/n] || big/little endian flag, the default is estimated automatically<br />
|-<br />
| ''int '' || '''format=sf_segyformat (bhead)''' || [1,2,3,5] || Data format. The default is taken from binary header.<br />
:1 is IBM floating point<br />
:2 is 4-byte integer<br />
:3 is 2-byte integer<br />
:5 is IEEE floating point<br />
|-<br />
| ''string '' || '''hfile=''' || || output text data header file<br />
|-<br />
| ''string '' || '''mask=''' || || optional header mask for reading only selected traces<br />
|-<br />
| ''int '' || '''ns=sf_segyns (bhead)''' || || Number of samples. The default is taken from binary header<br />
|-<br />
| ''string '' || '''read=''' || || what to read: h - header, d - data, b - both (default)<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if input is SU, n if input is SEGY<br />
|-<br />
| ''bool '' || '''suxdr=n''' || [y/n] || y, SU has XDR support<br />
|-<br />
| ''string '' || '''tape=''' || || <br />
|-<br />
| ''string '' || '''tfile=''' || || output trace header file<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
The SEG Y format is an [http://en.wikipedia.org/wiki/Open_standard open standard] for the exchange of geophysical data. It is controlled by the non-profit [http://www.seg.org/SEGportalWEBproject/portals/SEG_Online.portal?_nfpb=true&_pageLabel=pg_gen_content&Doc_Url=prod/SEG-Publications/Pub-Yearbook/committees.htm SEG Technical Standards Committee]. There are two versions of this standard: [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev0.pdf rev0] (1975)<ref>Barry, K.M., Cavers, D.A., and Kneale, C.W. 1975. Recommended standards for digital tape formats. ''Geophysics'', '''40''', no. 02, 344–352.</ref> and [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf rev1] (2002)<ref>Norris, M.W., Faichney, A.K., ''Eds''. 2001. SEG Y rev1 Data Exchange format. Society of Exploration Geophysicists, Tulsa, OK, 45 pp.</ref>. The implementation in <tt>sfsegyread</tt> is a mixture of rev0 (i.e. no checks for Extended Textual Headers) and rev1 ([http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE floating point format] allowed for trace data samples).<br />
<br />
A SEG-Y file as understood by <tt>sfsegyread</tt> contains a "Reel Identification Header" (3200 bytes in EBCDIC followed by 400 bytes in a binary encoding), followed by a number of "Trace Blocks". Each "Trace Block" contains a 240-byte "Trace Header" (binary) followed by "Trace Data" -- a sequence of <tt>ns</tt> samples. Binary values in both reel headers and trace headers are two's complement integers, either two bytes or four bytes long. There are no floating-point values defined in the headers. Trace Data samples can have various encodings, either floating point or integer, described further down, but they are all big-endian. To convert from SEG-Y to RSF, <tt>sfsegyread</tt> will strip the tape reel EBCDIC header and convert it to ASCII, will extract the reel binary header without changing it, and will put the trace headers into one RSF file, and the traces themselves on another.<br />
<br />
===SEG-Y Trace Headers===<br />
In the SEG-Y standard, only the first 180 bytes of the 240-byte trace header are defined; bytes 181-240 are reserved for non-standard header information, and these locations are increasingly used in modern SEG-Y files and its variants. The standard provides for a total of 71 4-byte and 2-byte predefined header words. These 71 standard words have defined lengths and byte offsets, and only these words and byte locations are read using <tt>segyread</tt> and output to the RSF header file with the <tt>hfile=</tt> option. The user may remap these predefined keywords to a different byte offsets.<br />
<br />
===SU File Format===<br />
An [http://www.cwp.mines.edu/sututor/node22.html SU file] is nothing more than a SEG-Y file without the reel headers, and with the Trace Data samples in the native encoding of the CPU the file was created on (Attention -- limited portability!). So, to convert from SU to RSF, <tt>sfsegyread</tt> will just separate headers and traces into two RSF files. <br />
<br />
===SEG-Y specific parameters===<br />
*<tt>hfile=</tt> specifies the name of the file in which the EBCDIC reel header will be put after conversion to ASCII. If you are certain there is no useful information in it, <tt>hfile=/dev/null</tt> works just fine. If you do not specify anything for this parameter you will get an ASCII file named <tt>header</tt> in the current directory. If you want to quickly preview this header before running <tt>sfsegyread</tt>, use<pre>dd if=input.segy count=40 bs=80 cbs=80 conv=unblock,ascii</pre><br />
*<tt>bfile=</tt> specifies name of the file in which the binary reel header (the 400-bytes thing following the 3600-bytes EBCDIC) will be put without any conversion. The default name is "binary". Unless you have software that knows how to read exactly this special type of file, it will be completely useless, so do <tt>bfile=/dev/null</tt><br />
*<tt>format=</tt> specifies the format in which the trace data samples are in the SEG-Y input file. This is read from the binary reel header of the SEG-Y file. Valid values are 1(IBM floating point), 2 (4-byte integer), 3 (2-byte integer) and 5 (IEEE floating point). If the input file is SU, the format will be assumed to be the native <tt>float</tt> format.<br />
<br />
*<tt>keyname=</tt> specifies the byte offset to remap a header using the trace header key names shown above. For example, if the CDP locations have been placed in bytes 181-184 instead of the standard 21-24, <tt>cdp=180</tt> will remap the trace header to that location. <br />
<br />
===SU-specific parameters===<br />
*<tt>suxdr=</tt> specifies whether the input file was created with a SU package with XDR support enabled. If you have access to the source code of your SU install (try <tt>$CWPROOT/src</tt>), type: <tt>grep 'XDRFLAG =' $CWPROOT/src/Makefile.config</tt> and look at the last uncommented entry. If no value is given for <tt>XDRFLAG</tt>, the package was not compiled with XDR support.<br />
===Common parameters===<br />
*<tt>su=</tt> specifies if the input file is SU or SEG-Y. Default is <tt>su=n</tt> (SEG-Y file).<br />
*<tt>tape=</tt> specifies the input data. Stdin could not be used because <tt>sfsegyread</tt> has to work with tapes, and needs to fseek back and forth through the input file. Thankfully, output is on stdout.<br />
*<tt>read=</tt> specifies what parts of the "Trace Blocks" will be read. It can be <tt>read=t</tt> (only trace data is read), <tt>read=h</tt> (only trace headers are read) or <tt>read=b</tt> (both are read).<br />
*<tt>tfile=</tt> gives the name of the RSF file to which trace headers are written. Obviously, it should be only specified with <tt>read=h</tt> or <tt>read=b</tt>.<br />
*<tt>mask=</tt> is an optional parameter specifying the name of a mask that says which traces will be read. The mask is a 1-D RSF file with integers. The number of samples in the mask is the same as the number of traces in the unmasked SEG-Y. In places corresponding to unwanted traces there should be zeros in the mask.<br />
*<tt>ns=</tt> specifies the number of samples in a trace. For SEG-Y files, the default is taken from the binary reel header, and for SU files, from the header of the first trace. This parameter is however critical enough that a command line override was given for it.<br />
*<tt>verbose=</tt> is the verbosity flag. Can be <tt>y</tt> or <tt>n</tt>.<br />
*<tt>endian=</tt> is a y/n flag (default y), specifying whether to automatically estimate or not if samples in the Trace Data blocks are big-endian or little-endian. Try it if you are in trouble and do not know what else to do, otherwise let the automatic estimation do its job.<br />
<br />
==sfsegywrite==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert an RSF dataset to SEGY or SU.<br />
|-<br />
! colspan="4" | sfsegywrite < in.rsf tfile=hdr.rsf verb=false su=false endian=sf_endian() tape= hfile= bfile=<br />
|-<br />
| colspan="4" | <br>Merges trace headers with data.<br />
|-<br />
| ''string '' || '''bfile=''' || || input binary data header file<br />
|-<br />
| ''bool '' || '''endian=sf_endian()''' || [y/n] || big/little endian flag. The default is estimated automatically<br />
|-<br />
| ''string '' || '''hfile=''' || || input text data header file<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if output is SU, n if output is SEGY<br />
|-<br />
| ''string '' || '''tape=''' || ||<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
Please see <tt>sfsegyread</tt> for a complete description of parameter meanings and background issues. Parameters <tt>bfile</tt> and <tt>hfile</tt> should only be given values when the desired file is SEG-Y (default). The output file is specified by the <tt>tape=</tt> tag.<br />
<br />
=Plotting programs=<br />
The source files for these programs can be found under<br />
[http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/plot/main/ plot/main]<br />
in the Madagascar distribution.<br />
<br />
THIS SECTION IS UNDER CONSTRUCTION<br />
<br />
==sfbox==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Draw a balloon-style label.<br />
|-<br />
! colspan="4" | sfbox lab_color=VP_WHITE lab_fat=0 pscale=1. pointer=y reverse=n lat=0. long=90. angle=0. x0=0. y0=0. scale0=1. xt=2. yt=0. x_oval=0. y_oval=0. boxit=y length= scalet= size=.25 label= > out.vpl<br />
|-<br />
| ''float '' || '''angle=0.''' || || longitude of floating label in 3-D<br />
|-<br />
| ''bool '' || '''boxit=y''' || [y/n] || if y, create a box around text<br />
|-<br />
| ''int '' || '''lab_color=VP_WHITE''' || || label color<br />
|-<br />
| ''int '' || '''lab_fat=0''' || || label fatness<br />
|-<br />
| ''string '' || '''label=''' || || text for label<br />
|-<br />
| ''float '' || '''lat=0.''' || || <br />
|-<br />
| ''float '' || '''length=''' || || normalization for xt and yt<br />
|-<br />
| ''float '' || '''long=90.''' || || latitude and longitude of viewpoint in 3-D<br />
|-<br />
| ''bool '' || '''pointer=y''' || [y/n] || if y, create arrow pointer<br />
|-<br />
| ''float '' || '''pscale=1.''' || || scale factor for width of pointer<br />
|-<br />
| ''bool '' || '''reverse=n''' || [y/n] || <br />
|-<br />
| ''float '' || '''scale0=1.''' || || scale factor for x0 and y0<br />
|-<br />
| ''float '' || '''scalet=''' || || <br />
|-<br />
| ''float '' || '''size=.25''' || || text height in inches<br />
|-<br />
| ''float '' || '''x0=0.''' || || <br />
|-<br />
| ''float '' || '''x_oval=0.''' || || <br />
|-<br />
| ''float '' || '''xt=2.''' || || <br />
|-<br />
| ''float '' || '''y0=0.''' || || position of the pointer tip<br />
|-<br />
| ''float '' || '''y_oval=0.''' || || size of the oval around pointer<br />
|-<br />
| ''float '' || '''yt=0.''' || || relative position of text<br />
|}<br />
==sfcontour==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Contour plot.<br />
|-<br />
! colspan="4" | sfcontour < in.rsf c= min1=o1 min2=o2 max1=o1+(n1-1)*d1 max2=o2+(n2-1)*d2 nc=50 dc= c0= transp=y minval= maxval= allpos=y barlabel= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=y''' || [y/n] || contour positive values only<br />
|-<br />
| ''string '' || '''barlabel=''' || || <br />
|-<br />
| ''floats '' || '''c=''' || || [nc]<br />
|-<br />
| ''float '' || '''c0=''' || || first contour<br />
|-<br />
| ''float '' || '''dc=''' || || contour increment<br />
|-<br />
| ''float '' || '''max1=o1+(n1-1)*d1''' || || <br />
|-<br />
| ''float '' || '''max2=o2+(n2-1)*d2''' || || data window to plot<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''min1=o1''' || || <br />
|-<br />
| ''float '' || '''min2=o2''' || || <br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nc=50''' || || number of contours<br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfdots==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot signal with lollipops.<br />
|-<br />
! colspan="4" | sfdots < in.rsf labels= dots=(n1 <= 130)? 1: 0 seemean=(bool) (n2 <= 30) strings=(bool) (n1 <= 400) connect=1 corners= silk=n gaineach=y labelsz=8 yreverse=n constsep=n seedead=n transp=n xxscale=1. yyscale=1. clip=-1. overlap=0.9 screenratio=VP_SCREEN_RATIO screenht=VP_STANDARD_HEIGHT screenwd=screenhigh / screenratio radius=dd1/3 label1= unit1= title= > plot.vpl<br />
|-<br />
| ''float '' || '''clip=-1.''' || || data clip<br />
|-<br />
| ''int '' || '''connect=1''' || || connection type: 1 - diagonal, 2 - bar, 4 - only for non-zero data<br />
|-<br />
| ''bool '' || '''constsep=n''' || [y/n] || if y, use constant trace separation<br />
|-<br />
| ''int '' || '''corners=''' || || number of polygon corners (default is 6)<br />
|-<br />
| ''int '' || '''dots=(n1 <= 130)? 1: 0''' || || type of dots: 1 - baloon, 0 - no dots, 2 - only for non-zero data<br />
|-<br />
| ''bool '' || '''gaineach=y''' || [y/n] || if y, gain each trace independently<br />
|-<br />
| ''string '' || '''label1=''' || || <br />
|-<br />
| ''strings'' || '''labels=''' || || trace labels [n2]<br />
|-<br />
| ''int '' || '''labelsz=8''' || || label size<br />
|-<br />
| ''float '' || '''overlap=0.9''' || || trace overlap<br />
|-<br />
| ''float '' || '''radius=dd1/3''' || || dot radius<br />
|-<br />
| ''float '' || '''screenht=VP_STANDARD_HEIGHT''' || || screen height<br />
|-<br />
| ''float '' || '''screenratio=VP_SCREEN_RATIO''' || || screen aspect ratio<br />
|-<br />
| ''float '' || '''screenwd=screenhigh / screenratio''' || || screen width<br />
|-<br />
| ''bool '' || '''seedead=n''' || [y/n] || if y, show zero traces<br />
|-<br />
| ''bool '' || '''seemean=(bool) (n2 <= 30)''' || [y/n] || if y, draw axis lines<br />
|-<br />
| ''bool '' || '''silk=n''' || [y/n] || if y, silky plot<br />
|-<br />
| ''bool '' || '''strings=(bool) (n1 <= 400)''' || [y/n] || if y, draw strings<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axis<br />
|-<br />
| ''string '' || '''unit1=''' || || <br />
|-<br />
| ''float '' || '''xxscale=1.''' || || x scaling<br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse y axis<br />
|-<br />
| ''float '' || '''yyscale=1.''' || || y scaling<br />
|}<br />
==sfgraph3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot for surfaces.<br />
|-<br />
! colspan="4" | sfgraph3 < in.rsf orient=1 min= max= point1=0.5 point2=0.5 frame1=0.5*(min+max) frame2=n1-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y > plot.vpl<br />
|-<br />
| ''float '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''float '' || '''frame1=0.5*(min+max)''' || || <br />
|-<br />
| ''int '' || '''frame2=n1-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''max=''' || || maximum function value<br />
|-<br />
| ''float '' || '''min=''' || || minimum function value<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''orient=1''' || || function orientation<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|}<br />
==sfgraph==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Graph plot.<br />
|-<br />
! colspan="4" | sfgraph < in.rsf symbolsz= pclip=100. transp=n symbol= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''pclip=100.''' || || clip percentile<br />
|-<br />
| ''string '' || '''symbol=''' || || if set, plot with symbols instead of lines<br />
|-<br />
| ''floats '' || '''symbolsz=''' || || symbol size (default is 2) [n2]<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfgrey3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot.<br />
|-<br />
! colspan="4" | sfgrey3 < in.rsf point1=0.5 point2=0.5 frame1=0 frame2=n2-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y scalebar=n minval= maxval= barreverse=n nreserve=8 bar= color= > plot.vpl<br />
|-<br />
| colspan="4" | Requires an "unsigned char" input (the output of sfbyte).<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''int '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''int '' || '''frame1=0''' || || <br />
|-<br />
| ''int '' || '''frame2=n2-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || if y, draw scalebar<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
for sfgrey and sfgrey3. Examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfgrey==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate raster plot.<br />
|-<br />
! colspan="4" | sfgrey < in.rsf > out.rsf bar=bar.rsf transp=y yreverse=y xreverse=n gpow= phalf= clip= pclip= gainstep=0.5+n1/256. allpos=n bias=0. polarity=n verb=n scalebar=n minval= maxval= barreverse=n wantframenum=(bool) (n3 > 1) nreserve=8 gainpanel= bar= color= > (plot.vpl | char.rsf)<br />
|-<br />
| colspan="4" | Can input char values.<br>If called "byte", outputs char values.<br><br>Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=n''' || [y/n] || if y, assume positive data<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=''' || || <br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''string '' || '''gainpanel=''' || || gain reference: 'a' for all, 'e' for each, or number<br />
|-<br />
| ''int '' || '''gainstep=0.5+n1/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=''' || || <br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''pclip=''' || || data clip percentile (default is 99)<br />
|-<br />
| ''float '' || '''phalf=''' || || percentage for estimating gpow<br />
|-<br />
| ''bool '' || '''polarity=n''' || [y/n] || if y, reverse polarity (white is high by default)<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the display axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''bool '' || '''wantframenum=(bool) (n3 > 1)''' || [y/n] || if y, display third axis position in the corner<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''bool '' || '''yreverse=y''' || [y/n] || if y, reverse the vertical axis<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
and examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfplas==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Assembler - convert ascii to vplot. <br />
|-<br />
! colspan="4" | sfplas<br />
|}<br />
==sfpldb==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Debugger - convert vplot to ascii. <br />
|-<br />
! colspan="4" | sfpldb<br />
|}<br />
==sfplotrays==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot rays.<br />
|-<br />
! colspan="4" | sfplotrays frame=frame.rsf nt=n1*n2 jr=1 frame= < rays.rsf > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''string '' || '''frame=''' || || <br />
|-<br />
| ''int '' || '''jr=1''' || || skip rays<br />
|-<br />
| ''int '' || '''nt=n1*n2''' || || maximum ray length<br />
|}<br />
==sfthplot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Hidden-line surface plot.<br />
|-<br />
! colspan="4" | sfthplot < in.rsf uflag=y dflag=y alpha=45. titlsz=9 axissz=6 plotfat=0 titlefat=2 axisfat=2 plotcolup=VP_YELLOW plotcoldn=VP_RED axis=y axis1=y axis2=y axis3=y clip=0. pclip=100. gainstep=0.5+nx/256. bias=0. dclip=1. norm=y xc=1.5 zc=3 ratio=5. zmax= zmin= sz=6. label#= unit#= tpow=0 epow=0 gpow=1 title= > plot.vpl<br />
|-<br />
| ''float '' || '''alpha=45.''' || || apparent angle in degrees, |alpha| < 89<br />
|-<br />
| ''bool '' || '''axis=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis1=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis2=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis3=y''' || [y/n] || plot axis<br />
|-<br />
| ''int '' || '''axisfat=2''' || || axes fatness<br />
|-<br />
| ''int '' || '''axissz=6''' || || axes size<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip<br />
|-<br />
| ''float '' || '''dclip=1.''' || || change the clip: clip *= dclip<br />
|-<br />
| ''bool '' || '''dflag=y''' || [y/n] || if y, plot down side of the surface<br />
|-<br />
| ''float '' || '''epow=0''' || || exponential gain<br />
|-<br />
| ''int '' || '''gainstep=0.5+nx/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=1''' || || power gain<br />
|-<br />
| ''string '' || '''label#=''' || || label on #-th axis<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || normalize by the clip<br />
|-<br />
| ''float '' || '''pclip=100.''' || || data clip percentile<br />
|-<br />
| ''int '' || '''plotcoldn=VP_RED''' || || color of the lower side<br />
|-<br />
| ''int '' || '''plotcolup=VP_YELLOW''' || || color of the upper side<br />
|-<br />
| ''int '' || '''plotfat=0''' || || line fatness<br />
|-<br />
| ''float '' || '''ratio=5.''' || || plot adjustment<br />
|-<br />
| ''float '' || '''sz=6.''' || || vertical scale<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''int '' || '''titlefat=2''' || || title fatness<br />
|-<br />
| ''int '' || '''titlsz=9''' || || title size<br />
|-<br />
| ''string '' || '''tpow=0''' || || time power gain<br />
|-<br />
| ''bool '' || '''uflag=y''' || [y/n] || if y, plot upper side of the surface<br />
|-<br />
| ''string '' || '''unit#=''' || || unit on #-th axis<br />
|-<br />
| ''float '' || '''xc=1.5''' || || <br />
|-<br />
| ''float '' || '''zc=3''' || || lower left corner of the plot<br />
|-<br />
| ''float '' || '''zmax=''' || || <br />
|-<br />
| ''float '' || '''zmin=''' || || <br />
|}<br />
==sfwiggle==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot data with wiggly traces. <br />
|-<br />
! colspan="4" | sfwiggle < in.rsf xpos=xpos.rsf xmax= xmin= poly=n fatp=1 xmask=1 ymask=1 pclip=98. zplot=0.75 clip=0. seemean=n verb=n transp=n yreverse=n xreverse=n xpos= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip (estimated from pclip by default<br />
|-<br />
| ''int '' || '''fatp=1''' || || <br />
|-<br />
| ''float '' || '''pclip=98.''' || || clip percentile<br />
|-<br />
| ''bool '' || '''poly=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''seemean=n''' || [y/n] || if y, plot mean lines of traces<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''int '' || '''xmask=1''' || || <br />
|-<br />
| ''float '' || '''xmax=''' || || maximum trace position (if using xpos)<br />
|-<br />
| ''float '' || '''xmin=''' || || minimum trace position (if using xpos)<br />
|-<br />
| ''string '' || '''xpos=''' || || optional header file with trace positions<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''int '' || '''ymask=1''' || || <br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse the vertical axis<br />
|-<br />
| ''float '' || '''zplot=0.75''' || || <br />
|}<br />
<br />
=filt/imag programs=<br />
==sfremap1==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 1-D ENO interpolation. <br />
|-<br />
! colspan="4" | sfremap1 < in.rsf > out.rsf pattern=pattern.rsf n1=n1 d1=d1 o1=o1 order=3<br />
|-<br />
| ''float '' || '''d1=d1''' || || Output sampling<br />
|-<br />
| ''int '' || '''n1=n1''' || || Number of output samples<br />
|-<br />
| ''float '' || '''o1=o1''' || || Output origin<br />
|-<br />
| ''int '' || '''order=3''' || || Interpolation order<br />
|-<br />
| ''string '' || '''pattern=''' || || auxiliary input file name<br />
|}<br />
To give an example of usage, we will create an input for <tt>sfremap1</tt> with:<br />
<pre><br />
sfmath n1=11 n2=11 d1=1 d2=1 o1=-5 o2=-5 output="x1*x1+x2*x2" > inp2remap1.rsf<br />
</pre><br />
Let us interpolate the data across both dimensions, then display it:<br />
<pre><br />
&lt; inp2remap1.rsf sfremap1 n1=1001 d1=0.01 | sftransp | \<br />
sfremap1 n1=1001 d1=0.01 | sftransp | sfgrey allpos=y | xtpen<br />
</pre><br />
The comparison with the uninterpolated data ( <tt>&lt; inp2remap1.rsf sfgrey allpos=y | xtpen</tt> ) is quite telling.<br />
<br />
=filt/proc programs=<br />
==sfstretch==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stretch of the time axis. <br />
|-<br />
! colspan="4" | sfstretch < in.rsf > out.rsf datum=dat.rsf inv=n dens=1 v0= half=y delay= tdelay= hdelay= nout=dens*n1 extend=4 mute=0 maxstr=0 rule=<br />
|-<br />
| ''file '' || '''datum=''' || || auxiliary input file name<br />
|-<br />
| ''float '' || '''delay=''' || || time delay for rule=lmo<br />
|-<br />
| ''int '' || '''dens=1''' || || axis stretching factor<br />
|-<br />
| ''int '' || '''extend=4''' || || trace extension<br />
|-<br />
| ''bool '' || '''half=y''' || [y/n] || if y, the second axis is half-offset instead of full offset<br />
|-<br />
| ''float '' || '''hdelay=''' || || offset delay for rule=rad<br />
|-<br />
| ''bool '' || '''inv=n''' || [y/n] || if y, do inverse stretching<br />
|-<br />
| ''float '' || '''maxstr=0''' || || maximum stretch<br />
|-<br />
| ''int '' || '''mute=0''' || || tapering size<br />
|-<br />
| ''int '' || '''nout=dens*n1''' || || output axis length (if inv=n)<br />
|-<br />
| ''string '' || '''rule=''' || || Stretch rule:<br />
:n - normal moveout (nmostretch), default<br />
:l - linear moveout (lmostretch)<br />
:L - logarithmic stretch (logstretch)<br />
:2 - t^2 stretch (t2stretch)<br />
:c - t^2 chebyshev stretch (t2chebstretch)<br />
:r - radial moveout (radstretch)<br />
:d - datuming (datstretch)<br />
|-<br />
| ''float '' || '''tdelay=''' || || time delay for rule=rad<br />
|-<br />
| ''float '' || '''v0=''' || || moveout velocity<br />
|}<br />
<br />
<tt>sfstretch rule=d</tt> (aka <tt>sfdatstretch</tt>) can be used to apply statics. Here is a synthetic example, courtesy of Alessandro Frigeri:<br />
<pre><br />
# generate a dataset with 'flat' signals<br />
sfmath n1=200 n2=100 output="sin(0.5*x1)" type=float > scan.rsf<br />
<br />
# generate a sinusoidal elevation correction<br />
sfmath n1=100 output="3*sin(x1)" type=float > statics.rsf<br />
<br />
# apply statics, producing a 'wavy' output.<br />
sfstretch < scan.rsf > out.rsf datum=statics.rsf rule=d<br />
</pre><br />
<br />
=user/ivlad programs=<br />
==sfprep4plot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Resamples a 2-D dataset to the desired picture resolution, with antialias<br />
|-<br />
! colspan="4" | sfprep4plot inp= out= verb=n h=none w=none unit= ppi= prar=y<br />
|-<br />
| colspan="4" | Only one of the h and w parameters needs to be specified.<br>If prar=n, no action will be taken on axis for which h/w was not specified<br>If prar=y and only one par (h or w) is specified, the picture will scale<br>along both axes until it is of the specified dimension.<br />
|-<br />
| ''int '' || '''h=none''' || || output height<br />
|-<br />
| ''string '' || '''inp=''' || || input file<br />
|-<br />
| ''string '' || '''out=''' || || output file<br />
|-<br />
| ''int '' || '''ppi=''' || || output resolution (px/in). Necessary when unit!=px<br />
|-<br />
| ''bool '' || '''prar=y''' || [y/n] || if y, PReserve Aspect Ratio of input<br />
|-<br />
| ''string '' || '''unit=''' || || unit of h and w. Can be: px(default), mm, cm, in<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || if y, print system commands, outputs<br />
|-<br />
| ''int '' || '''w=none''' || || output width<br />
|}<br />
For a figure that does not need the aspect ratio preserved,<br />
and needs to fill a 1280x1024 projector display:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=1280 h=1024 prar=n<br />
</pre><br />
For a print figure that has to fit in a 6x8in box<br />
at a resolution of 250 dpi, preserving the aspect ratio:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=6 h=8 unit=in ppi=250<br />
</pre><br />
A comparison of images before and after the application of <tt>sfprep4plot</tt>, courtesy of Joachim Mispel, is shown below:<br />
<br />
[[Image:sf_prep4plot.jpg]]<br />
<br />
=user/jennings programs=<br />
==sfsizes==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display the size of RSF files.<br />
|-<br />
! colspan="4" | sfsizes files=y human=n file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | Prints the element size, number of elements, and number of bytes<br>for a list of RSF files. Non-RSF files are ignored.<br />
|-<br />
| ''bool '' || '''files=y''' || [y/n] || If y, print size of each file. If n, print only total.<br />
|-<br />
| ''bool '' || '''human=n''' || [y/n] || If y, print human-readable file size. If n, print byte count.<br />
|}<br />
<br />
<br />
This program computes the "theoretical" size in bytes of the data fork of RSF files. The actual space occupied on disk may be different and machine dependent due to disk blocking factors, etc. This theoretical array size should be reproducible. It is also fast because the program only reads the RSF headers files, not the actual data.<br />
<br />
For example, to get the total size of all RSF files in a directory, in human readable format, without listing each file:<br />
<pre><br />
sfsizes files=n human=y *.rsf<br />
</pre><br />
This will also work because sfsizes simply skips any non-RSF file:<br />
<pre><br />
sfsizes files=n human=y *<br />
</pre><br />
==sffiglist==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display the size of RSF files.<br />
|-<br />
! colspan="4" | sfsizes files=y human=n file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | Prints the element size, number of elements, and number of bytes<br>for a list of RSF files. Non-RSF files are ignored.<br />
|-<br />
| ''bool '' || '''files=y''' || [y/n] || If y, print size of each file. If n, print only total.<br />
|-<br />
| ''bool '' || '''human=n''' || [y/n] || If y, print human-readable file size. If n, print byte count.<br />
|}<br />
<br />
<br />
This program computes the "theoretical" size in bytes of the data fork of RSF files. The actual space occupied on disk may be different and machine dependent due to disk blocking factors, etc. This theoretical array size should be reproducible. It is also fast because the program only reads the RSF headers files, not the actual data.<br />
<br />
For example, to get the total size of all RSF files in a directory, in human readable format, without listing each file:<br />
<pre><br />
sfsizes files=n human=y *.rsf<br />
</pre><br />
This will also work because sfsizes simply skips any non-RSF file:<br />
<pre><br />
sfsizes files=n human=y *<br />
</pre><br />
<br />
=user/psava programs=<br />
==sfsrmig3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 3-D S/R migration with extended SSF<br />
|-<br />
! colspan="4" | sfsrmig3 slo=Fs_s.rsf sls=Fs_r.rsf < Fw_s.rsf rwf=Fw_r.rsf > Fi.rsf cig=Fc.rsf ompchunk=1 ompnth=0 verb=y eps=0.01 twoway=n nrmax=1 dtmax=0.004 pmx=0 pmy=0 tmx=0 tmy=0 vpvs=1. hsym=n nht=1 oht=0 dht=0.1 nht=1 oht=0 dht=0.1 hsym=n nhh=1 ohh=0 dhh=0.1 nha=180 oha=0 dha=2.0 nhb=180 ohb=0 dhb=2.0 itype=<br />
|-<br />
| ''file '' || '''cig=''' || || auxiliary output file name<br />
|-<br />
| ''float '' || '''dha=2.0''' || ||<br />
|-<br />
| ''float '' || '''dhb=2.0''' || ||<br />
|-<br />
| ''float '' || '''dhh=0.1''' || ||<br />
|-<br />
| ''float '' || '''dht=0.1''' || ||<br />
|-<br />
| ''float '' || '''dtmax=0.004''' || || max time error<br />
|-<br />
| ''float '' || '''eps=0.01''' || || stability parameter<br />
|-<br />
| ''bool '' || '''hsym=n''' || [y/n] ||<br />
|-<br />
| ''string '' || '''itype=''' || || imaging condition type<br />
:o = zero lag (default)<br />
:e = extended<br />
:x = space-lags<br />
:h = space-lags magnitude<br />
:t = time-lag<br />
|-<br />
| ''int '' || '''nha=180''' || ||<br />
|-<br />
| ''int '' || '''nhb=180''' || ||<br />
|-<br />
| ''int '' || '''nhh=1''' || ||<br />
|-<br />
| ''int '' || '''nht=1''' || ||<br />
|-<br />
| ''int '' || '''nrmax=1''' || || max number of refs<br />
|-<br />
| ''float '' || '''oha=0''' || ||<br />
|-<br />
| ''float '' || '''ohb=0''' || ||<br />
|-<br />
| ''float '' || '''ohh=0''' || ||<br />
|-<br />
| ''float '' || '''oht=0''' || ||<br />
|-<br />
| ''int '' || '''ompchunk=1''' || || OpenMP data chunk size<br />
|-<br />
| ''int '' || '''ompnth=0''' || || OpenMP available threads<br />
|-<br />
| ''int '' || '''pmx=0''' || || padding on x<br />
|-<br />
| ''int '' || '''pmy=0''' || || padding on y<br />
|-<br />
| ''file '' || '''rwf=''' || || auxiliary input file name<br />
|-<br />
| ''file '' || '''slo=''' || || auxiliary input file name<br />
|-<br />
| ''string '' || '''sls=''' || || auxiliary input file name<br />
|-<br />
| ''int '' || '''tmx=0''' || || taper on x<br />
|-<br />
| ''int '' || '''tmy=0''' || || taper on y<br />
|-<br />
| ''bool '' || '''twoway=n''' || [y/n] || two-way traveltime<br />
|-<br />
| ''bool '' || '''verb=y''' || [y/n] || verbosity flag<br />
|-<br />
| ''float '' || '''vpvs=1.''' || || Vp/Vs ratio<br />
|}<br />
<br />
This program performs 3-D and 2-D shot-record (a.k.a. shot-profile) migration with an extended Split-Step Fourier (SSF) extrapolator with multiple reference velocities (hence "extended"). It takes as input a shot wavefield (<tt>stdin</tt>), receiver wavefield (<tt>rwf=</tt>) and slowness model (<tt>slo=</tt>). Outputs are an image (<tt>stdout</tt>) and a cube of Common Image Gathers (<tt>cig=</tt>). An important parameter is <tt>nrmax</tt>, the number of reference velocities. Its default value is 1, but for reasonable results it should be 5 or so. It is also good to specify nonzero taper values (<tt>tmx</tt> and, for 3-D, <tt>tmy</tt> as well). The values of padding parameters <tt>pmx</tt> and <tt>pmy</tt> are split in two by the program, i.e. if your data x axis is 501-points long, specify pmx=11 to get a value of 512 that will result in fast Fourier Transforms. <br />
<br />
The program will also migrate converted-wave data if a file with the S-wave slowness model (<tt>sls=</tt>) is provided.<br />
<br />
The <tt>vpvs</tt> parameter is only used when <tt>itype=h</tt>. Do not specify a <tt>vpvs</tt> value unless you know really well what you are doing.<br />
<br />
===Usage example===<br />
The commands below, slightly modified from [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/data/sigsbee/ptest/SConstruct?revision=3993&view=markup RSFSRC/book/data/sigsbee/ptest], show how to prepare the [http://www.reproducibility.org/RSF/book/data/sigsbee Sigsbee 2A] data and velocity for migration.<br />
<br />
Convert input data (shots) from SEG-Y to RSF:<br />
<bash><br />
sfsegyread tape=sigsbee2a_nfs.segy tfile=tdata.rsf hfile=/dev/null bfile=/dev/null > ddata.rsf<br />
</bash><br />
Convert trace headers to float (required by <tt>sfheadermath</tt>):<br />
<bash><br />
< tdata.rsf sfdd type=float > trchdr.rsf<br />
</bash><br />
Shot positions:<br />
<bash><br />
< trchdr.rsf sfheadermath output="fldr + 10925/150" | sfwindow squeeze=y > tsi.rsf<br />
</bash><br />
Extract offset positions from the trace header files, eliminate length-1 axis, scale, create a header for binning (required by <tt>sfintbin</tt>):<br />
<bash><br />
< trchdr.rsf sfheadermath output="offset" |\<br />
sfwindow squeeze=y |\<br />
sfmath output="input/75" |\<br />
sfcat axis=2 space=n tsi.rsf |\<br />
sftransp |\<br />
sfdd type=int > tos.rsf<br />
</bash><br />
Binning and muting:<br />
<bash><br />
< ddata.rsf sfintbin head=tos.rsf xkey=0 ykey=1 |\<br />
sfput label1=Time unit1=s d2=0.075 o2=0.0 label2=hx d3=0.150 o3=10.925 label3=sx |\<br />
sfmutter half=false t0=1.0 v0=6.0 |\<br />
sfput d2=0.02286 o2=0 unit2=km d3=0.04572 o3=3.32994 unit3=km > shots.rsf<br />
</bash><br />
Keeping only 20 shots so that this 1-node job will not take forever, FFT-ing, decimating frequency slices (same as shortening the time axis), and creating y and hy axes of length 1:<br />
<bash><br />
< shots.rsf sfwindow n3=20 f3=10 j3=20 |\<br />
sffft1 |\<br />
sfwindow n1=200 min1=1 j1=3 |\<br />
sfspray axis=3 n=1 o=0 d=1 label=hy |\<br />
sfspray axis=5 n=1 o=0 d=1 label=sy > rfft.rsf<br />
</bash><br />
The dimensions of the cube thus created are:<br />
<pre><br />
$ sfin rfft.rsf trail=n<br />
rfft.rsf:<br />
in="/var/tmp/rfft.rsf@"<br />
esize=8 type=complex form=native<br />
n1=200 d1=0.25 o1=1 label1="Frequency" unit1="Hz"<br />
n2=348 d2=0.02286 o2=0 label2="hx" unit2="km"<br />
n3=1 d3=1 o3=0 label3="hy" unit3="km"<br />
n4=20 d4=0.9144 o4=3.78714 label4="sx" unit4="km"<br />
1392000 elements 11136000 bytes<br />
</pre><br />
Create the source wavelet (limited to the same frequency band as the data) and Fourier transform it:<br />
<bash><br />
sfspike k1=1 n1=1500 d1=0.008 |\<br />
sfbandpass flo=15 fhi=25 |\<br />
sffft1 |\<br />
sfwindow n1=200 min1=1 j1=3 |\<br />
sfput label1=freq > sfft.rsf<br />
</bash><br />
This creates a frequency-domain wavelet:<br />
<pre><br />
$ sfin sfft.rsf<br />
sfft.rsf:<br />
in="/var/tmp/sfft.rsf@"<br />
esize=8 type=complex form=native<br />
n1=200 d1=0.25 o1=1 label1="freq" unit1="Hz"<br />
200 elements 1600 bytes<br />
</pre><br />
Create "synched" source and receiver wavefields with <tt>srsyn</tt> from wavelet and data frequency slices. Basically both the receiver and shot frequency slices are "placed" at the right location and padded with zeros up to the dimension of the x axis specified below.<br />
<bash><br />
< rfft.rsf sfsrsyn nx=1067 dx=0.02286 ox=3.05562 wav=sfft.rsf swf=swav.rsf > rwav.rsf<br />
</bash><br />
This creates frequency slices ready for migration for both source and receiver, only axis 1 (frequency) must become axis 3, for both datasets:<br />
<bash><br />
< swav.rsf sftransp plane=12 | sftransp plane=23 > stra.rsf<br />
</bash><br />
<bash><br />
< rwav.rsf sftransp plane=12 | sftransp plane=23 > rtra.rsf<br />
</bash><br />
This creates a surface receiver wavefield ready for input to migration. Axis 4 is shot number. The values of axis 4 are arbitrary because each shot has been padded with zeros so that it covers the entire velocity model. Therefore the aperture of the downward continuation for each shot will be as large as the survey.<br />
<pre><br />
sfin trail=n rtra.rsf<br />
rtra.rsf:<br />
in="/var/tmp/rtra.rsf@"<br />
esize=8 type=complex form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=200 d3=0.25 o3=1 label3="w" unit3="Hz"<br />
n4=20 d4=1 o4=0 label4="e" unit4="km"<br />
4268000 elements 34144000 bytes<br />
</pre><br />
Convert the velocity model from SEG-Y to RSF, decimate, convert from feet to km, transpose, convert to slowness and insert an additional axis:<br />
<bash><br />
sfsegyread tape=sigsbee2a_migvel.sgy tfile=/dev/null hfile=/dev/null bfile=/dev/null |\<br />
sfput o1=0 d1=0.00762 label1=z unit1=km o2=3.05562 d2=0.01143 label2=x unit2=km |\<br />
sfwindow j1=4 j2=2 |\<br />
sfscale rscale=0.0003048 |\<br />
sftransp |\<br />
sfmath output="1/input" |\<br />
sfspray axis=2 n=1 d=1 o=0 |\<br />
sfput label2=y > slow.rsf<br />
</bash><br />
This creates a slowness file ready for input to migration, with an x axis identical to the x axis of the wavefield files:<br />
<pre><br />
$ sfin slow.rsf<br />
slow.rsf:<br />
in="/var/tmp/slow.rsf@"<br />
esize=4 type=float form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=301 d3=0.03048 o3=0 label3="z" unit3="km"<br />
321167 elements 1284668 bytes<br />
</pre><br />
Finally, the migration command (for a 4-processor machine, hence the <tt>ompnth</tt> value). We choose not to compute any image gathers (<tt>itype=o</tt>), but due to the construction of the program we still have to explicitly assign the <tt>cig</tt> tag, or else a RSF file with the name of the tag and no rsf extension will be created:<br />
<bash><br />
< stra.rsf sfsrmig3 nrmax=20 dtmax=5e-05 eps=0.01 verb=y ompnth=4 \<br />
tmx=16 rwf=rtra.rsf slo=slow.rsf itype=o cig=/dev/null > img.rsf<br />
</bash><br />
The migration of 20 shots takes approximately 3 hours on a 4-processor machine (1 shot=9 minutes). Without the frequency slice decimation by a factor of 3 and the depth axis decimation by a factor of 4, it would have taken twelve times as much. The resulting image has a y axis of length 1:<br />
<pre><br />
$ sfin img.rsf trail=n<br />
img.rsf:<br />
in="/var/tmp/img.rsf@"<br />
esize=4 type=float form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=301 d3=0.03048 o3=0 label3="z" unit3="km"<br />
321167 elements 1284668 bytes<br />
</pre><br />
To properly visualize the image, we need to eliminate the axis of length 1, then transpose the x and z axes to their natural position:<br />
<bash><br />
<img.rsf sfwindow squeeze=y | sftransp | sfgrey > img.vpl<br />
</bash><br />
<br />
=References=<br />
<references/></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Guide_to_madagascar_programs&diff=927Guide to madagascar programs2009-08-14T02:35:58Z<p>Jenningsjwj: /* user/jennings programs */</p>
<hr />
<div><center><font size="-1">''This page was created from the LaTeX source in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/rsf/rsf/prog.tex?view=markup book/rsf/rsf/prog.tex] using [[latex2wiki]]''</font></center><br />
<br />
This guide introduces some of the most used <tt>madagascar</tt> programs and illustrates their usage with examples.<br />
=Main programs=<br />
The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/ system/main] in the Madagascar distribution. The "main" programs perform general-purpose operations on RSF hypercubes regardless of the data dimensionality or physical dimensions.<br />
<br />
==sfadd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Add, multiply, or divide RSF datasets.<br />
|-<br />
! colspan="4" | sfadd > out.rsf scale= add= sqrt= abs= log= exp= mode= [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | The various operations, if selected, occur in the following order:<br><br>(1) Take absolute value, abs=<br>(2) Add a scalar, add=<br>(3) Take the natural logarithm, log=<br>(4) Take the square root, sqrt=<br>(5) Multiply by a scalar, scale=<br>(6) Compute the base-e exponential, exp=<br>(7) Add, multiply, or divide the data sets, mode=<br><br>sfadd operates on integer, float, or complex data, but all the input<br>and output files must be of the same data type.<br><br>An alternative to sfadd is sfmath, which is more versatile, but may be<br>less efficient.<br />
|-<br />
| ''bools '' || '''abs=''' || || If true take absolute value [nin]<br />
|-<br />
| ''floats '' || '''add=''' || || Scalar values to add to each dataset [nin]<br />
|-<br />
| ''bools '' || '''exp=''' || || If true compute exponential [nin]<br />
|-<br />
| ''bools '' || '''log=''' || || If true take logarithm [nin]<br />
|-<br />
| ''string '' || '''mode=''' || || 'a' means add (default), <br> 'p' or 'm' means multiply, <br> 'd' means divide<br />
|-<br />
| ''floats '' || '''scale=''' || || Scalar values to multiply each dataset with [nin]<br />
|-<br />
| ''bools '' || '''sqrt=''' || || If true take square root [nin]<br />
|}<br />
<br />
<tt>sfadd</tt> is useful for combining (adding, dividing, or<br />
multiplying) several datasets. What if you want to subtract two<br />
datasets? Easy. Use the <tt>scale</tt> parameter as follows:<br />
<pre><br />
bash&#36; sfadd data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfadd < data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
The same task can be accomplished with the more general <tt>sfmath</tt> program:<br />
<pre><br />
bash&#36; sfmath one=data1.rsf two=data2.rsf output='one-two' > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfmath < data1.rsf two=data2.rsf output='input-two' > diff.rsf<br />
</pre><br />
In both cases, the size and shape of <tt>data1.rsf</tt> and<br />
<tt>data2.rsf</tt> hypercubes should be the same, and a warning<br />
message is printed out if the the axis sampling parameters (such as<br />
<tt>o1</tt> or <tt>d1</tt>) in these files are different.<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/add.c?view=markup system/main/add.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
/* find number of input files */<br />
if (isatty(fileno(stdin))) { <br />
/* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Collect input files in the <tt>in</tt> array from all command-line<br />
parameters that don't contain an "<tt>=</tt>" sign. The total number<br />
of input files in <tt>nin</tt>.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) continue; <br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
/* nin = no of input files*/<br />
</c><br />
<br />
A helper function <tt>check_compat</tt> checks the compatibility of<br />
input files.<br />
<c><br />
static void <br />
check_compat (sf_datatype type /* data type */, <br />
size_t nin /* number of files */, <br />
sf_file* in /* input files [nin] */, <br />
int dim /* file dimensionality */, <br />
const int* n /* dimensions [dim] */)<br />
/* Check that the input files are compatible. <br />
Issue error for type mismatch or size mismatch.<br />
Issue warning for grid parameters mismatch. */<br />
{<br />
int ni, id;<br />
size_t i;<br />
float d, di, o, oi;<br />
char key[3];<br />
const float tol=1.e-5; /* tolerance for comparison */<br />
<br />
for (i=1; i < nin; i++) {<br />
if (sf_gettype(in[i]) != type) <br />
sf_error ("type mismatch: need %d",type);<br />
for (id=1; id <= dim; id++) {<br />
(void) snprintf(key,3,"n%d",id);<br />
if (!sf_histint(in[i],key,&ni) || ni != n[id-1])<br />
sf_error("%s mismatch: need %d",key,n[id-1]);<br />
(void) snprintf(key,3,"d%d",id);<br />
if (sf_histfloat(in[0],key,&d)) {<br />
if (!sf_histfloat(in[i],key,&di) || <br />
(fabsf(di-d) > tol*fabsf(d)))<br />
sf_warning("%s mismatch: need %g",key,d);<br />
} else {<br />
d = 1.;<br />
}<br />
(void) snprintf(key,3,"o%d",id);<br />
if (sf_histfloat(in[0],key,&o) && <br />
(!sf_histfloat(in[i],key,&oi) || <br />
(fabsf(oi-o) > tol*fabsf(d))))<br />
sf_warning("%s mismatch: need %g",key,o);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
Finally, we enter the main loop, where input data are getting read<br />
buffer by buffer and combined in the total product depending on the<br />
data type.<br />
<c><br />
for (nbuf /= sf_esize(in[0]); nsiz > 0; nsiz -= nbuf) {<br />
if (nbuf > nsiz) nbuf=nsiz;<br />
<br />
for (j=0; j < nin; j++) {<br />
collect = (bool) (j != 0);<br />
switch(type) {<br />
case SF_FLOAT:<br />
sf_floatread((float*) bufi,<br />
nbuf,<br />
in[j]); <br />
add_float(collect, <br />
nbuf,<br />
(float*) buf,<br />
(const float*) bufi, <br />
cmode, <br />
scale[j], <br />
add[j], <br />
abs_flag[j], <br />
log_flag[j], <br />
sqrt_flag[j], <br />
exp_flag[j]);<br />
break;<br />
</c><br />
<br />
The data combination program for floating point numbers is<br />
<tt>add_float</tt>. <br />
<c><br />
static void add_float (bool collect, /* if collect */<br />
size_t nbuf, /* buffer size */<br />
float* buf, /* output [nbuf] */<br />
const float* bufi, /* input [nbuf] */ <br />
char cmode, /* operation */<br />
float scale, /* scale factor */<br />
float add, /* add factor */<br />
bool abs_flag, /* if abs */<br />
bool log_flag, /* if log */<br />
bool sqrt_flag, /* if sqrt */<br />
bool exp_flag /* if exp */)<br />
/* Add floating point numbers */<br />
{<br />
size_t j;<br />
float f;<br />
<br />
for (j=0; j < nbuf; j++) {<br />
f = bufi[j];<br />
if (abs_flag) f = fabsf(f);<br />
f += add;<br />
if (log_flag) f = logf(f);<br />
if (sqrt_flag) f = sqrtf(f);<br />
if (1. != scale) f *= scale;<br />
if (exp_flag) f = expf(f);<br />
if (collect) {<br />
switch (cmode) {<br />
case 'p': /* product */<br />
case 'm': /* multiply */<br />
buf[j] *= f;<br />
break;<br />
case 'd': /* delete */<br />
if (f != 0.) buf[j] /= f;<br />
break;<br />
default: /* add */<br />
buf[j] += f;<br />
break;<br />
}<br />
} else {<br />
buf[j] = f;<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display dataset attributes.<br />
|-<br />
! colspan="4" | sfattr < in.rsf want=<br />
|-<br />
| colspan="4" | <br>Sample output from "sfspike n1=100 | sfbandpass fhi=60 | sfattr"<br>******************************************* <br>rms = 0.992354 <br>mean value = 0.987576 <br>2-norm value = 9.92354 <br>variance = 0.00955481 <br>standard deviation = 0.0977487 <br>maximum value = 1.12735 at 97 <br>minimum value = 0.151392 at 100 <br>number of nonzero samples = 100 <br>total number of samples = 100 <br>******************************************* <br><br>rms = sqrt[ sum(data^2) / n ]<br>mean = sum(data) / n<br>norm = sum(abs(data)^lval)^(1/lval)<br>variance = [ sum(data^2) - n*mean^2 ] / [ n-1 ]<br>standard deviation = sqrt [ variance ]<br />
|-<br />
| ''int '' || '''lval=2''' || || norm option, lval is a non-negative integer, computes the vector lval-norm<br />
|-<br />
| ''string '' || '''want=''' || || 'all'(default),'rms','mean','norm','var','std','max','min','nonzero','samples','short' <br />
:want= 'rms' displays the root mean square<br />
:want= 'norm' displays the square norm, otherwise specified by lval.<br />
:want= 'var' displays the variance<br />
:want= 'std' displays the standard deviation<br />
:want= 'nonzero' displays number of nonzero samples<br />
:want= 'samples' displays total number of samples<br />
:want= 'short' displays a short one-line version<br />
|}<br />
<br />
<br />
<tt>sfattr</tt> is a useful diagnostic program. It reports certain<br />
statistical values for an RSF dataset: RMS (root-mean-square)<br />
amplitude, mean value, vector norm value, variance, standard deviation,<br />
maximum and minimum values, number of nonzero samples, and the total<br />
number of samples.<br />
If we denote data values as <math>d_i</math> for <math>i=0,1,2,\ldots,n</math>, then the RMS<br />
value is <math>\sqrt{\frac{1}{n}\,\sum\limits_{i=0}^n d_i^2}</math>, the mean<br />
value is <math>\frac{1}{n}\,\sum\limits_{i=0}^n d_i</math>, the <math>L_2</math>-norm value<br />
is <math>\sqrt{\sum\limits_{i=0}^n d_i^2}</math>, the variance is<br />
<math>\frac{1}{n-1}\,\left[\sum\limits_{i=0}^n d_i^2 - \frac{1}{n}\left(\sum\limits_{i=0}^n d_i\right)^2\right]</math>, and the standard<br />
deviation is the square root of the variance. Using <tt>sfattr</tt><br />
is a quick way to see the distribution of data values and check it for anomalies.<br />
<br />
The output can be parsed using utilities such as <tt>awk</tt>, to extract only a numeric value for feeding it as a parameter value into a command line interface. Notice the backticks in the example below:<br />
<bash><br />
sfgrey <vel.rsf allpos=y bias=`sfattr <vel.rsf want=min | awk '{print $4}'` | xtpen<br />
</bash><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/attr.c?view=markup system/main/attr.c]====<br />
<br />
Computations start by finding the input data (<tt>in</tt>) size<br />
(<tt>nsiz</tt>) and dimensions (<tt>dim</tt>).<br />
<c><br />
dim = (size_t) sf_filedims (in,n);<br />
for (nsiz=1, i=0; i < dim; i++) {<br />
nsiz *= n[i];<br />
}<br />
</c><br />
<br />
<br />
In the main loop, we read the input data buffer by buffer.<br />
<c><br />
for (nleft=nsiz; nleft > 0; nleft -= nbuf) {<br />
nbuf = (bufsiz < nleft)? bufsiz: nleft;<br />
switch (type) {<br />
case SF_FLOAT: <br />
sf_floatread((float*) buf,nbuf,in);<br />
break;<br />
case SF_INT:<br />
sf_intread((int*) buf,nbuf,in);<br />
break;<br />
case SF_COMPLEX:<br />
sf_complexread((sf_complex*) buf,nbuf,in);<br />
break;<br />
case SF_UCHAR:<br />
sf_ucharread((unsigned char*) buf,nbuf,in);<br />
break;<br />
case SF_CHAR:<br />
default:<br />
sf_charread(buf,nbuf,in);<br />
break;<br />
}<br />
</c><br />
<br />
<br />
The data attributes are accumulated in corresponding double-precision<br />
variables. <br />
<c><br />
fsum += f;<br />
fsqr += f*f;<br />
</c><br />
<br />
<br />
Finally, the attributes are reduced and printed out.<br />
<c><br />
fmean = fsum/nsiz;<br />
if (lval==2) fnorm = sqrt(fsqr);<br />
else if (lval==0) fnorm = nsiz-nzero;<br />
else fnorm = pow(flval,1./lval);<br />
frms = sqrt(fsqr/nsiz);<br />
if (nsiz > 1) fvar = (fsqr-nsiz*fmean*fmean)/(nsiz-1);<br />
else fvar = 0.0;<br />
fstd = sqrt(fvar);<br />
</c><br />
<br />
<c><br />
if(NULL==want || 0==strcmp(want,"rms"))<br />
printf("rms = %g \n",(float) frms);<br />
if(NULL==want || 0==strcmp(want,"mean"))<br />
printf("mean value = %g \n",(float) fmean);<br />
if(NULL==want || 0==strcmp(want,"norm"))<br />
printf("%d-norm value = %g \n",lval,(float) fnorm);<br />
if(NULL==want || 0==strcmp(want,"var"))<br />
printf("variance = %g \n",(float) fvar);<br />
if(NULL==want || 0==strcmp(want,"std"))<br />
printf("standard deviation = %g \n",(float) fstd);<br />
</c><br />
<br />
==sfcat==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Concatenate datasets. <br />
|-<br />
! colspan="4" | sfcat > out.rsf space= axis=3 nspace=(int) (ni/(20*nin) + 1) [<file0.rsf] file1.rsf file2.rsf ... <br />
|-<br />
| colspan="4" | sfmerge inserts additional space between merged data.<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis being merged<br />
|-<br />
| ''int '' || '''nspace=(int) (ni/(20*nin) + 1)''' || || if space=y, number of traces to insert<br />
|-<br />
| ''bool '' || '''space=''' || [y/n] || Insert additional space.<br />
:y is default for sfmerge, n is default for sfcat<br />
|}<br />
<br />
<br />
<tt>sfcat</tt> and <tt>sfmerge</tt> concatenate two or more files<br />
together along a particular axis. It is the same program, only<br />
<tt>sfcat</tt> has the default <tt>space=n</tt> and <tt>sfmerge</tt><br />
has the default <tt>space=y</tt>.<br />
Example of <tt>sfcat</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcat one.rsf one.rsf axis=1 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=4 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
12 elements 48 bytes<br />
</pre><br />
Example of <tt>sfmerge</tt>:<br />
<pre><br />
bash$ sfmerge one.rsf one.rsf axis=2 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=7 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
14 elements 56 bytes<br />
</pre><br />
In this case, an extra empty trace is inserted between the two merged files.<br />
The axes that are not being merged are checked for consistency:<br />
<pre><br />
bash$ sfcat one.rsf two.rsf > three.rsf<br />
sfcat: n2 mismatch: need 3<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cat.c?view=markup system/main/cat.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
in = (sf_file*) sf_alloc ((size_t) argc,sizeof(sf_file));<br />
<br />
if (!sf_stdin()) { /* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Everything on the command line that does not contain a "=" sign is<br />
treated as a file name, and the corresponding file object is added to the list.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) <br />
continue; /* not a file */<br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
</c><br />
<br />
As explained above, if the <tt>space=</tt> parameter is not set, it is<br />
inferred from the program name: <tt>sfmerge</tt> corresponds to<br />
<tt>space=y</tt> and <tt>sfcat</tt> corresponds to <tt>space=n</tt>.<br />
<c><br />
if (!sf_getbool("space",&space)) {<br />
/* Insert additional space.<br />
y is default for sfmerge, n is default for sfcat */<br />
prog = sf_getprog();<br />
if (NULL != strstr (prog, "merge")) {<br />
space = true;<br />
} else if (NULL != strstr (prog, "cat")) {<br />
space = false;<br />
} else {<br />
sf_warning("%s is neither merge nor cat,"<br />
" assume merge",prog);<br />
space = true;<br />
}<br />
}<br />
</c><br />
<br />
Find the axis for the merging (from the command line <tt>axis=</tt><br />
argument) and figure out two sizes: <tt>n1</tt> for everything after<br />
the axis and <tt>n2</tt> for everything before the axis.<br />
<c><br />
n1=1;<br />
n2=1;<br />
for (i=1; i <= dim; i++) {<br />
if (i < axis) n1 *= n[i-1];<br />
else if (i > axis) n2 *= n[i-1];<br />
}<br />
</c><br />
<br />
In the output, the selected axis will get extended.<br />
<c><br />
/* figure out the length of extended axis */<br />
ni = 0;<br />
for (j=0; j < nin; j++) {<br />
ni += naxis[j];<br />
}<br />
<br />
if (space) {<br />
if (!sf_getint("nspace",&nspace)) <br />
nspace = (int) (ni/(20*nin) + 1);<br />
/* if space=y, number of traces to insert */ <br />
ni += nspace*(nin-1);<br />
} <br />
<br />
(void) snprintf(key,3,"n%d",axis);<br />
sf_putint(out,key,(int) ni);<br />
</c><br />
<br />
The rest is simple: loop through the datasets reading and writing the<br />
data in buffer-size chunks and adding extra empty chunks if<br />
<tt>space=y</tt>.<br />
<c><br />
for (i2=0; i2 < n2; i2++) {<br />
for (j=0; j < nin; j++) {<br />
for (ni = n1*naxis[j]*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charread (buf,nbuf,in[j]);<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
if (!space || j == nin-1) continue;<br />
/* Add spaces */<br />
memset(buf,0,BUFSIZ);<br />
for (ni = n1*nspace*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfcmplx==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a complex dataset from its real and imaginary parts.<br />
|-<br />
! colspan="4" | sfcmplx > cmplx.rsf real.rsf imag.rsf<br />
|-<br />
| colspan="4" | There has to be only two input files specified and no additional parameters.<br />
|}<br />
<br />
<br />
<tt>sfcmplx</tt> simply creates a complex dataset from its real and<br />
imaginary parts. The reverse operation can be accomplished with<br />
<tt>sfreal</tt> and <tt>sfimag</tt>.<br />
Example of <tt>sfcmplx</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcmplx one.rsf one.rsf > cmplx.rsf<br />
bash$ sfin cmplx.rsf<br />
cmplx.rsf:<br />
in="/tmp/cmplx.rsf@"<br />
esize=8 type=complex form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 48 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cmplx.c?view=markup system/main/cmplx.c]====<br />
The program flow is simple. First, get the names of the input files.<br />
<c><br />
/* the first two non-parameters are real and imaginary files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == real) {<br />
real = sf_input (argv[i]);<br />
} else {<br />
imag = sf_input (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == imag) {<br />
if (NULL == real) sf_error ("not enough input");<br />
/* if only one input, real is in stdin */<br />
imag = real;<br />
real = sf_input("in");<br />
}<br />
</c><br />
<br />
The main part of the program reads the real and imaginary parts buffer by buffer and assembles and writes out the complex input. <br />
<c><br />
for (nleft= (size_t) (rsize*resize); nleft > 0; nleft -= nbuf) {<br />
nbuf = (BUFSIZ < nleft)? BUFSIZ: nleft;<br />
sf_charread(rbuf,nbuf,real);<br />
sf_charread(ibuf,nbuf,imag);<br />
for (i=0; i < nbuf; i += resize) {<br />
memcpy(cbuf+2*i, rbuf+i,(size_t) resize);<br />
memcpy(cbuf+2*i+resize,ibuf+i,(size_t) resize);<br />
}<br />
sf_charwrite(cbuf,2*nbuf,cmplx);<br />
}<br />
</c><br />
<br />
==sfconjgrad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic conjugate-gradient solver for linear inversion <br />
|-<br />
! colspan="4" | sfconjgrad < dat.rsf mod=mod.rsf > to.rsf < from.rsf > out.rsf niter=1<br />
|-<br />
| ''int '' || '''niter=1''' || || number of iterations<br />
|}<br />
<br />
<tt>sfconjgrad</tt> is a generic program for least-squares linear<br />
inversion with the [http://en.wikipedia.org/wiki/Conjugate_gradient_method conjugate-gradient method]. Suppose you have an<br />
executable program <tt><prog></tt> that takes an RSF file from the<br />
standard input and produces an RSF file in the standard output. It may<br />
take any number of additional parameters but one of them must be<br />
<tt>adj=</tt> that sets the forward (<tt>adj=0</tt>) or adjoint<br />
(<tt>adj=1</tt>) operations. The program <tt><prog></tt> is typically<br />
an RSF program but it could be anything (a script, a multiprocessor<br />
MPI program, etc.) as long as it implements a linear operator<br />
<math>\mathbf{L}</math> and its adjoint. There are no restrictions on the data<br />
size or shape. You can easily test the adjointness with<br />
<tt>sfdottest</tt>. The <tt>sfconjgrad</tt> program searches for a<br />
vector <math>\mathbf{m}</math> that minimizes the least-square misfit <br />
<math>\|\mathbf{d - L\,m}\|^2</math> for the given input data vector <math>\mathbf{d}</math>. <br />
<br />
The pseudocode for <tt>sfconjgrad</tt> is given at the end of the [http://www.reproducibility.org/RSF/book/gee/lsq/paper.pdf "Model fitting with least squares" chapter] of ''Imaging Estimation by Example'' by Jon Claerbout, with the earliest form published in [http://sepwww.stanford.edu/data/media/public/oldreports/sep48/48_25.pdf "Conjugate Gradient Tutorial"] (SEP-48, 1986, same author). A simple toy implementation with a small matrix shows that this is algorithm produces the same steps as the algorithm described in equations 45-49 of [http://www.cs.cmu.edu/~quake-papers/painless-conjugate-gradient.pdf "An introduction to the Conjugate Gradient Method Without the Agonizing Pain"] by J.R. Shewchuk, 1994, when the equation <math>A^T A x = A^T b</math> (in Shewchuk's notation) is solved. Multiplying with the transpose ensures a correct solution even when matrix A is square but not symmetric, or not square at all. The program [http://www.reproducibility.org/RSF/sfcconjgrad.html sfcconjgrad] implements this algorithm for the case when inputs are complex.<br />
<br />
Here is an example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
The <tt>sfdottest</tt> program can perform the dot product test to<br />
check that the adjoint mode works correctly.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=5.28394<br />
sfdottest: L'[d]*m=5.28394<br />
</pre><br />
Your numbers may be different because <tt>sfdottest</tt> generates new<br />
random input on each run.<br />
Next, let us make some random data with <tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfnoise seed=2005 rep=y < vec.rsf > dat.rsf<br />
</pre><br />
and try to invert the filtering operation using <tt>sfconjgrad</tt>:<br />
<pre><br />
bash$ sfconjgrad sfhelicon filt=flt.rsf lag=lag.rsf \<br />
mod=vec.rsf < dat.rsf > mod.rsf niter=10<br />
sfconjgrad: iter 1 of 10<br />
sfconjgrad: grad=3253.65<br />
sfconjgrad: iter 2 of 10<br />
sfconjgrad: grad=289.421<br />
sfconjgrad: iter 3 of 10<br />
sfconjgrad: grad=92.3481<br />
sfconjgrad: iter 4 of 10<br />
sfconjgrad: grad=36.9417<br />
sfconjgrad: iter 5 of 10<br />
sfconjgrad: grad=18.7228<br />
sfconjgrad: iter 6 of 10<br />
sfconjgrad: grad=11.1794<br />
sfconjgrad: iter 7 of 10<br />
sfconjgrad: grad=7.26941<br />
sfconjgrad: iter 8 of 10<br />
sfconjgrad: grad=5.15945<br />
sfconjgrad: iter 9 of 10<br />
sfconjgrad: grad=4.23055<br />
sfconjgrad: iter 10 of 10<br />
sfconjgrad: grad=3.57495<br />
</pre><br />
The output shows that, in 10 iterations, the norm of the gradient vector decreases by almost 1000. <br />
We can check the residual misfit before<br />
<pre><br />
bash$ < dat.rsf sfattr want=norm<br />
norm value = 49.7801<br />
</pre><br />
and after<br />
<pre><br />
bash$ sfhelicon filt=flt.rsf lag=lag.rsf < mod.rsf | \<br />
sfadd scale=1,-1 dat.rsf | sfattr want=norm<br />
norm value = 5.73563<br />
</pre><br />
In 10 iterations, the misfit decreased by an order of magnitude. The<br />
result can be improved by running the program for more iterations.<br />
<br />
An equivalent implementation for complex-valued inputs is [http://www.reproducibility.org/RSF/sfcconjgrad.html sfcconjgrad]. A simple, lightweight Python implementation can be found in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/fomels/conjgrad.py?view=markup $RSFROOT/lib/conjgrad.py].<br />
<br />
==sfcp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Copy or move a dataset.<br />
|-<br />
! colspan="4" | sfcp in.rsf out.rsf<br />
|-<br />
| colspan="4" | sfcp - copy, sfmv - move.<br>Mimics standard Unix commands.<br />
|}<br />
<br />
<br />
The <tt>sfcp</tt> and <tt>sfmv</tt> command imitate the Unix<br />
<tt>cp</tt> and <tt>mv</tt> commands and serve for copying and moving<br />
RSF files. Example:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcp one.rsf two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/cp.c?view=markup system/main/cp.c]====<br />
First, we look for the two first command-line arguments that don't<br />
have the "=" character in them and consider them as the names of the<br />
input and the output files. <br />
<c><br />
/* the first two non-parameters are in and out files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == in) {<br />
infile = argv[i];<br />
in = sf_input (infile);<br />
} else {<br />
out = sf_output (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == in || NULL == out)<br />
sf_error ("not enough input");<br />
</c><br />
<br />
Next, we use library functions <font color="#cd4b19">sf_cp</font> and <font color="#cd4b19">sf_rm</font> to do the actual work.<br />
<c><br />
sf_cp(in,out);<br />
if (NULL != strstr (sf_getprog(),"mv")) <br />
sf_rm(infile,false,false,false);<br />
</c><br />
<br />
==sfcut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of the dataset. <br />
|-<br />
! colspan="4" | sfcut < in.rsf > out.rsf verb=n [j1=1 j2=1 ... f1=0 f2=0 ... n1=n1 n2=n2 ... max1= max2= ... min1= min2= ...]<br />
|-<br />
| colspan="4" | jN defines the jump in N-th dimension<br>fN is the window start<br>nN is the window size<br>minN and maxN is the maximum and minimum in N-th dimension<br><br>Reverse of window. <br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
The <tt>sfcut</tt> command is related to <tt>sfwindow</tt> and has the same<br />
set of arguments only instead of extracting the selected window, it fills it<br />
with zeroes. The size of the input data is preserved. <br />
Examples:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > in.rsf<br />
bash$ < in.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < in.rsf sfcut n1=2 f1=1 n2=3 f2=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 0 0 1 1<br />
15: 1 0 0 1 1<br />
20: 1 0 0 1 1<br />
bash$ < in.rsf sfcut j1=2 | sfdisfil<br />
0: 0 1 0 1 0<br />
5: 0 1 0 1 0<br />
10: 0 1 0 1 0<br />
15: 0 1 0 1 0<br />
20: 0 1 0 1 0<br />
</pre><br />
<br />
==sfdd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert between different formats. <br />
|-<br />
! colspan="4" | sfdd < in.rsf > out.rsf line=8 form= type= format=<br />
|-<br />
| ''string '' || '''form=''' || || ascii, native, xdr<br />
|-<br />
| ''string '' || '''format=''' || || Element format (for conversion to ASCII)<br />
|-<br />
| ''int '' || '''line=8''' || || Number of numbers per line (for conversion to ASCII)<br />
|-<br />
| ''string '' || '''type=''' || || int, float, complex<br />
|}<br />
<br />
<br />
The <tt>sfdd</tt> program is used to change either the form (<tt>ascii</tt>,<br />
<tt>xdr</tt>, <tt>native</tt>) or the type (<tt>complex</tt>, <tt>float</tt>,<br />
<tt>int</tt>, <tt>char</tt>) of the input dataset. <br />
In the example below, we create a plain text (ASCII) file with numbers and<br />
then use <tt>sfdd</tt> to generate an RSF file in <tt>xdr</tt> form with<br />
<tt>complex</tt> numbers. <br />
<pre><br />
bash$ cat test.txt<br />
1 2 3 4 5 6<br />
bash$ echo n1=6 data_format=ascii_int in=test.txt > test.rsf<br />
bash$ sfin test.rsf<br />
test.rsf:<br />
in="test.txt"<br />
esize=0 type=int form=ascii<br />
n1=6 d1=? o1=?<br />
6 elements<br />
bash$ sfdd < test.rsf form=xdr type=complex > test2.rsf<br />
bash$ sfin test2.rsf<br />
test2.rsf:<br />
in="/tmp/test2.rsf@"<br />
esize=8 type=complex form=xdr<br />
n1=3 d1=? o1=?<br />
3 elements 24 bytes<br />
bash$ sfdisfil < test2.rsf<br />
0: 1, 2i 3, 4i 5, 6i<br />
</pre><br />
To learn more about the RSF data format, consult the [[Format| guide to RSF format]].<br />
<br />
==sfdisfil==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Print out data values.<br />
|-<br />
! colspan="4" | sfdisfil < in.rsf number=y col=0 format= header= trailer=<br />
|-<br />
| colspan="4" | <br>Alternatively, use sfdd and convert to ASCII form.<br />
|-<br />
| ''int '' || '''col=0''' || || Number of columns.<br />
:The default depends on the data type:<br />
:10 for int and char,<br />
:5 for float,<br />
:3 for complex<br />
|-<br />
| ''string '' || '''format=''' || || Format for numbers (printf-style).<br />
:The default depends on the data type:<br> "%4d " for int and char,<br> "%13.4g" for float,<br> "%10.4g,%10.4gi" for complex<br />
|-<br />
| ''string '' || '''header=''' || || Optional header string to output before data<br />
|-<br />
| ''bool '' || '''number=y''' || [y/n] || If number the elements<br />
|-<br />
| ''string '' || '''trailer=''' || || Optional trailer string to output after data<br />
|}<br />
<br />
<br />
The <tt>sfdisfil</tt> program simply dumps the data contents to the standard<br />
output in a text form. It is used mostly for debugging purposes to quickly<br />
examine RSF files. Here is an example:<br />
<pre><br />
bash$ sfmath o1=0 d1=2 n1=12 output=x1 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
10: 20 22<br />
</pre><br />
The output format is easily configurable.<br />
<pre><br />
bash$ < test.rsf sfdisfil col=6 number=n format="<br />
0.0 2.0 4.0 6.0 8.0 10.0<br />
12.0 14.0 16.0 18.0 20.0 22.0<br />
</pre><br />
Along with <tt>sfdd</tt>, <tt>sfdisfil</tt> provides a simple way to convert<br />
RSF data to an ASCII form.<br />
<br />
==sfdottest==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic dot-product test for linear operators with adjoints <br />
|-<br />
! colspan="4" | sfdottest mod=mod.rsf dat=dat.rsf > pip.rsf<br />
|}<br />
<br />
<br />
<tt>sfdottest</tt> is a generic dot-product test program for testing<br />
linear operators. Suppose there is an executable program<br />
<tt><prog></tt> that takes an RSF file from the standard input and<br />
produces an RSF file in the standard output. It may take any number of<br />
additional parameters but one of them must be <tt>adj=</tt> that sets<br />
the forward (<tt>adj=0</tt>) or adjoint (<tt>adj=1</tt>) operations.<br />
The program <tt><prog></tt> is typically an RSF program but it could<br />
be anything (a script, a multiprocessor MPI program, etc.) as long as<br />
it implements a linear operator <math>\mathbf{L}</math> and its adjoint<br />
<math>\mathbf{L}^T</math>. The <tt>sfdottest</tt> program is testing the equality<br />
<center><math><br />
d^T\,L\,m = m^T\,L^T\,d<br />
</math></center><br />
by using random vectors <math>\mathbf{m}</math> and <math>\mathbf{d}</math>. You can invoke it with<br />
<pre><br />
bash$ sfdottest <prog> [optional aruments] mod=mod.rsf dat=dat.rsf<br />
</pre><br />
where <tt>mod.rsf</tt> and <tt>dat.rsf</tt> are RSF files that<br />
represent vectors from the model and data spaces. Pay attention to the <br />
dimension and size of these vectors! If the program does not respond<br />
for a very long time, it is quite possible that the dimension and size<br />
of the vectors are inconsistent with the requirement of the program to be<br />
tested. <tt>sfdottest</tt><br />
does not create any temporary files and does not have any restrictive<br />
limitations on the size of the vectors.<br />
Here is an example. We first setup a vector with 100 elements using<br />
<tt>sfspike</tt> and then run <tt>sfdottest</tt> to test the<br />
<tt>sfcausint</tt> program. <tt>sfcausint</tt> implements a linear<br />
operator of causal integration and its adjoint, the anti-causal<br />
integration.<br />
<pre><br />
bash$ sfspike n1=100 > vec.rsf<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1410.2<br />
sfdottest: L'[d]*m=1410.2<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1165.87<br />
sfdottest: L'[d]*m=1165.87<br />
</pre><br />
The numbers are different on subsequent runs because of changing<br />
seed in the random number generator.<br />
Here is a somewhat more complicated example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
Now the <tt>sfdottest</tt> program can perform the dot product test.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=8.97375<br />
sfdottest: L'[d]*m=8.97375<br />
</pre><br />
Here is the same program tested in the inverse filtering mode:<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf inv=y<br />
sfdottest: L[m]*d=15.0222<br />
sfdottest: L'[d]*m=15.0222<br />
</pre><br />
<br />
==sfget==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Output parameters from the header.<br />
|-<br />
! colspan="4" | sfget < in.rsf parform=y par1 par2 ...<br />
|-<br />
| ''bool '' || '''parform=y''' || [y/n] || If y, print out parameter=value. If n, print out value.<br />
|}<br />
<br />
<br />
The <tt>sfget</tt> program extracts a parameter value from an RSF file. It is<br />
useful mostly for scripting. Here is, for example, a quick calculation of the<br />
maximum value on the first axis in an RSF dataset (the output of<br />
<tt>sfspike</tt>) using the standard Unix <tt>bc</tt> calculator.<br />
<pre><br />
bash$ ( sfspike n1=100 | sfget n1 d1 o1; echo "o1+(n1-1)*d1" ) | bc<br />
.396<br />
</pre><br />
See also <tt>sfput</tt>.<br />
<br />
<br />
<br />
==sfheadercut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheadercut mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array of size n2.<br />
|}<br />
<br />
<br />
<tt>sfheadercut</tt> is close to <tt>sfheaderwindow</tt> but instead<br />
of windowing the dataset, it fills the traces specified by the header<br />
mask with zeroes. The size of the input data is preserved.<br />
Here is an example of using <tt>sfheaderwindow</tt> for <br />
zeroing every other trace in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a mask with alternating ones and zeros using<br />
<tt>sfinterleave</tt>.<br />
<pre><br />
bash$ sfspike n1=5 mag=1 | sfdd type=int > ones.rsf<br />
bash$ sfspike n1=5 mag=0 | sfdd type=int > zeros.rsf<br />
bash$ sfinterleave axis=1 ones.rsf zeros.rsf > mask.rsf<br />
bash$ sfdisfil < mask.rsf<br />
0: 1 0 1 0 1 0 1 0 1 0<br />
</pre><br />
Finally, <tt>sfheadercut</tt> zeros the input traces.<br />
<pre><br />
bash$ sfheadercut < input.rsf mask=mask.rsf > output.rsf<br />
bash$ sfdisfil < output.rsf <br />
0: 1 1 1 1 1<br />
5: 0 0 0 0 0<br />
10: 3 3 3 3 3<br />
15: 0 0 0 0 0<br />
20: 5 5 5 5 5<br />
25: 0 0 0 0 0<br />
30: 7 7 7 7 7<br />
35: 0 0 0 0 0<br />
40: 9 9 9 9 9<br />
45: 0 0 0 0 0<br />
</pre><br />
<br />
<br />
<br />
==sfheadersort==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Sort a dataset according to a header key. <br />
|-<br />
! colspan="4" | sfheadersort < in.rsf > out.rsf head=<br />
|-<br />
| ''string '' || '''head=''' || || header file<br />
|}<br />
<br />
<br />
<tt>sfheadersort</tt> is used to sort traces in the input file<br />
according to trace header information. <br />
Here is an example of using<br />
<tt>sfheadersort</tt> for randomly shuffling traces in the input<br />
file. First, let us create an input file with seven traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=7 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7 <br />
</pre><br />
Next, we can create a random file with seven header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=7 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: 0.05256 -0.2879 0.1487 0.4097 0.1548<br />
5: 0.4501 0.2836<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally, we<br />
apply <tt>sfheadersort</tt> to shuffle the input traces.<br />
<pre><br />
bash$ < input.rsf sfheadersort head=random.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 1 1 1 1 1<br />
10: 3 3 3 3 3<br />
15: 5 5 5 5 5<br />
20: 7 7 7 7 7<br />
25: 4 4 4 4 4<br />
30: 6 6 6 6 6<br />
</pre><br />
As expected, the order of traces in the output file corresponds to the<br />
order of values in the header. Thanks to the separation between<br />
headers and data, the operation of <tt>sfheadersort</tt> is optimally<br />
efficient. It first sorts the headers and only then accesses the data,<br />
reading each data trace only once.<br />
<br />
==sfheaderwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheaderwindow mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array os size n2, windowed is n1xm2,<br>where m2 is the number of nonzero elements in mask.<br />
|}<br />
<br />
<br />
<tt>sfheaderwindow</tt> is used to window traces in the input file<br />
according to trace header information. <br />
Here is an example of using <tt>sfheaderwindow</tt> for randomly<br />
selecting part of the traces in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a random file with ten header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=10 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: -0.005768 0.02258 -0.04331 -0.4129 -0.3909<br />
5: -0.03582 0.4595 -0.3326 0.498 -0.3517<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally,<br />
we apply <tt>sfheaderwindow</tt> to window the input traces selecting<br />
only those for which the header is greater than zero.<br />
<pre><br />
bash$ < random.rsf sfmask min=0 > mask.rsf<br />
bash$ < mask.rsf sfdisfil<br />
0: 0 1 0 0 0 0 1 0 1 0<br />
bash$ < input.rsf sfheaderwindow mask=mask.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 7 7 7 7 7<br />
10: 9 9 9 9 9<br />
</pre><br />
In this case, only three traces are selected for the output. Thanks to<br />
the separation between headers and data, the operation of<br />
<tt>sfheaderwindow</tt> is optimally efficient. <br />
<br />
==sfin==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display basic information about RSF files.<br />
|-<br />
! colspan="4" | sfin info=y check=2. trail=y file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | n1,n2,... are data dimensions<br>o1,o2,... are axis origins<br>d1,d2,... are axis sampling intervals<br>label1,label2,... are axis labels<br>unit1,unit2,... are axis units<br />
|-<br />
| ''float '' || '''check=2.''' || || Portion of the data (in Mb) to check for zero values.<br />
|-<br />
| ''bool '' || '''info=y''' || [y/n] || If n, only display the name of the data file.<br />
|-<br />
| ''bool '' || '''trail=y''' || [y/n] || If n, skip trailing dimensions of one<br />
|}<br />
<br />
<br />
<tt>sfin</tt> is one of the most useful programs for operating with<br />
RSF files. It produces quick information on the file hypercube<br />
dimensions and checks the consistency of the associated data file.<br />
Here is an example. Let us create an RSF file and examine it with <tt>sfin</tt>.<br />
<pre><br />
bash$ sfspike n1=100 n2=20 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=100 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
2000 elements 8000 bytes<br />
</pre><br />
<tt>sfin</tt> reports the following information:<br />
<br />
*location of the data file (<tt>/tmp/spike.rsf\@</tt>) <br />
*element size (4 bytes) <br />
*element type (floating point) <br />
*element form (native) <br />
*hypercube dimensions (100 by 20) <br />
*axes scale (0.004 and 0.1) <br />
*axes origin (0 and 0) <br />
*axes labels <br />
*axes units <br />
*total number of elements <br />
*total number of bytes in the data file <br />
Suppose that the file got corrupted by a buggy program and reports<br />
incorrect dimensions. The <tt>sfin</tt> program should be able to<br />
catch the discrepancy.<br />
<pre><br />
bash$ echo n2=100 >> spike.rsf<br />
bash$ sfin spike.rsf > /dev/null<br />
sfin: Actually 8000 bytes, 20% of expected.<br />
</pre><br />
<tt>sfin</tt> also checks the first records in the file for zeros. <br />
<pre><br />
bash$ sfspike n1=100 n2=100 k2=99 > spike2.rsf<br />
bash$ sfin spike2.rsf >/dev/null<br />
sfin: The first 32768 bytes are all zeros<br />
</pre><br />
The number of bytes to check is adjustable<br />
<pre><br />
bash$ sfin spike2.rsf check=0.01 >/dev/null<br />
sfin: The first 16384 bytes are all zeros<br />
</pre><br />
You can also output only the location of the data file. This is<br />
sometimes handy in scripts.<br />
<pre><br />
bash$ sfin spike.rsf spike2.rsf info=n<br />
/tmp/spike.rsf@ /tmp/spike2.rsf@<br />
</pre><br />
An alternative is to use <tt>sfget</tt>, as follows:<br />
<pre><br />
bash$ sfget parform=n in < spike.rsf<br />
/tmp/spike.rsf@<br />
</pre><br />
<br />
==sfinterleave==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Combine several datasets by interleaving.<br />
|-<br />
! colspan="4" | sfinterleave > out.rsf axis=3 [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis for interleaving<br />
|}<br />
<br />
<br />
<tt>sfinterleave</tt> combines two or more datasets by interleaving them on one<br />
of the axes. Here is a quick example:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ sfscale < one.rsf dscale=2 > two.rsf<br />
bash$ sfdisfil < two.rsf<br />
0: 2 2 2 2 2<br />
5: 2 2 2 2 2<br />
10: 2 2 2 2 2<br />
15: 2 2 2 2 2<br />
20: 2 2 2 2 2<br />
bash$ sfinterleave one.rsf two.rsf axis=1 | sfdisfil<br />
0: 1 2 1 2 1<br />
5: 2 1 2 1 2<br />
10: 1 2 1 2 1<br />
15: 2 1 2 1 2<br />
20: 1 2 1 2 1<br />
25: 2 1 2 1 2<br />
30: 1 2 1 2 1<br />
35: 2 1 2 1 2<br />
40: 1 2 1 2 1<br />
45: 2 1 2 1 2<br />
bash$ sfinterleave < one.rsf two.rsf axis=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 1 1 1 1 1<br />
15: 2 2 2 2 2<br />
20: 1 1 1 1 1<br />
25: 2 2 2 2 2<br />
30: 1 1 1 1 1<br />
35: 2 2 2 2 2<br />
40: 1 1 1 1 1<br />
45: 2 2 2 2 2<br />
</pre><br />
<br />
==sfmask==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a mask.<br />
|-<br />
! colspan="4" | sfmask < in.rsf > out.rsf min=-FLT_MAX max=+FLT_MAX<br />
|-<br />
| colspan="4" | <br>Mask is an integer data with ones and zeros. <br>Ones correspond to input values between min and max.<br><br>The output can be used with sfheaderwindow.<br />
|-<br />
| ''float '' || '''max=+FLT_MAX''' || || maximum header value<br />
|-<br />
| ''float '' || '''min=-FLT_MAX''' || || minimum header value<br />
|}<br />
<br />
<br />
<tt>sfmask</tt> creates an integer output of ones and zeros comparing<br />
the values of the input data to specified <tt>min=</tt> and<br />
<tt>max=</tt> parameters. It is useful for <tt>sfheaderwindow</tt> and<br />
in many other applications. Here is a quick example:<br />
<pre><br />
bash$ sfmath n1=10 output="sin(x1)" > sin.rsf<br />
bash$ < sin.rsf sfdisfil<br />
0: 0 0.8415 0.9093 0.1411 -0.7568<br />
5: -0.9589 -0.2794 0.657 0.9894 0.4121<br />
bash$ < sin.rsf sfmask min=-0.5 max=0.5 | sfdisfil<br />
0: 1 0 0 1 0 0 1 0 0 1<br />
</pre><br />
<br />
==sfmath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations on data files.<br />
|-<br />
! colspan="4" | sfmath > out.rsf type= unit= output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs, conj (for complex data).<br> <br>sfmath will work on float or complex data, but all the input and output<br>files must be of the same data type.<br><br>An alternative to sfmath is sfadd, which may be more efficient, but is<br>less versatile.<br><br>Examples:<br><br>sfmath x=file1.rsf y=file2.rsf power=file3.rsf output='sin((x+2*y)^power)' > out.rsf<br>sfmath < file1.rsf tau=file2.rsf output='exp(tau*input)' > out.rsf<br>sfmath n1=100 type=complex output="exp(I*x1)" > out.rsf<br><br>See also: sfheadermath.<br />
|-<br />
| ''string '' || '''output=''' || || Mathematical description of the output<br />
|-<br />
| ''string '' || '''type=''' || || output data type [float,complex]<br />
|-<br />
| ''string '' || '''unit=''' || || <br />
|}<br />
<br />
<tt>sfmath</tt> is a versatile program for mathematical operations<br />
with RSF files. It can operate with several input file, all of the<br />
same dimensions and data type. The data type can be real (floating<br />
point) or complex. Here is an example that demonstrates several<br />
features of <tt>sfmath</tt>.<br />
<pre><br />
bash$ sfmath n1=629 d1=0.01 o1=0 n2=40 d2=1 o2=5 \<br />
output="x2*(8+sin(6*x1+x2/10))" > rad.rsf<br />
bash$ < rad.rsf sfrtoc | sfmath output="input*exp(I*x1)" > rose.rsf<br />
bash$ < rose.rsf sfgraph title=Rose screenratio=1 wantaxis=n | sfpen<br />
</pre><br />
The first line creates a 2-D dataset that consists of 40 traces 600<br />
samples each. The values of the data are computed with the formula<br />
<font color="#cd4b19">"x2*(8+sin(6*x1+x2/10))"</font>, where <tt>x1</tt> refers to the<br />
coordinate on the first axis, and <tt>x2</tt> is the coordinate of the<br />
second axis. In the second line, we convert the data from real to<br />
complex using <tt>sfrtoc</tt> and produce a complex dataset using<br />
formula <font color="#cd4b19">"input*exp(I*x1)"</font>, where <tt>input</tt> refers to the<br />
input file. Finally, we plot the complex data as a collection of<br />
parametric curves using <tt>sfgraph</tt> and display the result using<br />
<tt>sfpen</tt>. The plot appearing on your screen should look similar<br />
to the figure.<br />
[[Image:rose.png|frame|center|This figure was created with <tt>sfmath</tt>.]]<br />
One possible alternative to the second line above is<br />
<pre><br />
bash$ < rad.rsf sfmath output=x1 > ang.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*cos(a)" > cos.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*sin(a)" > sin.rsf<br />
bash$ sfcmplx cos.rsf sin.rsf > rose.rsf<br />
</pre><br />
Here we refer to input files by names (<tt>r</tt> and <tt>a</tt>) and combine the names in a formula.<br />
<br />
==sfpad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Pad a dataset with zeros.<br />
|-<br />
! colspan="4" | sfpad < in.rsf > out.rsf [beg1= beg2= ... end1= end2=... | n1= n2 = ... | n1out= n2out= ...]<br />
|-<br />
| colspan="4" | begN specifies the number of zeros to add before the beginning of axis N.<br>endN specifies the number of zeros to add after the end of axis N.<br><br>Alternatively:<br><br>nN or nNout specify the output length of axis N, padding occurs at the end.<br>nN and nNout are equivalent.<br />
|}<br />
<br />
<br />
<tt>pad</tt> increases the dimensions of the input dataset by padding<br />
the data with zeroes. Here are some simple examples.<br />
<pre><br />
bash$ sfspike n1=5 n2=3 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
bash$ < one.rsf sfpad n2=5 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 0 0 0 0 0<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfpad beg2=2 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 0 0 0 0<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < one.rsf sfpad beg2=1 end2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfwindow n1=3 | sfpad n1=5 n2=5 beg1=1 beg2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 1 1 1 0<br />
10: 0 1 1 1 0<br />
15: 0 1 1 1 0<br />
20: 0 0 0 0 0<br />
</pre><br />
You can use <tt>sfcat</tt> to pad data with values other than zeroes.<br />
<br />
==sfput==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Input parameters into a header. <br />
|-<br />
! colspan="4" | sfput < in.rsf > out.rsf<br />
|}<br />
<br />
<br />
<tt>sfput</tt> is a very simple program. It simply appends parameters<br />
from the command line to the output RSF file. One can achieve similar<br />
results with editing by hand or with standard Unix utilities like<br />
<tt>sed</tt> and <tt>echo</tt>. <tt>sfput</tt> is sometimes more<br />
convenient because it handles input/output operations similarly to<br />
other regular RSF programs.<br />
<pre><br />
bash$ sfspike n1=10 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
10 elements 40 bytes<br />
bash$ sfput < spike.rsf d1=25 label1=Depth unit1=m > spike2.rsf<br />
bash$ sfin spike2.rsf<br />
spike2.rsf:<br />
in="/tmp/spike2.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=25 o1=0 label1="Depth" unit1="m"<br />
10 elements 40 bytes<br />
</pre><br />
<br />
==sfreal==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extract real (sfreal) or imaginary (sfimag) part of a complex dataset. <br />
|-<br />
! colspan="4" | sfreal < cmplx.rsf > real.rsf<br />
|}<br />
<br />
<br />
<tt>sfreal</tt> extracts the real part of a complex type dataset. The<br />
imaginary part can be extracted with <tt>sfimag</tt>, an the real<br />
and imaginary part can be combined together with <tt>sfcmplx</tt>.<br />
Here is a simple example. Let us first create a complex dataset <br />
with <tt>sfmath</tt><br />
<pre><br />
bash$ sfmath n1=10 type=complex output="(2+I)*x1" > cmplx.rsf<br />
bash$ fdisfil < cmplx.rsf<br />
0: 0, 0i 2, 1i 4, 2i<br />
3: 6, 3i 8, 4i 10, 5i<br />
6: 12, 6i 14, 7i 16, 8i<br />
9: 18, 9i<br />
</pre><br />
Extracting the real part with <tt>sfreal</tt>:<br />
<pre><br />
bash$ sfreal < cmplx.rsf | sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
</pre><br />
Extracting the imaginary part with <tt>sfimag</tt>:<br />
<pre><br />
bash$ sfimag < cmplx.rsf | sfdisfil<br />
0: 0 1 2 3 4<br />
5: 5 6 7 8 9<br />
</pre><br />
<br />
==sfreverse==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Reverse one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfreverse < in.rsf > out.rsf which=-1 verb=false memsize=sf_memsize() opt=<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''opt=''' || || If y, change o and d parameters on the reversed axis;<br />
:if i, don't change o and d<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|-<br />
| ''int '' || '''which=-1''' || || Which axis to reverse.<br />
:To reverse a given axis, start with 0,<br />
:add 1 to number to reverse n1 dimension,<br />
:add 2 to number to reverse n2 dimension,<br />
:add 4 to number to reverse n3 dimension, etc.<br />
:Thus, which=7 would reverse the first three dimensions,<br />
:which=5 just n1 and n3, etc.<br />
:which=0 will just pass the input on through unchanged.<br />
|}<br />
Here is an example of using <tt>sfreverse</tt>. First, let us create a<br />
2-D dataset.<br />
<pre><br />
bash$ sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Reversing the first axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 | sfdisfil<br />
0: 4 3 2 1 0<br />
5: 5 4 3 2 1<br />
10: 6 5 4 3 2<br />
</pre><br />
Reversing the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=2 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
Reversing both the first and the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=3 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
As you can see, the <tt>which=</tt> parameter controls the axes that are<br />
being reversed by encoding them into one number.<br />
When an axis is reversed, what happens with its axis origin and<br />
sampling parameters? This behavior is controlled by <tt>opt=</tt>. In<br />
our example,<br />
<pre><br />
bash$ < test.rsf sfget n1 o1 d1<br />
n1=5<br />
o1=0<br />
d1=1<br />
bash$ < test.rsf sfreverse which=1 | sfget o1 d1<br />
o1=4<br />
d1=-1<br />
</pre><br />
The default behavior (equivalent to <tt>opt=y</tt>) puts the origin<br />
<tt>o1</tt> at the end of the axis and reverses the sampling parameter<br />
<tt>d1</tt>. Using <tt>opt=n</tt> preserves the sampling but reverses<br />
the origin.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=n | sfget o1 d1<br />
o1=-4<br />
d1=1<br />
</pre><br />
Using <tt>opt=i</tt> preserves both the sampling and the origin while<br />
reversing the axis.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=i | sfget o1 d1<br />
o1=0<br />
d1=1<br />
</pre><br />
One of the three possible behaviors may be desirable depending on the<br />
application.<br />
<br />
==sfrm==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Remove RSF files together with their data.<br />
|-<br />
! colspan="4" | sfrm file1.rsf [file2.rsf ...] [-i] [-v] [-f] <br />
|-<br />
| colspan="4" | Mimics the standard Unix rm command.<br><br>See also: sfmv, sfcp.<br />
|}<br />
<br />
<tt>sfrm</tt> is a program for removing RSF files. Its arguments mimic<br />
the arguments of the standard Unix <tt>rm</tt> utility: <tt>-v</tt><br />
for verbosity, <tt>-i</tt> for interactive inquiry, <tt>-f</tt> for<br />
force removal of suspicious files. Unlike the Unix <tt>rm</tt>,<br />
<tt>sfrm</tt> removes both the RSF header files and the binary files<br />
that the headers point to. <br />
Example:<br />
<pre><br />
bash&#36; sfspike n1=10 > spike.rsf datapath=./<br />
bash&#36; sfget in < spike.rsf<br />
in=./spike.rsf@<br />
bash&#36; ls spike*<br />
spike.rsf spike.rsf@<br />
bash&#36; sfrm -v spike.rsf<br />
sfrm: sf_rm: Removing header spike.rsf<br />
sfrm: sf_rm: Removing data ./spike.rsf@<br />
bash&#36; ls spike*<br />
ls: No match.<br />
</pre><br />
==sfrotate==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Rotate a portion of one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfrotate < in.rsf > out.rsf verb=n memsize=sf_memsize() rot#=(0,0,...)<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''rot#=(0,0,...)''' || || length of #-th axis that is moved to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<tt>sfrotate</tt> modifies the input dataset by splitting it into<br />
parts and putting the parts back in a different order. Here is a quick example.<br />
<pre><br />
bash&#36; sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Rotating the first axis by putting the last two columns in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=2 | sfdisfil<br />
0: 3 4 0 1 2<br />
5: 4 5 1 2 3<br />
10: 5 6 2 3 4<br />
</pre><br />
Rotating the second axis by putting the last row in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot2=1 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 0 1 2 3 4<br />
10: 1 2 3 4 5<br />
</pre><br />
Rotating both the first and the second axis:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=3 rot2=1 | sfdisfil<br />
0: 4 5 6 2 3<br />
5: 2 3 4 0 1<br />
10: 3 4 5 1 2<br />
</pre><br />
The transformation is shown schematically in Figure~(fig:rotate).<br />
[[Image:rotate.png|frame|center|Schematic transformation of data with <tt>sfrotate</tt>.]]<br />
<br />
==sfrtoc==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert real data to complex (by adding zero imaginary part).<br />
|-<br />
! colspan="4" | sfrtoc < real.rsf > cmplx.rsf<br />
|-<br />
| colspan="4" | <br>See also: sfcmplx<br />
|}<br />
The input to <tt>sfrtoc</tt> can be any <tt>type=float</tt> dataset:<br />
<pre><br />
bash$ sfspike n1=10 n2=20 n3=30 >real.rsf<br />
bash$ sfin real.rsf<br />
real.rsf:<br />
in="/var/tmp/real.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
</pre><br />
The output dataset will have <tt>type=complex</tt>, and its binary will be twice the size of the input:<br />
<pre><br />
bash$ <real.rsf sfrtoc >complex.rsf<br />
bash$ sfin complex.rsf <br />
complex.rsf:<br />
in="/var/tmp/complex.rsf@"<br />
esize=8 type=complex form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 48000 bytes<br />
</pre><br />
<br />
==sfscale==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Scale data.<br />
|-<br />
! colspan="4" | sfscale < in.rsf > out.rsf axis=0 rscale=0. dscale=1.<br />
|-<br />
| colspan="4" | <br>To scale by a constant factor, you can also use sfmath or sfheadermath.<br />
|-<br />
| ''int '' || '''axis=0''' || || Scale by maximum in the dimensions up to this axis.<br />
|-<br />
| ''float '' || '''dscale=1.''' || || Scale by this factor (works if rscale=0)<br />
|-<br />
| ''float '' || '''rscale=0.''' || || Scale by this factor.<br />
|}<br />
<tt>sfscale</tt> scales the input dataset by a factor. Here<br />
are some simple examples. First, let us create a test dataset.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil <br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Scale every data point by 2:<br />
<pre><br />
bash&#36; < test.rsf sfscale dscale=2 | sfdisfil<br />
0: 2 4 6 8 10<br />
5: 4 8 12 16 20<br />
10: 6 12 18 24 30<br />
</pre><br />
Divide every trace by its maximum value:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=1 | sfdisfil<br />
0: 0.2 0.4 0.6 0.8 1<br />
5: 0.2 0.4 0.6 0.8 1<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
Divide by the maximum value in the whole 2-D dataset:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=2 | sfdisfil<br />
0: 0.06667 0.1333 0.2 0.2667 0.3333<br />
5: 0.1333 0.2667 0.4 0.5333 0.6667<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
The <tt>rscale=</tt> parameter is synonymous to <tt>dscale=</tt> except<br />
when it is equal to zero. With <tt>sfscale dscale=0</tt>, the dataset gets<br />
multiplied by zero. If using <tt>rscale=0</tt>, the other parameters are<br />
used to define scaling. Thus, <tt>sfscale rscale=0 axis=1</tt> is<br />
equivalent to <tt>sfscale axis=1</tt>, and <tt>sfscale rscale=0</tt><br />
is equivalent to <tt>sfscale dscale=1</tt>.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
==sfspike==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate simple data: spikes, boxes, planes, constants.<br />
|-<br />
! colspan="4" | sfspike > spike.rsf mag= nsp=1 k#=[0,...] l#=[k1,k2,...] p#=[0,...] n#= o#=(0,...) d#=(0.004,0.1,0.1,...) label#=(Time,Distance,Distance,...) unit#=[s,km,km,...] title=<br />
|-<br />
| ''float '' || '''d#=(0.004,0.1,0.1,...)''' || || sampling on #-th axis<br />
|-<br />
| ''ints '' || '''k#=[0,...]''' || || spike starting position [nsp]<br />
|-<br />
| ''ints '' || '''l#=[k1,k2,...]''' || || spike ending position [nsp]<br />
|-<br />
| ''string '' || '''label#=(Time,Distance,Distance,...)''' || || label on #-th axis<br />
|-<br />
| ''floats '' || '''mag=''' || || spike magnitudes [nsp]<br />
|-<br />
| ''int '' || '''n#=''' || || dimension of #-th axis<br />
|-<br />
| ''int '' || '''nsp=1''' || || Number of spikes<br />
|-<br />
| ''float '' || '''o#=(0,...)''' || || origin on #-th axis<br />
|-<br />
| ''floats '' || '''p#=[0,...]''' || || spike inclination (in samples) [nsp]<br />
|-<br />
| ''string '' || '''title=''' || || title for plots<br />
|-<br />
| ''string '' || '''unit#=[s,km,km,...]''' || || unit on #-th axis<br />
|}<br />
This is the program for creating a RSF hypercube out of nothing. Calling <tt>sfspike</tt> without specifying the k# or l# parameters will result in a volume filled with values specified by <tt>mag</tt>. To get a file full of 1's, just give <tt>sfspike</tt> the axis values that running <tt>sfin</tt> on your desired output would produce. I.e. if you run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" > out.rsf<br />
</pre><br />
you will obtain the following file:<br />
<pre><br />
bash$ sfin out.rsf<br />
out.rsf:<br />
in="/var/tmp/out.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
300 elements 1200 bytes<br />
</pre><br />
To create a "flat reflector" in the file above, run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5> out2.rsf<br />
</pre><br />
Notice that the values for <tt>k</tt> and <tt>l</tt> are in samples, not in the physical units of the respective axes. The result can be visualised with <br />
<pre><br />
< out2.rsf sfgrey pclip=100 wantscalebar=y title="Illustration of k,l parameters" | xtpen<br />
</pre><br />
which produces the following plot:<br />
<br />
[[Image:sfspike_fig1.png]]<br />
<br />
The <tt>p</tt> parameters can be used to create slanted lines/planes. Specifying <tt>p2=1</tt> means that for each lateral step, the spike will be shifted down with 1 sample. Below is the command and the corresponding graphical output it creates:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=1 |\<br />
sfgrey pclip=100 wantscalebar=y title="Effect of p2=1" | xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig2.png]]<br />
<br />
Sfspike also supports negative and non-integer p values:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=-0.15 |\<br />
sfgrey pclip=100 wantscalebar=y allpos=y color=h title="Effect of p2=-0.15" |xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig3.png]]<br />
<br />
When <tt>nsp</tt> is greater than the number of values for <tt>k</tt> and <tt>l</tt> parameters, the extra spikes will be piled on top of the last one, increasing its amplitude. Look at the amplitude of the last event in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=3 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
and in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=5 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
(pictures coming soon). This feature can easily cause a bug when the number of events is large and they have not been properly counted, or when a new spike was added on a list but <tt>nsp</tt> was not updated.<br />
<br />
==sfspray==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extend a dataset by duplicating in the specified axis dimension.<br />
|-<br />
! colspan="4" | sfspray < in.rsf > out.rsf axis=2 n= d= o= label= unit=<br />
|-<br />
| colspan="4" | This operation is adjoint to sfstack.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to spray<br />
|-<br />
| ''float '' || '''d=''' || || Sampling of the newly created dimension<br />
|-<br />
| ''string '' || '''label=''' || || Label of the newly created dimension<br />
|-<br />
| ''int '' || '''n=''' || || Size of the newly created dimension<br />
|-<br />
| ''float '' || '''o=''' || || Origin of the newly created dimension<br />
|-<br />
| ''string '' || '''unit=''' || || Units of the newly created dimension<br />
|}<br />
<br />
<tt>sfspray</tt> extends the input hypercube by replicating the data<br />
in one of the dimensions. The output dataset acquires one additional<br />
dimension. Here is an example:<br />
Start with a 2-D dataset<br />
<pre><br />
bash&#36; sfmath n1=5 n2=2 output=x1+x2 > test.rsf<br />
bash&#36; sfin test.rsf<br />
test.rsf:<br />
in="/var/tmp/test.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
10 elements 40 bytes<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
</pre><br />
Extend the data in the second dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=2 n=3 > test2.rsf<br />
bash&#36; sfin test2.rsf<br />
test2.rsf:<br />
in="/var/tmp/test2.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=3 d2=1 o2=0 <br />
n3=2 d3=1 o3=0 <br />
30 elements 120 bytes<br />
bash&#36; < test2.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 0 1 2 3 4<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
20: 1 2 3 4 5<br />
25: 1 2 3 4 5<br />
</pre><br />
The output is three-dimensional, with traces from the original<br />
data duplicated along the second axis.<br />
Extend the data in the third dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=3 n=2 > test3.rsf<br />
bash&#36; sfin test3.rsf<br />
test3.rsf:<br />
in="/var/tmp/test3.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
n3=2 d3=? o3=? <br />
20 elements 80 bytes<br />
bash&#36; < test3.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
</pre><br />
The output is also three-dimensional, with the original data replicated<br />
along the third axis.<br />
<br />
==sfstack==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stack a dataset over one of the dimensions.<br />
|-<br />
! colspan="4" | sfstack < in.rsf > out.rsf axis=2 rms=n norm=y min=n max=n<br />
|-<br />
| colspan="4" | <br>This operation is adjoint to sfspray.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to stack<br />
|-<br />
| ''bool '' || '''max=n''' || [y/n] || If y, find maximum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''min=n''' || [y/n] || If y, find minimum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || If y, normalize by fold.<br />
|-<br />
| ''bool '' || '''rms=n''' || [y/n] || If y, compute the root-mean-square instead of stack.<br />
|}<br />
While <tt>sfspray</tt> adds a dimension to a hypercube,<br />
<tt>sfstack</tt> effectively removes one of the dimensions by stacking<br />
over it. Here are some examples:<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
bash&#36; < test.rsf sfstack axis=2 | sfdisfil<br />
0: 1.5 2 3 4 5<br />
bash&#36; < test.rsf sfstack axis=1 | sfdisfil<br />
0: 2.5 3 4<br />
</pre><br />
Why is the first value not 1 (in the first case) or 2 (in the second<br />
case)? By default, <tt>sfstack</tt> normalizes the stack by the fold<br />
(the number of non-zero entries). To avoid normalization, use<br />
<tt>norm=n</tt>, as follows:<br />
<pre><br />
bash&#36; < test.rsf sfstack norm=n | sfdisfil <br />
0: 3 6 9 12 15<br />
</pre><br />
<tt>sfstack</tt> can also compute root-mean-square values as <br />
well as minimum and maximum values.<br />
<pre><br />
bash&#36; < test.rsf sfstack rms=y | sfdisfil<br />
0: 1.581 2.16 3.109 4.082 5.066<br />
bash&#36; < test.rsf sfstack min=y | sfdisfil<br />
0: 0 1 2 3 4<br />
bash&#36; < test.rsf sfstack axis=1 max=y | sfdisfil <br />
0: 4 5 6<br />
</pre><br />
<br />
==sftransp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Transpose two axes in a dataset. <br />
|-<br />
! colspan="4" | sftransp < in.rsf > out.rsf memsize=sf_memsize() plane=<br />
|-<br />
| colspan="4" | <br>If you get a "Cannot allocate memory" error, give the program a<br>memsize=1 command-line parameter to force out-of-core operation.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''plane=''' || || Two-digit number with axes to transpose. The default is 12<br />
|}<br />
<br />
The <tt>sftransp</tt> program transposes the input hypercube<br />
exchanging the two axes specified by the <b>plane=</b> parameter. <br />
<pre><br />
bash&#36; sfspike n1=10 n2=20 n3=30 > orig123.rsf<br />
bash&#36; sfin orig123.rsf <br />
orig123.rsf:<br />
in="/var/tmp/orig123.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=23 >out132.rsf<br />
bash&#36; sfin out132.rsf <br />
out132.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=20 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=13 >out321.rsf<br />
bash&#36; sfin out321.rsf <br />
out321.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=30 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=10 d3=0.004 o3=0 label3="Time" unit3="s" <br />
6000 elements 24000 bytes<br />
</pre><br />
<tt>sftransp</tt> tries to fit the dataset in memory to transpose it<br />
there but, if not enough memory is available, it performs a slower<br />
transpose out of core using disk operations. You can control the<br />
amount of available memory using the <b>memsize=</b> parameter or<br />
the <b>RSFMEMSIZE</b> environmental variable.<br />
<br />
==sfwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a portion of the dataset. <br />
|-<br />
! colspan="4" | sfwindow < in.rsf > out.rsf verb=n squeeze=y j#=(1,...) d#=(d1,d2,...) f#=(0,...) min#=(o1,o2,,...) n#=(0,...) max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)<br />
|-<br />
| ''float '' || '''d#=(d1,d2,...)''' || || sampling in #-th dimension<br />
|-<br />
| ''int '' || '''f#=(0,...)''' || || window start in #-th dimension<br />
|-<br />
| ''int '' || '''j#=(1,...)''' || || jump in #-th dimension<br />
|-<br />
| ''float '' || '''max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)''' || || maximum in #-th dimension<br />
|-<br />
| ''float '' || '''min#=(o1,o2,,...)''' || || minimum in #-th dimension<br />
|-<br />
| ''int '' || '''n#=(0,...)''' || || window size in #-th dimension<br />
|-<br />
| ''bool '' || '''squeeze=y''' || [y/n] || if y, squeeze dimensions equal to 1 to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
<b>sfwindow</b> is used to window a portion of the dataset. Here is<br />
a quick example: Start by creating some data.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Now window the first two rows:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n2=2 | sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
</pre><br />
Window the first three columns:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n1=3 | sfdisfil<br />
0: 1 2 3 2 4<br />
5: 6 3 6 9<br />
</pre><br />
Window the middle row:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f2=1 n2=1 | sfdisfil<br />
0: 2 4 6 8 10<br />
</pre><br />
You can interpret the <b>f#</b> and <b>n#</b> parameters as<br />
meaning "skip that many rows/columns" and "select that many<br />
rows/columns" correspondingly. Window the middle point in the dataset:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f1=2 n1=1 f2=1 n2=1 | sfdisfil<br />
0: 6<br />
</pre><br />
Window every other column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=2 | sfdisfil<br />
0: 1 3 5 2 6<br />
5: 10 3 9 15<br />
</pre><br />
Window every third column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=3 | sfdisfil<br />
0: 1 4 2 8 3<br />
5: 12<br />
</pre><br />
Alternatively, <b>sfwindow</b> can use the minimum and maximum<br />
parameters to select a window. In the following example, we are<br />
creating a dataset with <b>sfspike</b> and then windowing a portion of it<br />
between 1 and 2 seconds in time and sampled at 8 miliseconds.<br />
<pre><br />
bash&#36; sfspike n1=1000 n2=10 > spike.rsf <br />
bash&#36; sfin spike.rsf<br />
spike.rsf:<br />
in="/var/tmp/spike.rsf@"<br />
esize=4 type=float form=native <br />
n1=1000 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10000 elements 40000 bytes<br />
bash&#36; < spike.rsf sfwindow min1=1 max1=2 d1=0.008 > window.rsf<br />
bash&#36; sfin window.rsf<br />
window.rsf:<br />
in="/var/tmp/window.rsf@"<br />
esize=4 type=float form=native <br />
n1=126 d1=0.008 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
1260 elements 5040 bytes<br />
</pre><br />
By default, <b>sfwindow</b> "squeezes" the hypercube dimensions<br />
that are equal to one toward the end of the dataset. Here is an<br />
example of taking a time slice:<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=1 d2=0.004 o2=1 label2="Time" unit2="s" <br />
10 elements 40 bytes<br />
</pre><br />
You can change this behavior by specifying <b>squeeze=n</b>.<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 squeeze=n > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=1 d1=0.004 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10 elements 40 bytes<br />
</pre><br />
<br />
=Seismic programs=<br />
Programs in this category are specific for operations on seismic data. The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/seismic/ system/seismic] in the Madagascar distribution.<br />
<br />
==sfheaderattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Integer header attributes. <br />
|-<br />
! colspan="4" | sfheaderattr < head.rsf<br />
|-<br />
| colspan="4" | <br>Only nonzero values are reported.<br />
|}<br />
<br />
The <tt>sfheaderattr</tt> examines the contents of a trace header file,<br />
typically generated by <tt>sfsegyread</tt>. In the example below, we examine<br />
trace headers in the output of <tt>suplane</tt>, a program from Seismic Unix.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
bash$ sfheaderattr < tfile.rsf<br />
*******************************************<br />
71 headers, 32 traces<br />
key[0]="tracl" min[0]=1 max[31]=32 mean=16.5<br />
key[1]="tracr" min[0]=1 max[31]=32 mean=16.5<br />
key[11]="offset" min[0]=400 max[31]=400 mean=400<br />
key[38]="ns" min[0]=64 max[31]=64 mean=64<br />
key[39]="dt" min[0]=4000 max[31]=4000 mean=4000<br />
*******************************************<br />
</pre><br />
For different standard keywords, a minimum, maximum, and mean values<br />
are reported unless they are identically zero. This quick inspection<br />
can help in identifying meaningful keywords set in the data. The input<br />
data type must be <tt>int</tt>.<br />
<br />
==sfheadermath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations, possibly on header keys. <br />
|-<br />
! colspan="4" | sfheadermath < in.rsf > out.rsf memsize=sf_memsize() output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs<br><br>See also sfmath. <br><br>An addition operation can be performed by sfstack.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''output=''' || || Describes the output in a mathematical notation.<br />
|}<br />
<tt>sfheadermath</tt> is a versatile program for mathematical<br />
operations on rows of the input file. If the input file is an<br />
<tt>n1</tt> by <tt>n2</tt> matrix, the output will be a <tt>1</tt> by<br />
<tt>n2</tt> matrix that contains one row made out of mathematical<br />
operations on the other rows. <tt>sfheadermath</tt> can identify a row<br />
by number or by a standard SEGY keyword. The latter is useful for<br />
processing headers extracted from SEGY or SU files.<br />
Here is an example. First, we create an SU file with <tt>suplane</tt> and convert it to RSF using <tt>sfsegyread</tt>.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
</pre><br />
The trace header information is saved in <tt>tfile.rsf</tt>. It<br />
contains 71 headers for 32 traces in integer format.<br />
<pre><br />
bash$ sfin tfile.rsf<br />
tfile.rsf:<br />
in="/tmp/tfile.rsf@"<br />
esize=4 type=int form=native<br />
n1=71 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
2272 elements 9088 bytes<br />
</pre><br />
Next, we will convert <tt>tfile.rsf</tt> to a floating-point format<br />
and run <tt>sfheadermath</tt> to create a new header.<br />
<pre><br />
bash$ < tfile.rsf sfdd type=float | \<br />
sfheadermath myheader=1 output="sqrt(myheader+(2+10*offset^2))" > new.rsf<br />
bash$ sfin new.rsf<br />
new.rsf:<br />
in="/tmp/new.rsf@"<br />
esize=4 type=float form=native<br />
n1=1 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
32 elements 128 bytes<br />
</pre><br />
We defined "myheader" as being the row number 1 in the input (note<br />
that numbering starts with 0) and combined it with "offset", which<br />
is a standard SEGY keyword that denotes row number 11 (see the output<br />
of <tt>sfheaderattr</tt> above.) A variety of mathematical expressions<br />
can be defined in the <tt>output=</tt> string. The expression<br />
processing engine is shared with <tt>sfmath</tt>.<br />
<br />
==sfsegyheader==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Make a trace header file for segywrite.<br />
|-<br />
! colspan="4" | sfsegyheader < in.rsf > out.rsf n1= d1=<br />
|-<br />
| colspan="4" | <br> Use the output for tfile= argument in segywrite.<br />
|-<br />
| ''float '' || '''d1=''' || || trace sampling<br />
|-<br />
| ''int '' || '''n1=''' || || number of samples in a trace<br />
|}<br />
<br />
==sfsegyread==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert a SEG-Y or SU dataset to RSF.<br />
|-<br />
! colspan="4" | sfsegyread mask=msk.rsf > out.rsf tfile=hdr.rsf verb=false su=false format=sf_segyformat (bhead) ns=sf_segyns (bhead) endian= tape= read= hfile= bfile= mask= tfile=<br />
|-<br />
| colspan="4" | <br>Data headers and trace headers are separated from the data.<br><br>Defined SEG-Y trace header key names and byte offsets:<br><br>tracl: trace sequence number within line 0<br><br>tracr: trace sequence number within reel 4<br><br>fldr: field record number 8 <br><br>tracf: trace number within field record 12 <br><br>ep: energy source point number 16 <br><br>cdp: CDP ensemble number 20 <br><br>cdpt: trace number within CDP ensemble 24 <br><br>trid: trace identification code:<br>1 = seismic data<br>2 = dead<br>3 = dummy<br>4 = time break<br>5 = uphole<br>6 = sweep<br>7 = timing<br>8 = water break<br>9---, N = optional use (N = 32,767) 28 <br><br>nvs: number of vertically summed traces 30 <br><br>nhs: number of horizontally summed traces 32 <br><br>duse: data use:<br>1 = production<br>2 = test 34<br><br>offset: distance from source point to receiver<br>group (negative if opposite to direction<br>in which the line was shot) 36 <br><br>gelev: receiver group elevation from sea level<br>(above sea level is positive) 40 <br><br>selev: source elevation from sea level<br>(above sea level is positive) 44 <br><br>sdepth: source depth (positive) 48 <br><br>gdel: datum elevation at receiver group 52 <br><br>sdel: datum elevation at source 56 <br><br>swdep: water depth at source 60 <br><br>gwdep: water depth at receiver group 64 <br><br>scalel: scale factor for previous 7 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 68 <br><br>scalco: scale factor for next 4 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 70 <br><br>sx: X source coordinate 72 <br><br>sy: Y source coordinate 76 <br><br>gx: X group coordinate 80 <br><br>gy: Y group coordinate 84 <br><br>counit: coordinate units code:<br>for previoius four entries<br>1 = length (meters or feet)<br>2 = seconds of arc (in this case, the<br>X values are unsigned intitude and the Y values<br>are latitude, a positive value designates<br>the number of seconds east of Greenwich<br>or north of the equator 88 <br><br>wevel: weathering velocity 90 <br><br>swevel: subweathering velocity 92 <br><br>sut: uphole time at source 94 <br><br>gut: uphole time at receiver group 96 <br><br>sstat: source static correction 98 <br><br>gstat: group static correction 100 <br><br>tstat: total static applied 102 <br><br>laga: lag time A, time in ms between end of 240-<br>byte trace identification header and time<br>break, positive if time break occurs after<br>end of header, time break is defined as<br>the initiation pulse which maybe recorded<br>on an auxiliary trace or as otherwise<br>specified by the recording system 104 <br><br>lagb: lag time B, time in ms between the time<br>break and the initiation time of the energy source,<br>may be positive or negative 106 <br><br>delrt: delay recording time, time in ms between<br>initiation time of energy source and time<br>when recording of data samples begins<br>(for deep water work if recording does not<br>start at zero time) 108 <br><br>muts: mute time--start 110 <br><br>mute: mute time--end 112 <br><br>ns: number of samples in this trace 114 <br><br>dt: sample interval, in micro-seconds 116 <br><br>gain: gain type of field instruments code:<br>1 = fixed<br>2 = binary<br>3 = floating point<br>4 ---- N = optional use 118 <br><br>igc: instrument gain constant 120 <br><br>igi: instrument early or initial gain 122 <br><br>corr: correlated:<br>1 = no<br>2 = yes 124 <br><br>sfs: sweep frequency at start 126 <br><br>sfe: sweep frequency at end 128 <br><br>slen: sweep length in ms 130 <br><br>styp: sweep type code:<br>1 = linear<br>2 = cos-squared<br>3 = other 132 <br><br>stas: sweep trace length at start in ms 134 <br><br>stae: sweep trace length at end in ms 136 <br><br>tatyp: taper type: 1=linear, 2=cos^2, 3=other 138 <br><br>afilf: alias filter frequency if used 140 <br><br>afils: alias filter slope 142 <br><br>nofilf: notch filter frequency if used 144 <br><br>nofils: notch filter slope 146 <br><br>lcf: low cut frequency if used 148 <br><br>hcf: high cut frequncy if used 150 <br><br>lcs: low cut slope 152 <br><br>hcs: high cut slope 154 <br><br>year: year data recorded 156 <br><br>day: day of year 158 <br><br>hour: hour of day (24 hour clock) 160 <br><br>minute: minute of hour 162 <br><br>sec: second of minute 164 <br><br>timbas: time basis code:<br>1 = local<br>2 = GMT<br>3 = other 166 <br><br>trwf: trace weighting factor, defined as 1/2^N<br>volts for the least sigificant bit 168 <br><br>grnors: geophone group number of roll switch<br>position one 170 <br><br>grnofr: geophone group number of trace one within<br>original field record 172 <br><br>grnlof: geophone group number of last trace within<br>original field record 174 <br><br>gaps: gap size (total number of groups dropped) 176 <br><br>otrav: overtravel taper code:<br>1 = down (or behind)<br>2 = up (or ahead)<br />
|-<br />
| ''string '' || '''bfile=''' || || output binary data header file<br />
|-<br />
| ''bool '' || '''endian=''' || [y/n] || big/little endian flag, the default is estimated automatically<br />
|-<br />
| ''int '' || '''format=sf_segyformat (bhead)''' || [1,2,3,5] || Data format. The default is taken from binary header.<br />
:1 is IBM floating point<br />
:2 is 4-byte integer<br />
:3 is 2-byte integer<br />
:5 is IEEE floating point<br />
|-<br />
| ''string '' || '''hfile=''' || || output text data header file<br />
|-<br />
| ''string '' || '''mask=''' || || optional header mask for reading only selected traces<br />
|-<br />
| ''int '' || '''ns=sf_segyns (bhead)''' || || Number of samples. The default is taken from binary header<br />
|-<br />
| ''string '' || '''read=''' || || what to read: h - header, d - data, b - both (default)<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if input is SU, n if input is SEGY<br />
|-<br />
| ''bool '' || '''suxdr=n''' || [y/n] || y, SU has XDR support<br />
|-<br />
| ''string '' || '''tape=''' || || <br />
|-<br />
| ''string '' || '''tfile=''' || || output trace header file<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
The SEG Y format is an [http://en.wikipedia.org/wiki/Open_standard open standard] for the exchange of geophysical data. It is controlled by the non-profit [http://www.seg.org/SEGportalWEBproject/portals/SEG_Online.portal?_nfpb=true&_pageLabel=pg_gen_content&Doc_Url=prod/SEG-Publications/Pub-Yearbook/committees.htm SEG Technical Standards Committee]. There are two versions of this standard: [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev0.pdf rev0] (1975)<ref>Barry, K.M., Cavers, D.A., and Kneale, C.W. 1975. Recommended standards for digital tape formats. ''Geophysics'', '''40''', no. 02, 344–352.</ref> and [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf rev1] (2002)<ref>Norris, M.W., Faichney, A.K., ''Eds''. 2001. SEG Y rev1 Data Exchange format. Society of Exploration Geophysicists, Tulsa, OK, 45 pp.</ref>. The implementation in <tt>sfsegyread</tt> is a mixture of rev0 (i.e. no checks for Extended Textual Headers) and rev1 ([http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE floating point format] allowed for trace data samples).<br />
<br />
A SEG-Y file as understood by <tt>sfsegyread</tt> contains a "Reel Identification Header" (3200 bytes in EBCDIC followed by 400 bytes in a binary encoding), followed by a number of "Trace Blocks". Each "Trace Block" contains a 240-byte "Trace Header" (binary) followed by "Trace Data" -- a sequence of <tt>ns</tt> samples. Binary values in both reel headers and trace headers are two's complement integers, either two bytes or four bytes long. There are no floating-point values defined in the headers. Trace Data samples can have various encodings, either floating point or integer, described further down, but they are all big-endian. To convert from SEG-Y to RSF, <tt>sfsegyread</tt> will strip the tape reel EBCDIC header and convert it to ASCII, will extract the reel binary header without changing it, and will put the trace headers into one RSF file, and the traces themselves on another.<br />
<br />
===SEG-Y Trace Headers===<br />
In the SEG-Y standard, only the first 180 bytes of the 240-byte trace header are defined; bytes 181-240 are reserved for non-standard header information, and these locations are increasingly used in modern SEG-Y files and its variants. The standard provides for a total of 71 4-byte and 2-byte predefined header words. These 71 standard words have defined lengths and byte offsets, and only these words and byte locations are read using <tt>segyread</tt> and output to the RSF header file with the <tt>hfile=</tt> option. The user may remap these predefined keywords to a different byte offsets.<br />
<br />
===SU File Format===<br />
An [http://www.cwp.mines.edu/sututor/node22.html SU file] is nothing more than a SEG-Y file without the reel headers, and with the Trace Data samples in the native encoding of the CPU the file was created on (Attention -- limited portability!). So, to convert from SU to RSF, <tt>sfsegyread</tt> will just separate headers and traces into two RSF files. <br />
<br />
===SEG-Y specific parameters===<br />
*<tt>hfile=</tt> specifies the name of the file in which the EBCDIC reel header will be put after conversion to ASCII. If you are certain there is no useful information in it, <tt>hfile=/dev/null</tt> works just fine. If you do not specify anything for this parameter you will get an ASCII file named <tt>header</tt> in the current directory. If you want to quickly preview this header before running <tt>sfsegyread</tt>, use<pre>dd if=input.segy count=40 bs=80 cbs=80 conv=unblock,ascii</pre><br />
*<tt>bfile=</tt> specifies name of the file in which the binary reel header (the 400-bytes thing following the 3600-bytes EBCDIC) will be put without any conversion. The default name is "binary". Unless you have software that knows how to read exactly this special type of file, it will be completely useless, so do <tt>bfile=/dev/null</tt><br />
*<tt>format=</tt> specifies the format in which the trace data samples are in the SEG-Y input file. This is read from the binary reel header of the SEG-Y file. Valid values are 1(IBM floating point), 2 (4-byte integer), 3 (2-byte integer) and 5 (IEEE floating point). If the input file is SU, the format will be assumed to be the native <tt>float</tt> format.<br />
<br />
*<tt>keyname=</tt> specifies the byte offset to remap a header using the trace header key names shown above. For example, if the CDP locations have been placed in bytes 181-184 instead of the standard 21-24, <tt>cdp=180</tt> will remap the trace header to that location. <br />
<br />
===SU-specific parameters===<br />
*<tt>suxdr=</tt> specifies whether the input file was created with a SU package with XDR support enabled. If you have access to the source code of your SU install (try <tt>$CWPROOT/src</tt>), type: <tt>grep 'XDRFLAG =' $CWPROOT/src/Makefile.config</tt> and look at the last uncommented entry. If no value is given for <tt>XDRFLAG</tt>, the package was not compiled with XDR support.<br />
===Common parameters===<br />
*<tt>su=</tt> specifies if the input file is SU or SEG-Y. Default is <tt>su=n</tt> (SEG-Y file).<br />
*<tt>tape=</tt> specifies the input data. Stdin could not be used because <tt>sfsegyread</tt> has to work with tapes, and needs to fseek back and forth through the input file. Thankfully, output is on stdout.<br />
*<tt>read=</tt> specifies what parts of the "Trace Blocks" will be read. It can be <tt>read=t</tt> (only trace data is read), <tt>read=h</tt> (only trace headers are read) or <tt>read=b</tt> (both are read).<br />
*<tt>tfile=</tt> gives the name of the RSF file to which trace headers are written. Obviously, it should be only specified with <tt>read=h</tt> or <tt>read=b</tt>.<br />
*<tt>mask=</tt> is an optional parameter specifying the name of a mask that says which traces will be read. The mask is a 1-D RSF file with integers. The number of samples in the mask is the same as the number of traces in the unmasked SEG-Y. In places corresponding to unwanted traces there should be zeros in the mask.<br />
*<tt>ns=</tt> specifies the number of samples in a trace. For SEG-Y files, the default is taken from the binary reel header, and for SU files, from the header of the first trace. This parameter is however critical enough that a command line override was given for it.<br />
*<tt>verbose=</tt> is the verbosity flag. Can be <tt>y</tt> or <tt>n</tt>.<br />
*<tt>endian=</tt> is a y/n flag (default y), specifying whether to automatically estimate or not if samples in the Trace Data blocks are big-endian or little-endian. Try it if you are in trouble and do not know what else to do, otherwise let the automatic estimation do its job.<br />
<br />
==sfsegywrite==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert an RSF dataset to SEGY or SU.<br />
|-<br />
! colspan="4" | sfsegywrite < in.rsf tfile=hdr.rsf verb=false su=false endian=sf_endian() tape= hfile= bfile=<br />
|-<br />
| colspan="4" | <br>Merges trace headers with data.<br />
|-<br />
| ''string '' || '''bfile=''' || || input binary data header file<br />
|-<br />
| ''bool '' || '''endian=sf_endian()''' || [y/n] || big/little endian flag. The default is estimated automatically<br />
|-<br />
| ''string '' || '''hfile=''' || || input text data header file<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if output is SU, n if output is SEGY<br />
|-<br />
| ''string '' || '''tape=''' || ||<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
Please see <tt>sfsegyread</tt> for a complete description of parameter meanings and background issues. Parameters <tt>bfile</tt> and <tt>hfile</tt> should only be given values when the desired file is SEG-Y (default). The output file is specified by the <tt>tape=</tt> tag.<br />
<br />
=Plotting programs=<br />
The source files for these programs can be found under<br />
[http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/plot/main/ plot/main]<br />
in the Madagascar distribution.<br />
<br />
THIS SECTION IS UNDER CONSTRUCTION<br />
<br />
==sfbox==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Draw a balloon-style label.<br />
|-<br />
! colspan="4" | sfbox lab_color=VP_WHITE lab_fat=0 pscale=1. pointer=y reverse=n lat=0. long=90. angle=0. x0=0. y0=0. scale0=1. xt=2. yt=0. x_oval=0. y_oval=0. boxit=y length= scalet= size=.25 label= > out.vpl<br />
|-<br />
| ''float '' || '''angle=0.''' || || longitude of floating label in 3-D<br />
|-<br />
| ''bool '' || '''boxit=y''' || [y/n] || if y, create a box around text<br />
|-<br />
| ''int '' || '''lab_color=VP_WHITE''' || || label color<br />
|-<br />
| ''int '' || '''lab_fat=0''' || || label fatness<br />
|-<br />
| ''string '' || '''label=''' || || text for label<br />
|-<br />
| ''float '' || '''lat=0.''' || || <br />
|-<br />
| ''float '' || '''length=''' || || normalization for xt and yt<br />
|-<br />
| ''float '' || '''long=90.''' || || latitude and longitude of viewpoint in 3-D<br />
|-<br />
| ''bool '' || '''pointer=y''' || [y/n] || if y, create arrow pointer<br />
|-<br />
| ''float '' || '''pscale=1.''' || || scale factor for width of pointer<br />
|-<br />
| ''bool '' || '''reverse=n''' || [y/n] || <br />
|-<br />
| ''float '' || '''scale0=1.''' || || scale factor for x0 and y0<br />
|-<br />
| ''float '' || '''scalet=''' || || <br />
|-<br />
| ''float '' || '''size=.25''' || || text height in inches<br />
|-<br />
| ''float '' || '''x0=0.''' || || <br />
|-<br />
| ''float '' || '''x_oval=0.''' || || <br />
|-<br />
| ''float '' || '''xt=2.''' || || <br />
|-<br />
| ''float '' || '''y0=0.''' || || position of the pointer tip<br />
|-<br />
| ''float '' || '''y_oval=0.''' || || size of the oval around pointer<br />
|-<br />
| ''float '' || '''yt=0.''' || || relative position of text<br />
|}<br />
==sfcontour==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Contour plot.<br />
|-<br />
! colspan="4" | sfcontour < in.rsf c= min1=o1 min2=o2 max1=o1+(n1-1)*d1 max2=o2+(n2-1)*d2 nc=50 dc= c0= transp=y minval= maxval= allpos=y barlabel= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=y''' || [y/n] || contour positive values only<br />
|-<br />
| ''string '' || '''barlabel=''' || || <br />
|-<br />
| ''floats '' || '''c=''' || || [nc]<br />
|-<br />
| ''float '' || '''c0=''' || || first contour<br />
|-<br />
| ''float '' || '''dc=''' || || contour increment<br />
|-<br />
| ''float '' || '''max1=o1+(n1-1)*d1''' || || <br />
|-<br />
| ''float '' || '''max2=o2+(n2-1)*d2''' || || data window to plot<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''min1=o1''' || || <br />
|-<br />
| ''float '' || '''min2=o2''' || || <br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nc=50''' || || number of contours<br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfdots==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot signal with lollipops.<br />
|-<br />
! colspan="4" | sfdots < in.rsf labels= dots=(n1 <= 130)? 1: 0 seemean=(bool) (n2 <= 30) strings=(bool) (n1 <= 400) connect=1 corners= silk=n gaineach=y labelsz=8 yreverse=n constsep=n seedead=n transp=n xxscale=1. yyscale=1. clip=-1. overlap=0.9 screenratio=VP_SCREEN_RATIO screenht=VP_STANDARD_HEIGHT screenwd=screenhigh / screenratio radius=dd1/3 label1= unit1= title= > plot.vpl<br />
|-<br />
| ''float '' || '''clip=-1.''' || || data clip<br />
|-<br />
| ''int '' || '''connect=1''' || || connection type: 1 - diagonal, 2 - bar, 4 - only for non-zero data<br />
|-<br />
| ''bool '' || '''constsep=n''' || [y/n] || if y, use constant trace separation<br />
|-<br />
| ''int '' || '''corners=''' || || number of polygon corners (default is 6)<br />
|-<br />
| ''int '' || '''dots=(n1 <= 130)? 1: 0''' || || type of dots: 1 - baloon, 0 - no dots, 2 - only for non-zero data<br />
|-<br />
| ''bool '' || '''gaineach=y''' || [y/n] || if y, gain each trace independently<br />
|-<br />
| ''string '' || '''label1=''' || || <br />
|-<br />
| ''strings'' || '''labels=''' || || trace labels [n2]<br />
|-<br />
| ''int '' || '''labelsz=8''' || || label size<br />
|-<br />
| ''float '' || '''overlap=0.9''' || || trace overlap<br />
|-<br />
| ''float '' || '''radius=dd1/3''' || || dot radius<br />
|-<br />
| ''float '' || '''screenht=VP_STANDARD_HEIGHT''' || || screen height<br />
|-<br />
| ''float '' || '''screenratio=VP_SCREEN_RATIO''' || || screen aspect ratio<br />
|-<br />
| ''float '' || '''screenwd=screenhigh / screenratio''' || || screen width<br />
|-<br />
| ''bool '' || '''seedead=n''' || [y/n] || if y, show zero traces<br />
|-<br />
| ''bool '' || '''seemean=(bool) (n2 <= 30)''' || [y/n] || if y, draw axis lines<br />
|-<br />
| ''bool '' || '''silk=n''' || [y/n] || if y, silky plot<br />
|-<br />
| ''bool '' || '''strings=(bool) (n1 <= 400)''' || [y/n] || if y, draw strings<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axis<br />
|-<br />
| ''string '' || '''unit1=''' || || <br />
|-<br />
| ''float '' || '''xxscale=1.''' || || x scaling<br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse y axis<br />
|-<br />
| ''float '' || '''yyscale=1.''' || || y scaling<br />
|}<br />
==sfgraph3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot for surfaces.<br />
|-<br />
! colspan="4" | sfgraph3 < in.rsf orient=1 min= max= point1=0.5 point2=0.5 frame1=0.5*(min+max) frame2=n1-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y > plot.vpl<br />
|-<br />
| ''float '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''float '' || '''frame1=0.5*(min+max)''' || || <br />
|-<br />
| ''int '' || '''frame2=n1-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''max=''' || || maximum function value<br />
|-<br />
| ''float '' || '''min=''' || || minimum function value<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''orient=1''' || || function orientation<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|}<br />
==sfgraph==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Graph plot.<br />
|-<br />
! colspan="4" | sfgraph < in.rsf symbolsz= pclip=100. transp=n symbol= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''pclip=100.''' || || clip percentile<br />
|-<br />
| ''string '' || '''symbol=''' || || if set, plot with symbols instead of lines<br />
|-<br />
| ''floats '' || '''symbolsz=''' || || symbol size (default is 2) [n2]<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfgrey3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot.<br />
|-<br />
! colspan="4" | sfgrey3 < in.rsf point1=0.5 point2=0.5 frame1=0 frame2=n2-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y scalebar=n minval= maxval= barreverse=n nreserve=8 bar= color= > plot.vpl<br />
|-<br />
| colspan="4" | Requires an "unsigned char" input (the output of sfbyte).<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''int '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''int '' || '''frame1=0''' || || <br />
|-<br />
| ''int '' || '''frame2=n2-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || if y, draw scalebar<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
for sfgrey and sfgrey3. Examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfgrey==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate raster plot.<br />
|-<br />
! colspan="4" | sfgrey < in.rsf > out.rsf bar=bar.rsf transp=y yreverse=y xreverse=n gpow= phalf= clip= pclip= gainstep=0.5+n1/256. allpos=n bias=0. polarity=n verb=n scalebar=n minval= maxval= barreverse=n wantframenum=(bool) (n3 > 1) nreserve=8 gainpanel= bar= color= > (plot.vpl | char.rsf)<br />
|-<br />
| colspan="4" | Can input char values.<br>If called "byte", outputs char values.<br><br>Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=n''' || [y/n] || if y, assume positive data<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=''' || || <br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''string '' || '''gainpanel=''' || || gain reference: 'a' for all, 'e' for each, or number<br />
|-<br />
| ''int '' || '''gainstep=0.5+n1/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=''' || || <br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''pclip=''' || || data clip percentile (default is 99)<br />
|-<br />
| ''float '' || '''phalf=''' || || percentage for estimating gpow<br />
|-<br />
| ''bool '' || '''polarity=n''' || [y/n] || if y, reverse polarity (white is high by default)<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the display axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''bool '' || '''wantframenum=(bool) (n3 > 1)''' || [y/n] || if y, display third axis position in the corner<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''bool '' || '''yreverse=y''' || [y/n] || if y, reverse the vertical axis<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
and examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfplas==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Assembler - convert ascii to vplot. <br />
|-<br />
! colspan="4" | sfplas<br />
|}<br />
==sfpldb==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Debugger - convert vplot to ascii. <br />
|-<br />
! colspan="4" | sfpldb<br />
|}<br />
==sfplotrays==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot rays.<br />
|-<br />
! colspan="4" | sfplotrays frame=frame.rsf nt=n1*n2 jr=1 frame= < rays.rsf > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''string '' || '''frame=''' || || <br />
|-<br />
| ''int '' || '''jr=1''' || || skip rays<br />
|-<br />
| ''int '' || '''nt=n1*n2''' || || maximum ray length<br />
|}<br />
==sfthplot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Hidden-line surface plot.<br />
|-<br />
! colspan="4" | sfthplot < in.rsf uflag=y dflag=y alpha=45. titlsz=9 axissz=6 plotfat=0 titlefat=2 axisfat=2 plotcolup=VP_YELLOW plotcoldn=VP_RED axis=y axis1=y axis2=y axis3=y clip=0. pclip=100. gainstep=0.5+nx/256. bias=0. dclip=1. norm=y xc=1.5 zc=3 ratio=5. zmax= zmin= sz=6. label#= unit#= tpow=0 epow=0 gpow=1 title= > plot.vpl<br />
|-<br />
| ''float '' || '''alpha=45.''' || || apparent angle in degrees, |alpha| < 89<br />
|-<br />
| ''bool '' || '''axis=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis1=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis2=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis3=y''' || [y/n] || plot axis<br />
|-<br />
| ''int '' || '''axisfat=2''' || || axes fatness<br />
|-<br />
| ''int '' || '''axissz=6''' || || axes size<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip<br />
|-<br />
| ''float '' || '''dclip=1.''' || || change the clip: clip *= dclip<br />
|-<br />
| ''bool '' || '''dflag=y''' || [y/n] || if y, plot down side of the surface<br />
|-<br />
| ''float '' || '''epow=0''' || || exponential gain<br />
|-<br />
| ''int '' || '''gainstep=0.5+nx/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=1''' || || power gain<br />
|-<br />
| ''string '' || '''label#=''' || || label on #-th axis<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || normalize by the clip<br />
|-<br />
| ''float '' || '''pclip=100.''' || || data clip percentile<br />
|-<br />
| ''int '' || '''plotcoldn=VP_RED''' || || color of the lower side<br />
|-<br />
| ''int '' || '''plotcolup=VP_YELLOW''' || || color of the upper side<br />
|-<br />
| ''int '' || '''plotfat=0''' || || line fatness<br />
|-<br />
| ''float '' || '''ratio=5.''' || || plot adjustment<br />
|-<br />
| ''float '' || '''sz=6.''' || || vertical scale<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''int '' || '''titlefat=2''' || || title fatness<br />
|-<br />
| ''int '' || '''titlsz=9''' || || title size<br />
|-<br />
| ''string '' || '''tpow=0''' || || time power gain<br />
|-<br />
| ''bool '' || '''uflag=y''' || [y/n] || if y, plot upper side of the surface<br />
|-<br />
| ''string '' || '''unit#=''' || || unit on #-th axis<br />
|-<br />
| ''float '' || '''xc=1.5''' || || <br />
|-<br />
| ''float '' || '''zc=3''' || || lower left corner of the plot<br />
|-<br />
| ''float '' || '''zmax=''' || || <br />
|-<br />
| ''float '' || '''zmin=''' || || <br />
|}<br />
==sfwiggle==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot data with wiggly traces. <br />
|-<br />
! colspan="4" | sfwiggle < in.rsf xpos=xpos.rsf xmax= xmin= poly=n fatp=1 xmask=1 ymask=1 pclip=98. zplot=0.75 clip=0. seemean=n verb=n transp=n yreverse=n xreverse=n xpos= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip (estimated from pclip by default<br />
|-<br />
| ''int '' || '''fatp=1''' || || <br />
|-<br />
| ''float '' || '''pclip=98.''' || || clip percentile<br />
|-<br />
| ''bool '' || '''poly=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''seemean=n''' || [y/n] || if y, plot mean lines of traces<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''int '' || '''xmask=1''' || || <br />
|-<br />
| ''float '' || '''xmax=''' || || maximum trace position (if using xpos)<br />
|-<br />
| ''float '' || '''xmin=''' || || minimum trace position (if using xpos)<br />
|-<br />
| ''string '' || '''xpos=''' || || optional header file with trace positions<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''int '' || '''ymask=1''' || || <br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse the vertical axis<br />
|-<br />
| ''float '' || '''zplot=0.75''' || || <br />
|}<br />
<br />
=filt/imag programs=<br />
==sfremap1==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 1-D ENO interpolation. <br />
|-<br />
! colspan="4" | sfremap1 < in.rsf > out.rsf pattern=pattern.rsf n1=n1 d1=d1 o1=o1 order=3<br />
|-<br />
| ''float '' || '''d1=d1''' || || Output sampling<br />
|-<br />
| ''int '' || '''n1=n1''' || || Number of output samples<br />
|-<br />
| ''float '' || '''o1=o1''' || || Output origin<br />
|-<br />
| ''int '' || '''order=3''' || || Interpolation order<br />
|-<br />
| ''string '' || '''pattern=''' || || auxiliary input file name<br />
|}<br />
To give an example of usage, we will create an input for <tt>sfremap1</tt> with:<br />
<pre><br />
sfmath n1=11 n2=11 d1=1 d2=1 o1=-5 o2=-5 output="x1*x1+x2*x2" > inp2remap1.rsf<br />
</pre><br />
Let us interpolate the data across both dimensions, then display it:<br />
<pre><br />
&lt; inp2remap1.rsf sfremap1 n1=1001 d1=0.01 | sftransp | \<br />
sfremap1 n1=1001 d1=0.01 | sftransp | sfgrey allpos=y | xtpen<br />
</pre><br />
The comparison with the uninterpolated data ( <tt>&lt; inp2remap1.rsf sfgrey allpos=y | xtpen</tt> ) is quite telling.<br />
<br />
=filt/proc programs=<br />
==sfstretch==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stretch of the time axis. <br />
|-<br />
! colspan="4" | sfstretch < in.rsf > out.rsf datum=dat.rsf inv=n dens=1 v0= half=y delay= tdelay= hdelay= nout=dens*n1 extend=4 mute=0 maxstr=0 rule=<br />
|-<br />
| ''file '' || '''datum=''' || || auxiliary input file name<br />
|-<br />
| ''float '' || '''delay=''' || || time delay for rule=lmo<br />
|-<br />
| ''int '' || '''dens=1''' || || axis stretching factor<br />
|-<br />
| ''int '' || '''extend=4''' || || trace extension<br />
|-<br />
| ''bool '' || '''half=y''' || [y/n] || if y, the second axis is half-offset instead of full offset<br />
|-<br />
| ''float '' || '''hdelay=''' || || offset delay for rule=rad<br />
|-<br />
| ''bool '' || '''inv=n''' || [y/n] || if y, do inverse stretching<br />
|-<br />
| ''float '' || '''maxstr=0''' || || maximum stretch<br />
|-<br />
| ''int '' || '''mute=0''' || || tapering size<br />
|-<br />
| ''int '' || '''nout=dens*n1''' || || output axis length (if inv=n)<br />
|-<br />
| ''string '' || '''rule=''' || || Stretch rule:<br />
:n - normal moveout (nmostretch), default<br />
:l - linear moveout (lmostretch)<br />
:L - logarithmic stretch (logstretch)<br />
:2 - t^2 stretch (t2stretch)<br />
:c - t^2 chebyshev stretch (t2chebstretch)<br />
:r - radial moveout (radstretch)<br />
:d - datuming (datstretch)<br />
|-<br />
| ''float '' || '''tdelay=''' || || time delay for rule=rad<br />
|-<br />
| ''float '' || '''v0=''' || || moveout velocity<br />
|}<br />
<br />
<tt>sfstretch rule=d</tt> (aka <tt>sfdatstretch</tt>) can be used to apply statics. Here is a synthetic example, courtesy of Alessandro Frigeri:<br />
<pre><br />
# generate a dataset with 'flat' signals<br />
sfmath n1=200 n2=100 output="sin(0.5*x1)" type=float > scan.rsf<br />
<br />
# generate a sinusoidal elevation correction<br />
sfmath n1=100 output="3*sin(x1)" type=float > statics.rsf<br />
<br />
# apply statics, producing a 'wavy' output.<br />
sfstretch < scan.rsf > out.rsf datum=statics.rsf rule=d<br />
</pre><br />
<br />
=user/ivlad programs=<br />
==sfprep4plot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Resamples a 2-D dataset to the desired picture resolution, with antialias<br />
|-<br />
! colspan="4" | sfprep4plot inp= out= verb=n h=none w=none unit= ppi= prar=y<br />
|-<br />
| colspan="4" | Only one of the h and w parameters needs to be specified.<br>If prar=n, no action will be taken on axis for which h/w was not specified<br>If prar=y and only one par (h or w) is specified, the picture will scale<br>along both axes until it is of the specified dimension.<br />
|-<br />
| ''int '' || '''h=none''' || || output height<br />
|-<br />
| ''string '' || '''inp=''' || || input file<br />
|-<br />
| ''string '' || '''out=''' || || output file<br />
|-<br />
| ''int '' || '''ppi=''' || || output resolution (px/in). Necessary when unit!=px<br />
|-<br />
| ''bool '' || '''prar=y''' || [y/n] || if y, PReserve Aspect Ratio of input<br />
|-<br />
| ''string '' || '''unit=''' || || unit of h and w. Can be: px(default), mm, cm, in<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || if y, print system commands, outputs<br />
|-<br />
| ''int '' || '''w=none''' || || output width<br />
|}<br />
For a figure that does not need the aspect ratio preserved,<br />
and needs to fill a 1280x1024 projector display:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=1280 h=1024 prar=n<br />
</pre><br />
For a print figure that has to fit in a 6x8in box<br />
at a resolution of 250 dpi, preserving the aspect ratio:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=6 h=8 unit=in ppi=250<br />
</pre><br />
A comparison of images before and after the application of <tt>sfprep4plot</tt>, courtesy of Joachim Mispel, is shown below:<br />
<br />
[[Image:sf_prep4plot.jpg]]<br />
<br />
=user/jennings programs=<br />
==sfsizes==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display the size of RSF files.<br />
|-<br />
! colspan="4" | sfsizes files=y human=n file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | Prints the element size, number of elements, and number of bytes<br>for a list of RSF files. Non-RSF files are ignored.<br />
|-<br />
| ''bool '' || '''files=y''' || [y/n] || If y, print size of each file. If n, print only total.<br />
|-<br />
| ''bool '' || '''human=n''' || [y/n] || If y, print human-readable file size. If n, print byte count.<br />
|}<br />
<br />
<br />
This program computes the "theoretical" size in bytes of the data fork of RSF files. The actual space occupied on disk may be different and machine dependent due to disk blocking factors, etc. This theoretical array size should be reproducible. It is also fast because the program only reads the RSF headers files, not the actual data.<br />
<br />
For example, to get the total size of all RSF files in a directory, in human readable format, without listing each file:<br />
<pre><br />
sfsizes files=n human=y *.rsf<br />
</pre><br />
This will also work because sfsizes simply skips any non-RSF file:<br />
<pre><br />
sfsizes files=n human=y *<br />
</pre><br />
==sfsizes==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display the size of RSF files.<br />
|-<br />
! colspan="4" | sfsizes files=y human=n file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | Prints the element size, number of elements, and number of bytes<br>for a list of RSF files. Non-RSF files are ignored.<br />
|-<br />
| ''bool '' || '''files=y''' || [y/n] || If y, print size of each file. If n, print only total.<br />
|-<br />
| ''bool '' || '''human=n''' || [y/n] || If y, print human-readable file size. If n, print byte count.<br />
|}<br />
<br />
<br />
This program computes the "theoretical" size in bytes of the data fork of RSF files. The actual space occupied on disk may be different and machine dependent due to disk blocking factors, etc. This theoretical array size should be reproducible. It is also fast because the program only reads the RSF headers files, not the actual data.<br />
<br />
For example, to get the total size of all RSF files in a directory, in human readable format, without listing each file:<br />
<pre><br />
sfsizes files=n human=y *.rsf<br />
</pre><br />
This will also work because sfsizes simply skips any non-RSF file:<br />
<pre><br />
sfsizes files=n human=y *<br />
</pre><br />
<br />
=user/psava programs=<br />
==sfsrmig3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 3-D S/R migration with extended SSF<br />
|-<br />
! colspan="4" | sfsrmig3 slo=Fs_s.rsf sls=Fs_r.rsf < Fw_s.rsf rwf=Fw_r.rsf > Fi.rsf cig=Fc.rsf ompchunk=1 ompnth=0 verb=y eps=0.01 twoway=n nrmax=1 dtmax=0.004 pmx=0 pmy=0 tmx=0 tmy=0 vpvs=1. hsym=n nht=1 oht=0 dht=0.1 nht=1 oht=0 dht=0.1 hsym=n nhh=1 ohh=0 dhh=0.1 nha=180 oha=0 dha=2.0 nhb=180 ohb=0 dhb=2.0 itype=<br />
|-<br />
| ''file '' || '''cig=''' || || auxiliary output file name<br />
|-<br />
| ''float '' || '''dha=2.0''' || ||<br />
|-<br />
| ''float '' || '''dhb=2.0''' || ||<br />
|-<br />
| ''float '' || '''dhh=0.1''' || ||<br />
|-<br />
| ''float '' || '''dht=0.1''' || ||<br />
|-<br />
| ''float '' || '''dtmax=0.004''' || || max time error<br />
|-<br />
| ''float '' || '''eps=0.01''' || || stability parameter<br />
|-<br />
| ''bool '' || '''hsym=n''' || [y/n] ||<br />
|-<br />
| ''string '' || '''itype=''' || || imaging condition type<br />
:o = zero lag (default)<br />
:e = extended<br />
:x = space-lags<br />
:h = space-lags magnitude<br />
:t = time-lag<br />
|-<br />
| ''int '' || '''nha=180''' || ||<br />
|-<br />
| ''int '' || '''nhb=180''' || ||<br />
|-<br />
| ''int '' || '''nhh=1''' || ||<br />
|-<br />
| ''int '' || '''nht=1''' || ||<br />
|-<br />
| ''int '' || '''nrmax=1''' || || max number of refs<br />
|-<br />
| ''float '' || '''oha=0''' || ||<br />
|-<br />
| ''float '' || '''ohb=0''' || ||<br />
|-<br />
| ''float '' || '''ohh=0''' || ||<br />
|-<br />
| ''float '' || '''oht=0''' || ||<br />
|-<br />
| ''int '' || '''ompchunk=1''' || || OpenMP data chunk size<br />
|-<br />
| ''int '' || '''ompnth=0''' || || OpenMP available threads<br />
|-<br />
| ''int '' || '''pmx=0''' || || padding on x<br />
|-<br />
| ''int '' || '''pmy=0''' || || padding on y<br />
|-<br />
| ''file '' || '''rwf=''' || || auxiliary input file name<br />
|-<br />
| ''file '' || '''slo=''' || || auxiliary input file name<br />
|-<br />
| ''string '' || '''sls=''' || || auxiliary input file name<br />
|-<br />
| ''int '' || '''tmx=0''' || || taper on x<br />
|-<br />
| ''int '' || '''tmy=0''' || || taper on y<br />
|-<br />
| ''bool '' || '''twoway=n''' || [y/n] || two-way traveltime<br />
|-<br />
| ''bool '' || '''verb=y''' || [y/n] || verbosity flag<br />
|-<br />
| ''float '' || '''vpvs=1.''' || || Vp/Vs ratio<br />
|}<br />
<br />
This program performs 3-D and 2-D shot-record (a.k.a. shot-profile) migration with an extended Split-Step Fourier (SSF) extrapolator with multiple reference velocities (hence "extended"). It takes as input a shot wavefield (<tt>stdin</tt>), receiver wavefield (<tt>rwf=</tt>) and slowness model (<tt>slo=</tt>). Outputs are an image (<tt>stdout</tt>) and a cube of Common Image Gathers (<tt>cig=</tt>). An important parameter is <tt>nrmax</tt>, the number of reference velocities. Its default value is 1, but for reasonable results it should be 5 or so. It is also good to specify nonzero taper values (<tt>tmx</tt> and, for 3-D, <tt>tmy</tt> as well). The values of padding parameters <tt>pmx</tt> and <tt>pmy</tt> are split in two by the program, i.e. if your data x axis is 501-points long, specify pmx=11 to get a value of 512 that will result in fast Fourier Transforms. <br />
<br />
The program will also migrate converted-wave data if a file with the S-wave slowness model (<tt>sls=</tt>) is provided.<br />
<br />
The <tt>vpvs</tt> parameter is only used when <tt>itype=h</tt>. Do not specify a <tt>vpvs</tt> value unless you know really well what you are doing.<br />
<br />
===Usage example===<br />
The commands below, slightly modified from [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/data/sigsbee/ptest/SConstruct?revision=3993&view=markup RSFSRC/book/data/sigsbee/ptest], show how to prepare the [http://www.reproducibility.org/RSF/book/data/sigsbee Sigsbee 2A] data and velocity for migration.<br />
<br />
Convert input data (shots) from SEG-Y to RSF:<br />
<bash><br />
sfsegyread tape=sigsbee2a_nfs.segy tfile=tdata.rsf hfile=/dev/null bfile=/dev/null > ddata.rsf<br />
</bash><br />
Convert trace headers to float (required by <tt>sfheadermath</tt>):<br />
<bash><br />
< tdata.rsf sfdd type=float > trchdr.rsf<br />
</bash><br />
Shot positions:<br />
<bash><br />
< trchdr.rsf sfheadermath output="fldr + 10925/150" | sfwindow squeeze=y > tsi.rsf<br />
</bash><br />
Extract offset positions from the trace header files, eliminate length-1 axis, scale, create a header for binning (required by <tt>sfintbin</tt>):<br />
<bash><br />
< trchdr.rsf sfheadermath output="offset" |\<br />
sfwindow squeeze=y |\<br />
sfmath output="input/75" |\<br />
sfcat axis=2 space=n tsi.rsf |\<br />
sftransp |\<br />
sfdd type=int > tos.rsf<br />
</bash><br />
Binning and muting:<br />
<bash><br />
< ddata.rsf sfintbin head=tos.rsf xkey=0 ykey=1 |\<br />
sfput label1=Time unit1=s d2=0.075 o2=0.0 label2=hx d3=0.150 o3=10.925 label3=sx |\<br />
sfmutter half=false t0=1.0 v0=6.0 |\<br />
sfput d2=0.02286 o2=0 unit2=km d3=0.04572 o3=3.32994 unit3=km > shots.rsf<br />
</bash><br />
Keeping only 20 shots so that this 1-node job will not take forever, FFT-ing, decimating frequency slices (same as shortening the time axis), and creating y and hy axes of length 1:<br />
<bash><br />
< shots.rsf sfwindow n3=20 f3=10 j3=20 |\<br />
sffft1 |\<br />
sfwindow n1=200 min1=1 j1=3 |\<br />
sfspray axis=3 n=1 o=0 d=1 label=hy |\<br />
sfspray axis=5 n=1 o=0 d=1 label=sy > rfft.rsf<br />
</bash><br />
The dimensions of the cube thus created are:<br />
<pre><br />
$ sfin rfft.rsf trail=n<br />
rfft.rsf:<br />
in="/var/tmp/rfft.rsf@"<br />
esize=8 type=complex form=native<br />
n1=200 d1=0.25 o1=1 label1="Frequency" unit1="Hz"<br />
n2=348 d2=0.02286 o2=0 label2="hx" unit2="km"<br />
n3=1 d3=1 o3=0 label3="hy" unit3="km"<br />
n4=20 d4=0.9144 o4=3.78714 label4="sx" unit4="km"<br />
1392000 elements 11136000 bytes<br />
</pre><br />
Create the source wavelet (limited to the same frequency band as the data) and Fourier transform it:<br />
<bash><br />
sfspike k1=1 n1=1500 d1=0.008 |\<br />
sfbandpass flo=15 fhi=25 |\<br />
sffft1 |\<br />
sfwindow n1=200 min1=1 j1=3 |\<br />
sfput label1=freq > sfft.rsf<br />
</bash><br />
This creates a frequency-domain wavelet:<br />
<pre><br />
$ sfin sfft.rsf<br />
sfft.rsf:<br />
in="/var/tmp/sfft.rsf@"<br />
esize=8 type=complex form=native<br />
n1=200 d1=0.25 o1=1 label1="freq" unit1="Hz"<br />
200 elements 1600 bytes<br />
</pre><br />
Create "synched" source and receiver wavefields with <tt>srsyn</tt> from wavelet and data frequency slices. Basically both the receiver and shot frequency slices are "placed" at the right location and padded with zeros up to the dimension of the x axis specified below.<br />
<bash><br />
< rfft.rsf sfsrsyn nx=1067 dx=0.02286 ox=3.05562 wav=sfft.rsf swf=swav.rsf > rwav.rsf<br />
</bash><br />
This creates frequency slices ready for migration for both source and receiver, only axis 1 (frequency) must become axis 3, for both datasets:<br />
<bash><br />
< swav.rsf sftransp plane=12 | sftransp plane=23 > stra.rsf<br />
</bash><br />
<bash><br />
< rwav.rsf sftransp plane=12 | sftransp plane=23 > rtra.rsf<br />
</bash><br />
This creates a surface receiver wavefield ready for input to migration. Axis 4 is shot number. The values of axis 4 are arbitrary because each shot has been padded with zeros so that it covers the entire velocity model. Therefore the aperture of the downward continuation for each shot will be as large as the survey.<br />
<pre><br />
sfin trail=n rtra.rsf<br />
rtra.rsf:<br />
in="/var/tmp/rtra.rsf@"<br />
esize=8 type=complex form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=200 d3=0.25 o3=1 label3="w" unit3="Hz"<br />
n4=20 d4=1 o4=0 label4="e" unit4="km"<br />
4268000 elements 34144000 bytes<br />
</pre><br />
Convert the velocity model from SEG-Y to RSF, decimate, convert from feet to km, transpose, convert to slowness and insert an additional axis:<br />
<bash><br />
sfsegyread tape=sigsbee2a_migvel.sgy tfile=/dev/null hfile=/dev/null bfile=/dev/null |\<br />
sfput o1=0 d1=0.00762 label1=z unit1=km o2=3.05562 d2=0.01143 label2=x unit2=km |\<br />
sfwindow j1=4 j2=2 |\<br />
sfscale rscale=0.0003048 |\<br />
sftransp |\<br />
sfmath output="1/input" |\<br />
sfspray axis=2 n=1 d=1 o=0 |\<br />
sfput label2=y > slow.rsf<br />
</bash><br />
This creates a slowness file ready for input to migration, with an x axis identical to the x axis of the wavefield files:<br />
<pre><br />
$ sfin slow.rsf<br />
slow.rsf:<br />
in="/var/tmp/slow.rsf@"<br />
esize=4 type=float form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=301 d3=0.03048 o3=0 label3="z" unit3="km"<br />
321167 elements 1284668 bytes<br />
</pre><br />
Finally, the migration command (for a 4-processor machine, hence the <tt>ompnth</tt> value). We choose not to compute any image gathers (<tt>itype=o</tt>), but due to the construction of the program we still have to explicitly assign the <tt>cig</tt> tag, or else a RSF file with the name of the tag and no rsf extension will be created:<br />
<bash><br />
< stra.rsf sfsrmig3 nrmax=20 dtmax=5e-05 eps=0.01 verb=y ompnth=4 \<br />
tmx=16 rwf=rtra.rsf slo=slow.rsf itype=o cig=/dev/null > img.rsf<br />
</bash><br />
The migration of 20 shots takes approximately 3 hours on a 4-processor machine (1 shot=9 minutes). Without the frequency slice decimation by a factor of 3 and the depth axis decimation by a factor of 4, it would have taken twelve times as much. The resulting image has a y axis of length 1:<br />
<pre><br />
$ sfin img.rsf trail=n<br />
img.rsf:<br />
in="/var/tmp/img.rsf@"<br />
esize=4 type=float form=native<br />
n1=1067 d1=0.02286 o1=3.05562 label1="x" unit1="km"<br />
n2=1 d2=1 o2=0 label2="y" unit2="km"<br />
n3=301 d3=0.03048 o3=0 label3="z" unit3="km"<br />
321167 elements 1284668 bytes<br />
</pre><br />
To properly visualize the image, we need to eliminate the axis of length 1, then transpose the x and z axes to their natural position:<br />
<bash><br />
<img.rsf sfwindow squeeze=y | sftransp | sfgrey > img.vpl<br />
</bash><br />
<br />
=References=<br />
<references/></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=926Advanced Installation2009-08-14T02:28:09Z<p>Jenningsjwj: /* Used by the Madagascar core */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation. If you cannot get <tt>mkoctfile</tt> installed, but still want some limited functionality of this API, specifying <tt>APIFORCE=y</tt> during the configuration.<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
==Used by the Madagascar core==<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing examples in $RSFSRC/book<br />
|-<br />
|-<br />
| RSFALTFIGS || $RSFROOT/figs || Alternate directory with figures for testing examples not in $RSFSRC/book<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
<br />
For future documentation writers: the environment variables read by Madagascar can be found by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>APIFORCE</tt>: If <tt>APIFORCE=y</tt>, those API components that do not have dependencies will be nevertheless installed. This is the case of scripts in interpreted languages which call standalone Madagascar programs. This option is provided for allowing a limited functionality to those who cannot install dependencies, while not annoying those who may want specifically to NOT have an API installed because of namespace conflicts or other reasons.<br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but currently only Fedora 9 and 10 are actively maintained. Thus, Madagascar does not attempt to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support.<br />
<br />
==Ubuntu 6.06-9.04==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, and considering the [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Ubuntu Life Cycle], Madagascar will attempt to support:<br />
* Ubuntu 6.06 LTS Server until end of June 2011 or until SCons stops supporting Python 2.4, whichever comes sooner<br />
* Ubuntu 8.04 LTS Desktop until end of April 2011 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 8.10 until end of April 2010 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 9.04 until end of October 2010 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 9.10 until end of April 2011 or until SCons stops supporting its Python version, whichever comes sooner<br />
<br />
You can install all of Madagascar's dependencies by running<br />
<pre><br />
sudo apt-get install freeglut3-dev g++ gfortran libc6-dev libg2-noxpm-dev libglew1.5-dev libjpeg62-dev \<br />
libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy scons units <br />
</pre><br />
<br />
If working with the development version, you will need <tt>subversion</tt> to download and update it.<br />
<br />
Ubuntu 9.04 changes:<br />
* Package <tt>g77</tt> (dependency for Fortran API in earlier versions of Ubuntu) does not seem to be present in the repositories, replaced with <tt>gfortran</tt><br />
* Package <tt>mesa-libGL-devel</tt> (dependency of OpenGL in earlier versions of Ubuntu) does not seem to be present in the repositories, replaced with <tt>freeglut3-dev</tt><br />
* Package <tt>libglew-dev</tt> (dependency of GLEW in earlier versions of Ubuntu) does not seem to be present in the repositories, replaced with <tt>libglew1.5-dev</tt><br />
<br />
==Fedora 10, 11==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, Madagascar will attempt to support the last two versions of Fedora (currently 10 and 11). Considering the [http://fedoraproject.org/wiki/LifeCycle Fedora Life Cycle] (release X maintained until one month after the release of X+2) and the [http://fedoraproject.org/wiki/Releases/12/Schedule Fedora 12 schedule], Fedora 10 should be dropped and Fedora 12 should be supported starting with 2009-12-03.<br />
<br />
You can install the common dependencies for both the stable version and the development one, by typing as root:<br />
<pre><br />
yum -y install atlas atlas-devel binutils blas blas-devel freeglut freeglut-devel gcc \<br />
gcc-c++ gcc-gfortran glibc-headers libjpeg-devel libXaw-devel netpbm-devel numpy octave \<br />
octave-devel scipy scons swig texlive units <br />
</pre><br />
Packages that are already installed will be ignored.<br />
<br />
To install LaTeX for building papers and books, you need <tt>texlive-latex</tt> .<br />
<br />
If you are using the development version, you also need the <tt>subversion</tt> package. If you are installing on a multicore machine, you will get a speedup if you install <tt>libgomp</tt>.<br />
<br />
==CentOS 3, 4, 5==<br />
Given that CentOS is a clone of RHEL, it is expected it will have the same lifecycle (7 years of support after release), CentOS 5 should be supported by Madagascar until 2014-03-14, or until SCons stable version ceases to support Python 2.4 &ndash; whichever comes first. CentOS 4 should be supported until 2012-02-15 or until SCons stable drops support for 2.3. CentOS 3 should be supported until 2010-10-22 or until SCons stable drops support for Python 2.2, whichever comes first.<br />
<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list .<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 4, 5==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, Madagascar will attempt to support Debian 4 until it stops being supported by its developers (end 2009-beg. 2010), and Debian 5 until it stops being supported by the Debian project or SCons stops supporting Python 2.5, whatever comes sooner.<br />
<br />
Specific dependencies:<br />
* Debian 4.0 ("Etch"): In order to build xtpen (for displaying .vpl images) you will need the <tt>libXaw7-dev</tt> package.<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source.<br />
<br />
==openSUSE 11.0, 11.1==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, and given that [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases have a lifetime of 2 years], Madagascar should theoretically attempt to support openSUSE 10.3 until 2009-10-31, openSUSE 11.0 until 2010-06-30, and openSUSE 11.1 until 2010-12-31. In practice, due to limited resources, installation has only been verified on openSUSE 11.0 and 11.1.<br />
<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the F90 API, you need <tt>gcc-fortran</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
* To install some graphics programs, you need <tt>cairo-devel</tt>, <tt>gd-devel</tt>, <tt>glew-devel</tt> and <tt>libtiff-devel</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. If you want to install a development version of Madagascar, the following might help. <br />
<br />
# <b>C compiler</b> for Mac OS X. One can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Another way is to use [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>Fink</b> provides a easy way to install it with the command <tt>fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
==How to adapt Madagascar to a new platform==<br />
The most laborious part of adapting madagascar to a new platform is finding the proper dependency names. This usually proceeds as follows: dependency X fails with a "missing file" error either as a header file in <tt>config.log</tt>, or a missing library during the build step. Possible package names are found through an internet search for the missing file name and the distribution name or by using specific [http://rpm.pbone.net/ rpm search tools]. Packages are installed and the configure (and, if necessary) build processes are repeated until the error goes away.<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
* If <tt>scons</tt> or <tt>scons install</tt> fail due to an a bug introduced in a tool you are certain you will not use, a quick workaround for the problem is already built into scons: the <tt>-k</tt> option, which means "keep going". Thus, if you use <tt>scons -k</tt> or <tt>scons -k install</tt>, SCons will not be able to build the failed component, or anything that depends on it, but it will keep going and make everything else that it can.<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=765Advanced Installation2009-04-10T19:20:20Z<p>Jenningsjwj: /* Capturing error and warning messages */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation. If you cannot get <tt>mkoctfile</tt> installed, but still want some limited functionality of this API, specifying <tt>APIFORCE=y</tt> during the configuration.<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
==Used by the Madagascar core==<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
<br />
For future documentation writers: the environment variables read by Madagascar can be found by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>APIFORCE</tt>: If <tt>APIFORCE=y</tt>, those API components that do not have dependencies will be nevertheless installed. This is the case of scripts in interpreted languages which call standalone Madagascar programs. This option is provided for allowing a limited functionality to those who cannot install dependencies, while not annoying those who may want specifically to NOT have an API installed because of namespace conflicts or other reasons.<br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but currently only Fedora 9 and 10 are actively maintained. Thus, Madagascar does not attempt to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support.<br />
<br />
==Ubuntu 6.06-8.10==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, and considering the [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Ubuntu Life Cycle], Madagascar will attempt to support:<br />
* Ubuntu 6.06 LTS Desktop until end of June 2009<br />
* Ubuntu 6.06 LTS Server until end of June 2011 or until SCons stops supporting Python 2.4, whichever comes sooner<br />
* Ubuntu 7.10 until end of April 2009<br />
* Ubuntu 8.04 LTS Desktop until end of April 2011 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 8.10 until end of April 2010 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 9.04 until end of October 2010 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 9.10 until end of April 2011 or until SCons stops supporting its Python version, whichever comes sooner<br />
<br />
You can install all of Madagascar's dependencies by running<br />
<pre><br />
sudo apt-get install g++ g77 libc6-dev libjpeg62-dev libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy units<br />
</pre><br />
<br />
==Fedora 9, 10==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, Madagascar will attempt to support the last two versions of Fedora (currently 9 and 10). Considering the [http://fedoraproject.org/wiki/LifeCycle Fedora Life Cycle] (release X maintained until one month after the release of X+2) and the [http://fedoraproject.org/wiki/Releases/11/Schedule Fedora 11 schedule], Fedora 9 should be dropped and Fedora 11 should be supported starting with 2009-06-26.<br />
<br />
You can install the common dependencies for both the stable version and the development one, by typing as root:<br />
<pre><br />
yum -y install atlas atlas-devel binutils blas blas-devel freeglut freeglut-devel gcc \<br />
gcc-c++ gcc-gfortran glibc-headers libjpeg-devel libXaw-devel netpbm-devel numpy octave \<br />
octave-devel scipy scons swig texlive units <br />
</pre><br />
Packages that are already installed will be ignored.<br />
<br />
To install LaTeX for building papers and books, you need <tt>texlive-latex</tt> .<br />
<br />
If you are using the development version, you also need the <tt>subversion</tt> package. If you are installing on a multicore machine, you will get a speedup if you install <tt>libgomp</tt>.<br />
<br />
==CentOS 3, 4, 5==<br />
Given that CentOS is a clone of RHEL, it is expected it will have the same lifecycle (7 years of support after release), CentOS 5 should be supported by Madagascar until 2014-03-14, or until SCons stable version ceases to support Python 2.4 &ndash; whichever comes first. CentOS 4 should be supported until 2012-02-15 or until SCons stable drops support for 2.3. CentOS 3 should be supported until 2010-10-22 or until SCons stable drops support for Python 2.2, whichever comes first.<br />
<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list .<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 4, 5==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, Madagascar will attempt to support Debian 4 until it stops being supported by its developers (end 2009-beg. 2010), and Debian 5 until it stops being supported by the Debian project or SCons stops supporting Python 2.5, whatever comes sooner.<br />
<br />
Specific dependencies:<br />
* Debian 4.0 ("Etch"): In order to build xtpen (for displaying .vpl images) you will need the <tt>libXaw7-dev</tt> package.<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source.<br />
<br />
==openSUSE 11.0, 11.1==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, and given that [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases have a lifetime of 2 years], Madagascar should theoretically attempt to support openSUSE 10.3 until 2009-10-31, openSUSE 11.0 until 2010-06-30, and openSUSE 11.1 until 2010-12-31. In practice, due to limited resources, installation has only been verified on openSUSE 11.0 and 11.1.<br />
<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. If you want to install a development version of Madagascar, the following might help. <br />
<br />
# <b>C compiler</b> for Mac OS X. One can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Another way is to use [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>Fink</b> provides a easy way to install it with the command <tt>fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file and observed at the same time with a command like this (tcsh):<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons -k |& tee log_build.asc<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Advanced_Installation&diff=764Advanced Installation2009-04-10T19:10:25Z<p>Jenningsjwj: /* Python and SCons */</p>
<hr />
<div>[[Image:Fotolia_419157_XS.jpg|right|]]<br />
Before reading this document, please familiarize yourself with the [[Installation|short Installation guide]].<br />
=What the installation process does=<br />
The term "installation" in the title is used for brevity, and it actually covers all three steps: configuration, build and install.<br />
# Configure: determine what tools are available on the system and how they should be used to built the software. Creates a layer of abstraction so that the build is platform-independent. Should ideally either solve or flag all problems, so that the build either works, or does not proceed at all.<br />
# Build: compiles the software and documentation using RSFSRC/build as a "workplace"<br />
# Install: moves the compiled executables and the documentation to the final locations in $RSFROOT, sometimes changing filenames. Kept separate from build so that it can be done by root, and to avoid build failures leaving junk files all over the system.<br />
A successful installation will have created in <tt>$RSFROOT</tt> the following directories:<br />
* <tt>bin/</tt>: executable programs<br />
* <tt>doc/</tt>: auto-generated HTML documentation<br />
* <tt>include/</tt>: header files with info on library procedures; fonts<br />
* <tt>lib/</tt>: libraries and Python modules<br />
<br />
=Prerequisites=<br />
Basic prerequisites are described in the [[Installation|short Installation guide]]. Here are some additional details. <br />
==Python and SCons==<br />
As described below under [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]], Madagascar supports the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. If your version of Python is older and you experience problems you should probably [http://www.python.org/ upgrade].<br />
<br />
Madagascar includes the latest stable version of SCons and the configure scripts will try to install it for you in RSFROOT if you don't have it already. However, if you have an older version of SCons the configure scripts will not try to install the newer version. Your older version might work fine, but Madagascar attempts to support only the latest stable version of SCons, so if you have problems you should upgrade.<br />
<br />
To install the SCons bundled with Madagascar go to <tt>RSFSRC/scons</tt>, unpack the tar file, and type<br />
<br />
<bash><br />
python setup.py install<br />
</bash><br />
<br />
This will install SCons in the standard location. You might need root privileges. If you don't have root privileges, or you don't want to interfere with the system SCons you can install it somewhere else with a --prefix option. A logical choice is to put it in RSFROOT like this:<br />
<br />
<bash><br />
python setup.py install --prefix=$RSFROOT<br />
</bash><br />
<br />
==Location==<br />
As long as you set the environment variables and directory permissions correctly, it does not matter in what part of your filesystem you place the install. If you have the luxury of installing anywhere, it is good practice to follow the [http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Filesystem Hierarchy Standard] and either:<br />
# Install everything (including <tt>figs</tt> if you do testing) under <tt>/usr/local/rsf</tt>, with the source tree in <tt>/usr/local/rsf/src</tt>, OR <br />
# Put the source tree in <tt>/usr/local/src/rsf</tt>, and specify <tt>RSFROOT=/usr/local</tt>, so that header files and binaries go in <tt>/usr/local/bin</tt> and <tt>/usr/local/include</tt>. To follow the standard, before installing set <tt>RSFDOC=/usr/local/share/rsf/doc</tt> and create the appropriate directories. The auto-generated HTML documentation will get put there. Also, if installed, the figs directory for testing should be <tt>/usr/local/share/rsf/figs/</tt>.<br />
# Package Madagascar (i.e. build a RPM, etc) and install it in the default locations. For RPMs, those are as like the ones from the previous option, just directly in the <tt>/usr/</tt> hierarchy, instead of in the <tt>/usr/local/</tt> one.<br />
<br />
==Disk space==<br />
At present (Feb 2007, r2530), the source directory containing the build tree from the development version was approx. 200Mb, the full installation (<tt>bin/</tt>, <tt>doc/</tt>, <tt>include/</tt> and <tt>lib</tt>) is 31Mb, and <tt>figs/</tt> (the optional directory if you want to do testing) is about 10 Gb. The stable version is significantly smaller.<br />
<br />
The only Madagascar-related directory where disk space can be an issue is <tt>$DATAPATH</tt>. Real 3-D seismic datasets can be measured in Terabytes. Buggy programs/processing flows can fill up <tt>$DATAPATH</tt>. A real problem are "disk memory leaks" -- removing header files with anything else than <tt>sfrm</tt> will leave the binaries intact. Crashed jobs which start to write to binary but never get to write the header also produce "leaks". Experience has shown that over time <tt>$DATAPATH</tt> inexorably fills up. You may need to <br />
# keep irreplaceable data and expensive results in a separate place;<br />
# remove the oldest files in <tt>$DATAPATH</tt> whenever the amount of free space declines under a preset threshold.<br />
<br />
==Dependencies==<br />
Some platforms feature complete lists of dependencies. See [[Advanced Installation#Platform-specific installation advice | Platform-specific installation advice]] for details.<br />
===C++ API===<br />
A C++ compiler. SCons is smart and will try to find it for you. If it does not work specify the path to your compiler in the <tt>CXX</tt> environment variable (can be passed as an option to the configuration script, like the <tt>API</tt> one).<br />
===F77 API===<br />
A Fortran 77 compiler. If SCons does not find one, then you can either specify its path through the <tt>F77</tt> variable, or if the executable is in your path, add its name to the list of F77 compilers in <tt>RSFSRC/configure.py</tt> .<br />
===F90 API===<br />
Same as for Fortran 77 &ndash; just substitute <tt>F90</tt>. If using the <tt>gfortran</tt> compiler, make sure to get [http://gcc.gnu.org/wiki/GFortranBinaries the latest version]. If you have more than one compiler installed on your system, specify the desired one at configuration time:<br />
<bash><br />
./configure API=f90 F90=/path/to/preferred/compiler<br />
</bash><br />
<br />
===Matlab API===<br />
Besides Matlab itself, you need Mex, which compiles C code into regular Matlab functions. Use the <tt>MATLAB</tt> and <tt>MEX</tt> environment variables to specify their paths if they are installed, but not found.<br />
===Octave API===<br />
The Octave function compiler (<tt>mkoctfile</tt>) is sometimes bundled in a separate package, so it may be missing from the Octave installation. If you cannot get <tt>mkoctfile</tt> installed, but still want some limited functionality of this API, specifying <tt>APIFORCE=y</tt> during the configuration.<br />
===Python API===<br />
This API requires [http://www.swig.org/ SWIG] and [http://numpy.scipy.org/ numpy]. Numpy requires Python 2.4 or newer (i.e. RHEL 5 or newer). However, these dependencies are unnecessary for the common case when Python is just used as [http://en.wikipedia.org/wiki/Glue_language glue] to create chains of programs, and it only needs to read the RSF header, and not the binary. To allow Python [http://en.wikipedia.org/wiki/Meta-programs metaprograms] in madagascar to function, and programming in this style to be done, a fallback development kit implementing only the header-related functionality will be installed in the lack of these dependencies.<br />
<br />
===Python modules in user space===<br />
Python is an evolving language. Many large systems have old versions for stability reasons, and administrators of such large systems tend to not install all software users may wish, and to not allow access to rpm either. To install a module in your user space, download the tarball, unzip it, cd into the directory and run: <br />
<br />
<pre>python setup.py install --prefix=/path/to/your/place</pre><br />
<br />
The installer will create a subdirectory named <tt>lib</tt>, or <tt>lib64</tt> under the directory above. These <tt>lib*</tt> dirs will have a directory named <tt>python</tt>, or <tt>python2.3</tt> for example, and those will have a subdirectory named <tt>site-packages</tt>. Add all paths to these <tt>site-packages</tt> subdirectories in your <tt>PYTHONPATH</tt> environment variable. Some (<tt>numpy</tt>) may create a <tt>bin</tt> directory that needs to be added to <tt>PATH</tt>.<br />
<br />
=Environment variables=<br />
==Used by the Madagascar core==<br />
Besides RSFROOT, DATAPATH and PYTHONPATH (described in the [[Installation|short Installation guide]]), Madagascar programs may read the variables below. They usually have reasonable defaults and were introduced just to provide more power to the advanced user.<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar's non-graphic programs<br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| RSF_DATASERVER || <nowiki>ftp://egl.beg.utexas.edu/</nowiki> || Data server for benchmark datasets<br />
|-<br />
| RSFDOC || $RSFROOT/doc || Directory for the HTML self-doc<br />
|-<br />
| RSFFIGS || $RSFROOT/figs || Directory with figures for testing<br />
|-<br />
| RSFMEMSIZE || 100 || Maximum RAM (Mb) to be used by some programs <br />
|-<br />
| RSFSRC || undefined || Root of the Madagascar source tree<br />
|-<br />
| TMPDATAPATH || $DATAPATH || Datapath for temporary files on local disk.<br />
|-<br />
| LATEX2HTML || undefined || LateX2HTML customization directory<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="3" style="background:#ffdead;"|Variables introduced by Madagascar graphics programs <br />
|-<br />
| '''Name''' || '''Default''' || Meaning<br />
|-<br />
| DEFAULT_PAPER_SIZE || "letter" || For pspen. Other options: legal, a3, a4, a5.<br />
|-<br />
| FATMULT || ? || Fatness multiplication factor. <br />
|-<br />
| GIFBORDER || 0.25 || For vplot2gif (spacing)<br />
|-<br />
| GIFDELAY || 100 || For vplot2gif (for animations)<br />
|-<br />
| IMAGE_TYPE || 'png' || Icon type for LateX2HTML <br />
|-<br />
| PATTERNMULT || None || Pattern multiplication factor <br />
|-<br />
| PLOTSTYLE || None || Used in vplot<br />
|-<br />
| PPI || 75 || For vplot2gif (screen resolution)<br />
|-<br />
| PPMSCALE || 1 || For vplot2gif<br />
|-<br />
| PSBORDER || 0.05 || For vplot2eps (border around the plot)<br />
|-<br />
| PSPRINTER || postscript or colorps || For pspen<br />
|-<br />
| PSTEXPENOPTS || color=n fat=1 fatmult=1.5 invras=y || Other vplot2eps options <br />
|-<br />
| VPLOTFONTDIR || ? || Dir with backup fonts in case the runtime-loaded vplot fonts are not found<br />
|-<br />
| VPLOTSPOOLDIR || /tmp || Where to put vplot tmp files<br />
|-<br />
| WSTYPE || "default" || Workstation type.<br />
|}<br />
<br />
<br />
{|class="wikitable" align="center" cellspacing="0" border="1"<br />
|-<br />
! colspan="2" style="background:#ffdead;"| Variables set by OS/other apps, read-only to Madagascar<br />
|-<br />
| '''Name''' || '''Primarily used/set by'''<br />
|-<br />
| CWPROOT || Seismic Unix<br />
|-<br />
| DISPLAY || Operating System (OS)<br />
|-<br />
| HOME || OS<br />
|-<br />
| LD_LIBRARY_PATH || linker<br />
|-<br />
| MATLABPATH || Matlab<br />
|-<br />
| XAUTHORITY || X-Windows<br />
|}<br />
<br />
<br />
For future documentation writers: the environment variables read by Madagascar can be found by going to $RSFSRC, temporarily moving the directory <tt>build/</tt> outside RSFSRC, and typing<br />
<bash><br />
grep environ.get *.py */*.py */*/*.py */*/*/*.py<br />
grep getenv */*.c */*/*.c */*/*/*.c<br />
</bash><br />
<br />
==Used by the Madagascar build process==<br />
Type <tt>scons -h</tt> in RSFSRC to get a list of environment variables that affect the build process, with explanations, defaults and actual values. Below are more detailed explanations for some of them:<br />
* <tt>APIFORCE</tt>: If <tt>APIFORCE=y</tt>, those API components that do not have dependencies will be nevertheless installed. This is the case of scripts in interpreted languages which call standalone Madagascar programs. This option is provided for allowing a limited functionality to those who cannot install dependencies, while not annoying those who may want specifically to NOT have an API installed because of namespace conflicts or other reasons.<br />
<br />
==Used by the Matlab API==<br />
To use the Matlab API, you need to add <tt>$RSFROOT/lib</tt> to <tt>MATLABPATH</tt><br />
==Used by the Octave API==<br />
To use the Octave API, you need to add <tt>$RSFROOT/lib</tt> to Octave's path. Determine Octave's version with<br />
<bash><br />
octave -v | head -1<br />
</bash><br />
If your version is lower than 2.9.6, type at a Unix command line:<br />
<bash><br />
echo 'LOADPATH = "::$RSFROOT/lib/octave"' >> ~/.octaverc<br />
</bash><br />
For later versions, use:<br />
<bash><br />
echo 'addpath([getenv("RSFROOT") "/lib/octave"])' >> ~/.octaverc<br />
</bash><br />
==RSFROOT for NFS-shared user home directories==<br />
Heterogeneous networks with user home directories shared through [http://en.wikipedia.org/wiki/Network_File_System_(protocol) NFS] are quite common in many institutions. In addition, even when the architecture is the same (i.e. 64-bit) and the operating system is the same (i.e. [http://en.wikipedia.org/wiki/RHEL RHEL]), the difference between operating system versions may be very significant because clusters may run legacy versions, while desktop workstations may run the latest-and-greatest (even beta), and entirely different Madagascar versions may be needed to support both. <br />
<br />
One possible solution of detecting the distribution version and architecture and setting RSFROOT appropriately is shown below. In the example network, all RHEL4 machines have the same architecture, but there are RHEL 3 machines with several architectures:<br />
<bash><br />
REDHAT_RELEASE=`awk -F'release' '{ print $2 }' /etc/redhat-release | awk -F' ' '{ print $1 }'`<br />
<br />
RSFROOT=/usr/local/rsf/rhel$REDHAT_RELEASE<br />
<br />
if [ $REDHAT_RELEASE == '4' ] ; then<br />
export RSFROOT<br />
elif [ $REDHAT_RELEASE == '3' ] ; then<br />
export RSFROOT=$RSFROOT/$ARCH<br />
fi<br />
</bash><br />
Of course, the Madagascar administrator will have to download appropriate versions of Madagascar to each $RSFROOT, and compile them on the appropriate system.<br />
<br />
=Platform-specific installation advice=<br />
==Supported platforms==<br />
Madagascar attempts to support any [http://en.wikipedia.org/wiki/POSIX POSIX-compliant] operating system demanded by users. For systems that bundle Python (i.e. Linux distributions, BSDs), backwards compatibility will attempt to cover those systems that were bundled with the oldest non-deprecated Python version currently supported by the latest stable version of [http://scons.org/ SCons]. For example, in early 2009 the stable SCons release (1.2) supported Python 2.2 or newer. [http://distrowatch.com/table.php?distribution=redhat Python 2.2 was bundled by RHEL3], so RHEL 3 and newer are supported. <br />
<br />
Attempts for backward compatibility with a given operating system are also stopped if the operating system itself becomes unsupported. For example, Python 2.2 was bundled by Fedora 1 and newer, but currently only Fedora 9 and 10 are actively maintained. Thus, Madagascar does not attempt to support Fedora 1, even though it included Python 2.2.<br />
<br />
Please keep in mind that the above statements constitute only general guidelines for what will be attempted, and do not constitute in any way a warranty of support.<br />
<br />
==Ubuntu 6.06-8.10==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, and considering the [http://www.ubuntu.com/products/whatisubuntu/serveredition/benefits/lifecycle Ubuntu Life Cycle], Madagascar will attempt to support:<br />
* Ubuntu 6.06 LTS Desktop until end of June 2009<br />
* Ubuntu 6.06 LTS Server until end of June 2011 or until SCons stops supporting Python 2.4, whichever comes sooner<br />
* Ubuntu 7.10 until end of April 2009<br />
* Ubuntu 8.04 LTS Desktop until end of April 2011 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 8.04 LTS Server until end of April 2013 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 8.10 until end of April 2010 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 9.04 until end of October 2010 or until SCons stops supporting Python 2.5, whichever comes sooner<br />
* Ubuntu 9.10 until end of April 2011 or until SCons stops supporting its Python version, whichever comes sooner<br />
<br />
You can install all of Madagascar's dependencies by running<br />
<pre><br />
sudo apt-get install g++ g77 libc6-dev libjpeg62-dev libx11-dev libxaw7-dev libnetpbm10-dev swig python-dev python-scipy python-numpy units<br />
</pre><br />
<br />
==Fedora 9, 10==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, Madagascar will attempt to support the last two versions of Fedora (currently 9 and 10). Considering the [http://fedoraproject.org/wiki/LifeCycle Fedora Life Cycle] (release X maintained until one month after the release of X+2) and the [http://fedoraproject.org/wiki/Releases/11/Schedule Fedora 11 schedule], Fedora 9 should be dropped and Fedora 11 should be supported starting with 2009-06-26.<br />
<br />
You can install the common dependencies for both the stable version and the development one, by typing as root:<br />
<pre><br />
yum -y install atlas atlas-devel binutils blas blas-devel freeglut freeglut-devel gcc \<br />
gcc-c++ gcc-gfortran glibc-headers libjpeg-devel libXaw-devel netpbm-devel numpy octave \<br />
octave-devel scipy scons swig texlive units <br />
</pre><br />
Packages that are already installed will be ignored.<br />
<br />
To install LaTeX for building papers and books, you need <tt>texlive-latex</tt> .<br />
<br />
If you are using the development version, you also need the <tt>subversion</tt> package. If you are installing on a multicore machine, you will get a speedup if you install <tt>libgomp</tt>.<br />
<br />
==CentOS 3, 4, 5==<br />
Given that CentOS is a clone of RHEL, it is expected it will have the same lifecycle (7 years of support after release), CentOS 5 should be supported by Madagascar until 2014-03-14, or until SCons stable version ceases to support Python 2.4 &ndash; whichever comes first. CentOS 4 should be supported until 2012-02-15 or until SCons stable drops support for 2.3. CentOS 3 should be supported until 2010-10-22 or until SCons stable drops support for Python 2.2, whichever comes first.<br />
<br />
To install and maintain the crucial SCons dependency using package management, you first need to [http://dag.wieers.com/rpm/FAQ.php#B2 add RPMforge's RHEL5 repository] to your local list .<br />
<br />
Dependencies can be installed from the repositories with:<br />
<pre><br />
yum -y install binutils freeglut freeglut-devel gcc gcc-c++ gcc-gfortran \<br />
glibc-headers libjpeg-devel libXaw-devel netpbm-devel scons units <br />
</pre><br />
A few dependencies ( <tt>octave</tt>, <tt>octave-devel</tt>, <tt>numpy</tt>, <tt>scipy</tt> and <tt>units</tt>) are not in the repositories, so they must be searched for and installed manually if you need them. Fortunately, none of the missing packages is crucial enough to stop the core Madagascar installation; they are needed only by optional components.<br />
<br />
==Debian 4, 5==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, Madagascar will attempt to support Debian 4 until it stops being supported by its developers (end 2009-beg. 2010), and Debian 5 until it stops being supported by the Debian project or SCons stops supporting Python 2.5, whatever comes sooner.<br />
<br />
Specific dependencies:<br />
* Debian 4.0 ("Etch"): In order to build xtpen (for displaying .vpl images) you will need the <tt>libXaw7-dev</tt> package.<br />
* Debian 5.0 ("Lenny"): Please make sure you have the <tt>libc6-dev</tt> package before trying to compile from source.<br />
<br />
==openSUSE 11.0, 11.1==<br />
Under the [[Advanced_Installation#Supported_platforms | platform support guidelines]] above, and given that [http://en.opensuse.org/SUSE_Linux_Lifetime openSUSE releases have a lifetime of 2 years], Madagascar should theoretically attempt to support openSUSE 10.3 until 2009-10-31, openSUSE 11.0 until 2010-06-30, and openSUSE 11.1 until 2010-12-31. In practice, due to limited resources, installation has only been verified on openSUSE 11.0 and 11.1.<br />
<br />
The development version of m8r has dependencies beyond the packages installed by the default openSUSE 11.0 DVD install:<br />
* To download the development version, you need <tt>subversion</tt><br />
* To compile the package, you need <tt>scons</tt> and <tt>gcc</tt><br />
* To install the C++ API, you need <tt>gcc-c++</tt><br />
* To install the Octave API, you need <tt>octave</tt><br />
* To install <tt>sfbyte2jpg</tt> and <tt>sfjpg2byte</tt> you need <tt>libjpeg-devel</tt><br />
* To install the vplot graphics, you need <tt>xorg-x11-devel</tt><br />
* To install LaTeX for building papers and books, you need <tt>texlive-latex</tt><br />
<br />
Packages can be installed by running as root <tt>zypper install <package name></tt>. The graphical front-end to Zypper integrated with YaST2 can of course be used as well (Geeko button... Applications... System... Configuration... Install Software)<br />
<br />
==Mac OS X==<br />
First of all, a [https://sourceforge.net/project/showfiles.php?group_id=162909 Mac OS X precompiled binary package] of the latest Madagascar stable release is available for download from SourceForge. If you want to install a development version of Madagascar, the following might help. <br />
<br />
# <b>C compiler</b> for Mac OS X. One can download the precompiled binary package of <b>Xcode</b> tools, including the <b>gcc</b> compiler, from [http://developer.apple.com/tools/xcode/ Apple]. Another way is to use [http://www.finkproject.org/ Fink], a tool that brings the full world of Unix Open Source software to Mac OS X. <br />
# [http://subversion.tigris.org/ Subversion] client for Mac OS X. There are two methods to install Subversion in Mac OS X: you can use <b>Fink</b> to update <b>Subversion client</b> package or the precompiled binary. Some useful information can be found on the [http://www.wikihow.com/Install-Subversion-on-Mac-OS-X Wikihow website] and [http://downloads.open.collab.net/binaries.html Collab]. You can use <b>Subversion</b> to [[Download#Current_development_version|download the development version]] of the <tt>Madagascar</tt> source code. Next, follow [[Installation|Installation instructions]] to install. <br />
# [[SEGTeX]], a <b>LaTeX</b> package for geophysical publications. To use <b>SEGTeX</b>, you may need [http://www.tug.org/texlive/ TeX Live]. <b>Fink</b> provides a easy way to install it with the command <tt>fink install texlive</tt>.<br />
<br />
==MS Windows==<br />
Due to its size, this topic has been assigned [[Windows | its own Wiki page]].<br />
<br />
=Multi-user installs=<br />
Some organizations may find it desirable to deny write access of some users to all RSFSRC/RSFROOT except their own user directory. Fortunately, this can be easily done by placing the restricted user dirs outside RSFSRC/RSFROOT, i.e. in their home dirs, say /home/joe/rsfsrc. In order to move a user's directory out of RSFSRC, you must:<br />
* "tell" the SConstruct in the user's dir where to find RSFSRC so that when the user builds in his directory, it can import <tt>configure.py</tt> and <tt>config.py</tt> You do that by setting the environment variable RSFSRC to the absolute path of the Madagascar source root, and by making sure that lines 2 and 3 in the users' SConstruct files are<br />
<python><br />
srcroot = os.environ.get('RSFSRC', '../..')<br />
sys.path.append(srcroot)<br />
</python> <br />
and then replace <tt>../..</tt> throughout the SConstruct using <tt>os.path.join</tt> and the <tt>srcroot</tt> variable.<br />
* "tell" the build scripts about the user's dir, so that it is included in the builds launched from RSFSRC. You do that with a symbolic link:<br />
<bash><br />
ln -s /home/joe/rsfsrc $RSFSRC/user/joe<br />
</bash><br />
''When the link exists'', those of Joe's programs that are mentioned in the "prog" string in SConstruct get included in the distribution, complete with self-doc. If Joe is just learning how to code and his stuff breaks the build, just remove the symbolic link. Even if build+installs are done after the link is removed, his stable programs and self-doc will continue to remain installed system-wide as long as the admin does not type <tt>scons -c install</tt> (not likely).<br />
* point the user's RSFDOC environment variable to a location where the user has write access<br />
* edit the users' SConstruct so that it uses the RSF library and headers already installed in $RSFROOT/lib and $RSFROOT/include , instead of building again the whole <tt>librsf</tt> with user-specific flags in <tt>RSFSRC/filt/lib/</tt>. To do that, replace in the user's SConstruct the env.Prepend statement with<br />
<python><br />
rsfroot = os.environ.get('RSFROOT','/usr/local/rsf')<br />
<br />
env.Prepend(CPPPATH=[os.path.join(rsfroot,'include')],<br />
LIBPATH=[os.path.join(rsfroot,'lib')],<br />
LIBS=['rsf'])<br />
</python><br />
* If the link from RSFSRC to Joe's directory was not made, add Joe's directory to his own path so that he can execute his own binaries.<br />
<br />
To understand how $DATAPATH disk space issues may become an issue in a multi-user environment, refer to the [[Advanced_Installation#Disk_space|Disk Space subsection]] at the beginning of this document.<br />
<br />
=Capturing error and warning messages=<br />
The messages during configuration are few and their importance quite high, so they should be watched "in person". A complete log of the configuration process is recorded in RSFSRC/configure.log<br />
<br />
Console messages generated during the build step can be captured to a log file as follows:<br />
<bash><br />
nice +10 nohup /usr/bin/time -p scons >& log_build.asc &<br />
</bash><br />
The log file can be of course named otherwise than <tt>log_build.asc</tt>. The file can be later grepped for error and warnings with commands such as:<br />
<bash><br />
grep -c error log_build.asc<br />
grep error log_build.asc | awk '/error.c/ {next}; /error.h/ {next}; /error.o/ {next}; {print}'<br />
grep -c warning log_build.asc<br />
grep warning log_build.asc | awk '/imaginary constants are a GCC extension/ {next}; {print}'<br />
</bash><br />
<br />
=Advanced troubleshooting=<br />
* If you removed one of your programs or changed its name, and <tt>scons install</tt> fails with "Source <tt>oldprogname</tt> not found, needed by target install", and you cleaned everything there was to clean but still get this message, remove <tt>RSFSRC/.sconsign*</tt><br />
* If during <tt>scons install</tt> you get a <tt>DBAccessError : (13, 'Permission denied')</tt> in some reproducible papers, check permissions in your <tt>$DATAPATH</tt> directory. This is where SCons places database ".sconsign" files for its dependencies (according to the rules in rsfproj and rsftex).<br />
<br />
=Further support=<br />
Subscribe to the [https://lists.sourceforge.net/lists/listinfo/rsf-user rsf-user mailing list].</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Guide_to_madagascar_programs&diff=711Guide to madagascar programs2009-03-12T18:35:56Z<p>Jenningsjwj: /* sfsizes */</p>
<hr />
<div><center><font size="-1">''This page was created from the LaTeX source in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/rsf/rsf/prog.tex?view=markup book/rsf/rsf/prog.tex] using [[latex2wiki]]''</font></center><br />
<br />
This guide introduces some of the most used <tt>madagascar</tt> programs and illustrates their usage with examples.<br />
=Main programs=<br />
The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/ system/main] in the Madagascar distribution. The "main" programs perform general-purpose operations on RSF hypercubes regardless of the data dimensionality or physical dimensions.<br />
<br />
==sfadd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Add, multiply, or divide RSF datasets.<br />
|-<br />
! colspan="4" | sfadd > out.rsf scale= add= sqrt= abs= log= exp= mode= [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | The various operations, if selected, occur in the following order:<br><br>(1) Take absolute value, abs=<br>(2) Add a scalar, add=<br>(3) Take the natural logarithm, log=<br>(4) Take the square root, sqrt=<br>(5) Multiply by a scalar, scale=<br>(6) Compute the base-e exponential, exp=<br>(7) Add, multiply, or divide the data sets, mode=<br><br>sfadd operates on integer, float, or complex data, but all the input<br>and output files must be of the same data type.<br><br>An alternative to sfadd is sfmath, which is more versatile, but may be<br>less efficient.<br />
|-<br />
| ''bools '' || '''abs=''' || || If true take absolute value [nin]<br />
|-<br />
| ''floats '' || '''add=''' || || Scalar values to add to each dataset [nin]<br />
|-<br />
| ''bools '' || '''exp=''' || || If true compute exponential [nin]<br />
|-<br />
| ''bools '' || '''log=''' || || If true take logarithm [nin]<br />
|-<br />
| ''string '' || '''mode=''' || || 'a' means add (default), <br> 'p' or 'm' means multiply, <br> 'd' means divide<br />
|-<br />
| ''floats '' || '''scale=''' || || Scalar values to multiply each dataset with [nin]<br />
|-<br />
| ''bools '' || '''sqrt=''' || || If true take square root [nin]<br />
|}<br />
<br />
<tt>sfadd</tt> is useful for combining (adding, dividing, or<br />
multiplying) several datasets. What if you want to subtract two<br />
datasets? Easy. Use the <tt>scale</tt> parameter as follows:<br />
<pre><br />
bash&#36; sfadd data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfadd < data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
The same task can be accomplished with the more general <tt>sfmath</tt> program:<br />
<pre><br />
bash&#36; sfmath one=data1.rsf two=data2.rsf output='one-two' > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfmath < data1.rsf two=data2.rsf output='input-two' > diff.rsf<br />
</pre><br />
In both cases, the size and shape of <tt>data1.rsf</tt> and<br />
<tt>data2.rsf</tt> hypercubes should be the same, and a warning<br />
message is printed out if the the axis sampling parameters (such as<br />
<tt>o1</tt> or <tt>d1</tt>) in these files are different.<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/add.c?view=markup user/main/add.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
/* find number of input files */<br />
if (isatty(fileno(stdin))) { <br />
/* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Collect input files in the <tt>in</tt> array from all command-line<br />
parameters that don't contain an "<tt>=</tt>" sign. The total number<br />
of input files in <tt>nin</tt>.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) continue; <br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
/* nin = no of input files*/<br />
</c><br />
<br />
A helper function <tt>check_compat</tt> checks the compatibility of<br />
input files.<br />
<c><br />
static void <br />
check_compat (sf_datatype type /* data type */, <br />
size_t nin /* number of files */, <br />
sf_file* in /* input files [nin] */, <br />
int dim /* file dimensionality */, <br />
const int* n /* dimensions [dim] */)<br />
/* Check that the input files are compatible. <br />
Issue error for type mismatch or size mismatch.<br />
Issue warning for grid parameters mismatch. */<br />
{<br />
int ni, id;<br />
size_t i;<br />
float d, di, o, oi;<br />
char key[3];<br />
const float tol=1.e-5; /* tolerance for comparison */<br />
<br />
for (i=1; i < nin; i++) {<br />
if (sf_gettype(in[i]) != type) <br />
sf_error ("type mismatch: need %d",type);<br />
for (id=1; id <= dim; id++) {<br />
(void) snprintf(key,3,"n%d",id);<br />
if (!sf_histint(in[i],key,&ni) || ni != n[id-1])<br />
sf_error("%s mismatch: need %d",key,n[id-1]);<br />
(void) snprintf(key,3,"d%d",id);<br />
if (sf_histfloat(in[0],key,&d)) {<br />
if (!sf_histfloat(in[i],key,&di) || <br />
(fabsf(di-d) > tol*fabsf(d)))<br />
sf_warning("%s mismatch: need %g",key,d);<br />
} else {<br />
d = 1.;<br />
}<br />
(void) snprintf(key,3,"o%d",id);<br />
if (sf_histfloat(in[0],key,&o) && <br />
(!sf_histfloat(in[i],key,&oi) || <br />
(fabsf(oi-o) > tol*fabsf(d))))<br />
sf_warning("%s mismatch: need %g",key,o);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
Finally, we enter the main loop, where input data are getting read<br />
buffer by buffer and combined in the total product depending on the<br />
data type.<br />
<c><br />
for (nbuf /= sf_esize(in[0]); nsiz > 0; nsiz -= nbuf) {<br />
if (nbuf > nsiz) nbuf=nsiz;<br />
<br />
for (j=0; j < nin; j++) {<br />
collect = (bool) (j != 0);<br />
switch(type) {<br />
case SF_FLOAT:<br />
sf_floatread((float*) bufi,<br />
nbuf,<br />
in[j]); <br />
add_float(collect, <br />
nbuf,<br />
(float*) buf,<br />
(const float*) bufi, <br />
cmode, <br />
scale[j], <br />
add[j], <br />
abs_flag[j], <br />
log_flag[j], <br />
sqrt_flag[j], <br />
exp_flag[j]);<br />
break;<br />
</c><br />
<br />
The data combination program for floating point numbers is<br />
<tt>add_float</tt>. <br />
<c><br />
static void add_float (bool collect, /* if collect */<br />
size_t nbuf, /* buffer size */<br />
float* buf, /* output [nbuf] */<br />
const float* bufi, /* input [nbuf] */ <br />
char cmode, /* operation */<br />
float scale, /* scale factor */<br />
float add, /* add factor */<br />
bool abs_flag, /* if abs */<br />
bool log_flag, /* if log */<br />
bool sqrt_flag, /* if sqrt */<br />
bool exp_flag /* if exp */)<br />
/* Add floating point numbers */<br />
{<br />
size_t j;<br />
float f;<br />
<br />
for (j=0; j < nbuf; j++) {<br />
f = bufi[j];<br />
if (abs_flag) f = fabsf(f);<br />
f += add;<br />
if (log_flag) f = logf(f);<br />
if (sqrt_flag) f = sqrtf(f);<br />
if (1. != scale) f *= scale;<br />
if (exp_flag) f = expf(f);<br />
if (collect) {<br />
switch (cmode) {<br />
case 'p': /* product */<br />
case 'm': /* multiply */<br />
buf[j] *= f;<br />
break;<br />
case 'd': /* delete */<br />
if (f != 0.) buf[j] /= f;<br />
break;<br />
default: /* add */<br />
buf[j] += f;<br />
break;<br />
}<br />
} else {<br />
buf[j] = f;<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display dataset attributes.<br />
|-<br />
! colspan="4" | sfattr < in.rsf want=<br />
|-<br />
| colspan="4" | <br>Sample output from "sfspike n1=100 | sfbandpass fhi=60 | sfattr"<br>******************************************* <br>rms = 0.992354 <br>mean value = 0.987576 <br>2-norm value = 9.92354 <br>variance = 0.00955481 <br>standard deviation = 0.0977487 <br>maximum value = 1.12735 at 97 <br>minimum value = 0.151392 at 100 <br>number of nonzero samples = 100 <br>total number of samples = 100 <br>******************************************* <br><br>rms = sqrt[ sum(data^2) / n ]<br>mean = sum(data) / n<br>norm = sum(abs(data)^lval)^(1/lval)<br>variance = [ sum(data^2) - n*mean^2 ] / [ n-1 ]<br>standard deviation = sqrt [ variance ]<br />
|-<br />
| ''int '' || '''lval=2''' || || norm option, lval is a non-negative integer, computes the vector lval-norm<br />
|-<br />
| ''string '' || '''want=''' || || 'all'(default),'rms','mean','norm','var','std','max','min','nonzero','samples','short' <br />
:want= 'rms' displays the root mean square<br />
:want= 'norm' displays the square norm, otherwise specified by lval.<br />
:want= 'var' displays the variance<br />
:want= 'std' displays the standard deviation<br />
:want= 'nonzero' displays number of nonzero samples<br />
:want= 'samples' displays total number of samples<br />
:want= 'short' displays a short one-line version<br />
|}<br />
<br />
<br />
<tt>sfattr</tt> is a useful diagnostic program. It reports certain<br />
statistical values for an RSF dataset: RMS (root-mean-square)<br />
amplitude, mean value, vector norm value, variance, standard deviation,<br />
maximum and minimum values, number of nonzero samples, and the total<br />
number of samples.<br />
If we denote data values as <math>d_i</math> for <math>i=0,1,2,\ldots,n</math>, then the RMS<br />
value is <math>\sqrt{\frac{1}{n}\,\sum\limits_{i=0}^n d_i^2}</math>, the mean<br />
value is <math>\frac{1}{n}\,\sum\limits_{i=0}^n d_i</math>, the <math>L_2</math>-norm value<br />
is <math>\sqrt{\sum\limits_{i=0}^n d_i^2}</math>, the variance is<br />
<math>\frac{1}{n-1}\,\left[\sum\limits_{i=0}^n d_i^2 - \frac{1}{n}\left(\sum\limits_{i=0}^n d_i\right)^2\right]</math>, and the standard<br />
deviation is the square root of the variance. Using <tt>sfattr</tt><br />
is a quick way to see the distribution of data values and check it for<br />
anomalies.<br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/attr.c?view=markup user/main/attr.c]====<br />
<br />
Computations start by finding the input data (<tt>in</tt>) size<br />
(<tt>nsiz</tt>) and dimensions (<tt>dim</tt>).<br />
<c><br />
dim = (size_t) sf_filedims (in,n);<br />
for (nsiz=1, i=0; i < dim; i++) {<br />
nsiz *= n[i];<br />
}<br />
</c><br />
<br />
<br />
In the main loop, we read the input data buffer by buffer.<br />
<c><br />
for (nleft=nsiz; nleft > 0; nleft -= nbuf) {<br />
nbuf = (bufsiz < nleft)? bufsiz: nleft;<br />
switch (type) {<br />
case SF_FLOAT: <br />
sf_floatread((float*) buf,nbuf,in);<br />
break;<br />
case SF_INT:<br />
sf_intread((int*) buf,nbuf,in);<br />
break;<br />
case SF_COMPLEX:<br />
sf_complexread((sf_complex*) buf,nbuf,in);<br />
break;<br />
case SF_UCHAR:<br />
sf_ucharread((unsigned char*) buf,nbuf,in);<br />
break;<br />
case SF_CHAR:<br />
default:<br />
sf_charread(buf,nbuf,in);<br />
break;<br />
}<br />
</c><br />
<br />
<br />
The data attributes are accumulated in corresponding double-precision<br />
variables. <br />
<c><br />
fsum += f;<br />
fsqr += f*f;<br />
</c><br />
<br />
<br />
Finally, the attributes are reduced and printed out.<br />
<c><br />
fmean = fsum/nsiz;<br />
if (lval==2) fnorm = sqrt(fsqr);<br />
else if (lval==0) fnorm = nsiz-nzero;<br />
else fnorm = pow(flval,1./lval);<br />
frms = sqrt(fsqr/nsiz);<br />
if (nsiz > 1) fvar = (fsqr-nsiz*fmean*fmean)/(nsiz-1);<br />
else fvar = 0.0;<br />
fstd = sqrt(fvar);<br />
</c><br />
<br />
<c><br />
if(NULL==want || 0==strcmp(want,"rms"))<br />
printf("rms = %g \n",(float) frms);<br />
if(NULL==want || 0==strcmp(want,"mean"))<br />
printf("mean value = %g \n",(float) fmean);<br />
if(NULL==want || 0==strcmp(want,"norm"))<br />
printf("%d-norm value = %g \n",lval,(float) fnorm);<br />
if(NULL==want || 0==strcmp(want,"var"))<br />
printf("variance = %g \n",(float) fvar);<br />
if(NULL==want || 0==strcmp(want,"std"))<br />
printf("standard deviation = %g \n",(float) fstd);<br />
</c><br />
<br />
==sfcat==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Concatenate datasets. <br />
|-<br />
! colspan="4" | sfcat > out.rsf space= axis=3 nspace=(int) (ni/(20*nin) + 1) [<file0.rsf] file1.rsf file2.rsf ... <br />
|-<br />
| colspan="4" | sfmerge inserts additional space between merged data.<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis being merged<br />
|-<br />
| ''int '' || '''nspace=(int) (ni/(20*nin) + 1)''' || || if space=y, number of traces to insert<br />
|-<br />
| ''bool '' || '''space=''' || [y/n] || Insert additional space.<br />
:y is default for sfmerge, n is default for sfcat<br />
|}<br />
<br />
<br />
<tt>sfcat</tt> and <tt>sfmerge</tt> concatenate two or more files<br />
together along a particular axis. It is the same program, only<br />
<tt>sfcat</tt> has the default <tt>space=n</tt> and <tt>sfmerge</tt><br />
has the default <tt>space=y</tt>.<br />
Example of <tt>sfcat</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcat one.rsf one.rsf axis=1 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=4 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
12 elements 48 bytes<br />
</pre><br />
Example of <tt>sfmerge</tt>:<br />
<pre><br />
bash$ sfmerge one.rsf one.rsf axis=2 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=7 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
14 elements 56 bytes<br />
</pre><br />
In this case, an extra empty trace is inserted between the two merged files.<br />
The axes that are not being merged are checked for consistency:<br />
<pre><br />
bash$ sfcat one.rsf two.rsf > three.rsf<br />
sfcat: n2 mismatch: need 3<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cat.c?view=markup user/main/cat.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
in = (sf_file*) sf_alloc ((size_t) argc,sizeof(sf_file));<br />
<br />
if (!sf_stdin()) { /* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Everything on the command line that does not contain a "=" sign is<br />
treated as a file name, and the corresponding file object is added to the list.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) <br />
continue; /* not a file */<br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
</c><br />
<br />
As explained above, if the <tt>space=</tt> parameter is not set, it is<br />
inferred from the program name: <tt>sfmerge</tt> corresponds to<br />
<tt>space=y</tt> and <tt>sfcat</tt> corresponds to <tt>space=n</tt>.<br />
<c><br />
if (!sf_getbool("space",&space)) {<br />
/* Insert additional space.<br />
y is default for sfmerge, n is default for sfcat */<br />
prog = sf_getprog();<br />
if (NULL != strstr (prog, "merge")) {<br />
space = true;<br />
} else if (NULL != strstr (prog, "cat")) {<br />
space = false;<br />
} else {<br />
sf_warning("%s is neither merge nor cat,"<br />
" assume merge",prog);<br />
space = true;<br />
}<br />
}<br />
</c><br />
<br />
Find the axis for the merging (from the command line <tt>axis=</tt><br />
argument) and figure out two sizes: <tt>n1</tt> for everything after<br />
the axis and <tt>n2</tt> for everything before the axis.<br />
<c><br />
n1=1;<br />
n2=1;<br />
for (i=1; i <= dim; i++) {<br />
if (i < axis) n1 *= n[i-1];<br />
else if (i > axis) n2 *= n[i-1];<br />
}<br />
</c><br />
<br />
In the output, the selected axis will get extended.<br />
<c><br />
/* figure out the length of extended axis */<br />
ni = 0;<br />
for (j=0; j < nin; j++) {<br />
ni += naxis[j];<br />
}<br />
<br />
if (space) {<br />
if (!sf_getint("nspace",&nspace)) <br />
nspace = (int) (ni/(20*nin) + 1);<br />
/* if space=y, number of traces to insert */ <br />
ni += nspace*(nin-1);<br />
} <br />
<br />
(void) snprintf(key,3,"n%d",axis);<br />
sf_putint(out,key,(int) ni);<br />
</c><br />
<br />
The rest is simple: loop through the datasets reading and writing the<br />
data in buffer-size chunks and adding extra empty chunks if<br />
<tt>space=y</tt>.<br />
<c><br />
for (i2=0; i2 < n2; i2++) {<br />
for (j=0; j < nin; j++) {<br />
for (ni = n1*naxis[j]*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charread (buf,nbuf,in[j]);<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
if (!space || j == nin-1) continue;<br />
/* Add spaces */<br />
memset(buf,0,BUFSIZ);<br />
for (ni = n1*nspace*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfcmplx==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a complex dataset from its real and imaginary parts.<br />
|-<br />
! colspan="4" | sfcmplx > cmplx.rsf real.rsf imag.rsf<br />
|-<br />
| colspan="4" | There has to be only two input files specified and no additional parameters.<br />
|}<br />
<br />
<br />
<tt>sfcmplx</tt> simply creates a complex dataset from its real and<br />
imaginary parts. The reverse operation can be accomplished with<br />
<tt>sfreal</tt> and <tt>sfimag</tt>.<br />
Example of <tt>sfcmplx</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcmplx one.rsf one.rsf > cmplx.rsf<br />
bash$ sfin cmplx.rsf<br />
cmplx.rsf:<br />
in="/tmp/cmplx.rsf@"<br />
esize=8 type=complex form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 48 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cmplx.c?view=markup user/main/cmplx.c]====<br />
The program flow is simple. First, get the names of the input files.<br />
<c><br />
/* the first two non-parameters are real and imaginary files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == real) {<br />
real = sf_input (argv[i]);<br />
} else {<br />
imag = sf_input (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == imag) {<br />
if (NULL == real) sf_error ("not enough input");<br />
/* if only one input, real is in stdin */<br />
imag = real;<br />
real = sf_input("in");<br />
}<br />
</c><br />
<br />
The main part of the program reads the real and imaginary parts buffer by buffer and assembles and writes out the complex input. <br />
<c><br />
for (nleft= (size_t) (rsize*resize); nleft > 0; nleft -= nbuf) {<br />
nbuf = (BUFSIZ < nleft)? BUFSIZ: nleft;<br />
sf_charread(rbuf,nbuf,real);<br />
sf_charread(ibuf,nbuf,imag);<br />
for (i=0; i < nbuf; i += resize) {<br />
memcpy(cbuf+2*i, rbuf+i,(size_t) resize);<br />
memcpy(cbuf+2*i+resize,ibuf+i,(size_t) resize);<br />
}<br />
sf_charwrite(cbuf,2*nbuf,cmplx);<br />
}<br />
</c><br />
<br />
==sfconjgrad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic conjugate-gradient solver for linear inversion <br />
|-<br />
! colspan="4" | sfconjgrad < dat.rsf mod=mod.rsf > to.rsf < from.rsf > out.rsf niter=1<br />
|-<br />
| ''int '' || '''niter=1''' || || number of iterations<br />
|}<br />
<br />
<br />
<tt>sfconjgrad</tt> is a generic program for least-squares linear<br />
inversion with the conjugate-gradient method. Suppose you have an<br />
executable program <tt><prog></tt> that takes an RSF file from the<br />
standard input and produces an RSF file in the standard output. It may<br />
take any number of additional parameters but one of them must be<br />
<tt>adj=</tt> that sets the forward (<tt>adj=0</tt>) or adjoint<br />
(<tt>adj=1</tt>) operations. The program <tt><prog></tt> is typically<br />
an RSF program but it could be anything (a script, a multiprocessor<br />
MPI program, etc.) as long as it implements a linear operator<br />
<math>\mathbf{L}</math> and its adjoint. There are no restrictions on the data<br />
size or shape. You can easily test the adjointness with<br />
<tt>sfdottest</tt>. The <tt>sfconjgrad</tt> program searches for a<br />
vector <math>\mathbf{m}</math> that minimizes the least-square misfit <br />
<math>\|\mathbf{d - L\,m}\|^2</math> for the given input data vector <math>\mathbf{d}</math>.<br />
Here is an example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
The <tt>sfdottest</tt> program can perform the dot product test to<br />
check that the adjoint mode works correctly.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=5.28394<br />
sfdottest: L'[d]*m=5.28394<br />
</pre><br />
Your numbers may be different because <tt>sfdottest</tt> generates new<br />
random input on each run.<br />
Next, let us make some random data with <tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfnoise seed=2005 rep=y < vec.rsf > dat.rsf<br />
</pre><br />
and try to invert the filtering operation using <tt>sfconjgrad</tt>:<br />
<pre><br />
bash$ sfconjgrad sfhelicon filt=flt.rsf lag=lag.rsf \<br />
mod=vec.rsf < dat.rsf > mod.rsf niter=10<br />
sfconjgrad: iter 1 of 10<br />
sfconjgrad: grad=3253.65<br />
sfconjgrad: iter 2 of 10<br />
sfconjgrad: grad=289.421<br />
sfconjgrad: iter 3 of 10<br />
sfconjgrad: grad=92.3481<br />
sfconjgrad: iter 4 of 10<br />
sfconjgrad: grad=36.9417<br />
sfconjgrad: iter 5 of 10<br />
sfconjgrad: grad=18.7228<br />
sfconjgrad: iter 6 of 10<br />
sfconjgrad: grad=11.1794<br />
sfconjgrad: iter 7 of 10<br />
sfconjgrad: grad=7.26941<br />
sfconjgrad: iter 8 of 10<br />
sfconjgrad: grad=5.15945<br />
sfconjgrad: iter 9 of 10<br />
sfconjgrad: grad=4.23055<br />
sfconjgrad: iter 10 of 10<br />
sfconjgrad: grad=3.57495<br />
</pre><br />
The output shows that, in 10 iterations, the norm of the gradient vector decreases by almost 1000. <br />
We can check the residual misfit before<br />
<pre><br />
bash$ < dat.rsf sfattr want=norm<br />
norm value = 49.7801<br />
</pre><br />
and after<br />
<pre><br />
bash$ sfhelicon filt=flt.rsf lag=lag.rsf < mod.rsf | \<br />
sfadd scale=1,-1 dat.rsf | sfattr want=norm<br />
norm value = 5.73563<br />
</pre><br />
In 10 iterations, the misfit decreased by an order of magnitude. The<br />
result can be improved by running the program for more iterations.<br />
<br />
==sfcp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Copy or move a dataset.<br />
|-<br />
! colspan="4" | sfcp in.rsf out.rsf<br />
|-<br />
| colspan="4" | sfcp - copy, sfmv - move.<br>Mimics standard Unix commands.<br />
|}<br />
<br />
<br />
The <tt>sfcp</tt> and <tt>sfmv</tt> command imitate the Unix<br />
<tt>cp</tt> and <tt>mv</tt> commands and serve for copying and moving<br />
RSF files. Example:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcp one.rsf two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
</pre><br />
<br />
==sfcut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of the dataset. <br />
|-<br />
! colspan="4" | sfcut < in.rsf > out.rsf verb=n [j1=1 j2=1 ... f1=0 f2=0 ... n1=n1 n2=n2 ... max1= max2= ... min1= min2= ...]<br />
|-<br />
| colspan="4" | jN defines the jump in N-th dimension<br>fN is the window start<br>nN is the window size<br>minN and maxN is the maximum and minimum in N-th dimension<br><br>Reverse of window. <br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
The <tt>sfcut</tt> command is related to <tt>sfwindow</tt> and has the same<br />
set of arguments only instead of extracting the selected window, it fills it<br />
with zeroes. The size of the input data is preserved. <br />
Examples:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > in.rsf<br />
bash$ < in.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < in.rsf sfcut n1=2 f1=1 n2=3 f2=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 0 0 1 1<br />
15: 1 0 0 1 1<br />
20: 1 0 0 1 1<br />
bash$ < in.rsf sfcut j1=2 | sfdisfil<br />
0: 0 1 0 1 0<br />
5: 0 1 0 1 0<br />
10: 0 1 0 1 0<br />
15: 0 1 0 1 0<br />
20: 0 1 0 1 0<br />
</pre><br />
<br />
==sfdd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert between different formats. <br />
|-<br />
! colspan="4" | sfdd < in.rsf > out.rsf line=8 form= type= format=<br />
|-<br />
| ''string '' || '''form=''' || || ascii, native, xdr<br />
|-<br />
| ''string '' || '''format=''' || || Element format (for conversion to ASCII)<br />
|-<br />
| ''int '' || '''line=8''' || || Number of numbers per line (for conversion to ASCII)<br />
|-<br />
| ''string '' || '''type=''' || || int, float, complex<br />
|}<br />
<br />
<br />
The <tt>sfdd</tt> program is used to change either the form (<tt>ascii</tt>,<br />
<tt>xdr</tt>, <tt>native</tt>) or the type (<tt>complex</tt>, <tt>float</tt>,<br />
<tt>int</tt>, <tt>char</tt>) of the input dataset. <br />
In the example below, we create a plain text (ASCII) file with numbers and<br />
then use <tt>sfdd</tt> to generate an RSF file in <tt>xdr</tt> form with<br />
<tt>complex</tt> numbers. <br />
<pre><br />
bash$ cat test.txt<br />
1 2 3 4 5 6<br />
bash$ echo n1=6 data_format=ascii_int in=test.txt > test.rsf<br />
bash$ sfin test.rsf<br />
test.rsf:<br />
in="test.txt"<br />
esize=0 type=int form=ascii<br />
n1=6 d1=? o1=?<br />
6 elements<br />
bash$ sfdd < test.rsf form=xdr type=complex > test2.rsf<br />
bash$ sfin test2.rsf<br />
test2.rsf:<br />
in="/tmp/test2.rsf@"<br />
esize=8 type=complex form=xdr<br />
n1=3 d1=? o1=?<br />
3 elements 24 bytes<br />
bash$ sfdisfil < test2.rsf<br />
0: 1, 2i 3, 4i 5, 6i<br />
</pre><br />
To learn more about the RSF data format, consult the [[Format| guide to RSF format]].<br />
<br />
==sfdisfil==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Print out data values.<br />
|-<br />
! colspan="4" | sfdisfil < in.rsf number=y col=0 format= header= trailer=<br />
|-<br />
| colspan="4" | <br>Alternatively, use sfdd and convert to ASCII form.<br />
|-<br />
| ''int '' || '''col=0''' || || Number of columns.<br />
:The default depends on the data type:<br />
:10 for int and char,<br />
:5 for float,<br />
:3 for complex<br />
|-<br />
| ''string '' || '''format=''' || || Format for numbers (printf-style).<br />
:The default depends on the data type:<br> "%4d " for int and char,<br> "%13.4g" for float,<br> "%10.4g,%10.4gi" for complex<br />
|-<br />
| ''string '' || '''header=''' || || Optional header string to output before data<br />
|-<br />
| ''bool '' || '''number=y''' || [y/n] || If number the elements<br />
|-<br />
| ''string '' || '''trailer=''' || || Optional trailer string to output after data<br />
|}<br />
<br />
<br />
The <tt>sfdisfil</tt> program simply dumps the data contents to the standard<br />
output in a text form. It is used mostly for debugging purposes to quickly<br />
examine RSF files. Here is an example:<br />
<pre><br />
bash$ sfmath o1=0 d1=2 n1=12 output=x1 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
10: 20 22<br />
</pre><br />
The output format is easily configurable.<br />
<pre><br />
bash$ < test.rsf sfdisfil col=6 number=n format="<br />
0.0 2.0 4.0 6.0 8.0 10.0<br />
12.0 14.0 16.0 18.0 20.0 22.0<br />
</pre><br />
Along with <tt>sfdd</tt>, <tt>sfdisfil</tt> provides a simple way to convert<br />
RSF data to an ASCII form.<br />
<br />
==sfdottest==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic dot-product test for linear operators with adjoints <br />
|-<br />
! colspan="4" | sfdottest mod=mod.rsf dat=dat.rsf > pip.rsf<br />
|}<br />
<br />
<br />
<tt>sfdottest</tt> is a generic dot-product test program for testing<br />
linear operators. Suppose there is an executable program<br />
<tt><prog></tt> that takes an RSF file from the standard input and<br />
produces an RSF file in the standard output. It may take any number of<br />
additional parameters but one of them must be <tt>adj=</tt> that sets<br />
the forward (<tt>adj=0</tt>) or adjoint (<tt>adj=1</tt>) operations.<br />
The program <tt><prog></tt> is typically an RSF program but it could<br />
be anything (a script, a multiprocessor MPI program, etc.) as long as<br />
it implements a linear operator <math>\mathbf{L}</math> and its adjoint<br />
<math>\mathbf{L}^T</math>. The <tt>sfdottest</tt> program is testing the equality<br />
<center><math><br />
d^T\,L\,m = m^T\,L^T\,d<br />
</math></center><br />
by using random vectors <math>\mathbf{m}</math> and <math>\mathbf{d}</math>. You can invoke it with<br />
<pre><br />
bash$ sfdottest <prog> [optional aruments] mod=mod.rsf dat=dat.rsf<br />
</pre><br />
where <tt>mod.rsf</tt> and <tt>dat.rsf</tt> are RSF files that<br />
represent vectors from the model and data spaces. <tt>sfdottest</tt><br />
does not create any temporary files and does not have any restrictive<br />
limitations on the size of the vectors.<br />
Here is an example. We first setup a vector with 100 elements using<br />
<tt>sfspike</tt> and then run <tt>sfdottest</tt> to test the<br />
<tt>sfcausint</tt> program. <tt>sfcausint</tt> implements a linear<br />
operator of causal integration and its adjoint, the anti-causal<br />
integration.<br />
<pre><br />
bash$ sfspike n1=100 > vec.rsf<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1410.2<br />
sfdottest: L'[d]*m=1410.2<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1165.87<br />
sfdottest: L'[d]*m=1165.87<br />
</pre><br />
The numbers are different on subsequent runs because of changing<br />
seed in the random number generator.<br />
Here is a somewhat more complicated example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
Now the <tt>sfdottest</tt> program can perform the dot product test.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=8.97375<br />
sfdottest: L'[d]*m=8.97375<br />
</pre><br />
Here is the same program tested in the inverse filtering mode:<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf inv=y<br />
sfdottest: L[m]*d=15.0222<br />
sfdottest: L'[d]*m=15.0222<br />
</pre><br />
<br />
==sfget==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Output parameters from the header.<br />
|-<br />
! colspan="4" | sfget < in.rsf parform=y par1 par2 ...<br />
|-<br />
| ''bool '' || '''parform=y''' || [y/n] || If y, print out parameter=value. If n, print out value.<br />
|}<br />
<br />
<br />
The <tt>sfget</tt> program extracts a parameter value from an RSF file. It is<br />
useful mostly for scripting. Here is, for example, a quick calculation of the<br />
maximum value on the first axis in an RSF dataset (the output of<br />
<tt>sfspike</tt>) using the standard Unix <tt>bc</tt> calculator.<br />
<pre><br />
bash$ ( sfspike n1=100 | sfget n1 d1 o1; echo "o1+(n1-1)*d1" ) | bc<br />
.396<br />
</pre><br />
See also <tt>sfput</tt>.<br />
<br />
<br />
<br />
==sfheadercut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheadercut mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array of size n2.<br />
|}<br />
<br />
<br />
<tt>sfheadercut</tt> is close to <tt>sfheaderwindow</tt> but instead<br />
of windowing the dataset, it fills the traces specified by the header<br />
mask with zeroes. The size of the input data is preserved.<br />
Here is an example of using <tt>sfheaderwindow</tt> for <br />
zeroing every other trace in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a mask with alternating ones and zeros using<br />
<tt>sfinterleave</tt>.<br />
<pre><br />
bash$ sfspike n1=5 mag=1 | sfdd type=int > ones.rsf<br />
bash$ sfspike n1=5 mag=0 | sfdd type=int > zeros.rsf<br />
bash$ sfinterleave axis=1 ones.rsf zeros.rsf > mask.rsf<br />
bash$ sfdisfil < mask.rsf<br />
0: 1 0 1 0 1 0 1 0 1 0<br />
</pre><br />
Finally, <tt>sfheadercut</tt> zeros the input traces.<br />
<pre><br />
bash$ sfheadercut < input.rsf mask=mask.rsf > output.rsf<br />
bash$ sfdisfil < output.rsf <br />
0: 1 1 1 1 1<br />
5: 0 0 0 0 0<br />
10: 3 3 3 3 3<br />
15: 0 0 0 0 0<br />
20: 5 5 5 5 5<br />
25: 0 0 0 0 0<br />
30: 7 7 7 7 7<br />
35: 0 0 0 0 0<br />
40: 9 9 9 9 9<br />
45: 0 0 0 0 0<br />
</pre><br />
<br />
<br />
<br />
==sfheadersort==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Sort a dataset according to a header key. <br />
|-<br />
! colspan="4" | sfheadersort < in.rsf > out.rsf head=<br />
|-<br />
| ''string '' || '''head=''' || || header file<br />
|}<br />
<br />
<br />
<tt>sfheadersort</tt> is used to sort traces in the input file<br />
according to trace header information. <br />
Here is an example of using<br />
<tt>sfheadersort</tt> for randomly shuffling traces in the input<br />
file. First, let us create an input file with seven traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=7 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7 <br />
</pre><br />
Next, we can create a random file with seven header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=7 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: 0.05256 -0.2879 0.1487 0.4097 0.1548<br />
5: 0.4501 0.2836<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally, we<br />
apply <tt>sfheadersort</tt> to shuffle the input traces.<br />
<pre><br />
bash$ < input.rsf sfheadersort head=random.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 1 1 1 1 1<br />
10: 3 3 3 3 3<br />
15: 5 5 5 5 5<br />
20: 7 7 7 7 7<br />
25: 4 4 4 4 4<br />
30: 6 6 6 6 6<br />
</pre><br />
As expected, the order of traces in the output file corresponds to the<br />
order of values in the header. Thanks to the separation between<br />
headers and data, the operation of <tt>sfheadersort</tt> is optimally<br />
efficient. It first sorts the headers and only then accesses the data,<br />
reading each data trace only once.<br />
<br />
==sfheaderwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheaderwindow mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array os size n2, windowed is n1xm2,<br>where m2 is the number of nonzero elements in mask.<br />
|}<br />
<br />
<br />
<tt>sfheaderwindow</tt> is used to window traces in the input file<br />
according to trace header information. <br />
Here is an example of using <tt>sfheaderwindow</tt> for randomly<br />
selecting part of the traces in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a random file with ten header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=10 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: -0.005768 0.02258 -0.04331 -0.4129 -0.3909<br />
5: -0.03582 0.4595 -0.3326 0.498 -0.3517<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally,<br />
we apply <tt>sfheaderwindow</tt> to window the input traces selecting<br />
only those for which the header is greater than zero.<br />
<pre><br />
bash$ < random.rsf sfmask min=0 > mask.rsf<br />
bash$ < mask.rsf sfdisfil<br />
0: 0 1 0 0 0 0 1 0 1 0<br />
bash$ < input.rsf sfheaderwindow mask=mask.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 7 7 7 7 7<br />
10: 9 9 9 9 9<br />
</pre><br />
In this case, only three traces are selected for the output. Thanks to<br />
the separation between headers and data, the operation of<br />
<tt>sfheaderwindow</tt> is optimally efficient. <br />
<br />
==sfin==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display basic information about RSF files.<br />
|-<br />
! colspan="4" | sfin info=y check=2. trail=y file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | n1,n2,... are data dimensions<br>o1,o2,... are axis origins<br>d1,d2,... are axis sampling intervals<br>label1,label2,... are axis labels<br>unit1,unit2,... are axis units<br />
|-<br />
| ''float '' || '''check=2.''' || || Portion of the data (in Mb) to check for zero values.<br />
|-<br />
| ''bool '' || '''info=y''' || [y/n] || If n, only display the name of the data file.<br />
|-<br />
| ''bool '' || '''trail=y''' || [y/n] || If n, skip trailing dimensions of one<br />
|}<br />
<br />
<br />
<tt>sfin</tt> is one of the most useful programs for operating with<br />
RSF files. It produces quick information on the file hypercube<br />
dimensions and checks the consistency of the associated data file.<br />
Here is an example. Let us create an RSF file and examine it with <tt>sfin</tt>.<br />
<pre><br />
bash$ sfspike n1=100 n2=20 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=100 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
2000 elements 8000 bytes<br />
</pre><br />
<tt>sfin</tt> reports the following information:<br />
<br />
*location of the data file (<tt>/tmp/spike.rsf\@</tt>) <br />
*element size (4 bytes) <br />
*element type (floating point) <br />
*element form (native) <br />
*hypercube dimensions (100 by 20) <br />
*axes scale (0.004 and 0.1) <br />
*axes origin (0 and 0) <br />
*axes labels <br />
*axes units <br />
*total number of elements <br />
*total number of bytes in the data file <br />
Suppose that the file got corrupted by a buggy program and reports<br />
incorrect dimensions. The <tt>sfin</tt> program should be able to<br />
catch the discrepancy.<br />
<pre><br />
bash$ echo n2=100 >> spike.rsf<br />
bash$ sfin spike.rsf > /dev/null<br />
sfin: Actually 8000 bytes, 20% of expected.<br />
</pre><br />
<tt>sfin</tt> also checks the first records in the file for zeros. <br />
<pre><br />
bash$ sfspike n1=100 n2=100 k2=99 > spike2.rsf<br />
bash$ sfin spike2.rsf >/dev/null<br />
sfin: The first 32768 bytes are all zeros<br />
</pre><br />
The number of bytes to check is adjustable<br />
<pre><br />
bash$ sfin spike2.rsf check=0.01 >/dev/null<br />
sfin: The first 16384 bytes are all zeros<br />
</pre><br />
You can also output only the location of the data file. This is<br />
sometimes handy in scripts.<br />
<pre><br />
bash$ sfin spike.rsf spike2.rsf info=n<br />
/tmp/spike.rsf@ /tmp/spike2.rsf@<br />
</pre><br />
An alternative is to use <tt>sfget</tt>, as follows:<br />
<pre><br />
bash$ sfget parform=n in < spike.rsf<br />
/tmp/spike.rsf@<br />
</pre><br />
<br />
==sfinterleave==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Combine several datasets by interleaving.<br />
|-<br />
! colspan="4" | sfinterleave > out.rsf axis=3 [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis for interleaving<br />
|}<br />
<br />
<br />
<tt>sfinterleave</tt> combines two or more datasets by interleaving them on one<br />
of the axes. Here is a quick example:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ sfscale < one.rsf dscale=2 > two.rsf<br />
bash$ sfdisfil < two.rsf<br />
0: 2 2 2 2 2<br />
5: 2 2 2 2 2<br />
10: 2 2 2 2 2<br />
15: 2 2 2 2 2<br />
20: 2 2 2 2 2<br />
bash$ sfinterleave one.rsf two.rsf axis=1 | sfdisfil<br />
0: 1 2 1 2 1<br />
5: 2 1 2 1 2<br />
10: 1 2 1 2 1<br />
15: 2 1 2 1 2<br />
20: 1 2 1 2 1<br />
25: 2 1 2 1 2<br />
30: 1 2 1 2 1<br />
35: 2 1 2 1 2<br />
40: 1 2 1 2 1<br />
45: 2 1 2 1 2<br />
bash$ sfinterleave < one.rsf two.rsf axis=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 1 1 1 1 1<br />
15: 2 2 2 2 2<br />
20: 1 1 1 1 1<br />
25: 2 2 2 2 2<br />
30: 1 1 1 1 1<br />
35: 2 2 2 2 2<br />
40: 1 1 1 1 1<br />
45: 2 2 2 2 2<br />
</pre><br />
<br />
==sfmask==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a mask.<br />
|-<br />
! colspan="4" | sfmask < in.rsf > out.rsf min=-FLT_MAX max=+FLT_MAX<br />
|-<br />
| colspan="4" | <br>Mask is an integer data with ones and zeros. <br>Ones correspond to input values between min and max.<br><br>The output can be used with sfheaderwindow.<br />
|-<br />
| ''float '' || '''max=+FLT_MAX''' || || maximum header value<br />
|-<br />
| ''float '' || '''min=-FLT_MAX''' || || minimum header value<br />
|}<br />
<br />
<br />
<tt>sfmask</tt> creates an integer output of ones and zeros comparing<br />
the values of the input data to specified <tt>min=</tt> and<br />
<tt>max=</tt> parameters. It is useful for <tt>sfheaderwindow</tt> and<br />
in many other applications. Here is a quick example:<br />
<pre><br />
bash$ sfmath n1=10 output="sin(x1)" > sin.rsf<br />
bash$ < sin.rsf sfdisfil<br />
0: 0 0.8415 0.9093 0.1411 -0.7568<br />
5: -0.9589 -0.2794 0.657 0.9894 0.4121<br />
bash$ < sin.rsf sfmask min=-0.5 max=0.5 | sfdisfil<br />
0: 1 0 0 1 0 0 1 0 0 1<br />
</pre><br />
<br />
==sfmath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations on data files.<br />
|-<br />
! colspan="4" | sfmath > out.rsf type= unit= output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs, conj (for complex data).<br> <br>sfmath will work on float or complex data, but all the input and output<br>files must be of the same data type.<br><br>An alternative to sfmath is sfadd, which may be more efficient, but is<br>less versatile.<br><br>Examples:<br><br>sfmath x=file1.rsf y=file2.rsf power=file3.rsf output='sin((x+2*y)^power)' > out.rsf<br>sfmath < file1.rsf tau=file2.rsf output='exp(tau*input)' > out.rsf<br>sfmath n1=100 type=complex output="exp(I*x1)" > out.rsf<br><br>See also: sfheadermath.<br />
|-<br />
| ''string '' || '''output=''' || || Mathematical description of the output<br />
|-<br />
| ''string '' || '''type=''' || || output data type [float,complex]<br />
|-<br />
| ''string '' || '''unit=''' || || <br />
|}<br />
<br />
<tt>sfmath</tt> is a versatile program for mathematical operations<br />
with RSF files. It can operate with several input file, all of the<br />
same dimensions and data type. The data type can be real (floating<br />
point) or complex. Here is an example that demonstrates several<br />
features of <tt>sfmath</tt>.<br />
<pre><br />
bash$ sfmath n1=629 d1=0.01 o1=0 n2=40 d2=1 o2=5 \<br />
output="x2*(8+sin(6*x1+x2/10))" > rad.rsf<br />
bash$ < rad.rsf sfrtoc | sfmath output="input*exp(I*x1)" > rose.rsf<br />
bash$ < rose.rsf sfgraph title=Rose screenratio=1 wantaxis=n | xtpen<br />
</pre><br />
The first line creates a 2-D dataset that consists of 40 traces 600<br />
samples each. The values of the data are computed with the formula<br />
<font color="#cd4b19">"x2*(8+sin(6*x1+x2/10))"</font>, where <tt>x1</tt> refers to the<br />
coordinate on the first axis, and <tt>x2</tt> is the coordinate of the<br />
second axis. In the second line, we convert the data from real to<br />
complex using <tt>sfrtoc</tt> and produce a complex dataset using<br />
formula <font color="#cd4b19">"input*exp(I*x1)"</font>, where <tt>input</tt> refers to the<br />
input file. Finally, we plot the complex data as a collection of<br />
parametric curves using <tt>sfgraph</tt> and display the result using<br />
<tt>xtpen</tt>. The plot appearing on your screen should look similar<br />
to the figure.<br />
[[Image:rose.png|frame|center|This figure was created with <tt>sfmath</tt>.]]<br />
One possible alternative to the second line above is<br />
<pre><br />
bash$ < rad.rsf sfmath output=x1 > ang.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*cos(a)" > cos.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*sin(a)" > sin.rsf<br />
bash$ sfcmplx cos.rsf sin.rsf > rose.rsf<br />
</pre><br />
Here we refer to input files by names (<tt>r</tt> and <tt>a</tt>) and combine the names in a formula.<br />
<br />
==sfpad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Pad a dataset with zeros.<br />
|-<br />
! colspan="4" | sfpad < in.rsf > out.rsf [beg1= beg2= ... end1= end2=... | n1= n2 = ... | n1out= n2out= ...]<br />
|-<br />
| colspan="4" | begN specifies the number of zeros to add before the beginning of axis N.<br>endN specifies the number of zeros to add after the end of axis N.<br><br>Alternatively:<br><br>nN or nNout specify the output length of axis N, padding occurs at the end.<br>nN and nNout are equivalent.<br />
|}<br />
<br />
<br />
<tt>pad</tt> increases the dimensions of the input dataset by padding<br />
the data with zeroes. Here are some simple examples.<br />
<pre><br />
bash$ sfspike n1=5 n2=3 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
bash$ < one.rsf sfpad n2=5 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 0 0 0 0 0<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfpad beg2=2 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 0 0 0 0<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < one.rsf sfpad beg2=1 end2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfwindow n1=3 | sfpad n1=5 n2=5 beg1=1 beg2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 1 1 1 0<br />
10: 0 1 1 1 0<br />
15: 0 1 1 1 0<br />
20: 0 0 0 0 0<br />
</pre><br />
You can use <tt>sfcat</tt> to pad data with values other than zeroes.<br />
<br />
==sfput==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Input parameters into a header. <br />
|-<br />
! colspan="4" | sfput < in.rsf > out.rsf<br />
|}<br />
<br />
<br />
<tt>sfput</tt> is a very simple program. It simply appends parameters<br />
from the command line to the output RSF file. One can achieve similar<br />
results with editing by hand or with standard Unix utilities like<br />
<tt>sed</tt> and <tt>echo</tt>. <tt>sfput</tt> is sometimes more<br />
convenient because it handles input/output operations similarly to<br />
other regular RSF programs.<br />
<pre><br />
bash$ sfspike n1=10 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
10 elements 40 bytes<br />
bash$ sfput < spike.rsf d1=25 label1=Depth unit1=m > spike2.rsf<br />
bash$ sfin spike2.rsf<br />
spike2.rsf:<br />
in="/tmp/spike2.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=25 o1=0 label1="Depth" unit1="m"<br />
10 elements 40 bytes<br />
</pre><br />
<br />
==sfreal==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extract real (sfreal) or imaginary (sfimag) part of a complex dataset. <br />
|-<br />
! colspan="4" | sfreal < cmplx.rsf > real.rsf<br />
|}<br />
<br />
<br />
<tt>sfreal</tt> extracts the real part of a complex type dataset. The<br />
imaginary part can be extracted with <tt>sfimag</tt>, an the real<br />
and imaginary part can be combined together with <tt>sfcmplx</tt>.<br />
Here is a simple example. Let us first create a complex dataset <br />
with <tt>sfmath</tt><br />
<pre><br />
bash$ sfmath n1=10 type=complex output="(2+I)*x1" > cmplx.rsf<br />
bash$ fdisfil < cmplx.rsf<br />
0: 0, 0i 2, 1i 4, 2i<br />
3: 6, 3i 8, 4i 10, 5i<br />
6: 12, 6i 14, 7i 16, 8i<br />
9: 18, 9i<br />
</pre><br />
Extracting the real part with <tt>sfreal</tt>:<br />
<pre><br />
bash$ sfreal < cmplx.rsf | sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
</pre><br />
Extracting the imaginary part with <tt>sfimag</tt>:<br />
<pre><br />
bash$ sfimag < cmplx.rsf | sfdisfil<br />
0: 0 1 2 3 4<br />
5: 5 6 7 8 9<br />
</pre><br />
<br />
==sfreverse==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Reverse one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfreverse < in.rsf > out.rsf which=-1 verb=false memsize=sf_memsize() opt=<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''opt=''' || || If y, change o and d parameters on the reversed axis;<br />
:if i, don't change o and d<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|-<br />
| ''int '' || '''which=-1''' || || Which axis to reverse.<br />
:To reverse a given axis, start with 0,<br />
:add 1 to number to reverse n1 dimension,<br />
:add 2 to number to reverse n2 dimension,<br />
:add 4 to number to reverse n3 dimension, etc.<br />
:Thus, which=7 would reverse the first three dimensions,<br />
:which=5 just n1 and n3, etc.<br />
:which=0 will just pass the input on through unchanged.<br />
|}<br />
Here is an example of using <tt>sfreverse</tt>. First, let us create a<br />
2-D dataset.<br />
<pre><br />
bash$ sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Reversing the first axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 | sfdisfil<br />
0: 4 3 2 1 0<br />
5: 5 4 3 2 1<br />
10: 6 5 4 3 2<br />
</pre><br />
Reversing the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=2 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
Reversing both the first and the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=3 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
As you can see, the <tt>which=</tt> parameter controls the axes that are<br />
being reversed by encoding them into one number.<br />
When an axis is reversed, what happens with its axis origin and<br />
sampling parameters? This behavior is controlled by <tt>opt=</tt>. In<br />
our example,<br />
<pre><br />
bash$ < test.rsf sfget n1 o1 d1<br />
n1=5<br />
o1=0<br />
d1=1<br />
bash$ < test.rsf sfreverse which=1 | sfget o1 d1<br />
o1=4<br />
d1=-1<br />
</pre><br />
The default behavior (equivalent to <tt>opt=y</tt>) puts the origin<br />
<tt>o1</tt> at the end of the axis and reverses the sampling parameter<br />
<tt>d1</tt>. Using <tt>opt=n</tt> preserves the sampling but reverses<br />
the origin.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=n | sfget o1 d1<br />
o1=-4<br />
d1=1<br />
</pre><br />
Using <tt>opt=i</tt> preserves both the sampling and the origin while<br />
reversing the axis.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=i | sfget o1 d1<br />
o1=0<br />
d1=1<br />
</pre><br />
One of the three possible behaviors may be desirable depending on the<br />
application.<br />
<br />
==sfrm==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Remove RSF files together with their data.<br />
|-<br />
! colspan="4" | sfrm file1.rsf [file2.rsf ...] [-i] [-v] [-f] <br />
|-<br />
| colspan="4" | Mimics the standard Unix rm command.<br><br>See also: sfmv, sfcp.<br />
|}<br />
<br />
<tt>sfrm</tt> is a program for removing RSF files. Its arguments mimic<br />
the arguments of the standard Unix <tt>rm</tt> utility: <tt>-v</tt><br />
for verbosity, <tt>-i</tt> for interactive inquiry, <tt>-f</tt> for<br />
force removal of suspicious files. Unlike the Unix <tt>rm</tt>,<br />
<tt>sfrm</tt> removes both the RSF header files and the binary files<br />
that the headers point to. <br />
Example:<br />
<pre><br />
bash&#36; sfspike n1=10 > spike.rsf datapath=./<br />
bash&#36; sfget in < spike.rsf<br />
in=./spike.rsf@<br />
bash&#36; ls spike*<br />
spike.rsf spike.rsf@<br />
bash&#36; sfrm -v spike.rsf<br />
sfrm: sf_rm: Removing header spike.rsf<br />
sfrm: sf_rm: Removing data ./spike.rsf@<br />
bash&#36; ls spike*<br />
ls: No match.<br />
</pre><br />
==sfrotate==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Rotate a portion of one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfrotate < in.rsf > out.rsf verb=n memsize=sf_memsize() rot#=(0,0,...)<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''rot#=(0,0,...)''' || || length of #-th axis that is moved to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<tt>sfrotate</tt> modifies the input dataset by splitting it into<br />
parts and putting the parts back in a different order. Here is a quick example.<br />
<pre><br />
bash&#36; sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Rotating the first axis by putting the last two columns in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=2 | sfdisfil<br />
0: 3 4 0 1 2<br />
5: 4 5 1 2 3<br />
10: 5 6 2 3 4<br />
</pre><br />
Rotating the second axis by putting the last row in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot2=1 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 0 1 2 3 4<br />
10: 1 2 3 4 5<br />
</pre><br />
Rotating both the first and the second axis:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=3 rot2=1 | sfdisfil<br />
0: 4 5 6 2 3<br />
5: 2 3 4 0 1<br />
10: 3 4 5 1 2<br />
</pre><br />
The transformation is shown schematically in Figure~(fig:rotate).<br />
[[Image:rotate.png|frame|center|Schematic transformation of data with <tt>sfrotate</tt>.]]<br />
<br />
==sfrtoc==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert real data to complex (by adding zero imaginary part).<br />
|-<br />
! colspan="4" | sfrtoc < real.rsf > cmplx.rsf<br />
|-<br />
| colspan="4" | <br>See also: sfcmplx<br />
|}<br />
The input to <tt>sfrtoc</tt> can be any <tt>type=float</tt> dataset:<br />
<pre><br />
bash$ sfspike n1=10 n2=20 n3=30 >real.rsf<br />
bash$ sfin real.rsf<br />
real.rsf:<br />
in="/var/tmp/real.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
</pre><br />
The output dataset will have <tt>type=complex</tt>, and its binary will be twice the size of the input:<br />
<pre><br />
bash$ <real.rsf sfrtoc >complex.rsf<br />
bash$ sfin complex.rsf <br />
complex.rsf:<br />
in="/var/tmp/complex.rsf@"<br />
esize=8 type=complex form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 48000 bytes<br />
</pre><br />
<br />
==sfscale==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Scale data.<br />
|-<br />
! colspan="4" | sfscale < in.rsf > out.rsf axis=0 rscale=0. dscale=1.<br />
|-<br />
| colspan="4" | <br>To scale by a constant factor, you can also use sfmath or sfheadermath.<br />
|-<br />
| ''int '' || '''axis=0''' || || Scale by maximum in the dimensions up to this axis.<br />
|-<br />
| ''float '' || '''dscale=1.''' || || Scale by this factor (works if rscale=0)<br />
|-<br />
| ''float '' || '''rscale=0.''' || || Scale by this factor.<br />
|}<br />
<tt>sfscale</tt> scales the input dataset by a factor. Here<br />
are some simple examples. First, let us create a test dataset.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil <br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Scale every data point by 2:<br />
<pre><br />
bash&#36; < test.rsf sfscale dscale=2 | sfdisfil<br />
0: 2 4 6 8 10<br />
5: 4 8 12 16 20<br />
10: 6 12 18 24 30<br />
</pre><br />
Divide every trace by its maximum value:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=1 | sfdisfil<br />
0: 0.2 0.4 0.6 0.8 1<br />
5: 0.2 0.4 0.6 0.8 1<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
Divide by the maximum value in the whole 2-D dataset:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=2 | sfdisfil<br />
0: 0.06667 0.1333 0.2 0.2667 0.3333<br />
5: 0.1333 0.2667 0.4 0.5333 0.6667<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
The <tt>rscale=</tt> parameter is synonymous to <tt>dscale=</tt> except<br />
when it is equal to zero. With <tt>sfscale dscale=0</tt>, the dataset gets<br />
multiplied by zero. If using <tt>rscale=0</tt>, the other parameters are<br />
used to define scaling. Thus, <tt>sfscale rscale=0 axis=1</tt> is<br />
equivalent to <tt>sfscale axis=1</tt>, and <tt>sfscale rscale=0</tt><br />
is equivalent to <tt>sfscale dscale=1</tt>.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
==sfspike==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate simple data: spikes, boxes, planes, constants.<br />
|-<br />
! colspan="4" | sfspike > spike.rsf mag= nsp=1 k#=[0,...] l#=[k1,k2,...] p#=[0,...] n#= o#=(0,...) d#=(0.004,0.1,0.1,...) label#=(Time,Distance,Distance,...) unit#=[s,km,km,...] title=<br />
|-<br />
| ''float '' || '''d#=(0.004,0.1,0.1,...)''' || || sampling on #-th axis<br />
|-<br />
| ''ints '' || '''k#=[0,...]''' || || spike starting position [nsp]<br />
|-<br />
| ''ints '' || '''l#=[k1,k2,...]''' || || spike ending position [nsp]<br />
|-<br />
| ''string '' || '''label#=(Time,Distance,Distance,...)''' || || label on #-th axis<br />
|-<br />
| ''floats '' || '''mag=''' || || spike magnitudes [nsp]<br />
|-<br />
| ''int '' || '''n#=''' || || dimension of #-th axis<br />
|-<br />
| ''int '' || '''nsp=1''' || || Number of spikes<br />
|-<br />
| ''float '' || '''o#=(0,...)''' || || origin on #-th axis<br />
|-<br />
| ''floats '' || '''p#=[0,...]''' || || spike inclination (in samples) [nsp]<br />
|-<br />
| ''string '' || '''title=''' || || title for plots<br />
|-<br />
| ''string '' || '''unit#=[s,km,km,...]''' || || unit on #-th axis<br />
|}<br />
This is the program for creating a RSF hypercube out of nothing. Calling <tt>sfspike</tt> without specifying the k# or l# parameters will result in a volume filled with values specified by <tt>mag</tt>. To get a file full of 1's, just give <tt>sfspike</tt> the axis values that running <tt>sfin</tt> on your desired output would produce. I.e. if you run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" > out.rsf<br />
</pre><br />
you will obtain the following file:<br />
<pre><br />
bash$ sfin out.rsf<br />
out.rsf:<br />
in="/var/tmp/out.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
300 elements 1200 bytes<br />
</pre><br />
To create a "flat reflector" in the file above, run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5> out2.rsf<br />
</pre><br />
Notice that the values for <tt>k</tt> and <tt>l</tt> are in samples, not in the physical units of the respective axes. The result can be visualised with <br />
<pre><br />
< out2.rsf sfgrey pclip=100 wantscalebar=y title="Illustration of k,l parameters" | xtpen<br />
</pre><br />
which produces the following plot:<br />
<br />
[[Image:sfspike_fig1.png]]<br />
<br />
The <tt>p</tt> parameters can be used to create slanted lines/planes. Specifying <tt>p2=1</tt> means that for each lateral step, the spike will be shifted down with 1 sample. Below is the command and the corresponding graphical output it creates:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=1 |\<br />
sfgrey pclip=100 wantscalebar=y title="Effect of p2=1" | xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig2.png]]<br />
<br />
Sfspike also supports negative and non-integer p values:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=-0.15 |\<br />
sfgrey pclip=100 wantscalebar=y allpos=y color=h title="Effect of p2=-0.15" |xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig3.png]]<br />
<br />
When <tt>nsp</tt> is greater than the number of values for <tt>k</tt> and <tt>l</tt> parameters, the extra spikes will be piled on top of the last one, increasing its amplitude. Look at the amplitude of the last event in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=3 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
and in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=5 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
(pictures coming soon). This feature can easily cause a bug when the number of events is large and they have not been properly counted, or when a new spike was added on a list but <tt>nsp</tt> was not updated.<br />
<br />
==sfspray==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extend a dataset by duplicating in the specified axis dimension.<br />
|-<br />
! colspan="4" | sfspray < in.rsf > out.rsf axis=2 n= d= o= label= unit=<br />
|-<br />
| colspan="4" | This operation is adjoint to sfstack.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to spray<br />
|-<br />
| ''float '' || '''d=''' || || Sampling of the newly created dimension<br />
|-<br />
| ''string '' || '''label=''' || || Label of the newly created dimension<br />
|-<br />
| ''int '' || '''n=''' || || Size of the newly created dimension<br />
|-<br />
| ''float '' || '''o=''' || || Origin of the newly created dimension<br />
|-<br />
| ''string '' || '''unit=''' || || Units of the newly created dimension<br />
|}<br />
<br />
<tt>sfspray</tt> extends the input hypercube by replicating the data<br />
in one of the dimensions. The output dataset acquires one additional<br />
dimension. Here is an example:<br />
Start with a 2-D dataset<br />
<pre><br />
bash&#36; sfmath n1=5 n2=2 output=x1+x2 > test.rsf<br />
bash&#36; sfin test.rsf<br />
test.rsf:<br />
in="/var/tmp/test.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
10 elements 40 bytes<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
</pre><br />
Extend the data in the second dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=2 n=3 > test2.rsf<br />
bash&#36; sfin test2.rsf<br />
test2.rsf:<br />
in="/var/tmp/test2.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=3 d2=1 o2=0 <br />
n3=2 d3=1 o3=0 <br />
30 elements 120 bytes<br />
bash&#36; < test2.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 0 1 2 3 4<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
20: 1 2 3 4 5<br />
25: 1 2 3 4 5<br />
</pre><br />
The output is three-dimensional, with traces from the original<br />
data duplicated along the second axis.<br />
Extend the data in the third dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=3 n=2 > test3.rsf<br />
bash&#36; sfin test3.rsf<br />
test3.rsf:<br />
in="/var/tmp/test3.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
n3=2 d3=? o3=? <br />
20 elements 80 bytes<br />
bash&#36; < test3.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
</pre><br />
The output is also three-dimensional, with the original data replicated<br />
along the third axis.<br />
<br />
==sfstack==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stack a dataset over one of the dimensions.<br />
|-<br />
! colspan="4" | sfstack < in.rsf > out.rsf axis=2 rms=n norm=y min=n max=n<br />
|-<br />
| colspan="4" | <br>This operation is adjoint to sfspray.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to stack<br />
|-<br />
| ''bool '' || '''max=n''' || [y/n] || If y, find maximum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''min=n''' || [y/n] || If y, find minimum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || If y, normalize by fold.<br />
|-<br />
| ''bool '' || '''rms=n''' || [y/n] || If y, compute the root-mean-square instead of stack.<br />
|}<br />
While <tt>sfspray</tt> adds a dimension to a hypercube,<br />
<tt>sfstack</tt> effectively removes one of the dimensions by stacking<br />
over it. Here are some examples:<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
bash&#36; < test.rsf sfstack axis=2 | sfdisfil<br />
0: 1.5 2 3 4 5<br />
bash&#36; < test.rsf sfstack axis=1 | sfdisfil<br />
0: 2.5 3 4<br />
</pre><br />
Why is the first value not 1 (in the first case) or 2 (in the second<br />
case)? By default, <tt>sfstack</tt> normalizes the stack by the fold<br />
(the number of non-zero entries). To avoid normalization, use<br />
<tt>norm=n</tt>, as follows:<br />
<pre><br />
bash&#36; < test.rsf sfstack norm=n | sfdisfil <br />
0: 3 6 9 12 15<br />
</pre><br />
<tt>sfstack</tt> can also compute root-mean-square values as <br />
well as minimum and maximum values.<br />
<pre><br />
bash&#36; < test.rsf sfstack rms=y | sfdisfil<br />
0: 1.581 2.16 3.109 4.082 5.066<br />
bash&#36; < test.rsf sfstack min=y | sfdisfil<br />
0: 0 1 2 3 4<br />
bash&#36; < test.rsf sfstack axis=1 max=y | sfdisfil <br />
0: 4 5 6<br />
</pre><br />
<br />
==sftransp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Transpose two axes in a dataset. <br />
|-<br />
! colspan="4" | sftransp < in.rsf > out.rsf memsize=sf_memsize() plane=<br />
|-<br />
| colspan="4" | <br>If you get a "Cannot allocate memory" error, give the program a<br>memsize=1 command-line parameter to force out-of-core operation.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''plane=''' || || Two-digit number with axes to transpose. The default is 12<br />
|}<br />
<br />
The <tt>sftransp</tt> program transposes the input hypercube<br />
exchanging the two axes specified by the <b>plane=</b> parameter. <br />
<pre><br />
bash&#36; sfspike n1=10 n2=20 n3=30 > orig123.rsf<br />
bash&#36; sfin orig123.rsf <br />
orig123.rsf:<br />
in="/var/tmp/orig123.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=23 >out132.rsf<br />
bash&#36; sfin out132.rsf <br />
out132.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=20 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=13 >out321.rsf<br />
bash&#36; sfin out321.rsf <br />
out321.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=30 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=10 d3=0.004 o3=0 label3="Time" unit3="s" <br />
6000 elements 24000 bytes<br />
</pre><br />
<tt>sftransp</tt> tries to fit the dataset in memory to transpose it<br />
there but, if not enough memory is available, it performs a slower<br />
transpose out of core using disk operations. You can control the<br />
amount of available memory using the <b>memsize=</b> parameter or<br />
the <b>RSFMEMSIZE</b> environmental variable.<br />
<br />
==sfwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a portion of the dataset. <br />
|-<br />
! colspan="4" | sfwindow < in.rsf > out.rsf verb=n squeeze=y j#=(1,...) d#=(d1,d2,...) f#=(0,...) min#=(o1,o2,,...) n#=(0,...) max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)<br />
|-<br />
| ''float '' || '''d#=(d1,d2,...)''' || || sampling in #-th dimension<br />
|-<br />
| ''int '' || '''f#=(0,...)''' || || window start in #-th dimension<br />
|-<br />
| ''int '' || '''j#=(1,...)''' || || jump in #-th dimension<br />
|-<br />
| ''float '' || '''max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)''' || || maximum in #-th dimension<br />
|-<br />
| ''float '' || '''min#=(o1,o2,,...)''' || || minimum in #-th dimension<br />
|-<br />
| ''int '' || '''n#=(0,...)''' || || window size in #-th dimension<br />
|-<br />
| ''bool '' || '''squeeze=y''' || [y/n] || if y, squeeze dimensions equal to 1 to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
<b>sfwindow</b> is used to window a portion of the dataset. Here is<br />
a quick example: Start by creating some data.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Now window the first two rows:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n2=2 | sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
</pre><br />
Window the first three columns:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n1=3 | sfdisfil<br />
0: 1 2 3 2 4<br />
5: 6 3 6 9<br />
</pre><br />
Window the middle row:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f2=1 n2=1 | sfdisfil<br />
0: 2 4 6 8 10<br />
</pre><br />
You can interpret the <b>f#</b> and <b>n#</b> parameters as<br />
meaning "skip that many rows/columns" and "select that many<br />
rows/columns" correspondingly. Window the middle point in the dataset:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f1=2 n1=1 f2=1 n2=1 | sfdisfil<br />
0: 6<br />
</pre><br />
Window every other column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=2 | sfdisfil<br />
0: 1 3 5 2 6<br />
5: 10 3 9 15<br />
</pre><br />
Window every third column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=3 | sfdisfil<br />
0: 1 4 2 8 3<br />
5: 12<br />
</pre><br />
Alternatively, <b>sfwindow</b> can use the minimum and maximum<br />
parameters to select a window. In the following example, we are<br />
creating a dataset with <b>sfspike</b> and then windowing a portion of it<br />
between 1 and 2 seconds in time and sampled at 8 miliseconds.<br />
<pre><br />
bash&#36; sfspike n1=1000 n2=10 > spike.rsf <br />
bash&#36; sfin spike.rsf<br />
spike.rsf:<br />
in="/var/tmp/spike.rsf@"<br />
esize=4 type=float form=native <br />
n1=1000 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10000 elements 40000 bytes<br />
bash&#36; < spike.rsf sfwindow min1=1 max1=2 d1=0.008 > window.rsf<br />
bash&#36; sfin window.rsf<br />
window.rsf:<br />
in="/var/tmp/window.rsf@"<br />
esize=4 type=float form=native <br />
n1=126 d1=0.008 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
1260 elements 5040 bytes<br />
</pre><br />
By default, <b>sfwindow</b> "squeezes" the hypercube dimensions<br />
that are equal to one toward the end of the dataset. Here is an<br />
example of taking a time slice:<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=1 d2=0.004 o2=1 label2="Time" unit2="s" <br />
10 elements 40 bytes<br />
</pre><br />
You can change this behavior by specifying <b>squeeze=n</b>.<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 squeeze=n > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=1 d1=0.004 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10 elements 40 bytes<br />
</pre><br />
<br />
=Seismic programs=<br />
Programs in this category are specific for operations on seismic data. The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/seismic/ system/seismic] in the Madagascar distribution.<br />
<br />
==sfheaderattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Integer header attributes. <br />
|-<br />
! colspan="4" | sfheaderattr < head.rsf<br />
|-<br />
| colspan="4" | <br>Only nonzero values are reported.<br />
|}<br />
<br />
The <tt>sfheaderattr</tt> examines the contents of a trace header file,<br />
typically generated by <tt>sfsegyread</tt>. In the example below, we examine<br />
trace headers in the output of <tt>suplane</tt>, a program from Seismic Unix.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
bash$ sfheaderattr < tfile.rsf<br />
*******************************************<br />
71 headers, 32 traces<br />
key[0]="tracl" min[0]=1 max[31]=32 mean=16.5<br />
key[1]="tracr" min[0]=1 max[31]=32 mean=16.5<br />
key[11]="offset" min[0]=400 max[31]=400 mean=400<br />
key[38]="ns" min[0]=64 max[31]=64 mean=64<br />
key[39]="dt" min[0]=4000 max[31]=4000 mean=4000<br />
*******************************************<br />
</pre><br />
For different standard keywords, a minimum, maximum, and mean values<br />
are reported unless they are identically zero. This quick inspection<br />
can help in identifying meaningful keywords set in the data. The input<br />
data type must be <tt>int</tt>.<br />
<br />
==sfheadermath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations, possibly on header keys. <br />
|-<br />
! colspan="4" | sfheadermath < in.rsf > out.rsf memsize=sf_memsize() output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs<br><br>See also sfmath. <br><br>An addition operation can be performed by sfstack.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''output=''' || || Describes the output in a mathematical notation.<br />
|}<br />
<tt>sfheadermath</tt> is a versatile program for mathematical<br />
operations on rows of the input file. If the input file is an<br />
<tt>n1</tt> by <tt>n2</tt> matrix, the output will be a <tt>1</tt> by<br />
<tt>n2</tt> matrix that contains one row made out of mathematical<br />
operations on the other rows. <tt>sfheadermath</tt> can identify a row<br />
by number or by a standard SEGY keyword. The latter is useful for<br />
processing headers extracted from SEGY or SU files.<br />
Here is an example. First, we create an SU file with <tt>suplane</tt> and convert it to RSF using <tt>sfsegyread</tt>.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
</pre><br />
The trace header information is saved in <tt>tfile.rsf</tt>. It<br />
contains 71 headers for 32 traces in integer format.<br />
<pre><br />
bash$ sfin tfile.rsf<br />
tfile.rsf:<br />
in="/tmp/tfile.rsf@"<br />
esize=4 type=int form=native<br />
n1=71 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
2272 elements 9088 bytes<br />
</pre><br />
Next, we will convert <tt>tfile.rsf</tt> to a floating-point format<br />
and run <tt>sfheadermath</tt> to create a new header.<br />
<pre><br />
bash$ < tfile.rsf sfdd type=float | \<br />
sfheadermath myheader=1 output="sqrt(myheader+(2+10*offset^2))" > new.rsf<br />
bash$ sfin new.rsf<br />
new.rsf:<br />
in="/tmp/new.rsf@"<br />
esize=4 type=float form=native<br />
n1=1 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
32 elements 128 bytes<br />
</pre><br />
We defined "myheader" as being the row number 1 in the input (note<br />
that numbering starts with 0) and combined it with "offset", which<br />
is a standard SEGY keyword that denotes row number 11 (see the output<br />
of <tt>sfheaderattr</tt> above.) A variety of mathematical expressions<br />
can be defined in the <tt>output=</tt> string. The expression<br />
processing engine is shared with <tt>sfmath</tt>.<br />
<br />
==sfsegyheader==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Make a trace header file for segywrite.<br />
|-<br />
! colspan="4" | sfsegyheader < in.rsf > out.rsf n1= d1=<br />
|-<br />
| colspan="4" | <br> Use the output for tfile= argument in segywrite.<br />
|-<br />
| ''float '' || '''d1=''' || || trace sampling<br />
|-<br />
| ''int '' || '''n1=''' || || number of samples in a trace<br />
|}<br />
<br />
==sfsegyread==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert a SEG-Y or SU dataset to RSF.<br />
|-<br />
! colspan="4" | sfsegyread mask=msk.rsf > out.rsf tfile=hdr.rsf verb=false su=false format=sf_segyformat (bhead) ns=sf_segyns (bhead) endian= tape= read= hfile= bfile= mask= tfile=<br />
|-<br />
| colspan="4" | <br>Data headers and trace headers are separated from the data.<br><br>Defined SEG-Y trace header key names and byte offsets:<br><br>tracl: trace sequence number within line 0<br><br>tracr: trace sequence number within reel 4<br><br>fldr: field record number 8 <br><br>tracf: trace number within field record 12 <br><br>ep: energy source point number 16 <br><br>cdp: CDP ensemble number 20 <br><br>cdpt: trace number within CDP ensemble 24 <br><br>trid: trace identification code:<br>1 = seismic data<br>2 = dead<br>3 = dummy<br>4 = time break<br>5 = uphole<br>6 = sweep<br>7 = timing<br>8 = water break<br>9---, N = optional use (N = 32,767) 28 <br><br>nvs: number of vertically summed traces 30 <br><br>nhs: number of horizontally summed traces 32 <br><br>duse: data use:<br>1 = production<br>2 = test 34<br><br>offset: distance from source point to receiver<br>group (negative if opposite to direction<br>in which the line was shot) 36 <br><br>gelev: receiver group elevation from sea level<br>(above sea level is positive) 40 <br><br>selev: source elevation from sea level<br>(above sea level is positive) 44 <br><br>sdepth: source depth (positive) 48 <br><br>gdel: datum elevation at receiver group 52 <br><br>sdel: datum elevation at source 56 <br><br>swdep: water depth at source 60 <br><br>gwdep: water depth at receiver group 64 <br><br>scalel: scale factor for previous 7 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 68 <br><br>scalco: scale factor for next 4 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 70 <br><br>sx: X source coordinate 72 <br><br>sy: Y source coordinate 76 <br><br>gx: X group coordinate 80 <br><br>gy: Y group coordinate 84 <br><br>counit: coordinate units code:<br>for previoius four entries<br>1 = length (meters or feet)<br>2 = seconds of arc (in this case, the<br>X values are unsigned intitude and the Y values<br>are latitude, a positive value designates<br>the number of seconds east of Greenwich<br>or north of the equator 88 <br><br>wevel: weathering velocity 90 <br><br>swevel: subweathering velocity 92 <br><br>sut: uphole time at source 94 <br><br>gut: uphole time at receiver group 96 <br><br>sstat: source static correction 98 <br><br>gstat: group static correction 100 <br><br>tstat: total static applied 102 <br><br>laga: lag time A, time in ms between end of 240-<br>byte trace identification header and time<br>break, positive if time break occurs after<br>end of header, time break is defined as<br>the initiation pulse which maybe recorded<br>on an auxiliary trace or as otherwise<br>specified by the recording system 104 <br><br>lagb: lag time B, time in ms between the time<br>break and the initiation time of the energy source,<br>may be positive or negative 106 <br><br>delrt: delay recording time, time in ms between<br>initiation time of energy source and time<br>when recording of data samples begins<br>(for deep water work if recording does not<br>start at zero time) 108 <br><br>muts: mute time--start 110 <br><br>mute: mute time--end 112 <br><br>ns: number of samples in this trace 114 <br><br>dt: sample interval, in micro-seconds 116 <br><br>gain: gain type of field instruments code:<br>1 = fixed<br>2 = binary<br>3 = floating point<br>4 ---- N = optional use 118 <br><br>igc: instrument gain constant 120 <br><br>igi: instrument early or initial gain 122 <br><br>corr: correlated:<br>1 = no<br>2 = yes 124 <br><br>sfs: sweep frequency at start 126 <br><br>sfe: sweep frequency at end 128 <br><br>slen: sweep length in ms 130 <br><br>styp: sweep type code:<br>1 = linear<br>2 = cos-squared<br>3 = other 132 <br><br>stas: sweep trace length at start in ms 134 <br><br>stae: sweep trace length at end in ms 136 <br><br>tatyp: taper type: 1=linear, 2=cos^2, 3=other 138 <br><br>afilf: alias filter frequency if used 140 <br><br>afils: alias filter slope 142 <br><br>nofilf: notch filter frequency if used 144 <br><br>nofils: notch filter slope 146 <br><br>lcf: low cut frequency if used 148 <br><br>hcf: high cut frequncy if used 150 <br><br>lcs: low cut slope 152 <br><br>hcs: high cut slope 154 <br><br>year: year data recorded 156 <br><br>day: day of year 158 <br><br>hour: hour of day (24 hour clock) 160 <br><br>minute: minute of hour 162 <br><br>sec: second of minute 164 <br><br>timbas: time basis code:<br>1 = local<br>2 = GMT<br>3 = other 166 <br><br>trwf: trace weighting factor, defined as 1/2^N<br>volts for the least sigificant bit 168 <br><br>grnors: geophone group number of roll switch<br>position one 170 <br><br>grnofr: geophone group number of trace one within<br>original field record 172 <br><br>grnlof: geophone group number of last trace within<br>original field record 174 <br><br>gaps: gap size (total number of groups dropped) 176 <br><br>otrav: overtravel taper code:<br>1 = down (or behind)<br>2 = up (or ahead)<br />
|-<br />
| ''string '' || '''bfile=''' || || output binary data header file<br />
|-<br />
| ''bool '' || '''endian=''' || [y/n] || big/little endian flag, the default is estimated automatically<br />
|-<br />
| ''int '' || '''format=sf_segyformat (bhead)''' || [1,2,3,5] || Data format. The default is taken from binary header.<br />
:1 is IBM floating point<br />
:2 is 4-byte integer<br />
:3 is 2-byte integer<br />
:5 is IEEE floating point<br />
|-<br />
| ''string '' || '''hfile=''' || || output text data header file<br />
|-<br />
| ''string '' || '''mask=''' || || optional header mask for reading only selected traces<br />
|-<br />
| ''int '' || '''ns=sf_segyns (bhead)''' || || Number of samples. The default is taken from binary header<br />
|-<br />
| ''string '' || '''read=''' || || what to read: h - header, d - data, b - both (default)<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if input is SU, n if input is SEGY<br />
|-<br />
| ''bool '' || '''suxdr=n''' || [y/n] || y, SU has XDR support<br />
|-<br />
| ''string '' || '''tape=''' || || <br />
|-<br />
| ''string '' || '''tfile=''' || || output trace header file<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
The SEG Y format is an [http://en.wikipedia.org/wiki/Open_standard open standard] for the exchange of geophysical data. It is controlled by the non-profit [http://www.seg.org/SEGportalWEBproject/portals/SEG_Online.portal?_nfpb=true&_pageLabel=pg_gen_content&Doc_Url=prod/SEG-Publications/Pub-Yearbook/committees.htm SEG Technical Standards Committee]. There are two versions of this standard: [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev0.pdf rev0] (1975)<ref>Barry, K.M., Cavers, D.A., and Kneale, C.W. 1975. Recommended standards for digital tape formats. ''Geophysics'', '''40''', no. 02, 344–352.</ref> and [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf rev1] (2002)<ref>Norris, M.W., Faichney, A.K., ''Eds''. 2001. SEG Y rev1 Data Exchange format. Society of Exploration Geophysicists, Tulsa, OK, 45 pp.</ref>. The implementation in <tt>sfsegyread</tt> is a mixture of rev0 (i.e. no checks for Extended Textual Headers) and rev1 ([http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE floating point format] allowed for trace data samples).<br />
<br />
A SEG-Y file as understood by <tt>sfsegyread</tt> contains a "Reel Identification Header" (3200 bytes in EBCDIC followed by 400 bytes in a binary encoding), followed by a number of "Trace Blocks". Each "Trace Block" contains a 240-byte "Trace Header" (binary) followed by "Trace Data" -- a sequence of <tt>ns</tt> samples. Binary values in both reel headers and trace headers are two's complement integers, either two bytes or four bytes long. There are no floating-point values defined in the headers. Trace Data samples can have various encodings, either floating point or integer, described further down, but they are all big-endian. To convert from SEG-Y to RSF, <tt>sfsegyread</tt> will strip the tape reel EBCDIC header and convert it to ASCII, will extract the reel binary header without changing it, and will put the trace headers into one RSF file, and the traces themselves on another.<br />
<br />
===SEG-Y Trace Headers===<br />
In the SEG-Y standard, only the first 180 bytes of the 240-byte trace header are defined; bytes 181-240 are reserved for non-standard header information, and these locations are increasingly used in modern SEG-Y files and its variants. The standard provides for a total of 71 4-byte and 2-byte predefined header words. These 71 standard words have defined lengths and byte offsets, and only these words and byte locations are read using <tt>segyread</tt> and output to the RSF header file with the <tt>hfile=</tt> option. The user may remap these predefined keywords to a different byte offsets.<br />
<br />
===SU File Format===<br />
An [http://www.cwp.mines.edu/sututor/node22.html SU file] is nothing more than a SEG-Y file without the reel headers, and with the Trace Data samples in the native encoding of the CPU the file was created on (Attention -- limited portability!). So, to convert from SU to RSF, <tt>sfsegyread</tt> will just separate headers and traces into two RSF files. <br />
<br />
===SEG-Y specific parameters===<br />
*<tt>hfile=</tt> specifies the name of the file in which the EBCDIC reel header will be put after conversion to ASCII. If you are certain there is no useful information in it, <tt>hfile=/dev/null</tt> works just fine. If you do not specify anything for this parameter you will get an ASCII file named <tt>header</tt> in the current directory. If you want to quickly preview this header before running <tt>sfsegyread</tt>, use<pre>dd if=input.segy count=40 bs=80 cbs=80 conv=unblock,ascii</pre><br />
*<tt>bfile=</tt> specifies name of the file in which the binary reel header (the 400-bytes thing following the 3600-bytes EBCDIC) will be put without any conversion. The default name is "binary". Unless you have software that knows how to read exactly this special type of file, it will be completely useless, so do <tt>bfile=/dev/null</tt><br />
*<tt>format=</tt> specifies the format in which the trace data samples are in the SEG-Y input file. This is read from the binary reel header of the SEG-Y file. Valid values are 1(IBM floating point), 2 (4-byte integer), 3 (2-byte integer) and 5 (IEEE floating point). If the input file is SU, the format will be assumed to be the native <tt>float</tt> format.<br />
<br />
*<tt>keyname=</tt> specifies the byte offset to remap a header using the trace header key names shown above. For example, if the CDP locations have been placed in bytes 181-184 instead of the standard 21-24, <tt>cdp=180</tt> will remap the trace header to that location. <br />
<br />
===SU-specific parameters===<br />
*<tt>suxdr=</tt> specifies whether the input file was created with a SU package with XDR support enabled. If you have access to the source code of your SU install (try <tt>$CWPROOT/src</tt>), type: <tt>grep 'XDRFLAG =' $CWPROOT/src/Makefile.config</tt> and look at the last uncommented entry. If no value is given for <tt>XDRFLAG</tt>, the package was not compiled with XDR support.<br />
===Common parameters===<br />
*<tt>su=</tt> specifies if the input file is SU or SEG-Y. Default is <tt>su=n</tt> (SEG-Y file).<br />
*<tt>tape=</tt> specifies the input data. Stdin could not be used because <tt>sfsegyread</tt> has to work with tapes, and needs to fseek back and forth through the input file. Thankfully, output is on stdout.<br />
*<tt>read=</tt> specifies what parts of the "Trace Blocks" will be read. It can be <tt>read=t</tt> (only trace data is read), <tt>read=h</tt> (only trace headers are read) or <tt>read=b</tt> (both are read).<br />
*<tt>tfile=</tt> gives the name of the RSF file to which trace headers are written. Obviously, it should be only specified with <tt>read=h</tt> or <tt>read=b</tt>.<br />
*<tt>mask=</tt> is an optional parameter specifying the name of a mask that says which traces will be read. The mask is a 1-D RSF file with integers. The number of samples in the mask is the same as the number of traces in the unmasked SEG-Y. In places corresponding to unwanted traces there should be zeros in the mask.<br />
*<tt>ns=</tt> specifies the number of samples in a trace. For SEG-Y files, the default is taken from the binary reel header, and for SU files, from the header of the first trace. This parameter is however critical enough that a command line override was given for it.<br />
*<tt>verbose=</tt> is the verbosity flag. Can be <tt>y</tt> or <tt>n</tt>.<br />
*<tt>endian=</tt> is a y/n flag (default y), specifying whether to automatically estimate or not if samples in the Trace Data blocks are big-endian or little-endian. Try it if you are in trouble and do not know what else to do, otherwise let the automatic estimation do its job.<br />
<br />
==sfsegywrite==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert an RSF dataset to SEGY or SU.<br />
|-<br />
! colspan="4" | sfsegywrite < in.rsf tfile=hdr.rsf verb=false su=false endian=sf_endian() tape= hfile= bfile=<br />
|-<br />
| colspan="4" | <br>Merges trace headers with data.<br />
|-<br />
| ''string '' || '''bfile=''' || || input binary data header file<br />
|-<br />
| ''bool '' || '''endian=sf_endian()''' || [y/n] || big/little endian flag. The default is estimated automatically<br />
|-<br />
| ''string '' || '''hfile=''' || || input text data header file<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if output is SU, n if output is SEGY<br />
|-<br />
| ''string '' || '''tape=''' || ||<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
Please see <tt>sfsegyread</tt> for a complete description of parameter meanings and background issues. Parameters <tt>bfile</tt> and <tt>hfile</tt> should only be given values when the desired file is SEG-Y (default). The output file is specified by the <tt>tape=</tt> tag.<br />
<br />
=Plotting programs=<br />
The source files for these programs can be found under<br />
[http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/plot/main/ plot/main]<br />
in the Madagascar distribution.<br />
<br />
THIS SECTION IS UNDER CONSTRUCTION<br />
<br />
==sfbox==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Draw a balloon-style label.<br />
|-<br />
! colspan="4" | sfbox lab_color=VP_WHITE lab_fat=0 pscale=1. pointer=y reverse=n lat=0. long=90. angle=0. x0=0. y0=0. scale0=1. xt=2. yt=0. x_oval=0. y_oval=0. boxit=y length= scalet= size=.25 label= > out.vpl<br />
|-<br />
| ''float '' || '''angle=0.''' || || longitude of floating label in 3-D<br />
|-<br />
| ''bool '' || '''boxit=y''' || [y/n] || if y, create a box around text<br />
|-<br />
| ''int '' || '''lab_color=VP_WHITE''' || || label color<br />
|-<br />
| ''int '' || '''lab_fat=0''' || || label fatness<br />
|-<br />
| ''string '' || '''label=''' || || text for label<br />
|-<br />
| ''float '' || '''lat=0.''' || || <br />
|-<br />
| ''float '' || '''length=''' || || normalization for xt and yt<br />
|-<br />
| ''float '' || '''long=90.''' || || latitude and longitude of viewpoint in 3-D<br />
|-<br />
| ''bool '' || '''pointer=y''' || [y/n] || if y, create arrow pointer<br />
|-<br />
| ''float '' || '''pscale=1.''' || || scale factor for width of pointer<br />
|-<br />
| ''bool '' || '''reverse=n''' || [y/n] || <br />
|-<br />
| ''float '' || '''scale0=1.''' || || scale factor for x0 and y0<br />
|-<br />
| ''float '' || '''scalet=''' || || <br />
|-<br />
| ''float '' || '''size=.25''' || || text height in inches<br />
|-<br />
| ''float '' || '''x0=0.''' || || <br />
|-<br />
| ''float '' || '''x_oval=0.''' || || <br />
|-<br />
| ''float '' || '''xt=2.''' || || <br />
|-<br />
| ''float '' || '''y0=0.''' || || position of the pointer tip<br />
|-<br />
| ''float '' || '''y_oval=0.''' || || size of the oval around pointer<br />
|-<br />
| ''float '' || '''yt=0.''' || || relative position of text<br />
|}<br />
==sfcontour==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Contour plot.<br />
|-<br />
! colspan="4" | sfcontour < in.rsf c= min1=o1 min2=o2 max1=o1+(n1-1)*d1 max2=o2+(n2-1)*d2 nc=50 dc= c0= transp=y minval= maxval= allpos=y barlabel= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=y''' || [y/n] || contour positive values only<br />
|-<br />
| ''string '' || '''barlabel=''' || || <br />
|-<br />
| ''floats '' || '''c=''' || || [nc]<br />
|-<br />
| ''float '' || '''c0=''' || || first contour<br />
|-<br />
| ''float '' || '''dc=''' || || contour increment<br />
|-<br />
| ''float '' || '''max1=o1+(n1-1)*d1''' || || <br />
|-<br />
| ''float '' || '''max2=o2+(n2-1)*d2''' || || data window to plot<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''min1=o1''' || || <br />
|-<br />
| ''float '' || '''min2=o2''' || || <br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nc=50''' || || number of contours<br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfdots==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot signal with lollipops.<br />
|-<br />
! colspan="4" | sfdots < in.rsf labels= dots=(n1 <= 130)? 1: 0 seemean=(bool) (n2 <= 30) strings=(bool) (n1 <= 400) connect=1 corners= silk=n gaineach=y labelsz=8 yreverse=n constsep=n seedead=n transp=n xxscale=1. yyscale=1. clip=-1. overlap=0.9 screenratio=VP_SCREEN_RATIO screenht=VP_STANDARD_HEIGHT screenwd=screenhigh / screenratio radius=dd1/3 label1= unit1= title= > plot.vpl<br />
|-<br />
| ''float '' || '''clip=-1.''' || || data clip<br />
|-<br />
| ''int '' || '''connect=1''' || || connection type: 1 - diagonal, 2 - bar, 4 - only for non-zero data<br />
|-<br />
| ''bool '' || '''constsep=n''' || [y/n] || if y, use constant trace separation<br />
|-<br />
| ''int '' || '''corners=''' || || number of polygon corners (default is 6)<br />
|-<br />
| ''int '' || '''dots=(n1 <= 130)? 1: 0''' || || type of dots: 1 - baloon, 0 - no dots, 2 - only for non-zero data<br />
|-<br />
| ''bool '' || '''gaineach=y''' || [y/n] || if y, gain each trace independently<br />
|-<br />
| ''string '' || '''label1=''' || || <br />
|-<br />
| ''strings'' || '''labels=''' || || trace labels [n2]<br />
|-<br />
| ''int '' || '''labelsz=8''' || || label size<br />
|-<br />
| ''float '' || '''overlap=0.9''' || || trace overlap<br />
|-<br />
| ''float '' || '''radius=dd1/3''' || || dot radius<br />
|-<br />
| ''float '' || '''screenht=VP_STANDARD_HEIGHT''' || || screen height<br />
|-<br />
| ''float '' || '''screenratio=VP_SCREEN_RATIO''' || || screen aspect ratio<br />
|-<br />
| ''float '' || '''screenwd=screenhigh / screenratio''' || || screen width<br />
|-<br />
| ''bool '' || '''seedead=n''' || [y/n] || if y, show zero traces<br />
|-<br />
| ''bool '' || '''seemean=(bool) (n2 <= 30)''' || [y/n] || if y, draw axis lines<br />
|-<br />
| ''bool '' || '''silk=n''' || [y/n] || if y, silky plot<br />
|-<br />
| ''bool '' || '''strings=(bool) (n1 <= 400)''' || [y/n] || if y, draw strings<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axis<br />
|-<br />
| ''string '' || '''unit1=''' || || <br />
|-<br />
| ''float '' || '''xxscale=1.''' || || x scaling<br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse y axis<br />
|-<br />
| ''float '' || '''yyscale=1.''' || || y scaling<br />
|}<br />
==sfgraph3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot for surfaces.<br />
|-<br />
! colspan="4" | sfgraph3 < in.rsf orient=1 min= max= point1=0.5 point2=0.5 frame1=0.5*(min+max) frame2=n1-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y > plot.vpl<br />
|-<br />
| ''float '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''float '' || '''frame1=0.5*(min+max)''' || || <br />
|-<br />
| ''int '' || '''frame2=n1-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''max=''' || || maximum function value<br />
|-<br />
| ''float '' || '''min=''' || || minimum function value<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''orient=1''' || || function orientation<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|}<br />
==sfgraph==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Graph plot.<br />
|-<br />
! colspan="4" | sfgraph < in.rsf symbolsz= pclip=100. transp=n symbol= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''pclip=100.''' || || clip percentile<br />
|-<br />
| ''string '' || '''symbol=''' || || if set, plot with symbols instead of lines<br />
|-<br />
| ''floats '' || '''symbolsz=''' || || symbol size (default is 2) [n2]<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfgrey3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot.<br />
|-<br />
! colspan="4" | sfgrey3 < in.rsf point1=0.5 point2=0.5 frame1=0 frame2=n2-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y scalebar=n minval= maxval= barreverse=n nreserve=8 bar= color= > plot.vpl<br />
|-<br />
| colspan="4" | Requires an "unsigned char" input (the output of sfbyte).<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''int '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''int '' || '''frame1=0''' || || <br />
|-<br />
| ''int '' || '''frame2=n2-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || if y, draw scalebar<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
for sfgrey and sfgrey3. Examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfgrey==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate raster plot.<br />
|-<br />
! colspan="4" | sfgrey < in.rsf > out.rsf bar=bar.rsf transp=y yreverse=y xreverse=n gpow= phalf= clip= pclip= gainstep=0.5+n1/256. allpos=n bias=0. polarity=n verb=n scalebar=n minval= maxval= barreverse=n wantframenum=(bool) (n3 > 1) nreserve=8 gainpanel= bar= color= > (plot.vpl | char.rsf)<br />
|-<br />
| colspan="4" | Can input char values.<br>If called "byte", outputs char values.<br><br>Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=n''' || [y/n] || if y, assume positive data<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=''' || || <br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''string '' || '''gainpanel=''' || || gain reference: 'a' for all, 'e' for each, or number<br />
|-<br />
| ''int '' || '''gainstep=0.5+n1/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=''' || || <br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''pclip=''' || || data clip percentile (default is 99)<br />
|-<br />
| ''float '' || '''phalf=''' || || percentage for estimating gpow<br />
|-<br />
| ''bool '' || '''polarity=n''' || [y/n] || if y, reverse polarity (white is high by default)<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the display axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''bool '' || '''wantframenum=(bool) (n3 > 1)''' || [y/n] || if y, display third axis position in the corner<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''bool '' || '''yreverse=y''' || [y/n] || if y, reverse the vertical axis<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
and examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfplas==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Assembler - convert ascii to vplot. <br />
|-<br />
! colspan="4" | sfplas<br />
|}<br />
==sfpldb==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Debugger - convert vplot to ascii. <br />
|-<br />
! colspan="4" | sfpldb<br />
|}<br />
==sfplotrays==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot rays.<br />
|-<br />
! colspan="4" | sfplotrays frame=frame.rsf nt=n1*n2 jr=1 frame= < rays.rsf > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''string '' || '''frame=''' || || <br />
|-<br />
| ''int '' || '''jr=1''' || || skip rays<br />
|-<br />
| ''int '' || '''nt=n1*n2''' || || maximum ray length<br />
|}<br />
==sfthplot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Hidden-line surface plot.<br />
|-<br />
! colspan="4" | sfthplot < in.rsf uflag=y dflag=y alpha=45. titlsz=9 axissz=6 plotfat=0 titlefat=2 axisfat=2 plotcolup=VP_YELLOW plotcoldn=VP_RED axis=y axis1=y axis2=y axis3=y clip=0. pclip=100. gainstep=0.5+nx/256. bias=0. dclip=1. norm=y xc=1.5 zc=3 ratio=5. zmax= zmin= sz=6. label#= unit#= tpow=0 epow=0 gpow=1 title= > plot.vpl<br />
|-<br />
| ''float '' || '''alpha=45.''' || || apparent angle in degrees, |alpha| < 89<br />
|-<br />
| ''bool '' || '''axis=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis1=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis2=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis3=y''' || [y/n] || plot axis<br />
|-<br />
| ''int '' || '''axisfat=2''' || || axes fatness<br />
|-<br />
| ''int '' || '''axissz=6''' || || axes size<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip<br />
|-<br />
| ''float '' || '''dclip=1.''' || || change the clip: clip *= dclip<br />
|-<br />
| ''bool '' || '''dflag=y''' || [y/n] || if y, plot down side of the surface<br />
|-<br />
| ''float '' || '''epow=0''' || || exponential gain<br />
|-<br />
| ''int '' || '''gainstep=0.5+nx/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=1''' || || power gain<br />
|-<br />
| ''string '' || '''label#=''' || || label on #-th axis<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || normalize by the clip<br />
|-<br />
| ''float '' || '''pclip=100.''' || || data clip percentile<br />
|-<br />
| ''int '' || '''plotcoldn=VP_RED''' || || color of the lower side<br />
|-<br />
| ''int '' || '''plotcolup=VP_YELLOW''' || || color of the upper side<br />
|-<br />
| ''int '' || '''plotfat=0''' || || line fatness<br />
|-<br />
| ''float '' || '''ratio=5.''' || || plot adjustment<br />
|-<br />
| ''float '' || '''sz=6.''' || || vertical scale<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''int '' || '''titlefat=2''' || || title fatness<br />
|-<br />
| ''int '' || '''titlsz=9''' || || title size<br />
|-<br />
| ''string '' || '''tpow=0''' || || time power gain<br />
|-<br />
| ''bool '' || '''uflag=y''' || [y/n] || if y, plot upper side of the surface<br />
|-<br />
| ''string '' || '''unit#=''' || || unit on #-th axis<br />
|-<br />
| ''float '' || '''xc=1.5''' || || <br />
|-<br />
| ''float '' || '''zc=3''' || || lower left corner of the plot<br />
|-<br />
| ''float '' || '''zmax=''' || || <br />
|-<br />
| ''float '' || '''zmin=''' || || <br />
|}<br />
==sfwiggle==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot data with wiggly traces. <br />
|-<br />
! colspan="4" | sfwiggle < in.rsf xpos=xpos.rsf xmax= xmin= poly=n fatp=1 xmask=1 ymask=1 pclip=98. zplot=0.75 clip=0. seemean=n verb=n transp=n yreverse=n xreverse=n xpos= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip (estimated from pclip by default<br />
|-<br />
| ''int '' || '''fatp=1''' || || <br />
|-<br />
| ''float '' || '''pclip=98.''' || || clip percentile<br />
|-<br />
| ''bool '' || '''poly=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''seemean=n''' || [y/n] || if y, plot mean lines of traces<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''int '' || '''xmask=1''' || || <br />
|-<br />
| ''float '' || '''xmax=''' || || maximum trace position (if using xpos)<br />
|-<br />
| ''float '' || '''xmin=''' || || minimum trace position (if using xpos)<br />
|-<br />
| ''string '' || '''xpos=''' || || optional header file with trace positions<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''int '' || '''ymask=1''' || || <br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse the vertical axis<br />
|-<br />
| ''float '' || '''zplot=0.75''' || || <br />
|}<br />
<br />
=filt/imag programs=<br />
==sfremap1==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 1-D ENO interpolation. <br />
|-<br />
! colspan="4" | sfremap1 < in.rsf > out.rsf pattern=pattern.rsf n1=n1 d1=d1 o1=o1 order=3<br />
|-<br />
| ''float '' || '''d1=d1''' || || Output sampling<br />
|-<br />
| ''int '' || '''n1=n1''' || || Number of output samples<br />
|-<br />
| ''float '' || '''o1=o1''' || || Output origin<br />
|-<br />
| ''int '' || '''order=3''' || || Interpolation order<br />
|-<br />
| ''string '' || '''pattern=''' || || auxiliary input file name<br />
|}<br />
To give an example of usage, we will create an input for <tt>sfremap1</tt> with:<br />
<pre><br />
sfmath n1=11 n2=11 d1=1 d2=1 o1=-5 o2=-5 output="x1*x1+x2*x2" > inp2remap1.rsf<br />
</pre><br />
Let us interpolate the data across both dimensions, then display it:<br />
<pre><br />
&lt; inp2remap1.rsf sfremap1 n1=1001 d1=0.01 | sftransp | \<br />
sfremap1 n1=1001 d1=0.01 | sftransp | sfgrey allpos=y | xtpen<br />
</pre><br />
The comparison with the uninterpolated data ( <tt>&lt; inp2remap1.rsf sfgrey allpos=y | xtpen</tt> ) is quite telling.<br />
<br />
=filt/proc programs=<br />
==sfstretch==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stretch of the time axis. <br />
|-<br />
! colspan="4" | sfstretch < in.rsf > out.rsf datum=dat.rsf inv=n dens=1 v0= half=y delay= tdelay= hdelay= nout=dens*n1 extend=4 mute=0 maxstr=0 rule=<br />
|-<br />
| ''file '' || '''datum=''' || || auxiliary input file name<br />
|-<br />
| ''float '' || '''delay=''' || || time delay for rule=lmo<br />
|-<br />
| ''int '' || '''dens=1''' || || axis stretching factor<br />
|-<br />
| ''int '' || '''extend=4''' || || trace extension<br />
|-<br />
| ''bool '' || '''half=y''' || [y/n] || if y, the second axis is half-offset instead of full offset<br />
|-<br />
| ''float '' || '''hdelay=''' || || offset delay for rule=rad<br />
|-<br />
| ''bool '' || '''inv=n''' || [y/n] || if y, do inverse stretching<br />
|-<br />
| ''float '' || '''maxstr=0''' || || maximum stretch<br />
|-<br />
| ''int '' || '''mute=0''' || || tapering size<br />
|-<br />
| ''int '' || '''nout=dens*n1''' || || output axis length (if inv=n)<br />
|-<br />
| ''string '' || '''rule=''' || || Stretch rule:<br />
:n - normal moveout (nmostretch), default<br />
:l - linear moveout (lmostretch)<br />
:L - logarithmic stretch (logstretch)<br />
:2 - t^2 stretch (t2stretch)<br />
:c - t^2 chebyshev stretch (t2chebstretch)<br />
:r - radial moveout (radstretch)<br />
:d - datuming (datstretch)<br />
|-<br />
| ''float '' || '''tdelay=''' || || time delay for rule=rad<br />
|-<br />
| ''float '' || '''v0=''' || || moveout velocity<br />
|}<br />
<br />
<tt>sfstretch rule=d</tt> (aka <tt>sfdatstretch</tt>) can be used to apply statics. Here is a synthetic example, courtesy of Alessandro Frigeri:<br />
<pre><br />
# generate a dataset with 'flat' signals<br />
sfmath n1=200 n2=100 output="sin(0.5*x1)" type=float > scan.rsf<br />
<br />
# generate a sinusoidal elevation correction<br />
sfmath n1=100 output="3*sin(x1)" type=float > statics.rsf<br />
<br />
# apply statics, producing a 'wavy' output.<br />
sfstretch < scan.rsf > out.rsf datum=statics.rsf rule=d<br />
</pre><br />
<br />
=user/ivlad programs=<br />
==sfprep4plot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Resamples a 2-D dataset to the desired picture resolution, with antialias<br />
|-<br />
! colspan="4" | sfprep4plot inp= out= verb=n h=none w=none unit= ppi= prar=y<br />
|-<br />
| colspan="4" | Only one of the h and w parameters needs to be specified.<br>If prar=n, no action will be taken on axis for which h/w was not specified<br>If prar=y and only one par (h or w) is specified, the picture will scale<br>along both axes until it is of the specified dimension.<br />
|-<br />
| ''int '' || '''h=none''' || || output height<br />
|-<br />
| ''string '' || '''inp=''' || || input file<br />
|-<br />
| ''string '' || '''out=''' || || output file<br />
|-<br />
| ''int '' || '''ppi=''' || || output resolution (px/in). Necessary when unit!=px<br />
|-<br />
| ''bool '' || '''prar=y''' || [y/n] || if y, PReserve Aspect Ratio of input<br />
|-<br />
| ''string '' || '''unit=''' || || unit of h and w. Can be: px(default), mm, cm, in<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || if y, print system commands, outputs<br />
|-<br />
| ''int '' || '''w=none''' || || output width<br />
|}<br />
For a figure that does not need the aspect ratio preserved,<br />
and needs to fill a 1280x1024 projector display:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=1280 h=1024 prar=n<br />
</pre><br />
For a print figure that has to fit in a 6x8in box<br />
at a resolution of 250 dpi, preserving the aspect ratio:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=6 h=8 unit=in ppi=250<br />
</pre><br />
A comparison of images before and after the application of <tt>sfprep4plot</tt>, courtesy of Joachim Mispel, is shown below:<br />
<br />
[[Image:sf_prep4plot.jpg]]<br />
<br />
=user/jennings programs=<br />
==sfsizes==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display the size of RSF files.<br />
|-<br />
! colspan="4" | sfsizes files=y human=n file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | Prints the element size, number of elements, and number of bytes<br>for a list of RSF files. Non-RSF files are ignored.<br />
|-<br />
| ''bool '' || '''files=y''' || [y/n] || If y, print size of each file. If n, print only total.<br />
|-<br />
| ''bool '' || '''human=n''' || [y/n] || If y, print human-readable file size. If n, print byte count.<br />
|}<br />
<br />
<br />
This program computes the "theoretical" size in bytes of the data fork of RSF files. The actual space occupied on disk may be different and machine dependent due to disk blocking factors, etc. This theoretical array size should be reproducible. It is also fast because the program only reads the RSF headers files, not the actual data.<br />
<br />
For example, to get the total size of all RSF files in a directory, in human readable format, without listing each file:<br />
<pre><br />
sfsizes files=n human=y *.rsf<br />
</pre><br />
This will also work because sfsizes simply skips any non-RSF file:<br />
<pre><br />
sfsizes files=n human=y *<br />
</pre><br />
<br />
=References=<br />
<references/></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Guide_to_madagascar_programs&diff=710Guide to madagascar programs2009-03-12T18:35:27Z<p>Jenningsjwj: /* sfsizes */</p>
<hr />
<div><center><font size="-1">''This page was created from the LaTeX source in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/rsf/rsf/prog.tex?view=markup book/rsf/rsf/prog.tex] using [[latex2wiki]]''</font></center><br />
<br />
This guide introduces some of the most used <tt>madagascar</tt> programs and illustrates their usage with examples.<br />
=Main programs=<br />
The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/ system/main] in the Madagascar distribution. The "main" programs perform general-purpose operations on RSF hypercubes regardless of the data dimensionality or physical dimensions.<br />
<br />
==sfadd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Add, multiply, or divide RSF datasets.<br />
|-<br />
! colspan="4" | sfadd > out.rsf scale= add= sqrt= abs= log= exp= mode= [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | The various operations, if selected, occur in the following order:<br><br>(1) Take absolute value, abs=<br>(2) Add a scalar, add=<br>(3) Take the natural logarithm, log=<br>(4) Take the square root, sqrt=<br>(5) Multiply by a scalar, scale=<br>(6) Compute the base-e exponential, exp=<br>(7) Add, multiply, or divide the data sets, mode=<br><br>sfadd operates on integer, float, or complex data, but all the input<br>and output files must be of the same data type.<br><br>An alternative to sfadd is sfmath, which is more versatile, but may be<br>less efficient.<br />
|-<br />
| ''bools '' || '''abs=''' || || If true take absolute value [nin]<br />
|-<br />
| ''floats '' || '''add=''' || || Scalar values to add to each dataset [nin]<br />
|-<br />
| ''bools '' || '''exp=''' || || If true compute exponential [nin]<br />
|-<br />
| ''bools '' || '''log=''' || || If true take logarithm [nin]<br />
|-<br />
| ''string '' || '''mode=''' || || 'a' means add (default), <br> 'p' or 'm' means multiply, <br> 'd' means divide<br />
|-<br />
| ''floats '' || '''scale=''' || || Scalar values to multiply each dataset with [nin]<br />
|-<br />
| ''bools '' || '''sqrt=''' || || If true take square root [nin]<br />
|}<br />
<br />
<tt>sfadd</tt> is useful for combining (adding, dividing, or<br />
multiplying) several datasets. What if you want to subtract two<br />
datasets? Easy. Use the <tt>scale</tt> parameter as follows:<br />
<pre><br />
bash&#36; sfadd data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfadd < data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
The same task can be accomplished with the more general <tt>sfmath</tt> program:<br />
<pre><br />
bash&#36; sfmath one=data1.rsf two=data2.rsf output='one-two' > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfmath < data1.rsf two=data2.rsf output='input-two' > diff.rsf<br />
</pre><br />
In both cases, the size and shape of <tt>data1.rsf</tt> and<br />
<tt>data2.rsf</tt> hypercubes should be the same, and a warning<br />
message is printed out if the the axis sampling parameters (such as<br />
<tt>o1</tt> or <tt>d1</tt>) in these files are different.<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/add.c?view=markup user/main/add.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
/* find number of input files */<br />
if (isatty(fileno(stdin))) { <br />
/* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Collect input files in the <tt>in</tt> array from all command-line<br />
parameters that don't contain an "<tt>=</tt>" sign. The total number<br />
of input files in <tt>nin</tt>.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) continue; <br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
/* nin = no of input files*/<br />
</c><br />
<br />
A helper function <tt>check_compat</tt> checks the compatibility of<br />
input files.<br />
<c><br />
static void <br />
check_compat (sf_datatype type /* data type */, <br />
size_t nin /* number of files */, <br />
sf_file* in /* input files [nin] */, <br />
int dim /* file dimensionality */, <br />
const int* n /* dimensions [dim] */)<br />
/* Check that the input files are compatible. <br />
Issue error for type mismatch or size mismatch.<br />
Issue warning for grid parameters mismatch. */<br />
{<br />
int ni, id;<br />
size_t i;<br />
float d, di, o, oi;<br />
char key[3];<br />
const float tol=1.e-5; /* tolerance for comparison */<br />
<br />
for (i=1; i < nin; i++) {<br />
if (sf_gettype(in[i]) != type) <br />
sf_error ("type mismatch: need %d",type);<br />
for (id=1; id <= dim; id++) {<br />
(void) snprintf(key,3,"n%d",id);<br />
if (!sf_histint(in[i],key,&ni) || ni != n[id-1])<br />
sf_error("%s mismatch: need %d",key,n[id-1]);<br />
(void) snprintf(key,3,"d%d",id);<br />
if (sf_histfloat(in[0],key,&d)) {<br />
if (!sf_histfloat(in[i],key,&di) || <br />
(fabsf(di-d) > tol*fabsf(d)))<br />
sf_warning("%s mismatch: need %g",key,d);<br />
} else {<br />
d = 1.;<br />
}<br />
(void) snprintf(key,3,"o%d",id);<br />
if (sf_histfloat(in[0],key,&o) && <br />
(!sf_histfloat(in[i],key,&oi) || <br />
(fabsf(oi-o) > tol*fabsf(d))))<br />
sf_warning("%s mismatch: need %g",key,o);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
Finally, we enter the main loop, where input data are getting read<br />
buffer by buffer and combined in the total product depending on the<br />
data type.<br />
<c><br />
for (nbuf /= sf_esize(in[0]); nsiz > 0; nsiz -= nbuf) {<br />
if (nbuf > nsiz) nbuf=nsiz;<br />
<br />
for (j=0; j < nin; j++) {<br />
collect = (bool) (j != 0);<br />
switch(type) {<br />
case SF_FLOAT:<br />
sf_floatread((float*) bufi,<br />
nbuf,<br />
in[j]); <br />
add_float(collect, <br />
nbuf,<br />
(float*) buf,<br />
(const float*) bufi, <br />
cmode, <br />
scale[j], <br />
add[j], <br />
abs_flag[j], <br />
log_flag[j], <br />
sqrt_flag[j], <br />
exp_flag[j]);<br />
break;<br />
</c><br />
<br />
The data combination program for floating point numbers is<br />
<tt>add_float</tt>. <br />
<c><br />
static void add_float (bool collect, /* if collect */<br />
size_t nbuf, /* buffer size */<br />
float* buf, /* output [nbuf] */<br />
const float* bufi, /* input [nbuf] */ <br />
char cmode, /* operation */<br />
float scale, /* scale factor */<br />
float add, /* add factor */<br />
bool abs_flag, /* if abs */<br />
bool log_flag, /* if log */<br />
bool sqrt_flag, /* if sqrt */<br />
bool exp_flag /* if exp */)<br />
/* Add floating point numbers */<br />
{<br />
size_t j;<br />
float f;<br />
<br />
for (j=0; j < nbuf; j++) {<br />
f = bufi[j];<br />
if (abs_flag) f = fabsf(f);<br />
f += add;<br />
if (log_flag) f = logf(f);<br />
if (sqrt_flag) f = sqrtf(f);<br />
if (1. != scale) f *= scale;<br />
if (exp_flag) f = expf(f);<br />
if (collect) {<br />
switch (cmode) {<br />
case 'p': /* product */<br />
case 'm': /* multiply */<br />
buf[j] *= f;<br />
break;<br />
case 'd': /* delete */<br />
if (f != 0.) buf[j] /= f;<br />
break;<br />
default: /* add */<br />
buf[j] += f;<br />
break;<br />
}<br />
} else {<br />
buf[j] = f;<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display dataset attributes.<br />
|-<br />
! colspan="4" | sfattr < in.rsf want=<br />
|-<br />
| colspan="4" | <br>Sample output from "sfspike n1=100 | sfbandpass fhi=60 | sfattr"<br>******************************************* <br>rms = 0.992354 <br>mean value = 0.987576 <br>2-norm value = 9.92354 <br>variance = 0.00955481 <br>standard deviation = 0.0977487 <br>maximum value = 1.12735 at 97 <br>minimum value = 0.151392 at 100 <br>number of nonzero samples = 100 <br>total number of samples = 100 <br>******************************************* <br><br>rms = sqrt[ sum(data^2) / n ]<br>mean = sum(data) / n<br>norm = sum(abs(data)^lval)^(1/lval)<br>variance = [ sum(data^2) - n*mean^2 ] / [ n-1 ]<br>standard deviation = sqrt [ variance ]<br />
|-<br />
| ''int '' || '''lval=2''' || || norm option, lval is a non-negative integer, computes the vector lval-norm<br />
|-<br />
| ''string '' || '''want=''' || || 'all'(default),'rms','mean','norm','var','std','max','min','nonzero','samples','short' <br />
:want= 'rms' displays the root mean square<br />
:want= 'norm' displays the square norm, otherwise specified by lval.<br />
:want= 'var' displays the variance<br />
:want= 'std' displays the standard deviation<br />
:want= 'nonzero' displays number of nonzero samples<br />
:want= 'samples' displays total number of samples<br />
:want= 'short' displays a short one-line version<br />
|}<br />
<br />
<br />
<tt>sfattr</tt> is a useful diagnostic program. It reports certain<br />
statistical values for an RSF dataset: RMS (root-mean-square)<br />
amplitude, mean value, vector norm value, variance, standard deviation,<br />
maximum and minimum values, number of nonzero samples, and the total<br />
number of samples.<br />
If we denote data values as <math>d_i</math> for <math>i=0,1,2,\ldots,n</math>, then the RMS<br />
value is <math>\sqrt{\frac{1}{n}\,\sum\limits_{i=0}^n d_i^2}</math>, the mean<br />
value is <math>\frac{1}{n}\,\sum\limits_{i=0}^n d_i</math>, the <math>L_2</math>-norm value<br />
is <math>\sqrt{\sum\limits_{i=0}^n d_i^2}</math>, the variance is<br />
<math>\frac{1}{n-1}\,\left[\sum\limits_{i=0}^n d_i^2 - \frac{1}{n}\left(\sum\limits_{i=0}^n d_i\right)^2\right]</math>, and the standard<br />
deviation is the square root of the variance. Using <tt>sfattr</tt><br />
is a quick way to see the distribution of data values and check it for<br />
anomalies.<br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/attr.c?view=markup user/main/attr.c]====<br />
<br />
Computations start by finding the input data (<tt>in</tt>) size<br />
(<tt>nsiz</tt>) and dimensions (<tt>dim</tt>).<br />
<c><br />
dim = (size_t) sf_filedims (in,n);<br />
for (nsiz=1, i=0; i < dim; i++) {<br />
nsiz *= n[i];<br />
}<br />
</c><br />
<br />
<br />
In the main loop, we read the input data buffer by buffer.<br />
<c><br />
for (nleft=nsiz; nleft > 0; nleft -= nbuf) {<br />
nbuf = (bufsiz < nleft)? bufsiz: nleft;<br />
switch (type) {<br />
case SF_FLOAT: <br />
sf_floatread((float*) buf,nbuf,in);<br />
break;<br />
case SF_INT:<br />
sf_intread((int*) buf,nbuf,in);<br />
break;<br />
case SF_COMPLEX:<br />
sf_complexread((sf_complex*) buf,nbuf,in);<br />
break;<br />
case SF_UCHAR:<br />
sf_ucharread((unsigned char*) buf,nbuf,in);<br />
break;<br />
case SF_CHAR:<br />
default:<br />
sf_charread(buf,nbuf,in);<br />
break;<br />
}<br />
</c><br />
<br />
<br />
The data attributes are accumulated in corresponding double-precision<br />
variables. <br />
<c><br />
fsum += f;<br />
fsqr += f*f;<br />
</c><br />
<br />
<br />
Finally, the attributes are reduced and printed out.<br />
<c><br />
fmean = fsum/nsiz;<br />
if (lval==2) fnorm = sqrt(fsqr);<br />
else if (lval==0) fnorm = nsiz-nzero;<br />
else fnorm = pow(flval,1./lval);<br />
frms = sqrt(fsqr/nsiz);<br />
if (nsiz > 1) fvar = (fsqr-nsiz*fmean*fmean)/(nsiz-1);<br />
else fvar = 0.0;<br />
fstd = sqrt(fvar);<br />
</c><br />
<br />
<c><br />
if(NULL==want || 0==strcmp(want,"rms"))<br />
printf("rms = %g \n",(float) frms);<br />
if(NULL==want || 0==strcmp(want,"mean"))<br />
printf("mean value = %g \n",(float) fmean);<br />
if(NULL==want || 0==strcmp(want,"norm"))<br />
printf("%d-norm value = %g \n",lval,(float) fnorm);<br />
if(NULL==want || 0==strcmp(want,"var"))<br />
printf("variance = %g \n",(float) fvar);<br />
if(NULL==want || 0==strcmp(want,"std"))<br />
printf("standard deviation = %g \n",(float) fstd);<br />
</c><br />
<br />
==sfcat==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Concatenate datasets. <br />
|-<br />
! colspan="4" | sfcat > out.rsf space= axis=3 nspace=(int) (ni/(20*nin) + 1) [<file0.rsf] file1.rsf file2.rsf ... <br />
|-<br />
| colspan="4" | sfmerge inserts additional space between merged data.<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis being merged<br />
|-<br />
| ''int '' || '''nspace=(int) (ni/(20*nin) + 1)''' || || if space=y, number of traces to insert<br />
|-<br />
| ''bool '' || '''space=''' || [y/n] || Insert additional space.<br />
:y is default for sfmerge, n is default for sfcat<br />
|}<br />
<br />
<br />
<tt>sfcat</tt> and <tt>sfmerge</tt> concatenate two or more files<br />
together along a particular axis. It is the same program, only<br />
<tt>sfcat</tt> has the default <tt>space=n</tt> and <tt>sfmerge</tt><br />
has the default <tt>space=y</tt>.<br />
Example of <tt>sfcat</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcat one.rsf one.rsf axis=1 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=4 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
12 elements 48 bytes<br />
</pre><br />
Example of <tt>sfmerge</tt>:<br />
<pre><br />
bash$ sfmerge one.rsf one.rsf axis=2 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=7 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
14 elements 56 bytes<br />
</pre><br />
In this case, an extra empty trace is inserted between the two merged files.<br />
The axes that are not being merged are checked for consistency:<br />
<pre><br />
bash$ sfcat one.rsf two.rsf > three.rsf<br />
sfcat: n2 mismatch: need 3<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cat.c?view=markup user/main/cat.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
in = (sf_file*) sf_alloc ((size_t) argc,sizeof(sf_file));<br />
<br />
if (!sf_stdin()) { /* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Everything on the command line that does not contain a "=" sign is<br />
treated as a file name, and the corresponding file object is added to the list.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) <br />
continue; /* not a file */<br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
</c><br />
<br />
As explained above, if the <tt>space=</tt> parameter is not set, it is<br />
inferred from the program name: <tt>sfmerge</tt> corresponds to<br />
<tt>space=y</tt> and <tt>sfcat</tt> corresponds to <tt>space=n</tt>.<br />
<c><br />
if (!sf_getbool("space",&space)) {<br />
/* Insert additional space.<br />
y is default for sfmerge, n is default for sfcat */<br />
prog = sf_getprog();<br />
if (NULL != strstr (prog, "merge")) {<br />
space = true;<br />
} else if (NULL != strstr (prog, "cat")) {<br />
space = false;<br />
} else {<br />
sf_warning("%s is neither merge nor cat,"<br />
" assume merge",prog);<br />
space = true;<br />
}<br />
}<br />
</c><br />
<br />
Find the axis for the merging (from the command line <tt>axis=</tt><br />
argument) and figure out two sizes: <tt>n1</tt> for everything after<br />
the axis and <tt>n2</tt> for everything before the axis.<br />
<c><br />
n1=1;<br />
n2=1;<br />
for (i=1; i <= dim; i++) {<br />
if (i < axis) n1 *= n[i-1];<br />
else if (i > axis) n2 *= n[i-1];<br />
}<br />
</c><br />
<br />
In the output, the selected axis will get extended.<br />
<c><br />
/* figure out the length of extended axis */<br />
ni = 0;<br />
for (j=0; j < nin; j++) {<br />
ni += naxis[j];<br />
}<br />
<br />
if (space) {<br />
if (!sf_getint("nspace",&nspace)) <br />
nspace = (int) (ni/(20*nin) + 1);<br />
/* if space=y, number of traces to insert */ <br />
ni += nspace*(nin-1);<br />
} <br />
<br />
(void) snprintf(key,3,"n%d",axis);<br />
sf_putint(out,key,(int) ni);<br />
</c><br />
<br />
The rest is simple: loop through the datasets reading and writing the<br />
data in buffer-size chunks and adding extra empty chunks if<br />
<tt>space=y</tt>.<br />
<c><br />
for (i2=0; i2 < n2; i2++) {<br />
for (j=0; j < nin; j++) {<br />
for (ni = n1*naxis[j]*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charread (buf,nbuf,in[j]);<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
if (!space || j == nin-1) continue;<br />
/* Add spaces */<br />
memset(buf,0,BUFSIZ);<br />
for (ni = n1*nspace*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfcmplx==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a complex dataset from its real and imaginary parts.<br />
|-<br />
! colspan="4" | sfcmplx > cmplx.rsf real.rsf imag.rsf<br />
|-<br />
| colspan="4" | There has to be only two input files specified and no additional parameters.<br />
|}<br />
<br />
<br />
<tt>sfcmplx</tt> simply creates a complex dataset from its real and<br />
imaginary parts. The reverse operation can be accomplished with<br />
<tt>sfreal</tt> and <tt>sfimag</tt>.<br />
Example of <tt>sfcmplx</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcmplx one.rsf one.rsf > cmplx.rsf<br />
bash$ sfin cmplx.rsf<br />
cmplx.rsf:<br />
in="/tmp/cmplx.rsf@"<br />
esize=8 type=complex form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 48 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cmplx.c?view=markup user/main/cmplx.c]====<br />
The program flow is simple. First, get the names of the input files.<br />
<c><br />
/* the first two non-parameters are real and imaginary files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == real) {<br />
real = sf_input (argv[i]);<br />
} else {<br />
imag = sf_input (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == imag) {<br />
if (NULL == real) sf_error ("not enough input");<br />
/* if only one input, real is in stdin */<br />
imag = real;<br />
real = sf_input("in");<br />
}<br />
</c><br />
<br />
The main part of the program reads the real and imaginary parts buffer by buffer and assembles and writes out the complex input. <br />
<c><br />
for (nleft= (size_t) (rsize*resize); nleft > 0; nleft -= nbuf) {<br />
nbuf = (BUFSIZ < nleft)? BUFSIZ: nleft;<br />
sf_charread(rbuf,nbuf,real);<br />
sf_charread(ibuf,nbuf,imag);<br />
for (i=0; i < nbuf; i += resize) {<br />
memcpy(cbuf+2*i, rbuf+i,(size_t) resize);<br />
memcpy(cbuf+2*i+resize,ibuf+i,(size_t) resize);<br />
}<br />
sf_charwrite(cbuf,2*nbuf,cmplx);<br />
}<br />
</c><br />
<br />
==sfconjgrad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic conjugate-gradient solver for linear inversion <br />
|-<br />
! colspan="4" | sfconjgrad < dat.rsf mod=mod.rsf > to.rsf < from.rsf > out.rsf niter=1<br />
|-<br />
| ''int '' || '''niter=1''' || || number of iterations<br />
|}<br />
<br />
<br />
<tt>sfconjgrad</tt> is a generic program for least-squares linear<br />
inversion with the conjugate-gradient method. Suppose you have an<br />
executable program <tt><prog></tt> that takes an RSF file from the<br />
standard input and produces an RSF file in the standard output. It may<br />
take any number of additional parameters but one of them must be<br />
<tt>adj=</tt> that sets the forward (<tt>adj=0</tt>) or adjoint<br />
(<tt>adj=1</tt>) operations. The program <tt><prog></tt> is typically<br />
an RSF program but it could be anything (a script, a multiprocessor<br />
MPI program, etc.) as long as it implements a linear operator<br />
<math>\mathbf{L}</math> and its adjoint. There are no restrictions on the data<br />
size or shape. You can easily test the adjointness with<br />
<tt>sfdottest</tt>. The <tt>sfconjgrad</tt> program searches for a<br />
vector <math>\mathbf{m}</math> that minimizes the least-square misfit <br />
<math>\|\mathbf{d - L\,m}\|^2</math> for the given input data vector <math>\mathbf{d}</math>.<br />
Here is an example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
The <tt>sfdottest</tt> program can perform the dot product test to<br />
check that the adjoint mode works correctly.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=5.28394<br />
sfdottest: L'[d]*m=5.28394<br />
</pre><br />
Your numbers may be different because <tt>sfdottest</tt> generates new<br />
random input on each run.<br />
Next, let us make some random data with <tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfnoise seed=2005 rep=y < vec.rsf > dat.rsf<br />
</pre><br />
and try to invert the filtering operation using <tt>sfconjgrad</tt>:<br />
<pre><br />
bash$ sfconjgrad sfhelicon filt=flt.rsf lag=lag.rsf \<br />
mod=vec.rsf < dat.rsf > mod.rsf niter=10<br />
sfconjgrad: iter 1 of 10<br />
sfconjgrad: grad=3253.65<br />
sfconjgrad: iter 2 of 10<br />
sfconjgrad: grad=289.421<br />
sfconjgrad: iter 3 of 10<br />
sfconjgrad: grad=92.3481<br />
sfconjgrad: iter 4 of 10<br />
sfconjgrad: grad=36.9417<br />
sfconjgrad: iter 5 of 10<br />
sfconjgrad: grad=18.7228<br />
sfconjgrad: iter 6 of 10<br />
sfconjgrad: grad=11.1794<br />
sfconjgrad: iter 7 of 10<br />
sfconjgrad: grad=7.26941<br />
sfconjgrad: iter 8 of 10<br />
sfconjgrad: grad=5.15945<br />
sfconjgrad: iter 9 of 10<br />
sfconjgrad: grad=4.23055<br />
sfconjgrad: iter 10 of 10<br />
sfconjgrad: grad=3.57495<br />
</pre><br />
The output shows that, in 10 iterations, the norm of the gradient vector decreases by almost 1000. <br />
We can check the residual misfit before<br />
<pre><br />
bash$ < dat.rsf sfattr want=norm<br />
norm value = 49.7801<br />
</pre><br />
and after<br />
<pre><br />
bash$ sfhelicon filt=flt.rsf lag=lag.rsf < mod.rsf | \<br />
sfadd scale=1,-1 dat.rsf | sfattr want=norm<br />
norm value = 5.73563<br />
</pre><br />
In 10 iterations, the misfit decreased by an order of magnitude. The<br />
result can be improved by running the program for more iterations.<br />
<br />
==sfcp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Copy or move a dataset.<br />
|-<br />
! colspan="4" | sfcp in.rsf out.rsf<br />
|-<br />
| colspan="4" | sfcp - copy, sfmv - move.<br>Mimics standard Unix commands.<br />
|}<br />
<br />
<br />
The <tt>sfcp</tt> and <tt>sfmv</tt> command imitate the Unix<br />
<tt>cp</tt> and <tt>mv</tt> commands and serve for copying and moving<br />
RSF files. Example:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcp one.rsf two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
</pre><br />
<br />
==sfcut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of the dataset. <br />
|-<br />
! colspan="4" | sfcut < in.rsf > out.rsf verb=n [j1=1 j2=1 ... f1=0 f2=0 ... n1=n1 n2=n2 ... max1= max2= ... min1= min2= ...]<br />
|-<br />
| colspan="4" | jN defines the jump in N-th dimension<br>fN is the window start<br>nN is the window size<br>minN and maxN is the maximum and minimum in N-th dimension<br><br>Reverse of window. <br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
The <tt>sfcut</tt> command is related to <tt>sfwindow</tt> and has the same<br />
set of arguments only instead of extracting the selected window, it fills it<br />
with zeroes. The size of the input data is preserved. <br />
Examples:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > in.rsf<br />
bash$ < in.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < in.rsf sfcut n1=2 f1=1 n2=3 f2=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 0 0 1 1<br />
15: 1 0 0 1 1<br />
20: 1 0 0 1 1<br />
bash$ < in.rsf sfcut j1=2 | sfdisfil<br />
0: 0 1 0 1 0<br />
5: 0 1 0 1 0<br />
10: 0 1 0 1 0<br />
15: 0 1 0 1 0<br />
20: 0 1 0 1 0<br />
</pre><br />
<br />
==sfdd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert between different formats. <br />
|-<br />
! colspan="4" | sfdd < in.rsf > out.rsf line=8 form= type= format=<br />
|-<br />
| ''string '' || '''form=''' || || ascii, native, xdr<br />
|-<br />
| ''string '' || '''format=''' || || Element format (for conversion to ASCII)<br />
|-<br />
| ''int '' || '''line=8''' || || Number of numbers per line (for conversion to ASCII)<br />
|-<br />
| ''string '' || '''type=''' || || int, float, complex<br />
|}<br />
<br />
<br />
The <tt>sfdd</tt> program is used to change either the form (<tt>ascii</tt>,<br />
<tt>xdr</tt>, <tt>native</tt>) or the type (<tt>complex</tt>, <tt>float</tt>,<br />
<tt>int</tt>, <tt>char</tt>) of the input dataset. <br />
In the example below, we create a plain text (ASCII) file with numbers and<br />
then use <tt>sfdd</tt> to generate an RSF file in <tt>xdr</tt> form with<br />
<tt>complex</tt> numbers. <br />
<pre><br />
bash$ cat test.txt<br />
1 2 3 4 5 6<br />
bash$ echo n1=6 data_format=ascii_int in=test.txt > test.rsf<br />
bash$ sfin test.rsf<br />
test.rsf:<br />
in="test.txt"<br />
esize=0 type=int form=ascii<br />
n1=6 d1=? o1=?<br />
6 elements<br />
bash$ sfdd < test.rsf form=xdr type=complex > test2.rsf<br />
bash$ sfin test2.rsf<br />
test2.rsf:<br />
in="/tmp/test2.rsf@"<br />
esize=8 type=complex form=xdr<br />
n1=3 d1=? o1=?<br />
3 elements 24 bytes<br />
bash$ sfdisfil < test2.rsf<br />
0: 1, 2i 3, 4i 5, 6i<br />
</pre><br />
To learn more about the RSF data format, consult the [[Format| guide to RSF format]].<br />
<br />
==sfdisfil==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Print out data values.<br />
|-<br />
! colspan="4" | sfdisfil < in.rsf number=y col=0 format= header= trailer=<br />
|-<br />
| colspan="4" | <br>Alternatively, use sfdd and convert to ASCII form.<br />
|-<br />
| ''int '' || '''col=0''' || || Number of columns.<br />
:The default depends on the data type:<br />
:10 for int and char,<br />
:5 for float,<br />
:3 for complex<br />
|-<br />
| ''string '' || '''format=''' || || Format for numbers (printf-style).<br />
:The default depends on the data type:<br> "%4d " for int and char,<br> "%13.4g" for float,<br> "%10.4g,%10.4gi" for complex<br />
|-<br />
| ''string '' || '''header=''' || || Optional header string to output before data<br />
|-<br />
| ''bool '' || '''number=y''' || [y/n] || If number the elements<br />
|-<br />
| ''string '' || '''trailer=''' || || Optional trailer string to output after data<br />
|}<br />
<br />
<br />
The <tt>sfdisfil</tt> program simply dumps the data contents to the standard<br />
output in a text form. It is used mostly for debugging purposes to quickly<br />
examine RSF files. Here is an example:<br />
<pre><br />
bash$ sfmath o1=0 d1=2 n1=12 output=x1 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
10: 20 22<br />
</pre><br />
The output format is easily configurable.<br />
<pre><br />
bash$ < test.rsf sfdisfil col=6 number=n format="<br />
0.0 2.0 4.0 6.0 8.0 10.0<br />
12.0 14.0 16.0 18.0 20.0 22.0<br />
</pre><br />
Along with <tt>sfdd</tt>, <tt>sfdisfil</tt> provides a simple way to convert<br />
RSF data to an ASCII form.<br />
<br />
==sfdottest==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic dot-product test for linear operators with adjoints <br />
|-<br />
! colspan="4" | sfdottest mod=mod.rsf dat=dat.rsf > pip.rsf<br />
|}<br />
<br />
<br />
<tt>sfdottest</tt> is a generic dot-product test program for testing<br />
linear operators. Suppose there is an executable program<br />
<tt><prog></tt> that takes an RSF file from the standard input and<br />
produces an RSF file in the standard output. It may take any number of<br />
additional parameters but one of them must be <tt>adj=</tt> that sets<br />
the forward (<tt>adj=0</tt>) or adjoint (<tt>adj=1</tt>) operations.<br />
The program <tt><prog></tt> is typically an RSF program but it could<br />
be anything (a script, a multiprocessor MPI program, etc.) as long as<br />
it implements a linear operator <math>\mathbf{L}</math> and its adjoint<br />
<math>\mathbf{L}^T</math>. The <tt>sfdottest</tt> program is testing the equality<br />
<center><math><br />
d^T\,L\,m = m^T\,L^T\,d<br />
</math></center><br />
by using random vectors <math>\mathbf{m}</math> and <math>\mathbf{d}</math>. You can invoke it with<br />
<pre><br />
bash$ sfdottest <prog> [optional aruments] mod=mod.rsf dat=dat.rsf<br />
</pre><br />
where <tt>mod.rsf</tt> and <tt>dat.rsf</tt> are RSF files that<br />
represent vectors from the model and data spaces. <tt>sfdottest</tt><br />
does not create any temporary files and does not have any restrictive<br />
limitations on the size of the vectors.<br />
Here is an example. We first setup a vector with 100 elements using<br />
<tt>sfspike</tt> and then run <tt>sfdottest</tt> to test the<br />
<tt>sfcausint</tt> program. <tt>sfcausint</tt> implements a linear<br />
operator of causal integration and its adjoint, the anti-causal<br />
integration.<br />
<pre><br />
bash$ sfspike n1=100 > vec.rsf<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1410.2<br />
sfdottest: L'[d]*m=1410.2<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1165.87<br />
sfdottest: L'[d]*m=1165.87<br />
</pre><br />
The numbers are different on subsequent runs because of changing<br />
seed in the random number generator.<br />
Here is a somewhat more complicated example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
Now the <tt>sfdottest</tt> program can perform the dot product test.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=8.97375<br />
sfdottest: L'[d]*m=8.97375<br />
</pre><br />
Here is the same program tested in the inverse filtering mode:<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf inv=y<br />
sfdottest: L[m]*d=15.0222<br />
sfdottest: L'[d]*m=15.0222<br />
</pre><br />
<br />
==sfget==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Output parameters from the header.<br />
|-<br />
! colspan="4" | sfget < in.rsf parform=y par1 par2 ...<br />
|-<br />
| ''bool '' || '''parform=y''' || [y/n] || If y, print out parameter=value. If n, print out value.<br />
|}<br />
<br />
<br />
The <tt>sfget</tt> program extracts a parameter value from an RSF file. It is<br />
useful mostly for scripting. Here is, for example, a quick calculation of the<br />
maximum value on the first axis in an RSF dataset (the output of<br />
<tt>sfspike</tt>) using the standard Unix <tt>bc</tt> calculator.<br />
<pre><br />
bash$ ( sfspike n1=100 | sfget n1 d1 o1; echo "o1+(n1-1)*d1" ) | bc<br />
.396<br />
</pre><br />
See also <tt>sfput</tt>.<br />
<br />
<br />
<br />
==sfheadercut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheadercut mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array of size n2.<br />
|}<br />
<br />
<br />
<tt>sfheadercut</tt> is close to <tt>sfheaderwindow</tt> but instead<br />
of windowing the dataset, it fills the traces specified by the header<br />
mask with zeroes. The size of the input data is preserved.<br />
Here is an example of using <tt>sfheaderwindow</tt> for <br />
zeroing every other trace in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a mask with alternating ones and zeros using<br />
<tt>sfinterleave</tt>.<br />
<pre><br />
bash$ sfspike n1=5 mag=1 | sfdd type=int > ones.rsf<br />
bash$ sfspike n1=5 mag=0 | sfdd type=int > zeros.rsf<br />
bash$ sfinterleave axis=1 ones.rsf zeros.rsf > mask.rsf<br />
bash$ sfdisfil < mask.rsf<br />
0: 1 0 1 0 1 0 1 0 1 0<br />
</pre><br />
Finally, <tt>sfheadercut</tt> zeros the input traces.<br />
<pre><br />
bash$ sfheadercut < input.rsf mask=mask.rsf > output.rsf<br />
bash$ sfdisfil < output.rsf <br />
0: 1 1 1 1 1<br />
5: 0 0 0 0 0<br />
10: 3 3 3 3 3<br />
15: 0 0 0 0 0<br />
20: 5 5 5 5 5<br />
25: 0 0 0 0 0<br />
30: 7 7 7 7 7<br />
35: 0 0 0 0 0<br />
40: 9 9 9 9 9<br />
45: 0 0 0 0 0<br />
</pre><br />
<br />
<br />
<br />
==sfheadersort==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Sort a dataset according to a header key. <br />
|-<br />
! colspan="4" | sfheadersort < in.rsf > out.rsf head=<br />
|-<br />
| ''string '' || '''head=''' || || header file<br />
|}<br />
<br />
<br />
<tt>sfheadersort</tt> is used to sort traces in the input file<br />
according to trace header information. <br />
Here is an example of using<br />
<tt>sfheadersort</tt> for randomly shuffling traces in the input<br />
file. First, let us create an input file with seven traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=7 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7 <br />
</pre><br />
Next, we can create a random file with seven header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=7 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: 0.05256 -0.2879 0.1487 0.4097 0.1548<br />
5: 0.4501 0.2836<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally, we<br />
apply <tt>sfheadersort</tt> to shuffle the input traces.<br />
<pre><br />
bash$ < input.rsf sfheadersort head=random.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 1 1 1 1 1<br />
10: 3 3 3 3 3<br />
15: 5 5 5 5 5<br />
20: 7 7 7 7 7<br />
25: 4 4 4 4 4<br />
30: 6 6 6 6 6<br />
</pre><br />
As expected, the order of traces in the output file corresponds to the<br />
order of values in the header. Thanks to the separation between<br />
headers and data, the operation of <tt>sfheadersort</tt> is optimally<br />
efficient. It first sorts the headers and only then accesses the data,<br />
reading each data trace only once.<br />
<br />
==sfheaderwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheaderwindow mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array os size n2, windowed is n1xm2,<br>where m2 is the number of nonzero elements in mask.<br />
|}<br />
<br />
<br />
<tt>sfheaderwindow</tt> is used to window traces in the input file<br />
according to trace header information. <br />
Here is an example of using <tt>sfheaderwindow</tt> for randomly<br />
selecting part of the traces in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a random file with ten header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=10 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: -0.005768 0.02258 -0.04331 -0.4129 -0.3909<br />
5: -0.03582 0.4595 -0.3326 0.498 -0.3517<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally,<br />
we apply <tt>sfheaderwindow</tt> to window the input traces selecting<br />
only those for which the header is greater than zero.<br />
<pre><br />
bash$ < random.rsf sfmask min=0 > mask.rsf<br />
bash$ < mask.rsf sfdisfil<br />
0: 0 1 0 0 0 0 1 0 1 0<br />
bash$ < input.rsf sfheaderwindow mask=mask.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 7 7 7 7 7<br />
10: 9 9 9 9 9<br />
</pre><br />
In this case, only three traces are selected for the output. Thanks to<br />
the separation between headers and data, the operation of<br />
<tt>sfheaderwindow</tt> is optimally efficient. <br />
<br />
==sfin==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display basic information about RSF files.<br />
|-<br />
! colspan="4" | sfin info=y check=2. trail=y file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | n1,n2,... are data dimensions<br>o1,o2,... are axis origins<br>d1,d2,... are axis sampling intervals<br>label1,label2,... are axis labels<br>unit1,unit2,... are axis units<br />
|-<br />
| ''float '' || '''check=2.''' || || Portion of the data (in Mb) to check for zero values.<br />
|-<br />
| ''bool '' || '''info=y''' || [y/n] || If n, only display the name of the data file.<br />
|-<br />
| ''bool '' || '''trail=y''' || [y/n] || If n, skip trailing dimensions of one<br />
|}<br />
<br />
<br />
<tt>sfin</tt> is one of the most useful programs for operating with<br />
RSF files. It produces quick information on the file hypercube<br />
dimensions and checks the consistency of the associated data file.<br />
Here is an example. Let us create an RSF file and examine it with <tt>sfin</tt>.<br />
<pre><br />
bash$ sfspike n1=100 n2=20 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=100 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
2000 elements 8000 bytes<br />
</pre><br />
<tt>sfin</tt> reports the following information:<br />
<br />
*location of the data file (<tt>/tmp/spike.rsf\@</tt>) <br />
*element size (4 bytes) <br />
*element type (floating point) <br />
*element form (native) <br />
*hypercube dimensions (100 by 20) <br />
*axes scale (0.004 and 0.1) <br />
*axes origin (0 and 0) <br />
*axes labels <br />
*axes units <br />
*total number of elements <br />
*total number of bytes in the data file <br />
Suppose that the file got corrupted by a buggy program and reports<br />
incorrect dimensions. The <tt>sfin</tt> program should be able to<br />
catch the discrepancy.<br />
<pre><br />
bash$ echo n2=100 >> spike.rsf<br />
bash$ sfin spike.rsf > /dev/null<br />
sfin: Actually 8000 bytes, 20% of expected.<br />
</pre><br />
<tt>sfin</tt> also checks the first records in the file for zeros. <br />
<pre><br />
bash$ sfspike n1=100 n2=100 k2=99 > spike2.rsf<br />
bash$ sfin spike2.rsf >/dev/null<br />
sfin: The first 32768 bytes are all zeros<br />
</pre><br />
The number of bytes to check is adjustable<br />
<pre><br />
bash$ sfin spike2.rsf check=0.01 >/dev/null<br />
sfin: The first 16384 bytes are all zeros<br />
</pre><br />
You can also output only the location of the data file. This is<br />
sometimes handy in scripts.<br />
<pre><br />
bash$ sfin spike.rsf spike2.rsf info=n<br />
/tmp/spike.rsf@ /tmp/spike2.rsf@<br />
</pre><br />
An alternative is to use <tt>sfget</tt>, as follows:<br />
<pre><br />
bash$ sfget parform=n in < spike.rsf<br />
/tmp/spike.rsf@<br />
</pre><br />
<br />
==sfinterleave==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Combine several datasets by interleaving.<br />
|-<br />
! colspan="4" | sfinterleave > out.rsf axis=3 [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis for interleaving<br />
|}<br />
<br />
<br />
<tt>sfinterleave</tt> combines two or more datasets by interleaving them on one<br />
of the axes. Here is a quick example:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ sfscale < one.rsf dscale=2 > two.rsf<br />
bash$ sfdisfil < two.rsf<br />
0: 2 2 2 2 2<br />
5: 2 2 2 2 2<br />
10: 2 2 2 2 2<br />
15: 2 2 2 2 2<br />
20: 2 2 2 2 2<br />
bash$ sfinterleave one.rsf two.rsf axis=1 | sfdisfil<br />
0: 1 2 1 2 1<br />
5: 2 1 2 1 2<br />
10: 1 2 1 2 1<br />
15: 2 1 2 1 2<br />
20: 1 2 1 2 1<br />
25: 2 1 2 1 2<br />
30: 1 2 1 2 1<br />
35: 2 1 2 1 2<br />
40: 1 2 1 2 1<br />
45: 2 1 2 1 2<br />
bash$ sfinterleave < one.rsf two.rsf axis=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 1 1 1 1 1<br />
15: 2 2 2 2 2<br />
20: 1 1 1 1 1<br />
25: 2 2 2 2 2<br />
30: 1 1 1 1 1<br />
35: 2 2 2 2 2<br />
40: 1 1 1 1 1<br />
45: 2 2 2 2 2<br />
</pre><br />
<br />
==sfmask==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a mask.<br />
|-<br />
! colspan="4" | sfmask < in.rsf > out.rsf min=-FLT_MAX max=+FLT_MAX<br />
|-<br />
| colspan="4" | <br>Mask is an integer data with ones and zeros. <br>Ones correspond to input values between min and max.<br><br>The output can be used with sfheaderwindow.<br />
|-<br />
| ''float '' || '''max=+FLT_MAX''' || || maximum header value<br />
|-<br />
| ''float '' || '''min=-FLT_MAX''' || || minimum header value<br />
|}<br />
<br />
<br />
<tt>sfmask</tt> creates an integer output of ones and zeros comparing<br />
the values of the input data to specified <tt>min=</tt> and<br />
<tt>max=</tt> parameters. It is useful for <tt>sfheaderwindow</tt> and<br />
in many other applications. Here is a quick example:<br />
<pre><br />
bash$ sfmath n1=10 output="sin(x1)" > sin.rsf<br />
bash$ < sin.rsf sfdisfil<br />
0: 0 0.8415 0.9093 0.1411 -0.7568<br />
5: -0.9589 -0.2794 0.657 0.9894 0.4121<br />
bash$ < sin.rsf sfmask min=-0.5 max=0.5 | sfdisfil<br />
0: 1 0 0 1 0 0 1 0 0 1<br />
</pre><br />
<br />
==sfmath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations on data files.<br />
|-<br />
! colspan="4" | sfmath > out.rsf type= unit= output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs, conj (for complex data).<br> <br>sfmath will work on float or complex data, but all the input and output<br>files must be of the same data type.<br><br>An alternative to sfmath is sfadd, which may be more efficient, but is<br>less versatile.<br><br>Examples:<br><br>sfmath x=file1.rsf y=file2.rsf power=file3.rsf output='sin((x+2*y)^power)' > out.rsf<br>sfmath < file1.rsf tau=file2.rsf output='exp(tau*input)' > out.rsf<br>sfmath n1=100 type=complex output="exp(I*x1)" > out.rsf<br><br>See also: sfheadermath.<br />
|-<br />
| ''string '' || '''output=''' || || Mathematical description of the output<br />
|-<br />
| ''string '' || '''type=''' || || output data type [float,complex]<br />
|-<br />
| ''string '' || '''unit=''' || || <br />
|}<br />
<br />
<tt>sfmath</tt> is a versatile program for mathematical operations<br />
with RSF files. It can operate with several input file, all of the<br />
same dimensions and data type. The data type can be real (floating<br />
point) or complex. Here is an example that demonstrates several<br />
features of <tt>sfmath</tt>.<br />
<pre><br />
bash$ sfmath n1=629 d1=0.01 o1=0 n2=40 d2=1 o2=5 \<br />
output="x2*(8+sin(6*x1+x2/10))" > rad.rsf<br />
bash$ < rad.rsf sfrtoc | sfmath output="input*exp(I*x1)" > rose.rsf<br />
bash$ < rose.rsf sfgraph title=Rose screenratio=1 wantaxis=n | xtpen<br />
</pre><br />
The first line creates a 2-D dataset that consists of 40 traces 600<br />
samples each. The values of the data are computed with the formula<br />
<font color="#cd4b19">"x2*(8+sin(6*x1+x2/10))"</font>, where <tt>x1</tt> refers to the<br />
coordinate on the first axis, and <tt>x2</tt> is the coordinate of the<br />
second axis. In the second line, we convert the data from real to<br />
complex using <tt>sfrtoc</tt> and produce a complex dataset using<br />
formula <font color="#cd4b19">"input*exp(I*x1)"</font>, where <tt>input</tt> refers to the<br />
input file. Finally, we plot the complex data as a collection of<br />
parametric curves using <tt>sfgraph</tt> and display the result using<br />
<tt>xtpen</tt>. The plot appearing on your screen should look similar<br />
to the figure.<br />
[[Image:rose.png|frame|center|This figure was created with <tt>sfmath</tt>.]]<br />
One possible alternative to the second line above is<br />
<pre><br />
bash$ < rad.rsf sfmath output=x1 > ang.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*cos(a)" > cos.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*sin(a)" > sin.rsf<br />
bash$ sfcmplx cos.rsf sin.rsf > rose.rsf<br />
</pre><br />
Here we refer to input files by names (<tt>r</tt> and <tt>a</tt>) and combine the names in a formula.<br />
<br />
==sfpad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Pad a dataset with zeros.<br />
|-<br />
! colspan="4" | sfpad < in.rsf > out.rsf [beg1= beg2= ... end1= end2=... | n1= n2 = ... | n1out= n2out= ...]<br />
|-<br />
| colspan="4" | begN specifies the number of zeros to add before the beginning of axis N.<br>endN specifies the number of zeros to add after the end of axis N.<br><br>Alternatively:<br><br>nN or nNout specify the output length of axis N, padding occurs at the end.<br>nN and nNout are equivalent.<br />
|}<br />
<br />
<br />
<tt>pad</tt> increases the dimensions of the input dataset by padding<br />
the data with zeroes. Here are some simple examples.<br />
<pre><br />
bash$ sfspike n1=5 n2=3 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
bash$ < one.rsf sfpad n2=5 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 0 0 0 0 0<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfpad beg2=2 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 0 0 0 0<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < one.rsf sfpad beg2=1 end2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfwindow n1=3 | sfpad n1=5 n2=5 beg1=1 beg2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 1 1 1 0<br />
10: 0 1 1 1 0<br />
15: 0 1 1 1 0<br />
20: 0 0 0 0 0<br />
</pre><br />
You can use <tt>sfcat</tt> to pad data with values other than zeroes.<br />
<br />
==sfput==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Input parameters into a header. <br />
|-<br />
! colspan="4" | sfput < in.rsf > out.rsf<br />
|}<br />
<br />
<br />
<tt>sfput</tt> is a very simple program. It simply appends parameters<br />
from the command line to the output RSF file. One can achieve similar<br />
results with editing by hand or with standard Unix utilities like<br />
<tt>sed</tt> and <tt>echo</tt>. <tt>sfput</tt> is sometimes more<br />
convenient because it handles input/output operations similarly to<br />
other regular RSF programs.<br />
<pre><br />
bash$ sfspike n1=10 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
10 elements 40 bytes<br />
bash$ sfput < spike.rsf d1=25 label1=Depth unit1=m > spike2.rsf<br />
bash$ sfin spike2.rsf<br />
spike2.rsf:<br />
in="/tmp/spike2.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=25 o1=0 label1="Depth" unit1="m"<br />
10 elements 40 bytes<br />
</pre><br />
<br />
==sfreal==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extract real (sfreal) or imaginary (sfimag) part of a complex dataset. <br />
|-<br />
! colspan="4" | sfreal < cmplx.rsf > real.rsf<br />
|}<br />
<br />
<br />
<tt>sfreal</tt> extracts the real part of a complex type dataset. The<br />
imaginary part can be extracted with <tt>sfimag</tt>, an the real<br />
and imaginary part can be combined together with <tt>sfcmplx</tt>.<br />
Here is a simple example. Let us first create a complex dataset <br />
with <tt>sfmath</tt><br />
<pre><br />
bash$ sfmath n1=10 type=complex output="(2+I)*x1" > cmplx.rsf<br />
bash$ fdisfil < cmplx.rsf<br />
0: 0, 0i 2, 1i 4, 2i<br />
3: 6, 3i 8, 4i 10, 5i<br />
6: 12, 6i 14, 7i 16, 8i<br />
9: 18, 9i<br />
</pre><br />
Extracting the real part with <tt>sfreal</tt>:<br />
<pre><br />
bash$ sfreal < cmplx.rsf | sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
</pre><br />
Extracting the imaginary part with <tt>sfimag</tt>:<br />
<pre><br />
bash$ sfimag < cmplx.rsf | sfdisfil<br />
0: 0 1 2 3 4<br />
5: 5 6 7 8 9<br />
</pre><br />
<br />
==sfreverse==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Reverse one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfreverse < in.rsf > out.rsf which=-1 verb=false memsize=sf_memsize() opt=<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''opt=''' || || If y, change o and d parameters on the reversed axis;<br />
:if i, don't change o and d<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|-<br />
| ''int '' || '''which=-1''' || || Which axis to reverse.<br />
:To reverse a given axis, start with 0,<br />
:add 1 to number to reverse n1 dimension,<br />
:add 2 to number to reverse n2 dimension,<br />
:add 4 to number to reverse n3 dimension, etc.<br />
:Thus, which=7 would reverse the first three dimensions,<br />
:which=5 just n1 and n3, etc.<br />
:which=0 will just pass the input on through unchanged.<br />
|}<br />
Here is an example of using <tt>sfreverse</tt>. First, let us create a<br />
2-D dataset.<br />
<pre><br />
bash$ sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Reversing the first axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 | sfdisfil<br />
0: 4 3 2 1 0<br />
5: 5 4 3 2 1<br />
10: 6 5 4 3 2<br />
</pre><br />
Reversing the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=2 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
Reversing both the first and the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=3 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
As you can see, the <tt>which=</tt> parameter controls the axes that are<br />
being reversed by encoding them into one number.<br />
When an axis is reversed, what happens with its axis origin and<br />
sampling parameters? This behavior is controlled by <tt>opt=</tt>. In<br />
our example,<br />
<pre><br />
bash$ < test.rsf sfget n1 o1 d1<br />
n1=5<br />
o1=0<br />
d1=1<br />
bash$ < test.rsf sfreverse which=1 | sfget o1 d1<br />
o1=4<br />
d1=-1<br />
</pre><br />
The default behavior (equivalent to <tt>opt=y</tt>) puts the origin<br />
<tt>o1</tt> at the end of the axis and reverses the sampling parameter<br />
<tt>d1</tt>. Using <tt>opt=n</tt> preserves the sampling but reverses<br />
the origin.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=n | sfget o1 d1<br />
o1=-4<br />
d1=1<br />
</pre><br />
Using <tt>opt=i</tt> preserves both the sampling and the origin while<br />
reversing the axis.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=i | sfget o1 d1<br />
o1=0<br />
d1=1<br />
</pre><br />
One of the three possible behaviors may be desirable depending on the<br />
application.<br />
<br />
==sfrm==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Remove RSF files together with their data.<br />
|-<br />
! colspan="4" | sfrm file1.rsf [file2.rsf ...] [-i] [-v] [-f] <br />
|-<br />
| colspan="4" | Mimics the standard Unix rm command.<br><br>See also: sfmv, sfcp.<br />
|}<br />
<br />
<tt>sfrm</tt> is a program for removing RSF files. Its arguments mimic<br />
the arguments of the standard Unix <tt>rm</tt> utility: <tt>-v</tt><br />
for verbosity, <tt>-i</tt> for interactive inquiry, <tt>-f</tt> for<br />
force removal of suspicious files. Unlike the Unix <tt>rm</tt>,<br />
<tt>sfrm</tt> removes both the RSF header files and the binary files<br />
that the headers point to. <br />
Example:<br />
<pre><br />
bash&#36; sfspike n1=10 > spike.rsf datapath=./<br />
bash&#36; sfget in < spike.rsf<br />
in=./spike.rsf@<br />
bash&#36; ls spike*<br />
spike.rsf spike.rsf@<br />
bash&#36; sfrm -v spike.rsf<br />
sfrm: sf_rm: Removing header spike.rsf<br />
sfrm: sf_rm: Removing data ./spike.rsf@<br />
bash&#36; ls spike*<br />
ls: No match.<br />
</pre><br />
==sfrotate==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Rotate a portion of one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfrotate < in.rsf > out.rsf verb=n memsize=sf_memsize() rot#=(0,0,...)<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''rot#=(0,0,...)''' || || length of #-th axis that is moved to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<tt>sfrotate</tt> modifies the input dataset by splitting it into<br />
parts and putting the parts back in a different order. Here is a quick example.<br />
<pre><br />
bash&#36; sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Rotating the first axis by putting the last two columns in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=2 | sfdisfil<br />
0: 3 4 0 1 2<br />
5: 4 5 1 2 3<br />
10: 5 6 2 3 4<br />
</pre><br />
Rotating the second axis by putting the last row in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot2=1 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 0 1 2 3 4<br />
10: 1 2 3 4 5<br />
</pre><br />
Rotating both the first and the second axis:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=3 rot2=1 | sfdisfil<br />
0: 4 5 6 2 3<br />
5: 2 3 4 0 1<br />
10: 3 4 5 1 2<br />
</pre><br />
The transformation is shown schematically in Figure~(fig:rotate).<br />
[[Image:rotate.png|frame|center|Schematic transformation of data with <tt>sfrotate</tt>.]]<br />
<br />
==sfrtoc==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert real data to complex (by adding zero imaginary part).<br />
|-<br />
! colspan="4" | sfrtoc < real.rsf > cmplx.rsf<br />
|-<br />
| colspan="4" | <br>See also: sfcmplx<br />
|}<br />
The input to <tt>sfrtoc</tt> can be any <tt>type=float</tt> dataset:<br />
<pre><br />
bash$ sfspike n1=10 n2=20 n3=30 >real.rsf<br />
bash$ sfin real.rsf<br />
real.rsf:<br />
in="/var/tmp/real.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
</pre><br />
The output dataset will have <tt>type=complex</tt>, and its binary will be twice the size of the input:<br />
<pre><br />
bash$ <real.rsf sfrtoc >complex.rsf<br />
bash$ sfin complex.rsf <br />
complex.rsf:<br />
in="/var/tmp/complex.rsf@"<br />
esize=8 type=complex form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 48000 bytes<br />
</pre><br />
<br />
==sfscale==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Scale data.<br />
|-<br />
! colspan="4" | sfscale < in.rsf > out.rsf axis=0 rscale=0. dscale=1.<br />
|-<br />
| colspan="4" | <br>To scale by a constant factor, you can also use sfmath or sfheadermath.<br />
|-<br />
| ''int '' || '''axis=0''' || || Scale by maximum in the dimensions up to this axis.<br />
|-<br />
| ''float '' || '''dscale=1.''' || || Scale by this factor (works if rscale=0)<br />
|-<br />
| ''float '' || '''rscale=0.''' || || Scale by this factor.<br />
|}<br />
<tt>sfscale</tt> scales the input dataset by a factor. Here<br />
are some simple examples. First, let us create a test dataset.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil <br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Scale every data point by 2:<br />
<pre><br />
bash&#36; < test.rsf sfscale dscale=2 | sfdisfil<br />
0: 2 4 6 8 10<br />
5: 4 8 12 16 20<br />
10: 6 12 18 24 30<br />
</pre><br />
Divide every trace by its maximum value:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=1 | sfdisfil<br />
0: 0.2 0.4 0.6 0.8 1<br />
5: 0.2 0.4 0.6 0.8 1<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
Divide by the maximum value in the whole 2-D dataset:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=2 | sfdisfil<br />
0: 0.06667 0.1333 0.2 0.2667 0.3333<br />
5: 0.1333 0.2667 0.4 0.5333 0.6667<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
The <tt>rscale=</tt> parameter is synonymous to <tt>dscale=</tt> except<br />
when it is equal to zero. With <tt>sfscale dscale=0</tt>, the dataset gets<br />
multiplied by zero. If using <tt>rscale=0</tt>, the other parameters are<br />
used to define scaling. Thus, <tt>sfscale rscale=0 axis=1</tt> is<br />
equivalent to <tt>sfscale axis=1</tt>, and <tt>sfscale rscale=0</tt><br />
is equivalent to <tt>sfscale dscale=1</tt>.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
==sfspike==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate simple data: spikes, boxes, planes, constants.<br />
|-<br />
! colspan="4" | sfspike > spike.rsf mag= nsp=1 k#=[0,...] l#=[k1,k2,...] p#=[0,...] n#= o#=(0,...) d#=(0.004,0.1,0.1,...) label#=(Time,Distance,Distance,...) unit#=[s,km,km,...] title=<br />
|-<br />
| ''float '' || '''d#=(0.004,0.1,0.1,...)''' || || sampling on #-th axis<br />
|-<br />
| ''ints '' || '''k#=[0,...]''' || || spike starting position [nsp]<br />
|-<br />
| ''ints '' || '''l#=[k1,k2,...]''' || || spike ending position [nsp]<br />
|-<br />
| ''string '' || '''label#=(Time,Distance,Distance,...)''' || || label on #-th axis<br />
|-<br />
| ''floats '' || '''mag=''' || || spike magnitudes [nsp]<br />
|-<br />
| ''int '' || '''n#=''' || || dimension of #-th axis<br />
|-<br />
| ''int '' || '''nsp=1''' || || Number of spikes<br />
|-<br />
| ''float '' || '''o#=(0,...)''' || || origin on #-th axis<br />
|-<br />
| ''floats '' || '''p#=[0,...]''' || || spike inclination (in samples) [nsp]<br />
|-<br />
| ''string '' || '''title=''' || || title for plots<br />
|-<br />
| ''string '' || '''unit#=[s,km,km,...]''' || || unit on #-th axis<br />
|}<br />
This is the program for creating a RSF hypercube out of nothing. Calling <tt>sfspike</tt> without specifying the k# or l# parameters will result in a volume filled with values specified by <tt>mag</tt>. To get a file full of 1's, just give <tt>sfspike</tt> the axis values that running <tt>sfin</tt> on your desired output would produce. I.e. if you run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" > out.rsf<br />
</pre><br />
you will obtain the following file:<br />
<pre><br />
bash$ sfin out.rsf<br />
out.rsf:<br />
in="/var/tmp/out.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
300 elements 1200 bytes<br />
</pre><br />
To create a "flat reflector" in the file above, run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5> out2.rsf<br />
</pre><br />
Notice that the values for <tt>k</tt> and <tt>l</tt> are in samples, not in the physical units of the respective axes. The result can be visualised with <br />
<pre><br />
< out2.rsf sfgrey pclip=100 wantscalebar=y title="Illustration of k,l parameters" | xtpen<br />
</pre><br />
which produces the following plot:<br />
<br />
[[Image:sfspike_fig1.png]]<br />
<br />
The <tt>p</tt> parameters can be used to create slanted lines/planes. Specifying <tt>p2=1</tt> means that for each lateral step, the spike will be shifted down with 1 sample. Below is the command and the corresponding graphical output it creates:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=1 |\<br />
sfgrey pclip=100 wantscalebar=y title="Effect of p2=1" | xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig2.png]]<br />
<br />
Sfspike also supports negative and non-integer p values:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=-0.15 |\<br />
sfgrey pclip=100 wantscalebar=y allpos=y color=h title="Effect of p2=-0.15" |xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig3.png]]<br />
<br />
When <tt>nsp</tt> is greater than the number of values for <tt>k</tt> and <tt>l</tt> parameters, the extra spikes will be piled on top of the last one, increasing its amplitude. Look at the amplitude of the last event in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=3 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
and in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=5 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
(pictures coming soon). This feature can easily cause a bug when the number of events is large and they have not been properly counted, or when a new spike was added on a list but <tt>nsp</tt> was not updated.<br />
<br />
==sfspray==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extend a dataset by duplicating in the specified axis dimension.<br />
|-<br />
! colspan="4" | sfspray < in.rsf > out.rsf axis=2 n= d= o= label= unit=<br />
|-<br />
| colspan="4" | This operation is adjoint to sfstack.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to spray<br />
|-<br />
| ''float '' || '''d=''' || || Sampling of the newly created dimension<br />
|-<br />
| ''string '' || '''label=''' || || Label of the newly created dimension<br />
|-<br />
| ''int '' || '''n=''' || || Size of the newly created dimension<br />
|-<br />
| ''float '' || '''o=''' || || Origin of the newly created dimension<br />
|-<br />
| ''string '' || '''unit=''' || || Units of the newly created dimension<br />
|}<br />
<br />
<tt>sfspray</tt> extends the input hypercube by replicating the data<br />
in one of the dimensions. The output dataset acquires one additional<br />
dimension. Here is an example:<br />
Start with a 2-D dataset<br />
<pre><br />
bash&#36; sfmath n1=5 n2=2 output=x1+x2 > test.rsf<br />
bash&#36; sfin test.rsf<br />
test.rsf:<br />
in="/var/tmp/test.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
10 elements 40 bytes<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
</pre><br />
Extend the data in the second dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=2 n=3 > test2.rsf<br />
bash&#36; sfin test2.rsf<br />
test2.rsf:<br />
in="/var/tmp/test2.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=3 d2=1 o2=0 <br />
n3=2 d3=1 o3=0 <br />
30 elements 120 bytes<br />
bash&#36; < test2.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 0 1 2 3 4<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
20: 1 2 3 4 5<br />
25: 1 2 3 4 5<br />
</pre><br />
The output is three-dimensional, with traces from the original<br />
data duplicated along the second axis.<br />
Extend the data in the third dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=3 n=2 > test3.rsf<br />
bash&#36; sfin test3.rsf<br />
test3.rsf:<br />
in="/var/tmp/test3.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
n3=2 d3=? o3=? <br />
20 elements 80 bytes<br />
bash&#36; < test3.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
</pre><br />
The output is also three-dimensional, with the original data replicated<br />
along the third axis.<br />
<br />
==sfstack==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stack a dataset over one of the dimensions.<br />
|-<br />
! colspan="4" | sfstack < in.rsf > out.rsf axis=2 rms=n norm=y min=n max=n<br />
|-<br />
| colspan="4" | <br>This operation is adjoint to sfspray.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to stack<br />
|-<br />
| ''bool '' || '''max=n''' || [y/n] || If y, find maximum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''min=n''' || [y/n] || If y, find minimum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || If y, normalize by fold.<br />
|-<br />
| ''bool '' || '''rms=n''' || [y/n] || If y, compute the root-mean-square instead of stack.<br />
|}<br />
While <tt>sfspray</tt> adds a dimension to a hypercube,<br />
<tt>sfstack</tt> effectively removes one of the dimensions by stacking<br />
over it. Here are some examples:<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
bash&#36; < test.rsf sfstack axis=2 | sfdisfil<br />
0: 1.5 2 3 4 5<br />
bash&#36; < test.rsf sfstack axis=1 | sfdisfil<br />
0: 2.5 3 4<br />
</pre><br />
Why is the first value not 1 (in the first case) or 2 (in the second<br />
case)? By default, <tt>sfstack</tt> normalizes the stack by the fold<br />
(the number of non-zero entries). To avoid normalization, use<br />
<tt>norm=n</tt>, as follows:<br />
<pre><br />
bash&#36; < test.rsf sfstack norm=n | sfdisfil <br />
0: 3 6 9 12 15<br />
</pre><br />
<tt>sfstack</tt> can also compute root-mean-square values as <br />
well as minimum and maximum values.<br />
<pre><br />
bash&#36; < test.rsf sfstack rms=y | sfdisfil<br />
0: 1.581 2.16 3.109 4.082 5.066<br />
bash&#36; < test.rsf sfstack min=y | sfdisfil<br />
0: 0 1 2 3 4<br />
bash&#36; < test.rsf sfstack axis=1 max=y | sfdisfil <br />
0: 4 5 6<br />
</pre><br />
<br />
==sftransp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Transpose two axes in a dataset. <br />
|-<br />
! colspan="4" | sftransp < in.rsf > out.rsf memsize=sf_memsize() plane=<br />
|-<br />
| colspan="4" | <br>If you get a "Cannot allocate memory" error, give the program a<br>memsize=1 command-line parameter to force out-of-core operation.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''plane=''' || || Two-digit number with axes to transpose. The default is 12<br />
|}<br />
<br />
The <tt>sftransp</tt> program transposes the input hypercube<br />
exchanging the two axes specified by the <b>plane=</b> parameter. <br />
<pre><br />
bash&#36; sfspike n1=10 n2=20 n3=30 > orig123.rsf<br />
bash&#36; sfin orig123.rsf <br />
orig123.rsf:<br />
in="/var/tmp/orig123.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=23 >out132.rsf<br />
bash&#36; sfin out132.rsf <br />
out132.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=20 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=13 >out321.rsf<br />
bash&#36; sfin out321.rsf <br />
out321.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=30 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=10 d3=0.004 o3=0 label3="Time" unit3="s" <br />
6000 elements 24000 bytes<br />
</pre><br />
<tt>sftransp</tt> tries to fit the dataset in memory to transpose it<br />
there but, if not enough memory is available, it performs a slower<br />
transpose out of core using disk operations. You can control the<br />
amount of available memory using the <b>memsize=</b> parameter or<br />
the <b>RSFMEMSIZE</b> environmental variable.<br />
<br />
==sfwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a portion of the dataset. <br />
|-<br />
! colspan="4" | sfwindow < in.rsf > out.rsf verb=n squeeze=y j#=(1,...) d#=(d1,d2,...) f#=(0,...) min#=(o1,o2,,...) n#=(0,...) max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)<br />
|-<br />
| ''float '' || '''d#=(d1,d2,...)''' || || sampling in #-th dimension<br />
|-<br />
| ''int '' || '''f#=(0,...)''' || || window start in #-th dimension<br />
|-<br />
| ''int '' || '''j#=(1,...)''' || || jump in #-th dimension<br />
|-<br />
| ''float '' || '''max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)''' || || maximum in #-th dimension<br />
|-<br />
| ''float '' || '''min#=(o1,o2,,...)''' || || minimum in #-th dimension<br />
|-<br />
| ''int '' || '''n#=(0,...)''' || || window size in #-th dimension<br />
|-<br />
| ''bool '' || '''squeeze=y''' || [y/n] || if y, squeeze dimensions equal to 1 to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
<b>sfwindow</b> is used to window a portion of the dataset. Here is<br />
a quick example: Start by creating some data.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Now window the first two rows:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n2=2 | sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
</pre><br />
Window the first three columns:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n1=3 | sfdisfil<br />
0: 1 2 3 2 4<br />
5: 6 3 6 9<br />
</pre><br />
Window the middle row:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f2=1 n2=1 | sfdisfil<br />
0: 2 4 6 8 10<br />
</pre><br />
You can interpret the <b>f#</b> and <b>n#</b> parameters as<br />
meaning "skip that many rows/columns" and "select that many<br />
rows/columns" correspondingly. Window the middle point in the dataset:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f1=2 n1=1 f2=1 n2=1 | sfdisfil<br />
0: 6<br />
</pre><br />
Window every other column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=2 | sfdisfil<br />
0: 1 3 5 2 6<br />
5: 10 3 9 15<br />
</pre><br />
Window every third column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=3 | sfdisfil<br />
0: 1 4 2 8 3<br />
5: 12<br />
</pre><br />
Alternatively, <b>sfwindow</b> can use the minimum and maximum<br />
parameters to select a window. In the following example, we are<br />
creating a dataset with <b>sfspike</b> and then windowing a portion of it<br />
between 1 and 2 seconds in time and sampled at 8 miliseconds.<br />
<pre><br />
bash&#36; sfspike n1=1000 n2=10 > spike.rsf <br />
bash&#36; sfin spike.rsf<br />
spike.rsf:<br />
in="/var/tmp/spike.rsf@"<br />
esize=4 type=float form=native <br />
n1=1000 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10000 elements 40000 bytes<br />
bash&#36; < spike.rsf sfwindow min1=1 max1=2 d1=0.008 > window.rsf<br />
bash&#36; sfin window.rsf<br />
window.rsf:<br />
in="/var/tmp/window.rsf@"<br />
esize=4 type=float form=native <br />
n1=126 d1=0.008 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
1260 elements 5040 bytes<br />
</pre><br />
By default, <b>sfwindow</b> "squeezes" the hypercube dimensions<br />
that are equal to one toward the end of the dataset. Here is an<br />
example of taking a time slice:<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=1 d2=0.004 o2=1 label2="Time" unit2="s" <br />
10 elements 40 bytes<br />
</pre><br />
You can change this behavior by specifying <b>squeeze=n</b>.<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 squeeze=n > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=1 d1=0.004 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10 elements 40 bytes<br />
</pre><br />
<br />
=Seismic programs=<br />
Programs in this category are specific for operations on seismic data. The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/seismic/ system/seismic] in the Madagascar distribution.<br />
<br />
==sfheaderattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Integer header attributes. <br />
|-<br />
! colspan="4" | sfheaderattr < head.rsf<br />
|-<br />
| colspan="4" | <br>Only nonzero values are reported.<br />
|}<br />
<br />
The <tt>sfheaderattr</tt> examines the contents of a trace header file,<br />
typically generated by <tt>sfsegyread</tt>. In the example below, we examine<br />
trace headers in the output of <tt>suplane</tt>, a program from Seismic Unix.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
bash$ sfheaderattr < tfile.rsf<br />
*******************************************<br />
71 headers, 32 traces<br />
key[0]="tracl" min[0]=1 max[31]=32 mean=16.5<br />
key[1]="tracr" min[0]=1 max[31]=32 mean=16.5<br />
key[11]="offset" min[0]=400 max[31]=400 mean=400<br />
key[38]="ns" min[0]=64 max[31]=64 mean=64<br />
key[39]="dt" min[0]=4000 max[31]=4000 mean=4000<br />
*******************************************<br />
</pre><br />
For different standard keywords, a minimum, maximum, and mean values<br />
are reported unless they are identically zero. This quick inspection<br />
can help in identifying meaningful keywords set in the data. The input<br />
data type must be <tt>int</tt>.<br />
<br />
==sfheadermath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations, possibly on header keys. <br />
|-<br />
! colspan="4" | sfheadermath < in.rsf > out.rsf memsize=sf_memsize() output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs<br><br>See also sfmath. <br><br>An addition operation can be performed by sfstack.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''output=''' || || Describes the output in a mathematical notation.<br />
|}<br />
<tt>sfheadermath</tt> is a versatile program for mathematical<br />
operations on rows of the input file. If the input file is an<br />
<tt>n1</tt> by <tt>n2</tt> matrix, the output will be a <tt>1</tt> by<br />
<tt>n2</tt> matrix that contains one row made out of mathematical<br />
operations on the other rows. <tt>sfheadermath</tt> can identify a row<br />
by number or by a standard SEGY keyword. The latter is useful for<br />
processing headers extracted from SEGY or SU files.<br />
Here is an example. First, we create an SU file with <tt>suplane</tt> and convert it to RSF using <tt>sfsegyread</tt>.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
</pre><br />
The trace header information is saved in <tt>tfile.rsf</tt>. It<br />
contains 71 headers for 32 traces in integer format.<br />
<pre><br />
bash$ sfin tfile.rsf<br />
tfile.rsf:<br />
in="/tmp/tfile.rsf@"<br />
esize=4 type=int form=native<br />
n1=71 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
2272 elements 9088 bytes<br />
</pre><br />
Next, we will convert <tt>tfile.rsf</tt> to a floating-point format<br />
and run <tt>sfheadermath</tt> to create a new header.<br />
<pre><br />
bash$ < tfile.rsf sfdd type=float | \<br />
sfheadermath myheader=1 output="sqrt(myheader+(2+10*offset^2))" > new.rsf<br />
bash$ sfin new.rsf<br />
new.rsf:<br />
in="/tmp/new.rsf@"<br />
esize=4 type=float form=native<br />
n1=1 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
32 elements 128 bytes<br />
</pre><br />
We defined "myheader" as being the row number 1 in the input (note<br />
that numbering starts with 0) and combined it with "offset", which<br />
is a standard SEGY keyword that denotes row number 11 (see the output<br />
of <tt>sfheaderattr</tt> above.) A variety of mathematical expressions<br />
can be defined in the <tt>output=</tt> string. The expression<br />
processing engine is shared with <tt>sfmath</tt>.<br />
<br />
==sfsegyheader==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Make a trace header file for segywrite.<br />
|-<br />
! colspan="4" | sfsegyheader < in.rsf > out.rsf n1= d1=<br />
|-<br />
| colspan="4" | <br> Use the output for tfile= argument in segywrite.<br />
|-<br />
| ''float '' || '''d1=''' || || trace sampling<br />
|-<br />
| ''int '' || '''n1=''' || || number of samples in a trace<br />
|}<br />
<br />
==sfsegyread==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert a SEG-Y or SU dataset to RSF.<br />
|-<br />
! colspan="4" | sfsegyread mask=msk.rsf > out.rsf tfile=hdr.rsf verb=false su=false format=sf_segyformat (bhead) ns=sf_segyns (bhead) endian= tape= read= hfile= bfile= mask= tfile=<br />
|-<br />
| colspan="4" | <br>Data headers and trace headers are separated from the data.<br><br>Defined SEG-Y trace header key names and byte offsets:<br><br>tracl: trace sequence number within line 0<br><br>tracr: trace sequence number within reel 4<br><br>fldr: field record number 8 <br><br>tracf: trace number within field record 12 <br><br>ep: energy source point number 16 <br><br>cdp: CDP ensemble number 20 <br><br>cdpt: trace number within CDP ensemble 24 <br><br>trid: trace identification code:<br>1 = seismic data<br>2 = dead<br>3 = dummy<br>4 = time break<br>5 = uphole<br>6 = sweep<br>7 = timing<br>8 = water break<br>9---, N = optional use (N = 32,767) 28 <br><br>nvs: number of vertically summed traces 30 <br><br>nhs: number of horizontally summed traces 32 <br><br>duse: data use:<br>1 = production<br>2 = test 34<br><br>offset: distance from source point to receiver<br>group (negative if opposite to direction<br>in which the line was shot) 36 <br><br>gelev: receiver group elevation from sea level<br>(above sea level is positive) 40 <br><br>selev: source elevation from sea level<br>(above sea level is positive) 44 <br><br>sdepth: source depth (positive) 48 <br><br>gdel: datum elevation at receiver group 52 <br><br>sdel: datum elevation at source 56 <br><br>swdep: water depth at source 60 <br><br>gwdep: water depth at receiver group 64 <br><br>scalel: scale factor for previous 7 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 68 <br><br>scalco: scale factor for next 4 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 70 <br><br>sx: X source coordinate 72 <br><br>sy: Y source coordinate 76 <br><br>gx: X group coordinate 80 <br><br>gy: Y group coordinate 84 <br><br>counit: coordinate units code:<br>for previoius four entries<br>1 = length (meters or feet)<br>2 = seconds of arc (in this case, the<br>X values are unsigned intitude and the Y values<br>are latitude, a positive value designates<br>the number of seconds east of Greenwich<br>or north of the equator 88 <br><br>wevel: weathering velocity 90 <br><br>swevel: subweathering velocity 92 <br><br>sut: uphole time at source 94 <br><br>gut: uphole time at receiver group 96 <br><br>sstat: source static correction 98 <br><br>gstat: group static correction 100 <br><br>tstat: total static applied 102 <br><br>laga: lag time A, time in ms between end of 240-<br>byte trace identification header and time<br>break, positive if time break occurs after<br>end of header, time break is defined as<br>the initiation pulse which maybe recorded<br>on an auxiliary trace or as otherwise<br>specified by the recording system 104 <br><br>lagb: lag time B, time in ms between the time<br>break and the initiation time of the energy source,<br>may be positive or negative 106 <br><br>delrt: delay recording time, time in ms between<br>initiation time of energy source and time<br>when recording of data samples begins<br>(for deep water work if recording does not<br>start at zero time) 108 <br><br>muts: mute time--start 110 <br><br>mute: mute time--end 112 <br><br>ns: number of samples in this trace 114 <br><br>dt: sample interval, in micro-seconds 116 <br><br>gain: gain type of field instruments code:<br>1 = fixed<br>2 = binary<br>3 = floating point<br>4 ---- N = optional use 118 <br><br>igc: instrument gain constant 120 <br><br>igi: instrument early or initial gain 122 <br><br>corr: correlated:<br>1 = no<br>2 = yes 124 <br><br>sfs: sweep frequency at start 126 <br><br>sfe: sweep frequency at end 128 <br><br>slen: sweep length in ms 130 <br><br>styp: sweep type code:<br>1 = linear<br>2 = cos-squared<br>3 = other 132 <br><br>stas: sweep trace length at start in ms 134 <br><br>stae: sweep trace length at end in ms 136 <br><br>tatyp: taper type: 1=linear, 2=cos^2, 3=other 138 <br><br>afilf: alias filter frequency if used 140 <br><br>afils: alias filter slope 142 <br><br>nofilf: notch filter frequency if used 144 <br><br>nofils: notch filter slope 146 <br><br>lcf: low cut frequency if used 148 <br><br>hcf: high cut frequncy if used 150 <br><br>lcs: low cut slope 152 <br><br>hcs: high cut slope 154 <br><br>year: year data recorded 156 <br><br>day: day of year 158 <br><br>hour: hour of day (24 hour clock) 160 <br><br>minute: minute of hour 162 <br><br>sec: second of minute 164 <br><br>timbas: time basis code:<br>1 = local<br>2 = GMT<br>3 = other 166 <br><br>trwf: trace weighting factor, defined as 1/2^N<br>volts for the least sigificant bit 168 <br><br>grnors: geophone group number of roll switch<br>position one 170 <br><br>grnofr: geophone group number of trace one within<br>original field record 172 <br><br>grnlof: geophone group number of last trace within<br>original field record 174 <br><br>gaps: gap size (total number of groups dropped) 176 <br><br>otrav: overtravel taper code:<br>1 = down (or behind)<br>2 = up (or ahead)<br />
|-<br />
| ''string '' || '''bfile=''' || || output binary data header file<br />
|-<br />
| ''bool '' || '''endian=''' || [y/n] || big/little endian flag, the default is estimated automatically<br />
|-<br />
| ''int '' || '''format=sf_segyformat (bhead)''' || [1,2,3,5] || Data format. The default is taken from binary header.<br />
:1 is IBM floating point<br />
:2 is 4-byte integer<br />
:3 is 2-byte integer<br />
:5 is IEEE floating point<br />
|-<br />
| ''string '' || '''hfile=''' || || output text data header file<br />
|-<br />
| ''string '' || '''mask=''' || || optional header mask for reading only selected traces<br />
|-<br />
| ''int '' || '''ns=sf_segyns (bhead)''' || || Number of samples. The default is taken from binary header<br />
|-<br />
| ''string '' || '''read=''' || || what to read: h - header, d - data, b - both (default)<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if input is SU, n if input is SEGY<br />
|-<br />
| ''bool '' || '''suxdr=n''' || [y/n] || y, SU has XDR support<br />
|-<br />
| ''string '' || '''tape=''' || || <br />
|-<br />
| ''string '' || '''tfile=''' || || output trace header file<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
The SEG Y format is an [http://en.wikipedia.org/wiki/Open_standard open standard] for the exchange of geophysical data. It is controlled by the non-profit [http://www.seg.org/SEGportalWEBproject/portals/SEG_Online.portal?_nfpb=true&_pageLabel=pg_gen_content&Doc_Url=prod/SEG-Publications/Pub-Yearbook/committees.htm SEG Technical Standards Committee]. There are two versions of this standard: [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev0.pdf rev0] (1975)<ref>Barry, K.M., Cavers, D.A., and Kneale, C.W. 1975. Recommended standards for digital tape formats. ''Geophysics'', '''40''', no. 02, 344–352.</ref> and [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf rev1] (2002)<ref>Norris, M.W., Faichney, A.K., ''Eds''. 2001. SEG Y rev1 Data Exchange format. Society of Exploration Geophysicists, Tulsa, OK, 45 pp.</ref>. The implementation in <tt>sfsegyread</tt> is a mixture of rev0 (i.e. no checks for Extended Textual Headers) and rev1 ([http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE floating point format] allowed for trace data samples).<br />
<br />
A SEG-Y file as understood by <tt>sfsegyread</tt> contains a "Reel Identification Header" (3200 bytes in EBCDIC followed by 400 bytes in a binary encoding), followed by a number of "Trace Blocks". Each "Trace Block" contains a 240-byte "Trace Header" (binary) followed by "Trace Data" -- a sequence of <tt>ns</tt> samples. Binary values in both reel headers and trace headers are two's complement integers, either two bytes or four bytes long. There are no floating-point values defined in the headers. Trace Data samples can have various encodings, either floating point or integer, described further down, but they are all big-endian. To convert from SEG-Y to RSF, <tt>sfsegyread</tt> will strip the tape reel EBCDIC header and convert it to ASCII, will extract the reel binary header without changing it, and will put the trace headers into one RSF file, and the traces themselves on another.<br />
<br />
===SEG-Y Trace Headers===<br />
In the SEG-Y standard, only the first 180 bytes of the 240-byte trace header are defined; bytes 181-240 are reserved for non-standard header information, and these locations are increasingly used in modern SEG-Y files and its variants. The standard provides for a total of 71 4-byte and 2-byte predefined header words. These 71 standard words have defined lengths and byte offsets, and only these words and byte locations are read using <tt>segyread</tt> and output to the RSF header file with the <tt>hfile=</tt> option. The user may remap these predefined keywords to a different byte offsets.<br />
<br />
===SU File Format===<br />
An [http://www.cwp.mines.edu/sututor/node22.html SU file] is nothing more than a SEG-Y file without the reel headers, and with the Trace Data samples in the native encoding of the CPU the file was created on (Attention -- limited portability!). So, to convert from SU to RSF, <tt>sfsegyread</tt> will just separate headers and traces into two RSF files. <br />
<br />
===SEG-Y specific parameters===<br />
*<tt>hfile=</tt> specifies the name of the file in which the EBCDIC reel header will be put after conversion to ASCII. If you are certain there is no useful information in it, <tt>hfile=/dev/null</tt> works just fine. If you do not specify anything for this parameter you will get an ASCII file named <tt>header</tt> in the current directory. If you want to quickly preview this header before running <tt>sfsegyread</tt>, use<pre>dd if=input.segy count=40 bs=80 cbs=80 conv=unblock,ascii</pre><br />
*<tt>bfile=</tt> specifies name of the file in which the binary reel header (the 400-bytes thing following the 3600-bytes EBCDIC) will be put without any conversion. The default name is "binary". Unless you have software that knows how to read exactly this special type of file, it will be completely useless, so do <tt>bfile=/dev/null</tt><br />
*<tt>format=</tt> specifies the format in which the trace data samples are in the SEG-Y input file. This is read from the binary reel header of the SEG-Y file. Valid values are 1(IBM floating point), 2 (4-byte integer), 3 (2-byte integer) and 5 (IEEE floating point). If the input file is SU, the format will be assumed to be the native <tt>float</tt> format.<br />
<br />
*<tt>keyname=</tt> specifies the byte offset to remap a header using the trace header key names shown above. For example, if the CDP locations have been placed in bytes 181-184 instead of the standard 21-24, <tt>cdp=180</tt> will remap the trace header to that location. <br />
<br />
===SU-specific parameters===<br />
*<tt>suxdr=</tt> specifies whether the input file was created with a SU package with XDR support enabled. If you have access to the source code of your SU install (try <tt>$CWPROOT/src</tt>), type: <tt>grep 'XDRFLAG =' $CWPROOT/src/Makefile.config</tt> and look at the last uncommented entry. If no value is given for <tt>XDRFLAG</tt>, the package was not compiled with XDR support.<br />
===Common parameters===<br />
*<tt>su=</tt> specifies if the input file is SU or SEG-Y. Default is <tt>su=n</tt> (SEG-Y file).<br />
*<tt>tape=</tt> specifies the input data. Stdin could not be used because <tt>sfsegyread</tt> has to work with tapes, and needs to fseek back and forth through the input file. Thankfully, output is on stdout.<br />
*<tt>read=</tt> specifies what parts of the "Trace Blocks" will be read. It can be <tt>read=t</tt> (only trace data is read), <tt>read=h</tt> (only trace headers are read) or <tt>read=b</tt> (both are read).<br />
*<tt>tfile=</tt> gives the name of the RSF file to which trace headers are written. Obviously, it should be only specified with <tt>read=h</tt> or <tt>read=b</tt>.<br />
*<tt>mask=</tt> is an optional parameter specifying the name of a mask that says which traces will be read. The mask is a 1-D RSF file with integers. The number of samples in the mask is the same as the number of traces in the unmasked SEG-Y. In places corresponding to unwanted traces there should be zeros in the mask.<br />
*<tt>ns=</tt> specifies the number of samples in a trace. For SEG-Y files, the default is taken from the binary reel header, and for SU files, from the header of the first trace. This parameter is however critical enough that a command line override was given for it.<br />
*<tt>verbose=</tt> is the verbosity flag. Can be <tt>y</tt> or <tt>n</tt>.<br />
*<tt>endian=</tt> is a y/n flag (default y), specifying whether to automatically estimate or not if samples in the Trace Data blocks are big-endian or little-endian. Try it if you are in trouble and do not know what else to do, otherwise let the automatic estimation do its job.<br />
<br />
==sfsegywrite==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert an RSF dataset to SEGY or SU.<br />
|-<br />
! colspan="4" | sfsegywrite < in.rsf tfile=hdr.rsf verb=false su=false endian=sf_endian() tape= hfile= bfile=<br />
|-<br />
| colspan="4" | <br>Merges trace headers with data.<br />
|-<br />
| ''string '' || '''bfile=''' || || input binary data header file<br />
|-<br />
| ''bool '' || '''endian=sf_endian()''' || [y/n] || big/little endian flag. The default is estimated automatically<br />
|-<br />
| ''string '' || '''hfile=''' || || input text data header file<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if output is SU, n if output is SEGY<br />
|-<br />
| ''string '' || '''tape=''' || ||<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
Please see <tt>sfsegyread</tt> for a complete description of parameter meanings and background issues. Parameters <tt>bfile</tt> and <tt>hfile</tt> should only be given values when the desired file is SEG-Y (default). The output file is specified by the <tt>tape=</tt> tag.<br />
<br />
=Plotting programs=<br />
The source files for these programs can be found under<br />
[http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/plot/main/ plot/main]<br />
in the Madagascar distribution.<br />
<br />
THIS SECTION IS UNDER CONSTRUCTION<br />
<br />
==sfbox==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Draw a balloon-style label.<br />
|-<br />
! colspan="4" | sfbox lab_color=VP_WHITE lab_fat=0 pscale=1. pointer=y reverse=n lat=0. long=90. angle=0. x0=0. y0=0. scale0=1. xt=2. yt=0. x_oval=0. y_oval=0. boxit=y length= scalet= size=.25 label= > out.vpl<br />
|-<br />
| ''float '' || '''angle=0.''' || || longitude of floating label in 3-D<br />
|-<br />
| ''bool '' || '''boxit=y''' || [y/n] || if y, create a box around text<br />
|-<br />
| ''int '' || '''lab_color=VP_WHITE''' || || label color<br />
|-<br />
| ''int '' || '''lab_fat=0''' || || label fatness<br />
|-<br />
| ''string '' || '''label=''' || || text for label<br />
|-<br />
| ''float '' || '''lat=0.''' || || <br />
|-<br />
| ''float '' || '''length=''' || || normalization for xt and yt<br />
|-<br />
| ''float '' || '''long=90.''' || || latitude and longitude of viewpoint in 3-D<br />
|-<br />
| ''bool '' || '''pointer=y''' || [y/n] || if y, create arrow pointer<br />
|-<br />
| ''float '' || '''pscale=1.''' || || scale factor for width of pointer<br />
|-<br />
| ''bool '' || '''reverse=n''' || [y/n] || <br />
|-<br />
| ''float '' || '''scale0=1.''' || || scale factor for x0 and y0<br />
|-<br />
| ''float '' || '''scalet=''' || || <br />
|-<br />
| ''float '' || '''size=.25''' || || text height in inches<br />
|-<br />
| ''float '' || '''x0=0.''' || || <br />
|-<br />
| ''float '' || '''x_oval=0.''' || || <br />
|-<br />
| ''float '' || '''xt=2.''' || || <br />
|-<br />
| ''float '' || '''y0=0.''' || || position of the pointer tip<br />
|-<br />
| ''float '' || '''y_oval=0.''' || || size of the oval around pointer<br />
|-<br />
| ''float '' || '''yt=0.''' || || relative position of text<br />
|}<br />
==sfcontour==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Contour plot.<br />
|-<br />
! colspan="4" | sfcontour < in.rsf c= min1=o1 min2=o2 max1=o1+(n1-1)*d1 max2=o2+(n2-1)*d2 nc=50 dc= c0= transp=y minval= maxval= allpos=y barlabel= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=y''' || [y/n] || contour positive values only<br />
|-<br />
| ''string '' || '''barlabel=''' || || <br />
|-<br />
| ''floats '' || '''c=''' || || [nc]<br />
|-<br />
| ''float '' || '''c0=''' || || first contour<br />
|-<br />
| ''float '' || '''dc=''' || || contour increment<br />
|-<br />
| ''float '' || '''max1=o1+(n1-1)*d1''' || || <br />
|-<br />
| ''float '' || '''max2=o2+(n2-1)*d2''' || || data window to plot<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''min1=o1''' || || <br />
|-<br />
| ''float '' || '''min2=o2''' || || <br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nc=50''' || || number of contours<br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfdots==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot signal with lollipops.<br />
|-<br />
! colspan="4" | sfdots < in.rsf labels= dots=(n1 <= 130)? 1: 0 seemean=(bool) (n2 <= 30) strings=(bool) (n1 <= 400) connect=1 corners= silk=n gaineach=y labelsz=8 yreverse=n constsep=n seedead=n transp=n xxscale=1. yyscale=1. clip=-1. overlap=0.9 screenratio=VP_SCREEN_RATIO screenht=VP_STANDARD_HEIGHT screenwd=screenhigh / screenratio radius=dd1/3 label1= unit1= title= > plot.vpl<br />
|-<br />
| ''float '' || '''clip=-1.''' || || data clip<br />
|-<br />
| ''int '' || '''connect=1''' || || connection type: 1 - diagonal, 2 - bar, 4 - only for non-zero data<br />
|-<br />
| ''bool '' || '''constsep=n''' || [y/n] || if y, use constant trace separation<br />
|-<br />
| ''int '' || '''corners=''' || || number of polygon corners (default is 6)<br />
|-<br />
| ''int '' || '''dots=(n1 <= 130)? 1: 0''' || || type of dots: 1 - baloon, 0 - no dots, 2 - only for non-zero data<br />
|-<br />
| ''bool '' || '''gaineach=y''' || [y/n] || if y, gain each trace independently<br />
|-<br />
| ''string '' || '''label1=''' || || <br />
|-<br />
| ''strings'' || '''labels=''' || || trace labels [n2]<br />
|-<br />
| ''int '' || '''labelsz=8''' || || label size<br />
|-<br />
| ''float '' || '''overlap=0.9''' || || trace overlap<br />
|-<br />
| ''float '' || '''radius=dd1/3''' || || dot radius<br />
|-<br />
| ''float '' || '''screenht=VP_STANDARD_HEIGHT''' || || screen height<br />
|-<br />
| ''float '' || '''screenratio=VP_SCREEN_RATIO''' || || screen aspect ratio<br />
|-<br />
| ''float '' || '''screenwd=screenhigh / screenratio''' || || screen width<br />
|-<br />
| ''bool '' || '''seedead=n''' || [y/n] || if y, show zero traces<br />
|-<br />
| ''bool '' || '''seemean=(bool) (n2 <= 30)''' || [y/n] || if y, draw axis lines<br />
|-<br />
| ''bool '' || '''silk=n''' || [y/n] || if y, silky plot<br />
|-<br />
| ''bool '' || '''strings=(bool) (n1 <= 400)''' || [y/n] || if y, draw strings<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axis<br />
|-<br />
| ''string '' || '''unit1=''' || || <br />
|-<br />
| ''float '' || '''xxscale=1.''' || || x scaling<br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse y axis<br />
|-<br />
| ''float '' || '''yyscale=1.''' || || y scaling<br />
|}<br />
==sfgraph3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot for surfaces.<br />
|-<br />
! colspan="4" | sfgraph3 < in.rsf orient=1 min= max= point1=0.5 point2=0.5 frame1=0.5*(min+max) frame2=n1-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y > plot.vpl<br />
|-<br />
| ''float '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''float '' || '''frame1=0.5*(min+max)''' || || <br />
|-<br />
| ''int '' || '''frame2=n1-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''max=''' || || maximum function value<br />
|-<br />
| ''float '' || '''min=''' || || minimum function value<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''orient=1''' || || function orientation<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|}<br />
==sfgraph==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Graph plot.<br />
|-<br />
! colspan="4" | sfgraph < in.rsf symbolsz= pclip=100. transp=n symbol= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''pclip=100.''' || || clip percentile<br />
|-<br />
| ''string '' || '''symbol=''' || || if set, plot with symbols instead of lines<br />
|-<br />
| ''floats '' || '''symbolsz=''' || || symbol size (default is 2) [n2]<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfgrey3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot.<br />
|-<br />
! colspan="4" | sfgrey3 < in.rsf point1=0.5 point2=0.5 frame1=0 frame2=n2-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y scalebar=n minval= maxval= barreverse=n nreserve=8 bar= color= > plot.vpl<br />
|-<br />
| colspan="4" | Requires an "unsigned char" input (the output of sfbyte).<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''int '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''int '' || '''frame1=0''' || || <br />
|-<br />
| ''int '' || '''frame2=n2-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || if y, draw scalebar<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
for sfgrey and sfgrey3. Examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfgrey==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate raster plot.<br />
|-<br />
! colspan="4" | sfgrey < in.rsf > out.rsf bar=bar.rsf transp=y yreverse=y xreverse=n gpow= phalf= clip= pclip= gainstep=0.5+n1/256. allpos=n bias=0. polarity=n verb=n scalebar=n minval= maxval= barreverse=n wantframenum=(bool) (n3 > 1) nreserve=8 gainpanel= bar= color= > (plot.vpl | char.rsf)<br />
|-<br />
| colspan="4" | Can input char values.<br>If called "byte", outputs char values.<br><br>Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=n''' || [y/n] || if y, assume positive data<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=''' || || <br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''string '' || '''gainpanel=''' || || gain reference: 'a' for all, 'e' for each, or number<br />
|-<br />
| ''int '' || '''gainstep=0.5+n1/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=''' || || <br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''pclip=''' || || data clip percentile (default is 99)<br />
|-<br />
| ''float '' || '''phalf=''' || || percentage for estimating gpow<br />
|-<br />
| ''bool '' || '''polarity=n''' || [y/n] || if y, reverse polarity (white is high by default)<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the display axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''bool '' || '''wantframenum=(bool) (n3 > 1)''' || [y/n] || if y, display third axis position in the corner<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''bool '' || '''yreverse=y''' || [y/n] || if y, reverse the vertical axis<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
and examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfplas==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Assembler - convert ascii to vplot. <br />
|-<br />
! colspan="4" | sfplas<br />
|}<br />
==sfpldb==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Debugger - convert vplot to ascii. <br />
|-<br />
! colspan="4" | sfpldb<br />
|}<br />
==sfplotrays==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot rays.<br />
|-<br />
! colspan="4" | sfplotrays frame=frame.rsf nt=n1*n2 jr=1 frame= < rays.rsf > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''string '' || '''frame=''' || || <br />
|-<br />
| ''int '' || '''jr=1''' || || skip rays<br />
|-<br />
| ''int '' || '''nt=n1*n2''' || || maximum ray length<br />
|}<br />
==sfthplot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Hidden-line surface plot.<br />
|-<br />
! colspan="4" | sfthplot < in.rsf uflag=y dflag=y alpha=45. titlsz=9 axissz=6 plotfat=0 titlefat=2 axisfat=2 plotcolup=VP_YELLOW plotcoldn=VP_RED axis=y axis1=y axis2=y axis3=y clip=0. pclip=100. gainstep=0.5+nx/256. bias=0. dclip=1. norm=y xc=1.5 zc=3 ratio=5. zmax= zmin= sz=6. label#= unit#= tpow=0 epow=0 gpow=1 title= > plot.vpl<br />
|-<br />
| ''float '' || '''alpha=45.''' || || apparent angle in degrees, |alpha| < 89<br />
|-<br />
| ''bool '' || '''axis=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis1=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis2=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis3=y''' || [y/n] || plot axis<br />
|-<br />
| ''int '' || '''axisfat=2''' || || axes fatness<br />
|-<br />
| ''int '' || '''axissz=6''' || || axes size<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip<br />
|-<br />
| ''float '' || '''dclip=1.''' || || change the clip: clip *= dclip<br />
|-<br />
| ''bool '' || '''dflag=y''' || [y/n] || if y, plot down side of the surface<br />
|-<br />
| ''float '' || '''epow=0''' || || exponential gain<br />
|-<br />
| ''int '' || '''gainstep=0.5+nx/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=1''' || || power gain<br />
|-<br />
| ''string '' || '''label#=''' || || label on #-th axis<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || normalize by the clip<br />
|-<br />
| ''float '' || '''pclip=100.''' || || data clip percentile<br />
|-<br />
| ''int '' || '''plotcoldn=VP_RED''' || || color of the lower side<br />
|-<br />
| ''int '' || '''plotcolup=VP_YELLOW''' || || color of the upper side<br />
|-<br />
| ''int '' || '''plotfat=0''' || || line fatness<br />
|-<br />
| ''float '' || '''ratio=5.''' || || plot adjustment<br />
|-<br />
| ''float '' || '''sz=6.''' || || vertical scale<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''int '' || '''titlefat=2''' || || title fatness<br />
|-<br />
| ''int '' || '''titlsz=9''' || || title size<br />
|-<br />
| ''string '' || '''tpow=0''' || || time power gain<br />
|-<br />
| ''bool '' || '''uflag=y''' || [y/n] || if y, plot upper side of the surface<br />
|-<br />
| ''string '' || '''unit#=''' || || unit on #-th axis<br />
|-<br />
| ''float '' || '''xc=1.5''' || || <br />
|-<br />
| ''float '' || '''zc=3''' || || lower left corner of the plot<br />
|-<br />
| ''float '' || '''zmax=''' || || <br />
|-<br />
| ''float '' || '''zmin=''' || || <br />
|}<br />
==sfwiggle==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot data with wiggly traces. <br />
|-<br />
! colspan="4" | sfwiggle < in.rsf xpos=xpos.rsf xmax= xmin= poly=n fatp=1 xmask=1 ymask=1 pclip=98. zplot=0.75 clip=0. seemean=n verb=n transp=n yreverse=n xreverse=n xpos= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip (estimated from pclip by default<br />
|-<br />
| ''int '' || '''fatp=1''' || || <br />
|-<br />
| ''float '' || '''pclip=98.''' || || clip percentile<br />
|-<br />
| ''bool '' || '''poly=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''seemean=n''' || [y/n] || if y, plot mean lines of traces<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''int '' || '''xmask=1''' || || <br />
|-<br />
| ''float '' || '''xmax=''' || || maximum trace position (if using xpos)<br />
|-<br />
| ''float '' || '''xmin=''' || || minimum trace position (if using xpos)<br />
|-<br />
| ''string '' || '''xpos=''' || || optional header file with trace positions<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''int '' || '''ymask=1''' || || <br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse the vertical axis<br />
|-<br />
| ''float '' || '''zplot=0.75''' || || <br />
|}<br />
<br />
=filt/imag programs=<br />
==sfremap1==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 1-D ENO interpolation. <br />
|-<br />
! colspan="4" | sfremap1 < in.rsf > out.rsf pattern=pattern.rsf n1=n1 d1=d1 o1=o1 order=3<br />
|-<br />
| ''float '' || '''d1=d1''' || || Output sampling<br />
|-<br />
| ''int '' || '''n1=n1''' || || Number of output samples<br />
|-<br />
| ''float '' || '''o1=o1''' || || Output origin<br />
|-<br />
| ''int '' || '''order=3''' || || Interpolation order<br />
|-<br />
| ''string '' || '''pattern=''' || || auxiliary input file name<br />
|}<br />
To give an example of usage, we will create an input for <tt>sfremap1</tt> with:<br />
<pre><br />
sfmath n1=11 n2=11 d1=1 d2=1 o1=-5 o2=-5 output="x1*x1+x2*x2" > inp2remap1.rsf<br />
</pre><br />
Let us interpolate the data across both dimensions, then display it:<br />
<pre><br />
&lt; inp2remap1.rsf sfremap1 n1=1001 d1=0.01 | sftransp | \<br />
sfremap1 n1=1001 d1=0.01 | sftransp | sfgrey allpos=y | xtpen<br />
</pre><br />
The comparison with the uninterpolated data ( <tt>&lt; inp2remap1.rsf sfgrey allpos=y | xtpen</tt> ) is quite telling.<br />
<br />
=filt/proc programs=<br />
==sfstretch==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stretch of the time axis. <br />
|-<br />
! colspan="4" | sfstretch < in.rsf > out.rsf datum=dat.rsf inv=n dens=1 v0= half=y delay= tdelay= hdelay= nout=dens*n1 extend=4 mute=0 maxstr=0 rule=<br />
|-<br />
| ''file '' || '''datum=''' || || auxiliary input file name<br />
|-<br />
| ''float '' || '''delay=''' || || time delay for rule=lmo<br />
|-<br />
| ''int '' || '''dens=1''' || || axis stretching factor<br />
|-<br />
| ''int '' || '''extend=4''' || || trace extension<br />
|-<br />
| ''bool '' || '''half=y''' || [y/n] || if y, the second axis is half-offset instead of full offset<br />
|-<br />
| ''float '' || '''hdelay=''' || || offset delay for rule=rad<br />
|-<br />
| ''bool '' || '''inv=n''' || [y/n] || if y, do inverse stretching<br />
|-<br />
| ''float '' || '''maxstr=0''' || || maximum stretch<br />
|-<br />
| ''int '' || '''mute=0''' || || tapering size<br />
|-<br />
| ''int '' || '''nout=dens*n1''' || || output axis length (if inv=n)<br />
|-<br />
| ''string '' || '''rule=''' || || Stretch rule:<br />
:n - normal moveout (nmostretch), default<br />
:l - linear moveout (lmostretch)<br />
:L - logarithmic stretch (logstretch)<br />
:2 - t^2 stretch (t2stretch)<br />
:c - t^2 chebyshev stretch (t2chebstretch)<br />
:r - radial moveout (radstretch)<br />
:d - datuming (datstretch)<br />
|-<br />
| ''float '' || '''tdelay=''' || || time delay for rule=rad<br />
|-<br />
| ''float '' || '''v0=''' || || moveout velocity<br />
|}<br />
<br />
<tt>sfstretch rule=d</tt> (aka <tt>sfdatstretch</tt>) can be used to apply statics. Here is a synthetic example, courtesy of Alessandro Frigeri:<br />
<pre><br />
# generate a dataset with 'flat' signals<br />
sfmath n1=200 n2=100 output="sin(0.5*x1)" type=float > scan.rsf<br />
<br />
# generate a sinusoidal elevation correction<br />
sfmath n1=100 output="3*sin(x1)" type=float > statics.rsf<br />
<br />
# apply statics, producing a 'wavy' output.<br />
sfstretch < scan.rsf > out.rsf datum=statics.rsf rule=d<br />
</pre><br />
<br />
=user/ivlad programs=<br />
==sfprep4plot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Resamples a 2-D dataset to the desired picture resolution, with antialias<br />
|-<br />
! colspan="4" | sfprep4plot inp= out= verb=n h=none w=none unit= ppi= prar=y<br />
|-<br />
| colspan="4" | Only one of the h and w parameters needs to be specified.<br>If prar=n, no action will be taken on axis for which h/w was not specified<br>If prar=y and only one par (h or w) is specified, the picture will scale<br>along both axes until it is of the specified dimension.<br />
|-<br />
| ''int '' || '''h=none''' || || output height<br />
|-<br />
| ''string '' || '''inp=''' || || input file<br />
|-<br />
| ''string '' || '''out=''' || || output file<br />
|-<br />
| ''int '' || '''ppi=''' || || output resolution (px/in). Necessary when unit!=px<br />
|-<br />
| ''bool '' || '''prar=y''' || [y/n] || if y, PReserve Aspect Ratio of input<br />
|-<br />
| ''string '' || '''unit=''' || || unit of h and w. Can be: px(default), mm, cm, in<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || if y, print system commands, outputs<br />
|-<br />
| ''int '' || '''w=none''' || || output width<br />
|}<br />
For a figure that does not need the aspect ratio preserved,<br />
and needs to fill a 1280x1024 projector display:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=1280 h=1024 prar=n<br />
</pre><br />
For a print figure that has to fit in a 6x8in box<br />
at a resolution of 250 dpi, preserving the aspect ratio:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=6 h=8 unit=in ppi=250<br />
</pre><br />
A comparison of images before and after the application of <tt>sfprep4plot</tt>, courtesy of Joachim Mispel, is shown below:<br />
<br />
[[Image:sf_prep4plot.jpg]]<br />
<br />
=user/jennings programs=<br />
==sfsizes==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display the size of RSF files.<br />
|-<br />
! colspan="4" | sfsizes files=y human=n file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | Prints the element size, number of elements, and number of bytes<br>for a list of RSF files. Non-RSF files are ignored.<br />
|-<br />
| ''bool '' || '''files=y''' || [y/n] || If y, print size of each file. If n, print only total.<br />
|-<br />
| ''bool '' || '''human=n''' || [y/n] || If y, print human-readable file size. If n, print byte count.<br />
|}<br />
<br />
<br />
This program computes the "theoretical" size in bytes of the data fork of RSF files. The actual space occupied on disk may be different and machine dependent due to disk blocking factors, etc.<br />
<br />
This theoretical array size should be reproducible. It is also fast because the program only reads the RSF headers files, not the actual data.<br />
<br />
For example, to get the total size of all RSF files in a directory, in human readable format, without listing each file:<br />
<pre><br />
sfsizes files=n human=y *.rsf<br />
</pre><br />
This will also work because sfsizes simply skips any non-RSF file:<br />
<pre><br />
sfsizes files=n human=y *<br />
</pre><br />
<br />
=References=<br />
<references/></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=BCU_task-centric_program_list&diff=709BCU task-centric program list2009-03-12T13:59:49Z<p>Jenningsjwj: /* Basic operations */</p>
<hr />
<div>[[Image:Fotolia_11174449_XS.jpg|right|]]<br />
List of '''Basic Cube Utilities''' (BCU) in Madagascar. Operations listed here can throw away data or fill in with zeros, but should not create new values or alter existing ones -- those belong to the [[NM task-centric program program_list | Numerical Methods program list]].<br />
<br />
An overview of all task-centric pages can be found in the main [[Task-centric program list]].<br />
<br />
'''All program names below should be prefixed with "sf".'''<br />
<br />
=I/O and file format conversions=<br />
<br />
== ASCII, binary file ==<br />
* Convert the binary file of a RSF dataset between different formats (binary, ASCII): [http://reproducibility.org/RSF/sfdd.html dd]<br />
<br />
==SEG-Y file==<br />
* Convert SEG-Y files to RSF: [http://reproducibility.org/RSF/sfsegyread.html segyread]<br />
* Convert RSF to SEG-Y or SU: [http://reproducibility.org/RSF/sfsegywrite.html segywrite]<br />
* Make a trace header file for segywrite: [http://reproducibility.org/RSF/segyheader.html segyheader]<br />
<br />
==SU file==<br />
* Convert SU files to RSF: [http://reproducibility.org/RSF/sfsegyread.html suread]<br />
* Convert RSF to SU: [http://reproducibility.org/RSF/sfsegywrite.html segywrite]<br />
<br />
=File operations=<br />
This section contains physics-agnostic methods for slicing, dicing, adding together files, etc:<br />
<br />
== Basic operations ==<br />
* Display basic information about RSF files: [http://reproducibility.org/RSF/sfin.html in]<br />
* Display the size of RSF data forks: [http://reproducibility.org/RSF/sfsizes.html sizes]<br />
* Copy a dataset: [http://reproducibility.org/RSF/sfcp.html cp]<br />
* Move a dataset: [http://reproducibility.org/RSF/sfcp.html mv]<br />
* Remove RSF files together with their data: [http://reproducibility.org/RSF/sfrm.html rm]<br />
* Print out data values: [http://reproducibility.org/RSF/sfdisfil.html disfil]<br />
<br />
== Operation on file content ==<br />
<br />
* Window a portion of the dataset: [http://reproducibility.org/RSF/sfwindow.html window]<br />
* Transpose two axes in a dataset: [http://reproducibility.org/RSF/sftransp.html transp]<br />
* Concatenate datasets: [http://reproducibility.org/RSF/sfcat.html cat] or [http://reproducibility.org/RSF/sfcat.html merge]<br />
* Convert real data to complex (by adding zero imaginary part): [http://reproducibility.org/RSF/sfrtoc.html rtoc]<br />
* Extract real part of a complex dataset: [http://reproducibility.org/RSF/sfreal.html real]<br />
* Extract imaginary part of a complex dataset: [http://reproducibility.org/RSF/sfreal.html imag]<br />
* Create a complex dataset from its real and imaginary parts: [http://reproducibility.org/RSF/sfcmplx.html cmplx]<br />
* Rotate a portion of one or more axes in the data hypercube: [http://reproducibility.org/RSF/sfrotate.html rotate]<br />
* Zero a portion of the dataset: [http://reproducibility.org/RSF/sfcut.html cut]<br />
* Pad a dataset with zeros: [http://reproducibility.org/RSF/sfpad.html pad]<br />
* Combine several datasets by interleaving: [http://reproducibility.org/RSF/sfinterleave.html interleave]<br />
* Pad and interleave traces: [http://reproducibility.org/RSF/sflpad.html lpad]<br />
* Compute Ni+1 x Ni+2 x ...: [http://reproducibility.org/RSF/sfleftsize.html leftsize]<br />
* Reverse one or more axes in the data hypercube: [http://reproducibility.org/RSF/sfreverse.html reverse]<br />
<br />
==Header operations==<br />
<br />
* Input parameters into a header: [http://reproducibility.org/RSF/sfput.html put]<br />
* Output parameters from the header: [http://reproducibility.org/RSF/sfget.html get]<br />
* Display the content of a header file: [http://reproducibility.org/RSF/sfheaderattr.html headerattr]<br />
* Zero a portion of a dataset based on a header mask: [http://reproducibility.org/RSF/sfheadercut.html headercut]<br />
* Mathematical operations, possibly on header keys: [http://reproducibility.org/RSF/sfheadermath.html headermath]<br />
* Sort a dataset according to a header key: [http://reproducibility.org/RSF/sfheadersort.html headersort]<br />
* Window a dataset based on a header mask: [http://reproducibility.org/RSF/sfheaderwindow.html headerwindow]<br />
<br />
= Graph, plots, displays =<br />
<br />
== Display ==<br />
<br />
* Generate raster plot: [http://reproducibility.org/RSF/sfgrey.html grey] (sfbyte is the same)<br />
<br />
* Draw a balloon-style label: [http://reproducibility.org/RSF/sfbox.html box]<br />
<br />
* Contour plot: [http://reproducibility.org/RSF/sfcontour.html contour]<br />
<br />
* Generate 3-D contour plot: [http://reproducibility.org/RSF/sfcontour3.html contour3]<br />
<br />
* Plot signal with lollipops: [http://reproducibility.org/RSF/sfdots.html dots]<br />
<br />
* Generate 3-D cube plot for surfaces: [http://reproducibility.org/RSF/sfgraph3.html graph3]<br />
<br />
* Graph plot: [http://reproducibility.org/RSF/sfgraph.html graph]<br />
<br />
* Generate 3-D cube plot: [http://reproducibility.org/RSF/sfgrey3.html grey3] (sfcubeplot is the same)<br />
<br />
* Plot rays: [http://reproducibility.org/RSF/sfplotrays.html plotrays]<br />
<br />
* Hidden-line surface plot: [http://reproducibility.org/RSF/sfthplot.html thplot]<br />
<br />
* Plot data with wiggly traces: [http://reproducibility.org/RSF/sfwiggle.html wiggle]<br />
<br />
* Resamples a 2-D dataset to the desired picture resolution, with antialias: [http://reproducibility.org/RSF/sfprep4plot.html prep4plot]<br />
<br />
* Setting up frames for a generic plot: [http://reproducibility.org/RSF/sfstdplot.html stdplot]<br />
<br />
== Plot format ==<br />
<br />
* Plot Assembler - convert ascii to vplot: [http://reproducibility.org/RSF/sfplas.html plas]<br />
<br />
* Plot Debugger - convert vplot to ascii: [http://reproducibility.org/RSF/sfpldb.html pldb]<br />
<br />
* Vplot filter for postscript: [http://reproducibility.org/RSF/sfpspen.html pspen]<br />
<br />
* Vplot filter for the virtual vplot device: [http://reproducibility.org/RSF/sfvppen.html vppen]</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Task-centric_program_list&diff=708Task-centric program list2009-03-12T13:57:50Z<p>Jenningsjwj: </p>
<hr />
<div>The categories in the [http://reproducibility.org/RSF/ self-documentation] are programmer-side categories, based on common ways in which programs are compiled. The list below attempts to group programs so that the user can find them in the natural progression of his workflow. A program can be in several categories. Feel free to create categories and to assign programs to them!<br />
<br />
* [[BCU task-centric program list]]: Basic Cube Utilities -- I/O, manipulation, format conversions, graphics...<br />
* [[NM task-centric program program list]]: Numerical Methods -- data statistics, linear algebra, interpolation... <br />
* [[Geophysics task-centric program list]]: migration, modeling, denoising ...<br />
* [[NGAM task-centric program list]]: Non-Geophysical Applied Mathematics -- Fractals, etc...</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Adding_new_programs_to_Madagascar&diff=707Adding new programs to Madagascar2009-03-12T13:55:58Z<p>Jenningsjwj: /* The Madagascar Wiki */</p>
<hr />
<div>[[Image:Fotolia_800161_XS.jpg|right|]]<br />
Whether you want to share your work with the world or keep it for yourself, madagascar is fully extensible. The following instructions explain the simplest way to add your own programs to the package.<br />
<br />
==How to add your program==<br />
<br />
#Create a directory for yourself or your group under <tt>MADAGASCAR/user</tt>, where <tt>MADAGASCAR</tt> is the top source directory. Put your programs there.<br />
#The following conventions are adopted:<br />
#*Files containing main programs start with <tt>M</tt>, i.e. <tt>Mmyprog.c</tt> or <tt>Mmyprog.py</tt>. Each main program file should start with a short one-line comment describing its purpose. <br />
#*Files containing subroutines start with small letters. A header/interface file <tt>myprog.h</tt> is automatically generated from <tt>myprog.c</tt>. By using header files, dependencies between different functions will be figured out automatically. Include a comment of the form <font color="#cd4b19">/*^*/</font> after any block of text that you want to be included in the header file. Include a comment of the form <font color="#cd4b19">/*< My function description >*/</font> after a function definition if you want its interface included in the header file. It is a good habit to comment interfaces to all your functions. <br />
#Create a <tt>SConstruct</tt> file in your directory by following examples from other <tt>user</tt> directories. Inside the triple quotation marks after <tt>progs=</tt>, replace the names of their programs with the names of your programs with spaces between the names. <br />
#Note that running <tt>scons</tt> inside your <tt>user</tt> directory compiles programs with debugging flags to make them suitable for debugging with common debuggers such as [http://www.gnu.org/software/gdb/ gdb], dbx, or [http://www.etnus.com/ TotalView]. Running <tt>scons install</tt> inside the top source directory will compile your programs with optimization flags and install them in <tt>&#36;RSFROOT</tt>. <br />
<br />
==How to share your program with others==<br />
<br />
Follow the guide on [[Contributing new programs to Madagascar]].<br />
<br />
==How to document your program==<br />
There are three levels of documentation. From the most simple to the most complex, they are: in-code documentation, the Wiki, and reproducible papers. <br />
===In-code documentation===<br />
Of course, do comment your code -- focusing on "why" (the code itself describes the "how"). Keep comments sparse so that as much code as possible can be kept in mind at the same time by the human reader. Use the other levels for more information.<br />
<br />
If you follow a certain syntax for some of your comments, then the scripts in the Madagascar framework will be able to automatically produce a self-doc page for your program. This page will be displayed in the terminal (using basic text-mode formatting) when the program is invoked without any arguments, and a HTML version will be automatically generated in $RSFDOC (default: $RSFROOT/doc). The self-doc page has the following sections: <tt>Name</tt>, <tt>Description</tt>, <tt>Synopsis</tt>, <tt>Comments</tt>, <tt>Parameters</tt>, <tt>Used in</tt>, <tt>Source</tt> and <tt>Version</tt>. <br />
====Self-doc for C programs====<br />
To automatically populate the <tt>Description</tt> and <tt>Comments</tt> sections, use the following syntax. Start the file with:<br />
<c><br />
/* Short description line<br />
Comments here blablabla lorem ipsum dolores sit amet...<br />
<br />
You can use several paragraphs for comments, no problem.*/<br />
<br />
/* Copyright notice */<br />
</c><br />
Notice that: (1) the description line is the first line in the file; (2) Comments are closed and then open again on a new line for Copyright (so that Copyright does not show up in the documentation).<br />
<br />
To make input parameters and their default values (if they exist) automatically appear in the <tt>Synopsis</tt> and <tt>Parameters</tt> sections, make sure to read the parameters in the code like in the following example:<br />
<c><br />
if (!sf_getbool("su",&su)) su=false;<br />
/* y if input is SU, n if input is SEGY */<br />
</c><br />
Notice that there are no complex logical operations inside the <tt>if</tt>, that there is no space between the equal sign and the right and left hand, and that a short comment follows immediately. If by necessity the parameter is read in a complex fashion, use angular brackets inside the short line following the read block, i.e.:<br />
<pre><br />
... sf_getfloat ... complex stuff ...<br />
/*< parameter_name parameter meaning >*/<br />
</pre><br />
<br />
====Self-doc for Python programs====<br />
To automatically populate the <tt>Description</tt> page, and <tt>Comments</tt> sections, use the following syntax. Start the file with:<br />
<python><br />
#! /usr/bin/env python<br />
'''My one-line description of this program<br />
If I have comments, put them in the lines below.<br />
<br />
I can use several paragraphs for that'''<br />
<br />
# Copyright notice...<br />
</python><br />
Then, make sure to<br />
<python><br />
import rsfprog<br />
</python><br />
To make input parameters and their default values (if they exist) automatically appear in the <tt>Synopsis</tt> and <tt>Parameters</tt> sections, make sure to follow each argument read with a comment, and call <tt>selfdoc</tt> if no argument was given. Here is an example from <tt>user/ivlad/Mpclip.py</tt>:<br />
<python><br />
par = rsf.Par(argv)<br />
<br />
inp = par.string('inp') # input file<br />
out = par.string('out') # output file<br />
if None in (inp, out):<br />
rsfprog.selfdoc() # self-doc<br />
return error<br />
<br />
verb = par.bool('verb', False) # if y, print system commands, outputs<br />
</python><br />
<br />
====Self-doc for Fortran 90 programs====<br />
To automatically populate the <tt>Description</tt> section (<tt>Comments</tt> is not available), use the following syntax. Start the file with:<br />
<pre><br />
! One-line short description, leave a blank line after it<br />
<br />
! Copyright notice...<br />
</pre><br />
<br />
To make input parameters and their default values (if they exist) automatically appear in the <tt>Synopsis</tt> and <tt>Parameters</tt> sections, make sure to read the parameters in the code like in the following example:<br />
<pre><br />
call from_par( "n1", nt, 512 ) ! Param description on same line or first line after<br />
</pre><br />
<br />
===The Madagascar Wiki===<br />
The self-doc is good as a reminder of what the parameters mean and what their default values are, but more is usually needed for someone who never used the tool. This is what the [[Guide to madagascar programs|Guide to programs]] is for. Whenever you change or create a program, make sure to add a section for it in there too, if possible with an implementation section. Documenting programs that already exist is also a great idea.<br />
<br />
You may have noticed that each program section on that page starts with a table that has the same content as the self-doc. That is created automatically the following way. Say you want to create this table for <tt>sfattr</tt>. At a command line, type:<br />
<pre><br />
sfdoc -m $HOME attr<br />
</pre><br />
This will create the file <tt>$HOME/sfattr.wiki</tt>. Its content can be copied and pasted into the Madagascar wiki, as they already are in the MediaWiki format. Another directory can be used instead of $HOME.<br />
<br />
If your program/script reads an environment variable, make sure you check [[Advanced Installation#Environment variables|the list of environment variables used by Madagascar]] and add your new variable or your peculiar usage of an existing variable.<br />
<br />
After creating the appropriate section in the [[Guide to madagascar programs|Guide to programs]], add your program name without the <tt>sf</tt> prefix to the <tt>docprogs</tt> list at the beginning of <tt>RSFSRC/framework/rsfdoc.py</tt> . This will ensure that a link to the wiki section is created in the auto-generated HTML program page in <tt>$RSFDOC</tt>.<br />
<br />
Add your program to the [[Task-centric program list]] so that it can be found by those users who do not already know they need it.<br />
<br />
===Reproducible documents===<br />
<tt>Madagascar</tt> programs are tested and illustrated by means of [[Reproducible_Documents|reproducible documents]]. See the [[Reproducible computational experiments using SCons|Guide to SCons interface for reproducible computations]] for a brief explanation of what a reproducible paper is and how to produce one.<br />
<br />
==Style guide==<br />
* Use components (macros, types, functions) from the Madagascar library to maximize component reuse and to make sure you do not reinvent the wheel. Be familiar with the [[Library Reference]].<br />
* User interface convention: if your program provides a verbosity option, use <tt>verb=n [y/n]</tt><br />
* Do not keep commented code in your program. This does not refer to writing comments about code, but to commenting out actual code. You can always use the version control system to retrieve the older version.<br />
<br />
==How to test your program==<br />
Automatic testing is the main goal for the 1.0 release, but right now the testing mechanism is semi-automatic. Testing can be done for any program that is used in a reproducible document in the <tt>RSF/book</tt> directory. To test whether the change you made in a program called, say, <tt>sfmyprog</tt> introduced any new bugs, make sure you have the latest set of stored figures from the [[Installation#RSF_reproducible_figures|figures repository]] and do the following:<br />
<br />
#<tt>cd RSF/book</tt><br />
#Run <pre>scons sfmyprog.test</pre> If the error messages are not helpful you can omit them from the console, but keep them in a file like this (sh): <pre>scons sfmyprog.test 2> sfmyprog.test.err</pre> or like this (csh): <pre>(scons sfmyprog.test > /dev/stdin) >& sfmyprog.test.err</pre><br />
#If testing fails, find the directory and figure where failure happened from the "<tt>Comparing ... and ...</tt>" statement just before the beginning of the error messages. The directory name will appear before that in a line "<tt> Testing in ...</tt>". <tt>cd</tt> to that directory. Let's say the figure that failed is called <tt>myfig.vpl</tt>. Run <pre>scons myfig.flip</pre> That will open a graphical display window that will quickly alternate between the stored figure and your figure. <br />
#* If the figures look identical, then it means the differences are due to rounding errors and other insignificant differences between platforms (work is done on improving the comparison mechanism). Load your figure into your copy of the figures repository with <pre>scons myfig.lock</pre><br />
#* If you see differences between the two figures, then it is time to debug your program.<br />
<br />
==Tips and tricks==<br />
===Backups===<br />
You may want to back up only your developer directory, not the entire Madagascar source tree. If you do not want to or do not have the permissions to change the backup scripts, you will need to make your RSF user directory a link to somewhere else. To get that to work, you need to modify your <tt>username/SConstruct</tt>. First thing in the file, define <br />
<python><br />
RSF_src_root = '/path/to/madagascar/source/root/'<br />
</python><br />
Then, replace <tt>../..</tt> throughout the SConstruct with<br />
<python><br />
os.path.join(RSF_src_root,'whatever_followed_after_dotdots')<br />
</python> .<br />
<br />
===External libraries===<br />
To link your programs to an external library, add to the <tt>env.Prepend</tt> statement in <tt>username/Sconstruct</tt><br />
the paths to its <tt>include</tt> dir, <tt>lib</tt> dir and the name of the library you are linking to.<br />
<br />
<br />
<br />
===Emacs customization===<br />
<br />
If you use [http://www.gnu.org/software/emacs/ Emacs], the following might be helpful.<br />
<br />
* Install the [http://www.emacswiki.org/cgi-bin/wiki/PythonMode python mode] (if you don't have it installed already) and put <br />
<lisp><br />
(setq auto-mode-alist<br />
(cons '("SConstruct" . python-mode) auto-mode-alist))<br />
</lisp> <br />
:in your <tt>.emacs</tt> file to enable it on <tt>SConstruct</tt> files.<br />
<br />
* Put <br />
<lisp><br />
(set-default 'compile-command "scons")<br />
</lisp> <br />
:in your <tt>.emacs</tt> file to have <tt>scons</tt> as the default compile command.<br />
<br />
* Use <br />
<lisp><br />
(add-hook 'c-mode-common-hook<br />
'(lambda () (c-set-style "linux")<br />
(c-set-offset 'case-label 4)<br />
(setq c-basic-offset 4)))<br />
</lisp> <br />
:to make sure that the identation in C files follows the previously adopted convention.</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Guide_to_madagascar_programs&diff=706Guide to madagascar programs2009-03-12T13:53:29Z<p>Jenningsjwj: /* sfsizes */</p>
<hr />
<div><center><font size="-1">''This page was created from the LaTeX source in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/rsf/rsf/prog.tex?view=markup book/rsf/rsf/prog.tex] using [[latex2wiki]]''</font></center><br />
<br />
This guide introduces some of the most used <tt>madagascar</tt> programs and illustrates their usage with examples.<br />
=Main programs=<br />
The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/ system/main] in the Madagascar distribution. The "main" programs perform general-purpose operations on RSF hypercubes regardless of the data dimensionality or physical dimensions.<br />
<br />
==sfadd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Add, multiply, or divide RSF datasets.<br />
|-<br />
! colspan="4" | sfadd > out.rsf scale= add= sqrt= abs= log= exp= mode= [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | The various operations, if selected, occur in the following order:<br><br>(1) Take absolute value, abs=<br>(2) Add a scalar, add=<br>(3) Take the natural logarithm, log=<br>(4) Take the square root, sqrt=<br>(5) Multiply by a scalar, scale=<br>(6) Compute the base-e exponential, exp=<br>(7) Add, multiply, or divide the data sets, mode=<br><br>sfadd operates on integer, float, or complex data, but all the input<br>and output files must be of the same data type.<br><br>An alternative to sfadd is sfmath, which is more versatile, but may be<br>less efficient.<br />
|-<br />
| ''bools '' || '''abs=''' || || If true take absolute value [nin]<br />
|-<br />
| ''floats '' || '''add=''' || || Scalar values to add to each dataset [nin]<br />
|-<br />
| ''bools '' || '''exp=''' || || If true compute exponential [nin]<br />
|-<br />
| ''bools '' || '''log=''' || || If true take logarithm [nin]<br />
|-<br />
| ''string '' || '''mode=''' || || 'a' means add (default), <br> 'p' or 'm' means multiply, <br> 'd' means divide<br />
|-<br />
| ''floats '' || '''scale=''' || || Scalar values to multiply each dataset with [nin]<br />
|-<br />
| ''bools '' || '''sqrt=''' || || If true take square root [nin]<br />
|}<br />
<br />
<tt>sfadd</tt> is useful for combining (adding, dividing, or<br />
multiplying) several datasets. What if you want to subtract two<br />
datasets? Easy. Use the <tt>scale</tt> parameter as follows:<br />
<pre><br />
bash&#36; sfadd data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfadd < data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
The same task can be accomplished with the more general <tt>sfmath</tt> program:<br />
<pre><br />
bash&#36; sfmath one=data1.rsf two=data2.rsf output='one-two' > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfmath < data1.rsf two=data2.rsf output='input-two' > diff.rsf<br />
</pre><br />
In both cases, the size and shape of <tt>data1.rsf</tt> and<br />
<tt>data2.rsf</tt> hypercubes should be the same, and a warning<br />
message is printed out if the the axis sampling parameters (such as<br />
<tt>o1</tt> or <tt>d1</tt>) in these files are different.<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/add.c?view=markup user/main/add.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
/* find number of input files */<br />
if (isatty(fileno(stdin))) { <br />
/* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Collect input files in the <tt>in</tt> array from all command-line<br />
parameters that don't contain an "<tt>=</tt>" sign. The total number<br />
of input files in <tt>nin</tt>.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) continue; <br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
/* nin = no of input files*/<br />
</c><br />
<br />
A helper function <tt>check_compat</tt> checks the compatibility of<br />
input files.<br />
<c><br />
static void <br />
check_compat (sf_datatype type /* data type */, <br />
size_t nin /* number of files */, <br />
sf_file* in /* input files [nin] */, <br />
int dim /* file dimensionality */, <br />
const int* n /* dimensions [dim] */)<br />
/* Check that the input files are compatible. <br />
Issue error for type mismatch or size mismatch.<br />
Issue warning for grid parameters mismatch. */<br />
{<br />
int ni, id;<br />
size_t i;<br />
float d, di, o, oi;<br />
char key[3];<br />
const float tol=1.e-5; /* tolerance for comparison */<br />
<br />
for (i=1; i < nin; i++) {<br />
if (sf_gettype(in[i]) != type) <br />
sf_error ("type mismatch: need %d",type);<br />
for (id=1; id <= dim; id++) {<br />
(void) snprintf(key,3,"n%d",id);<br />
if (!sf_histint(in[i],key,&ni) || ni != n[id-1])<br />
sf_error("%s mismatch: need %d",key,n[id-1]);<br />
(void) snprintf(key,3,"d%d",id);<br />
if (sf_histfloat(in[0],key,&d)) {<br />
if (!sf_histfloat(in[i],key,&di) || <br />
(fabsf(di-d) > tol*fabsf(d)))<br />
sf_warning("%s mismatch: need %g",key,d);<br />
} else {<br />
d = 1.;<br />
}<br />
(void) snprintf(key,3,"o%d",id);<br />
if (sf_histfloat(in[0],key,&o) && <br />
(!sf_histfloat(in[i],key,&oi) || <br />
(fabsf(oi-o) > tol*fabsf(d))))<br />
sf_warning("%s mismatch: need %g",key,o);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
Finally, we enter the main loop, where input data are getting read<br />
buffer by buffer and combined in the total product depending on the<br />
data type.<br />
<c><br />
for (nbuf /= sf_esize(in[0]); nsiz > 0; nsiz -= nbuf) {<br />
if (nbuf > nsiz) nbuf=nsiz;<br />
<br />
for (j=0; j < nin; j++) {<br />
collect = (bool) (j != 0);<br />
switch(type) {<br />
case SF_FLOAT:<br />
sf_floatread((float*) bufi,<br />
nbuf,<br />
in[j]); <br />
add_float(collect, <br />
nbuf,<br />
(float*) buf,<br />
(const float*) bufi, <br />
cmode, <br />
scale[j], <br />
add[j], <br />
abs_flag[j], <br />
log_flag[j], <br />
sqrt_flag[j], <br />
exp_flag[j]);<br />
break;<br />
</c><br />
<br />
The data combination program for floating point numbers is<br />
<tt>add_float</tt>. <br />
<c><br />
static void add_float (bool collect, /* if collect */<br />
size_t nbuf, /* buffer size */<br />
float* buf, /* output [nbuf] */<br />
const float* bufi, /* input [nbuf] */ <br />
char cmode, /* operation */<br />
float scale, /* scale factor */<br />
float add, /* add factor */<br />
bool abs_flag, /* if abs */<br />
bool log_flag, /* if log */<br />
bool sqrt_flag, /* if sqrt */<br />
bool exp_flag /* if exp */)<br />
/* Add floating point numbers */<br />
{<br />
size_t j;<br />
float f;<br />
<br />
for (j=0; j < nbuf; j++) {<br />
f = bufi[j];<br />
if (abs_flag) f = fabsf(f);<br />
f += add;<br />
if (log_flag) f = logf(f);<br />
if (sqrt_flag) f = sqrtf(f);<br />
if (1. != scale) f *= scale;<br />
if (exp_flag) f = expf(f);<br />
if (collect) {<br />
switch (cmode) {<br />
case 'p': /* product */<br />
case 'm': /* multiply */<br />
buf[j] *= f;<br />
break;<br />
case 'd': /* delete */<br />
if (f != 0.) buf[j] /= f;<br />
break;<br />
default: /* add */<br />
buf[j] += f;<br />
break;<br />
}<br />
} else {<br />
buf[j] = f;<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display dataset attributes.<br />
|-<br />
! colspan="4" | sfattr < in.rsf want=<br />
|-<br />
| colspan="4" | <br>Sample output from "sfspike n1=100 | sfbandpass fhi=60 | sfattr"<br>******************************************* <br>rms = 0.992354 <br>mean value = 0.987576 <br>2-norm value = 9.92354 <br>variance = 0.00955481 <br>standard deviation = 0.0977487 <br>maximum value = 1.12735 at 97 <br>minimum value = 0.151392 at 100 <br>number of nonzero samples = 100 <br>total number of samples = 100 <br>******************************************* <br><br>rms = sqrt[ sum(data^2) / n ]<br>mean = sum(data) / n<br>norm = sum(abs(data)^lval)^(1/lval)<br>variance = [ sum(data^2) - n*mean^2 ] / [ n-1 ]<br>standard deviation = sqrt [ variance ]<br />
|-<br />
| ''int '' || '''lval=2''' || || norm option, lval is a non-negative integer, computes the vector lval-norm<br />
|-<br />
| ''string '' || '''want=''' || || 'all'(default),'rms','mean','norm','var','std','max','min','nonzero','samples','short' <br />
:want= 'rms' displays the root mean square<br />
:want= 'norm' displays the square norm, otherwise specified by lval.<br />
:want= 'var' displays the variance<br />
:want= 'std' displays the standard deviation<br />
:want= 'nonzero' displays number of nonzero samples<br />
:want= 'samples' displays total number of samples<br />
:want= 'short' displays a short one-line version<br />
|}<br />
<br />
<br />
<tt>sfattr</tt> is a useful diagnostic program. It reports certain<br />
statistical values for an RSF dataset: RMS (root-mean-square)<br />
amplitude, mean value, vector norm value, variance, standard deviation,<br />
maximum and minimum values, number of nonzero samples, and the total<br />
number of samples.<br />
If we denote data values as <math>d_i</math> for <math>i=0,1,2,\ldots,n</math>, then the RMS<br />
value is <math>\sqrt{\frac{1}{n}\,\sum\limits_{i=0}^n d_i^2}</math>, the mean<br />
value is <math>\frac{1}{n}\,\sum\limits_{i=0}^n d_i</math>, the <math>L_2</math>-norm value<br />
is <math>\sqrt{\sum\limits_{i=0}^n d_i^2}</math>, the variance is<br />
<math>\frac{1}{n-1}\,\left[\sum\limits_{i=0}^n d_i^2 - \frac{1}{n}\left(\sum\limits_{i=0}^n d_i\right)^2\right]</math>, and the standard<br />
deviation is the square root of the variance. Using <tt>sfattr</tt><br />
is a quick way to see the distribution of data values and check it for<br />
anomalies.<br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/attr.c?view=markup user/main/attr.c]====<br />
<br />
Computations start by finding the input data (<tt>in</tt>) size<br />
(<tt>nsiz</tt>) and dimensions (<tt>dim</tt>).<br />
<c><br />
dim = (size_t) sf_filedims (in,n);<br />
for (nsiz=1, i=0; i < dim; i++) {<br />
nsiz *= n[i];<br />
}<br />
</c><br />
<br />
<br />
In the main loop, we read the input data buffer by buffer.<br />
<c><br />
for (nleft=nsiz; nleft > 0; nleft -= nbuf) {<br />
nbuf = (bufsiz < nleft)? bufsiz: nleft;<br />
switch (type) {<br />
case SF_FLOAT: <br />
sf_floatread((float*) buf,nbuf,in);<br />
break;<br />
case SF_INT:<br />
sf_intread((int*) buf,nbuf,in);<br />
break;<br />
case SF_COMPLEX:<br />
sf_complexread((sf_complex*) buf,nbuf,in);<br />
break;<br />
case SF_UCHAR:<br />
sf_ucharread((unsigned char*) buf,nbuf,in);<br />
break;<br />
case SF_CHAR:<br />
default:<br />
sf_charread(buf,nbuf,in);<br />
break;<br />
}<br />
</c><br />
<br />
<br />
The data attributes are accumulated in corresponding double-precision<br />
variables. <br />
<c><br />
fsum += f;<br />
fsqr += f*f;<br />
</c><br />
<br />
<br />
Finally, the attributes are reduced and printed out.<br />
<c><br />
fmean = fsum/nsiz;<br />
if (lval==2) fnorm = sqrt(fsqr);<br />
else if (lval==0) fnorm = nsiz-nzero;<br />
else fnorm = pow(flval,1./lval);<br />
frms = sqrt(fsqr/nsiz);<br />
if (nsiz > 1) fvar = (fsqr-nsiz*fmean*fmean)/(nsiz-1);<br />
else fvar = 0.0;<br />
fstd = sqrt(fvar);<br />
</c><br />
<br />
<c><br />
if(NULL==want || 0==strcmp(want,"rms"))<br />
printf("rms = %g \n",(float) frms);<br />
if(NULL==want || 0==strcmp(want,"mean"))<br />
printf("mean value = %g \n",(float) fmean);<br />
if(NULL==want || 0==strcmp(want,"norm"))<br />
printf("%d-norm value = %g \n",lval,(float) fnorm);<br />
if(NULL==want || 0==strcmp(want,"var"))<br />
printf("variance = %g \n",(float) fvar);<br />
if(NULL==want || 0==strcmp(want,"std"))<br />
printf("standard deviation = %g \n",(float) fstd);<br />
</c><br />
<br />
==sfcat==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Concatenate datasets. <br />
|-<br />
! colspan="4" | sfcat > out.rsf space= axis=3 nspace=(int) (ni/(20*nin) + 1) [<file0.rsf] file1.rsf file2.rsf ... <br />
|-<br />
| colspan="4" | sfmerge inserts additional space between merged data.<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis being merged<br />
|-<br />
| ''int '' || '''nspace=(int) (ni/(20*nin) + 1)''' || || if space=y, number of traces to insert<br />
|-<br />
| ''bool '' || '''space=''' || [y/n] || Insert additional space.<br />
:y is default for sfmerge, n is default for sfcat<br />
|}<br />
<br />
<br />
<tt>sfcat</tt> and <tt>sfmerge</tt> concatenate two or more files<br />
together along a particular axis. It is the same program, only<br />
<tt>sfcat</tt> has the default <tt>space=n</tt> and <tt>sfmerge</tt><br />
has the default <tt>space=y</tt>.<br />
Example of <tt>sfcat</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcat one.rsf one.rsf axis=1 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=4 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
12 elements 48 bytes<br />
</pre><br />
Example of <tt>sfmerge</tt>:<br />
<pre><br />
bash$ sfmerge one.rsf one.rsf axis=2 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=7 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
14 elements 56 bytes<br />
</pre><br />
In this case, an extra empty trace is inserted between the two merged files.<br />
The axes that are not being merged are checked for consistency:<br />
<pre><br />
bash$ sfcat one.rsf two.rsf > three.rsf<br />
sfcat: n2 mismatch: need 3<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cat.c?view=markup user/main/cat.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
in = (sf_file*) sf_alloc ((size_t) argc,sizeof(sf_file));<br />
<br />
if (!sf_stdin()) { /* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Everything on the command line that does not contain a "=" sign is<br />
treated as a file name, and the corresponding file object is added to the list.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) <br />
continue; /* not a file */<br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
</c><br />
<br />
As explained above, if the <tt>space=</tt> parameter is not set, it is<br />
inferred from the program name: <tt>sfmerge</tt> corresponds to<br />
<tt>space=y</tt> and <tt>sfcat</tt> corresponds to <tt>space=n</tt>.<br />
<c><br />
if (!sf_getbool("space",&space)) {<br />
/* Insert additional space.<br />
y is default for sfmerge, n is default for sfcat */<br />
prog = sf_getprog();<br />
if (NULL != strstr (prog, "merge")) {<br />
space = true;<br />
} else if (NULL != strstr (prog, "cat")) {<br />
space = false;<br />
} else {<br />
sf_warning("%s is neither merge nor cat,"<br />
" assume merge",prog);<br />
space = true;<br />
}<br />
}<br />
</c><br />
<br />
Find the axis for the merging (from the command line <tt>axis=</tt><br />
argument) and figure out two sizes: <tt>n1</tt> for everything after<br />
the axis and <tt>n2</tt> for everything before the axis.<br />
<c><br />
n1=1;<br />
n2=1;<br />
for (i=1; i <= dim; i++) {<br />
if (i < axis) n1 *= n[i-1];<br />
else if (i > axis) n2 *= n[i-1];<br />
}<br />
</c><br />
<br />
In the output, the selected axis will get extended.<br />
<c><br />
/* figure out the length of extended axis */<br />
ni = 0;<br />
for (j=0; j < nin; j++) {<br />
ni += naxis[j];<br />
}<br />
<br />
if (space) {<br />
if (!sf_getint("nspace",&nspace)) <br />
nspace = (int) (ni/(20*nin) + 1);<br />
/* if space=y, number of traces to insert */ <br />
ni += nspace*(nin-1);<br />
} <br />
<br />
(void) snprintf(key,3,"n%d",axis);<br />
sf_putint(out,key,(int) ni);<br />
</c><br />
<br />
The rest is simple: loop through the datasets reading and writing the<br />
data in buffer-size chunks and adding extra empty chunks if<br />
<tt>space=y</tt>.<br />
<c><br />
for (i2=0; i2 < n2; i2++) {<br />
for (j=0; j < nin; j++) {<br />
for (ni = n1*naxis[j]*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charread (buf,nbuf,in[j]);<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
if (!space || j == nin-1) continue;<br />
/* Add spaces */<br />
memset(buf,0,BUFSIZ);<br />
for (ni = n1*nspace*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfcmplx==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a complex dataset from its real and imaginary parts.<br />
|-<br />
! colspan="4" | sfcmplx > cmplx.rsf real.rsf imag.rsf<br />
|-<br />
| colspan="4" | There has to be only two input files specified and no additional parameters.<br />
|}<br />
<br />
<br />
<tt>sfcmplx</tt> simply creates a complex dataset from its real and<br />
imaginary parts. The reverse operation can be accomplished with<br />
<tt>sfreal</tt> and <tt>sfimag</tt>.<br />
Example of <tt>sfcmplx</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcmplx one.rsf one.rsf > cmplx.rsf<br />
bash$ sfin cmplx.rsf<br />
cmplx.rsf:<br />
in="/tmp/cmplx.rsf@"<br />
esize=8 type=complex form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 48 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cmplx.c?view=markup user/main/cmplx.c]====<br />
The program flow is simple. First, get the names of the input files.<br />
<c><br />
/* the first two non-parameters are real and imaginary files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == real) {<br />
real = sf_input (argv[i]);<br />
} else {<br />
imag = sf_input (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == imag) {<br />
if (NULL == real) sf_error ("not enough input");<br />
/* if only one input, real is in stdin */<br />
imag = real;<br />
real = sf_input("in");<br />
}<br />
</c><br />
<br />
The main part of the program reads the real and imaginary parts buffer by buffer and assembles and writes out the complex input. <br />
<c><br />
for (nleft= (size_t) (rsize*resize); nleft > 0; nleft -= nbuf) {<br />
nbuf = (BUFSIZ < nleft)? BUFSIZ: nleft;<br />
sf_charread(rbuf,nbuf,real);<br />
sf_charread(ibuf,nbuf,imag);<br />
for (i=0; i < nbuf; i += resize) {<br />
memcpy(cbuf+2*i, rbuf+i,(size_t) resize);<br />
memcpy(cbuf+2*i+resize,ibuf+i,(size_t) resize);<br />
}<br />
sf_charwrite(cbuf,2*nbuf,cmplx);<br />
}<br />
</c><br />
<br />
==sfconjgrad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic conjugate-gradient solver for linear inversion <br />
|-<br />
! colspan="4" | sfconjgrad < dat.rsf mod=mod.rsf > to.rsf < from.rsf > out.rsf niter=1<br />
|-<br />
| ''int '' || '''niter=1''' || || number of iterations<br />
|}<br />
<br />
<br />
<tt>sfconjgrad</tt> is a generic program for least-squares linear<br />
inversion with the conjugate-gradient method. Suppose you have an<br />
executable program <tt><prog></tt> that takes an RSF file from the<br />
standard input and produces an RSF file in the standard output. It may<br />
take any number of additional parameters but one of them must be<br />
<tt>adj=</tt> that sets the forward (<tt>adj=0</tt>) or adjoint<br />
(<tt>adj=1</tt>) operations. The program <tt><prog></tt> is typically<br />
an RSF program but it could be anything (a script, a multiprocessor<br />
MPI program, etc.) as long as it implements a linear operator<br />
<math>\mathbf{L}</math> and its adjoint. There are no restrictions on the data<br />
size or shape. You can easily test the adjointness with<br />
<tt>sfdottest</tt>. The <tt>sfconjgrad</tt> program searches for a<br />
vector <math>\mathbf{m}</math> that minimizes the least-square misfit <br />
<math>\|\mathbf{d - L\,m}\|^2</math> for the given input data vector <math>\mathbf{d}</math>.<br />
Here is an example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
The <tt>sfdottest</tt> program can perform the dot product test to<br />
check that the adjoint mode works correctly.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=5.28394<br />
sfdottest: L'[d]*m=5.28394<br />
</pre><br />
Your numbers may be different because <tt>sfdottest</tt> generates new<br />
random input on each run.<br />
Next, let us make some random data with <tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfnoise seed=2005 rep=y < vec.rsf > dat.rsf<br />
</pre><br />
and try to invert the filtering operation using <tt>sfconjgrad</tt>:<br />
<pre><br />
bash$ sfconjgrad sfhelicon filt=flt.rsf lag=lag.rsf \<br />
mod=vec.rsf < dat.rsf > mod.rsf niter=10<br />
sfconjgrad: iter 1 of 10<br />
sfconjgrad: grad=3253.65<br />
sfconjgrad: iter 2 of 10<br />
sfconjgrad: grad=289.421<br />
sfconjgrad: iter 3 of 10<br />
sfconjgrad: grad=92.3481<br />
sfconjgrad: iter 4 of 10<br />
sfconjgrad: grad=36.9417<br />
sfconjgrad: iter 5 of 10<br />
sfconjgrad: grad=18.7228<br />
sfconjgrad: iter 6 of 10<br />
sfconjgrad: grad=11.1794<br />
sfconjgrad: iter 7 of 10<br />
sfconjgrad: grad=7.26941<br />
sfconjgrad: iter 8 of 10<br />
sfconjgrad: grad=5.15945<br />
sfconjgrad: iter 9 of 10<br />
sfconjgrad: grad=4.23055<br />
sfconjgrad: iter 10 of 10<br />
sfconjgrad: grad=3.57495<br />
</pre><br />
The output shows that, in 10 iterations, the norm of the gradient vector decreases by almost 1000. <br />
We can check the residual misfit before<br />
<pre><br />
bash$ < dat.rsf sfattr want=norm<br />
norm value = 49.7801<br />
</pre><br />
and after<br />
<pre><br />
bash$ sfhelicon filt=flt.rsf lag=lag.rsf < mod.rsf | \<br />
sfadd scale=1,-1 dat.rsf | sfattr want=norm<br />
norm value = 5.73563<br />
</pre><br />
In 10 iterations, the misfit decreased by an order of magnitude. The<br />
result can be improved by running the program for more iterations.<br />
<br />
==sfcp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Copy or move a dataset.<br />
|-<br />
! colspan="4" | sfcp in.rsf out.rsf<br />
|-<br />
| colspan="4" | sfcp - copy, sfmv - move.<br>Mimics standard Unix commands.<br />
|}<br />
<br />
<br />
The <tt>sfcp</tt> and <tt>sfmv</tt> command imitate the Unix<br />
<tt>cp</tt> and <tt>mv</tt> commands and serve for copying and moving<br />
RSF files. Example:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcp one.rsf two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
</pre><br />
<br />
==sfcut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of the dataset. <br />
|-<br />
! colspan="4" | sfcut < in.rsf > out.rsf verb=n [j1=1 j2=1 ... f1=0 f2=0 ... n1=n1 n2=n2 ... max1= max2= ... min1= min2= ...]<br />
|-<br />
| colspan="4" | jN defines the jump in N-th dimension<br>fN is the window start<br>nN is the window size<br>minN and maxN is the maximum and minimum in N-th dimension<br><br>Reverse of window. <br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
The <tt>sfcut</tt> command is related to <tt>sfwindow</tt> and has the same<br />
set of arguments only instead of extracting the selected window, it fills it<br />
with zeroes. The size of the input data is preserved. <br />
Examples:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > in.rsf<br />
bash$ < in.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < in.rsf sfcut n1=2 f1=1 n2=3 f2=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 0 0 1 1<br />
15: 1 0 0 1 1<br />
20: 1 0 0 1 1<br />
bash$ < in.rsf sfcut j1=2 | sfdisfil<br />
0: 0 1 0 1 0<br />
5: 0 1 0 1 0<br />
10: 0 1 0 1 0<br />
15: 0 1 0 1 0<br />
20: 0 1 0 1 0<br />
</pre><br />
<br />
==sfdd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert between different formats. <br />
|-<br />
! colspan="4" | sfdd < in.rsf > out.rsf line=8 form= type= format=<br />
|-<br />
| ''string '' || '''form=''' || || ascii, native, xdr<br />
|-<br />
| ''string '' || '''format=''' || || Element format (for conversion to ASCII)<br />
|-<br />
| ''int '' || '''line=8''' || || Number of numbers per line (for conversion to ASCII)<br />
|-<br />
| ''string '' || '''type=''' || || int, float, complex<br />
|}<br />
<br />
<br />
The <tt>sfdd</tt> program is used to change either the form (<tt>ascii</tt>,<br />
<tt>xdr</tt>, <tt>native</tt>) or the type (<tt>complex</tt>, <tt>float</tt>,<br />
<tt>int</tt>, <tt>char</tt>) of the input dataset. <br />
In the example below, we create a plain text (ASCII) file with numbers and<br />
then use <tt>sfdd</tt> to generate an RSF file in <tt>xdr</tt> form with<br />
<tt>complex</tt> numbers. <br />
<pre><br />
bash$ cat test.txt<br />
1 2 3 4 5 6<br />
bash$ echo n1=6 data_format=ascii_int in=test.txt > test.rsf<br />
bash$ sfin test.rsf<br />
test.rsf:<br />
in="test.txt"<br />
esize=0 type=int form=ascii<br />
n1=6 d1=? o1=?<br />
6 elements<br />
bash$ sfdd < test.rsf form=xdr type=complex > test2.rsf<br />
bash$ sfin test2.rsf<br />
test2.rsf:<br />
in="/tmp/test2.rsf@"<br />
esize=8 type=complex form=xdr<br />
n1=3 d1=? o1=?<br />
3 elements 24 bytes<br />
bash$ sfdisfil < test2.rsf<br />
0: 1, 2i 3, 4i 5, 6i<br />
</pre><br />
To learn more about the RSF data format, consult the [[Format| guide to RSF format]].<br />
<br />
==sfdisfil==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Print out data values.<br />
|-<br />
! colspan="4" | sfdisfil < in.rsf number=y col=0 format= header= trailer=<br />
|-<br />
| colspan="4" | <br>Alternatively, use sfdd and convert to ASCII form.<br />
|-<br />
| ''int '' || '''col=0''' || || Number of columns.<br />
:The default depends on the data type:<br />
:10 for int and char,<br />
:5 for float,<br />
:3 for complex<br />
|-<br />
| ''string '' || '''format=''' || || Format for numbers (printf-style).<br />
:The default depends on the data type:<br> "%4d " for int and char,<br> "%13.4g" for float,<br> "%10.4g,%10.4gi" for complex<br />
|-<br />
| ''string '' || '''header=''' || || Optional header string to output before data<br />
|-<br />
| ''bool '' || '''number=y''' || [y/n] || If number the elements<br />
|-<br />
| ''string '' || '''trailer=''' || || Optional trailer string to output after data<br />
|}<br />
<br />
<br />
The <tt>sfdisfil</tt> program simply dumps the data contents to the standard<br />
output in a text form. It is used mostly for debugging purposes to quickly<br />
examine RSF files. Here is an example:<br />
<pre><br />
bash$ sfmath o1=0 d1=2 n1=12 output=x1 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
10: 20 22<br />
</pre><br />
The output format is easily configurable.<br />
<pre><br />
bash$ < test.rsf sfdisfil col=6 number=n format="<br />
0.0 2.0 4.0 6.0 8.0 10.0<br />
12.0 14.0 16.0 18.0 20.0 22.0<br />
</pre><br />
Along with <tt>sfdd</tt>, <tt>sfdisfil</tt> provides a simple way to convert<br />
RSF data to an ASCII form.<br />
<br />
==sfdottest==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic dot-product test for linear operators with adjoints <br />
|-<br />
! colspan="4" | sfdottest mod=mod.rsf dat=dat.rsf > pip.rsf<br />
|}<br />
<br />
<br />
<tt>sfdottest</tt> is a generic dot-product test program for testing<br />
linear operators. Suppose there is an executable program<br />
<tt><prog></tt> that takes an RSF file from the standard input and<br />
produces an RSF file in the standard output. It may take any number of<br />
additional parameters but one of them must be <tt>adj=</tt> that sets<br />
the forward (<tt>adj=0</tt>) or adjoint (<tt>adj=1</tt>) operations.<br />
The program <tt><prog></tt> is typically an RSF program but it could<br />
be anything (a script, a multiprocessor MPI program, etc.) as long as<br />
it implements a linear operator <math>\mathbf{L}</math> and its adjoint<br />
<math>\mathbf{L}^T</math>. The <tt>sfdottest</tt> program is testing the equality<br />
<center><math><br />
d^T\,L\,m = m^T\,L^T\,d<br />
</math></center><br />
by using random vectors <math>\mathbf{m}</math> and <math>\mathbf{d}</math>. You can invoke it with<br />
<pre><br />
bash$ sfdottest <prog> [optional aruments] mod=mod.rsf dat=dat.rsf<br />
</pre><br />
where <tt>mod.rsf</tt> and <tt>dat.rsf</tt> are RSF files that<br />
represent vectors from the model and data spaces. <tt>sfdottest</tt><br />
does not create any temporary files and does not have any restrictive<br />
limitations on the size of the vectors.<br />
Here is an example. We first setup a vector with 100 elements using<br />
<tt>sfspike</tt> and then run <tt>sfdottest</tt> to test the<br />
<tt>sfcausint</tt> program. <tt>sfcausint</tt> implements a linear<br />
operator of causal integration and its adjoint, the anti-causal<br />
integration.<br />
<pre><br />
bash$ sfspike n1=100 > vec.rsf<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1410.2<br />
sfdottest: L'[d]*m=1410.2<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1165.87<br />
sfdottest: L'[d]*m=1165.87<br />
</pre><br />
The numbers are different on subsequent runs because of changing<br />
seed in the random number generator.<br />
Here is a somewhat more complicated example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
Now the <tt>sfdottest</tt> program can perform the dot product test.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=8.97375<br />
sfdottest: L'[d]*m=8.97375<br />
</pre><br />
Here is the same program tested in the inverse filtering mode:<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf inv=y<br />
sfdottest: L[m]*d=15.0222<br />
sfdottest: L'[d]*m=15.0222<br />
</pre><br />
<br />
==sfget==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Output parameters from the header.<br />
|-<br />
! colspan="4" | sfget < in.rsf parform=y par1 par2 ...<br />
|-<br />
| ''bool '' || '''parform=y''' || [y/n] || If y, print out parameter=value. If n, print out value.<br />
|}<br />
<br />
<br />
The <tt>sfget</tt> program extracts a parameter value from an RSF file. It is<br />
useful mostly for scripting. Here is, for example, a quick calculation of the<br />
maximum value on the first axis in an RSF dataset (the output of<br />
<tt>sfspike</tt>) using the standard Unix <tt>bc</tt> calculator.<br />
<pre><br />
bash$ ( sfspike n1=100 | sfget n1 d1 o1; echo "o1+(n1-1)*d1" ) | bc<br />
.396<br />
</pre><br />
See also <tt>sfput</tt>.<br />
<br />
<br />
<br />
==sfheadercut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheadercut mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array of size n2.<br />
|}<br />
<br />
<br />
<tt>sfheadercut</tt> is close to <tt>sfheaderwindow</tt> but instead<br />
of windowing the dataset, it fills the traces specified by the header<br />
mask with zeroes. The size of the input data is preserved.<br />
Here is an example of using <tt>sfheaderwindow</tt> for <br />
zeroing every other trace in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a mask with alternating ones and zeros using<br />
<tt>sfinterleave</tt>.<br />
<pre><br />
bash$ sfspike n1=5 mag=1 | sfdd type=int > ones.rsf<br />
bash$ sfspike n1=5 mag=0 | sfdd type=int > zeros.rsf<br />
bash$ sfinterleave axis=1 ones.rsf zeros.rsf > mask.rsf<br />
bash$ sfdisfil < mask.rsf<br />
0: 1 0 1 0 1 0 1 0 1 0<br />
</pre><br />
Finally, <tt>sfheadercut</tt> zeros the input traces.<br />
<pre><br />
bash$ sfheadercut < input.rsf mask=mask.rsf > output.rsf<br />
bash$ sfdisfil < output.rsf <br />
0: 1 1 1 1 1<br />
5: 0 0 0 0 0<br />
10: 3 3 3 3 3<br />
15: 0 0 0 0 0<br />
20: 5 5 5 5 5<br />
25: 0 0 0 0 0<br />
30: 7 7 7 7 7<br />
35: 0 0 0 0 0<br />
40: 9 9 9 9 9<br />
45: 0 0 0 0 0<br />
</pre><br />
<br />
<br />
<br />
==sfheadersort==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Sort a dataset according to a header key. <br />
|-<br />
! colspan="4" | sfheadersort < in.rsf > out.rsf head=<br />
|-<br />
| ''string '' || '''head=''' || || header file<br />
|}<br />
<br />
<br />
<tt>sfheadersort</tt> is used to sort traces in the input file<br />
according to trace header information. <br />
Here is an example of using<br />
<tt>sfheadersort</tt> for randomly shuffling traces in the input<br />
file. First, let us create an input file with seven traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=7 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7 <br />
</pre><br />
Next, we can create a random file with seven header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=7 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: 0.05256 -0.2879 0.1487 0.4097 0.1548<br />
5: 0.4501 0.2836<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally, we<br />
apply <tt>sfheadersort</tt> to shuffle the input traces.<br />
<pre><br />
bash$ < input.rsf sfheadersort head=random.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 1 1 1 1 1<br />
10: 3 3 3 3 3<br />
15: 5 5 5 5 5<br />
20: 7 7 7 7 7<br />
25: 4 4 4 4 4<br />
30: 6 6 6 6 6<br />
</pre><br />
As expected, the order of traces in the output file corresponds to the<br />
order of values in the header. Thanks to the separation between<br />
headers and data, the operation of <tt>sfheadersort</tt> is optimally<br />
efficient. It first sorts the headers and only then accesses the data,<br />
reading each data trace only once.<br />
<br />
==sfheaderwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheaderwindow mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array os size n2, windowed is n1xm2,<br>where m2 is the number of nonzero elements in mask.<br />
|}<br />
<br />
<br />
<tt>sfheaderwindow</tt> is used to window traces in the input file<br />
according to trace header information. <br />
Here is an example of using <tt>sfheaderwindow</tt> for randomly<br />
selecting part of the traces in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a random file with ten header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=10 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: -0.005768 0.02258 -0.04331 -0.4129 -0.3909<br />
5: -0.03582 0.4595 -0.3326 0.498 -0.3517<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally,<br />
we apply <tt>sfheaderwindow</tt> to window the input traces selecting<br />
only those for which the header is greater than zero.<br />
<pre><br />
bash$ < random.rsf sfmask min=0 > mask.rsf<br />
bash$ < mask.rsf sfdisfil<br />
0: 0 1 0 0 0 0 1 0 1 0<br />
bash$ < input.rsf sfheaderwindow mask=mask.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 7 7 7 7 7<br />
10: 9 9 9 9 9<br />
</pre><br />
In this case, only three traces are selected for the output. Thanks to<br />
the separation between headers and data, the operation of<br />
<tt>sfheaderwindow</tt> is optimally efficient. <br />
<br />
==sfin==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display basic information about RSF files.<br />
|-<br />
! colspan="4" | sfin info=y check=2. trail=y file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | n1,n2,... are data dimensions<br>o1,o2,... are axis origins<br>d1,d2,... are axis sampling intervals<br>label1,label2,... are axis labels<br>unit1,unit2,... are axis units<br />
|-<br />
| ''float '' || '''check=2.''' || || Portion of the data (in Mb) to check for zero values.<br />
|-<br />
| ''bool '' || '''info=y''' || [y/n] || If n, only display the name of the data file.<br />
|-<br />
| ''bool '' || '''trail=y''' || [y/n] || If n, skip trailing dimensions of one<br />
|}<br />
<br />
<br />
<tt>sfin</tt> is one of the most useful programs for operating with<br />
RSF files. It produces quick information on the file hypercube<br />
dimensions and checks the consistency of the associated data file.<br />
Here is an example. Let us create an RSF file and examine it with <tt>sfin</tt>.<br />
<pre><br />
bash$ sfspike n1=100 n2=20 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=100 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
2000 elements 8000 bytes<br />
</pre><br />
<tt>sfin</tt> reports the following information:<br />
<br />
*location of the data file (<tt>/tmp/spike.rsf\@</tt>) <br />
*element size (4 bytes) <br />
*element type (floating point) <br />
*element form (native) <br />
*hypercube dimensions (100 by 20) <br />
*axes scale (0.004 and 0.1) <br />
*axes origin (0 and 0) <br />
*axes labels <br />
*axes units <br />
*total number of elements <br />
*total number of bytes in the data file <br />
Suppose that the file got corrupted by a buggy program and reports<br />
incorrect dimensions. The <tt>sfin</tt> program should be able to<br />
catch the discrepancy.<br />
<pre><br />
bash$ echo n2=100 >> spike.rsf<br />
bash$ sfin spike.rsf > /dev/null<br />
sfin: Actually 8000 bytes, 20% of expected.<br />
</pre><br />
<tt>sfin</tt> also checks the first records in the file for zeros. <br />
<pre><br />
bash$ sfspike n1=100 n2=100 k2=99 > spike2.rsf<br />
bash$ sfin spike2.rsf >/dev/null<br />
sfin: The first 32768 bytes are all zeros<br />
</pre><br />
The number of bytes to check is adjustable<br />
<pre><br />
bash$ sfin spike2.rsf check=0.01 >/dev/null<br />
sfin: The first 16384 bytes are all zeros<br />
</pre><br />
You can also output only the location of the data file. This is<br />
sometimes handy in scripts.<br />
<pre><br />
bash$ sfin spike.rsf spike2.rsf info=n<br />
/tmp/spike.rsf@ /tmp/spike2.rsf@<br />
</pre><br />
An alternative is to use <tt>sfget</tt>, as follows:<br />
<pre><br />
bash$ sfget parform=n in < spike.rsf<br />
/tmp/spike.rsf@<br />
</pre><br />
<br />
==sfinterleave==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Combine several datasets by interleaving.<br />
|-<br />
! colspan="4" | sfinterleave > out.rsf axis=3 [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis for interleaving<br />
|}<br />
<br />
<br />
<tt>sfinterleave</tt> combines two or more datasets by interleaving them on one<br />
of the axes. Here is a quick example:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ sfscale < one.rsf dscale=2 > two.rsf<br />
bash$ sfdisfil < two.rsf<br />
0: 2 2 2 2 2<br />
5: 2 2 2 2 2<br />
10: 2 2 2 2 2<br />
15: 2 2 2 2 2<br />
20: 2 2 2 2 2<br />
bash$ sfinterleave one.rsf two.rsf axis=1 | sfdisfil<br />
0: 1 2 1 2 1<br />
5: 2 1 2 1 2<br />
10: 1 2 1 2 1<br />
15: 2 1 2 1 2<br />
20: 1 2 1 2 1<br />
25: 2 1 2 1 2<br />
30: 1 2 1 2 1<br />
35: 2 1 2 1 2<br />
40: 1 2 1 2 1<br />
45: 2 1 2 1 2<br />
bash$ sfinterleave < one.rsf two.rsf axis=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 1 1 1 1 1<br />
15: 2 2 2 2 2<br />
20: 1 1 1 1 1<br />
25: 2 2 2 2 2<br />
30: 1 1 1 1 1<br />
35: 2 2 2 2 2<br />
40: 1 1 1 1 1<br />
45: 2 2 2 2 2<br />
</pre><br />
<br />
==sfmask==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a mask.<br />
|-<br />
! colspan="4" | sfmask < in.rsf > out.rsf min=-FLT_MAX max=+FLT_MAX<br />
|-<br />
| colspan="4" | <br>Mask is an integer data with ones and zeros. <br>Ones correspond to input values between min and max.<br><br>The output can be used with sfheaderwindow.<br />
|-<br />
| ''float '' || '''max=+FLT_MAX''' || || maximum header value<br />
|-<br />
| ''float '' || '''min=-FLT_MAX''' || || minimum header value<br />
|}<br />
<br />
<br />
<tt>sfmask</tt> creates an integer output of ones and zeros comparing<br />
the values of the input data to specified <tt>min=</tt> and<br />
<tt>max=</tt> parameters. It is useful for <tt>sfheaderwindow</tt> and<br />
in many other applications. Here is a quick example:<br />
<pre><br />
bash$ sfmath n1=10 output="sin(x1)" > sin.rsf<br />
bash$ < sin.rsf sfdisfil<br />
0: 0 0.8415 0.9093 0.1411 -0.7568<br />
5: -0.9589 -0.2794 0.657 0.9894 0.4121<br />
bash$ < sin.rsf sfmask min=-0.5 max=0.5 | sfdisfil<br />
0: 1 0 0 1 0 0 1 0 0 1<br />
</pre><br />
<br />
==sfmath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations on data files.<br />
|-<br />
! colspan="4" | sfmath > out.rsf type= unit= output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs, conj (for complex data).<br> <br>sfmath will work on float or complex data, but all the input and output<br>files must be of the same data type.<br><br>An alternative to sfmath is sfadd, which may be more efficient, but is<br>less versatile.<br><br>Examples:<br><br>sfmath x=file1.rsf y=file2.rsf power=file3.rsf output='sin((x+2*y)^power)' > out.rsf<br>sfmath < file1.rsf tau=file2.rsf output='exp(tau*input)' > out.rsf<br>sfmath n1=100 type=complex output="exp(I*x1)" > out.rsf<br><br>See also: sfheadermath.<br />
|-<br />
| ''string '' || '''output=''' || || Mathematical description of the output<br />
|-<br />
| ''string '' || '''type=''' || || output data type [float,complex]<br />
|-<br />
| ''string '' || '''unit=''' || || <br />
|}<br />
<br />
<tt>sfmath</tt> is a versatile program for mathematical operations<br />
with RSF files. It can operate with several input file, all of the<br />
same dimensions and data type. The data type can be real (floating<br />
point) or complex. Here is an example that demonstrates several<br />
features of <tt>sfmath</tt>.<br />
<pre><br />
bash$ sfmath n1=629 d1=0.01 o1=0 n2=40 d2=1 o2=5 \<br />
output="x2*(8+sin(6*x1+x2/10))" > rad.rsf<br />
bash$ < rad.rsf sfrtoc | sfmath output="input*exp(I*x1)" > rose.rsf<br />
bash$ < rose.rsf sfgraph title=Rose screenratio=1 wantaxis=n | xtpen<br />
</pre><br />
The first line creates a 2-D dataset that consists of 40 traces 600<br />
samples each. The values of the data are computed with the formula<br />
<font color="#cd4b19">"x2*(8+sin(6*x1+x2/10))"</font>, where <tt>x1</tt> refers to the<br />
coordinate on the first axis, and <tt>x2</tt> is the coordinate of the<br />
second axis. In the second line, we convert the data from real to<br />
complex using <tt>sfrtoc</tt> and produce a complex dataset using<br />
formula <font color="#cd4b19">"input*exp(I*x1)"</font>, where <tt>input</tt> refers to the<br />
input file. Finally, we plot the complex data as a collection of<br />
parametric curves using <tt>sfgraph</tt> and display the result using<br />
<tt>xtpen</tt>. The plot appearing on your screen should look similar<br />
to the figure.<br />
[[Image:rose.png|frame|center|This figure was created with <tt>sfmath</tt>.]]<br />
One possible alternative to the second line above is<br />
<pre><br />
bash$ < rad.rsf sfmath output=x1 > ang.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*cos(a)" > cos.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*sin(a)" > sin.rsf<br />
bash$ sfcmplx cos.rsf sin.rsf > rose.rsf<br />
</pre><br />
Here we refer to input files by names (<tt>r</tt> and <tt>a</tt>) and combine the names in a formula.<br />
<br />
==sfpad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Pad a dataset with zeros.<br />
|-<br />
! colspan="4" | sfpad < in.rsf > out.rsf [beg1= beg2= ... end1= end2=... | n1= n2 = ... | n1out= n2out= ...]<br />
|-<br />
| colspan="4" | begN specifies the number of zeros to add before the beginning of axis N.<br>endN specifies the number of zeros to add after the end of axis N.<br><br>Alternatively:<br><br>nN or nNout specify the output length of axis N, padding occurs at the end.<br>nN and nNout are equivalent.<br />
|}<br />
<br />
<br />
<tt>pad</tt> increases the dimensions of the input dataset by padding<br />
the data with zeroes. Here are some simple examples.<br />
<pre><br />
bash$ sfspike n1=5 n2=3 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
bash$ < one.rsf sfpad n2=5 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 0 0 0 0 0<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfpad beg2=2 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 0 0 0 0<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < one.rsf sfpad beg2=1 end2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfwindow n1=3 | sfpad n1=5 n2=5 beg1=1 beg2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 1 1 1 0<br />
10: 0 1 1 1 0<br />
15: 0 1 1 1 0<br />
20: 0 0 0 0 0<br />
</pre><br />
You can use <tt>sfcat</tt> to pad data with values other than zeroes.<br />
<br />
==sfput==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Input parameters into a header. <br />
|-<br />
! colspan="4" | sfput < in.rsf > out.rsf<br />
|}<br />
<br />
<br />
<tt>sfput</tt> is a very simple program. It simply appends parameters<br />
from the command line to the output RSF file. One can achieve similar<br />
results with editing by hand or with standard Unix utilities like<br />
<tt>sed</tt> and <tt>echo</tt>. <tt>sfput</tt> is sometimes more<br />
convenient because it handles input/output operations similarly to<br />
other regular RSF programs.<br />
<pre><br />
bash$ sfspike n1=10 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
10 elements 40 bytes<br />
bash$ sfput < spike.rsf d1=25 label1=Depth unit1=m > spike2.rsf<br />
bash$ sfin spike2.rsf<br />
spike2.rsf:<br />
in="/tmp/spike2.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=25 o1=0 label1="Depth" unit1="m"<br />
10 elements 40 bytes<br />
</pre><br />
<br />
==sfreal==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extract real (sfreal) or imaginary (sfimag) part of a complex dataset. <br />
|-<br />
! colspan="4" | sfreal < cmplx.rsf > real.rsf<br />
|}<br />
<br />
<br />
<tt>sfreal</tt> extracts the real part of a complex type dataset. The<br />
imaginary part can be extracted with <tt>sfimag</tt>, an the real<br />
and imaginary part can be combined together with <tt>sfcmplx</tt>.<br />
Here is a simple example. Let us first create a complex dataset <br />
with <tt>sfmath</tt><br />
<pre><br />
bash$ sfmath n1=10 type=complex output="(2+I)*x1" > cmplx.rsf<br />
bash$ fdisfil < cmplx.rsf<br />
0: 0, 0i 2, 1i 4, 2i<br />
3: 6, 3i 8, 4i 10, 5i<br />
6: 12, 6i 14, 7i 16, 8i<br />
9: 18, 9i<br />
</pre><br />
Extracting the real part with <tt>sfreal</tt>:<br />
<pre><br />
bash$ sfreal < cmplx.rsf | sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
</pre><br />
Extracting the imaginary part with <tt>sfimag</tt>:<br />
<pre><br />
bash$ sfimag < cmplx.rsf | sfdisfil<br />
0: 0 1 2 3 4<br />
5: 5 6 7 8 9<br />
</pre><br />
<br />
==sfreverse==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Reverse one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfreverse < in.rsf > out.rsf which=-1 verb=false memsize=sf_memsize() opt=<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''opt=''' || || If y, change o and d parameters on the reversed axis;<br />
:if i, don't change o and d<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|-<br />
| ''int '' || '''which=-1''' || || Which axis to reverse.<br />
:To reverse a given axis, start with 0,<br />
:add 1 to number to reverse n1 dimension,<br />
:add 2 to number to reverse n2 dimension,<br />
:add 4 to number to reverse n3 dimension, etc.<br />
:Thus, which=7 would reverse the first three dimensions,<br />
:which=5 just n1 and n3, etc.<br />
:which=0 will just pass the input on through unchanged.<br />
|}<br />
Here is an example of using <tt>sfreverse</tt>. First, let us create a<br />
2-D dataset.<br />
<pre><br />
bash$ sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Reversing the first axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 | sfdisfil<br />
0: 4 3 2 1 0<br />
5: 5 4 3 2 1<br />
10: 6 5 4 3 2<br />
</pre><br />
Reversing the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=2 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
Reversing both the first and the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=3 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
As you can see, the <tt>which=</tt> parameter controls the axes that are<br />
being reversed by encoding them into one number.<br />
When an axis is reversed, what happens with its axis origin and<br />
sampling parameters? This behavior is controlled by <tt>opt=</tt>. In<br />
our example,<br />
<pre><br />
bash$ < test.rsf sfget n1 o1 d1<br />
n1=5<br />
o1=0<br />
d1=1<br />
bash$ < test.rsf sfreverse which=1 | sfget o1 d1<br />
o1=4<br />
d1=-1<br />
</pre><br />
The default behavior (equivalent to <tt>opt=y</tt>) puts the origin<br />
<tt>o1</tt> at the end of the axis and reverses the sampling parameter<br />
<tt>d1</tt>. Using <tt>opt=n</tt> preserves the sampling but reverses<br />
the origin.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=n | sfget o1 d1<br />
o1=-4<br />
d1=1<br />
</pre><br />
Using <tt>opt=i</tt> preserves both the sampling and the origin while<br />
reversing the axis.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=i | sfget o1 d1<br />
o1=0<br />
d1=1<br />
</pre><br />
One of the three possible behaviors may be desirable depending on the<br />
application.<br />
<br />
==sfrm==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Remove RSF files together with their data.<br />
|-<br />
! colspan="4" | sfrm file1.rsf [file2.rsf ...] [-i] [-v] [-f] <br />
|-<br />
| colspan="4" | Mimics the standard Unix rm command.<br><br>See also: sfmv, sfcp.<br />
|}<br />
<br />
<tt>sfrm</tt> is a program for removing RSF files. Its arguments mimic<br />
the arguments of the standard Unix <tt>rm</tt> utility: <tt>-v</tt><br />
for verbosity, <tt>-i</tt> for interactive inquiry, <tt>-f</tt> for<br />
force removal of suspicious files. Unlike the Unix <tt>rm</tt>,<br />
<tt>sfrm</tt> removes both the RSF header files and the binary files<br />
that the headers point to. <br />
Example:<br />
<pre><br />
bash&#36; sfspike n1=10 > spike.rsf datapath=./<br />
bash&#36; sfget in < spike.rsf<br />
in=./spike.rsf@<br />
bash&#36; ls spike*<br />
spike.rsf spike.rsf@<br />
bash&#36; sfrm -v spike.rsf<br />
sfrm: sf_rm: Removing header spike.rsf<br />
sfrm: sf_rm: Removing data ./spike.rsf@<br />
bash&#36; ls spike*<br />
ls: No match.<br />
</pre><br />
==sfrotate==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Rotate a portion of one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfrotate < in.rsf > out.rsf verb=n memsize=sf_memsize() rot#=(0,0,...)<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''rot#=(0,0,...)''' || || length of #-th axis that is moved to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<tt>sfrotate</tt> modifies the input dataset by splitting it into<br />
parts and putting the parts back in a different order. Here is a quick example.<br />
<pre><br />
bash&#36; sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Rotating the first axis by putting the last two columns in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=2 | sfdisfil<br />
0: 3 4 0 1 2<br />
5: 4 5 1 2 3<br />
10: 5 6 2 3 4<br />
</pre><br />
Rotating the second axis by putting the last row in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot2=1 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 0 1 2 3 4<br />
10: 1 2 3 4 5<br />
</pre><br />
Rotating both the first and the second axis:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=3 rot2=1 | sfdisfil<br />
0: 4 5 6 2 3<br />
5: 2 3 4 0 1<br />
10: 3 4 5 1 2<br />
</pre><br />
The transformation is shown schematically in Figure~(fig:rotate).<br />
[[Image:rotate.png|frame|center|Schematic transformation of data with <tt>sfrotate</tt>.]]<br />
<br />
==sfrtoc==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert real data to complex (by adding zero imaginary part).<br />
|-<br />
! colspan="4" | sfrtoc < real.rsf > cmplx.rsf<br />
|-<br />
| colspan="4" | <br>See also: sfcmplx<br />
|}<br />
The input to <tt>sfrtoc</tt> can be any <tt>type=float</tt> dataset:<br />
<pre><br />
bash$ sfspike n1=10 n2=20 n3=30 >real.rsf<br />
bash$ sfin real.rsf<br />
real.rsf:<br />
in="/var/tmp/real.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
</pre><br />
The output dataset will have <tt>type=complex</tt>, and its binary will be twice the size of the input:<br />
<pre><br />
bash$ <real.rsf sfrtoc >complex.rsf<br />
bash$ sfin complex.rsf <br />
complex.rsf:<br />
in="/var/tmp/complex.rsf@"<br />
esize=8 type=complex form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 48000 bytes<br />
</pre><br />
<br />
==sfscale==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Scale data.<br />
|-<br />
! colspan="4" | sfscale < in.rsf > out.rsf axis=0 rscale=0. dscale=1.<br />
|-<br />
| colspan="4" | <br>To scale by a constant factor, you can also use sfmath or sfheadermath.<br />
|-<br />
| ''int '' || '''axis=0''' || || Scale by maximum in the dimensions up to this axis.<br />
|-<br />
| ''float '' || '''dscale=1.''' || || Scale by this factor (works if rscale=0)<br />
|-<br />
| ''float '' || '''rscale=0.''' || || Scale by this factor.<br />
|}<br />
<tt>sfscale</tt> scales the input dataset by a factor. Here<br />
are some simple examples. First, let us create a test dataset.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil <br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Scale every data point by 2:<br />
<pre><br />
bash&#36; < test.rsf sfscale dscale=2 | sfdisfil<br />
0: 2 4 6 8 10<br />
5: 4 8 12 16 20<br />
10: 6 12 18 24 30<br />
</pre><br />
Divide every trace by its maximum value:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=1 | sfdisfil<br />
0: 0.2 0.4 0.6 0.8 1<br />
5: 0.2 0.4 0.6 0.8 1<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
Divide by the maximum value in the whole 2-D dataset:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=2 | sfdisfil<br />
0: 0.06667 0.1333 0.2 0.2667 0.3333<br />
5: 0.1333 0.2667 0.4 0.5333 0.6667<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
The <tt>rscale=</tt> parameter is synonymous to <tt>dscale=</tt> except<br />
when it is equal to zero. With <tt>sfscale dscale=0</tt>, the dataset gets<br />
multiplied by zero. If using <tt>rscale=0</tt>, the other parameters are<br />
used to define scaling. Thus, <tt>sfscale rscale=0 axis=1</tt> is<br />
equivalent to <tt>sfscale axis=1</tt>, and <tt>sfscale rscale=0</tt><br />
is equivalent to <tt>sfscale dscale=1</tt>.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
==sfspike==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate simple data: spikes, boxes, planes, constants.<br />
|-<br />
! colspan="4" | sfspike > spike.rsf mag= nsp=1 k#=[0,...] l#=[k1,k2,...] p#=[0,...] n#= o#=(0,...) d#=(0.004,0.1,0.1,...) label#=(Time,Distance,Distance,...) unit#=[s,km,km,...] title=<br />
|-<br />
| ''float '' || '''d#=(0.004,0.1,0.1,...)''' || || sampling on #-th axis<br />
|-<br />
| ''ints '' || '''k#=[0,...]''' || || spike starting position [nsp]<br />
|-<br />
| ''ints '' || '''l#=[k1,k2,...]''' || || spike ending position [nsp]<br />
|-<br />
| ''string '' || '''label#=(Time,Distance,Distance,...)''' || || label on #-th axis<br />
|-<br />
| ''floats '' || '''mag=''' || || spike magnitudes [nsp]<br />
|-<br />
| ''int '' || '''n#=''' || || dimension of #-th axis<br />
|-<br />
| ''int '' || '''nsp=1''' || || Number of spikes<br />
|-<br />
| ''float '' || '''o#=(0,...)''' || || origin on #-th axis<br />
|-<br />
| ''floats '' || '''p#=[0,...]''' || || spike inclination (in samples) [nsp]<br />
|-<br />
| ''string '' || '''title=''' || || title for plots<br />
|-<br />
| ''string '' || '''unit#=[s,km,km,...]''' || || unit on #-th axis<br />
|}<br />
This is the program for creating a RSF hypercube out of nothing. Calling <tt>sfspike</tt> without specifying the k# or l# parameters will result in a volume filled with values specified by <tt>mag</tt>. To get a file full of 1's, just give <tt>sfspike</tt> the axis values that running <tt>sfin</tt> on your desired output would produce. I.e. if you run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" > out.rsf<br />
</pre><br />
you will obtain the following file:<br />
<pre><br />
bash$ sfin out.rsf<br />
out.rsf:<br />
in="/var/tmp/out.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
300 elements 1200 bytes<br />
</pre><br />
To create a "flat reflector" in the file above, run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5> out2.rsf<br />
</pre><br />
Notice that the values for <tt>k</tt> and <tt>l</tt> are in samples, not in the physical units of the respective axes. The result can be visualised with <br />
<pre><br />
< out2.rsf sfgrey pclip=100 wantscalebar=y title="Illustration of k,l parameters" | xtpen<br />
</pre><br />
which produces the following plot:<br />
<br />
[[Image:sfspike_fig1.png]]<br />
<br />
The <tt>p</tt> parameters can be used to create slanted lines/planes. Specifying <tt>p2=1</tt> means that for each lateral step, the spike will be shifted down with 1 sample. Below is the command and the corresponding graphical output it creates:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=1 |\<br />
sfgrey pclip=100 wantscalebar=y title="Effect of p2=1" | xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig2.png]]<br />
<br />
Sfspike also supports negative and non-integer p values:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=-0.15 |\<br />
sfgrey pclip=100 wantscalebar=y allpos=y color=h title="Effect of p2=-0.15" |xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig3.png]]<br />
<br />
When <tt>nsp</tt> is greater than the number of values for <tt>k</tt> and <tt>l</tt> parameters, the extra spikes will be piled on top of the last one, increasing its amplitude. Look at the amplitude of the last event in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=3 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
and in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=5 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
(pictures coming soon). This feature can easily cause a bug when the number of events is large and they have not been properly counted, or when a new spike was added on a list but <tt>nsp</tt> was not updated.<br />
<br />
==sfspray==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extend a dataset by duplicating in the specified axis dimension.<br />
|-<br />
! colspan="4" | sfspray < in.rsf > out.rsf axis=2 n= d= o= label= unit=<br />
|-<br />
| colspan="4" | This operation is adjoint to sfstack.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to spray<br />
|-<br />
| ''float '' || '''d=''' || || Sampling of the newly created dimension<br />
|-<br />
| ''string '' || '''label=''' || || Label of the newly created dimension<br />
|-<br />
| ''int '' || '''n=''' || || Size of the newly created dimension<br />
|-<br />
| ''float '' || '''o=''' || || Origin of the newly created dimension<br />
|-<br />
| ''string '' || '''unit=''' || || Units of the newly created dimension<br />
|}<br />
<br />
<tt>sfspray</tt> extends the input hypercube by replicating the data<br />
in one of the dimensions. The output dataset acquires one additional<br />
dimension. Here is an example:<br />
Start with a 2-D dataset<br />
<pre><br />
bash&#36; sfmath n1=5 n2=2 output=x1+x2 > test.rsf<br />
bash&#36; sfin test.rsf<br />
test.rsf:<br />
in="/var/tmp/test.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
10 elements 40 bytes<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
</pre><br />
Extend the data in the second dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=2 n=3 > test2.rsf<br />
bash&#36; sfin test2.rsf<br />
test2.rsf:<br />
in="/var/tmp/test2.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=3 d2=1 o2=0 <br />
n3=2 d3=1 o3=0 <br />
30 elements 120 bytes<br />
bash&#36; < test2.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 0 1 2 3 4<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
20: 1 2 3 4 5<br />
25: 1 2 3 4 5<br />
</pre><br />
The output is three-dimensional, with traces from the original<br />
data duplicated along the second axis.<br />
Extend the data in the third dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=3 n=2 > test3.rsf<br />
bash&#36; sfin test3.rsf<br />
test3.rsf:<br />
in="/var/tmp/test3.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
n3=2 d3=? o3=? <br />
20 elements 80 bytes<br />
bash&#36; < test3.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
</pre><br />
The output is also three-dimensional, with the original data replicated<br />
along the third axis.<br />
<br />
==sfstack==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stack a dataset over one of the dimensions.<br />
|-<br />
! colspan="4" | sfstack < in.rsf > out.rsf axis=2 rms=n norm=y min=n max=n<br />
|-<br />
| colspan="4" | <br>This operation is adjoint to sfspray.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to stack<br />
|-<br />
| ''bool '' || '''max=n''' || [y/n] || If y, find maximum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''min=n''' || [y/n] || If y, find minimum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || If y, normalize by fold.<br />
|-<br />
| ''bool '' || '''rms=n''' || [y/n] || If y, compute the root-mean-square instead of stack.<br />
|}<br />
While <tt>sfspray</tt> adds a dimension to a hypercube,<br />
<tt>sfstack</tt> effectively removes one of the dimensions by stacking<br />
over it. Here are some examples:<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
bash&#36; < test.rsf sfstack axis=2 | sfdisfil<br />
0: 1.5 2 3 4 5<br />
bash&#36; < test.rsf sfstack axis=1 | sfdisfil<br />
0: 2.5 3 4<br />
</pre><br />
Why is the first value not 1 (in the first case) or 2 (in the second<br />
case)? By default, <tt>sfstack</tt> normalizes the stack by the fold<br />
(the number of non-zero entries). To avoid normalization, use<br />
<tt>norm=n</tt>, as follows:<br />
<pre><br />
bash&#36; < test.rsf sfstack norm=n | sfdisfil <br />
0: 3 6 9 12 15<br />
</pre><br />
<tt>sfstack</tt> can also compute root-mean-square values as <br />
well as minimum and maximum values.<br />
<pre><br />
bash&#36; < test.rsf sfstack rms=y | sfdisfil<br />
0: 1.581 2.16 3.109 4.082 5.066<br />
bash&#36; < test.rsf sfstack min=y | sfdisfil<br />
0: 0 1 2 3 4<br />
bash&#36; < test.rsf sfstack axis=1 max=y | sfdisfil <br />
0: 4 5 6<br />
</pre><br />
<br />
==sftransp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Transpose two axes in a dataset. <br />
|-<br />
! colspan="4" | sftransp < in.rsf > out.rsf memsize=sf_memsize() plane=<br />
|-<br />
| colspan="4" | <br>If you get a "Cannot allocate memory" error, give the program a<br>memsize=1 command-line parameter to force out-of-core operation.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''plane=''' || || Two-digit number with axes to transpose. The default is 12<br />
|}<br />
<br />
The <tt>sftransp</tt> program transposes the input hypercube<br />
exchanging the two axes specified by the <b>plane=</b> parameter. <br />
<pre><br />
bash&#36; sfspike n1=10 n2=20 n3=30 > orig123.rsf<br />
bash&#36; sfin orig123.rsf <br />
orig123.rsf:<br />
in="/var/tmp/orig123.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=23 >out132.rsf<br />
bash&#36; sfin out132.rsf <br />
out132.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=20 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=13 >out321.rsf<br />
bash&#36; sfin out321.rsf <br />
out321.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=30 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=10 d3=0.004 o3=0 label3="Time" unit3="s" <br />
6000 elements 24000 bytes<br />
</pre><br />
<tt>sftransp</tt> tries to fit the dataset in memory to transpose it<br />
there but, if not enough memory is available, it performs a slower<br />
transpose out of core using disk operations. You can control the<br />
amount of available memory using the <b>memsize=</b> parameter or<br />
the <b>RSFMEMSIZE</b> environmental variable.<br />
<br />
==sfwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a portion of the dataset. <br />
|-<br />
! colspan="4" | sfwindow < in.rsf > out.rsf verb=n squeeze=y j#=(1,...) d#=(d1,d2,...) f#=(0,...) min#=(o1,o2,,...) n#=(0,...) max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)<br />
|-<br />
| ''float '' || '''d#=(d1,d2,...)''' || || sampling in #-th dimension<br />
|-<br />
| ''int '' || '''f#=(0,...)''' || || window start in #-th dimension<br />
|-<br />
| ''int '' || '''j#=(1,...)''' || || jump in #-th dimension<br />
|-<br />
| ''float '' || '''max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)''' || || maximum in #-th dimension<br />
|-<br />
| ''float '' || '''min#=(o1,o2,,...)''' || || minimum in #-th dimension<br />
|-<br />
| ''int '' || '''n#=(0,...)''' || || window size in #-th dimension<br />
|-<br />
| ''bool '' || '''squeeze=y''' || [y/n] || if y, squeeze dimensions equal to 1 to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
<b>sfwindow</b> is used to window a portion of the dataset. Here is<br />
a quick example: Start by creating some data.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Now window the first two rows:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n2=2 | sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
</pre><br />
Window the first three columns:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n1=3 | sfdisfil<br />
0: 1 2 3 2 4<br />
5: 6 3 6 9<br />
</pre><br />
Window the middle row:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f2=1 n2=1 | sfdisfil<br />
0: 2 4 6 8 10<br />
</pre><br />
You can interpret the <b>f#</b> and <b>n#</b> parameters as<br />
meaning "skip that many rows/columns" and "select that many<br />
rows/columns" correspondingly. Window the middle point in the dataset:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f1=2 n1=1 f2=1 n2=1 | sfdisfil<br />
0: 6<br />
</pre><br />
Window every other column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=2 | sfdisfil<br />
0: 1 3 5 2 6<br />
5: 10 3 9 15<br />
</pre><br />
Window every third column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=3 | sfdisfil<br />
0: 1 4 2 8 3<br />
5: 12<br />
</pre><br />
Alternatively, <b>sfwindow</b> can use the minimum and maximum<br />
parameters to select a window. In the following example, we are<br />
creating a dataset with <b>sfspike</b> and then windowing a portion of it<br />
between 1 and 2 seconds in time and sampled at 8 miliseconds.<br />
<pre><br />
bash&#36; sfspike n1=1000 n2=10 > spike.rsf <br />
bash&#36; sfin spike.rsf<br />
spike.rsf:<br />
in="/var/tmp/spike.rsf@"<br />
esize=4 type=float form=native <br />
n1=1000 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10000 elements 40000 bytes<br />
bash&#36; < spike.rsf sfwindow min1=1 max1=2 d1=0.008 > window.rsf<br />
bash&#36; sfin window.rsf<br />
window.rsf:<br />
in="/var/tmp/window.rsf@"<br />
esize=4 type=float form=native <br />
n1=126 d1=0.008 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
1260 elements 5040 bytes<br />
</pre><br />
By default, <b>sfwindow</b> "squeezes" the hypercube dimensions<br />
that are equal to one toward the end of the dataset. Here is an<br />
example of taking a time slice:<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=1 d2=0.004 o2=1 label2="Time" unit2="s" <br />
10 elements 40 bytes<br />
</pre><br />
You can change this behavior by specifying <b>squeeze=n</b>.<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 squeeze=n > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=1 d1=0.004 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10 elements 40 bytes<br />
</pre><br />
<br />
=Seismic programs=<br />
Programs in this category are specific for operations on seismic data. The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/seismic/ system/seismic] in the Madagascar distribution.<br />
<br />
==sfheaderattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Integer header attributes. <br />
|-<br />
! colspan="4" | sfheaderattr < head.rsf<br />
|-<br />
| colspan="4" | <br>Only nonzero values are reported.<br />
|}<br />
<br />
The <tt>sfheaderattr</tt> examines the contents of a trace header file,<br />
typically generated by <tt>sfsegyread</tt>. In the example below, we examine<br />
trace headers in the output of <tt>suplane</tt>, a program from Seismic Unix.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
bash$ sfheaderattr < tfile.rsf<br />
*******************************************<br />
71 headers, 32 traces<br />
key[0]="tracl" min[0]=1 max[31]=32 mean=16.5<br />
key[1]="tracr" min[0]=1 max[31]=32 mean=16.5<br />
key[11]="offset" min[0]=400 max[31]=400 mean=400<br />
key[38]="ns" min[0]=64 max[31]=64 mean=64<br />
key[39]="dt" min[0]=4000 max[31]=4000 mean=4000<br />
*******************************************<br />
</pre><br />
For different standard keywords, a minimum, maximum, and mean values<br />
are reported unless they are identically zero. This quick inspection<br />
can help in identifying meaningful keywords set in the data. The input<br />
data type must be <tt>int</tt>.<br />
<br />
==sfheadermath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations, possibly on header keys. <br />
|-<br />
! colspan="4" | sfheadermath < in.rsf > out.rsf memsize=sf_memsize() output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs<br><br>See also sfmath. <br><br>An addition operation can be performed by sfstack.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''output=''' || || Describes the output in a mathematical notation.<br />
|}<br />
<tt>sfheadermath</tt> is a versatile program for mathematical<br />
operations on rows of the input file. If the input file is an<br />
<tt>n1</tt> by <tt>n2</tt> matrix, the output will be a <tt>1</tt> by<br />
<tt>n2</tt> matrix that contains one row made out of mathematical<br />
operations on the other rows. <tt>sfheadermath</tt> can identify a row<br />
by number or by a standard SEGY keyword. The latter is useful for<br />
processing headers extracted from SEGY or SU files.<br />
Here is an example. First, we create an SU file with <tt>suplane</tt> and convert it to RSF using <tt>sfsegyread</tt>.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
</pre><br />
The trace header information is saved in <tt>tfile.rsf</tt>. It<br />
contains 71 headers for 32 traces in integer format.<br />
<pre><br />
bash$ sfin tfile.rsf<br />
tfile.rsf:<br />
in="/tmp/tfile.rsf@"<br />
esize=4 type=int form=native<br />
n1=71 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
2272 elements 9088 bytes<br />
</pre><br />
Next, we will convert <tt>tfile.rsf</tt> to a floating-point format<br />
and run <tt>sfheadermath</tt> to create a new header.<br />
<pre><br />
bash$ < tfile.rsf sfdd type=float | \<br />
sfheadermath myheader=1 output="sqrt(myheader+(2+10*offset^2))" > new.rsf<br />
bash$ sfin new.rsf<br />
new.rsf:<br />
in="/tmp/new.rsf@"<br />
esize=4 type=float form=native<br />
n1=1 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
32 elements 128 bytes<br />
</pre><br />
We defined "myheader" as being the row number 1 in the input (note<br />
that numbering starts with 0) and combined it with "offset", which<br />
is a standard SEGY keyword that denotes row number 11 (see the output<br />
of <tt>sfheaderattr</tt> above.) A variety of mathematical expressions<br />
can be defined in the <tt>output=</tt> string. The expression<br />
processing engine is shared with <tt>sfmath</tt>.<br />
<br />
==sfsegyheader==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Make a trace header file for segywrite.<br />
|-<br />
! colspan="4" | sfsegyheader < in.rsf > out.rsf n1= d1=<br />
|-<br />
| colspan="4" | <br> Use the output for tfile= argument in segywrite.<br />
|-<br />
| ''float '' || '''d1=''' || || trace sampling<br />
|-<br />
| ''int '' || '''n1=''' || || number of samples in a trace<br />
|}<br />
<br />
==sfsegyread==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert a SEG-Y or SU dataset to RSF.<br />
|-<br />
! colspan="4" | sfsegyread mask=msk.rsf > out.rsf tfile=hdr.rsf verb=false su=false format=sf_segyformat (bhead) ns=sf_segyns (bhead) endian= tape= read= hfile= bfile= mask= tfile=<br />
|-<br />
| colspan="4" | <br>Data headers and trace headers are separated from the data.<br><br>Defined SEG-Y trace header key names and byte offsets:<br><br>tracl: trace sequence number within line 0<br><br>tracr: trace sequence number within reel 4<br><br>fldr: field record number 8 <br><br>tracf: trace number within field record 12 <br><br>ep: energy source point number 16 <br><br>cdp: CDP ensemble number 20 <br><br>cdpt: trace number within CDP ensemble 24 <br><br>trid: trace identification code:<br>1 = seismic data<br>2 = dead<br>3 = dummy<br>4 = time break<br>5 = uphole<br>6 = sweep<br>7 = timing<br>8 = water break<br>9---, N = optional use (N = 32,767) 28 <br><br>nvs: number of vertically summed traces 30 <br><br>nhs: number of horizontally summed traces 32 <br><br>duse: data use:<br>1 = production<br>2 = test 34<br><br>offset: distance from source point to receiver<br>group (negative if opposite to direction<br>in which the line was shot) 36 <br><br>gelev: receiver group elevation from sea level<br>(above sea level is positive) 40 <br><br>selev: source elevation from sea level<br>(above sea level is positive) 44 <br><br>sdepth: source depth (positive) 48 <br><br>gdel: datum elevation at receiver group 52 <br><br>sdel: datum elevation at source 56 <br><br>swdep: water depth at source 60 <br><br>gwdep: water depth at receiver group 64 <br><br>scalel: scale factor for previous 7 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 68 <br><br>scalco: scale factor for next 4 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 70 <br><br>sx: X source coordinate 72 <br><br>sy: Y source coordinate 76 <br><br>gx: X group coordinate 80 <br><br>gy: Y group coordinate 84 <br><br>counit: coordinate units code:<br>for previoius four entries<br>1 = length (meters or feet)<br>2 = seconds of arc (in this case, the<br>X values are unsigned intitude and the Y values<br>are latitude, a positive value designates<br>the number of seconds east of Greenwich<br>or north of the equator 88 <br><br>wevel: weathering velocity 90 <br><br>swevel: subweathering velocity 92 <br><br>sut: uphole time at source 94 <br><br>gut: uphole time at receiver group 96 <br><br>sstat: source static correction 98 <br><br>gstat: group static correction 100 <br><br>tstat: total static applied 102 <br><br>laga: lag time A, time in ms between end of 240-<br>byte trace identification header and time<br>break, positive if time break occurs after<br>end of header, time break is defined as<br>the initiation pulse which maybe recorded<br>on an auxiliary trace or as otherwise<br>specified by the recording system 104 <br><br>lagb: lag time B, time in ms between the time<br>break and the initiation time of the energy source,<br>may be positive or negative 106 <br><br>delrt: delay recording time, time in ms between<br>initiation time of energy source and time<br>when recording of data samples begins<br>(for deep water work if recording does not<br>start at zero time) 108 <br><br>muts: mute time--start 110 <br><br>mute: mute time--end 112 <br><br>ns: number of samples in this trace 114 <br><br>dt: sample interval, in micro-seconds 116 <br><br>gain: gain type of field instruments code:<br>1 = fixed<br>2 = binary<br>3 = floating point<br>4 ---- N = optional use 118 <br><br>igc: instrument gain constant 120 <br><br>igi: instrument early or initial gain 122 <br><br>corr: correlated:<br>1 = no<br>2 = yes 124 <br><br>sfs: sweep frequency at start 126 <br><br>sfe: sweep frequency at end 128 <br><br>slen: sweep length in ms 130 <br><br>styp: sweep type code:<br>1 = linear<br>2 = cos-squared<br>3 = other 132 <br><br>stas: sweep trace length at start in ms 134 <br><br>stae: sweep trace length at end in ms 136 <br><br>tatyp: taper type: 1=linear, 2=cos^2, 3=other 138 <br><br>afilf: alias filter frequency if used 140 <br><br>afils: alias filter slope 142 <br><br>nofilf: notch filter frequency if used 144 <br><br>nofils: notch filter slope 146 <br><br>lcf: low cut frequency if used 148 <br><br>hcf: high cut frequncy if used 150 <br><br>lcs: low cut slope 152 <br><br>hcs: high cut slope 154 <br><br>year: year data recorded 156 <br><br>day: day of year 158 <br><br>hour: hour of day (24 hour clock) 160 <br><br>minute: minute of hour 162 <br><br>sec: second of minute 164 <br><br>timbas: time basis code:<br>1 = local<br>2 = GMT<br>3 = other 166 <br><br>trwf: trace weighting factor, defined as 1/2^N<br>volts for the least sigificant bit 168 <br><br>grnors: geophone group number of roll switch<br>position one 170 <br><br>grnofr: geophone group number of trace one within<br>original field record 172 <br><br>grnlof: geophone group number of last trace within<br>original field record 174 <br><br>gaps: gap size (total number of groups dropped) 176 <br><br>otrav: overtravel taper code:<br>1 = down (or behind)<br>2 = up (or ahead)<br />
|-<br />
| ''string '' || '''bfile=''' || || output binary data header file<br />
|-<br />
| ''bool '' || '''endian=''' || [y/n] || big/little endian flag, the default is estimated automatically<br />
|-<br />
| ''int '' || '''format=sf_segyformat (bhead)''' || [1,2,3,5] || Data format. The default is taken from binary header.<br />
:1 is IBM floating point<br />
:2 is 4-byte integer<br />
:3 is 2-byte integer<br />
:5 is IEEE floating point<br />
|-<br />
| ''string '' || '''hfile=''' || || output text data header file<br />
|-<br />
| ''string '' || '''mask=''' || || optional header mask for reading only selected traces<br />
|-<br />
| ''int '' || '''ns=sf_segyns (bhead)''' || || Number of samples. The default is taken from binary header<br />
|-<br />
| ''string '' || '''read=''' || || what to read: h - header, d - data, b - both (default)<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if input is SU, n if input is SEGY<br />
|-<br />
| ''bool '' || '''suxdr=n''' || [y/n] || y, SU has XDR support<br />
|-<br />
| ''string '' || '''tape=''' || || <br />
|-<br />
| ''string '' || '''tfile=''' || || output trace header file<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
The SEG Y format is an [http://en.wikipedia.org/wiki/Open_standard open standard] for the exchange of geophysical data. It is controlled by the non-profit [http://www.seg.org/SEGportalWEBproject/portals/SEG_Online.portal?_nfpb=true&_pageLabel=pg_gen_content&Doc_Url=prod/SEG-Publications/Pub-Yearbook/committees.htm SEG Technical Standards Committee]. There are two versions of this standard: [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev0.pdf rev0] (1975)<ref>Barry, K.M., Cavers, D.A., and Kneale, C.W. 1975. Recommended standards for digital tape formats. ''Geophysics'', '''40''', no. 02, 344–352.</ref> and [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf rev1] (2002)<ref>Norris, M.W., Faichney, A.K., ''Eds''. 2001. SEG Y rev1 Data Exchange format. Society of Exploration Geophysicists, Tulsa, OK, 45 pp.</ref>. The implementation in <tt>sfsegyread</tt> is a mixture of rev0 (i.e. no checks for Extended Textual Headers) and rev1 ([http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE floating point format] allowed for trace data samples).<br />
<br />
A SEG-Y file as understood by <tt>sfsegyread</tt> contains a "Reel Identification Header" (3200 bytes in EBCDIC followed by 400 bytes in a binary encoding), followed by a number of "Trace Blocks". Each "Trace Block" contains a 240-byte "Trace Header" (binary) followed by "Trace Data" -- a sequence of <tt>ns</tt> samples. Binary values in both reel headers and trace headers are two's complement integers, either two bytes or four bytes long. There are no floating-point values defined in the headers. Trace Data samples can have various encodings, either floating point or integer, described further down, but they are all big-endian. To convert from SEG-Y to RSF, <tt>sfsegyread</tt> will strip the tape reel EBCDIC header and convert it to ASCII, will extract the reel binary header without changing it, and will put the trace headers into one RSF file, and the traces themselves on another.<br />
<br />
===SEG-Y Trace Headers===<br />
In the SEG-Y standard, only the first 180 bytes of the 240-byte trace header are defined; bytes 181-240 are reserved for non-standard header information, and these locations are increasingly used in modern SEG-Y files and its variants. The standard provides for a total of 71 4-byte and 2-byte predefined header words. These 71 standard words have defined lengths and byte offsets, and only these words and byte locations are read using <tt>segyread</tt> and output to the RSF header file with the <tt>hfile=</tt> option. The user may remap these predefined keywords to a different byte offsets.<br />
<br />
===SU File Format===<br />
An [http://www.cwp.mines.edu/sututor/node22.html SU file] is nothing more than a SEG-Y file without the reel headers, and with the Trace Data samples in the native encoding of the CPU the file was created on (Attention -- limited portability!). So, to convert from SU to RSF, <tt>sfsegyread</tt> will just separate headers and traces into two RSF files. <br />
<br />
===SEG-Y specific parameters===<br />
*<tt>hfile=</tt> specifies the name of the file in which the EBCDIC reel header will be put after conversion to ASCII. If you are certain there is no useful information in it, <tt>hfile=/dev/null</tt> works just fine. If you do not specify anything for this parameter you will get an ASCII file named <tt>header</tt> in the current directory. If you want to quickly preview this header before running <tt>sfsegyread</tt>, use<pre>dd if=input.segy count=40 bs=80 cbs=80 conv=unblock,ascii</pre><br />
*<tt>bfile=</tt> specifies name of the file in which the binary reel header (the 400-bytes thing following the 3600-bytes EBCDIC) will be put without any conversion. The default name is "binary". Unless you have software that knows how to read exactly this special type of file, it will be completely useless, so do <tt>bfile=/dev/null</tt><br />
*<tt>format=</tt> specifies the format in which the trace data samples are in the SEG-Y input file. This is read from the binary reel header of the SEG-Y file. Valid values are 1(IBM floating point), 2 (4-byte integer), 3 (2-byte integer) and 5 (IEEE floating point). If the input file is SU, the format will be assumed to be the native <tt>float</tt> format.<br />
<br />
*<tt>keyname=</tt> specifies the byte offset to remap a header using the trace header key names shown above. For example, if the CDP locations have been placed in bytes 181-184 instead of the standard 21-24, <tt>cdp=180</tt> will remap the trace header to that location. <br />
<br />
===SU-specific parameters===<br />
*<tt>suxdr=</tt> specifies whether the input file was created with a SU package with XDR support enabled. If you have access to the source code of your SU install (try <tt>$CWPROOT/src</tt>), type: <tt>grep 'XDRFLAG =' $CWPROOT/src/Makefile.config</tt> and look at the last uncommented entry. If no value is given for <tt>XDRFLAG</tt>, the package was not compiled with XDR support.<br />
===Common parameters===<br />
*<tt>su=</tt> specifies if the input file is SU or SEG-Y. Default is <tt>su=n</tt> (SEG-Y file).<br />
*<tt>tape=</tt> specifies the input data. Stdin could not be used because <tt>sfsegyread</tt> has to work with tapes, and needs to fseek back and forth through the input file. Thankfully, output is on stdout.<br />
*<tt>read=</tt> specifies what parts of the "Trace Blocks" will be read. It can be <tt>read=t</tt> (only trace data is read), <tt>read=h</tt> (only trace headers are read) or <tt>read=b</tt> (both are read).<br />
*<tt>tfile=</tt> gives the name of the RSF file to which trace headers are written. Obviously, it should be only specified with <tt>read=h</tt> or <tt>read=b</tt>.<br />
*<tt>mask=</tt> is an optional parameter specifying the name of a mask that says which traces will be read. The mask is a 1-D RSF file with integers. The number of samples in the mask is the same as the number of traces in the unmasked SEG-Y. In places corresponding to unwanted traces there should be zeros in the mask.<br />
*<tt>ns=</tt> specifies the number of samples in a trace. For SEG-Y files, the default is taken from the binary reel header, and for SU files, from the header of the first trace. This parameter is however critical enough that a command line override was given for it.<br />
*<tt>verbose=</tt> is the verbosity flag. Can be <tt>y</tt> or <tt>n</tt>.<br />
*<tt>endian=</tt> is a y/n flag (default y), specifying whether to automatically estimate or not if samples in the Trace Data blocks are big-endian or little-endian. Try it if you are in trouble and do not know what else to do, otherwise let the automatic estimation do its job.<br />
<br />
==sfsegywrite==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert an RSF dataset to SEGY or SU.<br />
|-<br />
! colspan="4" | sfsegywrite < in.rsf tfile=hdr.rsf verb=false su=false endian=sf_endian() tape= hfile= bfile=<br />
|-<br />
| colspan="4" | <br>Merges trace headers with data.<br />
|-<br />
| ''string '' || '''bfile=''' || || input binary data header file<br />
|-<br />
| ''bool '' || '''endian=sf_endian()''' || [y/n] || big/little endian flag. The default is estimated automatically<br />
|-<br />
| ''string '' || '''hfile=''' || || input text data header file<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if output is SU, n if output is SEGY<br />
|-<br />
| ''string '' || '''tape=''' || ||<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
Please see <tt>sfsegyread</tt> for a complete description of parameter meanings and background issues. Parameters <tt>bfile</tt> and <tt>hfile</tt> should only be given values when the desired file is SEG-Y (default). The output file is specified by the <tt>tape=</tt> tag.<br />
<br />
=Plotting programs=<br />
The source files for these programs can be found under<br />
[http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/plot/main/ plot/main]<br />
in the Madagascar distribution.<br />
<br />
THIS SECTION IS UNDER CONSTRUCTION<br />
<br />
==sfbox==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Draw a balloon-style label.<br />
|-<br />
! colspan="4" | sfbox lab_color=VP_WHITE lab_fat=0 pscale=1. pointer=y reverse=n lat=0. long=90. angle=0. x0=0. y0=0. scale0=1. xt=2. yt=0. x_oval=0. y_oval=0. boxit=y length= scalet= size=.25 label= > out.vpl<br />
|-<br />
| ''float '' || '''angle=0.''' || || longitude of floating label in 3-D<br />
|-<br />
| ''bool '' || '''boxit=y''' || [y/n] || if y, create a box around text<br />
|-<br />
| ''int '' || '''lab_color=VP_WHITE''' || || label color<br />
|-<br />
| ''int '' || '''lab_fat=0''' || || label fatness<br />
|-<br />
| ''string '' || '''label=''' || || text for label<br />
|-<br />
| ''float '' || '''lat=0.''' || || <br />
|-<br />
| ''float '' || '''length=''' || || normalization for xt and yt<br />
|-<br />
| ''float '' || '''long=90.''' || || latitude and longitude of viewpoint in 3-D<br />
|-<br />
| ''bool '' || '''pointer=y''' || [y/n] || if y, create arrow pointer<br />
|-<br />
| ''float '' || '''pscale=1.''' || || scale factor for width of pointer<br />
|-<br />
| ''bool '' || '''reverse=n''' || [y/n] || <br />
|-<br />
| ''float '' || '''scale0=1.''' || || scale factor for x0 and y0<br />
|-<br />
| ''float '' || '''scalet=''' || || <br />
|-<br />
| ''float '' || '''size=.25''' || || text height in inches<br />
|-<br />
| ''float '' || '''x0=0.''' || || <br />
|-<br />
| ''float '' || '''x_oval=0.''' || || <br />
|-<br />
| ''float '' || '''xt=2.''' || || <br />
|-<br />
| ''float '' || '''y0=0.''' || || position of the pointer tip<br />
|-<br />
| ''float '' || '''y_oval=0.''' || || size of the oval around pointer<br />
|-<br />
| ''float '' || '''yt=0.''' || || relative position of text<br />
|}<br />
==sfcontour==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Contour plot.<br />
|-<br />
! colspan="4" | sfcontour < in.rsf c= min1=o1 min2=o2 max1=o1+(n1-1)*d1 max2=o2+(n2-1)*d2 nc=50 dc= c0= transp=y minval= maxval= allpos=y barlabel= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=y''' || [y/n] || contour positive values only<br />
|-<br />
| ''string '' || '''barlabel=''' || || <br />
|-<br />
| ''floats '' || '''c=''' || || [nc]<br />
|-<br />
| ''float '' || '''c0=''' || || first contour<br />
|-<br />
| ''float '' || '''dc=''' || || contour increment<br />
|-<br />
| ''float '' || '''max1=o1+(n1-1)*d1''' || || <br />
|-<br />
| ''float '' || '''max2=o2+(n2-1)*d2''' || || data window to plot<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''min1=o1''' || || <br />
|-<br />
| ''float '' || '''min2=o2''' || || <br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nc=50''' || || number of contours<br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfdots==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot signal with lollipops.<br />
|-<br />
! colspan="4" | sfdots < in.rsf labels= dots=(n1 <= 130)? 1: 0 seemean=(bool) (n2 <= 30) strings=(bool) (n1 <= 400) connect=1 corners= silk=n gaineach=y labelsz=8 yreverse=n constsep=n seedead=n transp=n xxscale=1. yyscale=1. clip=-1. overlap=0.9 screenratio=VP_SCREEN_RATIO screenht=VP_STANDARD_HEIGHT screenwd=screenhigh / screenratio radius=dd1/3 label1= unit1= title= > plot.vpl<br />
|-<br />
| ''float '' || '''clip=-1.''' || || data clip<br />
|-<br />
| ''int '' || '''connect=1''' || || connection type: 1 - diagonal, 2 - bar, 4 - only for non-zero data<br />
|-<br />
| ''bool '' || '''constsep=n''' || [y/n] || if y, use constant trace separation<br />
|-<br />
| ''int '' || '''corners=''' || || number of polygon corners (default is 6)<br />
|-<br />
| ''int '' || '''dots=(n1 <= 130)? 1: 0''' || || type of dots: 1 - baloon, 0 - no dots, 2 - only for non-zero data<br />
|-<br />
| ''bool '' || '''gaineach=y''' || [y/n] || if y, gain each trace independently<br />
|-<br />
| ''string '' || '''label1=''' || || <br />
|-<br />
| ''strings'' || '''labels=''' || || trace labels [n2]<br />
|-<br />
| ''int '' || '''labelsz=8''' || || label size<br />
|-<br />
| ''float '' || '''overlap=0.9''' || || trace overlap<br />
|-<br />
| ''float '' || '''radius=dd1/3''' || || dot radius<br />
|-<br />
| ''float '' || '''screenht=VP_STANDARD_HEIGHT''' || || screen height<br />
|-<br />
| ''float '' || '''screenratio=VP_SCREEN_RATIO''' || || screen aspect ratio<br />
|-<br />
| ''float '' || '''screenwd=screenhigh / screenratio''' || || screen width<br />
|-<br />
| ''bool '' || '''seedead=n''' || [y/n] || if y, show zero traces<br />
|-<br />
| ''bool '' || '''seemean=(bool) (n2 <= 30)''' || [y/n] || if y, draw axis lines<br />
|-<br />
| ''bool '' || '''silk=n''' || [y/n] || if y, silky plot<br />
|-<br />
| ''bool '' || '''strings=(bool) (n1 <= 400)''' || [y/n] || if y, draw strings<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axis<br />
|-<br />
| ''string '' || '''unit1=''' || || <br />
|-<br />
| ''float '' || '''xxscale=1.''' || || x scaling<br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse y axis<br />
|-<br />
| ''float '' || '''yyscale=1.''' || || y scaling<br />
|}<br />
==sfgraph3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot for surfaces.<br />
|-<br />
! colspan="4" | sfgraph3 < in.rsf orient=1 min= max= point1=0.5 point2=0.5 frame1=0.5*(min+max) frame2=n1-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y > plot.vpl<br />
|-<br />
| ''float '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''float '' || '''frame1=0.5*(min+max)''' || || <br />
|-<br />
| ''int '' || '''frame2=n1-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''max=''' || || maximum function value<br />
|-<br />
| ''float '' || '''min=''' || || minimum function value<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''orient=1''' || || function orientation<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|}<br />
==sfgraph==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Graph plot.<br />
|-<br />
! colspan="4" | sfgraph < in.rsf symbolsz= pclip=100. transp=n symbol= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''pclip=100.''' || || clip percentile<br />
|-<br />
| ''string '' || '''symbol=''' || || if set, plot with symbols instead of lines<br />
|-<br />
| ''floats '' || '''symbolsz=''' || || symbol size (default is 2) [n2]<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfgrey3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot.<br />
|-<br />
! colspan="4" | sfgrey3 < in.rsf point1=0.5 point2=0.5 frame1=0 frame2=n2-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y scalebar=n minval= maxval= barreverse=n nreserve=8 bar= color= > plot.vpl<br />
|-<br />
| colspan="4" | Requires an "unsigned char" input (the output of sfbyte).<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''int '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''int '' || '''frame1=0''' || || <br />
|-<br />
| ''int '' || '''frame2=n2-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || if y, draw scalebar<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
for sfgrey and sfgrey3. Examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfgrey==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate raster plot.<br />
|-<br />
! colspan="4" | sfgrey < in.rsf > out.rsf bar=bar.rsf transp=y yreverse=y xreverse=n gpow= phalf= clip= pclip= gainstep=0.5+n1/256. allpos=n bias=0. polarity=n verb=n scalebar=n minval= maxval= barreverse=n wantframenum=(bool) (n3 > 1) nreserve=8 gainpanel= bar= color= > (plot.vpl | char.rsf)<br />
|-<br />
| colspan="4" | Can input char values.<br>If called "byte", outputs char values.<br><br>Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=n''' || [y/n] || if y, assume positive data<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=''' || || <br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''string '' || '''gainpanel=''' || || gain reference: 'a' for all, 'e' for each, or number<br />
|-<br />
| ''int '' || '''gainstep=0.5+n1/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=''' || || <br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''pclip=''' || || data clip percentile (default is 99)<br />
|-<br />
| ''float '' || '''phalf=''' || || percentage for estimating gpow<br />
|-<br />
| ''bool '' || '''polarity=n''' || [y/n] || if y, reverse polarity (white is high by default)<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the display axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''bool '' || '''wantframenum=(bool) (n3 > 1)''' || [y/n] || if y, display third axis position in the corner<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''bool '' || '''yreverse=y''' || [y/n] || if y, reverse the vertical axis<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
and examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfplas==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Assembler - convert ascii to vplot. <br />
|-<br />
! colspan="4" | sfplas<br />
|}<br />
==sfpldb==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Debugger - convert vplot to ascii. <br />
|-<br />
! colspan="4" | sfpldb<br />
|}<br />
==sfplotrays==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot rays.<br />
|-<br />
! colspan="4" | sfplotrays frame=frame.rsf nt=n1*n2 jr=1 frame= < rays.rsf > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''string '' || '''frame=''' || || <br />
|-<br />
| ''int '' || '''jr=1''' || || skip rays<br />
|-<br />
| ''int '' || '''nt=n1*n2''' || || maximum ray length<br />
|}<br />
==sfthplot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Hidden-line surface plot.<br />
|-<br />
! colspan="4" | sfthplot < in.rsf uflag=y dflag=y alpha=45. titlsz=9 axissz=6 plotfat=0 titlefat=2 axisfat=2 plotcolup=VP_YELLOW plotcoldn=VP_RED axis=y axis1=y axis2=y axis3=y clip=0. pclip=100. gainstep=0.5+nx/256. bias=0. dclip=1. norm=y xc=1.5 zc=3 ratio=5. zmax= zmin= sz=6. label#= unit#= tpow=0 epow=0 gpow=1 title= > plot.vpl<br />
|-<br />
| ''float '' || '''alpha=45.''' || || apparent angle in degrees, |alpha| < 89<br />
|-<br />
| ''bool '' || '''axis=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis1=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis2=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis3=y''' || [y/n] || plot axis<br />
|-<br />
| ''int '' || '''axisfat=2''' || || axes fatness<br />
|-<br />
| ''int '' || '''axissz=6''' || || axes size<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip<br />
|-<br />
| ''float '' || '''dclip=1.''' || || change the clip: clip *= dclip<br />
|-<br />
| ''bool '' || '''dflag=y''' || [y/n] || if y, plot down side of the surface<br />
|-<br />
| ''float '' || '''epow=0''' || || exponential gain<br />
|-<br />
| ''int '' || '''gainstep=0.5+nx/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=1''' || || power gain<br />
|-<br />
| ''string '' || '''label#=''' || || label on #-th axis<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || normalize by the clip<br />
|-<br />
| ''float '' || '''pclip=100.''' || || data clip percentile<br />
|-<br />
| ''int '' || '''plotcoldn=VP_RED''' || || color of the lower side<br />
|-<br />
| ''int '' || '''plotcolup=VP_YELLOW''' || || color of the upper side<br />
|-<br />
| ''int '' || '''plotfat=0''' || || line fatness<br />
|-<br />
| ''float '' || '''ratio=5.''' || || plot adjustment<br />
|-<br />
| ''float '' || '''sz=6.''' || || vertical scale<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''int '' || '''titlefat=2''' || || title fatness<br />
|-<br />
| ''int '' || '''titlsz=9''' || || title size<br />
|-<br />
| ''string '' || '''tpow=0''' || || time power gain<br />
|-<br />
| ''bool '' || '''uflag=y''' || [y/n] || if y, plot upper side of the surface<br />
|-<br />
| ''string '' || '''unit#=''' || || unit on #-th axis<br />
|-<br />
| ''float '' || '''xc=1.5''' || || <br />
|-<br />
| ''float '' || '''zc=3''' || || lower left corner of the plot<br />
|-<br />
| ''float '' || '''zmax=''' || || <br />
|-<br />
| ''float '' || '''zmin=''' || || <br />
|}<br />
==sfwiggle==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot data with wiggly traces. <br />
|-<br />
! colspan="4" | sfwiggle < in.rsf xpos=xpos.rsf xmax= xmin= poly=n fatp=1 xmask=1 ymask=1 pclip=98. zplot=0.75 clip=0. seemean=n verb=n transp=n yreverse=n xreverse=n xpos= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip (estimated from pclip by default<br />
|-<br />
| ''int '' || '''fatp=1''' || || <br />
|-<br />
| ''float '' || '''pclip=98.''' || || clip percentile<br />
|-<br />
| ''bool '' || '''poly=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''seemean=n''' || [y/n] || if y, plot mean lines of traces<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''int '' || '''xmask=1''' || || <br />
|-<br />
| ''float '' || '''xmax=''' || || maximum trace position (if using xpos)<br />
|-<br />
| ''float '' || '''xmin=''' || || minimum trace position (if using xpos)<br />
|-<br />
| ''string '' || '''xpos=''' || || optional header file with trace positions<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''int '' || '''ymask=1''' || || <br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse the vertical axis<br />
|-<br />
| ''float '' || '''zplot=0.75''' || || <br />
|}<br />
<br />
=filt/imag programs=<br />
==sfremap1==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 1-D ENO interpolation. <br />
|-<br />
! colspan="4" | sfremap1 < in.rsf > out.rsf pattern=pattern.rsf n1=n1 d1=d1 o1=o1 order=3<br />
|-<br />
| ''float '' || '''d1=d1''' || || Output sampling<br />
|-<br />
| ''int '' || '''n1=n1''' || || Number of output samples<br />
|-<br />
| ''float '' || '''o1=o1''' || || Output origin<br />
|-<br />
| ''int '' || '''order=3''' || || Interpolation order<br />
|-<br />
| ''string '' || '''pattern=''' || || auxiliary input file name<br />
|}<br />
To give an example of usage, we will create an input for <tt>sfremap1</tt> with:<br />
<pre><br />
sfmath n1=11 n2=11 d1=1 d2=1 o1=-5 o2=-5 output="x1*x1+x2*x2" > inp2remap1.rsf<br />
</pre><br />
Let us interpolate the data across both dimensions, then display it:<br />
<pre><br />
&lt; inp2remap1.rsf sfremap1 n1=1001 d1=0.01 | sftransp | \<br />
sfremap1 n1=1001 d1=0.01 | sftransp | sfgrey allpos=y | xtpen<br />
</pre><br />
The comparison with the uninterpolated data ( <tt>&lt; inp2remap1.rsf sfgrey allpos=y | xtpen</tt> ) is quite telling.<br />
<br />
=filt/proc programs=<br />
==sfstretch==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stretch of the time axis. <br />
|-<br />
! colspan="4" | sfstretch < in.rsf > out.rsf datum=dat.rsf inv=n dens=1 v0= half=y delay= tdelay= hdelay= nout=dens*n1 extend=4 mute=0 maxstr=0 rule=<br />
|-<br />
| ''file '' || '''datum=''' || || auxiliary input file name<br />
|-<br />
| ''float '' || '''delay=''' || || time delay for rule=lmo<br />
|-<br />
| ''int '' || '''dens=1''' || || axis stretching factor<br />
|-<br />
| ''int '' || '''extend=4''' || || trace extension<br />
|-<br />
| ''bool '' || '''half=y''' || [y/n] || if y, the second axis is half-offset instead of full offset<br />
|-<br />
| ''float '' || '''hdelay=''' || || offset delay for rule=rad<br />
|-<br />
| ''bool '' || '''inv=n''' || [y/n] || if y, do inverse stretching<br />
|-<br />
| ''float '' || '''maxstr=0''' || || maximum stretch<br />
|-<br />
| ''int '' || '''mute=0''' || || tapering size<br />
|-<br />
| ''int '' || '''nout=dens*n1''' || || output axis length (if inv=n)<br />
|-<br />
| ''string '' || '''rule=''' || || Stretch rule:<br />
:n - normal moveout (nmostretch), default<br />
:l - linear moveout (lmostretch)<br />
:L - logarithmic stretch (logstretch)<br />
:2 - t^2 stretch (t2stretch)<br />
:c - t^2 chebyshev stretch (t2chebstretch)<br />
:r - radial moveout (radstretch)<br />
:d - datuming (datstretch)<br />
|-<br />
| ''float '' || '''tdelay=''' || || time delay for rule=rad<br />
|-<br />
| ''float '' || '''v0=''' || || moveout velocity<br />
|}<br />
<br />
<tt>sfstretch rule=d</tt> (aka <tt>sfdatstretch</tt>) can be used to apply statics. Here is a synthetic example, courtesy of Alessandro Frigeri:<br />
<pre><br />
# generate a dataset with 'flat' signals<br />
sfmath n1=200 n2=100 output="sin(0.5*x1)" type=float > scan.rsf<br />
<br />
# generate a sinusoidal elevation correction<br />
sfmath n1=100 output="3*sin(x1)" type=float > statics.rsf<br />
<br />
# apply statics, producing a 'wavy' output.<br />
sfstretch < scan.rsf > out.rsf datum=statics.rsf rule=d<br />
</pre><br />
<br />
=user/ivlad programs=<br />
==sfprep4plot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Resamples a 2-D dataset to the desired picture resolution, with antialias<br />
|-<br />
! colspan="4" | sfprep4plot inp= out= verb=n h=none w=none unit= ppi= prar=y<br />
|-<br />
| colspan="4" | Only one of the h and w parameters needs to be specified.<br>If prar=n, no action will be taken on axis for which h/w was not specified<br>If prar=y and only one par (h or w) is specified, the picture will scale<br>along both axes until it is of the specified dimension.<br />
|-<br />
| ''int '' || '''h=none''' || || output height<br />
|-<br />
| ''string '' || '''inp=''' || || input file<br />
|-<br />
| ''string '' || '''out=''' || || output file<br />
|-<br />
| ''int '' || '''ppi=''' || || output resolution (px/in). Necessary when unit!=px<br />
|-<br />
| ''bool '' || '''prar=y''' || [y/n] || if y, PReserve Aspect Ratio of input<br />
|-<br />
| ''string '' || '''unit=''' || || unit of h and w. Can be: px(default), mm, cm, in<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || if y, print system commands, outputs<br />
|-<br />
| ''int '' || '''w=none''' || || output width<br />
|}<br />
For a figure that does not need the aspect ratio preserved,<br />
and needs to fill a 1280x1024 projector display:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=1280 h=1024 prar=n<br />
</pre><br />
For a print figure that has to fit in a 6x8in box<br />
at a resolution of 250 dpi, preserving the aspect ratio:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=6 h=8 unit=in ppi=250<br />
</pre><br />
A comparison of images before and after the application of <tt>sfprep4plot</tt>, courtesy of Joachim Mispel, is shown below:<br />
<br />
[[Image:sf_prep4plot.jpg]]<br />
<br />
=user/jennings programs=<br />
==sfsizes==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display the size of RSF files.<br />
|-<br />
! colspan="4" | sfsizes files=y human=n file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | Prints the element size, number of elements, and number of bytes<br>for a list of RSF files. Non-RSF files are ignored.<br />
|-<br />
| ''bool '' || '''files=y''' || [y/n] || If y, print size of each file. If n, print only total.<br />
|-<br />
| ''bool '' || '''human=n''' || [y/n] || If y, print human-readable file size. If n, print byte count.<br />
|}<br />
<br />
<br />
This program computes the "theoretical" size in bytes of the data fork of RSF files. The actual space occupied on disk may be different and machine dependent due to disk blocking factors, etc. This behavior should make the output of sfsizes reproducible. It is also fast because it only reads the RSF headers files, not the actual data.<br />
<br />
For example, to get the total size of all RSF files in a directory, in human readable format, without listing each file:<br />
<pre><br />
sfsizes files=n human=y *.rsf<br />
</pre><br />
This will also work because sfsizes simply skips any non-RSF file:<br />
<pre><br />
sfsizes files=n human=y *<br />
</pre><br />
<br />
=References=<br />
<references/></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Guide_to_madagascar_programs&diff=705Guide to madagascar programs2009-03-12T13:39:28Z<p>Jenningsjwj: /* sfsizes */</p>
<hr />
<div><center><font size="-1">''This page was created from the LaTeX source in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/rsf/rsf/prog.tex?view=markup book/rsf/rsf/prog.tex] using [[latex2wiki]]''</font></center><br />
<br />
This guide introduces some of the most used <tt>madagascar</tt> programs and illustrates their usage with examples.<br />
=Main programs=<br />
The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/ system/main] in the Madagascar distribution. The "main" programs perform general-purpose operations on RSF hypercubes regardless of the data dimensionality or physical dimensions.<br />
<br />
==sfadd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Add, multiply, or divide RSF datasets.<br />
|-<br />
! colspan="4" | sfadd > out.rsf scale= add= sqrt= abs= log= exp= mode= [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | The various operations, if selected, occur in the following order:<br><br>(1) Take absolute value, abs=<br>(2) Add a scalar, add=<br>(3) Take the natural logarithm, log=<br>(4) Take the square root, sqrt=<br>(5) Multiply by a scalar, scale=<br>(6) Compute the base-e exponential, exp=<br>(7) Add, multiply, or divide the data sets, mode=<br><br>sfadd operates on integer, float, or complex data, but all the input<br>and output files must be of the same data type.<br><br>An alternative to sfadd is sfmath, which is more versatile, but may be<br>less efficient.<br />
|-<br />
| ''bools '' || '''abs=''' || || If true take absolute value [nin]<br />
|-<br />
| ''floats '' || '''add=''' || || Scalar values to add to each dataset [nin]<br />
|-<br />
| ''bools '' || '''exp=''' || || If true compute exponential [nin]<br />
|-<br />
| ''bools '' || '''log=''' || || If true take logarithm [nin]<br />
|-<br />
| ''string '' || '''mode=''' || || 'a' means add (default), <br> 'p' or 'm' means multiply, <br> 'd' means divide<br />
|-<br />
| ''floats '' || '''scale=''' || || Scalar values to multiply each dataset with [nin]<br />
|-<br />
| ''bools '' || '''sqrt=''' || || If true take square root [nin]<br />
|}<br />
<br />
<tt>sfadd</tt> is useful for combining (adding, dividing, or<br />
multiplying) several datasets. What if you want to subtract two<br />
datasets? Easy. Use the <tt>scale</tt> parameter as follows:<br />
<pre><br />
bash&#36; sfadd data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfadd < data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
The same task can be accomplished with the more general <tt>sfmath</tt> program:<br />
<pre><br />
bash&#36; sfmath one=data1.rsf two=data2.rsf output='one-two' > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfmath < data1.rsf two=data2.rsf output='input-two' > diff.rsf<br />
</pre><br />
In both cases, the size and shape of <tt>data1.rsf</tt> and<br />
<tt>data2.rsf</tt> hypercubes should be the same, and a warning<br />
message is printed out if the the axis sampling parameters (such as<br />
<tt>o1</tt> or <tt>d1</tt>) in these files are different.<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/add.c?view=markup user/main/add.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
/* find number of input files */<br />
if (isatty(fileno(stdin))) { <br />
/* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Collect input files in the <tt>in</tt> array from all command-line<br />
parameters that don't contain an "<tt>=</tt>" sign. The total number<br />
of input files in <tt>nin</tt>.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) continue; <br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
/* nin = no of input files*/<br />
</c><br />
<br />
A helper function <tt>check_compat</tt> checks the compatibility of<br />
input files.<br />
<c><br />
static void <br />
check_compat (sf_datatype type /* data type */, <br />
size_t nin /* number of files */, <br />
sf_file* in /* input files [nin] */, <br />
int dim /* file dimensionality */, <br />
const int* n /* dimensions [dim] */)<br />
/* Check that the input files are compatible. <br />
Issue error for type mismatch or size mismatch.<br />
Issue warning for grid parameters mismatch. */<br />
{<br />
int ni, id;<br />
size_t i;<br />
float d, di, o, oi;<br />
char key[3];<br />
const float tol=1.e-5; /* tolerance for comparison */<br />
<br />
for (i=1; i < nin; i++) {<br />
if (sf_gettype(in[i]) != type) <br />
sf_error ("type mismatch: need %d",type);<br />
for (id=1; id <= dim; id++) {<br />
(void) snprintf(key,3,"n%d",id);<br />
if (!sf_histint(in[i],key,&ni) || ni != n[id-1])<br />
sf_error("%s mismatch: need %d",key,n[id-1]);<br />
(void) snprintf(key,3,"d%d",id);<br />
if (sf_histfloat(in[0],key,&d)) {<br />
if (!sf_histfloat(in[i],key,&di) || <br />
(fabsf(di-d) > tol*fabsf(d)))<br />
sf_warning("%s mismatch: need %g",key,d);<br />
} else {<br />
d = 1.;<br />
}<br />
(void) snprintf(key,3,"o%d",id);<br />
if (sf_histfloat(in[0],key,&o) && <br />
(!sf_histfloat(in[i],key,&oi) || <br />
(fabsf(oi-o) > tol*fabsf(d))))<br />
sf_warning("%s mismatch: need %g",key,o);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
Finally, we enter the main loop, where input data are getting read<br />
buffer by buffer and combined in the total product depending on the<br />
data type.<br />
<c><br />
for (nbuf /= sf_esize(in[0]); nsiz > 0; nsiz -= nbuf) {<br />
if (nbuf > nsiz) nbuf=nsiz;<br />
<br />
for (j=0; j < nin; j++) {<br />
collect = (bool) (j != 0);<br />
switch(type) {<br />
case SF_FLOAT:<br />
sf_floatread((float*) bufi,<br />
nbuf,<br />
in[j]); <br />
add_float(collect, <br />
nbuf,<br />
(float*) buf,<br />
(const float*) bufi, <br />
cmode, <br />
scale[j], <br />
add[j], <br />
abs_flag[j], <br />
log_flag[j], <br />
sqrt_flag[j], <br />
exp_flag[j]);<br />
break;<br />
</c><br />
<br />
The data combination program for floating point numbers is<br />
<tt>add_float</tt>. <br />
<c><br />
static void add_float (bool collect, /* if collect */<br />
size_t nbuf, /* buffer size */<br />
float* buf, /* output [nbuf] */<br />
const float* bufi, /* input [nbuf] */ <br />
char cmode, /* operation */<br />
float scale, /* scale factor */<br />
float add, /* add factor */<br />
bool abs_flag, /* if abs */<br />
bool log_flag, /* if log */<br />
bool sqrt_flag, /* if sqrt */<br />
bool exp_flag /* if exp */)<br />
/* Add floating point numbers */<br />
{<br />
size_t j;<br />
float f;<br />
<br />
for (j=0; j < nbuf; j++) {<br />
f = bufi[j];<br />
if (abs_flag) f = fabsf(f);<br />
f += add;<br />
if (log_flag) f = logf(f);<br />
if (sqrt_flag) f = sqrtf(f);<br />
if (1. != scale) f *= scale;<br />
if (exp_flag) f = expf(f);<br />
if (collect) {<br />
switch (cmode) {<br />
case 'p': /* product */<br />
case 'm': /* multiply */<br />
buf[j] *= f;<br />
break;<br />
case 'd': /* delete */<br />
if (f != 0.) buf[j] /= f;<br />
break;<br />
default: /* add */<br />
buf[j] += f;<br />
break;<br />
}<br />
} else {<br />
buf[j] = f;<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display dataset attributes.<br />
|-<br />
! colspan="4" | sfattr < in.rsf want=<br />
|-<br />
| colspan="4" | <br>Sample output from "sfspike n1=100 | sfbandpass fhi=60 | sfattr"<br>******************************************* <br>rms = 0.992354 <br>mean value = 0.987576 <br>2-norm value = 9.92354 <br>variance = 0.00955481 <br>standard deviation = 0.0977487 <br>maximum value = 1.12735 at 97 <br>minimum value = 0.151392 at 100 <br>number of nonzero samples = 100 <br>total number of samples = 100 <br>******************************************* <br><br>rms = sqrt[ sum(data^2) / n ]<br>mean = sum(data) / n<br>norm = sum(abs(data)^lval)^(1/lval)<br>variance = [ sum(data^2) - n*mean^2 ] / [ n-1 ]<br>standard deviation = sqrt [ variance ]<br />
|-<br />
| ''int '' || '''lval=2''' || || norm option, lval is a non-negative integer, computes the vector lval-norm<br />
|-<br />
| ''string '' || '''want=''' || || 'all'(default),'rms','mean','norm','var','std','max','min','nonzero','samples','short' <br />
:want= 'rms' displays the root mean square<br />
:want= 'norm' displays the square norm, otherwise specified by lval.<br />
:want= 'var' displays the variance<br />
:want= 'std' displays the standard deviation<br />
:want= 'nonzero' displays number of nonzero samples<br />
:want= 'samples' displays total number of samples<br />
:want= 'short' displays a short one-line version<br />
|}<br />
<br />
<br />
<tt>sfattr</tt> is a useful diagnostic program. It reports certain<br />
statistical values for an RSF dataset: RMS (root-mean-square)<br />
amplitude, mean value, vector norm value, variance, standard deviation,<br />
maximum and minimum values, number of nonzero samples, and the total<br />
number of samples.<br />
If we denote data values as <math>d_i</math> for <math>i=0,1,2,\ldots,n</math>, then the RMS<br />
value is <math>\sqrt{\frac{1}{n}\,\sum\limits_{i=0}^n d_i^2}</math>, the mean<br />
value is <math>\frac{1}{n}\,\sum\limits_{i=0}^n d_i</math>, the <math>L_2</math>-norm value<br />
is <math>\sqrt{\sum\limits_{i=0}^n d_i^2}</math>, the variance is<br />
<math>\frac{1}{n-1}\,\left[\sum\limits_{i=0}^n d_i^2 - \frac{1}{n}\left(\sum\limits_{i=0}^n d_i\right)^2\right]</math>, and the standard<br />
deviation is the square root of the variance. Using <tt>sfattr</tt><br />
is a quick way to see the distribution of data values and check it for<br />
anomalies.<br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/attr.c?view=markup user/main/attr.c]====<br />
<br />
Computations start by finding the input data (<tt>in</tt>) size<br />
(<tt>nsiz</tt>) and dimensions (<tt>dim</tt>).<br />
<c><br />
dim = (size_t) sf_filedims (in,n);<br />
for (nsiz=1, i=0; i < dim; i++) {<br />
nsiz *= n[i];<br />
}<br />
</c><br />
<br />
<br />
In the main loop, we read the input data buffer by buffer.<br />
<c><br />
for (nleft=nsiz; nleft > 0; nleft -= nbuf) {<br />
nbuf = (bufsiz < nleft)? bufsiz: nleft;<br />
switch (type) {<br />
case SF_FLOAT: <br />
sf_floatread((float*) buf,nbuf,in);<br />
break;<br />
case SF_INT:<br />
sf_intread((int*) buf,nbuf,in);<br />
break;<br />
case SF_COMPLEX:<br />
sf_complexread((sf_complex*) buf,nbuf,in);<br />
break;<br />
case SF_UCHAR:<br />
sf_ucharread((unsigned char*) buf,nbuf,in);<br />
break;<br />
case SF_CHAR:<br />
default:<br />
sf_charread(buf,nbuf,in);<br />
break;<br />
}<br />
</c><br />
<br />
<br />
The data attributes are accumulated in corresponding double-precision<br />
variables. <br />
<c><br />
fsum += f;<br />
fsqr += f*f;<br />
</c><br />
<br />
<br />
Finally, the attributes are reduced and printed out.<br />
<c><br />
fmean = fsum/nsiz;<br />
if (lval==2) fnorm = sqrt(fsqr);<br />
else if (lval==0) fnorm = nsiz-nzero;<br />
else fnorm = pow(flval,1./lval);<br />
frms = sqrt(fsqr/nsiz);<br />
if (nsiz > 1) fvar = (fsqr-nsiz*fmean*fmean)/(nsiz-1);<br />
else fvar = 0.0;<br />
fstd = sqrt(fvar);<br />
</c><br />
<br />
<c><br />
if(NULL==want || 0==strcmp(want,"rms"))<br />
printf("rms = %g \n",(float) frms);<br />
if(NULL==want || 0==strcmp(want,"mean"))<br />
printf("mean value = %g \n",(float) fmean);<br />
if(NULL==want || 0==strcmp(want,"norm"))<br />
printf("%d-norm value = %g \n",lval,(float) fnorm);<br />
if(NULL==want || 0==strcmp(want,"var"))<br />
printf("variance = %g \n",(float) fvar);<br />
if(NULL==want || 0==strcmp(want,"std"))<br />
printf("standard deviation = %g \n",(float) fstd);<br />
</c><br />
<br />
==sfcat==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Concatenate datasets. <br />
|-<br />
! colspan="4" | sfcat > out.rsf space= axis=3 nspace=(int) (ni/(20*nin) + 1) [<file0.rsf] file1.rsf file2.rsf ... <br />
|-<br />
| colspan="4" | sfmerge inserts additional space between merged data.<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis being merged<br />
|-<br />
| ''int '' || '''nspace=(int) (ni/(20*nin) + 1)''' || || if space=y, number of traces to insert<br />
|-<br />
| ''bool '' || '''space=''' || [y/n] || Insert additional space.<br />
:y is default for sfmerge, n is default for sfcat<br />
|}<br />
<br />
<br />
<tt>sfcat</tt> and <tt>sfmerge</tt> concatenate two or more files<br />
together along a particular axis. It is the same program, only<br />
<tt>sfcat</tt> has the default <tt>space=n</tt> and <tt>sfmerge</tt><br />
has the default <tt>space=y</tt>.<br />
Example of <tt>sfcat</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcat one.rsf one.rsf axis=1 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=4 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
12 elements 48 bytes<br />
</pre><br />
Example of <tt>sfmerge</tt>:<br />
<pre><br />
bash$ sfmerge one.rsf one.rsf axis=2 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=7 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
14 elements 56 bytes<br />
</pre><br />
In this case, an extra empty trace is inserted between the two merged files.<br />
The axes that are not being merged are checked for consistency:<br />
<pre><br />
bash$ sfcat one.rsf two.rsf > three.rsf<br />
sfcat: n2 mismatch: need 3<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cat.c?view=markup user/main/cat.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
in = (sf_file*) sf_alloc ((size_t) argc,sizeof(sf_file));<br />
<br />
if (!sf_stdin()) { /* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Everything on the command line that does not contain a "=" sign is<br />
treated as a file name, and the corresponding file object is added to the list.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) <br />
continue; /* not a file */<br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
</c><br />
<br />
As explained above, if the <tt>space=</tt> parameter is not set, it is<br />
inferred from the program name: <tt>sfmerge</tt> corresponds to<br />
<tt>space=y</tt> and <tt>sfcat</tt> corresponds to <tt>space=n</tt>.<br />
<c><br />
if (!sf_getbool("space",&space)) {<br />
/* Insert additional space.<br />
y is default for sfmerge, n is default for sfcat */<br />
prog = sf_getprog();<br />
if (NULL != strstr (prog, "merge")) {<br />
space = true;<br />
} else if (NULL != strstr (prog, "cat")) {<br />
space = false;<br />
} else {<br />
sf_warning("%s is neither merge nor cat,"<br />
" assume merge",prog);<br />
space = true;<br />
}<br />
}<br />
</c><br />
<br />
Find the axis for the merging (from the command line <tt>axis=</tt><br />
argument) and figure out two sizes: <tt>n1</tt> for everything after<br />
the axis and <tt>n2</tt> for everything before the axis.<br />
<c><br />
n1=1;<br />
n2=1;<br />
for (i=1; i <= dim; i++) {<br />
if (i < axis) n1 *= n[i-1];<br />
else if (i > axis) n2 *= n[i-1];<br />
}<br />
</c><br />
<br />
In the output, the selected axis will get extended.<br />
<c><br />
/* figure out the length of extended axis */<br />
ni = 0;<br />
for (j=0; j < nin; j++) {<br />
ni += naxis[j];<br />
}<br />
<br />
if (space) {<br />
if (!sf_getint("nspace",&nspace)) <br />
nspace = (int) (ni/(20*nin) + 1);<br />
/* if space=y, number of traces to insert */ <br />
ni += nspace*(nin-1);<br />
} <br />
<br />
(void) snprintf(key,3,"n%d",axis);<br />
sf_putint(out,key,(int) ni);<br />
</c><br />
<br />
The rest is simple: loop through the datasets reading and writing the<br />
data in buffer-size chunks and adding extra empty chunks if<br />
<tt>space=y</tt>.<br />
<c><br />
for (i2=0; i2 < n2; i2++) {<br />
for (j=0; j < nin; j++) {<br />
for (ni = n1*naxis[j]*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charread (buf,nbuf,in[j]);<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
if (!space || j == nin-1) continue;<br />
/* Add spaces */<br />
memset(buf,0,BUFSIZ);<br />
for (ni = n1*nspace*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfcmplx==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a complex dataset from its real and imaginary parts.<br />
|-<br />
! colspan="4" | sfcmplx > cmplx.rsf real.rsf imag.rsf<br />
|-<br />
| colspan="4" | There has to be only two input files specified and no additional parameters.<br />
|}<br />
<br />
<br />
<tt>sfcmplx</tt> simply creates a complex dataset from its real and<br />
imaginary parts. The reverse operation can be accomplished with<br />
<tt>sfreal</tt> and <tt>sfimag</tt>.<br />
Example of <tt>sfcmplx</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcmplx one.rsf one.rsf > cmplx.rsf<br />
bash$ sfin cmplx.rsf<br />
cmplx.rsf:<br />
in="/tmp/cmplx.rsf@"<br />
esize=8 type=complex form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 48 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cmplx.c?view=markup user/main/cmplx.c]====<br />
The program flow is simple. First, get the names of the input files.<br />
<c><br />
/* the first two non-parameters are real and imaginary files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == real) {<br />
real = sf_input (argv[i]);<br />
} else {<br />
imag = sf_input (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == imag) {<br />
if (NULL == real) sf_error ("not enough input");<br />
/* if only one input, real is in stdin */<br />
imag = real;<br />
real = sf_input("in");<br />
}<br />
</c><br />
<br />
The main part of the program reads the real and imaginary parts buffer by buffer and assembles and writes out the complex input. <br />
<c><br />
for (nleft= (size_t) (rsize*resize); nleft > 0; nleft -= nbuf) {<br />
nbuf = (BUFSIZ < nleft)? BUFSIZ: nleft;<br />
sf_charread(rbuf,nbuf,real);<br />
sf_charread(ibuf,nbuf,imag);<br />
for (i=0; i < nbuf; i += resize) {<br />
memcpy(cbuf+2*i, rbuf+i,(size_t) resize);<br />
memcpy(cbuf+2*i+resize,ibuf+i,(size_t) resize);<br />
}<br />
sf_charwrite(cbuf,2*nbuf,cmplx);<br />
}<br />
</c><br />
<br />
==sfconjgrad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic conjugate-gradient solver for linear inversion <br />
|-<br />
! colspan="4" | sfconjgrad < dat.rsf mod=mod.rsf > to.rsf < from.rsf > out.rsf niter=1<br />
|-<br />
| ''int '' || '''niter=1''' || || number of iterations<br />
|}<br />
<br />
<br />
<tt>sfconjgrad</tt> is a generic program for least-squares linear<br />
inversion with the conjugate-gradient method. Suppose you have an<br />
executable program <tt><prog></tt> that takes an RSF file from the<br />
standard input and produces an RSF file in the standard output. It may<br />
take any number of additional parameters but one of them must be<br />
<tt>adj=</tt> that sets the forward (<tt>adj=0</tt>) or adjoint<br />
(<tt>adj=1</tt>) operations. The program <tt><prog></tt> is typically<br />
an RSF program but it could be anything (a script, a multiprocessor<br />
MPI program, etc.) as long as it implements a linear operator<br />
<math>\mathbf{L}</math> and its adjoint. There are no restrictions on the data<br />
size or shape. You can easily test the adjointness with<br />
<tt>sfdottest</tt>. The <tt>sfconjgrad</tt> program searches for a<br />
vector <math>\mathbf{m}</math> that minimizes the least-square misfit <br />
<math>\|\mathbf{d - L\,m}\|^2</math> for the given input data vector <math>\mathbf{d}</math>.<br />
Here is an example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
The <tt>sfdottest</tt> program can perform the dot product test to<br />
check that the adjoint mode works correctly.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=5.28394<br />
sfdottest: L'[d]*m=5.28394<br />
</pre><br />
Your numbers may be different because <tt>sfdottest</tt> generates new<br />
random input on each run.<br />
Next, let us make some random data with <tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfnoise seed=2005 rep=y < vec.rsf > dat.rsf<br />
</pre><br />
and try to invert the filtering operation using <tt>sfconjgrad</tt>:<br />
<pre><br />
bash$ sfconjgrad sfhelicon filt=flt.rsf lag=lag.rsf \<br />
mod=vec.rsf < dat.rsf > mod.rsf niter=10<br />
sfconjgrad: iter 1 of 10<br />
sfconjgrad: grad=3253.65<br />
sfconjgrad: iter 2 of 10<br />
sfconjgrad: grad=289.421<br />
sfconjgrad: iter 3 of 10<br />
sfconjgrad: grad=92.3481<br />
sfconjgrad: iter 4 of 10<br />
sfconjgrad: grad=36.9417<br />
sfconjgrad: iter 5 of 10<br />
sfconjgrad: grad=18.7228<br />
sfconjgrad: iter 6 of 10<br />
sfconjgrad: grad=11.1794<br />
sfconjgrad: iter 7 of 10<br />
sfconjgrad: grad=7.26941<br />
sfconjgrad: iter 8 of 10<br />
sfconjgrad: grad=5.15945<br />
sfconjgrad: iter 9 of 10<br />
sfconjgrad: grad=4.23055<br />
sfconjgrad: iter 10 of 10<br />
sfconjgrad: grad=3.57495<br />
</pre><br />
The output shows that, in 10 iterations, the norm of the gradient vector decreases by almost 1000. <br />
We can check the residual misfit before<br />
<pre><br />
bash$ < dat.rsf sfattr want=norm<br />
norm value = 49.7801<br />
</pre><br />
and after<br />
<pre><br />
bash$ sfhelicon filt=flt.rsf lag=lag.rsf < mod.rsf | \<br />
sfadd scale=1,-1 dat.rsf | sfattr want=norm<br />
norm value = 5.73563<br />
</pre><br />
In 10 iterations, the misfit decreased by an order of magnitude. The<br />
result can be improved by running the program for more iterations.<br />
<br />
==sfcp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Copy or move a dataset.<br />
|-<br />
! colspan="4" | sfcp in.rsf out.rsf<br />
|-<br />
| colspan="4" | sfcp - copy, sfmv - move.<br>Mimics standard Unix commands.<br />
|}<br />
<br />
<br />
The <tt>sfcp</tt> and <tt>sfmv</tt> command imitate the Unix<br />
<tt>cp</tt> and <tt>mv</tt> commands and serve for copying and moving<br />
RSF files. Example:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcp one.rsf two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
</pre><br />
<br />
==sfcut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of the dataset. <br />
|-<br />
! colspan="4" | sfcut < in.rsf > out.rsf verb=n [j1=1 j2=1 ... f1=0 f2=0 ... n1=n1 n2=n2 ... max1= max2= ... min1= min2= ...]<br />
|-<br />
| colspan="4" | jN defines the jump in N-th dimension<br>fN is the window start<br>nN is the window size<br>minN and maxN is the maximum and minimum in N-th dimension<br><br>Reverse of window. <br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
The <tt>sfcut</tt> command is related to <tt>sfwindow</tt> and has the same<br />
set of arguments only instead of extracting the selected window, it fills it<br />
with zeroes. The size of the input data is preserved. <br />
Examples:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > in.rsf<br />
bash$ < in.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < in.rsf sfcut n1=2 f1=1 n2=3 f2=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 0 0 1 1<br />
15: 1 0 0 1 1<br />
20: 1 0 0 1 1<br />
bash$ < in.rsf sfcut j1=2 | sfdisfil<br />
0: 0 1 0 1 0<br />
5: 0 1 0 1 0<br />
10: 0 1 0 1 0<br />
15: 0 1 0 1 0<br />
20: 0 1 0 1 0<br />
</pre><br />
<br />
==sfdd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert between different formats. <br />
|-<br />
! colspan="4" | sfdd < in.rsf > out.rsf line=8 form= type= format=<br />
|-<br />
| ''string '' || '''form=''' || || ascii, native, xdr<br />
|-<br />
| ''string '' || '''format=''' || || Element format (for conversion to ASCII)<br />
|-<br />
| ''int '' || '''line=8''' || || Number of numbers per line (for conversion to ASCII)<br />
|-<br />
| ''string '' || '''type=''' || || int, float, complex<br />
|}<br />
<br />
<br />
The <tt>sfdd</tt> program is used to change either the form (<tt>ascii</tt>,<br />
<tt>xdr</tt>, <tt>native</tt>) or the type (<tt>complex</tt>, <tt>float</tt>,<br />
<tt>int</tt>, <tt>char</tt>) of the input dataset. <br />
In the example below, we create a plain text (ASCII) file with numbers and<br />
then use <tt>sfdd</tt> to generate an RSF file in <tt>xdr</tt> form with<br />
<tt>complex</tt> numbers. <br />
<pre><br />
bash$ cat test.txt<br />
1 2 3 4 5 6<br />
bash$ echo n1=6 data_format=ascii_int in=test.txt > test.rsf<br />
bash$ sfin test.rsf<br />
test.rsf:<br />
in="test.txt"<br />
esize=0 type=int form=ascii<br />
n1=6 d1=? o1=?<br />
6 elements<br />
bash$ sfdd < test.rsf form=xdr type=complex > test2.rsf<br />
bash$ sfin test2.rsf<br />
test2.rsf:<br />
in="/tmp/test2.rsf@"<br />
esize=8 type=complex form=xdr<br />
n1=3 d1=? o1=?<br />
3 elements 24 bytes<br />
bash$ sfdisfil < test2.rsf<br />
0: 1, 2i 3, 4i 5, 6i<br />
</pre><br />
To learn more about the RSF data format, consult the [[Format| guide to RSF format]].<br />
<br />
==sfdisfil==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Print out data values.<br />
|-<br />
! colspan="4" | sfdisfil < in.rsf number=y col=0 format= header= trailer=<br />
|-<br />
| colspan="4" | <br>Alternatively, use sfdd and convert to ASCII form.<br />
|-<br />
| ''int '' || '''col=0''' || || Number of columns.<br />
:The default depends on the data type:<br />
:10 for int and char,<br />
:5 for float,<br />
:3 for complex<br />
|-<br />
| ''string '' || '''format=''' || || Format for numbers (printf-style).<br />
:The default depends on the data type:<br> "%4d " for int and char,<br> "%13.4g" for float,<br> "%10.4g,%10.4gi" for complex<br />
|-<br />
| ''string '' || '''header=''' || || Optional header string to output before data<br />
|-<br />
| ''bool '' || '''number=y''' || [y/n] || If number the elements<br />
|-<br />
| ''string '' || '''trailer=''' || || Optional trailer string to output after data<br />
|}<br />
<br />
<br />
The <tt>sfdisfil</tt> program simply dumps the data contents to the standard<br />
output in a text form. It is used mostly for debugging purposes to quickly<br />
examine RSF files. Here is an example:<br />
<pre><br />
bash$ sfmath o1=0 d1=2 n1=12 output=x1 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
10: 20 22<br />
</pre><br />
The output format is easily configurable.<br />
<pre><br />
bash$ < test.rsf sfdisfil col=6 number=n format="<br />
0.0 2.0 4.0 6.0 8.0 10.0<br />
12.0 14.0 16.0 18.0 20.0 22.0<br />
</pre><br />
Along with <tt>sfdd</tt>, <tt>sfdisfil</tt> provides a simple way to convert<br />
RSF data to an ASCII form.<br />
<br />
==sfdottest==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic dot-product test for linear operators with adjoints <br />
|-<br />
! colspan="4" | sfdottest mod=mod.rsf dat=dat.rsf > pip.rsf<br />
|}<br />
<br />
<br />
<tt>sfdottest</tt> is a generic dot-product test program for testing<br />
linear operators. Suppose there is an executable program<br />
<tt><prog></tt> that takes an RSF file from the standard input and<br />
produces an RSF file in the standard output. It may take any number of<br />
additional parameters but one of them must be <tt>adj=</tt> that sets<br />
the forward (<tt>adj=0</tt>) or adjoint (<tt>adj=1</tt>) operations.<br />
The program <tt><prog></tt> is typically an RSF program but it could<br />
be anything (a script, a multiprocessor MPI program, etc.) as long as<br />
it implements a linear operator <math>\mathbf{L}</math> and its adjoint<br />
<math>\mathbf{L}^T</math>. The <tt>sfdottest</tt> program is testing the equality<br />
<center><math><br />
d^T\,L\,m = m^T\,L^T\,d<br />
</math></center><br />
by using random vectors <math>\mathbf{m}</math> and <math>\mathbf{d}</math>. You can invoke it with<br />
<pre><br />
bash$ sfdottest <prog> [optional aruments] mod=mod.rsf dat=dat.rsf<br />
</pre><br />
where <tt>mod.rsf</tt> and <tt>dat.rsf</tt> are RSF files that<br />
represent vectors from the model and data spaces. <tt>sfdottest</tt><br />
does not create any temporary files and does not have any restrictive<br />
limitations on the size of the vectors.<br />
Here is an example. We first setup a vector with 100 elements using<br />
<tt>sfspike</tt> and then run <tt>sfdottest</tt> to test the<br />
<tt>sfcausint</tt> program. <tt>sfcausint</tt> implements a linear<br />
operator of causal integration and its adjoint, the anti-causal<br />
integration.<br />
<pre><br />
bash$ sfspike n1=100 > vec.rsf<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1410.2<br />
sfdottest: L'[d]*m=1410.2<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1165.87<br />
sfdottest: L'[d]*m=1165.87<br />
</pre><br />
The numbers are different on subsequent runs because of changing<br />
seed in the random number generator.<br />
Here is a somewhat more complicated example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
Now the <tt>sfdottest</tt> program can perform the dot product test.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=8.97375<br />
sfdottest: L'[d]*m=8.97375<br />
</pre><br />
Here is the same program tested in the inverse filtering mode:<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf inv=y<br />
sfdottest: L[m]*d=15.0222<br />
sfdottest: L'[d]*m=15.0222<br />
</pre><br />
<br />
==sfget==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Output parameters from the header.<br />
|-<br />
! colspan="4" | sfget < in.rsf parform=y par1 par2 ...<br />
|-<br />
| ''bool '' || '''parform=y''' || [y/n] || If y, print out parameter=value. If n, print out value.<br />
|}<br />
<br />
<br />
The <tt>sfget</tt> program extracts a parameter value from an RSF file. It is<br />
useful mostly for scripting. Here is, for example, a quick calculation of the<br />
maximum value on the first axis in an RSF dataset (the output of<br />
<tt>sfspike</tt>) using the standard Unix <tt>bc</tt> calculator.<br />
<pre><br />
bash$ ( sfspike n1=100 | sfget n1 d1 o1; echo "o1+(n1-1)*d1" ) | bc<br />
.396<br />
</pre><br />
See also <tt>sfput</tt>.<br />
<br />
<br />
<br />
==sfheadercut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheadercut mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array of size n2.<br />
|}<br />
<br />
<br />
<tt>sfheadercut</tt> is close to <tt>sfheaderwindow</tt> but instead<br />
of windowing the dataset, it fills the traces specified by the header<br />
mask with zeroes. The size of the input data is preserved.<br />
Here is an example of using <tt>sfheaderwindow</tt> for <br />
zeroing every other trace in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a mask with alternating ones and zeros using<br />
<tt>sfinterleave</tt>.<br />
<pre><br />
bash$ sfspike n1=5 mag=1 | sfdd type=int > ones.rsf<br />
bash$ sfspike n1=5 mag=0 | sfdd type=int > zeros.rsf<br />
bash$ sfinterleave axis=1 ones.rsf zeros.rsf > mask.rsf<br />
bash$ sfdisfil < mask.rsf<br />
0: 1 0 1 0 1 0 1 0 1 0<br />
</pre><br />
Finally, <tt>sfheadercut</tt> zeros the input traces.<br />
<pre><br />
bash$ sfheadercut < input.rsf mask=mask.rsf > output.rsf<br />
bash$ sfdisfil < output.rsf <br />
0: 1 1 1 1 1<br />
5: 0 0 0 0 0<br />
10: 3 3 3 3 3<br />
15: 0 0 0 0 0<br />
20: 5 5 5 5 5<br />
25: 0 0 0 0 0<br />
30: 7 7 7 7 7<br />
35: 0 0 0 0 0<br />
40: 9 9 9 9 9<br />
45: 0 0 0 0 0<br />
</pre><br />
<br />
<br />
<br />
==sfheadersort==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Sort a dataset according to a header key. <br />
|-<br />
! colspan="4" | sfheadersort < in.rsf > out.rsf head=<br />
|-<br />
| ''string '' || '''head=''' || || header file<br />
|}<br />
<br />
<br />
<tt>sfheadersort</tt> is used to sort traces in the input file<br />
according to trace header information. <br />
Here is an example of using<br />
<tt>sfheadersort</tt> for randomly shuffling traces in the input<br />
file. First, let us create an input file with seven traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=7 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7 <br />
</pre><br />
Next, we can create a random file with seven header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=7 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: 0.05256 -0.2879 0.1487 0.4097 0.1548<br />
5: 0.4501 0.2836<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally, we<br />
apply <tt>sfheadersort</tt> to shuffle the input traces.<br />
<pre><br />
bash$ < input.rsf sfheadersort head=random.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 1 1 1 1 1<br />
10: 3 3 3 3 3<br />
15: 5 5 5 5 5<br />
20: 7 7 7 7 7<br />
25: 4 4 4 4 4<br />
30: 6 6 6 6 6<br />
</pre><br />
As expected, the order of traces in the output file corresponds to the<br />
order of values in the header. Thanks to the separation between<br />
headers and data, the operation of <tt>sfheadersort</tt> is optimally<br />
efficient. It first sorts the headers and only then accesses the data,<br />
reading each data trace only once.<br />
<br />
==sfheaderwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheaderwindow mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array os size n2, windowed is n1xm2,<br>where m2 is the number of nonzero elements in mask.<br />
|}<br />
<br />
<br />
<tt>sfheaderwindow</tt> is used to window traces in the input file<br />
according to trace header information. <br />
Here is an example of using <tt>sfheaderwindow</tt> for randomly<br />
selecting part of the traces in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a random file with ten header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=10 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: -0.005768 0.02258 -0.04331 -0.4129 -0.3909<br />
5: -0.03582 0.4595 -0.3326 0.498 -0.3517<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally,<br />
we apply <tt>sfheaderwindow</tt> to window the input traces selecting<br />
only those for which the header is greater than zero.<br />
<pre><br />
bash$ < random.rsf sfmask min=0 > mask.rsf<br />
bash$ < mask.rsf sfdisfil<br />
0: 0 1 0 0 0 0 1 0 1 0<br />
bash$ < input.rsf sfheaderwindow mask=mask.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 7 7 7 7 7<br />
10: 9 9 9 9 9<br />
</pre><br />
In this case, only three traces are selected for the output. Thanks to<br />
the separation between headers and data, the operation of<br />
<tt>sfheaderwindow</tt> is optimally efficient. <br />
<br />
==sfin==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display basic information about RSF files.<br />
|-<br />
! colspan="4" | sfin info=y check=2. trail=y file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | n1,n2,... are data dimensions<br>o1,o2,... are axis origins<br>d1,d2,... are axis sampling intervals<br>label1,label2,... are axis labels<br>unit1,unit2,... are axis units<br />
|-<br />
| ''float '' || '''check=2.''' || || Portion of the data (in Mb) to check for zero values.<br />
|-<br />
| ''bool '' || '''info=y''' || [y/n] || If n, only display the name of the data file.<br />
|-<br />
| ''bool '' || '''trail=y''' || [y/n] || If n, skip trailing dimensions of one<br />
|}<br />
<br />
<br />
<tt>sfin</tt> is one of the most useful programs for operating with<br />
RSF files. It produces quick information on the file hypercube<br />
dimensions and checks the consistency of the associated data file.<br />
Here is an example. Let us create an RSF file and examine it with <tt>sfin</tt>.<br />
<pre><br />
bash$ sfspike n1=100 n2=20 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=100 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
2000 elements 8000 bytes<br />
</pre><br />
<tt>sfin</tt> reports the following information:<br />
<br />
*location of the data file (<tt>/tmp/spike.rsf\@</tt>) <br />
*element size (4 bytes) <br />
*element type (floating point) <br />
*element form (native) <br />
*hypercube dimensions (100 by 20) <br />
*axes scale (0.004 and 0.1) <br />
*axes origin (0 and 0) <br />
*axes labels <br />
*axes units <br />
*total number of elements <br />
*total number of bytes in the data file <br />
Suppose that the file got corrupted by a buggy program and reports<br />
incorrect dimensions. The <tt>sfin</tt> program should be able to<br />
catch the discrepancy.<br />
<pre><br />
bash$ echo n2=100 >> spike.rsf<br />
bash$ sfin spike.rsf > /dev/null<br />
sfin: Actually 8000 bytes, 20% of expected.<br />
</pre><br />
<tt>sfin</tt> also checks the first records in the file for zeros. <br />
<pre><br />
bash$ sfspike n1=100 n2=100 k2=99 > spike2.rsf<br />
bash$ sfin spike2.rsf >/dev/null<br />
sfin: The first 32768 bytes are all zeros<br />
</pre><br />
The number of bytes to check is adjustable<br />
<pre><br />
bash$ sfin spike2.rsf check=0.01 >/dev/null<br />
sfin: The first 16384 bytes are all zeros<br />
</pre><br />
You can also output only the location of the data file. This is<br />
sometimes handy in scripts.<br />
<pre><br />
bash$ sfin spike.rsf spike2.rsf info=n<br />
/tmp/spike.rsf@ /tmp/spike2.rsf@<br />
</pre><br />
An alternative is to use <tt>sfget</tt>, as follows:<br />
<pre><br />
bash$ sfget parform=n in < spike.rsf<br />
/tmp/spike.rsf@<br />
</pre><br />
<br />
==sfinterleave==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Combine several datasets by interleaving.<br />
|-<br />
! colspan="4" | sfinterleave > out.rsf axis=3 [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis for interleaving<br />
|}<br />
<br />
<br />
<tt>sfinterleave</tt> combines two or more datasets by interleaving them on one<br />
of the axes. Here is a quick example:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ sfscale < one.rsf dscale=2 > two.rsf<br />
bash$ sfdisfil < two.rsf<br />
0: 2 2 2 2 2<br />
5: 2 2 2 2 2<br />
10: 2 2 2 2 2<br />
15: 2 2 2 2 2<br />
20: 2 2 2 2 2<br />
bash$ sfinterleave one.rsf two.rsf axis=1 | sfdisfil<br />
0: 1 2 1 2 1<br />
5: 2 1 2 1 2<br />
10: 1 2 1 2 1<br />
15: 2 1 2 1 2<br />
20: 1 2 1 2 1<br />
25: 2 1 2 1 2<br />
30: 1 2 1 2 1<br />
35: 2 1 2 1 2<br />
40: 1 2 1 2 1<br />
45: 2 1 2 1 2<br />
bash$ sfinterleave < one.rsf two.rsf axis=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 1 1 1 1 1<br />
15: 2 2 2 2 2<br />
20: 1 1 1 1 1<br />
25: 2 2 2 2 2<br />
30: 1 1 1 1 1<br />
35: 2 2 2 2 2<br />
40: 1 1 1 1 1<br />
45: 2 2 2 2 2<br />
</pre><br />
<br />
==sfmask==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a mask.<br />
|-<br />
! colspan="4" | sfmask < in.rsf > out.rsf min=-FLT_MAX max=+FLT_MAX<br />
|-<br />
| colspan="4" | <br>Mask is an integer data with ones and zeros. <br>Ones correspond to input values between min and max.<br><br>The output can be used with sfheaderwindow.<br />
|-<br />
| ''float '' || '''max=+FLT_MAX''' || || maximum header value<br />
|-<br />
| ''float '' || '''min=-FLT_MAX''' || || minimum header value<br />
|}<br />
<br />
<br />
<tt>sfmask</tt> creates an integer output of ones and zeros comparing<br />
the values of the input data to specified <tt>min=</tt> and<br />
<tt>max=</tt> parameters. It is useful for <tt>sfheaderwindow</tt> and<br />
in many other applications. Here is a quick example:<br />
<pre><br />
bash$ sfmath n1=10 output="sin(x1)" > sin.rsf<br />
bash$ < sin.rsf sfdisfil<br />
0: 0 0.8415 0.9093 0.1411 -0.7568<br />
5: -0.9589 -0.2794 0.657 0.9894 0.4121<br />
bash$ < sin.rsf sfmask min=-0.5 max=0.5 | sfdisfil<br />
0: 1 0 0 1 0 0 1 0 0 1<br />
</pre><br />
<br />
==sfmath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations on data files.<br />
|-<br />
! colspan="4" | sfmath > out.rsf type= unit= output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs, conj (for complex data).<br> <br>sfmath will work on float or complex data, but all the input and output<br>files must be of the same data type.<br><br>An alternative to sfmath is sfadd, which may be more efficient, but is<br>less versatile.<br><br>Examples:<br><br>sfmath x=file1.rsf y=file2.rsf power=file3.rsf output='sin((x+2*y)^power)' > out.rsf<br>sfmath < file1.rsf tau=file2.rsf output='exp(tau*input)' > out.rsf<br>sfmath n1=100 type=complex output="exp(I*x1)" > out.rsf<br><br>See also: sfheadermath.<br />
|-<br />
| ''string '' || '''output=''' || || Mathematical description of the output<br />
|-<br />
| ''string '' || '''type=''' || || output data type [float,complex]<br />
|-<br />
| ''string '' || '''unit=''' || || <br />
|}<br />
<br />
<tt>sfmath</tt> is a versatile program for mathematical operations<br />
with RSF files. It can operate with several input file, all of the<br />
same dimensions and data type. The data type can be real (floating<br />
point) or complex. Here is an example that demonstrates several<br />
features of <tt>sfmath</tt>.<br />
<pre><br />
bash$ sfmath n1=629 d1=0.01 o1=0 n2=40 d2=1 o2=5 \<br />
output="x2*(8+sin(6*x1+x2/10))" > rad.rsf<br />
bash$ < rad.rsf sfrtoc | sfmath output="input*exp(I*x1)" > rose.rsf<br />
bash$ < rose.rsf sfgraph title=Rose screenratio=1 wantaxis=n | xtpen<br />
</pre><br />
The first line creates a 2-D dataset that consists of 40 traces 600<br />
samples each. The values of the data are computed with the formula<br />
<font color="#cd4b19">"x2*(8+sin(6*x1+x2/10))"</font>, where <tt>x1</tt> refers to the<br />
coordinate on the first axis, and <tt>x2</tt> is the coordinate of the<br />
second axis. In the second line, we convert the data from real to<br />
complex using <tt>sfrtoc</tt> and produce a complex dataset using<br />
formula <font color="#cd4b19">"input*exp(I*x1)"</font>, where <tt>input</tt> refers to the<br />
input file. Finally, we plot the complex data as a collection of<br />
parametric curves using <tt>sfgraph</tt> and display the result using<br />
<tt>xtpen</tt>. The plot appearing on your screen should look similar<br />
to the figure.<br />
[[Image:rose.png|frame|center|This figure was created with <tt>sfmath</tt>.]]<br />
One possible alternative to the second line above is<br />
<pre><br />
bash$ < rad.rsf sfmath output=x1 > ang.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*cos(a)" > cos.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*sin(a)" > sin.rsf<br />
bash$ sfcmplx cos.rsf sin.rsf > rose.rsf<br />
</pre><br />
Here we refer to input files by names (<tt>r</tt> and <tt>a</tt>) and combine the names in a formula.<br />
<br />
==sfpad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Pad a dataset with zeros.<br />
|-<br />
! colspan="4" | sfpad < in.rsf > out.rsf [beg1= beg2= ... end1= end2=... | n1= n2 = ... | n1out= n2out= ...]<br />
|-<br />
| colspan="4" | begN specifies the number of zeros to add before the beginning of axis N.<br>endN specifies the number of zeros to add after the end of axis N.<br><br>Alternatively:<br><br>nN or nNout specify the output length of axis N, padding occurs at the end.<br>nN and nNout are equivalent.<br />
|}<br />
<br />
<br />
<tt>pad</tt> increases the dimensions of the input dataset by padding<br />
the data with zeroes. Here are some simple examples.<br />
<pre><br />
bash$ sfspike n1=5 n2=3 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
bash$ < one.rsf sfpad n2=5 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 0 0 0 0 0<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfpad beg2=2 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 0 0 0 0<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < one.rsf sfpad beg2=1 end2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfwindow n1=3 | sfpad n1=5 n2=5 beg1=1 beg2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 1 1 1 0<br />
10: 0 1 1 1 0<br />
15: 0 1 1 1 0<br />
20: 0 0 0 0 0<br />
</pre><br />
You can use <tt>sfcat</tt> to pad data with values other than zeroes.<br />
<br />
==sfput==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Input parameters into a header. <br />
|-<br />
! colspan="4" | sfput < in.rsf > out.rsf<br />
|}<br />
<br />
<br />
<tt>sfput</tt> is a very simple program. It simply appends parameters<br />
from the command line to the output RSF file. One can achieve similar<br />
results with editing by hand or with standard Unix utilities like<br />
<tt>sed</tt> and <tt>echo</tt>. <tt>sfput</tt> is sometimes more<br />
convenient because it handles input/output operations similarly to<br />
other regular RSF programs.<br />
<pre><br />
bash$ sfspike n1=10 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
10 elements 40 bytes<br />
bash$ sfput < spike.rsf d1=25 label1=Depth unit1=m > spike2.rsf<br />
bash$ sfin spike2.rsf<br />
spike2.rsf:<br />
in="/tmp/spike2.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=25 o1=0 label1="Depth" unit1="m"<br />
10 elements 40 bytes<br />
</pre><br />
<br />
==sfreal==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extract real (sfreal) or imaginary (sfimag) part of a complex dataset. <br />
|-<br />
! colspan="4" | sfreal < cmplx.rsf > real.rsf<br />
|}<br />
<br />
<br />
<tt>sfreal</tt> extracts the real part of a complex type dataset. The<br />
imaginary part can be extracted with <tt>sfimag</tt>, an the real<br />
and imaginary part can be combined together with <tt>sfcmplx</tt>.<br />
Here is a simple example. Let us first create a complex dataset <br />
with <tt>sfmath</tt><br />
<pre><br />
bash$ sfmath n1=10 type=complex output="(2+I)*x1" > cmplx.rsf<br />
bash$ fdisfil < cmplx.rsf<br />
0: 0, 0i 2, 1i 4, 2i<br />
3: 6, 3i 8, 4i 10, 5i<br />
6: 12, 6i 14, 7i 16, 8i<br />
9: 18, 9i<br />
</pre><br />
Extracting the real part with <tt>sfreal</tt>:<br />
<pre><br />
bash$ sfreal < cmplx.rsf | sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
</pre><br />
Extracting the imaginary part with <tt>sfimag</tt>:<br />
<pre><br />
bash$ sfimag < cmplx.rsf | sfdisfil<br />
0: 0 1 2 3 4<br />
5: 5 6 7 8 9<br />
</pre><br />
<br />
==sfreverse==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Reverse one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfreverse < in.rsf > out.rsf which=-1 verb=false memsize=sf_memsize() opt=<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''opt=''' || || If y, change o and d parameters on the reversed axis;<br />
:if i, don't change o and d<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|-<br />
| ''int '' || '''which=-1''' || || Which axis to reverse.<br />
:To reverse a given axis, start with 0,<br />
:add 1 to number to reverse n1 dimension,<br />
:add 2 to number to reverse n2 dimension,<br />
:add 4 to number to reverse n3 dimension, etc.<br />
:Thus, which=7 would reverse the first three dimensions,<br />
:which=5 just n1 and n3, etc.<br />
:which=0 will just pass the input on through unchanged.<br />
|}<br />
Here is an example of using <tt>sfreverse</tt>. First, let us create a<br />
2-D dataset.<br />
<pre><br />
bash$ sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Reversing the first axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 | sfdisfil<br />
0: 4 3 2 1 0<br />
5: 5 4 3 2 1<br />
10: 6 5 4 3 2<br />
</pre><br />
Reversing the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=2 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
Reversing both the first and the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=3 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
As you can see, the <tt>which=</tt> parameter controls the axes that are<br />
being reversed by encoding them into one number.<br />
When an axis is reversed, what happens with its axis origin and<br />
sampling parameters? This behavior is controlled by <tt>opt=</tt>. In<br />
our example,<br />
<pre><br />
bash$ < test.rsf sfget n1 o1 d1<br />
n1=5<br />
o1=0<br />
d1=1<br />
bash$ < test.rsf sfreverse which=1 | sfget o1 d1<br />
o1=4<br />
d1=-1<br />
</pre><br />
The default behavior (equivalent to <tt>opt=y</tt>) puts the origin<br />
<tt>o1</tt> at the end of the axis and reverses the sampling parameter<br />
<tt>d1</tt>. Using <tt>opt=n</tt> preserves the sampling but reverses<br />
the origin.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=n | sfget o1 d1<br />
o1=-4<br />
d1=1<br />
</pre><br />
Using <tt>opt=i</tt> preserves both the sampling and the origin while<br />
reversing the axis.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=i | sfget o1 d1<br />
o1=0<br />
d1=1<br />
</pre><br />
One of the three possible behaviors may be desirable depending on the<br />
application.<br />
<br />
==sfrm==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Remove RSF files together with their data.<br />
|-<br />
! colspan="4" | sfrm file1.rsf [file2.rsf ...] [-i] [-v] [-f] <br />
|-<br />
| colspan="4" | Mimics the standard Unix rm command.<br><br>See also: sfmv, sfcp.<br />
|}<br />
<br />
<tt>sfrm</tt> is a program for removing RSF files. Its arguments mimic<br />
the arguments of the standard Unix <tt>rm</tt> utility: <tt>-v</tt><br />
for verbosity, <tt>-i</tt> for interactive inquiry, <tt>-f</tt> for<br />
force removal of suspicious files. Unlike the Unix <tt>rm</tt>,<br />
<tt>sfrm</tt> removes both the RSF header files and the binary files<br />
that the headers point to. <br />
Example:<br />
<pre><br />
bash&#36; sfspike n1=10 > spike.rsf datapath=./<br />
bash&#36; sfget in < spike.rsf<br />
in=./spike.rsf@<br />
bash&#36; ls spike*<br />
spike.rsf spike.rsf@<br />
bash&#36; sfrm -v spike.rsf<br />
sfrm: sf_rm: Removing header spike.rsf<br />
sfrm: sf_rm: Removing data ./spike.rsf@<br />
bash&#36; ls spike*<br />
ls: No match.<br />
</pre><br />
==sfrotate==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Rotate a portion of one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfrotate < in.rsf > out.rsf verb=n memsize=sf_memsize() rot#=(0,0,...)<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''rot#=(0,0,...)''' || || length of #-th axis that is moved to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<tt>sfrotate</tt> modifies the input dataset by splitting it into<br />
parts and putting the parts back in a different order. Here is a quick example.<br />
<pre><br />
bash&#36; sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Rotating the first axis by putting the last two columns in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=2 | sfdisfil<br />
0: 3 4 0 1 2<br />
5: 4 5 1 2 3<br />
10: 5 6 2 3 4<br />
</pre><br />
Rotating the second axis by putting the last row in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot2=1 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 0 1 2 3 4<br />
10: 1 2 3 4 5<br />
</pre><br />
Rotating both the first and the second axis:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=3 rot2=1 | sfdisfil<br />
0: 4 5 6 2 3<br />
5: 2 3 4 0 1<br />
10: 3 4 5 1 2<br />
</pre><br />
The transformation is shown schematically in Figure~(fig:rotate).<br />
[[Image:rotate.png|frame|center|Schematic transformation of data with <tt>sfrotate</tt>.]]<br />
<br />
==sfrtoc==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert real data to complex (by adding zero imaginary part).<br />
|-<br />
! colspan="4" | sfrtoc < real.rsf > cmplx.rsf<br />
|-<br />
| colspan="4" | <br>See also: sfcmplx<br />
|}<br />
The input to <tt>sfrtoc</tt> can be any <tt>type=float</tt> dataset:<br />
<pre><br />
bash$ sfspike n1=10 n2=20 n3=30 >real.rsf<br />
bash$ sfin real.rsf<br />
real.rsf:<br />
in="/var/tmp/real.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
</pre><br />
The output dataset will have <tt>type=complex</tt>, and its binary will be twice the size of the input:<br />
<pre><br />
bash$ <real.rsf sfrtoc >complex.rsf<br />
bash$ sfin complex.rsf <br />
complex.rsf:<br />
in="/var/tmp/complex.rsf@"<br />
esize=8 type=complex form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 48000 bytes<br />
</pre><br />
<br />
==sfscale==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Scale data.<br />
|-<br />
! colspan="4" | sfscale < in.rsf > out.rsf axis=0 rscale=0. dscale=1.<br />
|-<br />
| colspan="4" | <br>To scale by a constant factor, you can also use sfmath or sfheadermath.<br />
|-<br />
| ''int '' || '''axis=0''' || || Scale by maximum in the dimensions up to this axis.<br />
|-<br />
| ''float '' || '''dscale=1.''' || || Scale by this factor (works if rscale=0)<br />
|-<br />
| ''float '' || '''rscale=0.''' || || Scale by this factor.<br />
|}<br />
<tt>sfscale</tt> scales the input dataset by a factor. Here<br />
are some simple examples. First, let us create a test dataset.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil <br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Scale every data point by 2:<br />
<pre><br />
bash&#36; < test.rsf sfscale dscale=2 | sfdisfil<br />
0: 2 4 6 8 10<br />
5: 4 8 12 16 20<br />
10: 6 12 18 24 30<br />
</pre><br />
Divide every trace by its maximum value:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=1 | sfdisfil<br />
0: 0.2 0.4 0.6 0.8 1<br />
5: 0.2 0.4 0.6 0.8 1<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
Divide by the maximum value in the whole 2-D dataset:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=2 | sfdisfil<br />
0: 0.06667 0.1333 0.2 0.2667 0.3333<br />
5: 0.1333 0.2667 0.4 0.5333 0.6667<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
The <tt>rscale=</tt> parameter is synonymous to <tt>dscale=</tt> except<br />
when it is equal to zero. With <tt>sfscale dscale=0</tt>, the dataset gets<br />
multiplied by zero. If using <tt>rscale=0</tt>, the other parameters are<br />
used to define scaling. Thus, <tt>sfscale rscale=0 axis=1</tt> is<br />
equivalent to <tt>sfscale axis=1</tt>, and <tt>sfscale rscale=0</tt><br />
is equivalent to <tt>sfscale dscale=1</tt>.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
==sfspike==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate simple data: spikes, boxes, planes, constants.<br />
|-<br />
! colspan="4" | sfspike > spike.rsf mag= nsp=1 k#=[0,...] l#=[k1,k2,...] p#=[0,...] n#= o#=(0,...) d#=(0.004,0.1,0.1,...) label#=(Time,Distance,Distance,...) unit#=[s,km,km,...] title=<br />
|-<br />
| ''float '' || '''d#=(0.004,0.1,0.1,...)''' || || sampling on #-th axis<br />
|-<br />
| ''ints '' || '''k#=[0,...]''' || || spike starting position [nsp]<br />
|-<br />
| ''ints '' || '''l#=[k1,k2,...]''' || || spike ending position [nsp]<br />
|-<br />
| ''string '' || '''label#=(Time,Distance,Distance,...)''' || || label on #-th axis<br />
|-<br />
| ''floats '' || '''mag=''' || || spike magnitudes [nsp]<br />
|-<br />
| ''int '' || '''n#=''' || || dimension of #-th axis<br />
|-<br />
| ''int '' || '''nsp=1''' || || Number of spikes<br />
|-<br />
| ''float '' || '''o#=(0,...)''' || || origin on #-th axis<br />
|-<br />
| ''floats '' || '''p#=[0,...]''' || || spike inclination (in samples) [nsp]<br />
|-<br />
| ''string '' || '''title=''' || || title for plots<br />
|-<br />
| ''string '' || '''unit#=[s,km,km,...]''' || || unit on #-th axis<br />
|}<br />
This is the program for creating a RSF hypercube out of nothing. Calling <tt>sfspike</tt> without specifying the k# or l# parameters will result in a volume filled with values specified by <tt>mag</tt>. To get a file full of 1's, just give <tt>sfspike</tt> the axis values that running <tt>sfin</tt> on your desired output would produce. I.e. if you run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" > out.rsf<br />
</pre><br />
you will obtain the following file:<br />
<pre><br />
bash$ sfin out.rsf<br />
out.rsf:<br />
in="/var/tmp/out.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
300 elements 1200 bytes<br />
</pre><br />
To create a "flat reflector" in the file above, run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5> out2.rsf<br />
</pre><br />
Notice that the values for <tt>k</tt> and <tt>l</tt> are in samples, not in the physical units of the respective axes. The result can be visualised with <br />
<pre><br />
< out2.rsf sfgrey pclip=100 wantscalebar=y title="Illustration of k,l parameters" | xtpen<br />
</pre><br />
which produces the following plot:<br />
<br />
[[Image:sfspike_fig1.png]]<br />
<br />
The <tt>p</tt> parameters can be used to create slanted lines/planes. Specifying <tt>p2=1</tt> means that for each lateral step, the spike will be shifted down with 1 sample. Below is the command and the corresponding graphical output it creates:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=1 |\<br />
sfgrey pclip=100 wantscalebar=y title="Effect of p2=1" | xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig2.png]]<br />
<br />
Sfspike also supports negative and non-integer p values:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=-0.15 |\<br />
sfgrey pclip=100 wantscalebar=y allpos=y color=h title="Effect of p2=-0.15" |xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig3.png]]<br />
<br />
When <tt>nsp</tt> is greater than the number of values for <tt>k</tt> and <tt>l</tt> parameters, the extra spikes will be piled on top of the last one, increasing its amplitude. Look at the amplitude of the last event in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=3 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
and in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=5 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
(pictures coming soon). This feature can easily cause a bug when the number of events is large and they have not been properly counted, or when a new spike was added on a list but <tt>nsp</tt> was not updated.<br />
<br />
==sfspray==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extend a dataset by duplicating in the specified axis dimension.<br />
|-<br />
! colspan="4" | sfspray < in.rsf > out.rsf axis=2 n= d= o= label= unit=<br />
|-<br />
| colspan="4" | This operation is adjoint to sfstack.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to spray<br />
|-<br />
| ''float '' || '''d=''' || || Sampling of the newly created dimension<br />
|-<br />
| ''string '' || '''label=''' || || Label of the newly created dimension<br />
|-<br />
| ''int '' || '''n=''' || || Size of the newly created dimension<br />
|-<br />
| ''float '' || '''o=''' || || Origin of the newly created dimension<br />
|-<br />
| ''string '' || '''unit=''' || || Units of the newly created dimension<br />
|}<br />
<br />
<tt>sfspray</tt> extends the input hypercube by replicating the data<br />
in one of the dimensions. The output dataset acquires one additional<br />
dimension. Here is an example:<br />
Start with a 2-D dataset<br />
<pre><br />
bash&#36; sfmath n1=5 n2=2 output=x1+x2 > test.rsf<br />
bash&#36; sfin test.rsf<br />
test.rsf:<br />
in="/var/tmp/test.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
10 elements 40 bytes<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
</pre><br />
Extend the data in the second dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=2 n=3 > test2.rsf<br />
bash&#36; sfin test2.rsf<br />
test2.rsf:<br />
in="/var/tmp/test2.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=3 d2=1 o2=0 <br />
n3=2 d3=1 o3=0 <br />
30 elements 120 bytes<br />
bash&#36; < test2.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 0 1 2 3 4<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
20: 1 2 3 4 5<br />
25: 1 2 3 4 5<br />
</pre><br />
The output is three-dimensional, with traces from the original<br />
data duplicated along the second axis.<br />
Extend the data in the third dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=3 n=2 > test3.rsf<br />
bash&#36; sfin test3.rsf<br />
test3.rsf:<br />
in="/var/tmp/test3.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
n3=2 d3=? o3=? <br />
20 elements 80 bytes<br />
bash&#36; < test3.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
</pre><br />
The output is also three-dimensional, with the original data replicated<br />
along the third axis.<br />
<br />
==sfstack==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stack a dataset over one of the dimensions.<br />
|-<br />
! colspan="4" | sfstack < in.rsf > out.rsf axis=2 rms=n norm=y min=n max=n<br />
|-<br />
| colspan="4" | <br>This operation is adjoint to sfspray.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to stack<br />
|-<br />
| ''bool '' || '''max=n''' || [y/n] || If y, find maximum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''min=n''' || [y/n] || If y, find minimum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || If y, normalize by fold.<br />
|-<br />
| ''bool '' || '''rms=n''' || [y/n] || If y, compute the root-mean-square instead of stack.<br />
|}<br />
While <tt>sfspray</tt> adds a dimension to a hypercube,<br />
<tt>sfstack</tt> effectively removes one of the dimensions by stacking<br />
over it. Here are some examples:<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
bash&#36; < test.rsf sfstack axis=2 | sfdisfil<br />
0: 1.5 2 3 4 5<br />
bash&#36; < test.rsf sfstack axis=1 | sfdisfil<br />
0: 2.5 3 4<br />
</pre><br />
Why is the first value not 1 (in the first case) or 2 (in the second<br />
case)? By default, <tt>sfstack</tt> normalizes the stack by the fold<br />
(the number of non-zero entries). To avoid normalization, use<br />
<tt>norm=n</tt>, as follows:<br />
<pre><br />
bash&#36; < test.rsf sfstack norm=n | sfdisfil <br />
0: 3 6 9 12 15<br />
</pre><br />
<tt>sfstack</tt> can also compute root-mean-square values as <br />
well as minimum and maximum values.<br />
<pre><br />
bash&#36; < test.rsf sfstack rms=y | sfdisfil<br />
0: 1.581 2.16 3.109 4.082 5.066<br />
bash&#36; < test.rsf sfstack min=y | sfdisfil<br />
0: 0 1 2 3 4<br />
bash&#36; < test.rsf sfstack axis=1 max=y | sfdisfil <br />
0: 4 5 6<br />
</pre><br />
<br />
==sftransp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Transpose two axes in a dataset. <br />
|-<br />
! colspan="4" | sftransp < in.rsf > out.rsf memsize=sf_memsize() plane=<br />
|-<br />
| colspan="4" | <br>If you get a "Cannot allocate memory" error, give the program a<br>memsize=1 command-line parameter to force out-of-core operation.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''plane=''' || || Two-digit number with axes to transpose. The default is 12<br />
|}<br />
<br />
The <tt>sftransp</tt> program transposes the input hypercube<br />
exchanging the two axes specified by the <b>plane=</b> parameter. <br />
<pre><br />
bash&#36; sfspike n1=10 n2=20 n3=30 > orig123.rsf<br />
bash&#36; sfin orig123.rsf <br />
orig123.rsf:<br />
in="/var/tmp/orig123.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=23 >out132.rsf<br />
bash&#36; sfin out132.rsf <br />
out132.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=20 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=13 >out321.rsf<br />
bash&#36; sfin out321.rsf <br />
out321.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=30 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=10 d3=0.004 o3=0 label3="Time" unit3="s" <br />
6000 elements 24000 bytes<br />
</pre><br />
<tt>sftransp</tt> tries to fit the dataset in memory to transpose it<br />
there but, if not enough memory is available, it performs a slower<br />
transpose out of core using disk operations. You can control the<br />
amount of available memory using the <b>memsize=</b> parameter or<br />
the <b>RSFMEMSIZE</b> environmental variable.<br />
<br />
==sfwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a portion of the dataset. <br />
|-<br />
! colspan="4" | sfwindow < in.rsf > out.rsf verb=n squeeze=y j#=(1,...) d#=(d1,d2,...) f#=(0,...) min#=(o1,o2,,...) n#=(0,...) max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)<br />
|-<br />
| ''float '' || '''d#=(d1,d2,...)''' || || sampling in #-th dimension<br />
|-<br />
| ''int '' || '''f#=(0,...)''' || || window start in #-th dimension<br />
|-<br />
| ''int '' || '''j#=(1,...)''' || || jump in #-th dimension<br />
|-<br />
| ''float '' || '''max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)''' || || maximum in #-th dimension<br />
|-<br />
| ''float '' || '''min#=(o1,o2,,...)''' || || minimum in #-th dimension<br />
|-<br />
| ''int '' || '''n#=(0,...)''' || || window size in #-th dimension<br />
|-<br />
| ''bool '' || '''squeeze=y''' || [y/n] || if y, squeeze dimensions equal to 1 to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
<b>sfwindow</b> is used to window a portion of the dataset. Here is<br />
a quick example: Start by creating some data.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Now window the first two rows:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n2=2 | sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
</pre><br />
Window the first three columns:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n1=3 | sfdisfil<br />
0: 1 2 3 2 4<br />
5: 6 3 6 9<br />
</pre><br />
Window the middle row:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f2=1 n2=1 | sfdisfil<br />
0: 2 4 6 8 10<br />
</pre><br />
You can interpret the <b>f#</b> and <b>n#</b> parameters as<br />
meaning "skip that many rows/columns" and "select that many<br />
rows/columns" correspondingly. Window the middle point in the dataset:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f1=2 n1=1 f2=1 n2=1 | sfdisfil<br />
0: 6<br />
</pre><br />
Window every other column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=2 | sfdisfil<br />
0: 1 3 5 2 6<br />
5: 10 3 9 15<br />
</pre><br />
Window every third column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=3 | sfdisfil<br />
0: 1 4 2 8 3<br />
5: 12<br />
</pre><br />
Alternatively, <b>sfwindow</b> can use the minimum and maximum<br />
parameters to select a window. In the following example, we are<br />
creating a dataset with <b>sfspike</b> and then windowing a portion of it<br />
between 1 and 2 seconds in time and sampled at 8 miliseconds.<br />
<pre><br />
bash&#36; sfspike n1=1000 n2=10 > spike.rsf <br />
bash&#36; sfin spike.rsf<br />
spike.rsf:<br />
in="/var/tmp/spike.rsf@"<br />
esize=4 type=float form=native <br />
n1=1000 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10000 elements 40000 bytes<br />
bash&#36; < spike.rsf sfwindow min1=1 max1=2 d1=0.008 > window.rsf<br />
bash&#36; sfin window.rsf<br />
window.rsf:<br />
in="/var/tmp/window.rsf@"<br />
esize=4 type=float form=native <br />
n1=126 d1=0.008 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
1260 elements 5040 bytes<br />
</pre><br />
By default, <b>sfwindow</b> "squeezes" the hypercube dimensions<br />
that are equal to one toward the end of the dataset. Here is an<br />
example of taking a time slice:<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=1 d2=0.004 o2=1 label2="Time" unit2="s" <br />
10 elements 40 bytes<br />
</pre><br />
You can change this behavior by specifying <b>squeeze=n</b>.<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 squeeze=n > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=1 d1=0.004 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10 elements 40 bytes<br />
</pre><br />
<br />
=Seismic programs=<br />
Programs in this category are specific for operations on seismic data. The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/seismic/ system/seismic] in the Madagascar distribution.<br />
<br />
==sfheaderattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Integer header attributes. <br />
|-<br />
! colspan="4" | sfheaderattr < head.rsf<br />
|-<br />
| colspan="4" | <br>Only nonzero values are reported.<br />
|}<br />
<br />
The <tt>sfheaderattr</tt> examines the contents of a trace header file,<br />
typically generated by <tt>sfsegyread</tt>. In the example below, we examine<br />
trace headers in the output of <tt>suplane</tt>, a program from Seismic Unix.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
bash$ sfheaderattr < tfile.rsf<br />
*******************************************<br />
71 headers, 32 traces<br />
key[0]="tracl" min[0]=1 max[31]=32 mean=16.5<br />
key[1]="tracr" min[0]=1 max[31]=32 mean=16.5<br />
key[11]="offset" min[0]=400 max[31]=400 mean=400<br />
key[38]="ns" min[0]=64 max[31]=64 mean=64<br />
key[39]="dt" min[0]=4000 max[31]=4000 mean=4000<br />
*******************************************<br />
</pre><br />
For different standard keywords, a minimum, maximum, and mean values<br />
are reported unless they are identically zero. This quick inspection<br />
can help in identifying meaningful keywords set in the data. The input<br />
data type must be <tt>int</tt>.<br />
<br />
==sfheadermath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations, possibly on header keys. <br />
|-<br />
! colspan="4" | sfheadermath < in.rsf > out.rsf memsize=sf_memsize() output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs<br><br>See also sfmath. <br><br>An addition operation can be performed by sfstack.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''output=''' || || Describes the output in a mathematical notation.<br />
|}<br />
<tt>sfheadermath</tt> is a versatile program for mathematical<br />
operations on rows of the input file. If the input file is an<br />
<tt>n1</tt> by <tt>n2</tt> matrix, the output will be a <tt>1</tt> by<br />
<tt>n2</tt> matrix that contains one row made out of mathematical<br />
operations on the other rows. <tt>sfheadermath</tt> can identify a row<br />
by number or by a standard SEGY keyword. The latter is useful for<br />
processing headers extracted from SEGY or SU files.<br />
Here is an example. First, we create an SU file with <tt>suplane</tt> and convert it to RSF using <tt>sfsegyread</tt>.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
</pre><br />
The trace header information is saved in <tt>tfile.rsf</tt>. It<br />
contains 71 headers for 32 traces in integer format.<br />
<pre><br />
bash$ sfin tfile.rsf<br />
tfile.rsf:<br />
in="/tmp/tfile.rsf@"<br />
esize=4 type=int form=native<br />
n1=71 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
2272 elements 9088 bytes<br />
</pre><br />
Next, we will convert <tt>tfile.rsf</tt> to a floating-point format<br />
and run <tt>sfheadermath</tt> to create a new header.<br />
<pre><br />
bash$ < tfile.rsf sfdd type=float | \<br />
sfheadermath myheader=1 output="sqrt(myheader+(2+10*offset^2))" > new.rsf<br />
bash$ sfin new.rsf<br />
new.rsf:<br />
in="/tmp/new.rsf@"<br />
esize=4 type=float form=native<br />
n1=1 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
32 elements 128 bytes<br />
</pre><br />
We defined "myheader" as being the row number 1 in the input (note<br />
that numbering starts with 0) and combined it with "offset", which<br />
is a standard SEGY keyword that denotes row number 11 (see the output<br />
of <tt>sfheaderattr</tt> above.) A variety of mathematical expressions<br />
can be defined in the <tt>output=</tt> string. The expression<br />
processing engine is shared with <tt>sfmath</tt>.<br />
<br />
==sfsegyheader==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Make a trace header file for segywrite.<br />
|-<br />
! colspan="4" | sfsegyheader < in.rsf > out.rsf n1= d1=<br />
|-<br />
| colspan="4" | <br> Use the output for tfile= argument in segywrite.<br />
|-<br />
| ''float '' || '''d1=''' || || trace sampling<br />
|-<br />
| ''int '' || '''n1=''' || || number of samples in a trace<br />
|}<br />
<br />
==sfsegyread==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert a SEG-Y or SU dataset to RSF.<br />
|-<br />
! colspan="4" | sfsegyread mask=msk.rsf > out.rsf tfile=hdr.rsf verb=false su=false format=sf_segyformat (bhead) ns=sf_segyns (bhead) endian= tape= read= hfile= bfile= mask= tfile=<br />
|-<br />
| colspan="4" | <br>Data headers and trace headers are separated from the data.<br><br>Defined SEG-Y trace header key names and byte offsets:<br><br>tracl: trace sequence number within line 0<br><br>tracr: trace sequence number within reel 4<br><br>fldr: field record number 8 <br><br>tracf: trace number within field record 12 <br><br>ep: energy source point number 16 <br><br>cdp: CDP ensemble number 20 <br><br>cdpt: trace number within CDP ensemble 24 <br><br>trid: trace identification code:<br>1 = seismic data<br>2 = dead<br>3 = dummy<br>4 = time break<br>5 = uphole<br>6 = sweep<br>7 = timing<br>8 = water break<br>9---, N = optional use (N = 32,767) 28 <br><br>nvs: number of vertically summed traces 30 <br><br>nhs: number of horizontally summed traces 32 <br><br>duse: data use:<br>1 = production<br>2 = test 34<br><br>offset: distance from source point to receiver<br>group (negative if opposite to direction<br>in which the line was shot) 36 <br><br>gelev: receiver group elevation from sea level<br>(above sea level is positive) 40 <br><br>selev: source elevation from sea level<br>(above sea level is positive) 44 <br><br>sdepth: source depth (positive) 48 <br><br>gdel: datum elevation at receiver group 52 <br><br>sdel: datum elevation at source 56 <br><br>swdep: water depth at source 60 <br><br>gwdep: water depth at receiver group 64 <br><br>scalel: scale factor for previous 7 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 68 <br><br>scalco: scale factor for next 4 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 70 <br><br>sx: X source coordinate 72 <br><br>sy: Y source coordinate 76 <br><br>gx: X group coordinate 80 <br><br>gy: Y group coordinate 84 <br><br>counit: coordinate units code:<br>for previoius four entries<br>1 = length (meters or feet)<br>2 = seconds of arc (in this case, the<br>X values are unsigned intitude and the Y values<br>are latitude, a positive value designates<br>the number of seconds east of Greenwich<br>or north of the equator 88 <br><br>wevel: weathering velocity 90 <br><br>swevel: subweathering velocity 92 <br><br>sut: uphole time at source 94 <br><br>gut: uphole time at receiver group 96 <br><br>sstat: source static correction 98 <br><br>gstat: group static correction 100 <br><br>tstat: total static applied 102 <br><br>laga: lag time A, time in ms between end of 240-<br>byte trace identification header and time<br>break, positive if time break occurs after<br>end of header, time break is defined as<br>the initiation pulse which maybe recorded<br>on an auxiliary trace or as otherwise<br>specified by the recording system 104 <br><br>lagb: lag time B, time in ms between the time<br>break and the initiation time of the energy source,<br>may be positive or negative 106 <br><br>delrt: delay recording time, time in ms between<br>initiation time of energy source and time<br>when recording of data samples begins<br>(for deep water work if recording does not<br>start at zero time) 108 <br><br>muts: mute time--start 110 <br><br>mute: mute time--end 112 <br><br>ns: number of samples in this trace 114 <br><br>dt: sample interval, in micro-seconds 116 <br><br>gain: gain type of field instruments code:<br>1 = fixed<br>2 = binary<br>3 = floating point<br>4 ---- N = optional use 118 <br><br>igc: instrument gain constant 120 <br><br>igi: instrument early or initial gain 122 <br><br>corr: correlated:<br>1 = no<br>2 = yes 124 <br><br>sfs: sweep frequency at start 126 <br><br>sfe: sweep frequency at end 128 <br><br>slen: sweep length in ms 130 <br><br>styp: sweep type code:<br>1 = linear<br>2 = cos-squared<br>3 = other 132 <br><br>stas: sweep trace length at start in ms 134 <br><br>stae: sweep trace length at end in ms 136 <br><br>tatyp: taper type: 1=linear, 2=cos^2, 3=other 138 <br><br>afilf: alias filter frequency if used 140 <br><br>afils: alias filter slope 142 <br><br>nofilf: notch filter frequency if used 144 <br><br>nofils: notch filter slope 146 <br><br>lcf: low cut frequency if used 148 <br><br>hcf: high cut frequncy if used 150 <br><br>lcs: low cut slope 152 <br><br>hcs: high cut slope 154 <br><br>year: year data recorded 156 <br><br>day: day of year 158 <br><br>hour: hour of day (24 hour clock) 160 <br><br>minute: minute of hour 162 <br><br>sec: second of minute 164 <br><br>timbas: time basis code:<br>1 = local<br>2 = GMT<br>3 = other 166 <br><br>trwf: trace weighting factor, defined as 1/2^N<br>volts for the least sigificant bit 168 <br><br>grnors: geophone group number of roll switch<br>position one 170 <br><br>grnofr: geophone group number of trace one within<br>original field record 172 <br><br>grnlof: geophone group number of last trace within<br>original field record 174 <br><br>gaps: gap size (total number of groups dropped) 176 <br><br>otrav: overtravel taper code:<br>1 = down (or behind)<br>2 = up (or ahead)<br />
|-<br />
| ''string '' || '''bfile=''' || || output binary data header file<br />
|-<br />
| ''bool '' || '''endian=''' || [y/n] || big/little endian flag, the default is estimated automatically<br />
|-<br />
| ''int '' || '''format=sf_segyformat (bhead)''' || [1,2,3,5] || Data format. The default is taken from binary header.<br />
:1 is IBM floating point<br />
:2 is 4-byte integer<br />
:3 is 2-byte integer<br />
:5 is IEEE floating point<br />
|-<br />
| ''string '' || '''hfile=''' || || output text data header file<br />
|-<br />
| ''string '' || '''mask=''' || || optional header mask for reading only selected traces<br />
|-<br />
| ''int '' || '''ns=sf_segyns (bhead)''' || || Number of samples. The default is taken from binary header<br />
|-<br />
| ''string '' || '''read=''' || || what to read: h - header, d - data, b - both (default)<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if input is SU, n if input is SEGY<br />
|-<br />
| ''bool '' || '''suxdr=n''' || [y/n] || y, SU has XDR support<br />
|-<br />
| ''string '' || '''tape=''' || || <br />
|-<br />
| ''string '' || '''tfile=''' || || output trace header file<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
The SEG Y format is an [http://en.wikipedia.org/wiki/Open_standard open standard] for the exchange of geophysical data. It is controlled by the non-profit [http://www.seg.org/SEGportalWEBproject/portals/SEG_Online.portal?_nfpb=true&_pageLabel=pg_gen_content&Doc_Url=prod/SEG-Publications/Pub-Yearbook/committees.htm SEG Technical Standards Committee]. There are two versions of this standard: [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev0.pdf rev0] (1975)<ref>Barry, K.M., Cavers, D.A., and Kneale, C.W. 1975. Recommended standards for digital tape formats. ''Geophysics'', '''40''', no. 02, 344–352.</ref> and [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf rev1] (2002)<ref>Norris, M.W., Faichney, A.K., ''Eds''. 2001. SEG Y rev1 Data Exchange format. Society of Exploration Geophysicists, Tulsa, OK, 45 pp.</ref>. The implementation in <tt>sfsegyread</tt> is a mixture of rev0 (i.e. no checks for Extended Textual Headers) and rev1 ([http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE floating point format] allowed for trace data samples).<br />
<br />
A SEG-Y file as understood by <tt>sfsegyread</tt> contains a "Reel Identification Header" (3200 bytes in EBCDIC followed by 400 bytes in a binary encoding), followed by a number of "Trace Blocks". Each "Trace Block" contains a 240-byte "Trace Header" (binary) followed by "Trace Data" -- a sequence of <tt>ns</tt> samples. Binary values in both reel headers and trace headers are two's complement integers, either two bytes or four bytes long. There are no floating-point values defined in the headers. Trace Data samples can have various encodings, either floating point or integer, described further down, but they are all big-endian. To convert from SEG-Y to RSF, <tt>sfsegyread</tt> will strip the tape reel EBCDIC header and convert it to ASCII, will extract the reel binary header without changing it, and will put the trace headers into one RSF file, and the traces themselves on another.<br />
<br />
===SEG-Y Trace Headers===<br />
In the SEG-Y standard, only the first 180 bytes of the 240-byte trace header are defined; bytes 181-240 are reserved for non-standard header information, and these locations are increasingly used in modern SEG-Y files and its variants. The standard provides for a total of 71 4-byte and 2-byte predefined header words. These 71 standard words have defined lengths and byte offsets, and only these words and byte locations are read using <tt>segyread</tt> and output to the RSF header file with the <tt>hfile=</tt> option. The user may remap these predefined keywords to a different byte offsets.<br />
<br />
===SU File Format===<br />
An [http://www.cwp.mines.edu/sututor/node22.html SU file] is nothing more than a SEG-Y file without the reel headers, and with the Trace Data samples in the native encoding of the CPU the file was created on (Attention -- limited portability!). So, to convert from SU to RSF, <tt>sfsegyread</tt> will just separate headers and traces into two RSF files. <br />
<br />
===SEG-Y specific parameters===<br />
*<tt>hfile=</tt> specifies the name of the file in which the EBCDIC reel header will be put after conversion to ASCII. If you are certain there is no useful information in it, <tt>hfile=/dev/null</tt> works just fine. If you do not specify anything for this parameter you will get an ASCII file named <tt>header</tt> in the current directory. If you want to quickly preview this header before running <tt>sfsegyread</tt>, use<pre>dd if=input.segy count=40 bs=80 cbs=80 conv=unblock,ascii</pre><br />
*<tt>bfile=</tt> specifies name of the file in which the binary reel header (the 400-bytes thing following the 3600-bytes EBCDIC) will be put without any conversion. The default name is "binary". Unless you have software that knows how to read exactly this special type of file, it will be completely useless, so do <tt>bfile=/dev/null</tt><br />
*<tt>format=</tt> specifies the format in which the trace data samples are in the SEG-Y input file. This is read from the binary reel header of the SEG-Y file. Valid values are 1(IBM floating point), 2 (4-byte integer), 3 (2-byte integer) and 5 (IEEE floating point). If the input file is SU, the format will be assumed to be the native <tt>float</tt> format.<br />
<br />
*<tt>keyname=</tt> specifies the byte offset to remap a header using the trace header key names shown above. For example, if the CDP locations have been placed in bytes 181-184 instead of the standard 21-24, <tt>cdp=180</tt> will remap the trace header to that location. <br />
<br />
===SU-specific parameters===<br />
*<tt>suxdr=</tt> specifies whether the input file was created with a SU package with XDR support enabled. If you have access to the source code of your SU install (try <tt>$CWPROOT/src</tt>), type: <tt>grep 'XDRFLAG =' $CWPROOT/src/Makefile.config</tt> and look at the last uncommented entry. If no value is given for <tt>XDRFLAG</tt>, the package was not compiled with XDR support.<br />
===Common parameters===<br />
*<tt>su=</tt> specifies if the input file is SU or SEG-Y. Default is <tt>su=n</tt> (SEG-Y file).<br />
*<tt>tape=</tt> specifies the input data. Stdin could not be used because <tt>sfsegyread</tt> has to work with tapes, and needs to fseek back and forth through the input file. Thankfully, output is on stdout.<br />
*<tt>read=</tt> specifies what parts of the "Trace Blocks" will be read. It can be <tt>read=t</tt> (only trace data is read), <tt>read=h</tt> (only trace headers are read) or <tt>read=b</tt> (both are read).<br />
*<tt>tfile=</tt> gives the name of the RSF file to which trace headers are written. Obviously, it should be only specified with <tt>read=h</tt> or <tt>read=b</tt>.<br />
*<tt>mask=</tt> is an optional parameter specifying the name of a mask that says which traces will be read. The mask is a 1-D RSF file with integers. The number of samples in the mask is the same as the number of traces in the unmasked SEG-Y. In places corresponding to unwanted traces there should be zeros in the mask.<br />
*<tt>ns=</tt> specifies the number of samples in a trace. For SEG-Y files, the default is taken from the binary reel header, and for SU files, from the header of the first trace. This parameter is however critical enough that a command line override was given for it.<br />
*<tt>verbose=</tt> is the verbosity flag. Can be <tt>y</tt> or <tt>n</tt>.<br />
*<tt>endian=</tt> is a y/n flag (default y), specifying whether to automatically estimate or not if samples in the Trace Data blocks are big-endian or little-endian. Try it if you are in trouble and do not know what else to do, otherwise let the automatic estimation do its job.<br />
<br />
==sfsegywrite==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert an RSF dataset to SEGY or SU.<br />
|-<br />
! colspan="4" | sfsegywrite < in.rsf tfile=hdr.rsf verb=false su=false endian=sf_endian() tape= hfile= bfile=<br />
|-<br />
| colspan="4" | <br>Merges trace headers with data.<br />
|-<br />
| ''string '' || '''bfile=''' || || input binary data header file<br />
|-<br />
| ''bool '' || '''endian=sf_endian()''' || [y/n] || big/little endian flag. The default is estimated automatically<br />
|-<br />
| ''string '' || '''hfile=''' || || input text data header file<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if output is SU, n if output is SEGY<br />
|-<br />
| ''string '' || '''tape=''' || ||<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
Please see <tt>sfsegyread</tt> for a complete description of parameter meanings and background issues. Parameters <tt>bfile</tt> and <tt>hfile</tt> should only be given values when the desired file is SEG-Y (default). The output file is specified by the <tt>tape=</tt> tag.<br />
<br />
=Plotting programs=<br />
The source files for these programs can be found under<br />
[http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/plot/main/ plot/main]<br />
in the Madagascar distribution.<br />
<br />
THIS SECTION IS UNDER CONSTRUCTION<br />
<br />
==sfbox==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Draw a balloon-style label.<br />
|-<br />
! colspan="4" | sfbox lab_color=VP_WHITE lab_fat=0 pscale=1. pointer=y reverse=n lat=0. long=90. angle=0. x0=0. y0=0. scale0=1. xt=2. yt=0. x_oval=0. y_oval=0. boxit=y length= scalet= size=.25 label= > out.vpl<br />
|-<br />
| ''float '' || '''angle=0.''' || || longitude of floating label in 3-D<br />
|-<br />
| ''bool '' || '''boxit=y''' || [y/n] || if y, create a box around text<br />
|-<br />
| ''int '' || '''lab_color=VP_WHITE''' || || label color<br />
|-<br />
| ''int '' || '''lab_fat=0''' || || label fatness<br />
|-<br />
| ''string '' || '''label=''' || || text for label<br />
|-<br />
| ''float '' || '''lat=0.''' || || <br />
|-<br />
| ''float '' || '''length=''' || || normalization for xt and yt<br />
|-<br />
| ''float '' || '''long=90.''' || || latitude and longitude of viewpoint in 3-D<br />
|-<br />
| ''bool '' || '''pointer=y''' || [y/n] || if y, create arrow pointer<br />
|-<br />
| ''float '' || '''pscale=1.''' || || scale factor for width of pointer<br />
|-<br />
| ''bool '' || '''reverse=n''' || [y/n] || <br />
|-<br />
| ''float '' || '''scale0=1.''' || || scale factor for x0 and y0<br />
|-<br />
| ''float '' || '''scalet=''' || || <br />
|-<br />
| ''float '' || '''size=.25''' || || text height in inches<br />
|-<br />
| ''float '' || '''x0=0.''' || || <br />
|-<br />
| ''float '' || '''x_oval=0.''' || || <br />
|-<br />
| ''float '' || '''xt=2.''' || || <br />
|-<br />
| ''float '' || '''y0=0.''' || || position of the pointer tip<br />
|-<br />
| ''float '' || '''y_oval=0.''' || || size of the oval around pointer<br />
|-<br />
| ''float '' || '''yt=0.''' || || relative position of text<br />
|}<br />
==sfcontour==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Contour plot.<br />
|-<br />
! colspan="4" | sfcontour < in.rsf c= min1=o1 min2=o2 max1=o1+(n1-1)*d1 max2=o2+(n2-1)*d2 nc=50 dc= c0= transp=y minval= maxval= allpos=y barlabel= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=y''' || [y/n] || contour positive values only<br />
|-<br />
| ''string '' || '''barlabel=''' || || <br />
|-<br />
| ''floats '' || '''c=''' || || [nc]<br />
|-<br />
| ''float '' || '''c0=''' || || first contour<br />
|-<br />
| ''float '' || '''dc=''' || || contour increment<br />
|-<br />
| ''float '' || '''max1=o1+(n1-1)*d1''' || || <br />
|-<br />
| ''float '' || '''max2=o2+(n2-1)*d2''' || || data window to plot<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''min1=o1''' || || <br />
|-<br />
| ''float '' || '''min2=o2''' || || <br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nc=50''' || || number of contours<br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfdots==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot signal with lollipops.<br />
|-<br />
! colspan="4" | sfdots < in.rsf labels= dots=(n1 <= 130)? 1: 0 seemean=(bool) (n2 <= 30) strings=(bool) (n1 <= 400) connect=1 corners= silk=n gaineach=y labelsz=8 yreverse=n constsep=n seedead=n transp=n xxscale=1. yyscale=1. clip=-1. overlap=0.9 screenratio=VP_SCREEN_RATIO screenht=VP_STANDARD_HEIGHT screenwd=screenhigh / screenratio radius=dd1/3 label1= unit1= title= > plot.vpl<br />
|-<br />
| ''float '' || '''clip=-1.''' || || data clip<br />
|-<br />
| ''int '' || '''connect=1''' || || connection type: 1 - diagonal, 2 - bar, 4 - only for non-zero data<br />
|-<br />
| ''bool '' || '''constsep=n''' || [y/n] || if y, use constant trace separation<br />
|-<br />
| ''int '' || '''corners=''' || || number of polygon corners (default is 6)<br />
|-<br />
| ''int '' || '''dots=(n1 <= 130)? 1: 0''' || || type of dots: 1 - baloon, 0 - no dots, 2 - only for non-zero data<br />
|-<br />
| ''bool '' || '''gaineach=y''' || [y/n] || if y, gain each trace independently<br />
|-<br />
| ''string '' || '''label1=''' || || <br />
|-<br />
| ''strings'' || '''labels=''' || || trace labels [n2]<br />
|-<br />
| ''int '' || '''labelsz=8''' || || label size<br />
|-<br />
| ''float '' || '''overlap=0.9''' || || trace overlap<br />
|-<br />
| ''float '' || '''radius=dd1/3''' || || dot radius<br />
|-<br />
| ''float '' || '''screenht=VP_STANDARD_HEIGHT''' || || screen height<br />
|-<br />
| ''float '' || '''screenratio=VP_SCREEN_RATIO''' || || screen aspect ratio<br />
|-<br />
| ''float '' || '''screenwd=screenhigh / screenratio''' || || screen width<br />
|-<br />
| ''bool '' || '''seedead=n''' || [y/n] || if y, show zero traces<br />
|-<br />
| ''bool '' || '''seemean=(bool) (n2 <= 30)''' || [y/n] || if y, draw axis lines<br />
|-<br />
| ''bool '' || '''silk=n''' || [y/n] || if y, silky plot<br />
|-<br />
| ''bool '' || '''strings=(bool) (n1 <= 400)''' || [y/n] || if y, draw strings<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axis<br />
|-<br />
| ''string '' || '''unit1=''' || || <br />
|-<br />
| ''float '' || '''xxscale=1.''' || || x scaling<br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse y axis<br />
|-<br />
| ''float '' || '''yyscale=1.''' || || y scaling<br />
|}<br />
==sfgraph3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot for surfaces.<br />
|-<br />
! colspan="4" | sfgraph3 < in.rsf orient=1 min= max= point1=0.5 point2=0.5 frame1=0.5*(min+max) frame2=n1-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y > plot.vpl<br />
|-<br />
| ''float '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''float '' || '''frame1=0.5*(min+max)''' || || <br />
|-<br />
| ''int '' || '''frame2=n1-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''max=''' || || maximum function value<br />
|-<br />
| ''float '' || '''min=''' || || minimum function value<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''orient=1''' || || function orientation<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|}<br />
==sfgraph==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Graph plot.<br />
|-<br />
! colspan="4" | sfgraph < in.rsf symbolsz= pclip=100. transp=n symbol= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''pclip=100.''' || || clip percentile<br />
|-<br />
| ''string '' || '''symbol=''' || || if set, plot with symbols instead of lines<br />
|-<br />
| ''floats '' || '''symbolsz=''' || || symbol size (default is 2) [n2]<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfgrey3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot.<br />
|-<br />
! colspan="4" | sfgrey3 < in.rsf point1=0.5 point2=0.5 frame1=0 frame2=n2-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y scalebar=n minval= maxval= barreverse=n nreserve=8 bar= color= > plot.vpl<br />
|-<br />
| colspan="4" | Requires an "unsigned char" input (the output of sfbyte).<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''int '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''int '' || '''frame1=0''' || || <br />
|-<br />
| ''int '' || '''frame2=n2-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || if y, draw scalebar<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
for sfgrey and sfgrey3. Examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfgrey==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate raster plot.<br />
|-<br />
! colspan="4" | sfgrey < in.rsf > out.rsf bar=bar.rsf transp=y yreverse=y xreverse=n gpow= phalf= clip= pclip= gainstep=0.5+n1/256. allpos=n bias=0. polarity=n verb=n scalebar=n minval= maxval= barreverse=n wantframenum=(bool) (n3 > 1) nreserve=8 gainpanel= bar= color= > (plot.vpl | char.rsf)<br />
|-<br />
| colspan="4" | Can input char values.<br>If called "byte", outputs char values.<br><br>Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=n''' || [y/n] || if y, assume positive data<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=''' || || <br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''string '' || '''gainpanel=''' || || gain reference: 'a' for all, 'e' for each, or number<br />
|-<br />
| ''int '' || '''gainstep=0.5+n1/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=''' || || <br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''pclip=''' || || data clip percentile (default is 99)<br />
|-<br />
| ''float '' || '''phalf=''' || || percentage for estimating gpow<br />
|-<br />
| ''bool '' || '''polarity=n''' || [y/n] || if y, reverse polarity (white is high by default)<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the display axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''bool '' || '''wantframenum=(bool) (n3 > 1)''' || [y/n] || if y, display third axis position in the corner<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''bool '' || '''yreverse=y''' || [y/n] || if y, reverse the vertical axis<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
and examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfplas==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Assembler - convert ascii to vplot. <br />
|-<br />
! colspan="4" | sfplas<br />
|}<br />
==sfpldb==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Debugger - convert vplot to ascii. <br />
|-<br />
! colspan="4" | sfpldb<br />
|}<br />
==sfplotrays==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot rays.<br />
|-<br />
! colspan="4" | sfplotrays frame=frame.rsf nt=n1*n2 jr=1 frame= < rays.rsf > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''string '' || '''frame=''' || || <br />
|-<br />
| ''int '' || '''jr=1''' || || skip rays<br />
|-<br />
| ''int '' || '''nt=n1*n2''' || || maximum ray length<br />
|}<br />
==sfthplot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Hidden-line surface plot.<br />
|-<br />
! colspan="4" | sfthplot < in.rsf uflag=y dflag=y alpha=45. titlsz=9 axissz=6 plotfat=0 titlefat=2 axisfat=2 plotcolup=VP_YELLOW plotcoldn=VP_RED axis=y axis1=y axis2=y axis3=y clip=0. pclip=100. gainstep=0.5+nx/256. bias=0. dclip=1. norm=y xc=1.5 zc=3 ratio=5. zmax= zmin= sz=6. label#= unit#= tpow=0 epow=0 gpow=1 title= > plot.vpl<br />
|-<br />
| ''float '' || '''alpha=45.''' || || apparent angle in degrees, |alpha| < 89<br />
|-<br />
| ''bool '' || '''axis=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis1=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis2=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis3=y''' || [y/n] || plot axis<br />
|-<br />
| ''int '' || '''axisfat=2''' || || axes fatness<br />
|-<br />
| ''int '' || '''axissz=6''' || || axes size<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip<br />
|-<br />
| ''float '' || '''dclip=1.''' || || change the clip: clip *= dclip<br />
|-<br />
| ''bool '' || '''dflag=y''' || [y/n] || if y, plot down side of the surface<br />
|-<br />
| ''float '' || '''epow=0''' || || exponential gain<br />
|-<br />
| ''int '' || '''gainstep=0.5+nx/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=1''' || || power gain<br />
|-<br />
| ''string '' || '''label#=''' || || label on #-th axis<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || normalize by the clip<br />
|-<br />
| ''float '' || '''pclip=100.''' || || data clip percentile<br />
|-<br />
| ''int '' || '''plotcoldn=VP_RED''' || || color of the lower side<br />
|-<br />
| ''int '' || '''plotcolup=VP_YELLOW''' || || color of the upper side<br />
|-<br />
| ''int '' || '''plotfat=0''' || || line fatness<br />
|-<br />
| ''float '' || '''ratio=5.''' || || plot adjustment<br />
|-<br />
| ''float '' || '''sz=6.''' || || vertical scale<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''int '' || '''titlefat=2''' || || title fatness<br />
|-<br />
| ''int '' || '''titlsz=9''' || || title size<br />
|-<br />
| ''string '' || '''tpow=0''' || || time power gain<br />
|-<br />
| ''bool '' || '''uflag=y''' || [y/n] || if y, plot upper side of the surface<br />
|-<br />
| ''string '' || '''unit#=''' || || unit on #-th axis<br />
|-<br />
| ''float '' || '''xc=1.5''' || || <br />
|-<br />
| ''float '' || '''zc=3''' || || lower left corner of the plot<br />
|-<br />
| ''float '' || '''zmax=''' || || <br />
|-<br />
| ''float '' || '''zmin=''' || || <br />
|}<br />
==sfwiggle==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot data with wiggly traces. <br />
|-<br />
! colspan="4" | sfwiggle < in.rsf xpos=xpos.rsf xmax= xmin= poly=n fatp=1 xmask=1 ymask=1 pclip=98. zplot=0.75 clip=0. seemean=n verb=n transp=n yreverse=n xreverse=n xpos= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip (estimated from pclip by default<br />
|-<br />
| ''int '' || '''fatp=1''' || || <br />
|-<br />
| ''float '' || '''pclip=98.''' || || clip percentile<br />
|-<br />
| ''bool '' || '''poly=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''seemean=n''' || [y/n] || if y, plot mean lines of traces<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''int '' || '''xmask=1''' || || <br />
|-<br />
| ''float '' || '''xmax=''' || || maximum trace position (if using xpos)<br />
|-<br />
| ''float '' || '''xmin=''' || || minimum trace position (if using xpos)<br />
|-<br />
| ''string '' || '''xpos=''' || || optional header file with trace positions<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''int '' || '''ymask=1''' || || <br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse the vertical axis<br />
|-<br />
| ''float '' || '''zplot=0.75''' || || <br />
|}<br />
<br />
=filt/imag programs=<br />
==sfremap1==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 1-D ENO interpolation. <br />
|-<br />
! colspan="4" | sfremap1 < in.rsf > out.rsf pattern=pattern.rsf n1=n1 d1=d1 o1=o1 order=3<br />
|-<br />
| ''float '' || '''d1=d1''' || || Output sampling<br />
|-<br />
| ''int '' || '''n1=n1''' || || Number of output samples<br />
|-<br />
| ''float '' || '''o1=o1''' || || Output origin<br />
|-<br />
| ''int '' || '''order=3''' || || Interpolation order<br />
|-<br />
| ''string '' || '''pattern=''' || || auxiliary input file name<br />
|}<br />
To give an example of usage, we will create an input for <tt>sfremap1</tt> with:<br />
<pre><br />
sfmath n1=11 n2=11 d1=1 d2=1 o1=-5 o2=-5 output="x1*x1+x2*x2" > inp2remap1.rsf<br />
</pre><br />
Let us interpolate the data across both dimensions, then display it:<br />
<pre><br />
&lt; inp2remap1.rsf sfremap1 n1=1001 d1=0.01 | sftransp | \<br />
sfremap1 n1=1001 d1=0.01 | sftransp | sfgrey allpos=y | xtpen<br />
</pre><br />
The comparison with the uninterpolated data ( <tt>&lt; inp2remap1.rsf sfgrey allpos=y | xtpen</tt> ) is quite telling.<br />
<br />
=filt/proc programs=<br />
==sfstretch==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stretch of the time axis. <br />
|-<br />
! colspan="4" | sfstretch < in.rsf > out.rsf datum=dat.rsf inv=n dens=1 v0= half=y delay= tdelay= hdelay= nout=dens*n1 extend=4 mute=0 maxstr=0 rule=<br />
|-<br />
| ''file '' || '''datum=''' || || auxiliary input file name<br />
|-<br />
| ''float '' || '''delay=''' || || time delay for rule=lmo<br />
|-<br />
| ''int '' || '''dens=1''' || || axis stretching factor<br />
|-<br />
| ''int '' || '''extend=4''' || || trace extension<br />
|-<br />
| ''bool '' || '''half=y''' || [y/n] || if y, the second axis is half-offset instead of full offset<br />
|-<br />
| ''float '' || '''hdelay=''' || || offset delay for rule=rad<br />
|-<br />
| ''bool '' || '''inv=n''' || [y/n] || if y, do inverse stretching<br />
|-<br />
| ''float '' || '''maxstr=0''' || || maximum stretch<br />
|-<br />
| ''int '' || '''mute=0''' || || tapering size<br />
|-<br />
| ''int '' || '''nout=dens*n1''' || || output axis length (if inv=n)<br />
|-<br />
| ''string '' || '''rule=''' || || Stretch rule:<br />
:n - normal moveout (nmostretch), default<br />
:l - linear moveout (lmostretch)<br />
:L - logarithmic stretch (logstretch)<br />
:2 - t^2 stretch (t2stretch)<br />
:c - t^2 chebyshev stretch (t2chebstretch)<br />
:r - radial moveout (radstretch)<br />
:d - datuming (datstretch)<br />
|-<br />
| ''float '' || '''tdelay=''' || || time delay for rule=rad<br />
|-<br />
| ''float '' || '''v0=''' || || moveout velocity<br />
|}<br />
<br />
<tt>sfstretch rule=d</tt> (aka <tt>sfdatstretch</tt>) can be used to apply statics. Here is a synthetic example, courtesy of Alessandro Frigeri:<br />
<pre><br />
# generate a dataset with 'flat' signals<br />
sfmath n1=200 n2=100 output="sin(0.5*x1)" type=float > scan.rsf<br />
<br />
# generate a sinusoidal elevation correction<br />
sfmath n1=100 output="3*sin(x1)" type=float > statics.rsf<br />
<br />
# apply statics, producing a 'wavy' output.<br />
sfstretch < scan.rsf > out.rsf datum=statics.rsf rule=d<br />
</pre><br />
<br />
=user/ivlad programs=<br />
==sfprep4plot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Resamples a 2-D dataset to the desired picture resolution, with antialias<br />
|-<br />
! colspan="4" | sfprep4plot inp= out= verb=n h=none w=none unit= ppi= prar=y<br />
|-<br />
| colspan="4" | Only one of the h and w parameters needs to be specified.<br>If prar=n, no action will be taken on axis for which h/w was not specified<br>If prar=y and only one par (h or w) is specified, the picture will scale<br>along both axes until it is of the specified dimension.<br />
|-<br />
| ''int '' || '''h=none''' || || output height<br />
|-<br />
| ''string '' || '''inp=''' || || input file<br />
|-<br />
| ''string '' || '''out=''' || || output file<br />
|-<br />
| ''int '' || '''ppi=''' || || output resolution (px/in). Necessary when unit!=px<br />
|-<br />
| ''bool '' || '''prar=y''' || [y/n] || if y, PReserve Aspect Ratio of input<br />
|-<br />
| ''string '' || '''unit=''' || || unit of h and w. Can be: px(default), mm, cm, in<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || if y, print system commands, outputs<br />
|-<br />
| ''int '' || '''w=none''' || || output width<br />
|}<br />
For a figure that does not need the aspect ratio preserved,<br />
and needs to fill a 1280x1024 projector display:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=1280 h=1024 prar=n<br />
</pre><br />
For a print figure that has to fit in a 6x8in box<br />
at a resolution of 250 dpi, preserving the aspect ratio:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=6 h=8 unit=in ppi=250<br />
</pre><br />
A comparison of images before and after the application of <tt>sfprep4plot</tt>, courtesy of Joachim Mispel, is shown below:<br />
<br />
[[Image:sf_prep4plot.jpg]]<br />
<br />
=user/jennings programs=<br />
==sfsizes==<br />
{| class="wikitable" align="center"<br />
! colspan="4" style="background:#ffdead;" | Display the size of RSF files.<br />
|-<br />
! colspan="4" | sfsizes files=y human=n file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | Prints the element size, number of elements, and number of bytes<br>for a list of RSF files. Non-RSF files are ignored.<br />
|-<br />
| ''bool '' || '''files=y''' || [y/n] || If y, print size of each file. If n, print only total.<br />
|-<br />
| ''bool '' || '''human=n''' || [y/n] || If y, print human-readable file size. If n, print byte count.<br />
|}<br />
<br />
=References=<br />
<references/></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Guide_to_madagascar_programs&diff=704Guide to madagascar programs2009-03-12T13:37:56Z<p>Jenningsjwj: </p>
<hr />
<div><center><font size="-1">''This page was created from the LaTeX source in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/rsf/rsf/prog.tex?view=markup book/rsf/rsf/prog.tex] using [[latex2wiki]]''</font></center><br />
<br />
This guide introduces some of the most used <tt>madagascar</tt> programs and illustrates their usage with examples.<br />
=Main programs=<br />
The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/ system/main] in the Madagascar distribution. The "main" programs perform general-purpose operations on RSF hypercubes regardless of the data dimensionality or physical dimensions.<br />
<br />
==sfadd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Add, multiply, or divide RSF datasets.<br />
|-<br />
! colspan="4" | sfadd > out.rsf scale= add= sqrt= abs= log= exp= mode= [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | The various operations, if selected, occur in the following order:<br><br>(1) Take absolute value, abs=<br>(2) Add a scalar, add=<br>(3) Take the natural logarithm, log=<br>(4) Take the square root, sqrt=<br>(5) Multiply by a scalar, scale=<br>(6) Compute the base-e exponential, exp=<br>(7) Add, multiply, or divide the data sets, mode=<br><br>sfadd operates on integer, float, or complex data, but all the input<br>and output files must be of the same data type.<br><br>An alternative to sfadd is sfmath, which is more versatile, but may be<br>less efficient.<br />
|-<br />
| ''bools '' || '''abs=''' || || If true take absolute value [nin]<br />
|-<br />
| ''floats '' || '''add=''' || || Scalar values to add to each dataset [nin]<br />
|-<br />
| ''bools '' || '''exp=''' || || If true compute exponential [nin]<br />
|-<br />
| ''bools '' || '''log=''' || || If true take logarithm [nin]<br />
|-<br />
| ''string '' || '''mode=''' || || 'a' means add (default), <br> 'p' or 'm' means multiply, <br> 'd' means divide<br />
|-<br />
| ''floats '' || '''scale=''' || || Scalar values to multiply each dataset with [nin]<br />
|-<br />
| ''bools '' || '''sqrt=''' || || If true take square root [nin]<br />
|}<br />
<br />
<tt>sfadd</tt> is useful for combining (adding, dividing, or<br />
multiplying) several datasets. What if you want to subtract two<br />
datasets? Easy. Use the <tt>scale</tt> parameter as follows:<br />
<pre><br />
bash&#36; sfadd data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfadd < data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
The same task can be accomplished with the more general <tt>sfmath</tt> program:<br />
<pre><br />
bash&#36; sfmath one=data1.rsf two=data2.rsf output='one-two' > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfmath < data1.rsf two=data2.rsf output='input-two' > diff.rsf<br />
</pre><br />
In both cases, the size and shape of <tt>data1.rsf</tt> and<br />
<tt>data2.rsf</tt> hypercubes should be the same, and a warning<br />
message is printed out if the the axis sampling parameters (such as<br />
<tt>o1</tt> or <tt>d1</tt>) in these files are different.<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/add.c?view=markup user/main/add.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
/* find number of input files */<br />
if (isatty(fileno(stdin))) { <br />
/* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Collect input files in the <tt>in</tt> array from all command-line<br />
parameters that don't contain an "<tt>=</tt>" sign. The total number<br />
of input files in <tt>nin</tt>.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) continue; <br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
/* nin = no of input files*/<br />
</c><br />
<br />
A helper function <tt>check_compat</tt> checks the compatibility of<br />
input files.<br />
<c><br />
static void <br />
check_compat (sf_datatype type /* data type */, <br />
size_t nin /* number of files */, <br />
sf_file* in /* input files [nin] */, <br />
int dim /* file dimensionality */, <br />
const int* n /* dimensions [dim] */)<br />
/* Check that the input files are compatible. <br />
Issue error for type mismatch or size mismatch.<br />
Issue warning for grid parameters mismatch. */<br />
{<br />
int ni, id;<br />
size_t i;<br />
float d, di, o, oi;<br />
char key[3];<br />
const float tol=1.e-5; /* tolerance for comparison */<br />
<br />
for (i=1; i < nin; i++) {<br />
if (sf_gettype(in[i]) != type) <br />
sf_error ("type mismatch: need %d",type);<br />
for (id=1; id <= dim; id++) {<br />
(void) snprintf(key,3,"n%d",id);<br />
if (!sf_histint(in[i],key,&ni) || ni != n[id-1])<br />
sf_error("%s mismatch: need %d",key,n[id-1]);<br />
(void) snprintf(key,3,"d%d",id);<br />
if (sf_histfloat(in[0],key,&d)) {<br />
if (!sf_histfloat(in[i],key,&di) || <br />
(fabsf(di-d) > tol*fabsf(d)))<br />
sf_warning("%s mismatch: need %g",key,d);<br />
} else {<br />
d = 1.;<br />
}<br />
(void) snprintf(key,3,"o%d",id);<br />
if (sf_histfloat(in[0],key,&o) && <br />
(!sf_histfloat(in[i],key,&oi) || <br />
(fabsf(oi-o) > tol*fabsf(d))))<br />
sf_warning("%s mismatch: need %g",key,o);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
Finally, we enter the main loop, where input data are getting read<br />
buffer by buffer and combined in the total product depending on the<br />
data type.<br />
<c><br />
for (nbuf /= sf_esize(in[0]); nsiz > 0; nsiz -= nbuf) {<br />
if (nbuf > nsiz) nbuf=nsiz;<br />
<br />
for (j=0; j < nin; j++) {<br />
collect = (bool) (j != 0);<br />
switch(type) {<br />
case SF_FLOAT:<br />
sf_floatread((float*) bufi,<br />
nbuf,<br />
in[j]); <br />
add_float(collect, <br />
nbuf,<br />
(float*) buf,<br />
(const float*) bufi, <br />
cmode, <br />
scale[j], <br />
add[j], <br />
abs_flag[j], <br />
log_flag[j], <br />
sqrt_flag[j], <br />
exp_flag[j]);<br />
break;<br />
</c><br />
<br />
The data combination program for floating point numbers is<br />
<tt>add_float</tt>. <br />
<c><br />
static void add_float (bool collect, /* if collect */<br />
size_t nbuf, /* buffer size */<br />
float* buf, /* output [nbuf] */<br />
const float* bufi, /* input [nbuf] */ <br />
char cmode, /* operation */<br />
float scale, /* scale factor */<br />
float add, /* add factor */<br />
bool abs_flag, /* if abs */<br />
bool log_flag, /* if log */<br />
bool sqrt_flag, /* if sqrt */<br />
bool exp_flag /* if exp */)<br />
/* Add floating point numbers */<br />
{<br />
size_t j;<br />
float f;<br />
<br />
for (j=0; j < nbuf; j++) {<br />
f = bufi[j];<br />
if (abs_flag) f = fabsf(f);<br />
f += add;<br />
if (log_flag) f = logf(f);<br />
if (sqrt_flag) f = sqrtf(f);<br />
if (1. != scale) f *= scale;<br />
if (exp_flag) f = expf(f);<br />
if (collect) {<br />
switch (cmode) {<br />
case 'p': /* product */<br />
case 'm': /* multiply */<br />
buf[j] *= f;<br />
break;<br />
case 'd': /* delete */<br />
if (f != 0.) buf[j] /= f;<br />
break;<br />
default: /* add */<br />
buf[j] += f;<br />
break;<br />
}<br />
} else {<br />
buf[j] = f;<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display dataset attributes.<br />
|-<br />
! colspan="4" | sfattr < in.rsf want=<br />
|-<br />
| colspan="4" | <br>Sample output from "sfspike n1=100 | sfbandpass fhi=60 | sfattr"<br>******************************************* <br>rms = 0.992354 <br>mean value = 0.987576 <br>2-norm value = 9.92354 <br>variance = 0.00955481 <br>standard deviation = 0.0977487 <br>maximum value = 1.12735 at 97 <br>minimum value = 0.151392 at 100 <br>number of nonzero samples = 100 <br>total number of samples = 100 <br>******************************************* <br><br>rms = sqrt[ sum(data^2) / n ]<br>mean = sum(data) / n<br>norm = sum(abs(data)^lval)^(1/lval)<br>variance = [ sum(data^2) - n*mean^2 ] / [ n-1 ]<br>standard deviation = sqrt [ variance ]<br />
|-<br />
| ''int '' || '''lval=2''' || || norm option, lval is a non-negative integer, computes the vector lval-norm<br />
|-<br />
| ''string '' || '''want=''' || || 'all'(default),'rms','mean','norm','var','std','max','min','nonzero','samples','short' <br />
:want= 'rms' displays the root mean square<br />
:want= 'norm' displays the square norm, otherwise specified by lval.<br />
:want= 'var' displays the variance<br />
:want= 'std' displays the standard deviation<br />
:want= 'nonzero' displays number of nonzero samples<br />
:want= 'samples' displays total number of samples<br />
:want= 'short' displays a short one-line version<br />
|}<br />
<br />
<br />
<tt>sfattr</tt> is a useful diagnostic program. It reports certain<br />
statistical values for an RSF dataset: RMS (root-mean-square)<br />
amplitude, mean value, vector norm value, variance, standard deviation,<br />
maximum and minimum values, number of nonzero samples, and the total<br />
number of samples.<br />
If we denote data values as <math>d_i</math> for <math>i=0,1,2,\ldots,n</math>, then the RMS<br />
value is <math>\sqrt{\frac{1}{n}\,\sum\limits_{i=0}^n d_i^2}</math>, the mean<br />
value is <math>\frac{1}{n}\,\sum\limits_{i=0}^n d_i</math>, the <math>L_2</math>-norm value<br />
is <math>\sqrt{\sum\limits_{i=0}^n d_i^2}</math>, the variance is<br />
<math>\frac{1}{n-1}\,\left[\sum\limits_{i=0}^n d_i^2 - \frac{1}{n}\left(\sum\limits_{i=0}^n d_i\right)^2\right]</math>, and the standard<br />
deviation is the square root of the variance. Using <tt>sfattr</tt><br />
is a quick way to see the distribution of data values and check it for<br />
anomalies.<br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/attr.c?view=markup user/main/attr.c]====<br />
<br />
Computations start by finding the input data (<tt>in</tt>) size<br />
(<tt>nsiz</tt>) and dimensions (<tt>dim</tt>).<br />
<c><br />
dim = (size_t) sf_filedims (in,n);<br />
for (nsiz=1, i=0; i < dim; i++) {<br />
nsiz *= n[i];<br />
}<br />
</c><br />
<br />
<br />
In the main loop, we read the input data buffer by buffer.<br />
<c><br />
for (nleft=nsiz; nleft > 0; nleft -= nbuf) {<br />
nbuf = (bufsiz < nleft)? bufsiz: nleft;<br />
switch (type) {<br />
case SF_FLOAT: <br />
sf_floatread((float*) buf,nbuf,in);<br />
break;<br />
case SF_INT:<br />
sf_intread((int*) buf,nbuf,in);<br />
break;<br />
case SF_COMPLEX:<br />
sf_complexread((sf_complex*) buf,nbuf,in);<br />
break;<br />
case SF_UCHAR:<br />
sf_ucharread((unsigned char*) buf,nbuf,in);<br />
break;<br />
case SF_CHAR:<br />
default:<br />
sf_charread(buf,nbuf,in);<br />
break;<br />
}<br />
</c><br />
<br />
<br />
The data attributes are accumulated in corresponding double-precision<br />
variables. <br />
<c><br />
fsum += f;<br />
fsqr += f*f;<br />
</c><br />
<br />
<br />
Finally, the attributes are reduced and printed out.<br />
<c><br />
fmean = fsum/nsiz;<br />
if (lval==2) fnorm = sqrt(fsqr);<br />
else if (lval==0) fnorm = nsiz-nzero;<br />
else fnorm = pow(flval,1./lval);<br />
frms = sqrt(fsqr/nsiz);<br />
if (nsiz > 1) fvar = (fsqr-nsiz*fmean*fmean)/(nsiz-1);<br />
else fvar = 0.0;<br />
fstd = sqrt(fvar);<br />
</c><br />
<br />
<c><br />
if(NULL==want || 0==strcmp(want,"rms"))<br />
printf("rms = %g \n",(float) frms);<br />
if(NULL==want || 0==strcmp(want,"mean"))<br />
printf("mean value = %g \n",(float) fmean);<br />
if(NULL==want || 0==strcmp(want,"norm"))<br />
printf("%d-norm value = %g \n",lval,(float) fnorm);<br />
if(NULL==want || 0==strcmp(want,"var"))<br />
printf("variance = %g \n",(float) fvar);<br />
if(NULL==want || 0==strcmp(want,"std"))<br />
printf("standard deviation = %g \n",(float) fstd);<br />
</c><br />
<br />
==sfcat==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Concatenate datasets. <br />
|-<br />
! colspan="4" | sfcat > out.rsf space= axis=3 nspace=(int) (ni/(20*nin) + 1) [<file0.rsf] file1.rsf file2.rsf ... <br />
|-<br />
| colspan="4" | sfmerge inserts additional space between merged data.<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis being merged<br />
|-<br />
| ''int '' || '''nspace=(int) (ni/(20*nin) + 1)''' || || if space=y, number of traces to insert<br />
|-<br />
| ''bool '' || '''space=''' || [y/n] || Insert additional space.<br />
:y is default for sfmerge, n is default for sfcat<br />
|}<br />
<br />
<br />
<tt>sfcat</tt> and <tt>sfmerge</tt> concatenate two or more files<br />
together along a particular axis. It is the same program, only<br />
<tt>sfcat</tt> has the default <tt>space=n</tt> and <tt>sfmerge</tt><br />
has the default <tt>space=y</tt>.<br />
Example of <tt>sfcat</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcat one.rsf one.rsf axis=1 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=4 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
12 elements 48 bytes<br />
</pre><br />
Example of <tt>sfmerge</tt>:<br />
<pre><br />
bash$ sfmerge one.rsf one.rsf axis=2 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=7 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
14 elements 56 bytes<br />
</pre><br />
In this case, an extra empty trace is inserted between the two merged files.<br />
The axes that are not being merged are checked for consistency:<br />
<pre><br />
bash$ sfcat one.rsf two.rsf > three.rsf<br />
sfcat: n2 mismatch: need 3<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cat.c?view=markup user/main/cat.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
in = (sf_file*) sf_alloc ((size_t) argc,sizeof(sf_file));<br />
<br />
if (!sf_stdin()) { /* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Everything on the command line that does not contain a "=" sign is<br />
treated as a file name, and the corresponding file object is added to the list.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) <br />
continue; /* not a file */<br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
</c><br />
<br />
As explained above, if the <tt>space=</tt> parameter is not set, it is<br />
inferred from the program name: <tt>sfmerge</tt> corresponds to<br />
<tt>space=y</tt> and <tt>sfcat</tt> corresponds to <tt>space=n</tt>.<br />
<c><br />
if (!sf_getbool("space",&space)) {<br />
/* Insert additional space.<br />
y is default for sfmerge, n is default for sfcat */<br />
prog = sf_getprog();<br />
if (NULL != strstr (prog, "merge")) {<br />
space = true;<br />
} else if (NULL != strstr (prog, "cat")) {<br />
space = false;<br />
} else {<br />
sf_warning("%s is neither merge nor cat,"<br />
" assume merge",prog);<br />
space = true;<br />
}<br />
}<br />
</c><br />
<br />
Find the axis for the merging (from the command line <tt>axis=</tt><br />
argument) and figure out two sizes: <tt>n1</tt> for everything after<br />
the axis and <tt>n2</tt> for everything before the axis.<br />
<c><br />
n1=1;<br />
n2=1;<br />
for (i=1; i <= dim; i++) {<br />
if (i < axis) n1 *= n[i-1];<br />
else if (i > axis) n2 *= n[i-1];<br />
}<br />
</c><br />
<br />
In the output, the selected axis will get extended.<br />
<c><br />
/* figure out the length of extended axis */<br />
ni = 0;<br />
for (j=0; j < nin; j++) {<br />
ni += naxis[j];<br />
}<br />
<br />
if (space) {<br />
if (!sf_getint("nspace",&nspace)) <br />
nspace = (int) (ni/(20*nin) + 1);<br />
/* if space=y, number of traces to insert */ <br />
ni += nspace*(nin-1);<br />
} <br />
<br />
(void) snprintf(key,3,"n%d",axis);<br />
sf_putint(out,key,(int) ni);<br />
</c><br />
<br />
The rest is simple: loop through the datasets reading and writing the<br />
data in buffer-size chunks and adding extra empty chunks if<br />
<tt>space=y</tt>.<br />
<c><br />
for (i2=0; i2 < n2; i2++) {<br />
for (j=0; j < nin; j++) {<br />
for (ni = n1*naxis[j]*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charread (buf,nbuf,in[j]);<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
if (!space || j == nin-1) continue;<br />
/* Add spaces */<br />
memset(buf,0,BUFSIZ);<br />
for (ni = n1*nspace*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfcmplx==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a complex dataset from its real and imaginary parts.<br />
|-<br />
! colspan="4" | sfcmplx > cmplx.rsf real.rsf imag.rsf<br />
|-<br />
| colspan="4" | There has to be only two input files specified and no additional parameters.<br />
|}<br />
<br />
<br />
<tt>sfcmplx</tt> simply creates a complex dataset from its real and<br />
imaginary parts. The reverse operation can be accomplished with<br />
<tt>sfreal</tt> and <tt>sfimag</tt>.<br />
Example of <tt>sfcmplx</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcmplx one.rsf one.rsf > cmplx.rsf<br />
bash$ sfin cmplx.rsf<br />
cmplx.rsf:<br />
in="/tmp/cmplx.rsf@"<br />
esize=8 type=complex form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 48 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cmplx.c?view=markup user/main/cmplx.c]====<br />
The program flow is simple. First, get the names of the input files.<br />
<c><br />
/* the first two non-parameters are real and imaginary files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == real) {<br />
real = sf_input (argv[i]);<br />
} else {<br />
imag = sf_input (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == imag) {<br />
if (NULL == real) sf_error ("not enough input");<br />
/* if only one input, real is in stdin */<br />
imag = real;<br />
real = sf_input("in");<br />
}<br />
</c><br />
<br />
The main part of the program reads the real and imaginary parts buffer by buffer and assembles and writes out the complex input. <br />
<c><br />
for (nleft= (size_t) (rsize*resize); nleft > 0; nleft -= nbuf) {<br />
nbuf = (BUFSIZ < nleft)? BUFSIZ: nleft;<br />
sf_charread(rbuf,nbuf,real);<br />
sf_charread(ibuf,nbuf,imag);<br />
for (i=0; i < nbuf; i += resize) {<br />
memcpy(cbuf+2*i, rbuf+i,(size_t) resize);<br />
memcpy(cbuf+2*i+resize,ibuf+i,(size_t) resize);<br />
}<br />
sf_charwrite(cbuf,2*nbuf,cmplx);<br />
}<br />
</c><br />
<br />
==sfconjgrad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic conjugate-gradient solver for linear inversion <br />
|-<br />
! colspan="4" | sfconjgrad < dat.rsf mod=mod.rsf > to.rsf < from.rsf > out.rsf niter=1<br />
|-<br />
| ''int '' || '''niter=1''' || || number of iterations<br />
|}<br />
<br />
<br />
<tt>sfconjgrad</tt> is a generic program for least-squares linear<br />
inversion with the conjugate-gradient method. Suppose you have an<br />
executable program <tt><prog></tt> that takes an RSF file from the<br />
standard input and produces an RSF file in the standard output. It may<br />
take any number of additional parameters but one of them must be<br />
<tt>adj=</tt> that sets the forward (<tt>adj=0</tt>) or adjoint<br />
(<tt>adj=1</tt>) operations. The program <tt><prog></tt> is typically<br />
an RSF program but it could be anything (a script, a multiprocessor<br />
MPI program, etc.) as long as it implements a linear operator<br />
<math>\mathbf{L}</math> and its adjoint. There are no restrictions on the data<br />
size or shape. You can easily test the adjointness with<br />
<tt>sfdottest</tt>. The <tt>sfconjgrad</tt> program searches for a<br />
vector <math>\mathbf{m}</math> that minimizes the least-square misfit <br />
<math>\|\mathbf{d - L\,m}\|^2</math> for the given input data vector <math>\mathbf{d}</math>.<br />
Here is an example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
The <tt>sfdottest</tt> program can perform the dot product test to<br />
check that the adjoint mode works correctly.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=5.28394<br />
sfdottest: L'[d]*m=5.28394<br />
</pre><br />
Your numbers may be different because <tt>sfdottest</tt> generates new<br />
random input on each run.<br />
Next, let us make some random data with <tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfnoise seed=2005 rep=y < vec.rsf > dat.rsf<br />
</pre><br />
and try to invert the filtering operation using <tt>sfconjgrad</tt>:<br />
<pre><br />
bash$ sfconjgrad sfhelicon filt=flt.rsf lag=lag.rsf \<br />
mod=vec.rsf < dat.rsf > mod.rsf niter=10<br />
sfconjgrad: iter 1 of 10<br />
sfconjgrad: grad=3253.65<br />
sfconjgrad: iter 2 of 10<br />
sfconjgrad: grad=289.421<br />
sfconjgrad: iter 3 of 10<br />
sfconjgrad: grad=92.3481<br />
sfconjgrad: iter 4 of 10<br />
sfconjgrad: grad=36.9417<br />
sfconjgrad: iter 5 of 10<br />
sfconjgrad: grad=18.7228<br />
sfconjgrad: iter 6 of 10<br />
sfconjgrad: grad=11.1794<br />
sfconjgrad: iter 7 of 10<br />
sfconjgrad: grad=7.26941<br />
sfconjgrad: iter 8 of 10<br />
sfconjgrad: grad=5.15945<br />
sfconjgrad: iter 9 of 10<br />
sfconjgrad: grad=4.23055<br />
sfconjgrad: iter 10 of 10<br />
sfconjgrad: grad=3.57495<br />
</pre><br />
The output shows that, in 10 iterations, the norm of the gradient vector decreases by almost 1000. <br />
We can check the residual misfit before<br />
<pre><br />
bash$ < dat.rsf sfattr want=norm<br />
norm value = 49.7801<br />
</pre><br />
and after<br />
<pre><br />
bash$ sfhelicon filt=flt.rsf lag=lag.rsf < mod.rsf | \<br />
sfadd scale=1,-1 dat.rsf | sfattr want=norm<br />
norm value = 5.73563<br />
</pre><br />
In 10 iterations, the misfit decreased by an order of magnitude. The<br />
result can be improved by running the program for more iterations.<br />
<br />
==sfcp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Copy or move a dataset.<br />
|-<br />
! colspan="4" | sfcp in.rsf out.rsf<br />
|-<br />
| colspan="4" | sfcp - copy, sfmv - move.<br>Mimics standard Unix commands.<br />
|}<br />
<br />
<br />
The <tt>sfcp</tt> and <tt>sfmv</tt> command imitate the Unix<br />
<tt>cp</tt> and <tt>mv</tt> commands and serve for copying and moving<br />
RSF files. Example:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcp one.rsf two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
</pre><br />
<br />
==sfcut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of the dataset. <br />
|-<br />
! colspan="4" | sfcut < in.rsf > out.rsf verb=n [j1=1 j2=1 ... f1=0 f2=0 ... n1=n1 n2=n2 ... max1= max2= ... min1= min2= ...]<br />
|-<br />
| colspan="4" | jN defines the jump in N-th dimension<br>fN is the window start<br>nN is the window size<br>minN and maxN is the maximum and minimum in N-th dimension<br><br>Reverse of window. <br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
The <tt>sfcut</tt> command is related to <tt>sfwindow</tt> and has the same<br />
set of arguments only instead of extracting the selected window, it fills it<br />
with zeroes. The size of the input data is preserved. <br />
Examples:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > in.rsf<br />
bash$ < in.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < in.rsf sfcut n1=2 f1=1 n2=3 f2=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 0 0 1 1<br />
15: 1 0 0 1 1<br />
20: 1 0 0 1 1<br />
bash$ < in.rsf sfcut j1=2 | sfdisfil<br />
0: 0 1 0 1 0<br />
5: 0 1 0 1 0<br />
10: 0 1 0 1 0<br />
15: 0 1 0 1 0<br />
20: 0 1 0 1 0<br />
</pre><br />
<br />
==sfdd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert between different formats. <br />
|-<br />
! colspan="4" | sfdd < in.rsf > out.rsf line=8 form= type= format=<br />
|-<br />
| ''string '' || '''form=''' || || ascii, native, xdr<br />
|-<br />
| ''string '' || '''format=''' || || Element format (for conversion to ASCII)<br />
|-<br />
| ''int '' || '''line=8''' || || Number of numbers per line (for conversion to ASCII)<br />
|-<br />
| ''string '' || '''type=''' || || int, float, complex<br />
|}<br />
<br />
<br />
The <tt>sfdd</tt> program is used to change either the form (<tt>ascii</tt>,<br />
<tt>xdr</tt>, <tt>native</tt>) or the type (<tt>complex</tt>, <tt>float</tt>,<br />
<tt>int</tt>, <tt>char</tt>) of the input dataset. <br />
In the example below, we create a plain text (ASCII) file with numbers and<br />
then use <tt>sfdd</tt> to generate an RSF file in <tt>xdr</tt> form with<br />
<tt>complex</tt> numbers. <br />
<pre><br />
bash$ cat test.txt<br />
1 2 3 4 5 6<br />
bash$ echo n1=6 data_format=ascii_int in=test.txt > test.rsf<br />
bash$ sfin test.rsf<br />
test.rsf:<br />
in="test.txt"<br />
esize=0 type=int form=ascii<br />
n1=6 d1=? o1=?<br />
6 elements<br />
bash$ sfdd < test.rsf form=xdr type=complex > test2.rsf<br />
bash$ sfin test2.rsf<br />
test2.rsf:<br />
in="/tmp/test2.rsf@"<br />
esize=8 type=complex form=xdr<br />
n1=3 d1=? o1=?<br />
3 elements 24 bytes<br />
bash$ sfdisfil < test2.rsf<br />
0: 1, 2i 3, 4i 5, 6i<br />
</pre><br />
To learn more about the RSF data format, consult the [[Format| guide to RSF format]].<br />
<br />
==sfdisfil==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Print out data values.<br />
|-<br />
! colspan="4" | sfdisfil < in.rsf number=y col=0 format= header= trailer=<br />
|-<br />
| colspan="4" | <br>Alternatively, use sfdd and convert to ASCII form.<br />
|-<br />
| ''int '' || '''col=0''' || || Number of columns.<br />
:The default depends on the data type:<br />
:10 for int and char,<br />
:5 for float,<br />
:3 for complex<br />
|-<br />
| ''string '' || '''format=''' || || Format for numbers (printf-style).<br />
:The default depends on the data type:<br> "%4d " for int and char,<br> "%13.4g" for float,<br> "%10.4g,%10.4gi" for complex<br />
|-<br />
| ''string '' || '''header=''' || || Optional header string to output before data<br />
|-<br />
| ''bool '' || '''number=y''' || [y/n] || If number the elements<br />
|-<br />
| ''string '' || '''trailer=''' || || Optional trailer string to output after data<br />
|}<br />
<br />
<br />
The <tt>sfdisfil</tt> program simply dumps the data contents to the standard<br />
output in a text form. It is used mostly for debugging purposes to quickly<br />
examine RSF files. Here is an example:<br />
<pre><br />
bash$ sfmath o1=0 d1=2 n1=12 output=x1 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
10: 20 22<br />
</pre><br />
The output format is easily configurable.<br />
<pre><br />
bash$ < test.rsf sfdisfil col=6 number=n format="<br />
0.0 2.0 4.0 6.0 8.0 10.0<br />
12.0 14.0 16.0 18.0 20.0 22.0<br />
</pre><br />
Along with <tt>sfdd</tt>, <tt>sfdisfil</tt> provides a simple way to convert<br />
RSF data to an ASCII form.<br />
<br />
==sfdottest==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic dot-product test for linear operators with adjoints <br />
|-<br />
! colspan="4" | sfdottest mod=mod.rsf dat=dat.rsf > pip.rsf<br />
|}<br />
<br />
<br />
<tt>sfdottest</tt> is a generic dot-product test program for testing<br />
linear operators. Suppose there is an executable program<br />
<tt><prog></tt> that takes an RSF file from the standard input and<br />
produces an RSF file in the standard output. It may take any number of<br />
additional parameters but one of them must be <tt>adj=</tt> that sets<br />
the forward (<tt>adj=0</tt>) or adjoint (<tt>adj=1</tt>) operations.<br />
The program <tt><prog></tt> is typically an RSF program but it could<br />
be anything (a script, a multiprocessor MPI program, etc.) as long as<br />
it implements a linear operator <math>\mathbf{L}</math> and its adjoint<br />
<math>\mathbf{L}^T</math>. The <tt>sfdottest</tt> program is testing the equality<br />
<center><math><br />
d^T\,L\,m = m^T\,L^T\,d<br />
</math></center><br />
by using random vectors <math>\mathbf{m}</math> and <math>\mathbf{d}</math>. You can invoke it with<br />
<pre><br />
bash$ sfdottest <prog> [optional aruments] mod=mod.rsf dat=dat.rsf<br />
</pre><br />
where <tt>mod.rsf</tt> and <tt>dat.rsf</tt> are RSF files that<br />
represent vectors from the model and data spaces. <tt>sfdottest</tt><br />
does not create any temporary files and does not have any restrictive<br />
limitations on the size of the vectors.<br />
Here is an example. We first setup a vector with 100 elements using<br />
<tt>sfspike</tt> and then run <tt>sfdottest</tt> to test the<br />
<tt>sfcausint</tt> program. <tt>sfcausint</tt> implements a linear<br />
operator of causal integration and its adjoint, the anti-causal<br />
integration.<br />
<pre><br />
bash$ sfspike n1=100 > vec.rsf<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1410.2<br />
sfdottest: L'[d]*m=1410.2<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1165.87<br />
sfdottest: L'[d]*m=1165.87<br />
</pre><br />
The numbers are different on subsequent runs because of changing<br />
seed in the random number generator.<br />
Here is a somewhat more complicated example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
Now the <tt>sfdottest</tt> program can perform the dot product test.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=8.97375<br />
sfdottest: L'[d]*m=8.97375<br />
</pre><br />
Here is the same program tested in the inverse filtering mode:<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf inv=y<br />
sfdottest: L[m]*d=15.0222<br />
sfdottest: L'[d]*m=15.0222<br />
</pre><br />
<br />
==sfget==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Output parameters from the header.<br />
|-<br />
! colspan="4" | sfget < in.rsf parform=y par1 par2 ...<br />
|-<br />
| ''bool '' || '''parform=y''' || [y/n] || If y, print out parameter=value. If n, print out value.<br />
|}<br />
<br />
<br />
The <tt>sfget</tt> program extracts a parameter value from an RSF file. It is<br />
useful mostly for scripting. Here is, for example, a quick calculation of the<br />
maximum value on the first axis in an RSF dataset (the output of<br />
<tt>sfspike</tt>) using the standard Unix <tt>bc</tt> calculator.<br />
<pre><br />
bash$ ( sfspike n1=100 | sfget n1 d1 o1; echo "o1+(n1-1)*d1" ) | bc<br />
.396<br />
</pre><br />
See also <tt>sfput</tt>.<br />
<br />
<br />
<br />
==sfheadercut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheadercut mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array of size n2.<br />
|}<br />
<br />
<br />
<tt>sfheadercut</tt> is close to <tt>sfheaderwindow</tt> but instead<br />
of windowing the dataset, it fills the traces specified by the header<br />
mask with zeroes. The size of the input data is preserved.<br />
Here is an example of using <tt>sfheaderwindow</tt> for <br />
zeroing every other trace in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a mask with alternating ones and zeros using<br />
<tt>sfinterleave</tt>.<br />
<pre><br />
bash$ sfspike n1=5 mag=1 | sfdd type=int > ones.rsf<br />
bash$ sfspike n1=5 mag=0 | sfdd type=int > zeros.rsf<br />
bash$ sfinterleave axis=1 ones.rsf zeros.rsf > mask.rsf<br />
bash$ sfdisfil < mask.rsf<br />
0: 1 0 1 0 1 0 1 0 1 0<br />
</pre><br />
Finally, <tt>sfheadercut</tt> zeros the input traces.<br />
<pre><br />
bash$ sfheadercut < input.rsf mask=mask.rsf > output.rsf<br />
bash$ sfdisfil < output.rsf <br />
0: 1 1 1 1 1<br />
5: 0 0 0 0 0<br />
10: 3 3 3 3 3<br />
15: 0 0 0 0 0<br />
20: 5 5 5 5 5<br />
25: 0 0 0 0 0<br />
30: 7 7 7 7 7<br />
35: 0 0 0 0 0<br />
40: 9 9 9 9 9<br />
45: 0 0 0 0 0<br />
</pre><br />
<br />
<br />
<br />
==sfheadersort==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Sort a dataset according to a header key. <br />
|-<br />
! colspan="4" | sfheadersort < in.rsf > out.rsf head=<br />
|-<br />
| ''string '' || '''head=''' || || header file<br />
|}<br />
<br />
<br />
<tt>sfheadersort</tt> is used to sort traces in the input file<br />
according to trace header information. <br />
Here is an example of using<br />
<tt>sfheadersort</tt> for randomly shuffling traces in the input<br />
file. First, let us create an input file with seven traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=7 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7 <br />
</pre><br />
Next, we can create a random file with seven header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=7 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: 0.05256 -0.2879 0.1487 0.4097 0.1548<br />
5: 0.4501 0.2836<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally, we<br />
apply <tt>sfheadersort</tt> to shuffle the input traces.<br />
<pre><br />
bash$ < input.rsf sfheadersort head=random.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 1 1 1 1 1<br />
10: 3 3 3 3 3<br />
15: 5 5 5 5 5<br />
20: 7 7 7 7 7<br />
25: 4 4 4 4 4<br />
30: 6 6 6 6 6<br />
</pre><br />
As expected, the order of traces in the output file corresponds to the<br />
order of values in the header. Thanks to the separation between<br />
headers and data, the operation of <tt>sfheadersort</tt> is optimally<br />
efficient. It first sorts the headers and only then accesses the data,<br />
reading each data trace only once.<br />
<br />
==sfheaderwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheaderwindow mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array os size n2, windowed is n1xm2,<br>where m2 is the number of nonzero elements in mask.<br />
|}<br />
<br />
<br />
<tt>sfheaderwindow</tt> is used to window traces in the input file<br />
according to trace header information. <br />
Here is an example of using <tt>sfheaderwindow</tt> for randomly<br />
selecting part of the traces in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a random file with ten header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=10 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: -0.005768 0.02258 -0.04331 -0.4129 -0.3909<br />
5: -0.03582 0.4595 -0.3326 0.498 -0.3517<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally,<br />
we apply <tt>sfheaderwindow</tt> to window the input traces selecting<br />
only those for which the header is greater than zero.<br />
<pre><br />
bash$ < random.rsf sfmask min=0 > mask.rsf<br />
bash$ < mask.rsf sfdisfil<br />
0: 0 1 0 0 0 0 1 0 1 0<br />
bash$ < input.rsf sfheaderwindow mask=mask.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 7 7 7 7 7<br />
10: 9 9 9 9 9<br />
</pre><br />
In this case, only three traces are selected for the output. Thanks to<br />
the separation between headers and data, the operation of<br />
<tt>sfheaderwindow</tt> is optimally efficient. <br />
<br />
==sfin==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display basic information about RSF files.<br />
|-<br />
! colspan="4" | sfin info=y check=2. trail=y file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | n1,n2,... are data dimensions<br>o1,o2,... are axis origins<br>d1,d2,... are axis sampling intervals<br>label1,label2,... are axis labels<br>unit1,unit2,... are axis units<br />
|-<br />
| ''float '' || '''check=2.''' || || Portion of the data (in Mb) to check for zero values.<br />
|-<br />
| ''bool '' || '''info=y''' || [y/n] || If n, only display the name of the data file.<br />
|-<br />
| ''bool '' || '''trail=y''' || [y/n] || If n, skip trailing dimensions of one<br />
|}<br />
<br />
<br />
<tt>sfin</tt> is one of the most useful programs for operating with<br />
RSF files. It produces quick information on the file hypercube<br />
dimensions and checks the consistency of the associated data file.<br />
Here is an example. Let us create an RSF file and examine it with <tt>sfin</tt>.<br />
<pre><br />
bash$ sfspike n1=100 n2=20 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=100 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
2000 elements 8000 bytes<br />
</pre><br />
<tt>sfin</tt> reports the following information:<br />
<br />
*location of the data file (<tt>/tmp/spike.rsf\@</tt>) <br />
*element size (4 bytes) <br />
*element type (floating point) <br />
*element form (native) <br />
*hypercube dimensions (100 by 20) <br />
*axes scale (0.004 and 0.1) <br />
*axes origin (0 and 0) <br />
*axes labels <br />
*axes units <br />
*total number of elements <br />
*total number of bytes in the data file <br />
Suppose that the file got corrupted by a buggy program and reports<br />
incorrect dimensions. The <tt>sfin</tt> program should be able to<br />
catch the discrepancy.<br />
<pre><br />
bash$ echo n2=100 >> spike.rsf<br />
bash$ sfin spike.rsf > /dev/null<br />
sfin: Actually 8000 bytes, 20% of expected.<br />
</pre><br />
<tt>sfin</tt> also checks the first records in the file for zeros. <br />
<pre><br />
bash$ sfspike n1=100 n2=100 k2=99 > spike2.rsf<br />
bash$ sfin spike2.rsf >/dev/null<br />
sfin: The first 32768 bytes are all zeros<br />
</pre><br />
The number of bytes to check is adjustable<br />
<pre><br />
bash$ sfin spike2.rsf check=0.01 >/dev/null<br />
sfin: The first 16384 bytes are all zeros<br />
</pre><br />
You can also output only the location of the data file. This is<br />
sometimes handy in scripts.<br />
<pre><br />
bash$ sfin spike.rsf spike2.rsf info=n<br />
/tmp/spike.rsf@ /tmp/spike2.rsf@<br />
</pre><br />
An alternative is to use <tt>sfget</tt>, as follows:<br />
<pre><br />
bash$ sfget parform=n in < spike.rsf<br />
/tmp/spike.rsf@<br />
</pre><br />
<br />
==sfinterleave==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Combine several datasets by interleaving.<br />
|-<br />
! colspan="4" | sfinterleave > out.rsf axis=3 [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis for interleaving<br />
|}<br />
<br />
<br />
<tt>sfinterleave</tt> combines two or more datasets by interleaving them on one<br />
of the axes. Here is a quick example:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ sfscale < one.rsf dscale=2 > two.rsf<br />
bash$ sfdisfil < two.rsf<br />
0: 2 2 2 2 2<br />
5: 2 2 2 2 2<br />
10: 2 2 2 2 2<br />
15: 2 2 2 2 2<br />
20: 2 2 2 2 2<br />
bash$ sfinterleave one.rsf two.rsf axis=1 | sfdisfil<br />
0: 1 2 1 2 1<br />
5: 2 1 2 1 2<br />
10: 1 2 1 2 1<br />
15: 2 1 2 1 2<br />
20: 1 2 1 2 1<br />
25: 2 1 2 1 2<br />
30: 1 2 1 2 1<br />
35: 2 1 2 1 2<br />
40: 1 2 1 2 1<br />
45: 2 1 2 1 2<br />
bash$ sfinterleave < one.rsf two.rsf axis=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 1 1 1 1 1<br />
15: 2 2 2 2 2<br />
20: 1 1 1 1 1<br />
25: 2 2 2 2 2<br />
30: 1 1 1 1 1<br />
35: 2 2 2 2 2<br />
40: 1 1 1 1 1<br />
45: 2 2 2 2 2<br />
</pre><br />
<br />
==sfmask==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a mask.<br />
|-<br />
! colspan="4" | sfmask < in.rsf > out.rsf min=-FLT_MAX max=+FLT_MAX<br />
|-<br />
| colspan="4" | <br>Mask is an integer data with ones and zeros. <br>Ones correspond to input values between min and max.<br><br>The output can be used with sfheaderwindow.<br />
|-<br />
| ''float '' || '''max=+FLT_MAX''' || || maximum header value<br />
|-<br />
| ''float '' || '''min=-FLT_MAX''' || || minimum header value<br />
|}<br />
<br />
<br />
<tt>sfmask</tt> creates an integer output of ones and zeros comparing<br />
the values of the input data to specified <tt>min=</tt> and<br />
<tt>max=</tt> parameters. It is useful for <tt>sfheaderwindow</tt> and<br />
in many other applications. Here is a quick example:<br />
<pre><br />
bash$ sfmath n1=10 output="sin(x1)" > sin.rsf<br />
bash$ < sin.rsf sfdisfil<br />
0: 0 0.8415 0.9093 0.1411 -0.7568<br />
5: -0.9589 -0.2794 0.657 0.9894 0.4121<br />
bash$ < sin.rsf sfmask min=-0.5 max=0.5 | sfdisfil<br />
0: 1 0 0 1 0 0 1 0 0 1<br />
</pre><br />
<br />
==sfmath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations on data files.<br />
|-<br />
! colspan="4" | sfmath > out.rsf type= unit= output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs, conj (for complex data).<br> <br>sfmath will work on float or complex data, but all the input and output<br>files must be of the same data type.<br><br>An alternative to sfmath is sfadd, which may be more efficient, but is<br>less versatile.<br><br>Examples:<br><br>sfmath x=file1.rsf y=file2.rsf power=file3.rsf output='sin((x+2*y)^power)' > out.rsf<br>sfmath < file1.rsf tau=file2.rsf output='exp(tau*input)' > out.rsf<br>sfmath n1=100 type=complex output="exp(I*x1)" > out.rsf<br><br>See also: sfheadermath.<br />
|-<br />
| ''string '' || '''output=''' || || Mathematical description of the output<br />
|-<br />
| ''string '' || '''type=''' || || output data type [float,complex]<br />
|-<br />
| ''string '' || '''unit=''' || || <br />
|}<br />
<br />
<tt>sfmath</tt> is a versatile program for mathematical operations<br />
with RSF files. It can operate with several input file, all of the<br />
same dimensions and data type. The data type can be real (floating<br />
point) or complex. Here is an example that demonstrates several<br />
features of <tt>sfmath</tt>.<br />
<pre><br />
bash$ sfmath n1=629 d1=0.01 o1=0 n2=40 d2=1 o2=5 \<br />
output="x2*(8+sin(6*x1+x2/10))" > rad.rsf<br />
bash$ < rad.rsf sfrtoc | sfmath output="input*exp(I*x1)" > rose.rsf<br />
bash$ < rose.rsf sfgraph title=Rose screenratio=1 wantaxis=n | xtpen<br />
</pre><br />
The first line creates a 2-D dataset that consists of 40 traces 600<br />
samples each. The values of the data are computed with the formula<br />
<font color="#cd4b19">"x2*(8+sin(6*x1+x2/10))"</font>, where <tt>x1</tt> refers to the<br />
coordinate on the first axis, and <tt>x2</tt> is the coordinate of the<br />
second axis. In the second line, we convert the data from real to<br />
complex using <tt>sfrtoc</tt> and produce a complex dataset using<br />
formula <font color="#cd4b19">"input*exp(I*x1)"</font>, where <tt>input</tt> refers to the<br />
input file. Finally, we plot the complex data as a collection of<br />
parametric curves using <tt>sfgraph</tt> and display the result using<br />
<tt>xtpen</tt>. The plot appearing on your screen should look similar<br />
to the figure.<br />
[[Image:rose.png|frame|center|This figure was created with <tt>sfmath</tt>.]]<br />
One possible alternative to the second line above is<br />
<pre><br />
bash$ < rad.rsf sfmath output=x1 > ang.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*cos(a)" > cos.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*sin(a)" > sin.rsf<br />
bash$ sfcmplx cos.rsf sin.rsf > rose.rsf<br />
</pre><br />
Here we refer to input files by names (<tt>r</tt> and <tt>a</tt>) and combine the names in a formula.<br />
<br />
==sfpad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Pad a dataset with zeros.<br />
|-<br />
! colspan="4" | sfpad < in.rsf > out.rsf [beg1= beg2= ... end1= end2=... | n1= n2 = ... | n1out= n2out= ...]<br />
|-<br />
| colspan="4" | begN specifies the number of zeros to add before the beginning of axis N.<br>endN specifies the number of zeros to add after the end of axis N.<br><br>Alternatively:<br><br>nN or nNout specify the output length of axis N, padding occurs at the end.<br>nN and nNout are equivalent.<br />
|}<br />
<br />
<br />
<tt>pad</tt> increases the dimensions of the input dataset by padding<br />
the data with zeroes. Here are some simple examples.<br />
<pre><br />
bash$ sfspike n1=5 n2=3 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
bash$ < one.rsf sfpad n2=5 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 0 0 0 0 0<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfpad beg2=2 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 0 0 0 0<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < one.rsf sfpad beg2=1 end2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfwindow n1=3 | sfpad n1=5 n2=5 beg1=1 beg2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 1 1 1 0<br />
10: 0 1 1 1 0<br />
15: 0 1 1 1 0<br />
20: 0 0 0 0 0<br />
</pre><br />
You can use <tt>sfcat</tt> to pad data with values other than zeroes.<br />
<br />
==sfput==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Input parameters into a header. <br />
|-<br />
! colspan="4" | sfput < in.rsf > out.rsf<br />
|}<br />
<br />
<br />
<tt>sfput</tt> is a very simple program. It simply appends parameters<br />
from the command line to the output RSF file. One can achieve similar<br />
results with editing by hand or with standard Unix utilities like<br />
<tt>sed</tt> and <tt>echo</tt>. <tt>sfput</tt> is sometimes more<br />
convenient because it handles input/output operations similarly to<br />
other regular RSF programs.<br />
<pre><br />
bash$ sfspike n1=10 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
10 elements 40 bytes<br />
bash$ sfput < spike.rsf d1=25 label1=Depth unit1=m > spike2.rsf<br />
bash$ sfin spike2.rsf<br />
spike2.rsf:<br />
in="/tmp/spike2.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=25 o1=0 label1="Depth" unit1="m"<br />
10 elements 40 bytes<br />
</pre><br />
<br />
==sfreal==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extract real (sfreal) or imaginary (sfimag) part of a complex dataset. <br />
|-<br />
! colspan="4" | sfreal < cmplx.rsf > real.rsf<br />
|}<br />
<br />
<br />
<tt>sfreal</tt> extracts the real part of a complex type dataset. The<br />
imaginary part can be extracted with <tt>sfimag</tt>, an the real<br />
and imaginary part can be combined together with <tt>sfcmplx</tt>.<br />
Here is a simple example. Let us first create a complex dataset <br />
with <tt>sfmath</tt><br />
<pre><br />
bash$ sfmath n1=10 type=complex output="(2+I)*x1" > cmplx.rsf<br />
bash$ fdisfil < cmplx.rsf<br />
0: 0, 0i 2, 1i 4, 2i<br />
3: 6, 3i 8, 4i 10, 5i<br />
6: 12, 6i 14, 7i 16, 8i<br />
9: 18, 9i<br />
</pre><br />
Extracting the real part with <tt>sfreal</tt>:<br />
<pre><br />
bash$ sfreal < cmplx.rsf | sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
</pre><br />
Extracting the imaginary part with <tt>sfimag</tt>:<br />
<pre><br />
bash$ sfimag < cmplx.rsf | sfdisfil<br />
0: 0 1 2 3 4<br />
5: 5 6 7 8 9<br />
</pre><br />
<br />
==sfreverse==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Reverse one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfreverse < in.rsf > out.rsf which=-1 verb=false memsize=sf_memsize() opt=<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''opt=''' || || If y, change o and d parameters on the reversed axis;<br />
:if i, don't change o and d<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|-<br />
| ''int '' || '''which=-1''' || || Which axis to reverse.<br />
:To reverse a given axis, start with 0,<br />
:add 1 to number to reverse n1 dimension,<br />
:add 2 to number to reverse n2 dimension,<br />
:add 4 to number to reverse n3 dimension, etc.<br />
:Thus, which=7 would reverse the first three dimensions,<br />
:which=5 just n1 and n3, etc.<br />
:which=0 will just pass the input on through unchanged.<br />
|}<br />
Here is an example of using <tt>sfreverse</tt>. First, let us create a<br />
2-D dataset.<br />
<pre><br />
bash$ sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Reversing the first axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 | sfdisfil<br />
0: 4 3 2 1 0<br />
5: 5 4 3 2 1<br />
10: 6 5 4 3 2<br />
</pre><br />
Reversing the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=2 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
Reversing both the first and the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=3 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
As you can see, the <tt>which=</tt> parameter controls the axes that are<br />
being reversed by encoding them into one number.<br />
When an axis is reversed, what happens with its axis origin and<br />
sampling parameters? This behavior is controlled by <tt>opt=</tt>. In<br />
our example,<br />
<pre><br />
bash$ < test.rsf sfget n1 o1 d1<br />
n1=5<br />
o1=0<br />
d1=1<br />
bash$ < test.rsf sfreverse which=1 | sfget o1 d1<br />
o1=4<br />
d1=-1<br />
</pre><br />
The default behavior (equivalent to <tt>opt=y</tt>) puts the origin<br />
<tt>o1</tt> at the end of the axis and reverses the sampling parameter<br />
<tt>d1</tt>. Using <tt>opt=n</tt> preserves the sampling but reverses<br />
the origin.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=n | sfget o1 d1<br />
o1=-4<br />
d1=1<br />
</pre><br />
Using <tt>opt=i</tt> preserves both the sampling and the origin while<br />
reversing the axis.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=i | sfget o1 d1<br />
o1=0<br />
d1=1<br />
</pre><br />
One of the three possible behaviors may be desirable depending on the<br />
application.<br />
<br />
==sfrm==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Remove RSF files together with their data.<br />
|-<br />
! colspan="4" | sfrm file1.rsf [file2.rsf ...] [-i] [-v] [-f] <br />
|-<br />
| colspan="4" | Mimics the standard Unix rm command.<br><br>See also: sfmv, sfcp.<br />
|}<br />
<br />
<tt>sfrm</tt> is a program for removing RSF files. Its arguments mimic<br />
the arguments of the standard Unix <tt>rm</tt> utility: <tt>-v</tt><br />
for verbosity, <tt>-i</tt> for interactive inquiry, <tt>-f</tt> for<br />
force removal of suspicious files. Unlike the Unix <tt>rm</tt>,<br />
<tt>sfrm</tt> removes both the RSF header files and the binary files<br />
that the headers point to. <br />
Example:<br />
<pre><br />
bash&#36; sfspike n1=10 > spike.rsf datapath=./<br />
bash&#36; sfget in < spike.rsf<br />
in=./spike.rsf@<br />
bash&#36; ls spike*<br />
spike.rsf spike.rsf@<br />
bash&#36; sfrm -v spike.rsf<br />
sfrm: sf_rm: Removing header spike.rsf<br />
sfrm: sf_rm: Removing data ./spike.rsf@<br />
bash&#36; ls spike*<br />
ls: No match.<br />
</pre><br />
==sfrotate==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Rotate a portion of one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfrotate < in.rsf > out.rsf verb=n memsize=sf_memsize() rot#=(0,0,...)<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''rot#=(0,0,...)''' || || length of #-th axis that is moved to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<tt>sfrotate</tt> modifies the input dataset by splitting it into<br />
parts and putting the parts back in a different order. Here is a quick example.<br />
<pre><br />
bash&#36; sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Rotating the first axis by putting the last two columns in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=2 | sfdisfil<br />
0: 3 4 0 1 2<br />
5: 4 5 1 2 3<br />
10: 5 6 2 3 4<br />
</pre><br />
Rotating the second axis by putting the last row in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot2=1 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 0 1 2 3 4<br />
10: 1 2 3 4 5<br />
</pre><br />
Rotating both the first and the second axis:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=3 rot2=1 | sfdisfil<br />
0: 4 5 6 2 3<br />
5: 2 3 4 0 1<br />
10: 3 4 5 1 2<br />
</pre><br />
The transformation is shown schematically in Figure~(fig:rotate).<br />
[[Image:rotate.png|frame|center|Schematic transformation of data with <tt>sfrotate</tt>.]]<br />
<br />
==sfrtoc==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert real data to complex (by adding zero imaginary part).<br />
|-<br />
! colspan="4" | sfrtoc < real.rsf > cmplx.rsf<br />
|-<br />
| colspan="4" | <br>See also: sfcmplx<br />
|}<br />
The input to <tt>sfrtoc</tt> can be any <tt>type=float</tt> dataset:<br />
<pre><br />
bash$ sfspike n1=10 n2=20 n3=30 >real.rsf<br />
bash$ sfin real.rsf<br />
real.rsf:<br />
in="/var/tmp/real.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
</pre><br />
The output dataset will have <tt>type=complex</tt>, and its binary will be twice the size of the input:<br />
<pre><br />
bash$ <real.rsf sfrtoc >complex.rsf<br />
bash$ sfin complex.rsf <br />
complex.rsf:<br />
in="/var/tmp/complex.rsf@"<br />
esize=8 type=complex form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 48000 bytes<br />
</pre><br />
<br />
==sfscale==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Scale data.<br />
|-<br />
! colspan="4" | sfscale < in.rsf > out.rsf axis=0 rscale=0. dscale=1.<br />
|-<br />
| colspan="4" | <br>To scale by a constant factor, you can also use sfmath or sfheadermath.<br />
|-<br />
| ''int '' || '''axis=0''' || || Scale by maximum in the dimensions up to this axis.<br />
|-<br />
| ''float '' || '''dscale=1.''' || || Scale by this factor (works if rscale=0)<br />
|-<br />
| ''float '' || '''rscale=0.''' || || Scale by this factor.<br />
|}<br />
<tt>sfscale</tt> scales the input dataset by a factor. Here<br />
are some simple examples. First, let us create a test dataset.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil <br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Scale every data point by 2:<br />
<pre><br />
bash&#36; < test.rsf sfscale dscale=2 | sfdisfil<br />
0: 2 4 6 8 10<br />
5: 4 8 12 16 20<br />
10: 6 12 18 24 30<br />
</pre><br />
Divide every trace by its maximum value:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=1 | sfdisfil<br />
0: 0.2 0.4 0.6 0.8 1<br />
5: 0.2 0.4 0.6 0.8 1<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
Divide by the maximum value in the whole 2-D dataset:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=2 | sfdisfil<br />
0: 0.06667 0.1333 0.2 0.2667 0.3333<br />
5: 0.1333 0.2667 0.4 0.5333 0.6667<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
The <tt>rscale=</tt> parameter is synonymous to <tt>dscale=</tt> except<br />
when it is equal to zero. With <tt>sfscale dscale=0</tt>, the dataset gets<br />
multiplied by zero. If using <tt>rscale=0</tt>, the other parameters are<br />
used to define scaling. Thus, <tt>sfscale rscale=0 axis=1</tt> is<br />
equivalent to <tt>sfscale axis=1</tt>, and <tt>sfscale rscale=0</tt><br />
is equivalent to <tt>sfscale dscale=1</tt>.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
==sfspike==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate simple data: spikes, boxes, planes, constants.<br />
|-<br />
! colspan="4" | sfspike > spike.rsf mag= nsp=1 k#=[0,...] l#=[k1,k2,...] p#=[0,...] n#= o#=(0,...) d#=(0.004,0.1,0.1,...) label#=(Time,Distance,Distance,...) unit#=[s,km,km,...] title=<br />
|-<br />
| ''float '' || '''d#=(0.004,0.1,0.1,...)''' || || sampling on #-th axis<br />
|-<br />
| ''ints '' || '''k#=[0,...]''' || || spike starting position [nsp]<br />
|-<br />
| ''ints '' || '''l#=[k1,k2,...]''' || || spike ending position [nsp]<br />
|-<br />
| ''string '' || '''label#=(Time,Distance,Distance,...)''' || || label on #-th axis<br />
|-<br />
| ''floats '' || '''mag=''' || || spike magnitudes [nsp]<br />
|-<br />
| ''int '' || '''n#=''' || || dimension of #-th axis<br />
|-<br />
| ''int '' || '''nsp=1''' || || Number of spikes<br />
|-<br />
| ''float '' || '''o#=(0,...)''' || || origin on #-th axis<br />
|-<br />
| ''floats '' || '''p#=[0,...]''' || || spike inclination (in samples) [nsp]<br />
|-<br />
| ''string '' || '''title=''' || || title for plots<br />
|-<br />
| ''string '' || '''unit#=[s,km,km,...]''' || || unit on #-th axis<br />
|}<br />
This is the program for creating a RSF hypercube out of nothing. Calling <tt>sfspike</tt> without specifying the k# or l# parameters will result in a volume filled with values specified by <tt>mag</tt>. To get a file full of 1's, just give <tt>sfspike</tt> the axis values that running <tt>sfin</tt> on your desired output would produce. I.e. if you run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" > out.rsf<br />
</pre><br />
you will obtain the following file:<br />
<pre><br />
bash$ sfin out.rsf<br />
out.rsf:<br />
in="/var/tmp/out.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
300 elements 1200 bytes<br />
</pre><br />
To create a "flat reflector" in the file above, run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5> out2.rsf<br />
</pre><br />
Notice that the values for <tt>k</tt> and <tt>l</tt> are in samples, not in the physical units of the respective axes. The result can be visualised with <br />
<pre><br />
< out2.rsf sfgrey pclip=100 wantscalebar=y title="Illustration of k,l parameters" | xtpen<br />
</pre><br />
which produces the following plot:<br />
<br />
[[Image:sfspike_fig1.png]]<br />
<br />
The <tt>p</tt> parameters can be used to create slanted lines/planes. Specifying <tt>p2=1</tt> means that for each lateral step, the spike will be shifted down with 1 sample. Below is the command and the corresponding graphical output it creates:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=1 |\<br />
sfgrey pclip=100 wantscalebar=y title="Effect of p2=1" | xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig2.png]]<br />
<br />
Sfspike also supports negative and non-integer p values:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=-0.15 |\<br />
sfgrey pclip=100 wantscalebar=y allpos=y color=h title="Effect of p2=-0.15" |xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig3.png]]<br />
<br />
When <tt>nsp</tt> is greater than the number of values for <tt>k</tt> and <tt>l</tt> parameters, the extra spikes will be piled on top of the last one, increasing its amplitude. Look at the amplitude of the last event in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=3 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
and in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=5 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
(pictures coming soon). This feature can easily cause a bug when the number of events is large and they have not been properly counted, or when a new spike was added on a list but <tt>nsp</tt> was not updated.<br />
<br />
==sfspray==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extend a dataset by duplicating in the specified axis dimension.<br />
|-<br />
! colspan="4" | sfspray < in.rsf > out.rsf axis=2 n= d= o= label= unit=<br />
|-<br />
| colspan="4" | This operation is adjoint to sfstack.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to spray<br />
|-<br />
| ''float '' || '''d=''' || || Sampling of the newly created dimension<br />
|-<br />
| ''string '' || '''label=''' || || Label of the newly created dimension<br />
|-<br />
| ''int '' || '''n=''' || || Size of the newly created dimension<br />
|-<br />
| ''float '' || '''o=''' || || Origin of the newly created dimension<br />
|-<br />
| ''string '' || '''unit=''' || || Units of the newly created dimension<br />
|}<br />
<br />
<tt>sfspray</tt> extends the input hypercube by replicating the data<br />
in one of the dimensions. The output dataset acquires one additional<br />
dimension. Here is an example:<br />
Start with a 2-D dataset<br />
<pre><br />
bash&#36; sfmath n1=5 n2=2 output=x1+x2 > test.rsf<br />
bash&#36; sfin test.rsf<br />
test.rsf:<br />
in="/var/tmp/test.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
10 elements 40 bytes<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
</pre><br />
Extend the data in the second dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=2 n=3 > test2.rsf<br />
bash&#36; sfin test2.rsf<br />
test2.rsf:<br />
in="/var/tmp/test2.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=3 d2=1 o2=0 <br />
n3=2 d3=1 o3=0 <br />
30 elements 120 bytes<br />
bash&#36; < test2.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 0 1 2 3 4<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
20: 1 2 3 4 5<br />
25: 1 2 3 4 5<br />
</pre><br />
The output is three-dimensional, with traces from the original<br />
data duplicated along the second axis.<br />
Extend the data in the third dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=3 n=2 > test3.rsf<br />
bash&#36; sfin test3.rsf<br />
test3.rsf:<br />
in="/var/tmp/test3.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
n3=2 d3=? o3=? <br />
20 elements 80 bytes<br />
bash&#36; < test3.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
</pre><br />
The output is also three-dimensional, with the original data replicated<br />
along the third axis.<br />
<br />
==sfstack==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stack a dataset over one of the dimensions.<br />
|-<br />
! colspan="4" | sfstack < in.rsf > out.rsf axis=2 rms=n norm=y min=n max=n<br />
|-<br />
| colspan="4" | <br>This operation is adjoint to sfspray.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to stack<br />
|-<br />
| ''bool '' || '''max=n''' || [y/n] || If y, find maximum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''min=n''' || [y/n] || If y, find minimum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || If y, normalize by fold.<br />
|-<br />
| ''bool '' || '''rms=n''' || [y/n] || If y, compute the root-mean-square instead of stack.<br />
|}<br />
While <tt>sfspray</tt> adds a dimension to a hypercube,<br />
<tt>sfstack</tt> effectively removes one of the dimensions by stacking<br />
over it. Here are some examples:<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
bash&#36; < test.rsf sfstack axis=2 | sfdisfil<br />
0: 1.5 2 3 4 5<br />
bash&#36; < test.rsf sfstack axis=1 | sfdisfil<br />
0: 2.5 3 4<br />
</pre><br />
Why is the first value not 1 (in the first case) or 2 (in the second<br />
case)? By default, <tt>sfstack</tt> normalizes the stack by the fold<br />
(the number of non-zero entries). To avoid normalization, use<br />
<tt>norm=n</tt>, as follows:<br />
<pre><br />
bash&#36; < test.rsf sfstack norm=n | sfdisfil <br />
0: 3 6 9 12 15<br />
</pre><br />
<tt>sfstack</tt> can also compute root-mean-square values as <br />
well as minimum and maximum values.<br />
<pre><br />
bash&#36; < test.rsf sfstack rms=y | sfdisfil<br />
0: 1.581 2.16 3.109 4.082 5.066<br />
bash&#36; < test.rsf sfstack min=y | sfdisfil<br />
0: 0 1 2 3 4<br />
bash&#36; < test.rsf sfstack axis=1 max=y | sfdisfil <br />
0: 4 5 6<br />
</pre><br />
<br />
==sftransp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Transpose two axes in a dataset. <br />
|-<br />
! colspan="4" | sftransp < in.rsf > out.rsf memsize=sf_memsize() plane=<br />
|-<br />
| colspan="4" | <br>If you get a "Cannot allocate memory" error, give the program a<br>memsize=1 command-line parameter to force out-of-core operation.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''plane=''' || || Two-digit number with axes to transpose. The default is 12<br />
|}<br />
<br />
The <tt>sftransp</tt> program transposes the input hypercube<br />
exchanging the two axes specified by the <b>plane=</b> parameter. <br />
<pre><br />
bash&#36; sfspike n1=10 n2=20 n3=30 > orig123.rsf<br />
bash&#36; sfin orig123.rsf <br />
orig123.rsf:<br />
in="/var/tmp/orig123.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=23 >out132.rsf<br />
bash&#36; sfin out132.rsf <br />
out132.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=20 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=13 >out321.rsf<br />
bash&#36; sfin out321.rsf <br />
out321.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=30 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=10 d3=0.004 o3=0 label3="Time" unit3="s" <br />
6000 elements 24000 bytes<br />
</pre><br />
<tt>sftransp</tt> tries to fit the dataset in memory to transpose it<br />
there but, if not enough memory is available, it performs a slower<br />
transpose out of core using disk operations. You can control the<br />
amount of available memory using the <b>memsize=</b> parameter or<br />
the <b>RSFMEMSIZE</b> environmental variable.<br />
<br />
==sfwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a portion of the dataset. <br />
|-<br />
! colspan="4" | sfwindow < in.rsf > out.rsf verb=n squeeze=y j#=(1,...) d#=(d1,d2,...) f#=(0,...) min#=(o1,o2,,...) n#=(0,...) max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)<br />
|-<br />
| ''float '' || '''d#=(d1,d2,...)''' || || sampling in #-th dimension<br />
|-<br />
| ''int '' || '''f#=(0,...)''' || || window start in #-th dimension<br />
|-<br />
| ''int '' || '''j#=(1,...)''' || || jump in #-th dimension<br />
|-<br />
| ''float '' || '''max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)''' || || maximum in #-th dimension<br />
|-<br />
| ''float '' || '''min#=(o1,o2,,...)''' || || minimum in #-th dimension<br />
|-<br />
| ''int '' || '''n#=(0,...)''' || || window size in #-th dimension<br />
|-<br />
| ''bool '' || '''squeeze=y''' || [y/n] || if y, squeeze dimensions equal to 1 to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
<b>sfwindow</b> is used to window a portion of the dataset. Here is<br />
a quick example: Start by creating some data.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Now window the first two rows:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n2=2 | sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
</pre><br />
Window the first three columns:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n1=3 | sfdisfil<br />
0: 1 2 3 2 4<br />
5: 6 3 6 9<br />
</pre><br />
Window the middle row:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f2=1 n2=1 | sfdisfil<br />
0: 2 4 6 8 10<br />
</pre><br />
You can interpret the <b>f#</b> and <b>n#</b> parameters as<br />
meaning "skip that many rows/columns" and "select that many<br />
rows/columns" correspondingly. Window the middle point in the dataset:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f1=2 n1=1 f2=1 n2=1 | sfdisfil<br />
0: 6<br />
</pre><br />
Window every other column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=2 | sfdisfil<br />
0: 1 3 5 2 6<br />
5: 10 3 9 15<br />
</pre><br />
Window every third column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=3 | sfdisfil<br />
0: 1 4 2 8 3<br />
5: 12<br />
</pre><br />
Alternatively, <b>sfwindow</b> can use the minimum and maximum<br />
parameters to select a window. In the following example, we are<br />
creating a dataset with <b>sfspike</b> and then windowing a portion of it<br />
between 1 and 2 seconds in time and sampled at 8 miliseconds.<br />
<pre><br />
bash&#36; sfspike n1=1000 n2=10 > spike.rsf <br />
bash&#36; sfin spike.rsf<br />
spike.rsf:<br />
in="/var/tmp/spike.rsf@"<br />
esize=4 type=float form=native <br />
n1=1000 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10000 elements 40000 bytes<br />
bash&#36; < spike.rsf sfwindow min1=1 max1=2 d1=0.008 > window.rsf<br />
bash&#36; sfin window.rsf<br />
window.rsf:<br />
in="/var/tmp/window.rsf@"<br />
esize=4 type=float form=native <br />
n1=126 d1=0.008 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
1260 elements 5040 bytes<br />
</pre><br />
By default, <b>sfwindow</b> "squeezes" the hypercube dimensions<br />
that are equal to one toward the end of the dataset. Here is an<br />
example of taking a time slice:<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=1 d2=0.004 o2=1 label2="Time" unit2="s" <br />
10 elements 40 bytes<br />
</pre><br />
You can change this behavior by specifying <b>squeeze=n</b>.<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 squeeze=n > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=1 d1=0.004 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10 elements 40 bytes<br />
</pre><br />
<br />
=Seismic programs=<br />
Programs in this category are specific for operations on seismic data. The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/seismic/ system/seismic] in the Madagascar distribution.<br />
<br />
==sfheaderattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Integer header attributes. <br />
|-<br />
! colspan="4" | sfheaderattr < head.rsf<br />
|-<br />
| colspan="4" | <br>Only nonzero values are reported.<br />
|}<br />
<br />
The <tt>sfheaderattr</tt> examines the contents of a trace header file,<br />
typically generated by <tt>sfsegyread</tt>. In the example below, we examine<br />
trace headers in the output of <tt>suplane</tt>, a program from Seismic Unix.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
bash$ sfheaderattr < tfile.rsf<br />
*******************************************<br />
71 headers, 32 traces<br />
key[0]="tracl" min[0]=1 max[31]=32 mean=16.5<br />
key[1]="tracr" min[0]=1 max[31]=32 mean=16.5<br />
key[11]="offset" min[0]=400 max[31]=400 mean=400<br />
key[38]="ns" min[0]=64 max[31]=64 mean=64<br />
key[39]="dt" min[0]=4000 max[31]=4000 mean=4000<br />
*******************************************<br />
</pre><br />
For different standard keywords, a minimum, maximum, and mean values<br />
are reported unless they are identically zero. This quick inspection<br />
can help in identifying meaningful keywords set in the data. The input<br />
data type must be <tt>int</tt>.<br />
<br />
==sfheadermath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations, possibly on header keys. <br />
|-<br />
! colspan="4" | sfheadermath < in.rsf > out.rsf memsize=sf_memsize() output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs<br><br>See also sfmath. <br><br>An addition operation can be performed by sfstack.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''output=''' || || Describes the output in a mathematical notation.<br />
|}<br />
<tt>sfheadermath</tt> is a versatile program for mathematical<br />
operations on rows of the input file. If the input file is an<br />
<tt>n1</tt> by <tt>n2</tt> matrix, the output will be a <tt>1</tt> by<br />
<tt>n2</tt> matrix that contains one row made out of mathematical<br />
operations on the other rows. <tt>sfheadermath</tt> can identify a row<br />
by number or by a standard SEGY keyword. The latter is useful for<br />
processing headers extracted from SEGY or SU files.<br />
Here is an example. First, we create an SU file with <tt>suplane</tt> and convert it to RSF using <tt>sfsegyread</tt>.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
</pre><br />
The trace header information is saved in <tt>tfile.rsf</tt>. It<br />
contains 71 headers for 32 traces in integer format.<br />
<pre><br />
bash$ sfin tfile.rsf<br />
tfile.rsf:<br />
in="/tmp/tfile.rsf@"<br />
esize=4 type=int form=native<br />
n1=71 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
2272 elements 9088 bytes<br />
</pre><br />
Next, we will convert <tt>tfile.rsf</tt> to a floating-point format<br />
and run <tt>sfheadermath</tt> to create a new header.<br />
<pre><br />
bash$ < tfile.rsf sfdd type=float | \<br />
sfheadermath myheader=1 output="sqrt(myheader+(2+10*offset^2))" > new.rsf<br />
bash$ sfin new.rsf<br />
new.rsf:<br />
in="/tmp/new.rsf@"<br />
esize=4 type=float form=native<br />
n1=1 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
32 elements 128 bytes<br />
</pre><br />
We defined "myheader" as being the row number 1 in the input (note<br />
that numbering starts with 0) and combined it with "offset", which<br />
is a standard SEGY keyword that denotes row number 11 (see the output<br />
of <tt>sfheaderattr</tt> above.) A variety of mathematical expressions<br />
can be defined in the <tt>output=</tt> string. The expression<br />
processing engine is shared with <tt>sfmath</tt>.<br />
<br />
==sfsegyheader==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Make a trace header file for segywrite.<br />
|-<br />
! colspan="4" | sfsegyheader < in.rsf > out.rsf n1= d1=<br />
|-<br />
| colspan="4" | <br> Use the output for tfile= argument in segywrite.<br />
|-<br />
| ''float '' || '''d1=''' || || trace sampling<br />
|-<br />
| ''int '' || '''n1=''' || || number of samples in a trace<br />
|}<br />
<br />
==sfsegyread==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert a SEG-Y or SU dataset to RSF.<br />
|-<br />
! colspan="4" | sfsegyread mask=msk.rsf > out.rsf tfile=hdr.rsf verb=false su=false format=sf_segyformat (bhead) ns=sf_segyns (bhead) endian= tape= read= hfile= bfile= mask= tfile=<br />
|-<br />
| colspan="4" | <br>Data headers and trace headers are separated from the data.<br><br>Defined SEG-Y trace header key names and byte offsets:<br><br>tracl: trace sequence number within line 0<br><br>tracr: trace sequence number within reel 4<br><br>fldr: field record number 8 <br><br>tracf: trace number within field record 12 <br><br>ep: energy source point number 16 <br><br>cdp: CDP ensemble number 20 <br><br>cdpt: trace number within CDP ensemble 24 <br><br>trid: trace identification code:<br>1 = seismic data<br>2 = dead<br>3 = dummy<br>4 = time break<br>5 = uphole<br>6 = sweep<br>7 = timing<br>8 = water break<br>9---, N = optional use (N = 32,767) 28 <br><br>nvs: number of vertically summed traces 30 <br><br>nhs: number of horizontally summed traces 32 <br><br>duse: data use:<br>1 = production<br>2 = test 34<br><br>offset: distance from source point to receiver<br>group (negative if opposite to direction<br>in which the line was shot) 36 <br><br>gelev: receiver group elevation from sea level<br>(above sea level is positive) 40 <br><br>selev: source elevation from sea level<br>(above sea level is positive) 44 <br><br>sdepth: source depth (positive) 48 <br><br>gdel: datum elevation at receiver group 52 <br><br>sdel: datum elevation at source 56 <br><br>swdep: water depth at source 60 <br><br>gwdep: water depth at receiver group 64 <br><br>scalel: scale factor for previous 7 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 68 <br><br>scalco: scale factor for next 4 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 70 <br><br>sx: X source coordinate 72 <br><br>sy: Y source coordinate 76 <br><br>gx: X group coordinate 80 <br><br>gy: Y group coordinate 84 <br><br>counit: coordinate units code:<br>for previoius four entries<br>1 = length (meters or feet)<br>2 = seconds of arc (in this case, the<br>X values are unsigned intitude and the Y values<br>are latitude, a positive value designates<br>the number of seconds east of Greenwich<br>or north of the equator 88 <br><br>wevel: weathering velocity 90 <br><br>swevel: subweathering velocity 92 <br><br>sut: uphole time at source 94 <br><br>gut: uphole time at receiver group 96 <br><br>sstat: source static correction 98 <br><br>gstat: group static correction 100 <br><br>tstat: total static applied 102 <br><br>laga: lag time A, time in ms between end of 240-<br>byte trace identification header and time<br>break, positive if time break occurs after<br>end of header, time break is defined as<br>the initiation pulse which maybe recorded<br>on an auxiliary trace or as otherwise<br>specified by the recording system 104 <br><br>lagb: lag time B, time in ms between the time<br>break and the initiation time of the energy source,<br>may be positive or negative 106 <br><br>delrt: delay recording time, time in ms between<br>initiation time of energy source and time<br>when recording of data samples begins<br>(for deep water work if recording does not<br>start at zero time) 108 <br><br>muts: mute time--start 110 <br><br>mute: mute time--end 112 <br><br>ns: number of samples in this trace 114 <br><br>dt: sample interval, in micro-seconds 116 <br><br>gain: gain type of field instruments code:<br>1 = fixed<br>2 = binary<br>3 = floating point<br>4 ---- N = optional use 118 <br><br>igc: instrument gain constant 120 <br><br>igi: instrument early or initial gain 122 <br><br>corr: correlated:<br>1 = no<br>2 = yes 124 <br><br>sfs: sweep frequency at start 126 <br><br>sfe: sweep frequency at end 128 <br><br>slen: sweep length in ms 130 <br><br>styp: sweep type code:<br>1 = linear<br>2 = cos-squared<br>3 = other 132 <br><br>stas: sweep trace length at start in ms 134 <br><br>stae: sweep trace length at end in ms 136 <br><br>tatyp: taper type: 1=linear, 2=cos^2, 3=other 138 <br><br>afilf: alias filter frequency if used 140 <br><br>afils: alias filter slope 142 <br><br>nofilf: notch filter frequency if used 144 <br><br>nofils: notch filter slope 146 <br><br>lcf: low cut frequency if used 148 <br><br>hcf: high cut frequncy if used 150 <br><br>lcs: low cut slope 152 <br><br>hcs: high cut slope 154 <br><br>year: year data recorded 156 <br><br>day: day of year 158 <br><br>hour: hour of day (24 hour clock) 160 <br><br>minute: minute of hour 162 <br><br>sec: second of minute 164 <br><br>timbas: time basis code:<br>1 = local<br>2 = GMT<br>3 = other 166 <br><br>trwf: trace weighting factor, defined as 1/2^N<br>volts for the least sigificant bit 168 <br><br>grnors: geophone group number of roll switch<br>position one 170 <br><br>grnofr: geophone group number of trace one within<br>original field record 172 <br><br>grnlof: geophone group number of last trace within<br>original field record 174 <br><br>gaps: gap size (total number of groups dropped) 176 <br><br>otrav: overtravel taper code:<br>1 = down (or behind)<br>2 = up (or ahead)<br />
|-<br />
| ''string '' || '''bfile=''' || || output binary data header file<br />
|-<br />
| ''bool '' || '''endian=''' || [y/n] || big/little endian flag, the default is estimated automatically<br />
|-<br />
| ''int '' || '''format=sf_segyformat (bhead)''' || [1,2,3,5] || Data format. The default is taken from binary header.<br />
:1 is IBM floating point<br />
:2 is 4-byte integer<br />
:3 is 2-byte integer<br />
:5 is IEEE floating point<br />
|-<br />
| ''string '' || '''hfile=''' || || output text data header file<br />
|-<br />
| ''string '' || '''mask=''' || || optional header mask for reading only selected traces<br />
|-<br />
| ''int '' || '''ns=sf_segyns (bhead)''' || || Number of samples. The default is taken from binary header<br />
|-<br />
| ''string '' || '''read=''' || || what to read: h - header, d - data, b - both (default)<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if input is SU, n if input is SEGY<br />
|-<br />
| ''bool '' || '''suxdr=n''' || [y/n] || y, SU has XDR support<br />
|-<br />
| ''string '' || '''tape=''' || || <br />
|-<br />
| ''string '' || '''tfile=''' || || output trace header file<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
The SEG Y format is an [http://en.wikipedia.org/wiki/Open_standard open standard] for the exchange of geophysical data. It is controlled by the non-profit [http://www.seg.org/SEGportalWEBproject/portals/SEG_Online.portal?_nfpb=true&_pageLabel=pg_gen_content&Doc_Url=prod/SEG-Publications/Pub-Yearbook/committees.htm SEG Technical Standards Committee]. There are two versions of this standard: [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev0.pdf rev0] (1975)<ref>Barry, K.M., Cavers, D.A., and Kneale, C.W. 1975. Recommended standards for digital tape formats. ''Geophysics'', '''40''', no. 02, 344–352.</ref> and [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf rev1] (2002)<ref>Norris, M.W., Faichney, A.K., ''Eds''. 2001. SEG Y rev1 Data Exchange format. Society of Exploration Geophysicists, Tulsa, OK, 45 pp.</ref>. The implementation in <tt>sfsegyread</tt> is a mixture of rev0 (i.e. no checks for Extended Textual Headers) and rev1 ([http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE floating point format] allowed for trace data samples).<br />
<br />
A SEG-Y file as understood by <tt>sfsegyread</tt> contains a "Reel Identification Header" (3200 bytes in EBCDIC followed by 400 bytes in a binary encoding), followed by a number of "Trace Blocks". Each "Trace Block" contains a 240-byte "Trace Header" (binary) followed by "Trace Data" -- a sequence of <tt>ns</tt> samples. Binary values in both reel headers and trace headers are two's complement integers, either two bytes or four bytes long. There are no floating-point values defined in the headers. Trace Data samples can have various encodings, either floating point or integer, described further down, but they are all big-endian. To convert from SEG-Y to RSF, <tt>sfsegyread</tt> will strip the tape reel EBCDIC header and convert it to ASCII, will extract the reel binary header without changing it, and will put the trace headers into one RSF file, and the traces themselves on another.<br />
<br />
===SEG-Y Trace Headers===<br />
In the SEG-Y standard, only the first 180 bytes of the 240-byte trace header are defined; bytes 181-240 are reserved for non-standard header information, and these locations are increasingly used in modern SEG-Y files and its variants. The standard provides for a total of 71 4-byte and 2-byte predefined header words. These 71 standard words have defined lengths and byte offsets, and only these words and byte locations are read using <tt>segyread</tt> and output to the RSF header file with the <tt>hfile=</tt> option. The user may remap these predefined keywords to a different byte offsets.<br />
<br />
===SU File Format===<br />
An [http://www.cwp.mines.edu/sututor/node22.html SU file] is nothing more than a SEG-Y file without the reel headers, and with the Trace Data samples in the native encoding of the CPU the file was created on (Attention -- limited portability!). So, to convert from SU to RSF, <tt>sfsegyread</tt> will just separate headers and traces into two RSF files. <br />
<br />
===SEG-Y specific parameters===<br />
*<tt>hfile=</tt> specifies the name of the file in which the EBCDIC reel header will be put after conversion to ASCII. If you are certain there is no useful information in it, <tt>hfile=/dev/null</tt> works just fine. If you do not specify anything for this parameter you will get an ASCII file named <tt>header</tt> in the current directory. If you want to quickly preview this header before running <tt>sfsegyread</tt>, use<pre>dd if=input.segy count=40 bs=80 cbs=80 conv=unblock,ascii</pre><br />
*<tt>bfile=</tt> specifies name of the file in which the binary reel header (the 400-bytes thing following the 3600-bytes EBCDIC) will be put without any conversion. The default name is "binary". Unless you have software that knows how to read exactly this special type of file, it will be completely useless, so do <tt>bfile=/dev/null</tt><br />
*<tt>format=</tt> specifies the format in which the trace data samples are in the SEG-Y input file. This is read from the binary reel header of the SEG-Y file. Valid values are 1(IBM floating point), 2 (4-byte integer), 3 (2-byte integer) and 5 (IEEE floating point). If the input file is SU, the format will be assumed to be the native <tt>float</tt> format.<br />
<br />
*<tt>keyname=</tt> specifies the byte offset to remap a header using the trace header key names shown above. For example, if the CDP locations have been placed in bytes 181-184 instead of the standard 21-24, <tt>cdp=180</tt> will remap the trace header to that location. <br />
<br />
===SU-specific parameters===<br />
*<tt>suxdr=</tt> specifies whether the input file was created with a SU package with XDR support enabled. If you have access to the source code of your SU install (try <tt>$CWPROOT/src</tt>), type: <tt>grep 'XDRFLAG =' $CWPROOT/src/Makefile.config</tt> and look at the last uncommented entry. If no value is given for <tt>XDRFLAG</tt>, the package was not compiled with XDR support.<br />
===Common parameters===<br />
*<tt>su=</tt> specifies if the input file is SU or SEG-Y. Default is <tt>su=n</tt> (SEG-Y file).<br />
*<tt>tape=</tt> specifies the input data. Stdin could not be used because <tt>sfsegyread</tt> has to work with tapes, and needs to fseek back and forth through the input file. Thankfully, output is on stdout.<br />
*<tt>read=</tt> specifies what parts of the "Trace Blocks" will be read. It can be <tt>read=t</tt> (only trace data is read), <tt>read=h</tt> (only trace headers are read) or <tt>read=b</tt> (both are read).<br />
*<tt>tfile=</tt> gives the name of the RSF file to which trace headers are written. Obviously, it should be only specified with <tt>read=h</tt> or <tt>read=b</tt>.<br />
*<tt>mask=</tt> is an optional parameter specifying the name of a mask that says which traces will be read. The mask is a 1-D RSF file with integers. The number of samples in the mask is the same as the number of traces in the unmasked SEG-Y. In places corresponding to unwanted traces there should be zeros in the mask.<br />
*<tt>ns=</tt> specifies the number of samples in a trace. For SEG-Y files, the default is taken from the binary reel header, and for SU files, from the header of the first trace. This parameter is however critical enough that a command line override was given for it.<br />
*<tt>verbose=</tt> is the verbosity flag. Can be <tt>y</tt> or <tt>n</tt>.<br />
*<tt>endian=</tt> is a y/n flag (default y), specifying whether to automatically estimate or not if samples in the Trace Data blocks are big-endian or little-endian. Try it if you are in trouble and do not know what else to do, otherwise let the automatic estimation do its job.<br />
<br />
==sfsegywrite==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert an RSF dataset to SEGY or SU.<br />
|-<br />
! colspan="4" | sfsegywrite < in.rsf tfile=hdr.rsf verb=false su=false endian=sf_endian() tape= hfile= bfile=<br />
|-<br />
| colspan="4" | <br>Merges trace headers with data.<br />
|-<br />
| ''string '' || '''bfile=''' || || input binary data header file<br />
|-<br />
| ''bool '' || '''endian=sf_endian()''' || [y/n] || big/little endian flag. The default is estimated automatically<br />
|-<br />
| ''string '' || '''hfile=''' || || input text data header file<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if output is SU, n if output is SEGY<br />
|-<br />
| ''string '' || '''tape=''' || ||<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
Please see <tt>sfsegyread</tt> for a complete description of parameter meanings and background issues. Parameters <tt>bfile</tt> and <tt>hfile</tt> should only be given values when the desired file is SEG-Y (default). The output file is specified by the <tt>tape=</tt> tag.<br />
<br />
=Plotting programs=<br />
The source files for these programs can be found under<br />
[http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/plot/main/ plot/main]<br />
in the Madagascar distribution.<br />
<br />
THIS SECTION IS UNDER CONSTRUCTION<br />
<br />
==sfbox==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Draw a balloon-style label.<br />
|-<br />
! colspan="4" | sfbox lab_color=VP_WHITE lab_fat=0 pscale=1. pointer=y reverse=n lat=0. long=90. angle=0. x0=0. y0=0. scale0=1. xt=2. yt=0. x_oval=0. y_oval=0. boxit=y length= scalet= size=.25 label= > out.vpl<br />
|-<br />
| ''float '' || '''angle=0.''' || || longitude of floating label in 3-D<br />
|-<br />
| ''bool '' || '''boxit=y''' || [y/n] || if y, create a box around text<br />
|-<br />
| ''int '' || '''lab_color=VP_WHITE''' || || label color<br />
|-<br />
| ''int '' || '''lab_fat=0''' || || label fatness<br />
|-<br />
| ''string '' || '''label=''' || || text for label<br />
|-<br />
| ''float '' || '''lat=0.''' || || <br />
|-<br />
| ''float '' || '''length=''' || || normalization for xt and yt<br />
|-<br />
| ''float '' || '''long=90.''' || || latitude and longitude of viewpoint in 3-D<br />
|-<br />
| ''bool '' || '''pointer=y''' || [y/n] || if y, create arrow pointer<br />
|-<br />
| ''float '' || '''pscale=1.''' || || scale factor for width of pointer<br />
|-<br />
| ''bool '' || '''reverse=n''' || [y/n] || <br />
|-<br />
| ''float '' || '''scale0=1.''' || || scale factor for x0 and y0<br />
|-<br />
| ''float '' || '''scalet=''' || || <br />
|-<br />
| ''float '' || '''size=.25''' || || text height in inches<br />
|-<br />
| ''float '' || '''x0=0.''' || || <br />
|-<br />
| ''float '' || '''x_oval=0.''' || || <br />
|-<br />
| ''float '' || '''xt=2.''' || || <br />
|-<br />
| ''float '' || '''y0=0.''' || || position of the pointer tip<br />
|-<br />
| ''float '' || '''y_oval=0.''' || || size of the oval around pointer<br />
|-<br />
| ''float '' || '''yt=0.''' || || relative position of text<br />
|}<br />
==sfcontour==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Contour plot.<br />
|-<br />
! colspan="4" | sfcontour < in.rsf c= min1=o1 min2=o2 max1=o1+(n1-1)*d1 max2=o2+(n2-1)*d2 nc=50 dc= c0= transp=y minval= maxval= allpos=y barlabel= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=y''' || [y/n] || contour positive values only<br />
|-<br />
| ''string '' || '''barlabel=''' || || <br />
|-<br />
| ''floats '' || '''c=''' || || [nc]<br />
|-<br />
| ''float '' || '''c0=''' || || first contour<br />
|-<br />
| ''float '' || '''dc=''' || || contour increment<br />
|-<br />
| ''float '' || '''max1=o1+(n1-1)*d1''' || || <br />
|-<br />
| ''float '' || '''max2=o2+(n2-1)*d2''' || || data window to plot<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''min1=o1''' || || <br />
|-<br />
| ''float '' || '''min2=o2''' || || <br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nc=50''' || || number of contours<br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfdots==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot signal with lollipops.<br />
|-<br />
! colspan="4" | sfdots < in.rsf labels= dots=(n1 <= 130)? 1: 0 seemean=(bool) (n2 <= 30) strings=(bool) (n1 <= 400) connect=1 corners= silk=n gaineach=y labelsz=8 yreverse=n constsep=n seedead=n transp=n xxscale=1. yyscale=1. clip=-1. overlap=0.9 screenratio=VP_SCREEN_RATIO screenht=VP_STANDARD_HEIGHT screenwd=screenhigh / screenratio radius=dd1/3 label1= unit1= title= > plot.vpl<br />
|-<br />
| ''float '' || '''clip=-1.''' || || data clip<br />
|-<br />
| ''int '' || '''connect=1''' || || connection type: 1 - diagonal, 2 - bar, 4 - only for non-zero data<br />
|-<br />
| ''bool '' || '''constsep=n''' || [y/n] || if y, use constant trace separation<br />
|-<br />
| ''int '' || '''corners=''' || || number of polygon corners (default is 6)<br />
|-<br />
| ''int '' || '''dots=(n1 <= 130)? 1: 0''' || || type of dots: 1 - baloon, 0 - no dots, 2 - only for non-zero data<br />
|-<br />
| ''bool '' || '''gaineach=y''' || [y/n] || if y, gain each trace independently<br />
|-<br />
| ''string '' || '''label1=''' || || <br />
|-<br />
| ''strings'' || '''labels=''' || || trace labels [n2]<br />
|-<br />
| ''int '' || '''labelsz=8''' || || label size<br />
|-<br />
| ''float '' || '''overlap=0.9''' || || trace overlap<br />
|-<br />
| ''float '' || '''radius=dd1/3''' || || dot radius<br />
|-<br />
| ''float '' || '''screenht=VP_STANDARD_HEIGHT''' || || screen height<br />
|-<br />
| ''float '' || '''screenratio=VP_SCREEN_RATIO''' || || screen aspect ratio<br />
|-<br />
| ''float '' || '''screenwd=screenhigh / screenratio''' || || screen width<br />
|-<br />
| ''bool '' || '''seedead=n''' || [y/n] || if y, show zero traces<br />
|-<br />
| ''bool '' || '''seemean=(bool) (n2 <= 30)''' || [y/n] || if y, draw axis lines<br />
|-<br />
| ''bool '' || '''silk=n''' || [y/n] || if y, silky plot<br />
|-<br />
| ''bool '' || '''strings=(bool) (n1 <= 400)''' || [y/n] || if y, draw strings<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axis<br />
|-<br />
| ''string '' || '''unit1=''' || || <br />
|-<br />
| ''float '' || '''xxscale=1.''' || || x scaling<br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse y axis<br />
|-<br />
| ''float '' || '''yyscale=1.''' || || y scaling<br />
|}<br />
==sfgraph3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot for surfaces.<br />
|-<br />
! colspan="4" | sfgraph3 < in.rsf orient=1 min= max= point1=0.5 point2=0.5 frame1=0.5*(min+max) frame2=n1-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y > plot.vpl<br />
|-<br />
| ''float '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''float '' || '''frame1=0.5*(min+max)''' || || <br />
|-<br />
| ''int '' || '''frame2=n1-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''max=''' || || maximum function value<br />
|-<br />
| ''float '' || '''min=''' || || minimum function value<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''orient=1''' || || function orientation<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|}<br />
==sfgraph==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Graph plot.<br />
|-<br />
! colspan="4" | sfgraph < in.rsf symbolsz= pclip=100. transp=n symbol= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''pclip=100.''' || || clip percentile<br />
|-<br />
| ''string '' || '''symbol=''' || || if set, plot with symbols instead of lines<br />
|-<br />
| ''floats '' || '''symbolsz=''' || || symbol size (default is 2) [n2]<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfgrey3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot.<br />
|-<br />
! colspan="4" | sfgrey3 < in.rsf point1=0.5 point2=0.5 frame1=0 frame2=n2-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y scalebar=n minval= maxval= barreverse=n nreserve=8 bar= color= > plot.vpl<br />
|-<br />
| colspan="4" | Requires an "unsigned char" input (the output of sfbyte).<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''int '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''int '' || '''frame1=0''' || || <br />
|-<br />
| ''int '' || '''frame2=n2-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || if y, draw scalebar<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
for sfgrey and sfgrey3. Examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfgrey==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate raster plot.<br />
|-<br />
! colspan="4" | sfgrey < in.rsf > out.rsf bar=bar.rsf transp=y yreverse=y xreverse=n gpow= phalf= clip= pclip= gainstep=0.5+n1/256. allpos=n bias=0. polarity=n verb=n scalebar=n minval= maxval= barreverse=n wantframenum=(bool) (n3 > 1) nreserve=8 gainpanel= bar= color= > (plot.vpl | char.rsf)<br />
|-<br />
| colspan="4" | Can input char values.<br>If called "byte", outputs char values.<br><br>Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=n''' || [y/n] || if y, assume positive data<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=''' || || <br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''string '' || '''gainpanel=''' || || gain reference: 'a' for all, 'e' for each, or number<br />
|-<br />
| ''int '' || '''gainstep=0.5+n1/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=''' || || <br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''pclip=''' || || data clip percentile (default is 99)<br />
|-<br />
| ''float '' || '''phalf=''' || || percentage for estimating gpow<br />
|-<br />
| ''bool '' || '''polarity=n''' || [y/n] || if y, reverse polarity (white is high by default)<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the display axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''bool '' || '''wantframenum=(bool) (n3 > 1)''' || [y/n] || if y, display third axis position in the corner<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''bool '' || '''yreverse=y''' || [y/n] || if y, reverse the vertical axis<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
and examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfplas==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Assembler - convert ascii to vplot. <br />
|-<br />
! colspan="4" | sfplas<br />
|}<br />
==sfpldb==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Debugger - convert vplot to ascii. <br />
|-<br />
! colspan="4" | sfpldb<br />
|}<br />
==sfplotrays==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot rays.<br />
|-<br />
! colspan="4" | sfplotrays frame=frame.rsf nt=n1*n2 jr=1 frame= < rays.rsf > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''string '' || '''frame=''' || || <br />
|-<br />
| ''int '' || '''jr=1''' || || skip rays<br />
|-<br />
| ''int '' || '''nt=n1*n2''' || || maximum ray length<br />
|}<br />
==sfthplot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Hidden-line surface plot.<br />
|-<br />
! colspan="4" | sfthplot < in.rsf uflag=y dflag=y alpha=45. titlsz=9 axissz=6 plotfat=0 titlefat=2 axisfat=2 plotcolup=VP_YELLOW plotcoldn=VP_RED axis=y axis1=y axis2=y axis3=y clip=0. pclip=100. gainstep=0.5+nx/256. bias=0. dclip=1. norm=y xc=1.5 zc=3 ratio=5. zmax= zmin= sz=6. label#= unit#= tpow=0 epow=0 gpow=1 title= > plot.vpl<br />
|-<br />
| ''float '' || '''alpha=45.''' || || apparent angle in degrees, |alpha| < 89<br />
|-<br />
| ''bool '' || '''axis=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis1=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis2=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis3=y''' || [y/n] || plot axis<br />
|-<br />
| ''int '' || '''axisfat=2''' || || axes fatness<br />
|-<br />
| ''int '' || '''axissz=6''' || || axes size<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip<br />
|-<br />
| ''float '' || '''dclip=1.''' || || change the clip: clip *= dclip<br />
|-<br />
| ''bool '' || '''dflag=y''' || [y/n] || if y, plot down side of the surface<br />
|-<br />
| ''float '' || '''epow=0''' || || exponential gain<br />
|-<br />
| ''int '' || '''gainstep=0.5+nx/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=1''' || || power gain<br />
|-<br />
| ''string '' || '''label#=''' || || label on #-th axis<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || normalize by the clip<br />
|-<br />
| ''float '' || '''pclip=100.''' || || data clip percentile<br />
|-<br />
| ''int '' || '''plotcoldn=VP_RED''' || || color of the lower side<br />
|-<br />
| ''int '' || '''plotcolup=VP_YELLOW''' || || color of the upper side<br />
|-<br />
| ''int '' || '''plotfat=0''' || || line fatness<br />
|-<br />
| ''float '' || '''ratio=5.''' || || plot adjustment<br />
|-<br />
| ''float '' || '''sz=6.''' || || vertical scale<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''int '' || '''titlefat=2''' || || title fatness<br />
|-<br />
| ''int '' || '''titlsz=9''' || || title size<br />
|-<br />
| ''string '' || '''tpow=0''' || || time power gain<br />
|-<br />
| ''bool '' || '''uflag=y''' || [y/n] || if y, plot upper side of the surface<br />
|-<br />
| ''string '' || '''unit#=''' || || unit on #-th axis<br />
|-<br />
| ''float '' || '''xc=1.5''' || || <br />
|-<br />
| ''float '' || '''zc=3''' || || lower left corner of the plot<br />
|-<br />
| ''float '' || '''zmax=''' || || <br />
|-<br />
| ''float '' || '''zmin=''' || || <br />
|}<br />
==sfwiggle==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot data with wiggly traces. <br />
|-<br />
! colspan="4" | sfwiggle < in.rsf xpos=xpos.rsf xmax= xmin= poly=n fatp=1 xmask=1 ymask=1 pclip=98. zplot=0.75 clip=0. seemean=n verb=n transp=n yreverse=n xreverse=n xpos= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip (estimated from pclip by default<br />
|-<br />
| ''int '' || '''fatp=1''' || || <br />
|-<br />
| ''float '' || '''pclip=98.''' || || clip percentile<br />
|-<br />
| ''bool '' || '''poly=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''seemean=n''' || [y/n] || if y, plot mean lines of traces<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''int '' || '''xmask=1''' || || <br />
|-<br />
| ''float '' || '''xmax=''' || || maximum trace position (if using xpos)<br />
|-<br />
| ''float '' || '''xmin=''' || || minimum trace position (if using xpos)<br />
|-<br />
| ''string '' || '''xpos=''' || || optional header file with trace positions<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''int '' || '''ymask=1''' || || <br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse the vertical axis<br />
|-<br />
| ''float '' || '''zplot=0.75''' || || <br />
|}<br />
<br />
=filt/imag programs=<br />
==sfremap1==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 1-D ENO interpolation. <br />
|-<br />
! colspan="4" | sfremap1 < in.rsf > out.rsf pattern=pattern.rsf n1=n1 d1=d1 o1=o1 order=3<br />
|-<br />
| ''float '' || '''d1=d1''' || || Output sampling<br />
|-<br />
| ''int '' || '''n1=n1''' || || Number of output samples<br />
|-<br />
| ''float '' || '''o1=o1''' || || Output origin<br />
|-<br />
| ''int '' || '''order=3''' || || Interpolation order<br />
|-<br />
| ''string '' || '''pattern=''' || || auxiliary input file name<br />
|}<br />
To give an example of usage, we will create an input for <tt>sfremap1</tt> with:<br />
<pre><br />
sfmath n1=11 n2=11 d1=1 d2=1 o1=-5 o2=-5 output="x1*x1+x2*x2" > inp2remap1.rsf<br />
</pre><br />
Let us interpolate the data across both dimensions, then display it:<br />
<pre><br />
&lt; inp2remap1.rsf sfremap1 n1=1001 d1=0.01 | sftransp | \<br />
sfremap1 n1=1001 d1=0.01 | sftransp | sfgrey allpos=y | xtpen<br />
</pre><br />
The comparison with the uninterpolated data ( <tt>&lt; inp2remap1.rsf sfgrey allpos=y | xtpen</tt> ) is quite telling.<br />
<br />
=filt/proc programs=<br />
==sfstretch==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stretch of the time axis. <br />
|-<br />
! colspan="4" | sfstretch < in.rsf > out.rsf datum=dat.rsf inv=n dens=1 v0= half=y delay= tdelay= hdelay= nout=dens*n1 extend=4 mute=0 maxstr=0 rule=<br />
|-<br />
| ''file '' || '''datum=''' || || auxiliary input file name<br />
|-<br />
| ''float '' || '''delay=''' || || time delay for rule=lmo<br />
|-<br />
| ''int '' || '''dens=1''' || || axis stretching factor<br />
|-<br />
| ''int '' || '''extend=4''' || || trace extension<br />
|-<br />
| ''bool '' || '''half=y''' || [y/n] || if y, the second axis is half-offset instead of full offset<br />
|-<br />
| ''float '' || '''hdelay=''' || || offset delay for rule=rad<br />
|-<br />
| ''bool '' || '''inv=n''' || [y/n] || if y, do inverse stretching<br />
|-<br />
| ''float '' || '''maxstr=0''' || || maximum stretch<br />
|-<br />
| ''int '' || '''mute=0''' || || tapering size<br />
|-<br />
| ''int '' || '''nout=dens*n1''' || || output axis length (if inv=n)<br />
|-<br />
| ''string '' || '''rule=''' || || Stretch rule:<br />
:n - normal moveout (nmostretch), default<br />
:l - linear moveout (lmostretch)<br />
:L - logarithmic stretch (logstretch)<br />
:2 - t^2 stretch (t2stretch)<br />
:c - t^2 chebyshev stretch (t2chebstretch)<br />
:r - radial moveout (radstretch)<br />
:d - datuming (datstretch)<br />
|-<br />
| ''float '' || '''tdelay=''' || || time delay for rule=rad<br />
|-<br />
| ''float '' || '''v0=''' || || moveout velocity<br />
|}<br />
<br />
<tt>sfstretch rule=d</tt> (aka <tt>sfdatstretch</tt>) can be used to apply statics. Here is a synthetic example, courtesy of Alessandro Frigeri:<br />
<pre><br />
# generate a dataset with 'flat' signals<br />
sfmath n1=200 n2=100 output="sin(0.5*x1)" type=float > scan.rsf<br />
<br />
# generate a sinusoidal elevation correction<br />
sfmath n1=100 output="3*sin(x1)" type=float > statics.rsf<br />
<br />
# apply statics, producing a 'wavy' output.<br />
sfstretch < scan.rsf > out.rsf datum=statics.rsf rule=d<br />
</pre><br />
<br />
=user/ivlad programs=<br />
==sfprep4plot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Resamples a 2-D dataset to the desired picture resolution, with antialias<br />
|-<br />
! colspan="4" | sfprep4plot inp= out= verb=n h=none w=none unit= ppi= prar=y<br />
|-<br />
| colspan="4" | Only one of the h and w parameters needs to be specified.<br>If prar=n, no action will be taken on axis for which h/w was not specified<br>If prar=y and only one par (h or w) is specified, the picture will scale<br>along both axes until it is of the specified dimension.<br />
|-<br />
| ''int '' || '''h=none''' || || output height<br />
|-<br />
| ''string '' || '''inp=''' || || input file<br />
|-<br />
| ''string '' || '''out=''' || || output file<br />
|-<br />
| ''int '' || '''ppi=''' || || output resolution (px/in). Necessary when unit!=px<br />
|-<br />
| ''bool '' || '''prar=y''' || [y/n] || if y, PReserve Aspect Ratio of input<br />
|-<br />
| ''string '' || '''unit=''' || || unit of h and w. Can be: px(default), mm, cm, in<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || if y, print system commands, outputs<br />
|-<br />
| ''int '' || '''w=none''' || || output width<br />
|}<br />
For a figure that does not need the aspect ratio preserved,<br />
and needs to fill a 1280x1024 projector display:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=1280 h=1024 prar=n<br />
</pre><br />
For a print figure that has to fit in a 6x8in box<br />
at a resolution of 250 dpi, preserving the aspect ratio:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=6 h=8 unit=in ppi=250<br />
</pre><br />
A comparison of images before and after the application of <tt>sfprep4plot</tt>, courtesy of Joachim Mispel, is shown below:<br />
<br />
[[Image:sf_prep4plot.jpg]]<br />
<br />
=user/jennings programs=<br />
==sfsizes==<br />
<br />
<br />
<br />
=References=<br />
<references/></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Adding_new_programs_to_Madagascar&diff=689Adding new programs to Madagascar2009-03-06T17:55:55Z<p>Jenningsjwj: /* How to test your program */</p>
<hr />
<div>[[Image:Fotolia_800161_XS.jpg|right|]]<br />
Whether you want to share your work with the world or keep it for yourself, madagascar is fully extensible. The following instructions explain the simplest way to add your own programs to the package.<br />
<br />
==How to add your program==<br />
<br />
#Create a directory for yourself or your group under <tt>MADAGASCAR/user</tt>, where <tt>MADAGASCAR</tt> is the top source directory. Put your programs there.<br />
#The following conventions are adopted:<br />
#*Files containing main programs start with <tt>M</tt>, i.e. <tt>Mmyprog.c</tt> or <tt>Mmyprog.py</tt>. Each main program file should start with a short one-line comment describing its purpose. <br />
#*Files containing subroutines start with small letters. A header/interface file <tt>myprog.h</tt> is automatically generated from <tt>myprog.c</tt>. By using header files, dependencies between different functions will be figured out automatically. Include a comment of the form <font color="#cd4b19">/*^*/</font> after any block of text that you want to be included in the header file. Include a comment of the form <font color="#cd4b19">/*< My function description >*/</font> after a function definition if you want its interface included in the header file. It is a good habit to comment interfaces to all your functions. <br />
#Create a <tt>SConstruct</tt> file in your directory by following examples from other <tt>user</tt> directories. Inside the triple quotation marks after <tt>progs=</tt>, replace the names of their programs with the names of your programs with spaces between the names. <br />
#Note that running <tt>scons</tt> inside your <tt>user</tt> directory compiles programs with debugging flags to make them suitable for debugging with common debuggers such as [http://www.gnu.org/software/gdb/ gdb], dbx, or [http://www.etnus.com/ TotalView]. Running <tt>scons install</tt> inside the top source directory will compile your programs with optimization flags and install them in <tt>&#36;RSFROOT</tt>. <br />
<br />
==How to share your program with others==<br />
<br />
Follow the guide on [[Contributing new programs to Madagascar]].<br />
<br />
==How to document your program==<br />
There are three levels of documentation. From the most simple to the most complex, they are: in-code documentation, the Wiki, and reproducible papers. <br />
===In-code documentation===<br />
Of course, do comment your code -- focusing on "why" (the code itself describes the "how"). Keep comments sparse so that as much code as possible can be kept in mind at the same time by the human reader. Use the other levels for more information.<br />
<br />
If you follow a certain syntax for some of your comments, then the scripts in the Madagascar framework will be able to automatically produce a self-doc page for your program. This page will be displayed in the terminal (using basic text-mode formatting) when the program is invoked without any arguments, and a HTML version will be automatically generated in $RSFDOC (default: $RSFROOT/doc). The self-doc page has the following sections: <tt>Name</tt>, <tt>Description</tt>, <tt>Synopsis</tt>, <tt>Comments</tt>, <tt>Parameters</tt>, <tt>Used in</tt>, <tt>Source</tt> and <tt>Version</tt>. <br />
====Self-doc for C programs====<br />
To automatically populate the <tt>Description</tt> and <tt>Comments</tt> sections, use the following syntax. Start the file with:<br />
<c><br />
/* Short description line<br />
Comments here blablabla lorem ipsum dolores sit amet...<br />
<br />
You can use several paragraphs for comments, no problem.*/<br />
<br />
/* Copyright notice */<br />
</c><br />
Notice that: (1) the description line is the first line in the file; (2) Comments are closed and then open again on a new line for Copyright (so that Copyright does not show up in the documentation).<br />
<br />
To make input parameters and their default values (if they exist) automatically appear in the <tt>Synopsis</tt> and <tt>Parameters</tt> sections, make sure to read the parameters in the code like in the following example:<br />
<c><br />
if (!sf_getbool("su",&su)) su=false;<br />
/* y if input is SU, n if input is SEGY */<br />
</c><br />
Notice that there are no complex logical operations inside the <tt>if</tt>, that there is no space between the equal sign and the right and left hand, and that a short comment follows immediately. If by necessity the parameter is read in a complex fashion, use angular brackets inside the short line following the read block, i.e.:<br />
<pre><br />
... sf_getfloat ... complex stuff ...<br />
/*< parameter_name parameter meaning >*/<br />
</pre><br />
<br />
====Self-doc for Python programs====<br />
To automatically populate the <tt>Description</tt> page, and <tt>Comments</tt> sections, use the following syntax. Start the file with:<br />
<python><br />
#! /usr/bin/env python<br />
'''My one-line description of this program<br />
If I have comments, put them in the lines below.<br />
<br />
I can use several paragraphs for that'''<br />
<br />
# Copyright notice...<br />
</python><br />
Then, make sure to<br />
<python><br />
import rsfprog<br />
</python><br />
To make input parameters and their default values (if they exist) automatically appear in the <tt>Synopsis</tt> and <tt>Parameters</tt> sections, make sure to follow each argument read with a comment, and call <tt>selfdoc</tt> if no argument was given. Here is an example from <tt>user/ivlad/Mpclip.py</tt>:<br />
<python><br />
par = rsf.Par(argv)<br />
<br />
inp = par.string('inp') # input file<br />
out = par.string('out') # output file<br />
if None in (inp, out):<br />
rsfprog.selfdoc() # self-doc<br />
return error<br />
<br />
verb = par.bool('verb', False) # if y, print system commands, outputs<br />
</python><br />
<br />
====Self-doc for Fortran 90 programs====<br />
To automatically populate the <tt>Description</tt> section (<tt>Comments</tt> is not available), use the following syntax. Start the file with:<br />
<pre><br />
! One-line short description, leave a blank line after it<br />
<br />
! Copyright notice...<br />
</pre><br />
<br />
To make input parameters and their default values (if they exist) automatically appear in the <tt>Synopsis</tt> and <tt>Parameters</tt> sections, make sure to read the parameters in the code like in the following example:<br />
<pre><br />
call from_par( "n1", nt, 512 ) ! Param description on same line or first line after<br />
</pre><br />
<br />
===The Madagascar Wiki===<br />
The self-doc is good as a reminder of what the parameters mean and what their default values are, but more is usually needed for someone who never used the tool. This is what the [[Guide to madagascar programs|Guide to programs]] is for. Whenever you change or create a program, make sure to add a section for it in there too, if possible with an implementation section. Documenting programs that already exist is also a great idea.<br />
<br />
You may have noticed that each program section on that page starts with a table that has the same content as the self-doc. That is created automatically the following way. Say you want to create this table for <tt>sfattr</tt>. At a command line, type:<br />
<pre><br />
sfdoc -m $HOME attr<br />
</pre><br />
This will create the file <tt>$HOME/sfattr.wiki</tt>. Its content can be copied and pasted into the Madagascar wiki, as they already are in the MediaWiki format. Another directory can be used instead of $HOME.<br />
<br />
If your program/script reads an environment variable, make sure you check [[Advanced Installation#Environment variables|the list of environment variables used by Madagascar]] and add your new variable or your peculiar usage of an existing variable.<br />
<br />
After creating the appropriate section in the [[Guide to madagascar programs|Guide to programs]], add your program name without the <tt>sf</tt> prefix to the <tt>docprogs</tt> list at the beginning of <tt>RSFSRC/python/rsfdoc.py</tt> . This will ensure that a link to the wiki section is created in the auto-generated HTML program page in <tt>$RSFDOC</tt>.<br />
<br />
Add your program to the [[Task-centric program list]] so that it can be found by those users who do not already know they need it.<br />
<br />
===Reproducible documents===<br />
<tt>Madagascar</tt> programs are tested and illustrated by means of [[Reproducible_Documents|reproducible documents]]. See the [[Reproducible computational experiments using SCons|Guide to SCons interface for reproducible computations]] for a brief explanation of what a reproducible paper is and how to produce one.<br />
<br />
==Style guide==<br />
* Use components (macros, types, functions) from the Madagascar library to maximize component reuse and to make sure you do not reinvent the wheel. Be familiar with the [[Library Reference]].<br />
* User interface convention: if your program provides a verbosity option, use <tt>verb=n [y/n]</tt><br />
* Do not keep commented code in your program. This does not refer to writing comments about code, but to commenting out actual code. You can always use the version control system to retrieve the older version.<br />
<br />
==How to test your program==<br />
Automatic testing is the main goal for the 1.0 release, but right now the testing mechanism is semi-automatic. Testing can be done for any program that is used in a reproducible document in the <tt>RSF/book</tt> directory. To test whether the change you made in a program called, say, <tt>sfmyprog</tt> introduced any new bugs, make sure you have the latest set of stored figures from the [[Installation#RSF_reproducible_figures|figures repository]] and do the following:<br />
<br />
#<tt>cd RSF/book</tt><br />
#Run <pre>scons sfmyprog.test</pre> If the error messages are not helpful you can omit them from the console, but keep them in a file like this (sh): <pre>scons sfmyprog.test 2> sfmyprog.test.err</pre> or like this (csh): <pre>(scons sfmyprog.test > /dev/stdin) >& sfmyprog.test.err</pre><br />
#If testing fails, find the directory and figure where failure happened from the "<tt>Comparing ... and ...</tt>" statement just before the beginning of the error messages. The directory name will appear before that in a line "<tt> Testing in ...</tt>". <tt>cd</tt> to that directory. Let's say the figure that failed is called <tt>myfig.vpl</tt>. Run <pre>scons myfig.flip</pre> That will open a graphical display window that will quickly alternate between the stored figure and your figure. <br />
#* If the figures look identical, then it means the differences are due to rounding errors and other insignificant differences between platforms (work is done on improving the comparison mechanism). Load your figure into your copy of the figures repository with <pre>scons myfig.lock</pre><br />
#* If you see differences between the two figures, then it is time to debug your program.<br />
<br />
==Tips and tricks==<br />
===Backups===<br />
You may want to back up only your developer directory, not the entire Madagascar source tree. If you do not want to or do not have the permissions to change the backup scripts, you will need to make your RSF user directory a link to somewhere else. To get that to work, you need to modify your <tt>username/SConstruct</tt>. First thing in the file, define <br />
<python><br />
RSF_src_root = '/path/to/madagascar/source/root/'<br />
</python><br />
Then, replace <tt>../..</tt> throughout the SConstruct with<br />
<python><br />
os.path.join(RSF_src_root,'whatever_followed_after_dotdots')<br />
</python> .<br />
<br />
===External libraries===<br />
To link your programs to an external library, add to the <tt>env.Prepend</tt> statement in <tt>username/Sconstruct</tt><br />
the paths to its <tt>include</tt> dir, <tt>lib</tt> dir and the name of the library you are linking to.<br />
<br />
<br />
<br />
===Emacs customization===<br />
<br />
If you use [http://www.gnu.org/software/emacs/ Emacs], the following might be helpful.<br />
<br />
* Install the [http://www.emacswiki.org/cgi-bin/wiki/PythonMode python mode] (if you don't have it installed already) and put <br />
<lisp><br />
(setq auto-mode-alist<br />
(cons '("SConstruct" . python-mode) auto-mode-alist))<br />
</lisp> <br />
:in your <tt>.emacs</tt> file to enable it on <tt>SConstruct</tt> files.<br />
<br />
* Put <br />
<lisp><br />
(set-default 'compile-command "scons")<br />
</lisp> <br />
:in your <tt>.emacs</tt> file to have <tt>scons</tt> as the default compile command.<br />
<br />
* Use <br />
<lisp><br />
(add-hook 'c-mode-common-hook<br />
'(lambda () (c-set-style "linux")<br />
(c-set-offset 'case-label 4)<br />
(setq c-basic-offset 4)))<br />
</lisp> <br />
:to make sure that the identation in C files follows the previously adopted convention.</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Guide_to_madagascar_programs&diff=680Guide to madagascar programs2009-03-05T19:33:43Z<p>Jenningsjwj: /* sfgrey3 */</p>
<hr />
<div><center><font size="-1">''This page was created from the LaTeX source in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/rsf/rsf/prog.tex?view=markup book/rsf/rsf/prog.tex] using [[latex2wiki]]''</font></center><br />
<br />
This guide introduces some of the most used <tt>madagascar</tt> programs and illustrates their usage with examples.<br />
=Main programs=<br />
The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/ system/main] in the Madagascar distribution. The "main" programs perform general-purpose operations on RSF hypercubes regardless of the data dimensionality or physical dimensions.<br />
<br />
==sfadd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Add, multiply, or divide RSF datasets.<br />
|-<br />
! colspan="4" | sfadd > out.rsf scale= add= sqrt= abs= log= exp= mode= [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | The various operations, if selected, occur in the following order:<br><br>(1) Take absolute value, abs=<br>(2) Add a scalar, add=<br>(3) Take the natural logarithm, log=<br>(4) Take the square root, sqrt=<br>(5) Multiply by a scalar, scale=<br>(6) Compute the base-e exponential, exp=<br>(7) Add, multiply, or divide the data sets, mode=<br><br>sfadd operates on integer, float, or complex data, but all the input<br>and output files must be of the same data type.<br><br>An alternative to sfadd is sfmath, which is more versatile, but may be<br>less efficient.<br />
|-<br />
| ''bools '' || '''abs=''' || || If true take absolute value [nin]<br />
|-<br />
| ''floats '' || '''add=''' || || Scalar values to add to each dataset [nin]<br />
|-<br />
| ''bools '' || '''exp=''' || || If true compute exponential [nin]<br />
|-<br />
| ''bools '' || '''log=''' || || If true take logarithm [nin]<br />
|-<br />
| ''string '' || '''mode=''' || || 'a' means add (default), <br> 'p' or 'm' means multiply, <br> 'd' means divide<br />
|-<br />
| ''floats '' || '''scale=''' || || Scalar values to multiply each dataset with [nin]<br />
|-<br />
| ''bools '' || '''sqrt=''' || || If true take square root [nin]<br />
|}<br />
<br />
<tt>sfadd</tt> is useful for combining (adding, dividing, or<br />
multiplying) several datasets. What if you want to subtract two<br />
datasets? Easy. Use the <tt>scale</tt> parameter as follows:<br />
<pre><br />
bash&#36; sfadd data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfadd < data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
The same task can be accomplished with the more general <tt>sfmath</tt> program:<br />
<pre><br />
bash&#36; sfmath one=data1.rsf two=data2.rsf output='one-two' > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfmath < data1.rsf two=data2.rsf output='input-two' > diff.rsf<br />
</pre><br />
In both cases, the size and shape of <tt>data1.rsf</tt> and<br />
<tt>data2.rsf</tt> hypercubes should be the same, and a warning<br />
message is printed out if the the axis sampling parameters (such as<br />
<tt>o1</tt> or <tt>d1</tt>) in these files are different.<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/add.c?view=markup user/main/add.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
/* find number of input files */<br />
if (isatty(fileno(stdin))) { <br />
/* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Collect input files in the <tt>in</tt> array from all command-line<br />
parameters that don't contain an "<tt>=</tt>" sign. The total number<br />
of input files in <tt>nin</tt>.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) continue; <br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
/* nin = no of input files*/<br />
</c><br />
<br />
A helper function <tt>check_compat</tt> checks the compatibility of<br />
input files.<br />
<c><br />
static void <br />
check_compat (sf_datatype type /* data type */, <br />
size_t nin /* number of files */, <br />
sf_file* in /* input files [nin] */, <br />
int dim /* file dimensionality */, <br />
const int* n /* dimensions [dim] */)<br />
/* Check that the input files are compatible. <br />
Issue error for type mismatch or size mismatch.<br />
Issue warning for grid parameters mismatch. */<br />
{<br />
int ni, id;<br />
size_t i;<br />
float d, di, o, oi;<br />
char key[3];<br />
const float tol=1.e-5; /* tolerance for comparison */<br />
<br />
for (i=1; i < nin; i++) {<br />
if (sf_gettype(in[i]) != type) <br />
sf_error ("type mismatch: need %d",type);<br />
for (id=1; id <= dim; id++) {<br />
(void) snprintf(key,3,"n%d",id);<br />
if (!sf_histint(in[i],key,&ni) || ni != n[id-1])<br />
sf_error("%s mismatch: need %d",key,n[id-1]);<br />
(void) snprintf(key,3,"d%d",id);<br />
if (sf_histfloat(in[0],key,&d)) {<br />
if (!sf_histfloat(in[i],key,&di) || <br />
(fabsf(di-d) > tol*fabsf(d)))<br />
sf_warning("%s mismatch: need %g",key,d);<br />
} else {<br />
d = 1.;<br />
}<br />
(void) snprintf(key,3,"o%d",id);<br />
if (sf_histfloat(in[0],key,&o) && <br />
(!sf_histfloat(in[i],key,&oi) || <br />
(fabsf(oi-o) > tol*fabsf(d))))<br />
sf_warning("%s mismatch: need %g",key,o);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
Finally, we enter the main loop, where input data are getting read<br />
buffer by buffer and combined in the total product depending on the<br />
data type.<br />
<c><br />
for (nbuf /= sf_esize(in[0]); nsiz > 0; nsiz -= nbuf) {<br />
if (nbuf > nsiz) nbuf=nsiz;<br />
<br />
for (j=0; j < nin; j++) {<br />
collect = (bool) (j != 0);<br />
switch(type) {<br />
case SF_FLOAT:<br />
sf_floatread((float*) bufi,<br />
nbuf,<br />
in[j]); <br />
add_float(collect, <br />
nbuf,<br />
(float*) buf,<br />
(const float*) bufi, <br />
cmode, <br />
scale[j], <br />
add[j], <br />
abs_flag[j], <br />
log_flag[j], <br />
sqrt_flag[j], <br />
exp_flag[j]);<br />
break;<br />
</c><br />
<br />
The data combination program for floating point numbers is<br />
<tt>add_float</tt>. <br />
<c><br />
static void add_float (bool collect, /* if collect */<br />
size_t nbuf, /* buffer size */<br />
float* buf, /* output [nbuf] */<br />
const float* bufi, /* input [nbuf] */ <br />
char cmode, /* operation */<br />
float scale, /* scale factor */<br />
float add, /* add factor */<br />
bool abs_flag, /* if abs */<br />
bool log_flag, /* if log */<br />
bool sqrt_flag, /* if sqrt */<br />
bool exp_flag /* if exp */)<br />
/* Add floating point numbers */<br />
{<br />
size_t j;<br />
float f;<br />
<br />
for (j=0; j < nbuf; j++) {<br />
f = bufi[j];<br />
if (abs_flag) f = fabsf(f);<br />
f += add;<br />
if (log_flag) f = logf(f);<br />
if (sqrt_flag) f = sqrtf(f);<br />
if (1. != scale) f *= scale;<br />
if (exp_flag) f = expf(f);<br />
if (collect) {<br />
switch (cmode) {<br />
case 'p': /* product */<br />
case 'm': /* multiply */<br />
buf[j] *= f;<br />
break;<br />
case 'd': /* delete */<br />
if (f != 0.) buf[j] /= f;<br />
break;<br />
default: /* add */<br />
buf[j] += f;<br />
break;<br />
}<br />
} else {<br />
buf[j] = f;<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display dataset attributes.<br />
|-<br />
! colspan="4" | sfattr < in.rsf want=<br />
|-<br />
| colspan="4" | <br>Sample output from "sfspike n1=100 | sfbandpass fhi=60 | sfattr"<br>******************************************* <br>rms = 0.992354 <br>mean value = 0.987576 <br>2-norm value = 9.92354 <br>variance = 0.00955481 <br>standard deviation = 0.0977487 <br>maximum value = 1.12735 at 97 <br>minimum value = 0.151392 at 100 <br>number of nonzero samples = 100 <br>total number of samples = 100 <br>******************************************* <br><br>rms = sqrt[ sum(data^2) / n ]<br>mean = sum(data) / n<br>norm = sum(abs(data)^lval)^(1/lval)<br>variance = [ sum(data^2) - n*mean^2 ] / [ n-1 ]<br>standard deviation = sqrt [ variance ]<br />
|-<br />
| ''int '' || '''lval=2''' || || norm option, lval is a non-negative integer, computes the vector lval-norm<br />
|-<br />
| ''string '' || '''want=''' || || 'all'(default),'rms','mean','norm','var','std','max','min','nonzero','samples','short' <br />
:want= 'rms' displays the root mean square<br />
:want= 'norm' displays the square norm, otherwise specified by lval.<br />
:want= 'var' displays the variance<br />
:want= 'std' displays the standard deviation<br />
:want= 'nonzero' displays number of nonzero samples<br />
:want= 'samples' displays total number of samples<br />
:want= 'short' displays a short one-line version<br />
|}<br />
<br />
<br />
<tt>sfattr</tt> is a useful diagnostic program. It reports certain<br />
statistical values for an RSF dataset: RMS (root-mean-square)<br />
amplitude, mean value, vector norm value, variance, standard deviation,<br />
maximum and minimum values, number of nonzero samples, and the total<br />
number of samples.<br />
If we denote data values as <math>d_i</math> for <math>i=0,1,2,\ldots,n</math>, then the RMS<br />
value is <math>\sqrt{\frac{1}{n}\,\sum\limits_{i=0}^n d_i^2}</math>, the mean<br />
value is <math>\frac{1}{n}\,\sum\limits_{i=0}^n d_i</math>, the <math>L_2</math>-norm value<br />
is <math>\sqrt{\sum\limits_{i=0}^n d_i^2}</math>, the variance is<br />
<math>\frac{1}{n-1}\,\left[\sum\limits_{i=0}^n d_i^2 - \frac{1}{n}\left(\sum\limits_{i=0}^n d_i\right)^2\right]</math>, and the standard<br />
deviation is the square root of the variance. Using <tt>sfattr</tt><br />
is a quick way to see the distribution of data values and check it for<br />
anomalies.<br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/attr.c?view=markup user/main/attr.c]====<br />
<br />
Computations start by finding the input data (<tt>in</tt>) size<br />
(<tt>nsiz</tt>) and dimensions (<tt>dim</tt>).<br />
<c><br />
dim = (size_t) sf_filedims (in,n);<br />
for (nsiz=1, i=0; i < dim; i++) {<br />
nsiz *= n[i];<br />
}<br />
</c><br />
<br />
<br />
In the main loop, we read the input data buffer by buffer.<br />
<c><br />
for (nleft=nsiz; nleft > 0; nleft -= nbuf) {<br />
nbuf = (bufsiz < nleft)? bufsiz: nleft;<br />
switch (type) {<br />
case SF_FLOAT: <br />
sf_floatread((float*) buf,nbuf,in);<br />
break;<br />
case SF_INT:<br />
sf_intread((int*) buf,nbuf,in);<br />
break;<br />
case SF_COMPLEX:<br />
sf_complexread((sf_complex*) buf,nbuf,in);<br />
break;<br />
case SF_UCHAR:<br />
sf_ucharread((unsigned char*) buf,nbuf,in);<br />
break;<br />
case SF_CHAR:<br />
default:<br />
sf_charread(buf,nbuf,in);<br />
break;<br />
}<br />
</c><br />
<br />
<br />
The data attributes are accumulated in corresponding double-precision<br />
variables. <br />
<c><br />
fsum += f;<br />
fsqr += f*f;<br />
</c><br />
<br />
<br />
Finally, the attributes are reduced and printed out.<br />
<c><br />
fmean = fsum/nsiz;<br />
if (lval==2) fnorm = sqrt(fsqr);<br />
else if (lval==0) fnorm = nsiz-nzero;<br />
else fnorm = pow(flval,1./lval);<br />
frms = sqrt(fsqr/nsiz);<br />
if (nsiz > 1) fvar = (fsqr-nsiz*fmean*fmean)/(nsiz-1);<br />
else fvar = 0.0;<br />
fstd = sqrt(fvar);<br />
</c><br />
<br />
<c><br />
if(NULL==want || 0==strcmp(want,"rms"))<br />
printf("rms = %g \n",(float) frms);<br />
if(NULL==want || 0==strcmp(want,"mean"))<br />
printf("mean value = %g \n",(float) fmean);<br />
if(NULL==want || 0==strcmp(want,"norm"))<br />
printf("%d-norm value = %g \n",lval,(float) fnorm);<br />
if(NULL==want || 0==strcmp(want,"var"))<br />
printf("variance = %g \n",(float) fvar);<br />
if(NULL==want || 0==strcmp(want,"std"))<br />
printf("standard deviation = %g \n",(float) fstd);<br />
</c><br />
<br />
==sfcat==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Concatenate datasets. <br />
|-<br />
! colspan="4" | sfcat > out.rsf space= axis=3 nspace=(int) (ni/(20*nin) + 1) [<file0.rsf] file1.rsf file2.rsf ... <br />
|-<br />
| colspan="4" | sfmerge inserts additional space between merged data.<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis being merged<br />
|-<br />
| ''int '' || '''nspace=(int) (ni/(20*nin) + 1)''' || || if space=y, number of traces to insert<br />
|-<br />
| ''bool '' || '''space=''' || [y/n] || Insert additional space.<br />
:y is default for sfmerge, n is default for sfcat<br />
|}<br />
<br />
<br />
<tt>sfcat</tt> and <tt>sfmerge</tt> concatenate two or more files<br />
together along a particular axis. It is the same program, only<br />
<tt>sfcat</tt> has the default <tt>space=n</tt> and <tt>sfmerge</tt><br />
has the default <tt>space=y</tt>.<br />
Example of <tt>sfcat</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcat one.rsf one.rsf axis=1 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=4 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
12 elements 48 bytes<br />
</pre><br />
Example of <tt>sfmerge</tt>:<br />
<pre><br />
bash$ sfmerge one.rsf one.rsf axis=2 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=7 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
14 elements 56 bytes<br />
</pre><br />
In this case, an extra empty trace is inserted between the two merged files.<br />
The axes that are not being merged are checked for consistency:<br />
<pre><br />
bash$ sfcat one.rsf two.rsf > three.rsf<br />
sfcat: n2 mismatch: need 3<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cat.c?view=markup user/main/cat.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
in = (sf_file*) sf_alloc ((size_t) argc,sizeof(sf_file));<br />
<br />
if (!sf_stdin()) { /* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Everything on the command line that does not contain a "=" sign is<br />
treated as a file name, and the corresponding file object is added to the list.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) <br />
continue; /* not a file */<br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
</c><br />
<br />
As explained above, if the <tt>space=</tt> parameter is not set, it is<br />
inferred from the program name: <tt>sfmerge</tt> corresponds to<br />
<tt>space=y</tt> and <tt>sfcat</tt> corresponds to <tt>space=n</tt>.<br />
<c><br />
if (!sf_getbool("space",&space)) {<br />
/* Insert additional space.<br />
y is default for sfmerge, n is default for sfcat */<br />
prog = sf_getprog();<br />
if (NULL != strstr (prog, "merge")) {<br />
space = true;<br />
} else if (NULL != strstr (prog, "cat")) {<br />
space = false;<br />
} else {<br />
sf_warning("%s is neither merge nor cat,"<br />
" assume merge",prog);<br />
space = true;<br />
}<br />
}<br />
</c><br />
<br />
Find the axis for the merging (from the command line <tt>axis=</tt><br />
argument) and figure out two sizes: <tt>n1</tt> for everything after<br />
the axis and <tt>n2</tt> for everything before the axis.<br />
<c><br />
n1=1;<br />
n2=1;<br />
for (i=1; i <= dim; i++) {<br />
if (i < axis) n1 *= n[i-1];<br />
else if (i > axis) n2 *= n[i-1];<br />
}<br />
</c><br />
<br />
In the output, the selected axis will get extended.<br />
<c><br />
/* figure out the length of extended axis */<br />
ni = 0;<br />
for (j=0; j < nin; j++) {<br />
ni += naxis[j];<br />
}<br />
<br />
if (space) {<br />
if (!sf_getint("nspace",&nspace)) <br />
nspace = (int) (ni/(20*nin) + 1);<br />
/* if space=y, number of traces to insert */ <br />
ni += nspace*(nin-1);<br />
} <br />
<br />
(void) snprintf(key,3,"n%d",axis);<br />
sf_putint(out,key,(int) ni);<br />
</c><br />
<br />
The rest is simple: loop through the datasets reading and writing the<br />
data in buffer-size chunks and adding extra empty chunks if<br />
<tt>space=y</tt>.<br />
<c><br />
for (i2=0; i2 < n2; i2++) {<br />
for (j=0; j < nin; j++) {<br />
for (ni = n1*naxis[j]*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charread (buf,nbuf,in[j]);<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
if (!space || j == nin-1) continue;<br />
/* Add spaces */<br />
memset(buf,0,BUFSIZ);<br />
for (ni = n1*nspace*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfcmplx==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a complex dataset from its real and imaginary parts.<br />
|-<br />
! colspan="4" | sfcmplx > cmplx.rsf real.rsf imag.rsf<br />
|-<br />
| colspan="4" | There has to be only two input files specified and no additional parameters.<br />
|}<br />
<br />
<br />
<tt>sfcmplx</tt> simply creates a complex dataset from its real and<br />
imaginary parts. The reverse operation can be accomplished with<br />
<tt>sfreal</tt> and <tt>sfimag</tt>.<br />
Example of <tt>sfcmplx</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcmplx one.rsf one.rsf > cmplx.rsf<br />
bash$ sfin cmplx.rsf<br />
cmplx.rsf:<br />
in="/tmp/cmplx.rsf@"<br />
esize=8 type=complex form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 48 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cmplx.c?view=markup user/main/cmplx.c]====<br />
The program flow is simple. First, get the names of the input files.<br />
<c><br />
/* the first two non-parameters are real and imaginary files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == real) {<br />
real = sf_input (argv[i]);<br />
} else {<br />
imag = sf_input (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == imag) {<br />
if (NULL == real) sf_error ("not enough input");<br />
/* if only one input, real is in stdin */<br />
imag = real;<br />
real = sf_input("in");<br />
}<br />
</c><br />
<br />
The main part of the program reads the real and imaginary parts buffer by buffer and assembles and writes out the complex input. <br />
<c><br />
for (nleft= (size_t) (rsize*resize); nleft > 0; nleft -= nbuf) {<br />
nbuf = (BUFSIZ < nleft)? BUFSIZ: nleft;<br />
sf_charread(rbuf,nbuf,real);<br />
sf_charread(ibuf,nbuf,imag);<br />
for (i=0; i < nbuf; i += resize) {<br />
memcpy(cbuf+2*i, rbuf+i,(size_t) resize);<br />
memcpy(cbuf+2*i+resize,ibuf+i,(size_t) resize);<br />
}<br />
sf_charwrite(cbuf,2*nbuf,cmplx);<br />
}<br />
</c><br />
<br />
==sfconjgrad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic conjugate-gradient solver for linear inversion <br />
|-<br />
! colspan="4" | sfconjgrad < dat.rsf mod=mod.rsf > to.rsf < from.rsf > out.rsf niter=1<br />
|-<br />
| ''int '' || '''niter=1''' || || number of iterations<br />
|}<br />
<br />
<br />
<tt>sfconjgrad</tt> is a generic program for least-squares linear<br />
inversion with the conjugate-gradient method. Suppose you have an<br />
executable program <tt><prog></tt> that takes an RSF file from the<br />
standard input and produces an RSF file in the standard output. It may<br />
take any number of additional parameters but one of them must be<br />
<tt>adj=</tt> that sets the forward (<tt>adj=0</tt>) or adjoint<br />
(<tt>adj=1</tt>) operations. The program <tt><prog></tt> is typically<br />
an RSF program but it could be anything (a script, a multiprocessor<br />
MPI program, etc.) as long as it implements a linear operator<br />
<math>\mathbf{L}</math> and its adjoint. There are no restrictions on the data<br />
size or shape. You can easily test the adjointness with<br />
<tt>sfdottest</tt>. The <tt>sfconjgrad</tt> program searches for a<br />
vector <math>\mathbf{m}</math> that minimizes the least-square misfit <br />
<math>\|\mathbf{d - L\,m}\|^2</math> for the given input data vector <math>\mathbf{d}</math>.<br />
Here is an example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
The <tt>sfdottest</tt> program can perform the dot product test to<br />
check that the adjoint mode works correctly.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=5.28394<br />
sfdottest: L'[d]*m=5.28394<br />
</pre><br />
Your numbers may be different because <tt>sfdottest</tt> generates new<br />
random input on each run.<br />
Next, let us make some random data with <tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfnoise seed=2005 rep=y < vec.rsf > dat.rsf<br />
</pre><br />
and try to invert the filtering operation using <tt>sfconjgrad</tt>:<br />
<pre><br />
bash$ sfconjgrad sfhelicon filt=flt.rsf lag=lag.rsf \<br />
mod=vec.rsf < dat.rsf > mod.rsf niter=10<br />
sfconjgrad: iter 1 of 10<br />
sfconjgrad: grad=3253.65<br />
sfconjgrad: iter 2 of 10<br />
sfconjgrad: grad=289.421<br />
sfconjgrad: iter 3 of 10<br />
sfconjgrad: grad=92.3481<br />
sfconjgrad: iter 4 of 10<br />
sfconjgrad: grad=36.9417<br />
sfconjgrad: iter 5 of 10<br />
sfconjgrad: grad=18.7228<br />
sfconjgrad: iter 6 of 10<br />
sfconjgrad: grad=11.1794<br />
sfconjgrad: iter 7 of 10<br />
sfconjgrad: grad=7.26941<br />
sfconjgrad: iter 8 of 10<br />
sfconjgrad: grad=5.15945<br />
sfconjgrad: iter 9 of 10<br />
sfconjgrad: grad=4.23055<br />
sfconjgrad: iter 10 of 10<br />
sfconjgrad: grad=3.57495<br />
</pre><br />
The output shows that, in 10 iterations, the norm of the gradient vector decreases by almost 1000. <br />
We can check the residual misfit before<br />
<pre><br />
bash$ < dat.rsf sfattr want=norm<br />
norm value = 49.7801<br />
</pre><br />
and after<br />
<pre><br />
bash$ sfhelicon filt=flt.rsf lag=lag.rsf < mod.rsf | \<br />
sfadd scale=1,-1 dat.rsf | sfattr want=norm<br />
norm value = 5.73563<br />
</pre><br />
In 10 iterations, the misfit decreased by an order of magnitude. The<br />
result can be improved by running the program for more iterations.<br />
<br />
==sfcp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Copy or move a dataset.<br />
|-<br />
! colspan="4" | sfcp in.rsf out.rsf<br />
|-<br />
| colspan="4" | sfcp - copy, sfmv - move.<br>Mimics standard Unix commands.<br />
|}<br />
<br />
<br />
The <tt>sfcp</tt> and <tt>sfmv</tt> command imitate the Unix<br />
<tt>cp</tt> and <tt>mv</tt> commands and serve for copying and moving<br />
RSF files. Example:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcp one.rsf two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
</pre><br />
<br />
==sfcut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of the dataset. <br />
|-<br />
! colspan="4" | sfcut < in.rsf > out.rsf verb=n [j1=1 j2=1 ... f1=0 f2=0 ... n1=n1 n2=n2 ... max1= max2= ... min1= min2= ...]<br />
|-<br />
| colspan="4" | jN defines the jump in N-th dimension<br>fN is the window start<br>nN is the window size<br>minN and maxN is the maximum and minimum in N-th dimension<br><br>Reverse of window. <br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
The <tt>sfcut</tt> command is related to <tt>sfwindow</tt> and has the same<br />
set of arguments only instead of extracting the selected window, it fills it<br />
with zeroes. The size of the input data is preserved. <br />
Examples:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > in.rsf<br />
bash$ < in.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < in.rsf sfcut n1=2 f1=1 n2=3 f2=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 0 0 1 1<br />
15: 1 0 0 1 1<br />
20: 1 0 0 1 1<br />
bash$ < in.rsf sfcut j1=2 | sfdisfil<br />
0: 0 1 0 1 0<br />
5: 0 1 0 1 0<br />
10: 0 1 0 1 0<br />
15: 0 1 0 1 0<br />
20: 0 1 0 1 0<br />
</pre><br />
<br />
==sfdd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert between different formats. <br />
|-<br />
! colspan="4" | sfdd < in.rsf > out.rsf line=8 form= type= format=<br />
|-<br />
| ''string '' || '''form=''' || || ascii, native, xdr<br />
|-<br />
| ''string '' || '''format=''' || || Element format (for conversion to ASCII)<br />
|-<br />
| ''int '' || '''line=8''' || || Number of numbers per line (for conversion to ASCII)<br />
|-<br />
| ''string '' || '''type=''' || || int, float, complex<br />
|}<br />
<br />
<br />
The <tt>sfdd</tt> program is used to change either the form (<tt>ascii</tt>,<br />
<tt>xdr</tt>, <tt>native</tt>) or the type (<tt>complex</tt>, <tt>float</tt>,<br />
<tt>int</tt>, <tt>char</tt>) of the input dataset. <br />
In the example below, we create a plain text (ASCII) file with numbers and<br />
then use <tt>sfdd</tt> to generate an RSF file in <tt>xdr</tt> form with<br />
<tt>complex</tt> numbers. <br />
<pre><br />
bash$ cat test.txt<br />
1 2 3 4 5 6<br />
bash$ echo n1=6 data_format=ascii_int in=test.txt > test.rsf<br />
bash$ sfin test.rsf<br />
test.rsf:<br />
in="test.txt"<br />
esize=0 type=int form=ascii<br />
n1=6 d1=? o1=?<br />
6 elements<br />
bash$ sfdd < test.rsf form=xdr type=complex > test2.rsf<br />
bash$ sfin test2.rsf<br />
test2.rsf:<br />
in="/tmp/test2.rsf@"<br />
esize=8 type=complex form=xdr<br />
n1=3 d1=? o1=?<br />
3 elements 24 bytes<br />
bash$ sfdisfil < test2.rsf<br />
0: 1, 2i 3, 4i 5, 6i<br />
</pre><br />
To learn more about the RSF data format, consult the [[Format| guide to RSF format]].<br />
<br />
==sfdisfil==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Print out data values.<br />
|-<br />
! colspan="4" | sfdisfil < in.rsf number=y col=0 format= header= trailer=<br />
|-<br />
| colspan="4" | <br>Alternatively, use sfdd and convert to ASCII form.<br />
|-<br />
| ''int '' || '''col=0''' || || Number of columns.<br />
:The default depends on the data type:<br />
:10 for int and char,<br />
:5 for float,<br />
:3 for complex<br />
|-<br />
| ''string '' || '''format=''' || || Format for numbers (printf-style).<br />
:The default depends on the data type:<br> "%4d " for int and char,<br> "%13.4g" for float,<br> "%10.4g,%10.4gi" for complex<br />
|-<br />
| ''string '' || '''header=''' || || Optional header string to output before data<br />
|-<br />
| ''bool '' || '''number=y''' || [y/n] || If number the elements<br />
|-<br />
| ''string '' || '''trailer=''' || || Optional trailer string to output after data<br />
|}<br />
<br />
<br />
The <tt>sfdisfil</tt> program simply dumps the data contents to the standard<br />
output in a text form. It is used mostly for debugging purposes to quickly<br />
examine RSF files. Here is an example:<br />
<pre><br />
bash$ sfmath o1=0 d1=2 n1=12 output=x1 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
10: 20 22<br />
</pre><br />
The output format is easily configurable.<br />
<pre><br />
bash$ < test.rsf sfdisfil col=6 number=n format="<br />
0.0 2.0 4.0 6.0 8.0 10.0<br />
12.0 14.0 16.0 18.0 20.0 22.0<br />
</pre><br />
Along with <tt>sfdd</tt>, <tt>sfdisfil</tt> provides a simple way to convert<br />
RSF data to an ASCII form.<br />
<br />
==sfdottest==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic dot-product test for linear operators with adjoints <br />
|-<br />
! colspan="4" | sfdottest mod=mod.rsf dat=dat.rsf > pip.rsf<br />
|}<br />
<br />
<br />
<tt>sfdottest</tt> is a generic dot-product test program for testing<br />
linear operators. Suppose there is an executable program<br />
<tt><prog></tt> that takes an RSF file from the standard input and<br />
produces an RSF file in the standard output. It may take any number of<br />
additional parameters but one of them must be <tt>adj=</tt> that sets<br />
the forward (<tt>adj=0</tt>) or adjoint (<tt>adj=1</tt>) operations.<br />
The program <tt><prog></tt> is typically an RSF program but it could<br />
be anything (a script, a multiprocessor MPI program, etc.) as long as<br />
it implements a linear operator <math>\mathbf{L}</math> and its adjoint<br />
<math>\mathbf{L}^T</math>. The <tt>sfdottest</tt> program is testing the equality<br />
<center><math><br />
d^T\,L\,m = m^T\,L^T\,d<br />
</math></center><br />
by using random vectors <math>\mathbf{m}</math> and <math>\mathbf{d}</math>. You can invoke it with<br />
<pre><br />
bash$ sfdottest <prog> [optional aruments] mod=mod.rsf dat=dat.rsf<br />
</pre><br />
where <tt>mod.rsf</tt> and <tt>dat.rsf</tt> are RSF files that<br />
represent vectors from the model and data spaces. <tt>sfdottest</tt><br />
does not create any temporary files and does not have any restrictive<br />
limitations on the size of the vectors.<br />
Here is an example. We first setup a vector with 100 elements using<br />
<tt>sfspike</tt> and then run <tt>sfdottest</tt> to test the<br />
<tt>sfcausint</tt> program. <tt>sfcausint</tt> implements a linear<br />
operator of causal integration and its adjoint, the anti-causal<br />
integration.<br />
<pre><br />
bash$ sfspike n1=100 > vec.rsf<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1410.2<br />
sfdottest: L'[d]*m=1410.2<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1165.87<br />
sfdottest: L'[d]*m=1165.87<br />
</pre><br />
The numbers are different on subsequent runs because of changing<br />
seed in the random number generator.<br />
Here is a somewhat more complicated example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
Now the <tt>sfdottest</tt> program can perform the dot product test.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=8.97375<br />
sfdottest: L'[d]*m=8.97375<br />
</pre><br />
Here is the same program tested in the inverse filtering mode:<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf inv=y<br />
sfdottest: L[m]*d=15.0222<br />
sfdottest: L'[d]*m=15.0222<br />
</pre><br />
<br />
==sfget==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Output parameters from the header.<br />
|-<br />
! colspan="4" | sfget < in.rsf parform=y par1 par2 ...<br />
|-<br />
| ''bool '' || '''parform=y''' || [y/n] || If y, print out parameter=value. If n, print out value.<br />
|}<br />
<br />
<br />
The <tt>sfget</tt> program extracts a parameter value from an RSF file. It is<br />
useful mostly for scripting. Here is, for example, a quick calculation of the<br />
maximum value on the first axis in an RSF dataset (the output of<br />
<tt>sfspike</tt>) using the standard Unix <tt>bc</tt> calculator.<br />
<pre><br />
bash$ ( sfspike n1=100 | sfget n1 d1 o1; echo "o1+(n1-1)*d1" ) | bc<br />
.396<br />
</pre><br />
See also <tt>sfput</tt>.<br />
<br />
<br />
<br />
==sfheadercut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheadercut mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array of size n2.<br />
|}<br />
<br />
<br />
<tt>sfheadercut</tt> is close to <tt>sfheaderwindow</tt> but instead<br />
of windowing the dataset, it fills the traces specified by the header<br />
mask with zeroes. The size of the input data is preserved.<br />
Here is an example of using <tt>sfheaderwindow</tt> for <br />
zeroing every other trace in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a mask with alternating ones and zeros using<br />
<tt>sfinterleave</tt>.<br />
<pre><br />
bash$ sfspike n1=5 mag=1 | sfdd type=int > ones.rsf<br />
bash$ sfspike n1=5 mag=0 | sfdd type=int > zeros.rsf<br />
bash$ sfinterleave axis=1 ones.rsf zeros.rsf > mask.rsf<br />
bash$ sfdisfil < mask.rsf<br />
0: 1 0 1 0 1 0 1 0 1 0<br />
</pre><br />
Finally, <tt>sfheadercut</tt> zeros the input traces.<br />
<pre><br />
bash$ sfheadercut < input.rsf mask=mask.rsf > output.rsf<br />
bash$ sfdisfil < output.rsf <br />
0: 1 1 1 1 1<br />
5: 0 0 0 0 0<br />
10: 3 3 3 3 3<br />
15: 0 0 0 0 0<br />
20: 5 5 5 5 5<br />
25: 0 0 0 0 0<br />
30: 7 7 7 7 7<br />
35: 0 0 0 0 0<br />
40: 9 9 9 9 9<br />
45: 0 0 0 0 0<br />
</pre><br />
<br />
<br />
<br />
==sfheadersort==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Sort a dataset according to a header key. <br />
|-<br />
! colspan="4" | sfheadersort < in.rsf > out.rsf head=<br />
|-<br />
| ''string '' || '''head=''' || || header file<br />
|}<br />
<br />
<br />
<tt>sfheadersort</tt> is used to sort traces in the input file<br />
according to trace header information. <br />
Here is an example of using<br />
<tt>sfheadersort</tt> for randomly shuffling traces in the input<br />
file. First, let us create an input file with seven traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=7 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7 <br />
</pre><br />
Next, we can create a random file with seven header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=7 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: 0.05256 -0.2879 0.1487 0.4097 0.1548<br />
5: 0.4501 0.2836<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally, we<br />
apply <tt>sfheadersort</tt> to shuffle the input traces.<br />
<pre><br />
bash$ < input.rsf sfheadersort head=random.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 1 1 1 1 1<br />
10: 3 3 3 3 3<br />
15: 5 5 5 5 5<br />
20: 7 7 7 7 7<br />
25: 4 4 4 4 4<br />
30: 6 6 6 6 6<br />
</pre><br />
As expected, the order of traces in the output file corresponds to the<br />
order of values in the header. Thanks to the separation between<br />
headers and data, the operation of <tt>sfheadersort</tt> is optimally<br />
efficient. It first sorts the headers and only then accesses the data,<br />
reading each data trace only once.<br />
<br />
==sfheaderwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheaderwindow mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array os size n2, windowed is n1xm2,<br>where m2 is the number of nonzero elements in mask.<br />
|}<br />
<br />
<br />
<tt>sfheaderwindow</tt> is used to window traces in the input file<br />
according to trace header information. <br />
Here is an example of using <tt>sfheaderwindow</tt> for randomly<br />
selecting part of the traces in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a random file with ten header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=10 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: -0.005768 0.02258 -0.04331 -0.4129 -0.3909<br />
5: -0.03582 0.4595 -0.3326 0.498 -0.3517<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally,<br />
we apply <tt>sfheaderwindow</tt> to window the input traces selecting<br />
only those for which the header is greater than zero.<br />
<pre><br />
bash$ < random.rsf sfmask min=0 > mask.rsf<br />
bash$ < mask.rsf sfdisfil<br />
0: 0 1 0 0 0 0 1 0 1 0<br />
bash$ < input.rsf sfheaderwindow mask=mask.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 7 7 7 7 7<br />
10: 9 9 9 9 9<br />
</pre><br />
In this case, only three traces are selected for the output. Thanks to<br />
the separation between headers and data, the operation of<br />
<tt>sfheaderwindow</tt> is optimally efficient. <br />
<br />
==sfin==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display basic information about RSF files.<br />
|-<br />
! colspan="4" | sfin info=y check=2. trail=y file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | n1,n2,... are data dimensions<br>o1,o2,... are axis origins<br>d1,d2,... are axis sampling intervals<br>label1,label2,... are axis labels<br>unit1,unit2,... are axis units<br />
|-<br />
| ''float '' || '''check=2.''' || || Portion of the data (in Mb) to check for zero values.<br />
|-<br />
| ''bool '' || '''info=y''' || [y/n] || If n, only display the name of the data file.<br />
|-<br />
| ''bool '' || '''trail=y''' || [y/n] || If n, skip trailing dimensions of one<br />
|}<br />
<br />
<br />
<tt>sfin</tt> is one of the most useful programs for operating with<br />
RSF files. It produces quick information on the file hypercube<br />
dimensions and checks the consistency of the associated data file.<br />
Here is an example. Let us create an RSF file and examine it with <tt>sfin</tt>.<br />
<pre><br />
bash$ sfspike n1=100 n2=20 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=100 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
2000 elements 8000 bytes<br />
</pre><br />
<tt>sfin</tt> reports the following information:<br />
<br />
*location of the data file (<tt>/tmp/spike.rsf\@</tt>) <br />
*element size (4 bytes) <br />
*element type (floating point) <br />
*element form (native) <br />
*hypercube dimensions (100 by 20) <br />
*axes scale (0.004 and 0.1) <br />
*axes origin (0 and 0) <br />
*axes labels <br />
*axes units <br />
*total number of elements <br />
*total number of bytes in the data file <br />
Suppose that the file got corrupted by a buggy program and reports<br />
incorrect dimensions. The <tt>sfin</tt> program should be able to<br />
catch the discrepancy.<br />
<pre><br />
bash$ echo n2=100 >> spike.rsf<br />
bash$ sfin spike.rsf > /dev/null<br />
sfin: Actually 8000 bytes, 20% of expected.<br />
</pre><br />
<tt>sfin</tt> also checks the first records in the file for zeros. <br />
<pre><br />
bash$ sfspike n1=100 n2=100 k2=99 > spike2.rsf<br />
bash$ sfin spike2.rsf >/dev/null<br />
sfin: The first 32768 bytes are all zeros<br />
</pre><br />
The number of bytes to check is adjustable<br />
<pre><br />
bash$ sfin spike2.rsf check=0.01 >/dev/null<br />
sfin: The first 16384 bytes are all zeros<br />
</pre><br />
You can also output only the location of the data file. This is<br />
sometimes handy in scripts.<br />
<pre><br />
bash$ sfin spike.rsf spike2.rsf info=n<br />
/tmp/spike.rsf@ /tmp/spike2.rsf@<br />
</pre><br />
An alternative is to use <tt>sfget</tt>, as follows:<br />
<pre><br />
bash$ sfget parform=n in < spike.rsf<br />
/tmp/spike.rsf@<br />
</pre><br />
<br />
==sfinterleave==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Combine several datasets by interleaving.<br />
|-<br />
! colspan="4" | sfinterleave > out.rsf axis=3 [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis for interleaving<br />
|}<br />
<br />
<br />
<tt>sfinterleave</tt> combines two or more datasets by interleaving them on one<br />
of the axes. Here is a quick example:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ sfscale < one.rsf dscale=2 > two.rsf<br />
bash$ sfdisfil < two.rsf<br />
0: 2 2 2 2 2<br />
5: 2 2 2 2 2<br />
10: 2 2 2 2 2<br />
15: 2 2 2 2 2<br />
20: 2 2 2 2 2<br />
bash$ sfinterleave one.rsf two.rsf axis=1 | sfdisfil<br />
0: 1 2 1 2 1<br />
5: 2 1 2 1 2<br />
10: 1 2 1 2 1<br />
15: 2 1 2 1 2<br />
20: 1 2 1 2 1<br />
25: 2 1 2 1 2<br />
30: 1 2 1 2 1<br />
35: 2 1 2 1 2<br />
40: 1 2 1 2 1<br />
45: 2 1 2 1 2<br />
bash$ sfinterleave < one.rsf two.rsf axis=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 1 1 1 1 1<br />
15: 2 2 2 2 2<br />
20: 1 1 1 1 1<br />
25: 2 2 2 2 2<br />
30: 1 1 1 1 1<br />
35: 2 2 2 2 2<br />
40: 1 1 1 1 1<br />
45: 2 2 2 2 2<br />
</pre><br />
<br />
==sfmask==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a mask.<br />
|-<br />
! colspan="4" | sfmask < in.rsf > out.rsf min=-FLT_MAX max=+FLT_MAX<br />
|-<br />
| colspan="4" | <br>Mask is an integer data with ones and zeros. <br>Ones correspond to input values between min and max.<br><br>The output can be used with sfheaderwindow.<br />
|-<br />
| ''float '' || '''max=+FLT_MAX''' || || maximum header value<br />
|-<br />
| ''float '' || '''min=-FLT_MAX''' || || minimum header value<br />
|}<br />
<br />
<br />
<tt>sfmask</tt> creates an integer output of ones and zeros comparing<br />
the values of the input data to specified <tt>min=</tt> and<br />
<tt>max=</tt> parameters. It is useful for <tt>sfheaderwindow</tt> and<br />
in many other applications. Here is a quick example:<br />
<pre><br />
bash$ sfmath n1=10 output="sin(x1)" > sin.rsf<br />
bash$ < sin.rsf sfdisfil<br />
0: 0 0.8415 0.9093 0.1411 -0.7568<br />
5: -0.9589 -0.2794 0.657 0.9894 0.4121<br />
bash$ < sin.rsf sfmask min=-0.5 max=0.5 | sfdisfil<br />
0: 1 0 0 1 0 0 1 0 0 1<br />
</pre><br />
<br />
==sfmath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations on data files.<br />
|-<br />
! colspan="4" | sfmath > out.rsf type= unit= output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs, conj (for complex data).<br> <br>sfmath will work on float or complex data, but all the input and output<br>files must be of the same data type.<br><br>An alternative to sfmath is sfadd, which may be more efficient, but is<br>less versatile.<br><br>Examples:<br><br>sfmath x=file1.rsf y=file2.rsf power=file3.rsf output='sin((x+2*y)^power)' > out.rsf<br>sfmath < file1.rsf tau=file2.rsf output='exp(tau*input)' > out.rsf<br>sfmath n1=100 type=complex output="exp(I*x1)" > out.rsf<br><br>See also: sfheadermath.<br />
|-<br />
| ''string '' || '''output=''' || || Mathematical description of the output<br />
|-<br />
| ''string '' || '''type=''' || || output data type [float,complex]<br />
|-<br />
| ''string '' || '''unit=''' || || <br />
|}<br />
<br />
<tt>sfmath</tt> is a versatile program for mathematical operations<br />
with RSF files. It can operate with several input file, all of the<br />
same dimensions and data type. The data type can be real (floating<br />
point) or complex. Here is an example that demonstrates several<br />
features of <tt>sfmath</tt>.<br />
<pre><br />
bash$ sfmath n1=629 d1=0.01 o1=0 n2=40 d2=1 o2=5 \<br />
output="x2*(8+sin(6*x1+x2/10))" > rad.rsf<br />
bash$ < rad.rsf sfrtoc | sfmath output="input*exp(I*x1)" > rose.rsf<br />
bash$ < rose.rsf sfgraph title=Rose screenratio=1 wantaxis=n | xtpen<br />
</pre><br />
The first line creates a 2-D dataset that consists of 40 traces 600<br />
samples each. The values of the data are computed with the formula<br />
<font color="#cd4b19">"x2*(8+sin(6*x1+x2/10))"</font>, where <tt>x1</tt> refers to the<br />
coordinate on the first axis, and <tt>x2</tt> is the coordinate of the<br />
second axis. In the second line, we convert the data from real to<br />
complex using <tt>sfrtoc</tt> and produce a complex dataset using<br />
formula <font color="#cd4b19">"input*exp(I*x1)"</font>, where <tt>input</tt> refers to the<br />
input file. Finally, we plot the complex data as a collection of<br />
parametric curves using <tt>sfgraph</tt> and display the result using<br />
<tt>xtpen</tt>. The plot appearing on your screen should look similar<br />
to the figure.<br />
[[Image:rose.png|frame|center|This figure was created with <tt>sfmath</tt>.]]<br />
One possible alternative to the second line above is<br />
<pre><br />
bash$ < rad.rsf sfmath output=x1 > ang.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*cos(a)" > cos.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*sin(a)" > sin.rsf<br />
bash$ sfcmplx cos.rsf sin.rsf > rose.rsf<br />
</pre><br />
Here we refer to input files by names (<tt>r</tt> and <tt>a</tt>) and combine the names in a formula.<br />
<br />
==sfpad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Pad a dataset with zeros.<br />
|-<br />
! colspan="4" | sfpad < in.rsf > out.rsf [beg1= beg2= ... end1= end2=... | n1= n2 = ... | n1out= n2out= ...]<br />
|-<br />
| colspan="4" | begN specifies the number of zeros to add before the beginning of axis N.<br>endN specifies the number of zeros to add after the end of axis N.<br><br>Alternatively:<br><br>nN or nNout specify the output length of axis N, padding occurs at the end.<br>nN and nNout are equivalent.<br />
|}<br />
<br />
<br />
<tt>pad</tt> increases the dimensions of the input dataset by padding<br />
the data with zeroes. Here are some simple examples.<br />
<pre><br />
bash$ sfspike n1=5 n2=3 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
bash$ < one.rsf sfpad n2=5 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 0 0 0 0 0<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfpad beg2=2 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 0 0 0 0<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < one.rsf sfpad beg2=1 end2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfwindow n1=3 | sfpad n1=5 n2=5 beg1=1 beg2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 1 1 1 0<br />
10: 0 1 1 1 0<br />
15: 0 1 1 1 0<br />
20: 0 0 0 0 0<br />
</pre><br />
You can use <tt>sfcat</tt> to pad data with values other than zeroes.<br />
<br />
==sfput==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Input parameters into a header. <br />
|-<br />
! colspan="4" | sfput < in.rsf > out.rsf<br />
|}<br />
<br />
<br />
<tt>sfput</tt> is a very simple program. It simply appends parameters<br />
from the command line to the output RSF file. One can achieve similar<br />
results with editing by hand or with standard Unix utilities like<br />
<tt>sed</tt> and <tt>echo</tt>. <tt>sfput</tt> is sometimes more<br />
convenient because it handles input/output operations similarly to<br />
other regular RSF programs.<br />
<pre><br />
bash$ sfspike n1=10 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
10 elements 40 bytes<br />
bash$ sfput < spike.rsf d1=25 label1=Depth unit1=m > spike2.rsf<br />
bash$ sfin spike2.rsf<br />
spike2.rsf:<br />
in="/tmp/spike2.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=25 o1=0 label1="Depth" unit1="m"<br />
10 elements 40 bytes<br />
</pre><br />
<br />
==sfreal==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extract real (sfreal) or imaginary (sfimag) part of a complex dataset. <br />
|-<br />
! colspan="4" | sfreal < cmplx.rsf > real.rsf<br />
|}<br />
<br />
<br />
<tt>sfreal</tt> extracts the real part of a complex type dataset. The<br />
imaginary part can be extracted with <tt>sfimag</tt>, an the real<br />
and imaginary part can be combined together with <tt>sfcmplx</tt>.<br />
Here is a simple example. Let us first create a complex dataset <br />
with <tt>sfmath</tt><br />
<pre><br />
bash$ sfmath n1=10 type=complex output="(2+I)*x1" > cmplx.rsf<br />
bash$ fdisfil < cmplx.rsf<br />
0: 0, 0i 2, 1i 4, 2i<br />
3: 6, 3i 8, 4i 10, 5i<br />
6: 12, 6i 14, 7i 16, 8i<br />
9: 18, 9i<br />
</pre><br />
Extracting the real part with <tt>sfreal</tt>:<br />
<pre><br />
bash$ sfreal < cmplx.rsf | sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
</pre><br />
Extracting the imaginary part with <tt>sfimag</tt>:<br />
<pre><br />
bash$ sfimag < cmplx.rsf | sfdisfil<br />
0: 0 1 2 3 4<br />
5: 5 6 7 8 9<br />
</pre><br />
<br />
==sfreverse==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Reverse one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfreverse < in.rsf > out.rsf which=-1 verb=false memsize=sf_memsize() opt=<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''opt=''' || || If y, change o and d parameters on the reversed axis;<br />
:if i, don't change o and d<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|-<br />
| ''int '' || '''which=-1''' || || Which axis to reverse.<br />
:To reverse a given axis, start with 0,<br />
:add 1 to number to reverse n1 dimension,<br />
:add 2 to number to reverse n2 dimension,<br />
:add 4 to number to reverse n3 dimension, etc.<br />
:Thus, which=7 would reverse the first three dimensions,<br />
:which=5 just n1 and n3, etc.<br />
:which=0 will just pass the input on through unchanged.<br />
|}<br />
Here is an example of using <tt>sfreverse</tt>. First, let us create a<br />
2-D dataset.<br />
<pre><br />
bash$ sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Reversing the first axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 | sfdisfil<br />
0: 4 3 2 1 0<br />
5: 5 4 3 2 1<br />
10: 6 5 4 3 2<br />
</pre><br />
Reversing the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=2 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
Reversing both the first and the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=3 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
As you can see, the <tt>which=</tt> parameter controls the axes that are<br />
being reversed by encoding them into one number.<br />
When an axis is reversed, what happens with its axis origin and<br />
sampling parameters? This behavior is controlled by <tt>opt=</tt>. In<br />
our example,<br />
<pre><br />
bash$ < test.rsf sfget n1 o1 d1<br />
n1=5<br />
o1=0<br />
d1=1<br />
bash$ < test.rsf sfreverse which=1 | sfget o1 d1<br />
o1=4<br />
d1=-1<br />
</pre><br />
The default behavior (equivalent to <tt>opt=y</tt>) puts the origin<br />
<tt>o1</tt> at the end of the axis and reverses the sampling parameter<br />
<tt>d1</tt>. Using <tt>opt=n</tt> preserves the sampling but reverses<br />
the origin.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=n | sfget o1 d1<br />
o1=-4<br />
d1=1<br />
</pre><br />
Using <tt>opt=i</tt> preserves both the sampling and the origin while<br />
reversing the axis.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=i | sfget o1 d1<br />
o1=0<br />
d1=1<br />
</pre><br />
One of the three possible behaviors may be desirable depending on the<br />
application.<br />
<br />
==sfrm==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Remove RSF files together with their data.<br />
|-<br />
! colspan="4" | sfrm file1.rsf [file2.rsf ...] [-i] [-v] [-f] <br />
|-<br />
| colspan="4" | Mimics the standard Unix rm command.<br><br>See also: sfmv, sfcp.<br />
|}<br />
<br />
<tt>sfrm</tt> is a program for removing RSF files. Its arguments mimic<br />
the arguments of the standard Unix <tt>rm</tt> utility: <tt>-v</tt><br />
for verbosity, <tt>-i</tt> for interactive inquiry, <tt>-f</tt> for<br />
force removal of suspicious files. Unlike the Unix <tt>rm</tt>,<br />
<tt>sfrm</tt> removes both the RSF header files and the binary files<br />
that the headers point to. <br />
Example:<br />
<pre><br />
bash&#36; sfspike n1=10 > spike.rsf datapath=./<br />
bash&#36; sfget in < spike.rsf<br />
in=./spike.rsf@<br />
bash&#36; ls spike*<br />
spike.rsf spike.rsf@<br />
bash&#36; sfrm -v spike.rsf<br />
sfrm: sf_rm: Removing header spike.rsf<br />
sfrm: sf_rm: Removing data ./spike.rsf@<br />
bash&#36; ls spike*<br />
ls: No match.<br />
</pre><br />
==sfrotate==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Rotate a portion of one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfrotate < in.rsf > out.rsf verb=n memsize=sf_memsize() rot#=(0,0,...)<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''rot#=(0,0,...)''' || || length of #-th axis that is moved to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<tt>sfrotate</tt> modifies the input dataset by splitting it into<br />
parts and putting the parts back in a different order. Here is a quick example.<br />
<pre><br />
bash&#36; sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Rotating the first axis by putting the last two columns in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=2 | sfdisfil<br />
0: 3 4 0 1 2<br />
5: 4 5 1 2 3<br />
10: 5 6 2 3 4<br />
</pre><br />
Rotating the second axis by putting the last row in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot2=1 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 0 1 2 3 4<br />
10: 1 2 3 4 5<br />
</pre><br />
Rotating both the first and the second axis:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=3 rot2=1 | sfdisfil<br />
0: 4 5 6 2 3<br />
5: 2 3 4 0 1<br />
10: 3 4 5 1 2<br />
</pre><br />
The transformation is shown schematically in Figure~(fig:rotate).<br />
[[Image:rotate.png|frame|center|Schematic transformation of data with <tt>sfrotate</tt>.]]<br />
<br />
==sfrtoc==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert real data to complex (by adding zero imaginary part).<br />
|-<br />
! colspan="4" | sfrtoc < real.rsf > cmplx.rsf<br />
|-<br />
| colspan="4" | <br>See also: sfcmplx<br />
|}<br />
The input to <tt>sfrtoc</tt> can be any <tt>type=float</tt> dataset:<br />
<pre><br />
bash$ sfspike n1=10 n2=20 n3=30 >real.rsf<br />
bash$ sfin real.rsf<br />
real.rsf:<br />
in="/var/tmp/real.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
</pre><br />
The output dataset will have <tt>type=complex</tt>, and its binary will be twice the size of the input:<br />
<pre><br />
bash$ <real.rsf sfrtoc >complex.rsf<br />
bash$ sfin complex.rsf <br />
complex.rsf:<br />
in="/var/tmp/complex.rsf@"<br />
esize=8 type=complex form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 48000 bytes<br />
</pre><br />
<br />
==sfscale==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Scale data.<br />
|-<br />
! colspan="4" | sfscale < in.rsf > out.rsf axis=0 rscale=0. dscale=1.<br />
|-<br />
| colspan="4" | <br>To scale by a constant factor, you can also use sfmath or sfheadermath.<br />
|-<br />
| ''int '' || '''axis=0''' || || Scale by maximum in the dimensions up to this axis.<br />
|-<br />
| ''float '' || '''dscale=1.''' || || Scale by this factor (works if rscale=0)<br />
|-<br />
| ''float '' || '''rscale=0.''' || || Scale by this factor.<br />
|}<br />
<tt>sfscale</tt> scales the input dataset by a factor. Here<br />
are some simple examples. First, let us create a test dataset.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil <br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Scale every data point by 2:<br />
<pre><br />
bash&#36; < test.rsf sfscale dscale=2 | sfdisfil<br />
0: 2 4 6 8 10<br />
5: 4 8 12 16 20<br />
10: 6 12 18 24 30<br />
</pre><br />
Divide every trace by its maximum value:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=1 | sfdisfil<br />
0: 0.2 0.4 0.6 0.8 1<br />
5: 0.2 0.4 0.6 0.8 1<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
Divide by the maximum value in the whole 2-D dataset:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=2 | sfdisfil<br />
0: 0.06667 0.1333 0.2 0.2667 0.3333<br />
5: 0.1333 0.2667 0.4 0.5333 0.6667<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
The <tt>rscale=</tt> parameter is synonymous to <tt>dscale=</tt> except<br />
when it is equal to zero. With <tt>sfscale dscale=0</tt>, the dataset gets<br />
multiplied by zero. If using <tt>rscale=0</tt>, the other parameters are<br />
used to define scaling. Thus, <tt>sfscale rscale=0 axis=1</tt> is<br />
equivalent to <tt>sfscale axis=1</tt>, and <tt>sfscale rscale=0</tt><br />
is equivalent to <tt>sfscale dscale=1</tt>.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
==sfspike==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate simple data: spikes, boxes, planes, constants.<br />
|-<br />
! colspan="4" | sfspike > spike.rsf mag= nsp=1 k#=[0,...] l#=[k1,k2,...] p#=[0,...] n#= o#=(0,...) d#=(0.004,0.1,0.1,...) label#=(Time,Distance,Distance,...) unit#=[s,km,km,...] title=<br />
|-<br />
| ''float '' || '''d#=(0.004,0.1,0.1,...)''' || || sampling on #-th axis<br />
|-<br />
| ''ints '' || '''k#=[0,...]''' || || spike starting position [nsp]<br />
|-<br />
| ''ints '' || '''l#=[k1,k2,...]''' || || spike ending position [nsp]<br />
|-<br />
| ''string '' || '''label#=(Time,Distance,Distance,...)''' || || label on #-th axis<br />
|-<br />
| ''floats '' || '''mag=''' || || spike magnitudes [nsp]<br />
|-<br />
| ''int '' || '''n#=''' || || dimension of #-th axis<br />
|-<br />
| ''int '' || '''nsp=1''' || || Number of spikes<br />
|-<br />
| ''float '' || '''o#=(0,...)''' || || origin on #-th axis<br />
|-<br />
| ''floats '' || '''p#=[0,...]''' || || spike inclination (in samples) [nsp]<br />
|-<br />
| ''string '' || '''title=''' || || title for plots<br />
|-<br />
| ''string '' || '''unit#=[s,km,km,...]''' || || unit on #-th axis<br />
|}<br />
This is the program for creating a RSF hypercube out of nothing. Calling <tt>sfspike</tt> without specifying the k# or l# parameters will result in a volume filled with values specified by <tt>mag</tt>. To get a file full of 1's, just give <tt>sfspike</tt> the axis values that running <tt>sfin</tt> on your desired output would produce. I.e. if you run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" > out.rsf<br />
</pre><br />
you will obtain the following file:<br />
<pre><br />
bash$ sfin out.rsf<br />
out.rsf:<br />
in="/var/tmp/out.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
300 elements 1200 bytes<br />
</pre><br />
To create a "flat reflector" in the file above, run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5> out2.rsf<br />
</pre><br />
Notice that the values for <tt>k</tt> and <tt>l</tt> are in samples, not in the physical units of the respective axes. The result can be visualised with <br />
<pre><br />
< out2.rsf sfgrey pclip=100 wantscalebar=y title="Illustration of k,l parameters" | xtpen<br />
</pre><br />
which produces the following plot:<br />
<br />
[[Image:sfspike_fig1.png]]<br />
<br />
The <tt>p</tt> parameters can be used to create slanted lines/planes. Specifying <tt>p2=1</tt> means that for each lateral step, the spike will be shifted down with 1 sample. Below is the command and the corresponding graphical output it creates:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=1 |\<br />
sfgrey pclip=100 wantscalebar=y title="Effect of p2=1" | xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig2.png]]<br />
<br />
Sfspike also supports negative and non-integer p values:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=-0.15 |\<br />
sfgrey pclip=100 wantscalebar=y allpos=y color=h title="Effect of p2=-0.15" |xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig3.png]]<br />
<br />
When <tt>nsp</tt> is greater than the number of values for <tt>k</tt> and <tt>l</tt> parameters, the extra spikes will be piled on top of the last one, increasing its amplitude. Look at the amplitude of the last event in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=3 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
and in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=5 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
(pictures coming soon). This feature can easily cause a bug when the number of events is large and they have not been properly counted, or when a new spike was added on a list but <tt>nsp</tt> was not updated.<br />
<br />
==sfspray==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extend a dataset by duplicating in the specified axis dimension.<br />
|-<br />
! colspan="4" | sfspray < in.rsf > out.rsf axis=2 n= d= o= label= unit=<br />
|-<br />
| colspan="4" | This operation is adjoint to sfstack.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to spray<br />
|-<br />
| ''float '' || '''d=''' || || Sampling of the newly created dimension<br />
|-<br />
| ''string '' || '''label=''' || || Label of the newly created dimension<br />
|-<br />
| ''int '' || '''n=''' || || Size of the newly created dimension<br />
|-<br />
| ''float '' || '''o=''' || || Origin of the newly created dimension<br />
|-<br />
| ''string '' || '''unit=''' || || Units of the newly created dimension<br />
|}<br />
<br />
<tt>sfspray</tt> extends the input hypercube by replicating the data<br />
in one of the dimensions. The output dataset acquires one additional<br />
dimension. Here is an example:<br />
Start with a 2-D dataset<br />
<pre><br />
bash&#36; sfmath n1=5 n2=2 output=x1+x2 > test.rsf<br />
bash&#36; sfin test.rsf<br />
test.rsf:<br />
in="/var/tmp/test.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
10 elements 40 bytes<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
</pre><br />
Extend the data in the second dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=2 n=3 > test2.rsf<br />
bash&#36; sfin test2.rsf<br />
test2.rsf:<br />
in="/var/tmp/test2.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=3 d2=1 o2=0 <br />
n3=2 d3=1 o3=0 <br />
30 elements 120 bytes<br />
bash&#36; < test2.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 0 1 2 3 4<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
20: 1 2 3 4 5<br />
25: 1 2 3 4 5<br />
</pre><br />
The output is three-dimensional, with traces from the original<br />
data duplicated along the second axis.<br />
Extend the data in the third dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=3 n=2 > test3.rsf<br />
bash&#36; sfin test3.rsf<br />
test3.rsf:<br />
in="/var/tmp/test3.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
n3=2 d3=? o3=? <br />
20 elements 80 bytes<br />
bash&#36; < test3.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
</pre><br />
The output is also three-dimensional, with the original data replicated<br />
along the third axis.<br />
<br />
==sfstack==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stack a dataset over one of the dimensions.<br />
|-<br />
! colspan="4" | sfstack < in.rsf > out.rsf axis=2 rms=n norm=y min=n max=n<br />
|-<br />
| colspan="4" | <br>This operation is adjoint to sfspray.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to stack<br />
|-<br />
| ''bool '' || '''max=n''' || [y/n] || If y, find maximum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''min=n''' || [y/n] || If y, find minimum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || If y, normalize by fold.<br />
|-<br />
| ''bool '' || '''rms=n''' || [y/n] || If y, compute the root-mean-square instead of stack.<br />
|}<br />
While <tt>sfspray</tt> adds a dimension to a hypercube,<br />
<tt>sfstack</tt> effectively removes one of the dimensions by stacking<br />
over it. Here are some examples:<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
bash&#36; < test.rsf sfstack axis=2 | sfdisfil<br />
0: 1.5 2 3 4 5<br />
bash&#36; < test.rsf sfstack axis=1 | sfdisfil<br />
0: 2.5 3 4<br />
</pre><br />
Why is the first value not 1 (in the first case) or 2 (in the second<br />
case)? By default, <tt>sfstack</tt> normalizes the stack by the fold<br />
(the number of non-zero entries). To avoid normalization, use<br />
<tt>norm=n</tt>, as follows:<br />
<pre><br />
bash&#36; < test.rsf sfstack norm=n | sfdisfil <br />
0: 3 6 9 12 15<br />
</pre><br />
<tt>sfstack</tt> can also compute root-mean-square values as <br />
well as minimum and maximum values.<br />
<pre><br />
bash&#36; < test.rsf sfstack rms=y | sfdisfil<br />
0: 1.581 2.16 3.109 4.082 5.066<br />
bash&#36; < test.rsf sfstack min=y | sfdisfil<br />
0: 0 1 2 3 4<br />
bash&#36; < test.rsf sfstack axis=1 max=y | sfdisfil <br />
0: 4 5 6<br />
</pre><br />
<br />
==sftransp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Transpose two axes in a dataset. <br />
|-<br />
! colspan="4" | sftransp < in.rsf > out.rsf memsize=sf_memsize() plane=<br />
|-<br />
| colspan="4" | <br>If you get a "Cannot allocate memory" error, give the program a<br>memsize=1 command-line parameter to force out-of-core operation.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''plane=''' || || Two-digit number with axes to transpose. The default is 12<br />
|}<br />
<br />
The <tt>sftransp</tt> program transposes the input hypercube<br />
exchanging the two axes specified by the <b>plane=</b> parameter. <br />
<pre><br />
bash&#36; sfspike n1=10 n2=20 n3=30 > orig123.rsf<br />
bash&#36; sfin orig123.rsf <br />
orig123.rsf:<br />
in="/var/tmp/orig123.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=23 >out132.rsf<br />
bash&#36; sfin out132.rsf <br />
out132.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=20 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=13 >out321.rsf<br />
bash&#36; sfin out321.rsf <br />
out321.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=30 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=10 d3=0.004 o3=0 label3="Time" unit3="s" <br />
6000 elements 24000 bytes<br />
</pre><br />
<tt>sftransp</tt> tries to fit the dataset in memory to transpose it<br />
there but, if not enough memory is available, it performs a slower<br />
transpose out of core using disk operations. You can control the<br />
amount of available memory using the <b>memsize=</b> parameter or<br />
the <b>RSFMEMSIZE</b> environmental variable.<br />
<br />
==sfwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a portion of the dataset. <br />
|-<br />
! colspan="4" | sfwindow < in.rsf > out.rsf verb=n squeeze=y j#=(1,...) d#=(d1,d2,...) f#=(0,...) min#=(o1,o2,,...) n#=(0,...) max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)<br />
|-<br />
| ''float '' || '''d#=(d1,d2,...)''' || || sampling in #-th dimension<br />
|-<br />
| ''int '' || '''f#=(0,...)''' || || window start in #-th dimension<br />
|-<br />
| ''int '' || '''j#=(1,...)''' || || jump in #-th dimension<br />
|-<br />
| ''float '' || '''max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)''' || || maximum in #-th dimension<br />
|-<br />
| ''float '' || '''min#=(o1,o2,,...)''' || || minimum in #-th dimension<br />
|-<br />
| ''int '' || '''n#=(0,...)''' || || window size in #-th dimension<br />
|-<br />
| ''bool '' || '''squeeze=y''' || [y/n] || if y, squeeze dimensions equal to 1 to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
<b>sfwindow</b> is used to window a portion of the dataset. Here is<br />
a quick example: Start by creating some data.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Now window the first two rows:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n2=2 | sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
</pre><br />
Window the first three columns:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n1=3 | sfdisfil<br />
0: 1 2 3 2 4<br />
5: 6 3 6 9<br />
</pre><br />
Window the middle row:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f2=1 n2=1 | sfdisfil<br />
0: 2 4 6 8 10<br />
</pre><br />
You can interpret the <b>f#</b> and <b>n#</b> parameters as<br />
meaning "skip that many rows/columns" and "select that many<br />
rows/columns" correspondingly. Window the middle point in the dataset:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f1=2 n1=1 f2=1 n2=1 | sfdisfil<br />
0: 6<br />
</pre><br />
Window every other column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=2 | sfdisfil<br />
0: 1 3 5 2 6<br />
5: 10 3 9 15<br />
</pre><br />
Window every third column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=3 | sfdisfil<br />
0: 1 4 2 8 3<br />
5: 12<br />
</pre><br />
Alternatively, <b>sfwindow</b> can use the minimum and maximum<br />
parameters to select a window. In the following example, we are<br />
creating a dataset with <b>sfspike</b> and then windowing a portion of it<br />
between 1 and 2 seconds in time and sampled at 8 miliseconds.<br />
<pre><br />
bash&#36; sfspike n1=1000 n2=10 > spike.rsf <br />
bash&#36; sfin spike.rsf<br />
spike.rsf:<br />
in="/var/tmp/spike.rsf@"<br />
esize=4 type=float form=native <br />
n1=1000 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10000 elements 40000 bytes<br />
bash&#36; < spike.rsf sfwindow min1=1 max1=2 d1=0.008 > window.rsf<br />
bash&#36; sfin window.rsf<br />
window.rsf:<br />
in="/var/tmp/window.rsf@"<br />
esize=4 type=float form=native <br />
n1=126 d1=0.008 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
1260 elements 5040 bytes<br />
</pre><br />
By default, <b>sfwindow</b> "squeezes" the hypercube dimensions<br />
that are equal to one toward the end of the dataset. Here is an<br />
example of taking a time slice:<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=1 d2=0.004 o2=1 label2="Time" unit2="s" <br />
10 elements 40 bytes<br />
</pre><br />
You can change this behavior by specifying <b>squeeze=n</b>.<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 squeeze=n > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=1 d1=0.004 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10 elements 40 bytes<br />
</pre><br />
<br />
=Seismic programs=<br />
Programs in this category are specific for operations on seismic data. The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/seismic/ system/seismic] in the Madagascar distribution.<br />
<br />
==sfheaderattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Integer header attributes. <br />
|-<br />
! colspan="4" | sfheaderattr < head.rsf<br />
|-<br />
| colspan="4" | <br>Only nonzero values are reported.<br />
|}<br />
<br />
The <tt>sfheaderattr</tt> examines the contents of a trace header file,<br />
typically generated by <tt>sfsegyread</tt>. In the example below, we examine<br />
trace headers in the output of <tt>suplane</tt>, a program from Seismic Unix.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
bash$ sfheaderattr < tfile.rsf<br />
*******************************************<br />
71 headers, 32 traces<br />
key[0]="tracl" min[0]=1 max[31]=32 mean=16.5<br />
key[1]="tracr" min[0]=1 max[31]=32 mean=16.5<br />
key[11]="offset" min[0]=400 max[31]=400 mean=400<br />
key[38]="ns" min[0]=64 max[31]=64 mean=64<br />
key[39]="dt" min[0]=4000 max[31]=4000 mean=4000<br />
*******************************************<br />
</pre><br />
For different standard keywords, a minimum, maximum, and mean values<br />
are reported unless they are identically zero. This quick inspection<br />
can help in identifying meaningful keywords set in the data. The input<br />
data type must be <tt>int</tt>.<br />
<br />
==sfheadermath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations, possibly on header keys. <br />
|-<br />
! colspan="4" | sfheadermath < in.rsf > out.rsf memsize=sf_memsize() output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs<br><br>See also sfmath. <br><br>An addition operation can be performed by sfstack.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''output=''' || || Describes the output in a mathematical notation.<br />
|}<br />
<tt>sfheadermath</tt> is a versatile program for mathematical<br />
operations on rows of the input file. If the input file is an<br />
<tt>n1</tt> by <tt>n2</tt> matrix, the output will be a <tt>1</tt> by<br />
<tt>n2</tt> matrix that contains one row made out of mathematical<br />
operations on the other rows. <tt>sfheadermath</tt> can identify a row<br />
by number or by a standard SEGY keyword. The latter is useful for<br />
processing headers extracted from SEGY or SU files.<br />
Here is an example. First, we create an SU file with <tt>suplane</tt> and convert it to RSF using <tt>sfsegyread</tt>.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
</pre><br />
The trace header information is saved in <tt>tfile.rsf</tt>. It<br />
contains 71 headers for 32 traces in integer format.<br />
<pre><br />
bash$ sfin tfile.rsf<br />
tfile.rsf:<br />
in="/tmp/tfile.rsf@"<br />
esize=4 type=int form=native<br />
n1=71 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
2272 elements 9088 bytes<br />
</pre><br />
Next, we will convert <tt>tfile.rsf</tt> to a floating-point format<br />
and run <tt>sfheadermath</tt> to create a new header.<br />
<pre><br />
bash$ < tfile.rsf sfdd type=float | \<br />
sfheadermath myheader=1 output="sqrt(myheader+(2+10*offset^2))" > new.rsf<br />
bash$ sfin new.rsf<br />
new.rsf:<br />
in="/tmp/new.rsf@"<br />
esize=4 type=float form=native<br />
n1=1 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
32 elements 128 bytes<br />
</pre><br />
We defined "myheader" as being the row number 1 in the input (note<br />
that numbering starts with 0) and combined it with "offset", which<br />
is a standard SEGY keyword that denotes row number 11 (see the output<br />
of <tt>sfheaderattr</tt> above.) A variety of mathematical expressions<br />
can be defined in the <tt>output=</tt> string. The expression<br />
processing engine is shared with <tt>sfmath</tt>.<br />
<br />
==sfsegyheader==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Make a trace header file for segywrite.<br />
|-<br />
! colspan="4" | sfsegyheader < in.rsf > out.rsf n1= d1=<br />
|-<br />
| colspan="4" | <br> Use the output for tfile= argument in segywrite.<br />
|-<br />
| ''float '' || '''d1=''' || || trace sampling<br />
|-<br />
| ''int '' || '''n1=''' || || number of samples in a trace<br />
|}<br />
<br />
==sfsegyread==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert a SEG-Y or SU dataset to RSF.<br />
|-<br />
! colspan="4" | sfsegyread mask=msk.rsf > out.rsf tfile=hdr.rsf verb=false su=false format=sf_segyformat (bhead) ns=sf_segyns (bhead) endian= tape= read= hfile= bfile= mask= tfile=<br />
|-<br />
| colspan="4" | <br>Data headers and trace headers are separated from the data.<br><br>Defined SEG-Y trace header key names and byte offsets:<br><br>tracl: trace sequence number within line 0<br><br>tracr: trace sequence number within reel 4<br><br>fldr: field record number 8 <br><br>tracf: trace number within field record 12 <br><br>ep: energy source point number 16 <br><br>cdp: CDP ensemble number 20 <br><br>cdpt: trace number within CDP ensemble 24 <br><br>trid: trace identification code:<br>1 = seismic data<br>2 = dead<br>3 = dummy<br>4 = time break<br>5 = uphole<br>6 = sweep<br>7 = timing<br>8 = water break<br>9---, N = optional use (N = 32,767) 28 <br><br>nvs: number of vertically summed traces 30 <br><br>nhs: number of horizontally summed traces 32 <br><br>duse: data use:<br>1 = production<br>2 = test 34<br><br>offset: distance from source point to receiver<br>group (negative if opposite to direction<br>in which the line was shot) 36 <br><br>gelev: receiver group elevation from sea level<br>(above sea level is positive) 40 <br><br>selev: source elevation from sea level<br>(above sea level is positive) 44 <br><br>sdepth: source depth (positive) 48 <br><br>gdel: datum elevation at receiver group 52 <br><br>sdel: datum elevation at source 56 <br><br>swdep: water depth at source 60 <br><br>gwdep: water depth at receiver group 64 <br><br>scalel: scale factor for previous 7 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 68 <br><br>scalco: scale factor for next 4 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 70 <br><br>sx: X source coordinate 72 <br><br>sy: Y source coordinate 76 <br><br>gx: X group coordinate 80 <br><br>gy: Y group coordinate 84 <br><br>counit: coordinate units code:<br>for previoius four entries<br>1 = length (meters or feet)<br>2 = seconds of arc (in this case, the<br>X values are unsigned intitude and the Y values<br>are latitude, a positive value designates<br>the number of seconds east of Greenwich<br>or north of the equator 88 <br><br>wevel: weathering velocity 90 <br><br>swevel: subweathering velocity 92 <br><br>sut: uphole time at source 94 <br><br>gut: uphole time at receiver group 96 <br><br>sstat: source static correction 98 <br><br>gstat: group static correction 100 <br><br>tstat: total static applied 102 <br><br>laga: lag time A, time in ms between end of 240-<br>byte trace identification header and time<br>break, positive if time break occurs after<br>end of header, time break is defined as<br>the initiation pulse which maybe recorded<br>on an auxiliary trace or as otherwise<br>specified by the recording system 104 <br><br>lagb: lag time B, time in ms between the time<br>break and the initiation time of the energy source,<br>may be positive or negative 106 <br><br>delrt: delay recording time, time in ms between<br>initiation time of energy source and time<br>when recording of data samples begins<br>(for deep water work if recording does not<br>start at zero time) 108 <br><br>muts: mute time--start 110 <br><br>mute: mute time--end 112 <br><br>ns: number of samples in this trace 114 <br><br>dt: sample interval, in micro-seconds 116 <br><br>gain: gain type of field instruments code:<br>1 = fixed<br>2 = binary<br>3 = floating point<br>4 ---- N = optional use 118 <br><br>igc: instrument gain constant 120 <br><br>igi: instrument early or initial gain 122 <br><br>corr: correlated:<br>1 = no<br>2 = yes 124 <br><br>sfs: sweep frequency at start 126 <br><br>sfe: sweep frequency at end 128 <br><br>slen: sweep length in ms 130 <br><br>styp: sweep type code:<br>1 = linear<br>2 = cos-squared<br>3 = other 132 <br><br>stas: sweep trace length at start in ms 134 <br><br>stae: sweep trace length at end in ms 136 <br><br>tatyp: taper type: 1=linear, 2=cos^2, 3=other 138 <br><br>afilf: alias filter frequency if used 140 <br><br>afils: alias filter slope 142 <br><br>nofilf: notch filter frequency if used 144 <br><br>nofils: notch filter slope 146 <br><br>lcf: low cut frequency if used 148 <br><br>hcf: high cut frequncy if used 150 <br><br>lcs: low cut slope 152 <br><br>hcs: high cut slope 154 <br><br>year: year data recorded 156 <br><br>day: day of year 158 <br><br>hour: hour of day (24 hour clock) 160 <br><br>minute: minute of hour 162 <br><br>sec: second of minute 164 <br><br>timbas: time basis code:<br>1 = local<br>2 = GMT<br>3 = other 166 <br><br>trwf: trace weighting factor, defined as 1/2^N<br>volts for the least sigificant bit 168 <br><br>grnors: geophone group number of roll switch<br>position one 170 <br><br>grnofr: geophone group number of trace one within<br>original field record 172 <br><br>grnlof: geophone group number of last trace within<br>original field record 174 <br><br>gaps: gap size (total number of groups dropped) 176 <br><br>otrav: overtravel taper code:<br>1 = down (or behind)<br>2 = up (or ahead)<br />
|-<br />
| ''string '' || '''bfile=''' || || output binary data header file<br />
|-<br />
| ''bool '' || '''endian=''' || [y/n] || big/little endian flag, the default is estimated automatically<br />
|-<br />
| ''int '' || '''format=sf_segyformat (bhead)''' || [1,2,3,5] || Data format. The default is taken from binary header.<br />
:1 is IBM floating point<br />
:2 is 4-byte integer<br />
:3 is 2-byte integer<br />
:5 is IEEE floating point<br />
|-<br />
| ''string '' || '''hfile=''' || || output text data header file<br />
|-<br />
| ''string '' || '''mask=''' || || optional header mask for reading only selected traces<br />
|-<br />
| ''int '' || '''ns=sf_segyns (bhead)''' || || Number of samples. The default is taken from binary header<br />
|-<br />
| ''string '' || '''read=''' || || what to read: h - header, d - data, b - both (default)<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if input is SU, n if input is SEGY<br />
|-<br />
| ''bool '' || '''suxdr=n''' || [y/n] || y, SU has XDR support<br />
|-<br />
| ''string '' || '''tape=''' || || <br />
|-<br />
| ''string '' || '''tfile=''' || || output trace header file<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
The SEG Y format is an [http://en.wikipedia.org/wiki/Open_standard open standard] for the exchange of geophysical data. It is controlled by the non-profit [http://www.seg.org/SEGportalWEBproject/portals/SEG_Online.portal?_nfpb=true&_pageLabel=pg_gen_content&Doc_Url=prod/SEG-Publications/Pub-Yearbook/committees.htm SEG Technical Standards Committee]. There are two versions of this standard: [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev0.pdf rev0] (1975)<ref>Barry, K.M., Cavers, D.A., and Kneale, C.W. 1975. Recommended standards for digital tape formats. ''Geophysics'', '''40''', no. 02, 344–352.</ref> and [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf rev1] (2002)<ref>Norris, M.W., Faichney, A.K., ''Eds''. 2001. SEG Y rev1 Data Exchange format. Society of Exploration Geophysicists, Tulsa, OK, 45 pp.</ref>. The implementation in <tt>sfsegyread</tt> is a mixture of rev0 (i.e. no checks for Extended Textual Headers) and rev1 ([http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE floating point format] allowed for trace data samples).<br />
<br />
A SEG-Y file as understood by <tt>sfsegyread</tt> contains a "Reel Identification Header" (3200 bytes in EBCDIC followed by 400 bytes in a binary encoding), followed by a number of "Trace Blocks". Each "Trace Block" contains a 240-byte "Trace Header" (binary) followed by "Trace Data" -- a sequence of <tt>ns</tt> samples. Binary values in both reel headers and trace headers are two's complement integers, either two bytes or four bytes long. There are no floating-point values defined in the headers. Trace Data samples can have various encodings, either floating point or integer, described further down, but they are all big-endian. To convert from SEG-Y to RSF, <tt>sfsegyread</tt> will strip the tape reel EBCDIC header and convert it to ASCII, will extract the reel binary header without changing it, and will put the trace headers into one RSF file, and the traces themselves on another.<br />
<br />
===SEG-Y Trace Headers===<br />
In the SEG-Y standard, only the first 180 bytes of the 240-byte trace header are defined; bytes 181-240 are reserved for non-standard header information, and these locations are increasingly used in modern SEG-Y files and its variants. The standard provides for a total of 71 4-byte and 2-byte predefined header words. These 71 standard words have defined lengths and byte offsets, and only these words and byte locations are read using <tt>segyread</tt> and output to the RSF header file with the <tt>hfile=</tt> option. The user may remap these predefined keywords to a different byte offsets.<br />
<br />
===SU File Format===<br />
An [http://www.cwp.mines.edu/sututor/node22.html SU file] is nothing more than a SEG-Y file without the reel headers, and with the Trace Data samples in the native encoding of the CPU the file was created on (Attention -- limited portability!). So, to convert from SU to RSF, <tt>sfsegyread</tt> will just separate headers and traces into two RSF files. <br />
<br />
===SEG-Y specific parameters===<br />
*<tt>hfile=</tt> specifies the name of the file in which the EBCDIC reel header will be put after conversion to ASCII. If you are certain there is no useful information in it, <tt>hfile=/dev/null</tt> works just fine. If you do not specify anything for this parameter you will get an ASCII file named <tt>header</tt> in the current directory. If you want to quickly preview this header before running <tt>sfsegyread</tt>, use<pre>dd if=input.segy count=40 bs=80 cbs=80 conv=unblock,ascii</pre><br />
*<tt>bfile=</tt> specifies name of the file in which the binary reel header (the 400-bytes thing following the 3600-bytes EBCDIC) will be put without any conversion. The default name is "binary". Unless you have software that knows how to read exactly this special type of file, it will be completely useless, so do <tt>bfile=/dev/null</tt><br />
*<tt>format=</tt> specifies the format in which the trace data samples are in the SEG-Y input file. This is read from the binary reel header of the SEG-Y file. Valid values are 1(IBM floating point), 2 (4-byte integer), 3 (2-byte integer) and 5 (IEEE floating point). If the input file is SU, the format will be assumed to be the native <tt>float</tt> format.<br />
<br />
*<tt>keyname=</tt> specifies the byte offset to remap a header using the trace header key names shown above. For example, if the CDP locations have been placed in bytes 181-184 instead of the standard 21-24, <tt>cdp=180</tt> will remap the trace header to that location. <br />
<br />
===SU-specific parameters===<br />
*<tt>suxdr=</tt> specifies whether the input file was created with a SU package with XDR support enabled. If you have access to the source code of your SU install (try <tt>$CWPROOT/src</tt>), type: <tt>grep 'XDRFLAG =' $CWPROOT/src/Makefile.config</tt> and look at the last uncommented entry. If no value is given for <tt>XDRFLAG</tt>, the package was not compiled with XDR support.<br />
===Common parameters===<br />
*<tt>su=</tt> specifies if the input file is SU or SEG-Y. Default is <tt>su=n</tt> (SEG-Y file).<br />
*<tt>tape=</tt> specifies the input data. Stdin could not be used because <tt>sfsegyread</tt> has to work with tapes, and needs to fseek back and forth through the input file. Thankfully, output is on stdout.<br />
*<tt>read=</tt> specifies what parts of the "Trace Blocks" will be read. It can be <tt>read=t</tt> (only trace data is read), <tt>read=h</tt> (only trace headers are read) or <tt>read=b</tt> (both are read).<br />
*<tt>tfile=</tt> gives the name of the RSF file to which trace headers are written. Obviously, it should be only specified with <tt>read=h</tt> or <tt>read=b</tt>.<br />
*<tt>mask=</tt> is an optional parameter specifying the name of a mask that says which traces will be read. The mask is a 1-D RSF file with integers. The number of samples in the mask is the same as the number of traces in the unmasked SEG-Y. In places corresponding to unwanted traces there should be zeros in the mask.<br />
*<tt>ns=</tt> specifies the number of samples in a trace. For SEG-Y files, the default is taken from the binary reel header, and for SU files, from the header of the first trace. This parameter is however critical enough that a command line override was given for it.<br />
*<tt>verbose=</tt> is the verbosity flag. Can be <tt>y</tt> or <tt>n</tt>.<br />
*<tt>endian=</tt> is a y/n flag (default y), specifying whether to automatically estimate or not if samples in the Trace Data blocks are big-endian or little-endian. Try it if you are in trouble and do not know what else to do, otherwise let the automatic estimation do its job.<br />
<br />
==sfsegywrite==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert an RSF dataset to SEGY or SU.<br />
|-<br />
! colspan="4" | sfsegywrite < in.rsf tfile=hdr.rsf verb=false su=false endian=sf_endian() tape= hfile= bfile=<br />
|-<br />
| colspan="4" | <br>Merges trace headers with data.<br />
|-<br />
| ''string '' || '''bfile=''' || || input binary data header file<br />
|-<br />
| ''bool '' || '''endian=sf_endian()''' || [y/n] || big/little endian flag. The default is estimated automatically<br />
|-<br />
| ''string '' || '''hfile=''' || || input text data header file<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if output is SU, n if output is SEGY<br />
|-<br />
| ''string '' || '''tape=''' || ||<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
Please see <tt>sfsegyread</tt> for a complete description of parameter meanings and background issues. Parameters <tt>bfile</tt> and <tt>hfile</tt> should only be given values when the desired file is SEG-Y (default). The output file is specified by the <tt>tape=</tt> tag.<br />
<br />
=Plotting programs=<br />
The source files for these programs can be found under<br />
[http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/plot/main/ plot/main]<br />
in the Madagascar distribution.<br />
<br />
THIS SECTION IS UNDER CONSTRUCTION<br />
<br />
==sfbox==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Draw a balloon-style label.<br />
|-<br />
! colspan="4" | sfbox lab_color=VP_WHITE lab_fat=0 pscale=1. pointer=y reverse=n lat=0. long=90. angle=0. x0=0. y0=0. scale0=1. xt=2. yt=0. x_oval=0. y_oval=0. boxit=y length= scalet= size=.25 label= > out.vpl<br />
|-<br />
| ''float '' || '''angle=0.''' || || longitude of floating label in 3-D<br />
|-<br />
| ''bool '' || '''boxit=y''' || [y/n] || if y, create a box around text<br />
|-<br />
| ''int '' || '''lab_color=VP_WHITE''' || || label color<br />
|-<br />
| ''int '' || '''lab_fat=0''' || || label fatness<br />
|-<br />
| ''string '' || '''label=''' || || text for label<br />
|-<br />
| ''float '' || '''lat=0.''' || || <br />
|-<br />
| ''float '' || '''length=''' || || normalization for xt and yt<br />
|-<br />
| ''float '' || '''long=90.''' || || latitude and longitude of viewpoint in 3-D<br />
|-<br />
| ''bool '' || '''pointer=y''' || [y/n] || if y, create arrow pointer<br />
|-<br />
| ''float '' || '''pscale=1.''' || || scale factor for width of pointer<br />
|-<br />
| ''bool '' || '''reverse=n''' || [y/n] || <br />
|-<br />
| ''float '' || '''scale0=1.''' || || scale factor for x0 and y0<br />
|-<br />
| ''float '' || '''scalet=''' || || <br />
|-<br />
| ''float '' || '''size=.25''' || || text height in inches<br />
|-<br />
| ''float '' || '''x0=0.''' || || <br />
|-<br />
| ''float '' || '''x_oval=0.''' || || <br />
|-<br />
| ''float '' || '''xt=2.''' || || <br />
|-<br />
| ''float '' || '''y0=0.''' || || position of the pointer tip<br />
|-<br />
| ''float '' || '''y_oval=0.''' || || size of the oval around pointer<br />
|-<br />
| ''float '' || '''yt=0.''' || || relative position of text<br />
|}<br />
==sfcontour==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Contour plot.<br />
|-<br />
! colspan="4" | sfcontour < in.rsf c= min1=o1 min2=o2 max1=o1+(n1-1)*d1 max2=o2+(n2-1)*d2 nc=50 dc= c0= transp=y minval= maxval= allpos=y barlabel= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=y''' || [y/n] || contour positive values only<br />
|-<br />
| ''string '' || '''barlabel=''' || || <br />
|-<br />
| ''floats '' || '''c=''' || || [nc]<br />
|-<br />
| ''float '' || '''c0=''' || || first contour<br />
|-<br />
| ''float '' || '''dc=''' || || contour increment<br />
|-<br />
| ''float '' || '''max1=o1+(n1-1)*d1''' || || <br />
|-<br />
| ''float '' || '''max2=o2+(n2-1)*d2''' || || data window to plot<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''min1=o1''' || || <br />
|-<br />
| ''float '' || '''min2=o2''' || || <br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nc=50''' || || number of contours<br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfdots==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot signal with lollipops.<br />
|-<br />
! colspan="4" | sfdots < in.rsf labels= dots=(n1 <= 130)? 1: 0 seemean=(bool) (n2 <= 30) strings=(bool) (n1 <= 400) connect=1 corners= silk=n gaineach=y labelsz=8 yreverse=n constsep=n seedead=n transp=n xxscale=1. yyscale=1. clip=-1. overlap=0.9 screenratio=VP_SCREEN_RATIO screenht=VP_STANDARD_HEIGHT screenwd=screenhigh / screenratio radius=dd1/3 label1= unit1= title= > plot.vpl<br />
|-<br />
| ''float '' || '''clip=-1.''' || || data clip<br />
|-<br />
| ''int '' || '''connect=1''' || || connection type: 1 - diagonal, 2 - bar, 4 - only for non-zero data<br />
|-<br />
| ''bool '' || '''constsep=n''' || [y/n] || if y, use constant trace separation<br />
|-<br />
| ''int '' || '''corners=''' || || number of polygon corners (default is 6)<br />
|-<br />
| ''int '' || '''dots=(n1 <= 130)? 1: 0''' || || type of dots: 1 - baloon, 0 - no dots, 2 - only for non-zero data<br />
|-<br />
| ''bool '' || '''gaineach=y''' || [y/n] || if y, gain each trace independently<br />
|-<br />
| ''string '' || '''label1=''' || || <br />
|-<br />
| ''strings'' || '''labels=''' || || trace labels [n2]<br />
|-<br />
| ''int '' || '''labelsz=8''' || || label size<br />
|-<br />
| ''float '' || '''overlap=0.9''' || || trace overlap<br />
|-<br />
| ''float '' || '''radius=dd1/3''' || || dot radius<br />
|-<br />
| ''float '' || '''screenht=VP_STANDARD_HEIGHT''' || || screen height<br />
|-<br />
| ''float '' || '''screenratio=VP_SCREEN_RATIO''' || || screen aspect ratio<br />
|-<br />
| ''float '' || '''screenwd=screenhigh / screenratio''' || || screen width<br />
|-<br />
| ''bool '' || '''seedead=n''' || [y/n] || if y, show zero traces<br />
|-<br />
| ''bool '' || '''seemean=(bool) (n2 <= 30)''' || [y/n] || if y, draw axis lines<br />
|-<br />
| ''bool '' || '''silk=n''' || [y/n] || if y, silky plot<br />
|-<br />
| ''bool '' || '''strings=(bool) (n1 <= 400)''' || [y/n] || if y, draw strings<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axis<br />
|-<br />
| ''string '' || '''unit1=''' || || <br />
|-<br />
| ''float '' || '''xxscale=1.''' || || x scaling<br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse y axis<br />
|-<br />
| ''float '' || '''yyscale=1.''' || || y scaling<br />
|}<br />
==sfgraph3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot for surfaces.<br />
|-<br />
! colspan="4" | sfgraph3 < in.rsf orient=1 min= max= point1=0.5 point2=0.5 frame1=0.5*(min+max) frame2=n1-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y > plot.vpl<br />
|-<br />
| ''float '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''float '' || '''frame1=0.5*(min+max)''' || || <br />
|-<br />
| ''int '' || '''frame2=n1-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''max=''' || || maximum function value<br />
|-<br />
| ''float '' || '''min=''' || || minimum function value<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''orient=1''' || || function orientation<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|}<br />
==sfgraph==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Graph plot.<br />
|-<br />
! colspan="4" | sfgraph < in.rsf symbolsz= pclip=100. transp=n symbol= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''pclip=100.''' || || clip percentile<br />
|-<br />
| ''string '' || '''symbol=''' || || if set, plot with symbols instead of lines<br />
|-<br />
| ''floats '' || '''symbolsz=''' || || symbol size (default is 2) [n2]<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfgrey3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot.<br />
|-<br />
! colspan="4" | sfgrey3 < in.rsf point1=0.5 point2=0.5 frame1=0 frame2=n2-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y scalebar=n minval= maxval= barreverse=n nreserve=8 bar= color= > plot.vpl<br />
|-<br />
| colspan="4" | Requires an "unsigned char" input (the output of sfbyte).<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''int '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''int '' || '''frame1=0''' || || <br />
|-<br />
| ''int '' || '''frame2=n2-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || if y, draw scalebar<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
for sfgrey and sfgrey3. Examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfgrey==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate raster plot.<br />
|-<br />
! colspan="4" | sfgrey < in.rsf > out.rsf bar=bar.rsf transp=y yreverse=y xreverse=n gpow= phalf= clip= pclip= gainstep=0.5+n1/256. allpos=n bias=0. polarity=n verb=n scalebar=n minval= maxval= barreverse=n wantframenum=(bool) (n3 > 1) nreserve=8 gainpanel= bar= color= > (plot.vpl | char.rsf)<br />
|-<br />
| colspan="4" | Can input char values.<br>If called "byte", outputs char values.<br><br>Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=n''' || [y/n] || if y, assume positive data<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=''' || || <br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''string '' || '''gainpanel=''' || || gain reference: 'a' for all, 'e' for each, or number<br />
|-<br />
| ''int '' || '''gainstep=0.5+n1/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=''' || || <br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''pclip=''' || || data clip percentile (default is 99)<br />
|-<br />
| ''float '' || '''phalf=''' || || percentage for estimating gpow<br />
|-<br />
| ''bool '' || '''polarity=n''' || [y/n] || if y, reverse polarity (white is high by default)<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the display axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''bool '' || '''wantframenum=(bool) (n3 > 1)''' || [y/n] || if y, display third axis position in the corner<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''bool '' || '''yreverse=y''' || [y/n] || if y, reverse the vertical axis<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
and examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfplas==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Assembler - convert ascii to vplot. <br />
|-<br />
! colspan="4" | sfplas<br />
|}<br />
==sfpldb==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Debugger - convert vplot to ascii. <br />
|-<br />
! colspan="4" | sfpldb<br />
|}<br />
==sfplotrays==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot rays.<br />
|-<br />
! colspan="4" | sfplotrays frame=frame.rsf nt=n1*n2 jr=1 frame= < rays.rsf > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''string '' || '''frame=''' || || <br />
|-<br />
| ''int '' || '''jr=1''' || || skip rays<br />
|-<br />
| ''int '' || '''nt=n1*n2''' || || maximum ray length<br />
|}<br />
==sfthplot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Hidden-line surface plot.<br />
|-<br />
! colspan="4" | sfthplot < in.rsf uflag=y dflag=y alpha=45. titlsz=9 axissz=6 plotfat=0 titlefat=2 axisfat=2 plotcolup=VP_YELLOW plotcoldn=VP_RED axis=y axis1=y axis2=y axis3=y clip=0. pclip=100. gainstep=0.5+nx/256. bias=0. dclip=1. norm=y xc=1.5 zc=3 ratio=5. zmax= zmin= sz=6. label#= unit#= tpow=0 epow=0 gpow=1 title= > plot.vpl<br />
|-<br />
| ''float '' || '''alpha=45.''' || || apparent angle in degrees, |alpha| < 89<br />
|-<br />
| ''bool '' || '''axis=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis1=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis2=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis3=y''' || [y/n] || plot axis<br />
|-<br />
| ''int '' || '''axisfat=2''' || || axes fatness<br />
|-<br />
| ''int '' || '''axissz=6''' || || axes size<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip<br />
|-<br />
| ''float '' || '''dclip=1.''' || || change the clip: clip *= dclip<br />
|-<br />
| ''bool '' || '''dflag=y''' || [y/n] || if y, plot down side of the surface<br />
|-<br />
| ''float '' || '''epow=0''' || || exponential gain<br />
|-<br />
| ''int '' || '''gainstep=0.5+nx/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=1''' || || power gain<br />
|-<br />
| ''string '' || '''label#=''' || || label on #-th axis<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || normalize by the clip<br />
|-<br />
| ''float '' || '''pclip=100.''' || || data clip percentile<br />
|-<br />
| ''int '' || '''plotcoldn=VP_RED''' || || color of the lower side<br />
|-<br />
| ''int '' || '''plotcolup=VP_YELLOW''' || || color of the upper side<br />
|-<br />
| ''int '' || '''plotfat=0''' || || line fatness<br />
|-<br />
| ''float '' || '''ratio=5.''' || || plot adjustment<br />
|-<br />
| ''float '' || '''sz=6.''' || || vertical scale<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''int '' || '''titlefat=2''' || || title fatness<br />
|-<br />
| ''int '' || '''titlsz=9''' || || title size<br />
|-<br />
| ''string '' || '''tpow=0''' || || time power gain<br />
|-<br />
| ''bool '' || '''uflag=y''' || [y/n] || if y, plot upper side of the surface<br />
|-<br />
| ''string '' || '''unit#=''' || || unit on #-th axis<br />
|-<br />
| ''float '' || '''xc=1.5''' || || <br />
|-<br />
| ''float '' || '''zc=3''' || || lower left corner of the plot<br />
|-<br />
| ''float '' || '''zmax=''' || || <br />
|-<br />
| ''float '' || '''zmin=''' || || <br />
|}<br />
==sfwiggle==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot data with wiggly traces. <br />
|-<br />
! colspan="4" | sfwiggle < in.rsf xpos=xpos.rsf xmax= xmin= poly=n fatp=1 xmask=1 ymask=1 pclip=98. zplot=0.75 clip=0. seemean=n verb=n transp=n yreverse=n xreverse=n xpos= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip (estimated from pclip by default<br />
|-<br />
| ''int '' || '''fatp=1''' || || <br />
|-<br />
| ''float '' || '''pclip=98.''' || || clip percentile<br />
|-<br />
| ''bool '' || '''poly=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''seemean=n''' || [y/n] || if y, plot mean lines of traces<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''int '' || '''xmask=1''' || || <br />
|-<br />
| ''float '' || '''xmax=''' || || maximum trace position (if using xpos)<br />
|-<br />
| ''float '' || '''xmin=''' || || minimum trace position (if using xpos)<br />
|-<br />
| ''string '' || '''xpos=''' || || optional header file with trace positions<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''int '' || '''ymask=1''' || || <br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse the vertical axis<br />
|-<br />
| ''float '' || '''zplot=0.75''' || || <br />
|}<br />
<br />
=filt/imag programs=<br />
==sfremap1==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 1-D ENO interpolation. <br />
|-<br />
! colspan="4" | sfremap1 < in.rsf > out.rsf pattern=pattern.rsf n1=n1 d1=d1 o1=o1 order=3<br />
|-<br />
| ''float '' || '''d1=d1''' || || Output sampling<br />
|-<br />
| ''int '' || '''n1=n1''' || || Number of output samples<br />
|-<br />
| ''float '' || '''o1=o1''' || || Output origin<br />
|-<br />
| ''int '' || '''order=3''' || || Interpolation order<br />
|-<br />
| ''string '' || '''pattern=''' || || auxiliary input file name<br />
|}<br />
To give an example of usage, we will create an input for <tt>sfremap1</tt> with:<br />
<pre><br />
sfmath n1=11 n2=11 d1=1 d2=1 o1=-5 o2=-5 output="x1*x1+x2*x2" > inp2remap1.rsf<br />
</pre><br />
Let us interpolate the data across both dimensions, then display it:<br />
<pre><br />
&lt; inp2remap1.rsf sfremap1 n1=1001 d1=0.01 | sftransp | \<br />
sfremap1 n1=1001 d1=0.01 | sftransp | sfgrey allpos=y | xtpen<br />
</pre><br />
The comparison with the uninterpolated data ( <tt>&lt; inp2remap1.rsf sfgrey allpos=y | xtpen</tt> ) is quite telling.<br />
<br />
=filt/proc programs=<br />
==sfstretch==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stretch of the time axis. <br />
|-<br />
! colspan="4" | sfstretch < in.rsf > out.rsf datum=dat.rsf inv=n dens=1 v0= half=y delay= tdelay= hdelay= nout=dens*n1 extend=4 mute=0 maxstr=0 rule=<br />
|-<br />
| ''file '' || '''datum=''' || || auxiliary input file name<br />
|-<br />
| ''float '' || '''delay=''' || || time delay for rule=lmo<br />
|-<br />
| ''int '' || '''dens=1''' || || axis stretching factor<br />
|-<br />
| ''int '' || '''extend=4''' || || trace extension<br />
|-<br />
| ''bool '' || '''half=y''' || [y/n] || if y, the second axis is half-offset instead of full offset<br />
|-<br />
| ''float '' || '''hdelay=''' || || offset delay for rule=rad<br />
|-<br />
| ''bool '' || '''inv=n''' || [y/n] || if y, do inverse stretching<br />
|-<br />
| ''float '' || '''maxstr=0''' || || maximum stretch<br />
|-<br />
| ''int '' || '''mute=0''' || || tapering size<br />
|-<br />
| ''int '' || '''nout=dens*n1''' || || output axis length (if inv=n)<br />
|-<br />
| ''string '' || '''rule=''' || || Stretch rule:<br />
:n - normal moveout (nmostretch), default<br />
:l - linear moveout (lmostretch)<br />
:L - logarithmic stretch (logstretch)<br />
:2 - t^2 stretch (t2stretch)<br />
:c - t^2 chebyshev stretch (t2chebstretch)<br />
:r - radial moveout (radstretch)<br />
:d - datuming (datstretch)<br />
|-<br />
| ''float '' || '''tdelay=''' || || time delay for rule=rad<br />
|-<br />
| ''float '' || '''v0=''' || || moveout velocity<br />
|}<br />
<br />
<tt>sfstretch rule=d</tt> (aka <tt>sfdatstretch</tt>) can be used to apply statics. Here is a synthetic example, courtesy of Alessandro Frigeri:<br />
<pre><br />
# generate a dataset with 'flat' signals<br />
sfmath n1=200 n2=100 output="sin(0.5*x1)" type=float > scan.rsf<br />
<br />
# generate a sinusoidal elevation correction<br />
sfmath n1=100 output="3*sin(x1)" type=float > statics.rsf<br />
<br />
# apply statics, producing a 'wavy' output.<br />
sfstretch < scan.rsf > out.rsf datum=statics.rsf rule=d<br />
</pre><br />
<br />
=user/ivlad programs=<br />
==sfprep4plot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Resamples a 2-D dataset to the desired picture resolution, with antialias<br />
|-<br />
! colspan="4" | sfprep4plot inp= out= verb=n h=none w=none unit= ppi= prar=y<br />
|-<br />
| colspan="4" | Only one of the h and w parameters needs to be specified.<br>If prar=n, no action will be taken on axis for which h/w was not specified<br>If prar=y and only one par (h or w) is specified, the picture will scale<br>along both axes until it is of the specified dimension.<br />
|-<br />
| ''int '' || '''h=none''' || || output height<br />
|-<br />
| ''string '' || '''inp=''' || || input file<br />
|-<br />
| ''string '' || '''out=''' || || output file<br />
|-<br />
| ''int '' || '''ppi=''' || || output resolution (px/in). Necessary when unit!=px<br />
|-<br />
| ''bool '' || '''prar=y''' || [y/n] || if y, PReserve Aspect Ratio of input<br />
|-<br />
| ''string '' || '''unit=''' || || unit of h and w. Can be: px(default), mm, cm, in<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || if y, print system commands, outputs<br />
|-<br />
| ''int '' || '''w=none''' || || output width<br />
|}<br />
For a figure that does not need the aspect ratio preserved,<br />
and needs to fill a 1280x1024 projector display:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=1280 h=1024 prar=n<br />
</pre><br />
For a print figure that has to fit in a 6x8in box<br />
at a resolution of 250 dpi, preserving the aspect ratio:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=6 h=8 unit=in ppi=250<br />
</pre><br />
A comparison of images before and after the application of <tt>sfprep4plot</tt>, courtesy of Joachim Mispel, is shown below:<br />
<br />
[[Image:sf_prep4plot.jpg]]<br />
<br />
=References=<br />
<references/></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Guide_to_madagascar_programs&diff=679Guide to madagascar programs2009-03-05T19:33:23Z<p>Jenningsjwj: /* sfgrey */</p>
<hr />
<div><center><font size="-1">''This page was created from the LaTeX source in [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/book/rsf/rsf/prog.tex?view=markup book/rsf/rsf/prog.tex] using [[latex2wiki]]''</font></center><br />
<br />
This guide introduces some of the most used <tt>madagascar</tt> programs and illustrates their usage with examples.<br />
=Main programs=<br />
The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/main/ system/main] in the Madagascar distribution. The "main" programs perform general-purpose operations on RSF hypercubes regardless of the data dimensionality or physical dimensions.<br />
<br />
==sfadd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Add, multiply, or divide RSF datasets.<br />
|-<br />
! colspan="4" | sfadd > out.rsf scale= add= sqrt= abs= log= exp= mode= [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | The various operations, if selected, occur in the following order:<br><br>(1) Take absolute value, abs=<br>(2) Add a scalar, add=<br>(3) Take the natural logarithm, log=<br>(4) Take the square root, sqrt=<br>(5) Multiply by a scalar, scale=<br>(6) Compute the base-e exponential, exp=<br>(7) Add, multiply, or divide the data sets, mode=<br><br>sfadd operates on integer, float, or complex data, but all the input<br>and output files must be of the same data type.<br><br>An alternative to sfadd is sfmath, which is more versatile, but may be<br>less efficient.<br />
|-<br />
| ''bools '' || '''abs=''' || || If true take absolute value [nin]<br />
|-<br />
| ''floats '' || '''add=''' || || Scalar values to add to each dataset [nin]<br />
|-<br />
| ''bools '' || '''exp=''' || || If true compute exponential [nin]<br />
|-<br />
| ''bools '' || '''log=''' || || If true take logarithm [nin]<br />
|-<br />
| ''string '' || '''mode=''' || || 'a' means add (default), <br> 'p' or 'm' means multiply, <br> 'd' means divide<br />
|-<br />
| ''floats '' || '''scale=''' || || Scalar values to multiply each dataset with [nin]<br />
|-<br />
| ''bools '' || '''sqrt=''' || || If true take square root [nin]<br />
|}<br />
<br />
<tt>sfadd</tt> is useful for combining (adding, dividing, or<br />
multiplying) several datasets. What if you want to subtract two<br />
datasets? Easy. Use the <tt>scale</tt> parameter as follows:<br />
<pre><br />
bash&#36; sfadd data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfadd < data1.rsf data2.rsf scale=1,-1 > diff.rsf<br />
</pre><br />
The same task can be accomplished with the more general <tt>sfmath</tt> program:<br />
<pre><br />
bash&#36; sfmath one=data1.rsf two=data2.rsf output='one-two' > diff.rsf<br />
</pre><br />
or<br />
<pre><br />
bash&#36; sfmath < data1.rsf two=data2.rsf output='input-two' > diff.rsf<br />
</pre><br />
In both cases, the size and shape of <tt>data1.rsf</tt> and<br />
<tt>data2.rsf</tt> hypercubes should be the same, and a warning<br />
message is printed out if the the axis sampling parameters (such as<br />
<tt>o1</tt> or <tt>d1</tt>) in these files are different.<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/add.c?view=markup user/main/add.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
/* find number of input files */<br />
if (isatty(fileno(stdin))) { <br />
/* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Collect input files in the <tt>in</tt> array from all command-line<br />
parameters that don't contain an "<tt>=</tt>" sign. The total number<br />
of input files in <tt>nin</tt>.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) continue; <br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
/* nin = no of input files*/<br />
</c><br />
<br />
A helper function <tt>check_compat</tt> checks the compatibility of<br />
input files.<br />
<c><br />
static void <br />
check_compat (sf_datatype type /* data type */, <br />
size_t nin /* number of files */, <br />
sf_file* in /* input files [nin] */, <br />
int dim /* file dimensionality */, <br />
const int* n /* dimensions [dim] */)<br />
/* Check that the input files are compatible. <br />
Issue error for type mismatch or size mismatch.<br />
Issue warning for grid parameters mismatch. */<br />
{<br />
int ni, id;<br />
size_t i;<br />
float d, di, o, oi;<br />
char key[3];<br />
const float tol=1.e-5; /* tolerance for comparison */<br />
<br />
for (i=1; i < nin; i++) {<br />
if (sf_gettype(in[i]) != type) <br />
sf_error ("type mismatch: need %d",type);<br />
for (id=1; id <= dim; id++) {<br />
(void) snprintf(key,3,"n%d",id);<br />
if (!sf_histint(in[i],key,&ni) || ni != n[id-1])<br />
sf_error("%s mismatch: need %d",key,n[id-1]);<br />
(void) snprintf(key,3,"d%d",id);<br />
if (sf_histfloat(in[0],key,&d)) {<br />
if (!sf_histfloat(in[i],key,&di) || <br />
(fabsf(di-d) > tol*fabsf(d)))<br />
sf_warning("%s mismatch: need %g",key,d);<br />
} else {<br />
d = 1.;<br />
}<br />
(void) snprintf(key,3,"o%d",id);<br />
if (sf_histfloat(in[0],key,&o) && <br />
(!sf_histfloat(in[i],key,&oi) || <br />
(fabsf(oi-o) > tol*fabsf(d))))<br />
sf_warning("%s mismatch: need %g",key,o);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
Finally, we enter the main loop, where input data are getting read<br />
buffer by buffer and combined in the total product depending on the<br />
data type.<br />
<c><br />
for (nbuf /= sf_esize(in[0]); nsiz > 0; nsiz -= nbuf) {<br />
if (nbuf > nsiz) nbuf=nsiz;<br />
<br />
for (j=0; j < nin; j++) {<br />
collect = (bool) (j != 0);<br />
switch(type) {<br />
case SF_FLOAT:<br />
sf_floatread((float*) bufi,<br />
nbuf,<br />
in[j]); <br />
add_float(collect, <br />
nbuf,<br />
(float*) buf,<br />
(const float*) bufi, <br />
cmode, <br />
scale[j], <br />
add[j], <br />
abs_flag[j], <br />
log_flag[j], <br />
sqrt_flag[j], <br />
exp_flag[j]);<br />
break;<br />
</c><br />
<br />
The data combination program for floating point numbers is<br />
<tt>add_float</tt>. <br />
<c><br />
static void add_float (bool collect, /* if collect */<br />
size_t nbuf, /* buffer size */<br />
float* buf, /* output [nbuf] */<br />
const float* bufi, /* input [nbuf] */ <br />
char cmode, /* operation */<br />
float scale, /* scale factor */<br />
float add, /* add factor */<br />
bool abs_flag, /* if abs */<br />
bool log_flag, /* if log */<br />
bool sqrt_flag, /* if sqrt */<br />
bool exp_flag /* if exp */)<br />
/* Add floating point numbers */<br />
{<br />
size_t j;<br />
float f;<br />
<br />
for (j=0; j < nbuf; j++) {<br />
f = bufi[j];<br />
if (abs_flag) f = fabsf(f);<br />
f += add;<br />
if (log_flag) f = logf(f);<br />
if (sqrt_flag) f = sqrtf(f);<br />
if (1. != scale) f *= scale;<br />
if (exp_flag) f = expf(f);<br />
if (collect) {<br />
switch (cmode) {<br />
case 'p': /* product */<br />
case 'm': /* multiply */<br />
buf[j] *= f;<br />
break;<br />
case 'd': /* delete */<br />
if (f != 0.) buf[j] /= f;<br />
break;<br />
default: /* add */<br />
buf[j] += f;<br />
break;<br />
}<br />
} else {<br />
buf[j] = f;<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display dataset attributes.<br />
|-<br />
! colspan="4" | sfattr < in.rsf want=<br />
|-<br />
| colspan="4" | <br>Sample output from "sfspike n1=100 | sfbandpass fhi=60 | sfattr"<br>******************************************* <br>rms = 0.992354 <br>mean value = 0.987576 <br>2-norm value = 9.92354 <br>variance = 0.00955481 <br>standard deviation = 0.0977487 <br>maximum value = 1.12735 at 97 <br>minimum value = 0.151392 at 100 <br>number of nonzero samples = 100 <br>total number of samples = 100 <br>******************************************* <br><br>rms = sqrt[ sum(data^2) / n ]<br>mean = sum(data) / n<br>norm = sum(abs(data)^lval)^(1/lval)<br>variance = [ sum(data^2) - n*mean^2 ] / [ n-1 ]<br>standard deviation = sqrt [ variance ]<br />
|-<br />
| ''int '' || '''lval=2''' || || norm option, lval is a non-negative integer, computes the vector lval-norm<br />
|-<br />
| ''string '' || '''want=''' || || 'all'(default),'rms','mean','norm','var','std','max','min','nonzero','samples','short' <br />
:want= 'rms' displays the root mean square<br />
:want= 'norm' displays the square norm, otherwise specified by lval.<br />
:want= 'var' displays the variance<br />
:want= 'std' displays the standard deviation<br />
:want= 'nonzero' displays number of nonzero samples<br />
:want= 'samples' displays total number of samples<br />
:want= 'short' displays a short one-line version<br />
|}<br />
<br />
<br />
<tt>sfattr</tt> is a useful diagnostic program. It reports certain<br />
statistical values for an RSF dataset: RMS (root-mean-square)<br />
amplitude, mean value, vector norm value, variance, standard deviation,<br />
maximum and minimum values, number of nonzero samples, and the total<br />
number of samples.<br />
If we denote data values as <math>d_i</math> for <math>i=0,1,2,\ldots,n</math>, then the RMS<br />
value is <math>\sqrt{\frac{1}{n}\,\sum\limits_{i=0}^n d_i^2}</math>, the mean<br />
value is <math>\frac{1}{n}\,\sum\limits_{i=0}^n d_i</math>, the <math>L_2</math>-norm value<br />
is <math>\sqrt{\sum\limits_{i=0}^n d_i^2}</math>, the variance is<br />
<math>\frac{1}{n-1}\,\left[\sum\limits_{i=0}^n d_i^2 - \frac{1}{n}\left(\sum\limits_{i=0}^n d_i\right)^2\right]</math>, and the standard<br />
deviation is the square root of the variance. Using <tt>sfattr</tt><br />
is a quick way to see the distribution of data values and check it for<br />
anomalies.<br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/attr.c?view=markup user/main/attr.c]====<br />
<br />
Computations start by finding the input data (<tt>in</tt>) size<br />
(<tt>nsiz</tt>) and dimensions (<tt>dim</tt>).<br />
<c><br />
dim = (size_t) sf_filedims (in,n);<br />
for (nsiz=1, i=0; i < dim; i++) {<br />
nsiz *= n[i];<br />
}<br />
</c><br />
<br />
<br />
In the main loop, we read the input data buffer by buffer.<br />
<c><br />
for (nleft=nsiz; nleft > 0; nleft -= nbuf) {<br />
nbuf = (bufsiz < nleft)? bufsiz: nleft;<br />
switch (type) {<br />
case SF_FLOAT: <br />
sf_floatread((float*) buf,nbuf,in);<br />
break;<br />
case SF_INT:<br />
sf_intread((int*) buf,nbuf,in);<br />
break;<br />
case SF_COMPLEX:<br />
sf_complexread((sf_complex*) buf,nbuf,in);<br />
break;<br />
case SF_UCHAR:<br />
sf_ucharread((unsigned char*) buf,nbuf,in);<br />
break;<br />
case SF_CHAR:<br />
default:<br />
sf_charread(buf,nbuf,in);<br />
break;<br />
}<br />
</c><br />
<br />
<br />
The data attributes are accumulated in corresponding double-precision<br />
variables. <br />
<c><br />
fsum += f;<br />
fsqr += f*f;<br />
</c><br />
<br />
<br />
Finally, the attributes are reduced and printed out.<br />
<c><br />
fmean = fsum/nsiz;<br />
if (lval==2) fnorm = sqrt(fsqr);<br />
else if (lval==0) fnorm = nsiz-nzero;<br />
else fnorm = pow(flval,1./lval);<br />
frms = sqrt(fsqr/nsiz);<br />
if (nsiz > 1) fvar = (fsqr-nsiz*fmean*fmean)/(nsiz-1);<br />
else fvar = 0.0;<br />
fstd = sqrt(fvar);<br />
</c><br />
<br />
<c><br />
if(NULL==want || 0==strcmp(want,"rms"))<br />
printf("rms = %g \n",(float) frms);<br />
if(NULL==want || 0==strcmp(want,"mean"))<br />
printf("mean value = %g \n",(float) fmean);<br />
if(NULL==want || 0==strcmp(want,"norm"))<br />
printf("%d-norm value = %g \n",lval,(float) fnorm);<br />
if(NULL==want || 0==strcmp(want,"var"))<br />
printf("variance = %g \n",(float) fvar);<br />
if(NULL==want || 0==strcmp(want,"std"))<br />
printf("standard deviation = %g \n",(float) fstd);<br />
</c><br />
<br />
==sfcat==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Concatenate datasets. <br />
|-<br />
! colspan="4" | sfcat > out.rsf space= axis=3 nspace=(int) (ni/(20*nin) + 1) [<file0.rsf] file1.rsf file2.rsf ... <br />
|-<br />
| colspan="4" | sfmerge inserts additional space between merged data.<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis being merged<br />
|-<br />
| ''int '' || '''nspace=(int) (ni/(20*nin) + 1)''' || || if space=y, number of traces to insert<br />
|-<br />
| ''bool '' || '''space=''' || [y/n] || Insert additional space.<br />
:y is default for sfmerge, n is default for sfcat<br />
|}<br />
<br />
<br />
<tt>sfcat</tt> and <tt>sfmerge</tt> concatenate two or more files<br />
together along a particular axis. It is the same program, only<br />
<tt>sfcat</tt> has the default <tt>space=n</tt> and <tt>sfmerge</tt><br />
has the default <tt>space=y</tt>.<br />
Example of <tt>sfcat</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcat one.rsf one.rsf axis=1 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=4 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
12 elements 48 bytes<br />
</pre><br />
Example of <tt>sfmerge</tt>:<br />
<pre><br />
bash$ sfmerge one.rsf one.rsf axis=2 > two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=7 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
14 elements 56 bytes<br />
</pre><br />
In this case, an extra empty trace is inserted between the two merged files.<br />
The axes that are not being merged are checked for consistency:<br />
<pre><br />
bash$ sfcat one.rsf two.rsf > three.rsf<br />
sfcat: n2 mismatch: need 3<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cat.c?view=markup user/main/cat.c]====<br />
The first input file is either in the list or in the standard input.<br />
<c><br />
in = (sf_file*) sf_alloc ((size_t) argc,sizeof(sf_file));<br />
<br />
if (!sf_stdin()) { /* no input file in stdin */<br />
nin=0;<br />
} else {<br />
in[0] = sf_input("in");<br />
nin=1;<br />
}<br />
</c><br />
<br />
Everything on the command line that does not contain a "=" sign is<br />
treated as a file name, and the corresponding file object is added to the list.<br />
<c><br />
for (i=1; i< argc; i++) { /* collect inputs */<br />
if (NULL != strchr(argv[i],'=')) <br />
continue; /* not a file */<br />
in[nin] = sf_input(argv[i]);<br />
nin++;<br />
}<br />
if (0==nin) sf_error ("no input");<br />
</c><br />
<br />
As explained above, if the <tt>space=</tt> parameter is not set, it is<br />
inferred from the program name: <tt>sfmerge</tt> corresponds to<br />
<tt>space=y</tt> and <tt>sfcat</tt> corresponds to <tt>space=n</tt>.<br />
<c><br />
if (!sf_getbool("space",&space)) {<br />
/* Insert additional space.<br />
y is default for sfmerge, n is default for sfcat */<br />
prog = sf_getprog();<br />
if (NULL != strstr (prog, "merge")) {<br />
space = true;<br />
} else if (NULL != strstr (prog, "cat")) {<br />
space = false;<br />
} else {<br />
sf_warning("%s is neither merge nor cat,"<br />
" assume merge",prog);<br />
space = true;<br />
}<br />
}<br />
</c><br />
<br />
Find the axis for the merging (from the command line <tt>axis=</tt><br />
argument) and figure out two sizes: <tt>n1</tt> for everything after<br />
the axis and <tt>n2</tt> for everything before the axis.<br />
<c><br />
n1=1;<br />
n2=1;<br />
for (i=1; i <= dim; i++) {<br />
if (i < axis) n1 *= n[i-1];<br />
else if (i > axis) n2 *= n[i-1];<br />
}<br />
</c><br />
<br />
In the output, the selected axis will get extended.<br />
<c><br />
/* figure out the length of extended axis */<br />
ni = 0;<br />
for (j=0; j < nin; j++) {<br />
ni += naxis[j];<br />
}<br />
<br />
if (space) {<br />
if (!sf_getint("nspace",&nspace)) <br />
nspace = (int) (ni/(20*nin) + 1);<br />
/* if space=y, number of traces to insert */ <br />
ni += nspace*(nin-1);<br />
} <br />
<br />
(void) snprintf(key,3,"n%d",axis);<br />
sf_putint(out,key,(int) ni);<br />
</c><br />
<br />
The rest is simple: loop through the datasets reading and writing the<br />
data in buffer-size chunks and adding extra empty chunks if<br />
<tt>space=y</tt>.<br />
<c><br />
for (i2=0; i2 < n2; i2++) {<br />
for (j=0; j < nin; j++) {<br />
for (ni = n1*naxis[j]*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charread (buf,nbuf,in[j]);<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
if (!space || j == nin-1) continue;<br />
/* Add spaces */<br />
memset(buf,0,BUFSIZ);<br />
for (ni = n1*nspace*esize; ni > 0; ni -= nbuf) {<br />
nbuf = (BUFSIZ < ni)? BUFSIZ: ni;<br />
sf_charwrite (buf,nbuf,out);<br />
}<br />
}<br />
}<br />
</c><br />
<br />
==sfcmplx==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a complex dataset from its real and imaginary parts.<br />
|-<br />
! colspan="4" | sfcmplx > cmplx.rsf real.rsf imag.rsf<br />
|-<br />
| colspan="4" | There has to be only two input files specified and no additional parameters.<br />
|}<br />
<br />
<br />
<tt>sfcmplx</tt> simply creates a complex dataset from its real and<br />
imaginary parts. The reverse operation can be accomplished with<br />
<tt>sfreal</tt> and <tt>sfimag</tt>.<br />
Example of <tt>sfcmplx</tt>:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcmplx one.rsf one.rsf > cmplx.rsf<br />
bash$ sfin cmplx.rsf<br />
cmplx.rsf:<br />
in="/tmp/cmplx.rsf@"<br />
esize=8 type=complex form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 48 bytes<br />
</pre><br />
<br />
====Implementation: [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/user/main/cmplx.c?view=markup user/main/cmplx.c]====<br />
The program flow is simple. First, get the names of the input files.<br />
<c><br />
/* the first two non-parameters are real and imaginary files */<br />
for (i=1; i< argc; i++) { <br />
if (NULL == strchr(argv[i],'=')) {<br />
if (NULL == real) {<br />
real = sf_input (argv[i]);<br />
} else {<br />
imag = sf_input (argv[i]);<br />
break;<br />
}<br />
}<br />
}<br />
if (NULL == imag) {<br />
if (NULL == real) sf_error ("not enough input");<br />
/* if only one input, real is in stdin */<br />
imag = real;<br />
real = sf_input("in");<br />
}<br />
</c><br />
<br />
The main part of the program reads the real and imaginary parts buffer by buffer and assembles and writes out the complex input. <br />
<c><br />
for (nleft= (size_t) (rsize*resize); nleft > 0; nleft -= nbuf) {<br />
nbuf = (BUFSIZ < nleft)? BUFSIZ: nleft;<br />
sf_charread(rbuf,nbuf,real);<br />
sf_charread(ibuf,nbuf,imag);<br />
for (i=0; i < nbuf; i += resize) {<br />
memcpy(cbuf+2*i, rbuf+i,(size_t) resize);<br />
memcpy(cbuf+2*i+resize,ibuf+i,(size_t) resize);<br />
}<br />
sf_charwrite(cbuf,2*nbuf,cmplx);<br />
}<br />
</c><br />
<br />
==sfconjgrad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic conjugate-gradient solver for linear inversion <br />
|-<br />
! colspan="4" | sfconjgrad < dat.rsf mod=mod.rsf > to.rsf < from.rsf > out.rsf niter=1<br />
|-<br />
| ''int '' || '''niter=1''' || || number of iterations<br />
|}<br />
<br />
<br />
<tt>sfconjgrad</tt> is a generic program for least-squares linear<br />
inversion with the conjugate-gradient method. Suppose you have an<br />
executable program <tt><prog></tt> that takes an RSF file from the<br />
standard input and produces an RSF file in the standard output. It may<br />
take any number of additional parameters but one of them must be<br />
<tt>adj=</tt> that sets the forward (<tt>adj=0</tt>) or adjoint<br />
(<tt>adj=1</tt>) operations. The program <tt><prog></tt> is typically<br />
an RSF program but it could be anything (a script, a multiprocessor<br />
MPI program, etc.) as long as it implements a linear operator<br />
<math>\mathbf{L}</math> and its adjoint. There are no restrictions on the data<br />
size or shape. You can easily test the adjointness with<br />
<tt>sfdottest</tt>. The <tt>sfconjgrad</tt> program searches for a<br />
vector <math>\mathbf{m}</math> that minimizes the least-square misfit <br />
<math>\|\mathbf{d - L\,m}\|^2</math> for the given input data vector <math>\mathbf{d}</math>.<br />
Here is an example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
The <tt>sfdottest</tt> program can perform the dot product test to<br />
check that the adjoint mode works correctly.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=5.28394<br />
sfdottest: L'[d]*m=5.28394<br />
</pre><br />
Your numbers may be different because <tt>sfdottest</tt> generates new<br />
random input on each run.<br />
Next, let us make some random data with <tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfnoise seed=2005 rep=y < vec.rsf > dat.rsf<br />
</pre><br />
and try to invert the filtering operation using <tt>sfconjgrad</tt>:<br />
<pre><br />
bash$ sfconjgrad sfhelicon filt=flt.rsf lag=lag.rsf \<br />
mod=vec.rsf < dat.rsf > mod.rsf niter=10<br />
sfconjgrad: iter 1 of 10<br />
sfconjgrad: grad=3253.65<br />
sfconjgrad: iter 2 of 10<br />
sfconjgrad: grad=289.421<br />
sfconjgrad: iter 3 of 10<br />
sfconjgrad: grad=92.3481<br />
sfconjgrad: iter 4 of 10<br />
sfconjgrad: grad=36.9417<br />
sfconjgrad: iter 5 of 10<br />
sfconjgrad: grad=18.7228<br />
sfconjgrad: iter 6 of 10<br />
sfconjgrad: grad=11.1794<br />
sfconjgrad: iter 7 of 10<br />
sfconjgrad: grad=7.26941<br />
sfconjgrad: iter 8 of 10<br />
sfconjgrad: grad=5.15945<br />
sfconjgrad: iter 9 of 10<br />
sfconjgrad: grad=4.23055<br />
sfconjgrad: iter 10 of 10<br />
sfconjgrad: grad=3.57495<br />
</pre><br />
The output shows that, in 10 iterations, the norm of the gradient vector decreases by almost 1000. <br />
We can check the residual misfit before<br />
<pre><br />
bash$ < dat.rsf sfattr want=norm<br />
norm value = 49.7801<br />
</pre><br />
and after<br />
<pre><br />
bash$ sfhelicon filt=flt.rsf lag=lag.rsf < mod.rsf | \<br />
sfadd scale=1,-1 dat.rsf | sfattr want=norm<br />
norm value = 5.73563<br />
</pre><br />
In 10 iterations, the misfit decreased by an order of magnitude. The<br />
result can be improved by running the program for more iterations.<br />
<br />
==sfcp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Copy or move a dataset.<br />
|-<br />
! colspan="4" | sfcp in.rsf out.rsf<br />
|-<br />
| colspan="4" | sfcp - copy, sfmv - move.<br>Mimics standard Unix commands.<br />
|}<br />
<br />
<br />
The <tt>sfcp</tt> and <tt>sfmv</tt> command imitate the Unix<br />
<tt>cp</tt> and <tt>mv</tt> commands and serve for copying and moving<br />
RSF files. Example:<br />
<pre><br />
bash$ sfspike n1=2 n2=3 > one.rsf<br />
bash$ sfin one.rsf<br />
one.rsf:<br />
in="/tmp/one.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
bash$ sfcp one.rsf two.rsf<br />
bash$ sfin two.rsf<br />
two.rsf:<br />
in="/tmp/two.rsf@"<br />
esize=4 type=float form=native<br />
n1=2 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=3 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
6 elements 24 bytes<br />
</pre><br />
<br />
==sfcut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of the dataset. <br />
|-<br />
! colspan="4" | sfcut < in.rsf > out.rsf verb=n [j1=1 j2=1 ... f1=0 f2=0 ... n1=n1 n2=n2 ... max1= max2= ... min1= min2= ...]<br />
|-<br />
| colspan="4" | jN defines the jump in N-th dimension<br>fN is the window start<br>nN is the window size<br>minN and maxN is the maximum and minimum in N-th dimension<br><br>Reverse of window. <br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
The <tt>sfcut</tt> command is related to <tt>sfwindow</tt> and has the same<br />
set of arguments only instead of extracting the selected window, it fills it<br />
with zeroes. The size of the input data is preserved. <br />
Examples:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > in.rsf<br />
bash$ < in.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < in.rsf sfcut n1=2 f1=1 n2=3 f2=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 0 0 1 1<br />
15: 1 0 0 1 1<br />
20: 1 0 0 1 1<br />
bash$ < in.rsf sfcut j1=2 | sfdisfil<br />
0: 0 1 0 1 0<br />
5: 0 1 0 1 0<br />
10: 0 1 0 1 0<br />
15: 0 1 0 1 0<br />
20: 0 1 0 1 0<br />
</pre><br />
<br />
==sfdd==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert between different formats. <br />
|-<br />
! colspan="4" | sfdd < in.rsf > out.rsf line=8 form= type= format=<br />
|-<br />
| ''string '' || '''form=''' || || ascii, native, xdr<br />
|-<br />
| ''string '' || '''format=''' || || Element format (for conversion to ASCII)<br />
|-<br />
| ''int '' || '''line=8''' || || Number of numbers per line (for conversion to ASCII)<br />
|-<br />
| ''string '' || '''type=''' || || int, float, complex<br />
|}<br />
<br />
<br />
The <tt>sfdd</tt> program is used to change either the form (<tt>ascii</tt>,<br />
<tt>xdr</tt>, <tt>native</tt>) or the type (<tt>complex</tt>, <tt>float</tt>,<br />
<tt>int</tt>, <tt>char</tt>) of the input dataset. <br />
In the example below, we create a plain text (ASCII) file with numbers and<br />
then use <tt>sfdd</tt> to generate an RSF file in <tt>xdr</tt> form with<br />
<tt>complex</tt> numbers. <br />
<pre><br />
bash$ cat test.txt<br />
1 2 3 4 5 6<br />
bash$ echo n1=6 data_format=ascii_int in=test.txt > test.rsf<br />
bash$ sfin test.rsf<br />
test.rsf:<br />
in="test.txt"<br />
esize=0 type=int form=ascii<br />
n1=6 d1=? o1=?<br />
6 elements<br />
bash$ sfdd < test.rsf form=xdr type=complex > test2.rsf<br />
bash$ sfin test2.rsf<br />
test2.rsf:<br />
in="/tmp/test2.rsf@"<br />
esize=8 type=complex form=xdr<br />
n1=3 d1=? o1=?<br />
3 elements 24 bytes<br />
bash$ sfdisfil < test2.rsf<br />
0: 1, 2i 3, 4i 5, 6i<br />
</pre><br />
To learn more about the RSF data format, consult the [[Format| guide to RSF format]].<br />
<br />
==sfdisfil==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Print out data values.<br />
|-<br />
! colspan="4" | sfdisfil < in.rsf number=y col=0 format= header= trailer=<br />
|-<br />
| colspan="4" | <br>Alternatively, use sfdd and convert to ASCII form.<br />
|-<br />
| ''int '' || '''col=0''' || || Number of columns.<br />
:The default depends on the data type:<br />
:10 for int and char,<br />
:5 for float,<br />
:3 for complex<br />
|-<br />
| ''string '' || '''format=''' || || Format for numbers (printf-style).<br />
:The default depends on the data type:<br> "%4d " for int and char,<br> "%13.4g" for float,<br> "%10.4g,%10.4gi" for complex<br />
|-<br />
| ''string '' || '''header=''' || || Optional header string to output before data<br />
|-<br />
| ''bool '' || '''number=y''' || [y/n] || If number the elements<br />
|-<br />
| ''string '' || '''trailer=''' || || Optional trailer string to output after data<br />
|}<br />
<br />
<br />
The <tt>sfdisfil</tt> program simply dumps the data contents to the standard<br />
output in a text form. It is used mostly for debugging purposes to quickly<br />
examine RSF files. Here is an example:<br />
<pre><br />
bash$ sfmath o1=0 d1=2 n1=12 output=x1 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
10: 20 22<br />
</pre><br />
The output format is easily configurable.<br />
<pre><br />
bash$ < test.rsf sfdisfil col=6 number=n format="<br />
0.0 2.0 4.0 6.0 8.0 10.0<br />
12.0 14.0 16.0 18.0 20.0 22.0<br />
</pre><br />
Along with <tt>sfdd</tt>, <tt>sfdisfil</tt> provides a simple way to convert<br />
RSF data to an ASCII form.<br />
<br />
==sfdottest==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generic dot-product test for linear operators with adjoints <br />
|-<br />
! colspan="4" | sfdottest mod=mod.rsf dat=dat.rsf > pip.rsf<br />
|}<br />
<br />
<br />
<tt>sfdottest</tt> is a generic dot-product test program for testing<br />
linear operators. Suppose there is an executable program<br />
<tt><prog></tt> that takes an RSF file from the standard input and<br />
produces an RSF file in the standard output. It may take any number of<br />
additional parameters but one of them must be <tt>adj=</tt> that sets<br />
the forward (<tt>adj=0</tt>) or adjoint (<tt>adj=1</tt>) operations.<br />
The program <tt><prog></tt> is typically an RSF program but it could<br />
be anything (a script, a multiprocessor MPI program, etc.) as long as<br />
it implements a linear operator <math>\mathbf{L}</math> and its adjoint<br />
<math>\mathbf{L}^T</math>. The <tt>sfdottest</tt> program is testing the equality<br />
<center><math><br />
d^T\,L\,m = m^T\,L^T\,d<br />
</math></center><br />
by using random vectors <math>\mathbf{m}</math> and <math>\mathbf{d}</math>. You can invoke it with<br />
<pre><br />
bash$ sfdottest <prog> [optional aruments] mod=mod.rsf dat=dat.rsf<br />
</pre><br />
where <tt>mod.rsf</tt> and <tt>dat.rsf</tt> are RSF files that<br />
represent vectors from the model and data spaces. <tt>sfdottest</tt><br />
does not create any temporary files and does not have any restrictive<br />
limitations on the size of the vectors.<br />
Here is an example. We first setup a vector with 100 elements using<br />
<tt>sfspike</tt> and then run <tt>sfdottest</tt> to test the<br />
<tt>sfcausint</tt> program. <tt>sfcausint</tt> implements a linear<br />
operator of causal integration and its adjoint, the anti-causal<br />
integration.<br />
<pre><br />
bash$ sfspike n1=100 > vec.rsf<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1410.2<br />
sfdottest: L'[d]*m=1410.2<br />
bash$ sfdottest sfcausint mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=1165.87<br />
sfdottest: L'[d]*m=1165.87<br />
</pre><br />
The numbers are different on subsequent runs because of changing<br />
seed in the random number generator.<br />
Here is a somewhat more complicated example. The <tt>sfhelicon</tt><br />
program implements Claerbout's multidimensional helical filtering<br />
(Claerbout, 1998<ref>Claerbout, J., 1998, Multidimensional recursive filters via a helix: Geophysics, '''63''', 1532--1541.</ref>). It requires a filter to be specified in<br />
addition to the input and output vectors. We create a helical <br />
2-D filter using the Unix <tt>echo</tt> command.<br />
<pre><br />
bash$ echo 1 19 20 n1=3 n=20,20 data_format=ascii_int in=lag.rsf > lag.rsf<br />
bash$ echo 1 1 1 a0=-3 n1=3 data_format=ascii_float in=flt.rsf > flt.rsf<br />
</pre><br />
Next, we create an example 2-D model and data vector with <tt>sfspike</tt>.<br />
<pre><br />
bash$ sfspike n1=50 n2=50 > vec.rsf<br />
</pre><br />
Now the <tt>sfdottest</tt> program can perform the dot product test.<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf<br />
sfdottest: L[m]*d=8.97375<br />
sfdottest: L'[d]*m=8.97375<br />
</pre><br />
Here is the same program tested in the inverse filtering mode:<br />
<pre><br />
bash$ sfdottest sfhelicon filt=flt.rsf lag=lag.rsf \<br />
> mod=vec.rsf dat=vec.rsf inv=y<br />
sfdottest: L[m]*d=15.0222<br />
sfdottest: L'[d]*m=15.0222<br />
</pre><br />
<br />
==sfget==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Output parameters from the header.<br />
|-<br />
! colspan="4" | sfget < in.rsf parform=y par1 par2 ...<br />
|-<br />
| ''bool '' || '''parform=y''' || [y/n] || If y, print out parameter=value. If n, print out value.<br />
|}<br />
<br />
<br />
The <tt>sfget</tt> program extracts a parameter value from an RSF file. It is<br />
useful mostly for scripting. Here is, for example, a quick calculation of the<br />
maximum value on the first axis in an RSF dataset (the output of<br />
<tt>sfspike</tt>) using the standard Unix <tt>bc</tt> calculator.<br />
<pre><br />
bash$ ( sfspike n1=100 | sfget n1 d1 o1; echo "o1+(n1-1)*d1" ) | bc<br />
.396<br />
</pre><br />
See also <tt>sfput</tt>.<br />
<br />
<br />
<br />
==sfheadercut==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Zero a portion of a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheadercut mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array of size n2.<br />
|}<br />
<br />
<br />
<tt>sfheadercut</tt> is close to <tt>sfheaderwindow</tt> but instead<br />
of windowing the dataset, it fills the traces specified by the header<br />
mask with zeroes. The size of the input data is preserved.<br />
Here is an example of using <tt>sfheaderwindow</tt> for <br />
zeroing every other trace in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a mask with alternating ones and zeros using<br />
<tt>sfinterleave</tt>.<br />
<pre><br />
bash$ sfspike n1=5 mag=1 | sfdd type=int > ones.rsf<br />
bash$ sfspike n1=5 mag=0 | sfdd type=int > zeros.rsf<br />
bash$ sfinterleave axis=1 ones.rsf zeros.rsf > mask.rsf<br />
bash$ sfdisfil < mask.rsf<br />
0: 1 0 1 0 1 0 1 0 1 0<br />
</pre><br />
Finally, <tt>sfheadercut</tt> zeros the input traces.<br />
<pre><br />
bash$ sfheadercut < input.rsf mask=mask.rsf > output.rsf<br />
bash$ sfdisfil < output.rsf <br />
0: 1 1 1 1 1<br />
5: 0 0 0 0 0<br />
10: 3 3 3 3 3<br />
15: 0 0 0 0 0<br />
20: 5 5 5 5 5<br />
25: 0 0 0 0 0<br />
30: 7 7 7 7 7<br />
35: 0 0 0 0 0<br />
40: 9 9 9 9 9<br />
45: 0 0 0 0 0<br />
</pre><br />
<br />
<br />
<br />
==sfheadersort==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Sort a dataset according to a header key. <br />
|-<br />
! colspan="4" | sfheadersort < in.rsf > out.rsf head=<br />
|-<br />
| ''string '' || '''head=''' || || header file<br />
|}<br />
<br />
<br />
<tt>sfheadersort</tt> is used to sort traces in the input file<br />
according to trace header information. <br />
Here is an example of using<br />
<tt>sfheadersort</tt> for randomly shuffling traces in the input<br />
file. First, let us create an input file with seven traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=7 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7 <br />
</pre><br />
Next, we can create a random file with seven header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=7 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: 0.05256 -0.2879 0.1487 0.4097 0.1548<br />
5: 0.4501 0.2836<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally, we<br />
apply <tt>sfheadersort</tt> to shuffle the input traces.<br />
<pre><br />
bash$ < input.rsf sfheadersort head=random.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 1 1 1 1 1<br />
10: 3 3 3 3 3<br />
15: 5 5 5 5 5<br />
20: 7 7 7 7 7<br />
25: 4 4 4 4 4<br />
30: 6 6 6 6 6<br />
</pre><br />
As expected, the order of traces in the output file corresponds to the<br />
order of values in the header. Thanks to the separation between<br />
headers and data, the operation of <tt>sfheadersort</tt> is optimally<br />
efficient. It first sorts the headers and only then accesses the data,<br />
reading each data trace only once.<br />
<br />
==sfheaderwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a dataset based on a header mask.<br />
|-<br />
! colspan="4" | sfheaderwindow mask=head.rsf < in.rsf > out.rsf<br />
|-<br />
| colspan="4" | <br>The input data is a collection of traces n1xn2,<br>mask is an integer array os size n2, windowed is n1xm2,<br>where m2 is the number of nonzero elements in mask.<br />
|}<br />
<br />
<br />
<tt>sfheaderwindow</tt> is used to window traces in the input file<br />
according to trace header information. <br />
Here is an example of using <tt>sfheaderwindow</tt> for randomly<br />
selecting part of the traces in the input file. First, let us create<br />
an input file with ten traces:<br />
<pre><br />
bash$ sfmath n1=5 n2=10 output=x2+1 > input.rsf<br />
bash$ < input.rsf sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 3 3 3 3 3<br />
15: 4 4 4 4 4<br />
20: 5 5 5 5 5<br />
25: 6 6 6 6 6<br />
30: 7 7 7 7 7<br />
35: 8 8 8 8 8<br />
40: 9 9 9 9 9<br />
45: 10 10 10 10 10<br />
</pre><br />
Next, we can create a random file with ten header values using<br />
<tt>sfnoise</tt>.<br />
<pre><br />
bash$ sfspike n1=10 | sfnoise rep=y type=n > random.rsf<br />
bash$ < random.rsf sfdisfil<br />
0: -0.005768 0.02258 -0.04331 -0.4129 -0.3909<br />
5: -0.03582 0.4595 -0.3326 0.498 -0.3517<br />
</pre><br />
If you reproduce this example, your numbers will most likely be different,<br />
because, in the absence of <tt>seed=</tt> parameter, <tt>sfnoise</tt><br />
uses a random seed value to generate pseudo-random numbers. Finally,<br />
we apply <tt>sfheaderwindow</tt> to window the input traces selecting<br />
only those for which the header is greater than zero.<br />
<pre><br />
bash$ < random.rsf sfmask min=0 > mask.rsf<br />
bash$ < mask.rsf sfdisfil<br />
0: 0 1 0 0 0 0 1 0 1 0<br />
bash$ < input.rsf sfheaderwindow mask=mask.rsf > output.rsf<br />
bash$ < output.rsf sfdisfil<br />
0: 2 2 2 2 2<br />
5: 7 7 7 7 7<br />
10: 9 9 9 9 9<br />
</pre><br />
In this case, only three traces are selected for the output. Thanks to<br />
the separation between headers and data, the operation of<br />
<tt>sfheaderwindow</tt> is optimally efficient. <br />
<br />
==sfin==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Display basic information about RSF files.<br />
|-<br />
! colspan="4" | sfin info=y check=2. trail=y file1.rsf file2.rsf ...<br />
|-<br />
| colspan="4" | n1,n2,... are data dimensions<br>o1,o2,... are axis origins<br>d1,d2,... are axis sampling intervals<br>label1,label2,... are axis labels<br>unit1,unit2,... are axis units<br />
|-<br />
| ''float '' || '''check=2.''' || || Portion of the data (in Mb) to check for zero values.<br />
|-<br />
| ''bool '' || '''info=y''' || [y/n] || If n, only display the name of the data file.<br />
|-<br />
| ''bool '' || '''trail=y''' || [y/n] || If n, skip trailing dimensions of one<br />
|}<br />
<br />
<br />
<tt>sfin</tt> is one of the most useful programs for operating with<br />
RSF files. It produces quick information on the file hypercube<br />
dimensions and checks the consistency of the associated data file.<br />
Here is an example. Let us create an RSF file and examine it with <tt>sfin</tt>.<br />
<pre><br />
bash$ sfspike n1=100 n2=20 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=100 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
2000 elements 8000 bytes<br />
</pre><br />
<tt>sfin</tt> reports the following information:<br />
<br />
*location of the data file (<tt>/tmp/spike.rsf\@</tt>) <br />
*element size (4 bytes) <br />
*element type (floating point) <br />
*element form (native) <br />
*hypercube dimensions (100 by 20) <br />
*axes scale (0.004 and 0.1) <br />
*axes origin (0 and 0) <br />
*axes labels <br />
*axes units <br />
*total number of elements <br />
*total number of bytes in the data file <br />
Suppose that the file got corrupted by a buggy program and reports<br />
incorrect dimensions. The <tt>sfin</tt> program should be able to<br />
catch the discrepancy.<br />
<pre><br />
bash$ echo n2=100 >> spike.rsf<br />
bash$ sfin spike.rsf > /dev/null<br />
sfin: Actually 8000 bytes, 20% of expected.<br />
</pre><br />
<tt>sfin</tt> also checks the first records in the file for zeros. <br />
<pre><br />
bash$ sfspike n1=100 n2=100 k2=99 > spike2.rsf<br />
bash$ sfin spike2.rsf >/dev/null<br />
sfin: The first 32768 bytes are all zeros<br />
</pre><br />
The number of bytes to check is adjustable<br />
<pre><br />
bash$ sfin spike2.rsf check=0.01 >/dev/null<br />
sfin: The first 16384 bytes are all zeros<br />
</pre><br />
You can also output only the location of the data file. This is<br />
sometimes handy in scripts.<br />
<pre><br />
bash$ sfin spike.rsf spike2.rsf info=n<br />
/tmp/spike.rsf@ /tmp/spike2.rsf@<br />
</pre><br />
An alternative is to use <tt>sfget</tt>, as follows:<br />
<pre><br />
bash$ sfget parform=n in < spike.rsf<br />
/tmp/spike.rsf@<br />
</pre><br />
<br />
==sfinterleave==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Combine several datasets by interleaving.<br />
|-<br />
! colspan="4" | sfinterleave > out.rsf axis=3 [< file0.rsf] file1.rsf file2.rsf ...<br />
|-<br />
| ''int '' || '''axis=3''' || || Axis for interleaving<br />
|}<br />
<br />
<br />
<tt>sfinterleave</tt> combines two or more datasets by interleaving them on one<br />
of the axes. Here is a quick example:<br />
<pre><br />
bash$ sfspike n1=5 n2=5 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ sfscale < one.rsf dscale=2 > two.rsf<br />
bash$ sfdisfil < two.rsf<br />
0: 2 2 2 2 2<br />
5: 2 2 2 2 2<br />
10: 2 2 2 2 2<br />
15: 2 2 2 2 2<br />
20: 2 2 2 2 2<br />
bash$ sfinterleave one.rsf two.rsf axis=1 | sfdisfil<br />
0: 1 2 1 2 1<br />
5: 2 1 2 1 2<br />
10: 1 2 1 2 1<br />
15: 2 1 2 1 2<br />
20: 1 2 1 2 1<br />
25: 2 1 2 1 2<br />
30: 1 2 1 2 1<br />
35: 2 1 2 1 2<br />
40: 1 2 1 2 1<br />
45: 2 1 2 1 2<br />
bash$ sfinterleave < one.rsf two.rsf axis=2 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 2 2 2 2 2<br />
10: 1 1 1 1 1<br />
15: 2 2 2 2 2<br />
20: 1 1 1 1 1<br />
25: 2 2 2 2 2<br />
30: 1 1 1 1 1<br />
35: 2 2 2 2 2<br />
40: 1 1 1 1 1<br />
45: 2 2 2 2 2<br />
</pre><br />
<br />
==sfmask==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Create a mask.<br />
|-<br />
! colspan="4" | sfmask < in.rsf > out.rsf min=-FLT_MAX max=+FLT_MAX<br />
|-<br />
| colspan="4" | <br>Mask is an integer data with ones and zeros. <br>Ones correspond to input values between min and max.<br><br>The output can be used with sfheaderwindow.<br />
|-<br />
| ''float '' || '''max=+FLT_MAX''' || || maximum header value<br />
|-<br />
| ''float '' || '''min=-FLT_MAX''' || || minimum header value<br />
|}<br />
<br />
<br />
<tt>sfmask</tt> creates an integer output of ones and zeros comparing<br />
the values of the input data to specified <tt>min=</tt> and<br />
<tt>max=</tt> parameters. It is useful for <tt>sfheaderwindow</tt> and<br />
in many other applications. Here is a quick example:<br />
<pre><br />
bash$ sfmath n1=10 output="sin(x1)" > sin.rsf<br />
bash$ < sin.rsf sfdisfil<br />
0: 0 0.8415 0.9093 0.1411 -0.7568<br />
5: -0.9589 -0.2794 0.657 0.9894 0.4121<br />
bash$ < sin.rsf sfmask min=-0.5 max=0.5 | sfdisfil<br />
0: 1 0 0 1 0 0 1 0 0 1<br />
</pre><br />
<br />
==sfmath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations on data files.<br />
|-<br />
! colspan="4" | sfmath > out.rsf type= unit= output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs, conj (for complex data).<br> <br>sfmath will work on float or complex data, but all the input and output<br>files must be of the same data type.<br><br>An alternative to sfmath is sfadd, which may be more efficient, but is<br>less versatile.<br><br>Examples:<br><br>sfmath x=file1.rsf y=file2.rsf power=file3.rsf output='sin((x+2*y)^power)' > out.rsf<br>sfmath < file1.rsf tau=file2.rsf output='exp(tau*input)' > out.rsf<br>sfmath n1=100 type=complex output="exp(I*x1)" > out.rsf<br><br>See also: sfheadermath.<br />
|-<br />
| ''string '' || '''output=''' || || Mathematical description of the output<br />
|-<br />
| ''string '' || '''type=''' || || output data type [float,complex]<br />
|-<br />
| ''string '' || '''unit=''' || || <br />
|}<br />
<br />
<tt>sfmath</tt> is a versatile program for mathematical operations<br />
with RSF files. It can operate with several input file, all of the<br />
same dimensions and data type. The data type can be real (floating<br />
point) or complex. Here is an example that demonstrates several<br />
features of <tt>sfmath</tt>.<br />
<pre><br />
bash$ sfmath n1=629 d1=0.01 o1=0 n2=40 d2=1 o2=5 \<br />
output="x2*(8+sin(6*x1+x2/10))" > rad.rsf<br />
bash$ < rad.rsf sfrtoc | sfmath output="input*exp(I*x1)" > rose.rsf<br />
bash$ < rose.rsf sfgraph title=Rose screenratio=1 wantaxis=n | xtpen<br />
</pre><br />
The first line creates a 2-D dataset that consists of 40 traces 600<br />
samples each. The values of the data are computed with the formula<br />
<font color="#cd4b19">"x2*(8+sin(6*x1+x2/10))"</font>, where <tt>x1</tt> refers to the<br />
coordinate on the first axis, and <tt>x2</tt> is the coordinate of the<br />
second axis. In the second line, we convert the data from real to<br />
complex using <tt>sfrtoc</tt> and produce a complex dataset using<br />
formula <font color="#cd4b19">"input*exp(I*x1)"</font>, where <tt>input</tt> refers to the<br />
input file. Finally, we plot the complex data as a collection of<br />
parametric curves using <tt>sfgraph</tt> and display the result using<br />
<tt>xtpen</tt>. The plot appearing on your screen should look similar<br />
to the figure.<br />
[[Image:rose.png|frame|center|This figure was created with <tt>sfmath</tt>.]]<br />
One possible alternative to the second line above is<br />
<pre><br />
bash$ < rad.rsf sfmath output=x1 > ang.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*cos(a)" > cos.rsf<br />
bash$ sfmath r=rad.rsf a=ang.rsf output="r*sin(a)" > sin.rsf<br />
bash$ sfcmplx cos.rsf sin.rsf > rose.rsf<br />
</pre><br />
Here we refer to input files by names (<tt>r</tt> and <tt>a</tt>) and combine the names in a formula.<br />
<br />
==sfpad==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Pad a dataset with zeros.<br />
|-<br />
! colspan="4" | sfpad < in.rsf > out.rsf [beg1= beg2= ... end1= end2=... | n1= n2 = ... | n1out= n2out= ...]<br />
|-<br />
| colspan="4" | begN specifies the number of zeros to add before the beginning of axis N.<br>endN specifies the number of zeros to add after the end of axis N.<br><br>Alternatively:<br><br>nN or nNout specify the output length of axis N, padding occurs at the end.<br>nN and nNout are equivalent.<br />
|}<br />
<br />
<br />
<tt>pad</tt> increases the dimensions of the input dataset by padding<br />
the data with zeroes. Here are some simple examples.<br />
<pre><br />
bash$ sfspike n1=5 n2=3 > one.rsf<br />
bash$ sfdisfil < one.rsf<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
bash$ < one.rsf sfpad n2=5 | sfdisfil<br />
0: 1 1 1 1 1<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 0 0 0 0 0<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfpad beg2=2 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 0 0 0 0<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 1 1 1 1 1<br />
bash$ < one.rsf sfpad beg2=1 end2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 1 1 1 1 1<br />
10: 1 1 1 1 1<br />
15: 1 1 1 1 1<br />
20: 0 0 0 0 0<br />
bash$ < one.rsf sfwindow n1=3 | sfpad n1=5 n2=5 beg1=1 beg2=1 | sfdisfil<br />
0: 0 0 0 0 0<br />
5: 0 1 1 1 0<br />
10: 0 1 1 1 0<br />
15: 0 1 1 1 0<br />
20: 0 0 0 0 0<br />
</pre><br />
You can use <tt>sfcat</tt> to pad data with values other than zeroes.<br />
<br />
==sfput==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Input parameters into a header. <br />
|-<br />
! colspan="4" | sfput < in.rsf > out.rsf<br />
|}<br />
<br />
<br />
<tt>sfput</tt> is a very simple program. It simply appends parameters<br />
from the command line to the output RSF file. One can achieve similar<br />
results with editing by hand or with standard Unix utilities like<br />
<tt>sed</tt> and <tt>echo</tt>. <tt>sfput</tt> is sometimes more<br />
convenient because it handles input/output operations similarly to<br />
other regular RSF programs.<br />
<pre><br />
bash$ sfspike n1=10 > spike.rsf<br />
bash$ sfin spike.rsf<br />
spike.rsf:<br />
in="/tmp/spike.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
10 elements 40 bytes<br />
bash$ sfput < spike.rsf d1=25 label1=Depth unit1=m > spike2.rsf<br />
bash$ sfin spike2.rsf<br />
spike2.rsf:<br />
in="/tmp/spike2.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=25 o1=0 label1="Depth" unit1="m"<br />
10 elements 40 bytes<br />
</pre><br />
<br />
==sfreal==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extract real (sfreal) or imaginary (sfimag) part of a complex dataset. <br />
|-<br />
! colspan="4" | sfreal < cmplx.rsf > real.rsf<br />
|}<br />
<br />
<br />
<tt>sfreal</tt> extracts the real part of a complex type dataset. The<br />
imaginary part can be extracted with <tt>sfimag</tt>, an the real<br />
and imaginary part can be combined together with <tt>sfcmplx</tt>.<br />
Here is a simple example. Let us first create a complex dataset <br />
with <tt>sfmath</tt><br />
<pre><br />
bash$ sfmath n1=10 type=complex output="(2+I)*x1" > cmplx.rsf<br />
bash$ fdisfil < cmplx.rsf<br />
0: 0, 0i 2, 1i 4, 2i<br />
3: 6, 3i 8, 4i 10, 5i<br />
6: 12, 6i 14, 7i 16, 8i<br />
9: 18, 9i<br />
</pre><br />
Extracting the real part with <tt>sfreal</tt>:<br />
<pre><br />
bash$ sfreal < cmplx.rsf | sfdisfil<br />
0: 0 2 4 6 8<br />
5: 10 12 14 16 18<br />
</pre><br />
Extracting the imaginary part with <tt>sfimag</tt>:<br />
<pre><br />
bash$ sfimag < cmplx.rsf | sfdisfil<br />
0: 0 1 2 3 4<br />
5: 5 6 7 8 9<br />
</pre><br />
<br />
==sfreverse==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Reverse one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfreverse < in.rsf > out.rsf which=-1 verb=false memsize=sf_memsize() opt=<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''opt=''' || || If y, change o and d parameters on the reversed axis;<br />
:if i, don't change o and d<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|-<br />
| ''int '' || '''which=-1''' || || Which axis to reverse.<br />
:To reverse a given axis, start with 0,<br />
:add 1 to number to reverse n1 dimension,<br />
:add 2 to number to reverse n2 dimension,<br />
:add 4 to number to reverse n3 dimension, etc.<br />
:Thus, which=7 would reverse the first three dimensions,<br />
:which=5 just n1 and n3, etc.<br />
:which=0 will just pass the input on through unchanged.<br />
|}<br />
Here is an example of using <tt>sfreverse</tt>. First, let us create a<br />
2-D dataset.<br />
<pre><br />
bash$ sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash$ < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Reversing the first axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 | sfdisfil<br />
0: 4 3 2 1 0<br />
5: 5 4 3 2 1<br />
10: 6 5 4 3 2<br />
</pre><br />
Reversing the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=2 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
Reversing both the first and the second axis:<br />
<pre><br />
bash$ < test.rsf sfreverse which=3 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
</pre><br />
As you can see, the <tt>which=</tt> parameter controls the axes that are<br />
being reversed by encoding them into one number.<br />
When an axis is reversed, what happens with its axis origin and<br />
sampling parameters? This behavior is controlled by <tt>opt=</tt>. In<br />
our example,<br />
<pre><br />
bash$ < test.rsf sfget n1 o1 d1<br />
n1=5<br />
o1=0<br />
d1=1<br />
bash$ < test.rsf sfreverse which=1 | sfget o1 d1<br />
o1=4<br />
d1=-1<br />
</pre><br />
The default behavior (equivalent to <tt>opt=y</tt>) puts the origin<br />
<tt>o1</tt> at the end of the axis and reverses the sampling parameter<br />
<tt>d1</tt>. Using <tt>opt=n</tt> preserves the sampling but reverses<br />
the origin.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=n | sfget o1 d1<br />
o1=-4<br />
d1=1<br />
</pre><br />
Using <tt>opt=i</tt> preserves both the sampling and the origin while<br />
reversing the axis.<br />
<pre><br />
bash$ < test.rsf sfreverse which=1 opt=i | sfget o1 d1<br />
o1=0<br />
d1=1<br />
</pre><br />
One of the three possible behaviors may be desirable depending on the<br />
application.<br />
<br />
==sfrm==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Remove RSF files together with their data.<br />
|-<br />
! colspan="4" | sfrm file1.rsf [file2.rsf ...] [-i] [-v] [-f] <br />
|-<br />
| colspan="4" | Mimics the standard Unix rm command.<br><br>See also: sfmv, sfcp.<br />
|}<br />
<br />
<tt>sfrm</tt> is a program for removing RSF files. Its arguments mimic<br />
the arguments of the standard Unix <tt>rm</tt> utility: <tt>-v</tt><br />
for verbosity, <tt>-i</tt> for interactive inquiry, <tt>-f</tt> for<br />
force removal of suspicious files. Unlike the Unix <tt>rm</tt>,<br />
<tt>sfrm</tt> removes both the RSF header files and the binary files<br />
that the headers point to. <br />
Example:<br />
<pre><br />
bash&#36; sfspike n1=10 > spike.rsf datapath=./<br />
bash&#36; sfget in < spike.rsf<br />
in=./spike.rsf@<br />
bash&#36; ls spike*<br />
spike.rsf spike.rsf@<br />
bash&#36; sfrm -v spike.rsf<br />
sfrm: sf_rm: Removing header spike.rsf<br />
sfrm: sf_rm: Removing data ./spike.rsf@<br />
bash&#36; ls spike*<br />
ls: No match.<br />
</pre><br />
==sfrotate==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Rotate a portion of one or more axes in the data hypercube. <br />
|-<br />
! colspan="4" | sfrotate < in.rsf > out.rsf verb=n memsize=sf_memsize() rot#=(0,0,...)<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''rot#=(0,0,...)''' || || length of #-th axis that is moved to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<tt>sfrotate</tt> modifies the input dataset by splitting it into<br />
parts and putting the parts back in a different order. Here is a quick example.<br />
<pre><br />
bash&#36; sfmath n1=5 d1=1 n2=3 d2=1 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
</pre><br />
Rotating the first axis by putting the last two columns in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=2 | sfdisfil<br />
0: 3 4 0 1 2<br />
5: 4 5 1 2 3<br />
10: 5 6 2 3 4<br />
</pre><br />
Rotating the second axis by putting the last row in front:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot2=1 | sfdisfil<br />
0: 2 3 4 5 6<br />
5: 0 1 2 3 4<br />
10: 1 2 3 4 5<br />
</pre><br />
Rotating both the first and the second axis:<br />
<pre><br />
bash&#36; < test.rsf sfrotate rot1=3 rot2=1 | sfdisfil<br />
0: 4 5 6 2 3<br />
5: 2 3 4 0 1<br />
10: 3 4 5 1 2<br />
</pre><br />
The transformation is shown schematically in Figure~(fig:rotate).<br />
[[Image:rotate.png|frame|center|Schematic transformation of data with <tt>sfrotate</tt>.]]<br />
<br />
==sfrtoc==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert real data to complex (by adding zero imaginary part).<br />
|-<br />
! colspan="4" | sfrtoc < real.rsf > cmplx.rsf<br />
|-<br />
| colspan="4" | <br>See also: sfcmplx<br />
|}<br />
The input to <tt>sfrtoc</tt> can be any <tt>type=float</tt> dataset:<br />
<pre><br />
bash$ sfspike n1=10 n2=20 n3=30 >real.rsf<br />
bash$ sfin real.rsf<br />
real.rsf:<br />
in="/var/tmp/real.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
</pre><br />
The output dataset will have <tt>type=complex</tt>, and its binary will be twice the size of the input:<br />
<pre><br />
bash$ <real.rsf sfrtoc >complex.rsf<br />
bash$ sfin complex.rsf <br />
complex.rsf:<br />
in="/var/tmp/complex.rsf@"<br />
esize=8 type=complex form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 48000 bytes<br />
</pre><br />
<br />
==sfscale==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Scale data.<br />
|-<br />
! colspan="4" | sfscale < in.rsf > out.rsf axis=0 rscale=0. dscale=1.<br />
|-<br />
| colspan="4" | <br>To scale by a constant factor, you can also use sfmath or sfheadermath.<br />
|-<br />
| ''int '' || '''axis=0''' || || Scale by maximum in the dimensions up to this axis.<br />
|-<br />
| ''float '' || '''dscale=1.''' || || Scale by this factor (works if rscale=0)<br />
|-<br />
| ''float '' || '''rscale=0.''' || || Scale by this factor.<br />
|}<br />
<tt>sfscale</tt> scales the input dataset by a factor. Here<br />
are some simple examples. First, let us create a test dataset.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil <br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Scale every data point by 2:<br />
<pre><br />
bash&#36; < test.rsf sfscale dscale=2 | sfdisfil<br />
0: 2 4 6 8 10<br />
5: 4 8 12 16 20<br />
10: 6 12 18 24 30<br />
</pre><br />
Divide every trace by its maximum value:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=1 | sfdisfil<br />
0: 0.2 0.4 0.6 0.8 1<br />
5: 0.2 0.4 0.6 0.8 1<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
Divide by the maximum value in the whole 2-D dataset:<br />
<pre><br />
bash&#36; < test.rsf sfscale axis=2 | sfdisfil<br />
0: 0.06667 0.1333 0.2 0.2667 0.3333<br />
5: 0.1333 0.2667 0.4 0.5333 0.6667<br />
10: 0.2 0.4 0.6 0.8 1<br />
</pre><br />
The <tt>rscale=</tt> parameter is synonymous to <tt>dscale=</tt> except<br />
when it is equal to zero. With <tt>sfscale dscale=0</tt>, the dataset gets<br />
multiplied by zero. If using <tt>rscale=0</tt>, the other parameters are<br />
used to define scaling. Thus, <tt>sfscale rscale=0 axis=1</tt> is<br />
equivalent to <tt>sfscale axis=1</tt>, and <tt>sfscale rscale=0</tt><br />
is equivalent to <tt>sfscale dscale=1</tt>.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
==sfspike==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate simple data: spikes, boxes, planes, constants.<br />
|-<br />
! colspan="4" | sfspike > spike.rsf mag= nsp=1 k#=[0,...] l#=[k1,k2,...] p#=[0,...] n#= o#=(0,...) d#=(0.004,0.1,0.1,...) label#=(Time,Distance,Distance,...) unit#=[s,km,km,...] title=<br />
|-<br />
| ''float '' || '''d#=(0.004,0.1,0.1,...)''' || || sampling on #-th axis<br />
|-<br />
| ''ints '' || '''k#=[0,...]''' || || spike starting position [nsp]<br />
|-<br />
| ''ints '' || '''l#=[k1,k2,...]''' || || spike ending position [nsp]<br />
|-<br />
| ''string '' || '''label#=(Time,Distance,Distance,...)''' || || label on #-th axis<br />
|-<br />
| ''floats '' || '''mag=''' || || spike magnitudes [nsp]<br />
|-<br />
| ''int '' || '''n#=''' || || dimension of #-th axis<br />
|-<br />
| ''int '' || '''nsp=1''' || || Number of spikes<br />
|-<br />
| ''float '' || '''o#=(0,...)''' || || origin on #-th axis<br />
|-<br />
| ''floats '' || '''p#=[0,...]''' || || spike inclination (in samples) [nsp]<br />
|-<br />
| ''string '' || '''title=''' || || title for plots<br />
|-<br />
| ''string '' || '''unit#=[s,km,km,...]''' || || unit on #-th axis<br />
|}<br />
This is the program for creating a RSF hypercube out of nothing. Calling <tt>sfspike</tt> without specifying the k# or l# parameters will result in a volume filled with values specified by <tt>mag</tt>. To get a file full of 1's, just give <tt>sfspike</tt> the axis values that running <tt>sfin</tt> on your desired output would produce. I.e. if you run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" > out.rsf<br />
</pre><br />
you will obtain the following file:<br />
<pre><br />
bash$ sfin out.rsf<br />
out.rsf:<br />
in="/var/tmp/out.rsf@"<br />
esize=4 type=float form=native<br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s"<br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km"<br />
300 elements 1200 bytes<br />
</pre><br />
To create a "flat reflector" in the file above, run<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5> out2.rsf<br />
</pre><br />
Notice that the values for <tt>k</tt> and <tt>l</tt> are in samples, not in the physical units of the respective axes. The result can be visualised with <br />
<pre><br />
< out2.rsf sfgrey pclip=100 wantscalebar=y title="Illustration of k,l parameters" | xtpen<br />
</pre><br />
which produces the following plot:<br />
<br />
[[Image:sfspike_fig1.png]]<br />
<br />
The <tt>p</tt> parameters can be used to create slanted lines/planes. Specifying <tt>p2=1</tt> means that for each lateral step, the spike will be shifted down with 1 sample. Below is the command and the corresponding graphical output it creates:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=1 |\<br />
sfgrey pclip=100 wantscalebar=y title="Effect of p2=1" | xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig2.png]]<br />
<br />
Sfspike also supports negative and non-integer p values:<br />
<pre><br />
sfspike n1=10 d1=0.004 o1=0 label1="Time" unit1="s" n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" k1=4 k2=3 l2=28 mag=0.5 p2=-0.15 |\<br />
sfgrey pclip=100 wantscalebar=y allpos=y color=h title="Effect of p2=-0.15" |xtpen<br />
</pre><br />
<br />
[[Image:sfspike_fig3.png]]<br />
<br />
When <tt>nsp</tt> is greater than the number of values for <tt>k</tt> and <tt>l</tt> parameters, the extra spikes will be piled on top of the last one, increasing its amplitude. Look at the amplitude of the last event in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=3 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
and in<br />
<br />
<pre><br />
sfspike n1=240 n2=192 nsp=5 k1=80,160,240 k2=0 p2=-1.25 l2=128| sfgrey pclip=100 | xtpen<br />
</pre><br />
<br />
(pictures coming soon). This feature can easily cause a bug when the number of events is large and they have not been properly counted, or when a new spike was added on a list but <tt>nsp</tt> was not updated.<br />
<br />
==sfspray==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Extend a dataset by duplicating in the specified axis dimension.<br />
|-<br />
! colspan="4" | sfspray < in.rsf > out.rsf axis=2 n= d= o= label= unit=<br />
|-<br />
| colspan="4" | This operation is adjoint to sfstack.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to spray<br />
|-<br />
| ''float '' || '''d=''' || || Sampling of the newly created dimension<br />
|-<br />
| ''string '' || '''label=''' || || Label of the newly created dimension<br />
|-<br />
| ''int '' || '''n=''' || || Size of the newly created dimension<br />
|-<br />
| ''float '' || '''o=''' || || Origin of the newly created dimension<br />
|-<br />
| ''string '' || '''unit=''' || || Units of the newly created dimension<br />
|}<br />
<br />
<tt>sfspray</tt> extends the input hypercube by replicating the data<br />
in one of the dimensions. The output dataset acquires one additional<br />
dimension. Here is an example:<br />
Start with a 2-D dataset<br />
<pre><br />
bash&#36; sfmath n1=5 n2=2 output=x1+x2 > test.rsf<br />
bash&#36; sfin test.rsf<br />
test.rsf:<br />
in="/var/tmp/test.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
10 elements 40 bytes<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
</pre><br />
Extend the data in the second dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=2 n=3 > test2.rsf<br />
bash&#36; sfin test2.rsf<br />
test2.rsf:<br />
in="/var/tmp/test2.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=3 d2=1 o2=0 <br />
n3=2 d3=1 o3=0 <br />
30 elements 120 bytes<br />
bash&#36; < test2.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 0 1 2 3 4<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
20: 1 2 3 4 5<br />
25: 1 2 3 4 5<br />
</pre><br />
The output is three-dimensional, with traces from the original<br />
data duplicated along the second axis.<br />
Extend the data in the third dimension<br />
<pre><br />
bash&#36; < test.rsf sfspray axis=3 n=2 > test3.rsf<br />
bash&#36; sfin test3.rsf<br />
test3.rsf:<br />
in="/var/tmp/test3.rsf@"<br />
esize=4 type=float form=native <br />
n1=5 d1=1 o1=0 <br />
n2=2 d2=1 o2=0 <br />
n3=2 d3=? o3=? <br />
20 elements 80 bytes<br />
bash&#36; < test3.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 0 1 2 3 4<br />
15: 1 2 3 4 5<br />
</pre><br />
The output is also three-dimensional, with the original data replicated<br />
along the third axis.<br />
<br />
==sfstack==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stack a dataset over one of the dimensions.<br />
|-<br />
! colspan="4" | sfstack < in.rsf > out.rsf axis=2 rms=n norm=y min=n max=n<br />
|-<br />
| colspan="4" | <br>This operation is adjoint to sfspray.<br />
|-<br />
| ''int '' || '''axis=2''' || || which axis to stack<br />
|-<br />
| ''bool '' || '''max=n''' || [y/n] || If y, find maximum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''min=n''' || [y/n] || If y, find minimum instead of stack. Ignores rms and norm.<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || If y, normalize by fold.<br />
|-<br />
| ''bool '' || '''rms=n''' || [y/n] || If y, compute the root-mean-square instead of stack.<br />
|}<br />
While <tt>sfspray</tt> adds a dimension to a hypercube,<br />
<tt>sfstack</tt> effectively removes one of the dimensions by stacking<br />
over it. Here are some examples:<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 output=x1+x2 > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 0 1 2 3 4<br />
5: 1 2 3 4 5<br />
10: 2 3 4 5 6<br />
bash&#36; < test.rsf sfstack axis=2 | sfdisfil<br />
0: 1.5 2 3 4 5<br />
bash&#36; < test.rsf sfstack axis=1 | sfdisfil<br />
0: 2.5 3 4<br />
</pre><br />
Why is the first value not 1 (in the first case) or 2 (in the second<br />
case)? By default, <tt>sfstack</tt> normalizes the stack by the fold<br />
(the number of non-zero entries). To avoid normalization, use<br />
<tt>norm=n</tt>, as follows:<br />
<pre><br />
bash&#36; < test.rsf sfstack norm=n | sfdisfil <br />
0: 3 6 9 12 15<br />
</pre><br />
<tt>sfstack</tt> can also compute root-mean-square values as <br />
well as minimum and maximum values.<br />
<pre><br />
bash&#36; < test.rsf sfstack rms=y | sfdisfil<br />
0: 1.581 2.16 3.109 4.082 5.066<br />
bash&#36; < test.rsf sfstack min=y | sfdisfil<br />
0: 0 1 2 3 4<br />
bash&#36; < test.rsf sfstack axis=1 max=y | sfdisfil <br />
0: 4 5 6<br />
</pre><br />
<br />
==sftransp==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Transpose two axes in a dataset. <br />
|-<br />
! colspan="4" | sftransp < in.rsf > out.rsf memsize=sf_memsize() plane=<br />
|-<br />
| colspan="4" | <br>If you get a "Cannot allocate memory" error, give the program a<br>memsize=1 command-line parameter to force out-of-core operation.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''int '' || '''plane=''' || || Two-digit number with axes to transpose. The default is 12<br />
|}<br />
<br />
The <tt>sftransp</tt> program transposes the input hypercube<br />
exchanging the two axes specified by the <b>plane=</b> parameter. <br />
<pre><br />
bash&#36; sfspike n1=10 n2=20 n3=30 > orig123.rsf<br />
bash&#36; sfin orig123.rsf <br />
orig123.rsf:<br />
in="/var/tmp/orig123.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=30 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=23 >out132.rsf<br />
bash&#36; sfin out132.rsf <br />
out132.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=30 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=20 d3=0.1 o3=0 label3="Distance" unit3="km" <br />
6000 elements 24000 bytes<br />
bash&#36; <orig123.rsf sftransp plane=13 >out321.rsf<br />
bash&#36; sfin out321.rsf <br />
out321.rsf:<br />
in="/var/tmp/out132.rsf@"<br />
esize=4 type=float form=native <br />
n1=30 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=20 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
n3=10 d3=0.004 o3=0 label3="Time" unit3="s" <br />
6000 elements 24000 bytes<br />
</pre><br />
<tt>sftransp</tt> tries to fit the dataset in memory to transpose it<br />
there but, if not enough memory is available, it performs a slower<br />
transpose out of core using disk operations. You can control the<br />
amount of available memory using the <b>memsize=</b> parameter or<br />
the <b>RSFMEMSIZE</b> environmental variable.<br />
<br />
==sfwindow==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Window a portion of the dataset. <br />
|-<br />
! colspan="4" | sfwindow < in.rsf > out.rsf verb=n squeeze=y j#=(1,...) d#=(d1,d2,...) f#=(0,...) min#=(o1,o2,,...) n#=(0,...) max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)<br />
|-<br />
| ''float '' || '''d#=(d1,d2,...)''' || || sampling in #-th dimension<br />
|-<br />
| ''int '' || '''f#=(0,...)''' || || window start in #-th dimension<br />
|-<br />
| ''int '' || '''j#=(1,...)''' || || jump in #-th dimension<br />
|-<br />
| ''float '' || '''max#=(o1+(n1-1)*d1,o2+(n1-1)*d2,,...)''' || || maximum in #-th dimension<br />
|-<br />
| ''float '' || '''min#=(o1,o2,,...)''' || || minimum in #-th dimension<br />
|-<br />
| ''int '' || '''n#=(0,...)''' || || window size in #-th dimension<br />
|-<br />
| ''bool '' || '''squeeze=y''' || [y/n] || if y, squeeze dimensions equal to 1 to the end<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
<br />
<b>sfwindow</b> is used to window a portion of the dataset. Here is<br />
a quick example: Start by creating some data.<br />
<pre><br />
bash&#36; sfmath n1=5 n2=3 o1=1 o2=1 output="x1*x2" > test.rsf<br />
bash&#36; < test.rsf sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
10: 3 6 9 12 15<br />
</pre><br />
Now window the first two rows:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n2=2 | sfdisfil<br />
0: 1 2 3 4 5<br />
5: 2 4 6 8 10<br />
</pre><br />
Window the first three columns:<br />
<pre><br />
bash&#36; < test.rsf sfwindow n1=3 | sfdisfil<br />
0: 1 2 3 2 4<br />
5: 6 3 6 9<br />
</pre><br />
Window the middle row:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f2=1 n2=1 | sfdisfil<br />
0: 2 4 6 8 10<br />
</pre><br />
You can interpret the <b>f#</b> and <b>n#</b> parameters as<br />
meaning "skip that many rows/columns" and "select that many<br />
rows/columns" correspondingly. Window the middle point in the dataset:<br />
<pre><br />
bash&#36; < test.rsf sfwindow f1=2 n1=1 f2=1 n2=1 | sfdisfil<br />
0: 6<br />
</pre><br />
Window every other column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=2 | sfdisfil<br />
0: 1 3 5 2 6<br />
5: 10 3 9 15<br />
</pre><br />
Window every third column:<br />
<pre><br />
bash&#36; < test.rsf sfwindow j1=3 | sfdisfil<br />
0: 1 4 2 8 3<br />
5: 12<br />
</pre><br />
Alternatively, <b>sfwindow</b> can use the minimum and maximum<br />
parameters to select a window. In the following example, we are<br />
creating a dataset with <b>sfspike</b> and then windowing a portion of it<br />
between 1 and 2 seconds in time and sampled at 8 miliseconds.<br />
<pre><br />
bash&#36; sfspike n1=1000 n2=10 > spike.rsf <br />
bash&#36; sfin spike.rsf<br />
spike.rsf:<br />
in="/var/tmp/spike.rsf@"<br />
esize=4 type=float form=native <br />
n1=1000 d1=0.004 o1=0 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10000 elements 40000 bytes<br />
bash&#36; < spike.rsf sfwindow min1=1 max1=2 d1=0.008 > window.rsf<br />
bash&#36; sfin window.rsf<br />
window.rsf:<br />
in="/var/tmp/window.rsf@"<br />
esize=4 type=float form=native <br />
n1=126 d1=0.008 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
1260 elements 5040 bytes<br />
</pre><br />
By default, <b>sfwindow</b> "squeezes" the hypercube dimensions<br />
that are equal to one toward the end of the dataset. Here is an<br />
example of taking a time slice:<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=10 d1=0.1 o1=0 label1="Distance" unit1="km" <br />
n2=1 d2=0.004 o2=1 label2="Time" unit2="s" <br />
10 elements 40 bytes<br />
</pre><br />
You can change this behavior by specifying <b>squeeze=n</b>.<br />
<pre><br />
bash&#36; < spike.rsf sfwindow n1=1 min1=1 squeeze=n > slice.rsf<br />
bash&#36; sfin slice.rsf <br />
slice.rsf:<br />
in="/var/tmp/slice.rsf@"<br />
esize=4 type=float form=native <br />
n1=1 d1=0.004 o1=1 label1="Time" unit1="s" <br />
n2=10 d2=0.1 o2=0 label2="Distance" unit2="km" <br />
10 elements 40 bytes<br />
</pre><br />
<br />
=Seismic programs=<br />
Programs in this category are specific for operations on seismic data. The source files for these programs can be found under [http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/system/seismic/ system/seismic] in the Madagascar distribution.<br />
<br />
==sfheaderattr==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Integer header attributes. <br />
|-<br />
! colspan="4" | sfheaderattr < head.rsf<br />
|-<br />
| colspan="4" | <br>Only nonzero values are reported.<br />
|}<br />
<br />
The <tt>sfheaderattr</tt> examines the contents of a trace header file,<br />
typically generated by <tt>sfsegyread</tt>. In the example below, we examine<br />
trace headers in the output of <tt>suplane</tt>, a program from Seismic Unix.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
bash$ sfheaderattr < tfile.rsf<br />
*******************************************<br />
71 headers, 32 traces<br />
key[0]="tracl" min[0]=1 max[31]=32 mean=16.5<br />
key[1]="tracr" min[0]=1 max[31]=32 mean=16.5<br />
key[11]="offset" min[0]=400 max[31]=400 mean=400<br />
key[38]="ns" min[0]=64 max[31]=64 mean=64<br />
key[39]="dt" min[0]=4000 max[31]=4000 mean=4000<br />
*******************************************<br />
</pre><br />
For different standard keywords, a minimum, maximum, and mean values<br />
are reported unless they are identically zero. This quick inspection<br />
can help in identifying meaningful keywords set in the data. The input<br />
data type must be <tt>int</tt>.<br />
<br />
==sfheadermath==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Mathematical operations, possibly on header keys. <br />
|-<br />
! colspan="4" | sfheadermath < in.rsf > out.rsf memsize=sf_memsize() output=<br />
|-<br />
| colspan="4" | <br>Known functions: cos, sin, tan, acos, asin, atan, <br> cosh, sinh, tanh, acosh, asinh, atanh,<br> exp, log, sqrt, abs<br><br>See also sfmath. <br><br>An addition operation can be performed by sfstack.<br />
|-<br />
| ''int '' || '''memsize=sf_memsize()''' || || Max amount of RAM (in Mb) to be used<br />
|-<br />
| ''string '' || '''output=''' || || Describes the output in a mathematical notation.<br />
|}<br />
<tt>sfheadermath</tt> is a versatile program for mathematical<br />
operations on rows of the input file. If the input file is an<br />
<tt>n1</tt> by <tt>n2</tt> matrix, the output will be a <tt>1</tt> by<br />
<tt>n2</tt> matrix that contains one row made out of mathematical<br />
operations on the other rows. <tt>sfheadermath</tt> can identify a row<br />
by number or by a standard SEGY keyword. The latter is useful for<br />
processing headers extracted from SEGY or SU files.<br />
Here is an example. First, we create an SU file with <tt>suplane</tt> and convert it to RSF using <tt>sfsegyread</tt>.<br />
<pre><br />
bash$ suplane > plane.su<br />
bash$ sfsegyread tape=plane.su su=y tfile=tfile.rsf > plane.rsf<br />
</pre><br />
The trace header information is saved in <tt>tfile.rsf</tt>. It<br />
contains 71 headers for 32 traces in integer format.<br />
<pre><br />
bash$ sfin tfile.rsf<br />
tfile.rsf:<br />
in="/tmp/tfile.rsf@"<br />
esize=4 type=int form=native<br />
n1=71 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
2272 elements 9088 bytes<br />
</pre><br />
Next, we will convert <tt>tfile.rsf</tt> to a floating-point format<br />
and run <tt>sfheadermath</tt> to create a new header.<br />
<pre><br />
bash$ < tfile.rsf sfdd type=float | \<br />
sfheadermath myheader=1 output="sqrt(myheader+(2+10*offset^2))" > new.rsf<br />
bash$ sfin new.rsf<br />
new.rsf:<br />
in="/tmp/new.rsf@"<br />
esize=4 type=float form=native<br />
n1=1 d1=? o1=?<br />
n2=32 d2=? o2=?<br />
32 elements 128 bytes<br />
</pre><br />
We defined "myheader" as being the row number 1 in the input (note<br />
that numbering starts with 0) and combined it with "offset", which<br />
is a standard SEGY keyword that denotes row number 11 (see the output<br />
of <tt>sfheaderattr</tt> above.) A variety of mathematical expressions<br />
can be defined in the <tt>output=</tt> string. The expression<br />
processing engine is shared with <tt>sfmath</tt>.<br />
<br />
==sfsegyheader==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Make a trace header file for segywrite.<br />
|-<br />
! colspan="4" | sfsegyheader < in.rsf > out.rsf n1= d1=<br />
|-<br />
| colspan="4" | <br> Use the output for tfile= argument in segywrite.<br />
|-<br />
| ''float '' || '''d1=''' || || trace sampling<br />
|-<br />
| ''int '' || '''n1=''' || || number of samples in a trace<br />
|}<br />
<br />
==sfsegyread==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert a SEG-Y or SU dataset to RSF.<br />
|-<br />
! colspan="4" | sfsegyread mask=msk.rsf > out.rsf tfile=hdr.rsf verb=false su=false format=sf_segyformat (bhead) ns=sf_segyns (bhead) endian= tape= read= hfile= bfile= mask= tfile=<br />
|-<br />
| colspan="4" | <br>Data headers and trace headers are separated from the data.<br><br>Defined SEG-Y trace header key names and byte offsets:<br><br>tracl: trace sequence number within line 0<br><br>tracr: trace sequence number within reel 4<br><br>fldr: field record number 8 <br><br>tracf: trace number within field record 12 <br><br>ep: energy source point number 16 <br><br>cdp: CDP ensemble number 20 <br><br>cdpt: trace number within CDP ensemble 24 <br><br>trid: trace identification code:<br>1 = seismic data<br>2 = dead<br>3 = dummy<br>4 = time break<br>5 = uphole<br>6 = sweep<br>7 = timing<br>8 = water break<br>9---, N = optional use (N = 32,767) 28 <br><br>nvs: number of vertically summed traces 30 <br><br>nhs: number of horizontally summed traces 32 <br><br>duse: data use:<br>1 = production<br>2 = test 34<br><br>offset: distance from source point to receiver<br>group (negative if opposite to direction<br>in which the line was shot) 36 <br><br>gelev: receiver group elevation from sea level<br>(above sea level is positive) 40 <br><br>selev: source elevation from sea level<br>(above sea level is positive) 44 <br><br>sdepth: source depth (positive) 48 <br><br>gdel: datum elevation at receiver group 52 <br><br>sdel: datum elevation at source 56 <br><br>swdep: water depth at source 60 <br><br>gwdep: water depth at receiver group 64 <br><br>scalel: scale factor for previous 7 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 68 <br><br>scalco: scale factor for next 4 entries<br>with value plus or minus 10 to the<br>power 0, 1, 2, 3, or 4 (if positive,<br>multiply, if negative divide) 70 <br><br>sx: X source coordinate 72 <br><br>sy: Y source coordinate 76 <br><br>gx: X group coordinate 80 <br><br>gy: Y group coordinate 84 <br><br>counit: coordinate units code:<br>for previoius four entries<br>1 = length (meters or feet)<br>2 = seconds of arc (in this case, the<br>X values are unsigned intitude and the Y values<br>are latitude, a positive value designates<br>the number of seconds east of Greenwich<br>or north of the equator 88 <br><br>wevel: weathering velocity 90 <br><br>swevel: subweathering velocity 92 <br><br>sut: uphole time at source 94 <br><br>gut: uphole time at receiver group 96 <br><br>sstat: source static correction 98 <br><br>gstat: group static correction 100 <br><br>tstat: total static applied 102 <br><br>laga: lag time A, time in ms between end of 240-<br>byte trace identification header and time<br>break, positive if time break occurs after<br>end of header, time break is defined as<br>the initiation pulse which maybe recorded<br>on an auxiliary trace or as otherwise<br>specified by the recording system 104 <br><br>lagb: lag time B, time in ms between the time<br>break and the initiation time of the energy source,<br>may be positive or negative 106 <br><br>delrt: delay recording time, time in ms between<br>initiation time of energy source and time<br>when recording of data samples begins<br>(for deep water work if recording does not<br>start at zero time) 108 <br><br>muts: mute time--start 110 <br><br>mute: mute time--end 112 <br><br>ns: number of samples in this trace 114 <br><br>dt: sample interval, in micro-seconds 116 <br><br>gain: gain type of field instruments code:<br>1 = fixed<br>2 = binary<br>3 = floating point<br>4 ---- N = optional use 118 <br><br>igc: instrument gain constant 120 <br><br>igi: instrument early or initial gain 122 <br><br>corr: correlated:<br>1 = no<br>2 = yes 124 <br><br>sfs: sweep frequency at start 126 <br><br>sfe: sweep frequency at end 128 <br><br>slen: sweep length in ms 130 <br><br>styp: sweep type code:<br>1 = linear<br>2 = cos-squared<br>3 = other 132 <br><br>stas: sweep trace length at start in ms 134 <br><br>stae: sweep trace length at end in ms 136 <br><br>tatyp: taper type: 1=linear, 2=cos^2, 3=other 138 <br><br>afilf: alias filter frequency if used 140 <br><br>afils: alias filter slope 142 <br><br>nofilf: notch filter frequency if used 144 <br><br>nofils: notch filter slope 146 <br><br>lcf: low cut frequency if used 148 <br><br>hcf: high cut frequncy if used 150 <br><br>lcs: low cut slope 152 <br><br>hcs: high cut slope 154 <br><br>year: year data recorded 156 <br><br>day: day of year 158 <br><br>hour: hour of day (24 hour clock) 160 <br><br>minute: minute of hour 162 <br><br>sec: second of minute 164 <br><br>timbas: time basis code:<br>1 = local<br>2 = GMT<br>3 = other 166 <br><br>trwf: trace weighting factor, defined as 1/2^N<br>volts for the least sigificant bit 168 <br><br>grnors: geophone group number of roll switch<br>position one 170 <br><br>grnofr: geophone group number of trace one within<br>original field record 172 <br><br>grnlof: geophone group number of last trace within<br>original field record 174 <br><br>gaps: gap size (total number of groups dropped) 176 <br><br>otrav: overtravel taper code:<br>1 = down (or behind)<br>2 = up (or ahead)<br />
|-<br />
| ''string '' || '''bfile=''' || || output binary data header file<br />
|-<br />
| ''bool '' || '''endian=''' || [y/n] || big/little endian flag, the default is estimated automatically<br />
|-<br />
| ''int '' || '''format=sf_segyformat (bhead)''' || [1,2,3,5] || Data format. The default is taken from binary header.<br />
:1 is IBM floating point<br />
:2 is 4-byte integer<br />
:3 is 2-byte integer<br />
:5 is IEEE floating point<br />
|-<br />
| ''string '' || '''hfile=''' || || output text data header file<br />
|-<br />
| ''string '' || '''mask=''' || || optional header mask for reading only selected traces<br />
|-<br />
| ''int '' || '''ns=sf_segyns (bhead)''' || || Number of samples. The default is taken from binary header<br />
|-<br />
| ''string '' || '''read=''' || || what to read: h - header, d - data, b - both (default)<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if input is SU, n if input is SEGY<br />
|-<br />
| ''bool '' || '''suxdr=n''' || [y/n] || y, SU has XDR support<br />
|-<br />
| ''string '' || '''tape=''' || || <br />
|-<br />
| ''string '' || '''tfile=''' || || output trace header file<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
<br />
The SEG Y format is an [http://en.wikipedia.org/wiki/Open_standard open standard] for the exchange of geophysical data. It is controlled by the non-profit [http://www.seg.org/SEGportalWEBproject/portals/SEG_Online.portal?_nfpb=true&_pageLabel=pg_gen_content&Doc_Url=prod/SEG-Publications/Pub-Yearbook/committees.htm SEG Technical Standards Committee]. There are two versions of this standard: [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev0.pdf rev0] (1975)<ref>Barry, K.M., Cavers, D.A., and Kneale, C.W. 1975. Recommended standards for digital tape formats. ''Geophysics'', '''40''', no. 02, 344–352.</ref> and [http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf rev1] (2002)<ref>Norris, M.W., Faichney, A.K., ''Eds''. 2001. SEG Y rev1 Data Exchange format. Society of Exploration Geophysicists, Tulsa, OK, 45 pp.</ref>. The implementation in <tt>sfsegyread</tt> is a mixture of rev0 (i.e. no checks for Extended Textual Headers) and rev1 ([http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE floating point format] allowed for trace data samples).<br />
<br />
A SEG-Y file as understood by <tt>sfsegyread</tt> contains a "Reel Identification Header" (3200 bytes in EBCDIC followed by 400 bytes in a binary encoding), followed by a number of "Trace Blocks". Each "Trace Block" contains a 240-byte "Trace Header" (binary) followed by "Trace Data" -- a sequence of <tt>ns</tt> samples. Binary values in both reel headers and trace headers are two's complement integers, either two bytes or four bytes long. There are no floating-point values defined in the headers. Trace Data samples can have various encodings, either floating point or integer, described further down, but they are all big-endian. To convert from SEG-Y to RSF, <tt>sfsegyread</tt> will strip the tape reel EBCDIC header and convert it to ASCII, will extract the reel binary header without changing it, and will put the trace headers into one RSF file, and the traces themselves on another.<br />
<br />
===SEG-Y Trace Headers===<br />
In the SEG-Y standard, only the first 180 bytes of the 240-byte trace header are defined; bytes 181-240 are reserved for non-standard header information, and these locations are increasingly used in modern SEG-Y files and its variants. The standard provides for a total of 71 4-byte and 2-byte predefined header words. These 71 standard words have defined lengths and byte offsets, and only these words and byte locations are read using <tt>segyread</tt> and output to the RSF header file with the <tt>hfile=</tt> option. The user may remap these predefined keywords to a different byte offsets.<br />
<br />
===SU File Format===<br />
An [http://www.cwp.mines.edu/sututor/node22.html SU file] is nothing more than a SEG-Y file without the reel headers, and with the Trace Data samples in the native encoding of the CPU the file was created on (Attention -- limited portability!). So, to convert from SU to RSF, <tt>sfsegyread</tt> will just separate headers and traces into two RSF files. <br />
<br />
===SEG-Y specific parameters===<br />
*<tt>hfile=</tt> specifies the name of the file in which the EBCDIC reel header will be put after conversion to ASCII. If you are certain there is no useful information in it, <tt>hfile=/dev/null</tt> works just fine. If you do not specify anything for this parameter you will get an ASCII file named <tt>header</tt> in the current directory. If you want to quickly preview this header before running <tt>sfsegyread</tt>, use<pre>dd if=input.segy count=40 bs=80 cbs=80 conv=unblock,ascii</pre><br />
*<tt>bfile=</tt> specifies name of the file in which the binary reel header (the 400-bytes thing following the 3600-bytes EBCDIC) will be put without any conversion. The default name is "binary". Unless you have software that knows how to read exactly this special type of file, it will be completely useless, so do <tt>bfile=/dev/null</tt><br />
*<tt>format=</tt> specifies the format in which the trace data samples are in the SEG-Y input file. This is read from the binary reel header of the SEG-Y file. Valid values are 1(IBM floating point), 2 (4-byte integer), 3 (2-byte integer) and 5 (IEEE floating point). If the input file is SU, the format will be assumed to be the native <tt>float</tt> format.<br />
<br />
*<tt>keyname=</tt> specifies the byte offset to remap a header using the trace header key names shown above. For example, if the CDP locations have been placed in bytes 181-184 instead of the standard 21-24, <tt>cdp=180</tt> will remap the trace header to that location. <br />
<br />
===SU-specific parameters===<br />
*<tt>suxdr=</tt> specifies whether the input file was created with a SU package with XDR support enabled. If you have access to the source code of your SU install (try <tt>$CWPROOT/src</tt>), type: <tt>grep 'XDRFLAG =' $CWPROOT/src/Makefile.config</tt> and look at the last uncommented entry. If no value is given for <tt>XDRFLAG</tt>, the package was not compiled with XDR support.<br />
===Common parameters===<br />
*<tt>su=</tt> specifies if the input file is SU or SEG-Y. Default is <tt>su=n</tt> (SEG-Y file).<br />
*<tt>tape=</tt> specifies the input data. Stdin could not be used because <tt>sfsegyread</tt> has to work with tapes, and needs to fseek back and forth through the input file. Thankfully, output is on stdout.<br />
*<tt>read=</tt> specifies what parts of the "Trace Blocks" will be read. It can be <tt>read=t</tt> (only trace data is read), <tt>read=h</tt> (only trace headers are read) or <tt>read=b</tt> (both are read).<br />
*<tt>tfile=</tt> gives the name of the RSF file to which trace headers are written. Obviously, it should be only specified with <tt>read=h</tt> or <tt>read=b</tt>.<br />
*<tt>mask=</tt> is an optional parameter specifying the name of a mask that says which traces will be read. The mask is a 1-D RSF file with integers. The number of samples in the mask is the same as the number of traces in the unmasked SEG-Y. In places corresponding to unwanted traces there should be zeros in the mask.<br />
*<tt>ns=</tt> specifies the number of samples in a trace. For SEG-Y files, the default is taken from the binary reel header, and for SU files, from the header of the first trace. This parameter is however critical enough that a command line override was given for it.<br />
*<tt>verbose=</tt> is the verbosity flag. Can be <tt>y</tt> or <tt>n</tt>.<br />
*<tt>endian=</tt> is a y/n flag (default y), specifying whether to automatically estimate or not if samples in the Trace Data blocks are big-endian or little-endian. Try it if you are in trouble and do not know what else to do, otherwise let the automatic estimation do its job.<br />
<br />
==sfsegywrite==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Convert an RSF dataset to SEGY or SU.<br />
|-<br />
! colspan="4" | sfsegywrite < in.rsf tfile=hdr.rsf verb=false su=false endian=sf_endian() tape= hfile= bfile=<br />
|-<br />
| colspan="4" | <br>Merges trace headers with data.<br />
|-<br />
| ''string '' || '''bfile=''' || || input binary data header file<br />
|-<br />
| ''bool '' || '''endian=sf_endian()''' || [y/n] || big/little endian flag. The default is estimated automatically<br />
|-<br />
| ''string '' || '''hfile=''' || || input text data header file<br />
|-<br />
| ''bool '' || '''su=n''' || [y/n] || y if output is SU, n if output is SEGY<br />
|-<br />
| ''string '' || '''tape=''' || ||<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || Verbosity flag<br />
|}<br />
Please see <tt>sfsegyread</tt> for a complete description of parameter meanings and background issues. Parameters <tt>bfile</tt> and <tt>hfile</tt> should only be given values when the desired file is SEG-Y (default). The output file is specified by the <tt>tape=</tt> tag.<br />
<br />
=Plotting programs=<br />
The source files for these programs can be found under<br />
[http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/plot/main/ plot/main]<br />
in the Madagascar distribution.<br />
<br />
THIS SECTION IS UNDER CONSTRUCTION<br />
<br />
==sfbox==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Draw a balloon-style label.<br />
|-<br />
! colspan="4" | sfbox lab_color=VP_WHITE lab_fat=0 pscale=1. pointer=y reverse=n lat=0. long=90. angle=0. x0=0. y0=0. scale0=1. xt=2. yt=0. x_oval=0. y_oval=0. boxit=y length= scalet= size=.25 label= > out.vpl<br />
|-<br />
| ''float '' || '''angle=0.''' || || longitude of floating label in 3-D<br />
|-<br />
| ''bool '' || '''boxit=y''' || [y/n] || if y, create a box around text<br />
|-<br />
| ''int '' || '''lab_color=VP_WHITE''' || || label color<br />
|-<br />
| ''int '' || '''lab_fat=0''' || || label fatness<br />
|-<br />
| ''string '' || '''label=''' || || text for label<br />
|-<br />
| ''float '' || '''lat=0.''' || || <br />
|-<br />
| ''float '' || '''length=''' || || normalization for xt and yt<br />
|-<br />
| ''float '' || '''long=90.''' || || latitude and longitude of viewpoint in 3-D<br />
|-<br />
| ''bool '' || '''pointer=y''' || [y/n] || if y, create arrow pointer<br />
|-<br />
| ''float '' || '''pscale=1.''' || || scale factor for width of pointer<br />
|-<br />
| ''bool '' || '''reverse=n''' || [y/n] || <br />
|-<br />
| ''float '' || '''scale0=1.''' || || scale factor for x0 and y0<br />
|-<br />
| ''float '' || '''scalet=''' || || <br />
|-<br />
| ''float '' || '''size=.25''' || || text height in inches<br />
|-<br />
| ''float '' || '''x0=0.''' || || <br />
|-<br />
| ''float '' || '''x_oval=0.''' || || <br />
|-<br />
| ''float '' || '''xt=2.''' || || <br />
|-<br />
| ''float '' || '''y0=0.''' || || position of the pointer tip<br />
|-<br />
| ''float '' || '''y_oval=0.''' || || size of the oval around pointer<br />
|-<br />
| ''float '' || '''yt=0.''' || || relative position of text<br />
|}<br />
==sfcontour==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Contour plot.<br />
|-<br />
! colspan="4" | sfcontour < in.rsf c= min1=o1 min2=o2 max1=o1+(n1-1)*d1 max2=o2+(n2-1)*d2 nc=50 dc= c0= transp=y minval= maxval= allpos=y barlabel= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=y''' || [y/n] || contour positive values only<br />
|-<br />
| ''string '' || '''barlabel=''' || || <br />
|-<br />
| ''floats '' || '''c=''' || || [nc]<br />
|-<br />
| ''float '' || '''c0=''' || || first contour<br />
|-<br />
| ''float '' || '''dc=''' || || contour increment<br />
|-<br />
| ''float '' || '''max1=o1+(n1-1)*d1''' || || <br />
|-<br />
| ''float '' || '''max2=o2+(n2-1)*d2''' || || data window to plot<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''min1=o1''' || || <br />
|-<br />
| ''float '' || '''min2=o2''' || || <br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nc=50''' || || number of contours<br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfdots==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot signal with lollipops.<br />
|-<br />
! colspan="4" | sfdots < in.rsf labels= dots=(n1 <= 130)? 1: 0 seemean=(bool) (n2 <= 30) strings=(bool) (n1 <= 400) connect=1 corners= silk=n gaineach=y labelsz=8 yreverse=n constsep=n seedead=n transp=n xxscale=1. yyscale=1. clip=-1. overlap=0.9 screenratio=VP_SCREEN_RATIO screenht=VP_STANDARD_HEIGHT screenwd=screenhigh / screenratio radius=dd1/3 label1= unit1= title= > plot.vpl<br />
|-<br />
| ''float '' || '''clip=-1.''' || || data clip<br />
|-<br />
| ''int '' || '''connect=1''' || || connection type: 1 - diagonal, 2 - bar, 4 - only for non-zero data<br />
|-<br />
| ''bool '' || '''constsep=n''' || [y/n] || if y, use constant trace separation<br />
|-<br />
| ''int '' || '''corners=''' || || number of polygon corners (default is 6)<br />
|-<br />
| ''int '' || '''dots=(n1 <= 130)? 1: 0''' || || type of dots: 1 - baloon, 0 - no dots, 2 - only for non-zero data<br />
|-<br />
| ''bool '' || '''gaineach=y''' || [y/n] || if y, gain each trace independently<br />
|-<br />
| ''string '' || '''label1=''' || || <br />
|-<br />
| ''strings'' || '''labels=''' || || trace labels [n2]<br />
|-<br />
| ''int '' || '''labelsz=8''' || || label size<br />
|-<br />
| ''float '' || '''overlap=0.9''' || || trace overlap<br />
|-<br />
| ''float '' || '''radius=dd1/3''' || || dot radius<br />
|-<br />
| ''float '' || '''screenht=VP_STANDARD_HEIGHT''' || || screen height<br />
|-<br />
| ''float '' || '''screenratio=VP_SCREEN_RATIO''' || || screen aspect ratio<br />
|-<br />
| ''float '' || '''screenwd=screenhigh / screenratio''' || || screen width<br />
|-<br />
| ''bool '' || '''seedead=n''' || [y/n] || if y, show zero traces<br />
|-<br />
| ''bool '' || '''seemean=(bool) (n2 <= 30)''' || [y/n] || if y, draw axis lines<br />
|-<br />
| ''bool '' || '''silk=n''' || [y/n] || if y, silky plot<br />
|-<br />
| ''bool '' || '''strings=(bool) (n1 <= 400)''' || [y/n] || if y, draw strings<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axis<br />
|-<br />
| ''string '' || '''unit1=''' || || <br />
|-<br />
| ''float '' || '''xxscale=1.''' || || x scaling<br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse y axis<br />
|-<br />
| ''float '' || '''yyscale=1.''' || || y scaling<br />
|}<br />
==sfgraph3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot for surfaces.<br />
|-<br />
! colspan="4" | sfgraph3 < in.rsf orient=1 min= max= point1=0.5 point2=0.5 frame1=0.5*(min+max) frame2=n1-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y > plot.vpl<br />
|-<br />
| ''float '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''float '' || '''frame1=0.5*(min+max)''' || || <br />
|-<br />
| ''int '' || '''frame2=n1-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''max=''' || || maximum function value<br />
|-<br />
| ''float '' || '''min=''' || || minimum function value<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''orient=1''' || || function orientation<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|}<br />
==sfgraph==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Graph plot.<br />
|-<br />
! colspan="4" | sfgraph < in.rsf symbolsz= pclip=100. transp=n symbol= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''pclip=100.''' || || clip percentile<br />
|-<br />
| ''string '' || '''symbol=''' || || if set, plot with symbols instead of lines<br />
|-<br />
| ''floats '' || '''symbolsz=''' || || symbol size (default is 2) [n2]<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|}<br />
==sfgrey3==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate 3-D cube plot.<br />
|-<br />
! colspan="4" | sfgrey3 < in.rsf point1=0.5 point2=0.5 frame1=0 frame2=n2-1 frame3=0 movie=0 dframe=1 n1pix=n1/point1+n3/(1.-point1) n2pix=n2/point2+n3/(1.-point2) flat=y scalebar=n minval= maxval= barreverse=n nreserve=8 bar= color= > plot.vpl<br />
|-<br />
| colspan="4" | Requires an "unsigned char" input (the output of sfbyte).<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''string '' || '''color=''' || || color scheme<br />
|-<br />
| ''int '' || '''dframe=1''' || || frame increment in a movie<br />
|-<br />
| ''bool '' || '''flat=y''' || [y/n] || if n, display perspective view<br />
|-<br />
| ''int '' || '''frame1=0''' || || <br />
|-<br />
| ''int '' || '''frame2=n2-1''' || || <br />
|-<br />
| ''int '' || '''frame3=0''' || || frame numbers for cube faces<br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''movie=0''' || || 0: no movie, 1: movie over axis 1, 2: axis 2, 3: axis 3<br />
|-<br />
| ''int '' || '''n1pix=n1/point1+n3/(1.-point1)''' || || number of vertical pixels<br />
|-<br />
| ''int '' || '''n2pix=n2/point2+n3/(1.-point2)''' || || number of horizontal pixels<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''point1=0.5''' || || fraction of the vertical axis for front face<br />
|-<br />
| ''float '' || '''point2=0.5''' || || fraction of the horizontal axis for front face<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || if y, draw scalebar<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
for sfgrey and sfgrey3. Examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfgrey==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Generate raster plot.<br />
|-<br />
! colspan="4" | sfgrey < in.rsf > out.rsf bar=bar.rsf transp=y yreverse=y xreverse=n gpow= phalf= clip= pclip= gainstep=0.5+n1/256. allpos=n bias=0. polarity=n verb=n scalebar=n minval= maxval= barreverse=n wantframenum=(bool) (n3 > 1) nreserve=8 gainpanel= bar= color= > (plot.vpl | char.rsf)<br />
|-<br />
| colspan="4" | Can input char values.<br>If called "byte", outputs char values.<br><br>Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''bool '' || '''allpos=n''' || [y/n] || if y, assume positive data<br />
|-<br />
| ''string '' || '''bar=''' || || file for scalebar data<br />
|-<br />
| ''bool '' || '''barreverse=n''' || [y/n] || if y, go from small to large on the bar scale<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=''' || || <br />
|-<br />
| ''string '' || '''color=''' || || color scheme (default is i)<br />
|-<br />
| ''string '' || '''gainpanel=''' || || gain reference: 'a' for all, 'e' for each, or number<br />
|-<br />
| ''int '' || '''gainstep=0.5+n1/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=''' || || <br />
|-<br />
| ''float '' || '''maxval=''' || || maximum value for scalebar (default is the data maximum)<br />
|-<br />
| ''float '' || '''minval=''' || || minimum value for scalebar (default is the data minimum)<br />
|-<br />
| ''int '' || '''nreserve=8''' || || reserved colors<br />
|-<br />
| ''float '' || '''pclip=''' || || data clip percentile (default is 99)<br />
|-<br />
| ''float '' || '''phalf=''' || || percentage for estimating gpow<br />
|-<br />
| ''bool '' || '''polarity=n''' || [y/n] || if y, reverse polarity (white is high by default)<br />
|-<br />
| ''bool '' || '''scalebar=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''transp=y''' || [y/n] || if y, transpose the display axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''bool '' || '''wantframenum=(bool) (n3 > 1)''' || [y/n] || if y, display third axis position in the corner<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''bool '' || '''yreverse=y''' || [y/n] || if y, reverse the vertical axis<br />
|}<br />
<br />
Different [http://reproducibility.org/rsflog/index.php?/archives/14-Color-schemes.html color schemes] are available<br />
and examples are in the book at [http://reproducibility.org/RSF/book/rsf/rsf/sfgrey.html rsf/rsf/sfgrey].<br />
<br />
==sfplas==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Assembler - convert ascii to vplot. <br />
|-<br />
! colspan="4" | sfplas<br />
|}<br />
==sfpldb==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot Debugger - convert vplot to ascii. <br />
|-<br />
! colspan="4" | sfpldb<br />
|}<br />
==sfplotrays==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot rays.<br />
|-<br />
! colspan="4" | sfplotrays frame=frame.rsf nt=n1*n2 jr=1 frame= < rays.rsf > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''string '' || '''frame=''' || || <br />
|-<br />
| ''int '' || '''jr=1''' || || skip rays<br />
|-<br />
| ''int '' || '''nt=n1*n2''' || || maximum ray length<br />
|}<br />
==sfthplot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Hidden-line surface plot.<br />
|-<br />
! colspan="4" | sfthplot < in.rsf uflag=y dflag=y alpha=45. titlsz=9 axissz=6 plotfat=0 titlefat=2 axisfat=2 plotcolup=VP_YELLOW plotcoldn=VP_RED axis=y axis1=y axis2=y axis3=y clip=0. pclip=100. gainstep=0.5+nx/256. bias=0. dclip=1. norm=y xc=1.5 zc=3 ratio=5. zmax= zmin= sz=6. label#= unit#= tpow=0 epow=0 gpow=1 title= > plot.vpl<br />
|-<br />
| ''float '' || '''alpha=45.''' || || apparent angle in degrees, |alpha| < 89<br />
|-<br />
| ''bool '' || '''axis=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis1=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis2=y''' || [y/n] || <br />
|-<br />
| ''bool '' || '''axis3=y''' || [y/n] || plot axis<br />
|-<br />
| ''int '' || '''axisfat=2''' || || axes fatness<br />
|-<br />
| ''int '' || '''axissz=6''' || || axes size<br />
|-<br />
| ''float '' || '''bias=0.''' || || subtract bias from data<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip<br />
|-<br />
| ''float '' || '''dclip=1.''' || || change the clip: clip *= dclip<br />
|-<br />
| ''bool '' || '''dflag=y''' || [y/n] || if y, plot down side of the surface<br />
|-<br />
| ''float '' || '''epow=0''' || || exponential gain<br />
|-<br />
| ''int '' || '''gainstep=0.5+nx/256.''' || || subsampling for gpow and clip estimation<br />
|-<br />
| ''float '' || '''gpow=1''' || || power gain<br />
|-<br />
| ''string '' || '''label#=''' || || label on #-th axis<br />
|-<br />
| ''bool '' || '''norm=y''' || [y/n] || normalize by the clip<br />
|-<br />
| ''float '' || '''pclip=100.''' || || data clip percentile<br />
|-<br />
| ''int '' || '''plotcoldn=VP_RED''' || || color of the lower side<br />
|-<br />
| ''int '' || '''plotcolup=VP_YELLOW''' || || color of the upper side<br />
|-<br />
| ''int '' || '''plotfat=0''' || || line fatness<br />
|-<br />
| ''float '' || '''ratio=5.''' || || plot adjustment<br />
|-<br />
| ''float '' || '''sz=6.''' || || vertical scale<br />
|-<br />
| ''string '' || '''title=''' || || <br />
|-<br />
| ''int '' || '''titlefat=2''' || || title fatness<br />
|-<br />
| ''int '' || '''titlsz=9''' || || title size<br />
|-<br />
| ''string '' || '''tpow=0''' || || time power gain<br />
|-<br />
| ''bool '' || '''uflag=y''' || [y/n] || if y, plot upper side of the surface<br />
|-<br />
| ''string '' || '''unit#=''' || || unit on #-th axis<br />
|-<br />
| ''float '' || '''xc=1.5''' || || <br />
|-<br />
| ''float '' || '''zc=3''' || || lower left corner of the plot<br />
|-<br />
| ''float '' || '''zmax=''' || || <br />
|-<br />
| ''float '' || '''zmin=''' || || <br />
|}<br />
==sfwiggle==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Plot data with wiggly traces. <br />
|-<br />
! colspan="4" | sfwiggle < in.rsf xpos=xpos.rsf xmax= xmin= poly=n fatp=1 xmask=1 ymask=1 pclip=98. zplot=0.75 clip=0. seemean=n verb=n transp=n yreverse=n xreverse=n xpos= > plot.vpl<br />
|-<br />
| colspan="4" | Run "sfdoc stdplot" for more parameters.<br />
|-<br />
| ''float '' || '''clip=0.''' || || data clip (estimated from pclip by default<br />
|-<br />
| ''int '' || '''fatp=1''' || || <br />
|-<br />
| ''float '' || '''pclip=98.''' || || clip percentile<br />
|-<br />
| ''bool '' || '''poly=n''' || [y/n] || <br />
|-<br />
| ''bool '' || '''seemean=n''' || [y/n] || if y, plot mean lines of traces<br />
|-<br />
| ''bool '' || '''transp=n''' || [y/n] || if y, transpose the axes<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || verbosity flag<br />
|-<br />
| ''int '' || '''xmask=1''' || || <br />
|-<br />
| ''float '' || '''xmax=''' || || maximum trace position (if using xpos)<br />
|-<br />
| ''float '' || '''xmin=''' || || minimum trace position (if using xpos)<br />
|-<br />
| ''string '' || '''xpos=''' || || optional header file with trace positions<br />
|-<br />
| ''bool '' || '''xreverse=n''' || [y/n] || if y, reverse the horizontal axis<br />
|-<br />
| ''int '' || '''ymask=1''' || || <br />
|-<br />
| ''bool '' || '''yreverse=n''' || [y/n] || if y, reverse the vertical axis<br />
|-<br />
| ''float '' || '''zplot=0.75''' || || <br />
|}<br />
<br />
=filt/imag programs=<br />
==sfremap1==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | 1-D ENO interpolation. <br />
|-<br />
! colspan="4" | sfremap1 < in.rsf > out.rsf pattern=pattern.rsf n1=n1 d1=d1 o1=o1 order=3<br />
|-<br />
| ''float '' || '''d1=d1''' || || Output sampling<br />
|-<br />
| ''int '' || '''n1=n1''' || || Number of output samples<br />
|-<br />
| ''float '' || '''o1=o1''' || || Output origin<br />
|-<br />
| ''int '' || '''order=3''' || || Interpolation order<br />
|-<br />
| ''string '' || '''pattern=''' || || auxiliary input file name<br />
|}<br />
To give an example of usage, we will create an input for <tt>sfremap1</tt> with:<br />
<pre><br />
sfmath n1=11 n2=11 d1=1 d2=1 o1=-5 o2=-5 output="x1*x1+x2*x2" > inp2remap1.rsf<br />
</pre><br />
Let us interpolate the data across both dimensions, then display it:<br />
<pre><br />
&lt; inp2remap1.rsf sfremap1 n1=1001 d1=0.01 | sftransp | \<br />
sfremap1 n1=1001 d1=0.01 | sftransp | sfgrey allpos=y | xtpen<br />
</pre><br />
The comparison with the uninterpolated data ( <tt>&lt; inp2remap1.rsf sfgrey allpos=y | xtpen</tt> ) is quite telling.<br />
<br />
=filt/proc programs=<br />
==sfstretch==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Stretch of the time axis. <br />
|-<br />
! colspan="4" | sfstretch < in.rsf > out.rsf datum=dat.rsf inv=n dens=1 v0= half=y delay= tdelay= hdelay= nout=dens*n1 extend=4 mute=0 maxstr=0 rule=<br />
|-<br />
| ''file '' || '''datum=''' || || auxiliary input file name<br />
|-<br />
| ''float '' || '''delay=''' || || time delay for rule=lmo<br />
|-<br />
| ''int '' || '''dens=1''' || || axis stretching factor<br />
|-<br />
| ''int '' || '''extend=4''' || || trace extension<br />
|-<br />
| ''bool '' || '''half=y''' || [y/n] || if y, the second axis is half-offset instead of full offset<br />
|-<br />
| ''float '' || '''hdelay=''' || || offset delay for rule=rad<br />
|-<br />
| ''bool '' || '''inv=n''' || [y/n] || if y, do inverse stretching<br />
|-<br />
| ''float '' || '''maxstr=0''' || || maximum stretch<br />
|-<br />
| ''int '' || '''mute=0''' || || tapering size<br />
|-<br />
| ''int '' || '''nout=dens*n1''' || || output axis length (if inv=n)<br />
|-<br />
| ''string '' || '''rule=''' || || Stretch rule:<br />
:n - normal moveout (nmostretch), default<br />
:l - linear moveout (lmostretch)<br />
:L - logarithmic stretch (logstretch)<br />
:2 - t^2 stretch (t2stretch)<br />
:c - t^2 chebyshev stretch (t2chebstretch)<br />
:r - radial moveout (radstretch)<br />
:d - datuming (datstretch)<br />
|-<br />
| ''float '' || '''tdelay=''' || || time delay for rule=rad<br />
|-<br />
| ''float '' || '''v0=''' || || moveout velocity<br />
|}<br />
<br />
<tt>sfstretch rule=d</tt> (aka <tt>sfdatstretch</tt>) can be used to apply statics. Here is a synthetic example, courtesy of Alessandro Frigeri:<br />
<pre><br />
# generate a dataset with 'flat' signals<br />
sfmath n1=200 n2=100 output="sin(0.5*x1)" type=float > scan.rsf<br />
<br />
# generate a sinusoidal elevation correction<br />
sfmath n1=100 output="3*sin(x1)" type=float > statics.rsf<br />
<br />
# apply statics, producing a 'wavy' output.<br />
sfstretch < scan.rsf > out.rsf datum=statics.rsf rule=d<br />
</pre><br />
<br />
=user/ivlad programs=<br />
==sfprep4plot==<br />
{| class="wikitable" align="center" cellspacing="0" border="1"<br />
! colspan="4" style="background:#ffdead;" | Resamples a 2-D dataset to the desired picture resolution, with antialias<br />
|-<br />
! colspan="4" | sfprep4plot inp= out= verb=n h=none w=none unit= ppi= prar=y<br />
|-<br />
| colspan="4" | Only one of the h and w parameters needs to be specified.<br>If prar=n, no action will be taken on axis for which h/w was not specified<br>If prar=y and only one par (h or w) is specified, the picture will scale<br>along both axes until it is of the specified dimension.<br />
|-<br />
| ''int '' || '''h=none''' || || output height<br />
|-<br />
| ''string '' || '''inp=''' || || input file<br />
|-<br />
| ''string '' || '''out=''' || || output file<br />
|-<br />
| ''int '' || '''ppi=''' || || output resolution (px/in). Necessary when unit!=px<br />
|-<br />
| ''bool '' || '''prar=y''' || [y/n] || if y, PReserve Aspect Ratio of input<br />
|-<br />
| ''string '' || '''unit=''' || || unit of h and w. Can be: px(default), mm, cm, in<br />
|-<br />
| ''bool '' || '''verb=n''' || [y/n] || if y, print system commands, outputs<br />
|-<br />
| ''int '' || '''w=none''' || || output width<br />
|}<br />
For a figure that does not need the aspect ratio preserved,<br />
and needs to fill a 1280x1024 projector display:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=1280 h=1024 prar=n<br />
</pre><br />
For a print figure that has to fit in a 6x8in box<br />
at a resolution of 250 dpi, preserving the aspect ratio:<br />
<pre><br />
sfprep4plot inp=file1.rsf out=file2.rsf w=6 h=8 unit=in ppi=250<br />
</pre><br />
A comparison of images before and after the application of <tt>sfprep4plot</tt>, courtesy of Joachim Mispel, is shown below:<br />
<br />
[[Image:sf_prep4plot.jpg]]<br />
<br />
=References=<br />
<references/></div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=MediaWiki:Sidebar&diff=466MediaWiki:Sidebar2009-01-10T16:50:33Z<p>Jenningsjwj: </p>
<hr />
<div>* Getting Madagascar<br />
** Download|Download <br />
** Installation|Installation<br />
** http://rsf.svn.sourceforge.net/viewvc/rsf/trunk/ |SVN repository<br />
** SEGTeX|SEGTeX<br />
* Introduction<br />
** Package overview|Package overview<br />
** Revisiting SEP tour with Madagascar and SCons|Hands-on tour<br />
** Reproducible Documents|Reproducible documents<br />
* User Documentation<br />
** http://www.reproducibility.org/RSF/ |List of programs<br />
** Guide to madagascar programs|Common programs<br />
** Guide to RSF file format|The RSF file format<br />
** Reproducible computational experiments using SCons|Reproducibility with SCons<br />
* Developer documentation<br />
** Adding new programs to madagascar|Adding programs<br />
** Guide to madagascar API|API demo: clipping data<br />
** Guide to programming with madagascar|API demo: explicit finite differences<br />
** Maintenance_guide|Maintenance guide<br />
* Community<br />
** https://lists.sourceforge.net/lists/listinfo/rsf-user |User mailing list<br />
** https://lists.sourceforge.net/lists/listinfo/rsf-devel |Developer mailing list<br />
** http://sourceforge.net/projects/rsf/ |SourceForge project<br />
** conferences|Conferences<br />
** http://www.reproducibility.org/rsflog/ |Development blog</div>Jenningsjwjhttps://www.reproducibility.org/wiki2020/index.php?title=Contributing_new_programs_to_Madagascar&diff=461Contributing new programs to Madagascar2009-01-10T14:39:14Z<p>Jenningsjwj: /* Python 2.3 and older */</p>
<hr />
<div>[[Image:Fotolia_10977350_XS.jpg|right|]]<br />
This page is intended for developers maintaining Madagascar infrastructure and programs.<br />
<br />
==Style suggestions==<br />
Please try to:<br />
* Do [http://en.wikipedia.org/wiki/Atomic_commit atomic commits]<br />
* Use <tt>svn commit -m "your message here"</tt> to let others know what changed<br />
* If you plan to do large-scale substantive changes, use a repository [http://en.wikipedia.org/wiki/Branching_(software) branch]<br />
<br />
==Backward compatibility features==<br />
If you introduce or notice a feature that is used solely for backwards compatibility with an old version of a dependency, please document it here, so that the feature can be eliminated when the Madagascar community stops supporting that version of that dependency. This could be more elegantly done by using a special string to flag a backwards compatibility comment in the code, then have the documentation builder build this list automatically. This would make it more likely for this page to be kept in synch with the codebase.<br />
<br />
===Python 2.2 and older===<br />
* In <tt>framework/rsfdoc.py</tt>: Everything in the <tt>have_datetime_module=False</tt> branches<br />
<br />
===Python 2.3 and older===<br />
* In <tt>configure.py</tt>: Everything in the <tt>have_subprocess=False</tt> branches<br />
* In <tt>configure.py</tt>: See code after comment "For Py 2.4 and up this can be done more elegantly..."<br />
* In <tt>user/ivlad/ivlad.py</tt>: Everything in the <tt>have_subprocess=False</tt> branches<br />
* The entire <tt>api/python/rsfbak.py</tt> (also needed on systems which do not have recent versions of numpy ''and'' SWIG)<br />
<br />
==cfortran.h==<br />
This source code file provides a machine-independent interface between C procedures, Fortran procedures and global data (more details [http://www-zeus.desy.de/~burow/cfortran/ on the website of its initial author]). It is a dependency of the F77 and F90 APIs, as well as of vplot. It is included in m8r in two places. Version 4.3 (2002) is still distributed through the website of the original author. Another version (fork?) is [http://root.cern.ch/viewvc/trunk/montecarlo/eg/inc/cfortran.h?view=log maintained at CERN] and distributed in the include directory of the interface to event generators in the Monte Carlo libraries in the [http://cernlib.web.cern.ch/cernlib/ CERN Program Library] (CERNlib). Debian distributes the Free Software part of this package as <tt>cernlib</tt>. Under Fedora, <tt>cfortran.h</tt> is included in <tt>cernlib-g77-devel</tt> and <tt>cernlib-devel</tt>, which happily overwrite each other's files and create copies of <tt>cfortran.h</tt> in two different locations deeply nested under <tt>/usr/include</tt>. CERNlib's Debian maintainer states that [http://people.debian.org/~kmccarty/cernlib/index.html "CERNlib is an ancient mass of mostly Fortran code"] and that [http://people.debian.org/~kmccarty/physics-software-rant.html "Most components of CERNLIB are completely broken on modern 64-bit architectures"], so m8r developers should be aware that CERNlib will probably be superseded at some point in the future by [http://en.wikipedia.org/wiki/ROOT ROOT], with upstream <tt>cfortran.h</tt> maintenance possibly continuing this way.<br />
<br />
==Automated code checks==<br />
Madagascar contains the beginning of an implementation of static code checks for security vulnerabilities and coding mistakes with [http://www.splint.org/ Splint]. This is visible in the code through the presence of comments like <tt>/*@out@*/</tt> and <tt>/*@null@*/</tt>, which instruct Splint about the intent of different variables and function return values. Future plans include using also dynamic checking by [http://valgrind.org/ Valgrind] or IBM's [http://www-306.ibm.com/software/awdtools/purify/ Rational Purify].</div>Jenningsjwj