https://public.kitware.com/Wiki/api.php?action=feedcontributions&user=Newacct&feedformat=atomKitwarePublic - User contributions [en]2024-03-29T10:55:51ZUser contributionsMediaWiki 1.38.6https://public.kitware.com/Wiki/index.php?title=ITK/Examples/Broken/Statistics/ExpectationMaximizationMixtureModelEstimator_1D&diff=40516ITK/Examples/Broken/Statistics/ExpectationMaximizationMixtureModelEstimator 1D2011-06-08T23:34:37Z<p>Newacct: </p>
<hr />
<div>Someone please confirm that this outputs the mean and the variance (i.e. I used a standard deviation of 30 to create the samples and the second estimated parameter is near 1000 (~30^2) . Is this correct?)<br />
<br />
==ExpectationMaximizationMixtureModelEstimator_1D.cxx==<br />
<source lang="cpp"><br />
#include "itkVector.h"<br />
#include "itkListSample.h"<br />
#include "itkGaussianMixtureModelComponent.h"<br />
#include "itkExpectationMaximizationMixtureModelEstimator.h"<br />
#include "itkNormalVariateGenerator.h"<br />
<br />
int main(int, char*[])<br />
{<br />
unsigned int numberOfClasses = 2;<br />
typedef itk::Vector< double, 1 > MeasurementVectorType;<br />
typedef itk::Statistics::ListSample< MeasurementVectorType > SampleType;<br />
SampleType::Pointer sample = SampleType::New();<br />
<br />
typedef itk::Statistics::NormalVariateGenerator NormalGeneratorType;<br />
NormalGeneratorType::Pointer normalGenerator = NormalGeneratorType::New();<br />
<br />
normalGenerator->Initialize(101);<br />
<br />
MeasurementVectorType mv;<br />
double mean = 100;<br />
double standardDeviation = 30;<br />
for(unsigned int i = 0; i < 10; ++i )<br />
{<br />
mv[0] = ( normalGenerator->GetVariate() * standardDeviation ) + mean;<br />
std::cout << "m[" << i << "] = " << mv[0] << std::endl;<br />
sample->PushBack( mv );<br />
}<br />
<br />
normalGenerator->Initialize(3024);<br />
mean = 200;<br />
standardDeviation = 30;<br />
for(unsigned int i = 0; i < 10; ++i )<br />
{<br />
mv[0] = ( normalGenerator->GetVariate() * standardDeviation ) + mean;<br />
std::cout << "m[" << i << "] = " << mv[0] << std::endl;<br />
sample->PushBack( mv );<br />
}<br />
<br />
typedef itk::Array< double > ParametersType;<br />
ParametersType params1( 2 );<br />
<br />
std::vector< ParametersType > initialParameters( numberOfClasses );<br />
params1[0] = 110.0;<br />
params1[1] = 50.0;<br />
initialParameters[0] = params1;<br />
<br />
ParametersType params2( 2 );<br />
params2[0] = 210.0;<br />
params2[1] = 50.0;<br />
initialParameters[1] = params2;<br />
<br />
typedef itk::Statistics::GaussianMixtureModelComponent< SampleType > ComponentType;<br />
<br />
std::vector< ComponentType::Pointer > components;<br />
for ( unsigned int i = 0 ; i < numberOfClasses ; i++ )<br />
{<br />
components.push_back( ComponentType::New() );<br />
components[i]->SetSample( sample );<br />
components[i]->SetParameters( initialParameters[i] );<br />
}<br />
<br />
typedef itk::Statistics::ExpectationMaximizationMixtureModelEstimator<<br />
SampleType > EstimatorType;<br />
EstimatorType::Pointer estimator = EstimatorType::New();<br />
<br />
estimator->SetSample(sample);<br />
estimator->SetMaximumIteration(500);<br />
<br />
itk::Array< double > initialProportions(numberOfClasses);<br />
initialProportions[0] = 0.5;<br />
initialProportions[1] = 0.5;<br />
<br />
estimator->SetInitialProportions( initialProportions );<br />
<br />
for(unsigned int i = 0; i < numberOfClasses; i++)<br />
{<br />
estimator->AddComponent( (ComponentType::Superclass*)<br />
components[i].GetPointer() );<br />
}<br />
<br />
estimator->Update();<br />
<br />
for(unsigned int i = 0; i < numberOfClasses; i++ )<br />
{<br />
std::cout << "Cluster[" << i << "]" << std::endl;<br />
std::cout << " Parameters:" << std::endl;<br />
std::cout << " " << components[i]->GetFullParameters()<br />
<< std::endl;<br />
std::cout << " Proportion: ";<br />
std::cout << " " << estimator->GetProportions()[i] << std::endl;<br />
}<br />
<br />
return EXIT_SUCCESS;<br />
}<br />
</source><br />
{{ITKCMakeLists|ExpectationMaximizationMixtureModelEstimator_1D}}</div>Newaccthttps://public.kitware.com/Wiki/index.php?title=ITK/Examples/Broken/Statistics/ExpectationMaximizationMixtureModelEstimator_1D&diff=40515ITK/Examples/Broken/Statistics/ExpectationMaximizationMixtureModelEstimator 1D2011-06-08T23:33:43Z<p>Newacct: </p>
<hr />
<div>Someone please confirm that this outputs the mean and the variance (i.e. I used a standard deviation of 30 to create the samples and the second estimated parameter is near 1000 (~30^2) . Is this correct?)<br />
<br />
==ExpectationMaximizationMixtureModelEstimator_1D.cxx==<br />
<source lang="cpp"><br />
#include "itkVector.h"<br />
#include "itkListSample.h"<br />
#include "itkGaussianMixtureModelComponent.h"<br />
#include "itkExpectationMaximizationMixtureModelEstimator.h"<br />
#include "itkNormalVariateGenerator.h"<br />
<br />
int main(int, char*[])<br />
{<br />
unsigned int numberOfClasses = 2;<br />
typedef itk::Vector< double, 1 > MeasurementVectorType;<br />
typedef itk::Statistics::ListSample< MeasurementVectorType > SampleType;<br />
SampleType::Pointer sample = SampleType::New();<br />
<br />
typedef itk::Statistics::NormalVariateGenerator NormalGeneratorType;<br />
NormalGeneratorType::Pointer normalGenerator = NormalGeneratorType::New();<br />
<br />
normalGenerator->Initialize(101);<br />
<br />
MeasurementVectorType mv;<br />
double mean = 100;<br />
double standardDeviation = 30;<br />
for(unsigned int i = 0; i < 10; ++i )<br />
{<br />
mv[0] = ( normalGenerator->GetVariate() * standardDeviation ) + mean;<br />
std::cout << "m[" << i << "] = " << mv[0] << std::endl;<br />
sample->PushBack( mv );<br />
}<br />
<br />
normalGenerator->Initialize(3024);<br />
mean = 200;<br />
standardDeviation = 30;<br />
for(unsigned int i = 0; i < 10; ++i )<br />
{<br />
mv[0] = ( normalGenerator->GetVariate() * standardDeviation ) + mean;<br />
std::cout << "m[" << i << "] = " << mv[0] << std::endl;<br />
sample->PushBack( mv );<br />
}<br />
<br />
typedef itk::Array< double > ParametersType;<br />
ParametersType params1( 2 );<br />
<br />
std::vector< ParametersType > initialParameters( numberOfClasses );<br />
params1[0] = 110.0;<br />
params1[1] = 50.0;<br />
initialParameters[0] = params1;<br />
<br />
ParametersType params2( 2 );<br />
params2[0] = 210.0;<br />
params2[1] = 50.0;<br />
initialParameters[1] = params2;<br />
<br />
typedef itk::Statistics::GaussianMixtureModelComponent< SampleType > ComponentType;<br />
<br />
std::vector< ComponentType::Pointer > components;<br />
for ( unsigned int i = 0 ; i < numberOfClasses ; i++ )<br />
{<br />
components.push_back( ComponentType::New() );<br />
components[i]->SetSample( sample );<br />
components[i]->SetParameters( initialParameters[i] );<br />
}<br />
<br />
typedef itk::Statistics::ExpectationMaximizationMixtureModelEstimator<<br />
SampleType > EstimatorType;<br />
EstimatorType::Pointer estimator = EstimatorType::New();<br />
<br />
estimator->SetSample(sample);<br />
estimator->SetMaximumIteration(500);<br />
<br />
itk::Array< double > initialProportions(numberOfClasses);<br />
initialProportions[0] = 0.5;<br />
initialProportions[1] = 0.5;<br />
<br />
estimator->SetInitialProportions( initialProportions );<br />
<br />
for(unsigned int i = 0; i < numberOfClasses; i++)<br />
{<br />
estimator->AddComponent( (ComponentType::Superclass*)<br />
(components[i]).GetPointer() );<br />
}<br />
<br />
estimator->Update();<br />
<br />
for(unsigned int i = 0; i < numberOfClasses; i++ )<br />
{<br />
std::cout << "Cluster[" << i << "]" << std::endl;<br />
std::cout << " Parameters:" << std::endl;<br />
std::cout << " " << (components[i])->GetFullParameters()<br />
<< std::endl;<br />
std::cout << " Proportion: ";<br />
std::cout << " " << estimator->GetProportions()[i] << std::endl;<br />
}<br />
<br />
return EXIT_SUCCESS;<br />
}<br />
</source><br />
{{ITKCMakeLists|ExpectationMaximizationMixtureModelEstimator_1D}}</div>Newaccthttps://public.kitware.com/Wiki/index.php?title=ITK/Best_of_the_List&diff=40460ITK/Best of the List2011-06-07T03:57:52Z<p>Newacct: /* Invert Image Intensity */</p>
<hr />
<div>This is a collection of some of the most useful posts to the InsightUsers mailing list.<br />
<br />
== Setting up WinCVS ==<br />
<br />
You don't need to add `:pserver` to the `CVSROOT` text box in WinCVS.<br />
<br />
Simply go to "Admin" --> "Preferences", a popup window will appear containing several tabs. Take "General", then<br />
<br />
* in "Authentication", choose `pserver`<br />
* in "Path" set `/cvsroot/Insight`<br />
* in Host address set `www.itk.org`<br />
* in User name set `anoncvs`<br />
<br />
WinCVS will compose the `CVSROOT` entry for you. The CVSROOT entry will look like:<br />
<br />
anoncvs@www.itk.org:/cvsroot/Insight<br />
<br />
at that point you can go to "Admin" --> "Login".<br />
<br />
Note that WinCVS also allows you to write the classical comman line invokation. If you prefer this, just go to "Admin" --> "Command line".<br />
<br />
(Luis Ibanez, [http://www.itk.org/pipermail/insight-users/2004-May/008533.html original post], 15 May 2004)<br />
<br />
== Combining Images ==<br />
<br />
JoinImageFilter is designed to combine two input images into a single<br />
output vector image. For instance, you can give it two scalar images as<br />
input and the output will be have a vector at each pixel with two<br />
components. Or you can give it a scalar image and a vector image and the<br />
output will be a vector image. The "join" is in analagous to a database<br />
"join" query.<br />
<br />
I think you will need to use the PasteImageFilter. To do what you want, you<br />
will need to create an image that is the size of your two image sets<br />
combined, the run through two PasteImageFilters to paste the first image in<br />
the first part of the result and then a second PasteImageFilter to past the<br />
second image into the second part of the result.<br />
<br />
I have been meaning to put together an AppendImageFilter that will take two<br />
stacks of images and create a single image that has the two datasets<br />
appended along a designated axis.<br />
<br />
(Jim Miller, [http://public.kitware.com/pipermail/insight-users/2004-March/007364.html original], March 2004)<br />
<br />
== Tutorial: Segmenting Ventricles ==<br />
<br />
Here are the parameters that you can use with the `GeodesicActiveContourSegmentation` application (in InsightApplications), in<br />
order to segment the ventricles from one of the BrainWeb datasets.<br />
<br />
1. Load the BrainWeb image:<br />
<br />
`brainweb1e1a10f20.mha`<br />
<br />
2. In FastMarching<br />
1. Set the distance to 3.0<br />
2. Set Stopping value = 10.0<br />
<br />
3. In Gradient magnitude keep sigma = 1.2<br />
<br />
4. In Sigmoid keep alpha = -1, beta= 5.0<br />
<br />
5. In GeodesicActive contour do:<br />
<br />
1. RMS error = 0.01<br />
2. Iterations = 200<br />
3. Curvature scaling = 1.0<br />
4. Propagation scaling = 20.0<br />
5. Advection scaling = 20.0<br />
<br />
6. Place seed point at locations (or close to them)<br />
<br />
1. ( 67, 87, 87)<br />
2. (113, 87, 87)<br />
3. ( 85, 135, 87)<br />
4. ( 95, 135, 87)<br />
5. ( 78, 108, 97)<br />
6. (101, 108, 97)<br />
<br />
The reason why you may be getting always a sphere is that the weight of propagation and advection terms are too low in your case, so the front is not moving enough.<br />
<br />
The VTK visualization button is something that was never finished in this application. So it is normal (although it is not good)<br />
that the displayed window is all white.<br />
<br />
If you really want to see a volume rendering of the resulting segmentation, is is much easier now to use VolView and its ITK Geodesic Active Contour plugin. You can download the free version of VolView from:<br />
<br />
* http://www.kitware.com/products/volview.html<br />
<br />
(Luis Ibanez, [http://www.itk.org/pipermail/insight-users/2004-April/007770.html original post], 7 April 2004)<br />
<br />
== Adding Noise to Images ==<br />
<br />
It is frequently useful to add different types of noise to images, for the purposes of validation and testing. You can use the [http://www.itk.org/Insight/Doxygen/html/classitk_1_1RandomImageSource.html Random image source] in order to generate a pure noise image. Then use the [http://www.itk.org/Insight/Doxygen/html/classitk_1_1AddImageFilter.html AddImageFilter] in order to add the noise to an input image, for simulating "additive" noise.<br />
<br />
You could use the [http://www.itk.org/Insight/Doxygen/html/classitk_1_1MultiplyImageFilter.html MultiplyImageFilter] for simulating multiplicative noise.<br />
<br />
You can also use classes from the Statistics framework as noise generators. Please look at the [http://www.itk.org/ItkSoftwareGuide.pdf SoftwareGuide] in Section 10.2.7, pdf-page 462.<br />
<br />
You will find a detailed description of ITK denoising (or smoothing) filters in the software guide Section 6.5, pdf-page 167 to 197.<br />
<br />
(Luis Ibanez, [http://www.itk.org/pipermail/insight-users/2003-December/005855.html original post], December 2003)<br />
<br />
== Invert Image Intensity ==<br />
<br />
There is not currently a filter to invert the intensity of an image (ie. make a negative). This example nicely illustrates the use of image functors, and how easy it is to extend ITK with only a little code.<br />
<br />
First we define a functor class that is applied to each pixel in the image:<br />
<br />
template <class InputPixelType><br />
struct InvertIntensityFunctor<br />
{<br />
InputPixelType operator()( InputPixelType input )<br />
{<br />
return NumericTraits<InputPixelType>::max() - input;<br />
}<br />
};<br />
<br />
Then we declare a unary functor with the inverter as a parameter, thus:<br />
<br />
typedef itk::UnaryFunctorImageFilter<<br />
InputImageType,<br />
InputImageType,<br />
InvertIntensityFunctor<typename InputImageType::PixelType> ><br />
InverterType;<br />
<br />
You can then insert this image filter into your pipeline just like any other image filter.<br />
<br />
(From insight-users... where?)<br />
<br />
{{ITK/Template/Footer}}</div>Newaccthttps://public.kitware.com/Wiki/index.php?title=CDash:Database&diff=26754CDash:Database2010-08-08T07:22:47Z<p>Newacct: </p>
<hr />
<div>In this section we discuss the coding design related to the database. Currently CDash supports MySQL and PostGreSQL so make sure the code you write, especially the SQL queries are working for both instances.<br />
<br />
= Adding/Changing database fields =<br />
When adding, removing or changing fields to an existing table, follow the following instructions<br />
<br />
* Edit the SQL files to reflect your changes<br />
** cdash/sql/mysql/cdash.sql (for new installations)<br />
** cdash/sql/pgsql/cdash.sql (for new installations)<br />
<br />
* Edit backwardCompatibilityTools.php<br />
** Search for the upgrade section upgrade-A-B where A.B represents the major.minor version of the upcoming stable release<br />
** Use the AddTableField(), AddTableIndex(), ModifyTableField(), etc... functions. These functions make sure that if the query is called twice it doesn't modify the schema again.<br />
** PGSQL doesn't like the "ON UPDATE" function in the schema, so avoid it and do the update manually in your queries.<br />
<br />
= Creating a completely new table =<br />
To add a completely new table you just need to edit:<br />
<br />
* cdash/sql/mysql/cdash.sql (for new installations)<br />
* cdash/sql/pgsql/cdash.sql (for new installations)<br />
* cdash/sql/mysql/cdash-upgrade-A.B-C.D (for current installation)<br />
* cdash/sql/pgsql/cdash-upgrade-A.B-C.D (for current installation)<br />
<br />
Where A.B is the major.minor version of the current stable release and C.D is the major.minor version of the upcoming stable release.<br />
<br />
= Automatic translation to PGSQL =<br />
The postgres layer in cdash relies on some of the features of the mysqlcompat <br />
package: http://pgfoundry.org/projects/mysqlcompat<br />
<br />
The following patch to the mysqlcompat package is required to use it with recent versions of PostgreSQL:<br />
http://public.kitware.com/Wiki/images/d/d0/Mysqlcompat.txt<br />
<br />
(Note that this *is* actually a patch file, but the CDash wiki doesn't allow upload of files ending with ".patch".)<br />
<br />
== Installation on Ubuntu ==<br />
<br />
apt-get install libsql-translator-perl<br />
<br />
Then run the script <br />
<br />
CDash/sql/convert.sh<br />
<br />
'''Warning''' The indexes generated by the script are all the same so you would need to prepend the table name.</div>Newaccthttps://public.kitware.com/Wiki/index.php?title=Talk:CMake:ConvertFromQmake&diff=25838Talk:CMake:ConvertFromQmake2010-07-28T06:17:49Z<p>Newacct: </p>
<hr />
<div>== bash Script ==<br />
<br />
Hi!<br />
<br />
I'm sorry to say that, but for me the ruby-script didn't work at all. But I don't talk ruby, so I wrote a simple bash-script to do the grunt work for a simple qmake-project. Here it comes, I hope you find it useful... it requires what most bash-scripts require: sed, awk, grep, and ofcourse cmake...<br />
<br />
<source lang=bash><br />
#!/bin/bash<br />
<br />
###############################################################################<br />
#<br />
# CMakeLists.txt - Generator<br />
#<br />
###############################################################################<br />
# This script tries to create a basic CMakeLists.txt from an existing *.pro<br />
# qmake-projectfile<br />
###############################################################################<br />
# Parameters: $1 = projectfile<br />
###############################################################################<br />
prof=$(basename $1)<br />
odir=$CWD<br />
cd $(dirname $1)<br />
pro=${prof/\.pr?/}<br />
out=CMakeLists.txt<br />
<br />
ext=""<br />
for ((i=0; i<${#pro} ; i++)) ; do ext="${ext}#" ; done<br />
rm $out<br />
echo -e "\<br />
################################################$ext\n\<br />
# CMakeLists.txt generated from qmake-project $pro #\n\<br />
################################################$ext\n" >> $out<br />
echo "# ... Project setup ..." >> $out<br />
echo "project($pro)" >> $out<br />
mive=$(cmake --version | sed 's/[a-zA-Z\s-]*//g' | awk '{print $1}')<br />
echo "cmake_minimum_required(VERSION $mive)" >> $out<br />
<br />
# we've got a qmake project, so I guess we need to link QT<br />
# -> we'll need CMP0003 directive ...<br />
echo -e "if(COMMAND cmake_policy)\n\<br />
\tcmake_policy(SET CMP0003 NEW)\nendif(COMMAND cmake_policy)\n" >> $out<br />
<br />
# Now let's not care about what really stands in "CONFIG", just use alot...<br />
echo -e "\<br />
# ########## Qt4 setup ##########\n\<br />
FIND_PACKAGE(Qt4 REQUIRED)\n\<br />
INCLUDE(\${QT_USE_FILE})\n\<br />
INCLUDE_DIRECTORIES(\${CMAKE_SOURCE_DIR} \${QT_INCLUDES})\n\<br />
ADD_DEFINITIONS(-DQT_GUI_LIBS -DQT_CORE_LIB)\n" >> $out<br />
<br />
# finally we could traverse the qmake project file ...<br />
sources=$(egrep "^SOURCES" $prof | sed -e 's/SOURCES//' -e 's/+=//')<br />
headers=$(egrep "^HEADERS" $prof | sed -e 's/HEADERS//' -e 's/+=//')<br />
forms=$(egrep "^FORMS" $prof | sed -e 's/FORMS//' -e 's/+=//')<br />
resources=$(egrep "^RESOURCES" $prof | sed -e 's/RESOURCES//' -e 's/+=//')<br />
transl=$(egrep "^TRANSLATIONS" $prof | sed -e 's/TRANSLATIONS//' -e 's/+=//')<br />
<br />
echo -e "# Source files\nSET(SRCS\n\t$sources\n)\n" >> $out<br />
echo -e "# Header files\nSET(HDRS\n\t$headers\n)\n" >> $out<br />
if [ -n "$resources" ]<br />
then echo -e "# Resource files\nSET(RSCS\n\t$resources\n)\n" >> $out<br />
fi<br />
if [ -n "$transl" ]<br />
then echo -e "# Translation files\nSET(TRANS\n\t$transl\n)\n" >> $out<br />
fi<br />
<br />
final=""<br />
<br />
if [ -n "$forms" ]<br />
then # Forms is not empty - we need the uic-wrapper and a moc wrapper<br />
echo -e "# UI files\nSET(UIS\n\t$forms\n)\n" >> $out<br />
<br />
# if we have forms, we will also need the moc wrapper. But what are<br />
# the moc-files? Just running moc on the Header files and inspecting<br />
# the output for error-messages should suffice ;)<br />
mocs=""<br />
for head in $headers<br />
do<br />
moc $head 1> /dev/null 2> __erg__<br />
erg=$(cat __erg__)<br />
if [ -z "$erg" ] # nothing recorded - no error -> do it!<br />
then mocs="$mocs $head"<br />
fi<br />
done<br />
if [ -n "$mocs" ]<br />
then<br />
echo -e "# Headers to be moc'ed ...\nSET(MOCH\n\t$mocs\n)\n" >> $out<br />
echo -e "# MOC-wrapper for Metadata stuff\nQT4_WRAP_CPP(MOC \${MOCH})\n" >> $out<br />
final="$final \${MOC}"<br />
fi<br />
<br />
echo -e "# UIC-wrapper for used forms\nQT4_WRAP_UI(UI_H \${UIS})\n" >> $out<br />
final="$final \${UI_H}"<br />
fi<br />
<br />
if [ -n "$transl" ]<br />
then<br />
echo -e "# add translations ...\nQT4_ADD_TRANSLATION(QM \${TRANS})\n" >> $out<br />
final="$final \${QM}"<br />
fi<br />
<br />
if [ -n "$resources" ]<br />
then # Resources are not empty - so lets add them<br />
echo -e "# add Resource files ...\nQT4_ADD_RESOURCES(QRC \${RSCS})\n" >> $out<br />
final="$final \${QRC}"<br />
fi<br />
<br />
echo -e "# And now - for the final steps ...\n\<br />
ADD_EXECUTABLE($pro \${HDRS} \${SRCS}$final)\n\<br />
TARGET_LINK_LIBRARIES($pro \${QT_LIBRARIES})\n\n# finally the installer\n\<br />
INSTALL(TARGETS $pro DESTINATION bin)" >> $out<br />
<br />
rm __erg__<br />
cd $odir<br />
</source><br />
<br />
I hope you find it useful. For very simple QMake-Projects it probably works better than the ruby-example. Maybe you'll add it to the wiki as I don't feel to have the right to do that.<br />
<br />
Cheers, St0fF<br />
<br />
== Examples of qmake to CMake conversions? ==<br />
<br />
For people with simple QMake scripts it would be great to have one or more simple examples showing a qmake script and the corresponding CMake script. --[[User:Colinb|Colinb]] 20:08, 18 March 2010 (UTC)</div>Newaccthttps://public.kitware.com/Wiki/index.php?title=ParaView/Simple_ParaView_3_Python_Filters&diff=22170ParaView/Simple ParaView 3 Python Filters2010-04-28T05:50:10Z<p>Newacct: </p>
<hr />
<div>== Examples of Filters Programmed using the Python Programmable Filter ==<br />
<br />
It would be nice, if you have written a possibly useful pp-filter, if you would add the code to this page. Here are some simple examples. <br />
<br />
<font color=blue>'''Note:''' These scripts are meant to be used at values for the '''Script''' paramaters for '''Programmable Filter''' or '''Programmable Source''' as identified by the title. These will not directly work from the python shell or pvpython.</font><br />
<br />
==CSV Reader (Source) ==<br />
<source lang="python"><br />
# This source reads a text file and produces a data set<br />
# The file is of the form (where [denotes optional and repeatable]:<br />
# X,Y,Z[,ARRAYNAME]<br />
# x0,y0,z0[,value]<br />
# x1,y1,z1[,value]<br />
# ...<br />
from paraview import vtk<br />
import os<br />
pts = vtk.vtkPoints()<br />
firstline = True<br />
filename = os.path.normcase("c:/datafile.txt")<br />
f = open(filename)<br />
pdo = self.GetOutput()<br />
for line in f:<br />
if firstline:<br />
#skip first line, presumed to be a header<br />
firstline = False<br />
for pos,word in enumerate(line.split(",")):<br />
if pos > 2:<br />
newArray = vtk.vtkDoubleArray()<br />
newArray.SetName(word)<br />
newArray.SetNumberOfComponents(1)<br />
pdo.GetPointData().AddArray(newArray)<br />
else:<br />
for pos,word in enumerate(line.split(",")):<br />
print word<br />
if pos == 0:<br />
x = float(word)<br />
if pos == 1:<br />
y = float(word)<br />
if pos == 2:<br />
z = float(word)<br />
if pos > 2:<br />
array = pdo.GetPointData().GetArray(pos-3)<br />
array.InsertNextValue(float(word))<br />
pts.InsertNextPoint(x,y,z)<br />
pdo.SetPoints(pts)<br />
</source><br />
<br />
==Tetrahedra Volume (Filter) ==<br />
<source lang="python"><br />
# This filter computes the volume of the tetrahedra in an unstructured mesh:<br />
pdi = self.GetInput()<br />
pdo = self.GetOutput()<br />
newData = vtk.vtkDoubleArray()<br />
newData.SetName("Volume")<br />
numTets = pdi.GetNumberOfCells()<br />
for i in range(numTets):<br />
cell = pdi.GetCell(i)<br />
p1 = pdi.GetPoint(cell.GetPointId(0))<br />
p2 = pdi.GetPoint(cell.GetPointId(1))<br />
p3 = pdi.GetPoint(cell.GetPointId(2))<br />
p4 = pdi.GetPoint(cell.GetPointId(3))<br />
volume = vtk.vtkTetra.ComputeVolume(p1,p2,p3,p4)<br />
newData.InsertNextValue(volume)<br />
pdo.GetCellData().AddArray(newData)<br />
</source><br />
<br />
==Tetrahedra Radius (Filter) ==<br />
<source lang="python"><br />
# This filter computes the radius h of the tetrahedra in an unstructured mesh:<br />
# Adapted by Johan Jansson (jjan@csc.kth.se) <br />
from math import *<br />
pdi = self.GetInput()<br />
pdo = self.GetOutput()<br />
newData = vtk.vtkDoubleArray()<br />
newData.SetName("h")<br />
numTets = pdi.GetNumberOfCells()<br />
for i in range(numTets):<br />
cell = pdi.GetCell(i)<br />
p1 = pdi.GetPoint(cell.GetPointId(0))<br />
p2 = pdi.GetPoint(cell.GetPointId(1))<br />
p3 = pdi.GetPoint(cell.GetPointId(2))<br />
p4 = pdi.GetPoint(cell.GetPointId(3))<br />
c = [0.0, 0.0, 0.0]<br />
h = vtk.vtkTetra.Circumsphere(p1,p2,p3,p4,c)<br />
# VTK actually computes the square<br />
h = sqrt(h)<br />
newData.InsertNextValue(h)<br />
pdo.GetCellData().AddArray(newData)<br />
</source><br />
<br />
==Flip Tetrahedra (Filter)==<br />
<source lang="python"><br />
# This filter flips the tetrahedra (useful, if you have different convention of <br />
# tet orientation than VTK, and wish to use the vtkMeshQuality filter).<br />
pdi = self.GetInput()<br />
pdo = self.GetOutput()<br />
numTets = pdi.GetNumberOfCells()<br />
newcells = vtk.vtkCellArray()<br />
for i in range(numTets):<br />
cell = pdi.GetCell(i)<br />
i1 = cell.GetPointId(0)<br />
i2 = cell.GetPointId(1)<br />
i3 = cell.GetPointId(2)<br />
i4 = cell.GetPointId(3)<br />
newcells.InsertNextCell(4)<br />
newcells.InsertCellPoint(i1)<br />
newcells.InsertCellPoint(i2)<br />
newcells.InsertCellPoint(i4)<br />
newcells.InsertCellPoint(i3)<br />
pdo.SetCells( 10, newcells )<br />
</source><br />
<br />
<br />
==Helix (Source)==<br />
This is intended as the Python script for a 'Programmable Source'. It generates a helix with two sets of scalar data defined along the helix. The scalar data can be visualized using filters such as the 'tube' filter where the scalar value is represented as a color. The scalar called 'First Property' or the scalar called 'Second Property' can be chosen from the 'Display' tab of the 'tube' filter under the 'Color by' option. This lists the available scalars that are defined at points along the helix.<br />
<source lang="python"><br />
#This script generates a helix curve.<br />
#This is intended as the script of a 'Programmable Source'<br />
import math<br />
<br />
numPts = 80.0 # Points along Helix<br />
length = 8.0 # Length of Helix<br />
rounds = 3.0 # Number of times around <br />
<br />
#Get a vtk.PolyData object for the output<br />
pdo = self.GetPolyDataOutput()<br />
<br />
#This will store the points for the Helix<br />
newPts = vtk.vtkPoints()<br />
<br />
#Associate scalar values with the points.<br />
#Also set the name for the scalar that will be<br />
#visible in Paraview dropdown lists for setting<br />
#color along the helix.<br />
vals1 = vtk.vtkDoubleArray()<br />
vals1.SetName('First Property')<br />
vals2 = vtk.vtkDoubleArray()<br />
vals2.SetName('Second Property')<br />
<br />
for i in range(numPts):<br />
#Generate the Points along the Helix<br />
x = i*length/numPts<br />
y = math.sin(i*rounds*2*math.pi/numPts)<br />
z = math.cos(i*rounds*2*math.pi/numPts)<br />
#Insert the Points into the vtkPoints object<br />
#The first parameter indicates the reference.<br />
#value for the point. Here we add the sequentially.<br />
#Note that the first point is at index 0 (not 1).<br />
newPts.InsertPoint(i, x,y,z)<br />
<br />
#Order of Scalars should match order Pts were added<br />
vals1.InsertNextValue(i)<br />
vals2.InsertNextValue(math.sin(i*2.0*math.pi/numPts)) <br />
<br />
#Add the points to the vtkPolyData object<br />
#Right now the points are not associated with a line - <br />
#it is just a set of unconnected points. We need to<br />
#create a 'cell' object that ties points together<br />
#to make, in this case, a curve. This is done below.<br />
#A 'cell' is just an object that tell how points are<br />
#connected to make a 1D, 2D, or 3D object.<br />
pdo.SetPoints(newPts) <br />
<br />
# Add the scalar point data<br />
pdo.GetPointData().SetScalars(vals1) #'First Property' scalar<br />
pdo.GetPointData().AddArray(vals2) #'Second Property' scalar<br />
<br />
#Make a vtkPolyLine which holds the info necessary<br />
#to create a curve composed of line segments. This<br />
#really just hold constructor data that will be passed<br />
#to vtkPolyData to add a new line.<br />
aPolyLine = vtk.vtkPolyLine()<br />
<br />
#Indicate the number of points along the line<br />
aPolyLine.GetPointIds().SetNumberOfIds(numPts)<br />
for i in range(numPts):<br />
#Add the points to the line. The first value indicates<br />
#the order of the point on the line. The second value<br />
#is a reference to a point in a vtkPoints object. Depends<br />
#on the order that Points were added to vtkPoints object.<br />
#Note that this will not be associated with actual points<br />
#until it is added to a vtkPolyData object which holds a<br />
#vtkPoints object.<br />
aPolyLine.GetPointIds().SetId(i, i)<br />
<br />
#Allocate the number of 'cells' that will be added. We are just<br />
#adding one vtkPolyLine 'cell' to the vtkPolyData object.<br />
pdo.Allocate(1, 1) <br />
<br />
#Add the poly line 'cell' to the vtkPolyData object.<br />
pdo.InsertNextCell(aPolyLine.GetCellType(), aPolyLine.GetPointIds()) <br />
<br />
#The Helix is ready to plot! Click 'Apply'.<br />
</source><br />
<br />
<br />
==Producing Data with Timesteps (Source)==<br />
<br />
This example demonstrates how to write a source which produces multiple timesteps. There's one caveat. Currently ParaView client does not notice the timesteps produced by the source and hence the GUI will not update the animation time ranges automatically, as is the case for standard reader.<br />
<br />
===Script(RequestInformation)===<br />
<source lang="python"><br />
def SetOutputTimesteps(algorithm, timesteps):<br />
executive = algorithm.GetExecutive()<br />
outInfo = executive.GetOutputInformation(0)<br />
outInfo.Remove(executive.TIME_STEPS())<br />
for timestep in timesteps:<br />
outInfo.Append(executive.TIME_STEPS(), timestep)<br />
outInfo.Remove(executive.TIME_RANGE())<br />
outInfo.Append(executive.TIME_RANGE(), timesteps[0])<br />
outInfo.Append(executive.TIME_RANGE(), timesteps[-1])<br />
SetOutputTimesteps(self, (0, 10, 20, 30))<br />
</source><br />
<br />
===Script (RequestData)===<br />
<source lang="python"><br />
<br />
def GetUpdateTimesteps(algorithm):<br />
executive = algorithm.GetExecutive()<br />
outInfo = executive.GetOutputInformation(0)<br />
if not outInfo.Has(executive.UPDATE_TIME_STEPS()):<br />
return []<br />
count = outInfo.Length(executive.UPDATE_TIME_STEPS())<br />
timesteps = [outInfo.Get(executive.UPDATE_TIME_STEPS(), cc)<br />
for cc in range(count)]<br />
return timesteps<br />
<br />
# This is the requested time-step. This may not be exactly equal to the <br />
# timesteps published in RequestInformation(). Your code must handle that<br />
# correctly<br />
req_timesteps = GetUpdateTimesteps(self)<br />
<br />
output = self.GetOutput()<br />
<br />
# TODO: Generate the data as you want.<br />
<br />
# Now mark the timestep produced.<br />
output.GetInformation().Remove(output.DATA_TIME_STEPS())<br />
output.GetInformation().Append(output.DATA_TIME_STEPS(), req_timesteps[0])<br />
</source><br />
<br />
{{ParaView/Template/Footer}}</div>Newaccthttps://public.kitware.com/Wiki/index.php?title=CDash:Dart2AndCDashSubmission&diff=18652CDash:Dart2AndCDashSubmission2009-12-24T05:59:43Z<p>Newacct: </p>
<hr />
<div>[[CDash | < CDash Main Page]]<br />
<br />
== Setting up dual Dart2 and CDash Submissions ==<br />
If you are moving from Dart2 to CDash you may want to submit to both dashboards in parallel for a while, before switching solely to CDash.<br />
<br />
The following shows how to setup CTest to use a trigger script, which in turn does a submit to both Dart2 (via XML-RPC) and CDash (via HTTP).<br />
<br />
Note: This method doesn't support submission of Dart2 notes files.<br />
<br />
Configure CTest to use a trigger script:<br />
<br />
SET (CTEST_DROP_METHOD "http")<br />
SET (CTEST_DROP_SITE "mysite.org")<br />
SET (CTEST_DROP_LOCATION "/cgi-bin/HTTPUploadDartFile.cgi")<br />
SET (CTEST_TRIGGER_SITE "http://${DROP_SITE}/cgi-bin/TriggerSiteDart2AndCDash.cgi")<br />
<br />
Both <tt>HTTPUploadDartFile.cgi</tt> and <tt>TriggerSiteDart2AndCDash.cgi</tt> have a hard coded path that may require editing: <tt>/srv/dart2/incoming</tt><br />
<br />
''This current implementation only supports a single hard coded project in <tt>TriggerSiteDart2AndCDash.cgi</tt>. You can of course create a specific trigger site per project to workaround this.''<br />
<br />
=== HTTPUploadDartFile.cgi ===<br />
<br />
#!/usr/bin/env python<br />
#<br />
# Script that will upload files to specified directory on the server, where<br />
# triggering script will find it.<br />
#<br />
# Installation:<br />
# Place this script in your cgi-bin area.<br />
# Change the variable "incoming_directory" to match your<br />
# installation.<br />
###<br />
<br />
import cgi<br />
import re<br />
import sys<br />
import os<br />
<br />
print "Content-type: text/html"<br />
print<br />
<br />
done = 0<br />
<br />
incoming_directory = '/srv/dart2/incoming'<br />
<br />
form = cgi.FieldStorage()<br />
<br />
# Debug<br />
#try:<br />
# tmpfile = open("/tmp/http_upload_log_file.log", "w")<br />
# tmpfile.write(`form`)<br />
# tmpfile.close()<br />
#except Exception: pass<br />
<br />
FileData = ""<br />
FileName = ""<br />
<br />
# process form<br />
if type(form.value) == type("foo"):<br />
if "QUERY_STRING" in os.environ:<br />
dt = cgi.parse_qs(os.environ["QUERY_STRING"])<br />
if "FileName" in dt:<br />
FileName = dt["FileName"][0]<br />
FileData = form.value<br />
elif "FileName" in form:<br />
FileName = form["FileName"].value<br />
if "FileData" in form:<br />
FileData = "form"<br />
<br />
# verify file specified<br />
if not FileData or not FileName:<br />
print "Please send file. "<br />
print "FileName has to contain file name"<br />
print "FileData has to contain file content"<br />
print form<br />
sys.exit(0)<br />
<br />
print "Received file: " + FileName<br />
<br />
# check if valid file name<br />
filename = re.sub("[/\\|:%%]", "_", FileName)<br />
if re.match(".+___.+___[0-9]{8}-[0-9]{4}-(Experimental|Nightly|Continuous)___XML___(Update|Configure|Build|Test|Coverage|Purify).xml", filename):<br />
print "Correct file name"<br />
else:<br />
print "Can only upload files with format:"<br />
print "<site>___<BuildType>___<TAG>-<TestType>___XML___<File>.xml"<br />
sys.exit(0)<br />
<br />
# get the file data<br />
file_lines = ""<br />
if FileData == "form":<br />
fileitem = form["FileData"]<br />
if fileitem.file:<br />
file_lines = fileitem.file.read()<br />
else:<br />
print "Not a file"<br />
else:<br />
file_lines = FileData<br />
<br />
# write to a file on disk<br />
if file_lines:<br />
file = open(incoming_directory + "/" + filename, "w")<br />
if not file:<br />
print "Cannot create file: %s/%s" % ( incoming_directory, filename )<br />
sys.exit(0)<br />
file.write(file_lines)<br />
file.close()<br />
print "Thank you for the file"<br />
done = 1<br />
<br />
if not done:<br />
print "Problem summiting data"<br />
<br />
=== TriggerSiteDart2AndCDash.cgi ===<br />
Note: If the script fails it will create log files in <tt>/tmp/tmp*.html</tt>.<br />
<br />
#!/usr/bin/env python<br />
#<br />
# Script that will resubmit incoming testing results to<br />
# Dart2 (via XMLRPC) and CDash (via HTTP).<br />
#<br />
# This scripts intended use is to allow the transition from<br />
# Dart2 to CDash, by allowing both to be run in parallel.<br />
#<br />
###<br />
<br />
import cgi<br />
import cgitb; cgitb.enable(display=0, logdir="/tmp")<br />
<br />
import sys<br />
import os<br />
import xmlrpclib<br />
import put<br />
<br />
def Trigger(dart2Url, cdashUrl, projectName, dropLocation):<br />
print "Content-Type: text/html"<br />
print<br />
<br />
form = cgi.FieldStorage()<br />
xmlfile = ""<br />
if "xmlfile" in form:<br />
xmlfile = form["xmlfile"].value<br />
<br />
if not xmlfile:<br />
print "No submission file"<br />
sys.exit(1)<br />
<br />
ipfile = dropLocation + xmlfile<br />
<br />
try:<br />
dart2Server = xmlrpclib.ServerProxy(dart2Url + projectName + "/Command/")<br />
<br />
try:<br />
fp = open(ipfile)<br />
content = fp.read()<br />
bin = xmlrpclib.Binary(content)<br />
print "Server responded: [%s]" % dart2Server.Submit.put(bin)<br />
fp.close()<br />
except Exception, v:<br />
print "ERROR", v<br />
print "Unexpected error:", sys.exc_info()<br />
except:<br />
print "Problem submitting XML-RPC for the file: %s" % xmlfile<br />
<br />
try:<br />
cdashServer = cdashUrl + "CDash/submit.php?project=" + projectName<br />
<br />
f = open(ipfile, 'rb')<br />
put.putfile(f, cdashServer)<br />
f.close()<br />
except:<br />
print "Problem submitting HTTP for the file: %s" % xmlfile<br />
<br />
os.unlink(ipfile)<br />
<br />
<br />
if __name__ == "__main__":<br />
# Ensure all paths have a trailing slash<br />
# Dart2 URL, CDash URL, project, incoming directory<br />
Trigger("http://localhost:8081/", "http://localhost/", "MyProject", "/srv/dart2/incoming/")<br />
<br />
=== put.py ===<br />
<br />
Note: This version of ''put'' requires Apache2 (for chunking).<br />
<br />
#!/usr/bin/env python<br />
"""<br />
put.py - Python HTTP PUT Client<br />
Author: Sean B. Palmer, inamidst.com<br />
<br />
Basic API usage, once with optional auth:<br />
<br />
import put<br />
put.putname('test.txt', 'http://example.org/test')<br />
<br />
f = open('test.txt', 'rb')<br />
put.putfile(f, 'http://example.org/test')<br />
f.close()<br />
<br />
bytes = open('test.txt', 'rb').read()<br />
auth = {'username': 'myuser', 'password': 'mypass'}<br />
put.put(bytes, 'http://example.org/test', **auth)<br />
"""<br />
<br />
import sys, httplib, urlparse<br />
from optparse import OptionParser<br />
<br />
# True by default when running as a script<br />
# Otherwise, we turn the noise off...<br />
verbose = True<br />
<br />
def barf(msg):<br />
print >> sys.stderr, "Error! %s" % msg<br />
sys.exit(1)<br />
<br />
if sys.version_info < (2, 4):<br />
barf("Requires Python 2.4+")<br />
<br />
def parseuri(uri):<br />
"""Parse URI, return (host, port, path) tuple.<br />
<br />
>>> parseuri('http://example.org/testing?somequery#frag')<br />
('example.org', 80, '/testing?somequery')<br />
>>> parseuri('http://example.net:8080/test.html')<br />
('example.net', 8080, '/test.html')<br />
"""<br />
<br />
scheme, netplace, path, query, fragid = urlparse.urlsplit(uri)<br />
<br />
if ':' in netplace:<br />
host, port = netplace.split(':', 2)<br />
port = int(port)<br />
else: host, port = netplace, 80<br />
<br />
if query: path += '?' + query<br />
<br />
return host, port, path<br />
<br />
def putfile(f, uri, username=None, password=None):<br />
"""HTTP PUT the file f to uri, with optional auth data."""<br />
host, port, path = parseuri(uri)<br />
<br />
redirect = set([301, 302, 307])<br />
authenticate = set([401])<br />
okay = set([200, 201, 204])<br />
<br />
authorized = False<br />
authorization = None<br />
tries = 0<br />
<br />
while True:<br />
# Attempt to HTTP PUT the data<br />
h = httplib.HTTPConnection(host, port)<br />
<br />
h.putrequest('PUT', path)<br />
<br />
h.putheader('User-Agent', 'put.py/1.0')<br />
h.putheader('Connection', 'keep-alive')<br />
h.putheader('Transfer-Encoding', 'chunked')<br />
h.putheader('Expect', '100-continue')<br />
h.putheader('Accept', '*/*')<br />
if authorization:<br />
h.putheader('Authorization', authorization)<br />
h.endheaders()<br />
<br />
# Chunked transfer encoding<br />
# Cf. 'All HTTP/1.1 applications MUST be able to receive and<br />
# decode the "chunked" transfer-coding'<br />
# - http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html<br />
while True:<br />
bytes = f.read(2048)<br />
if not bytes: break<br />
length = len(bytes)<br />
h.send('%X\r\n' % length)<br />
h.send(bytes + '\r\n')<br />
h.send('0\r\n\r\n')<br />
f.seek(0);<br />
<br />
resp = h.getresponse()<br />
status = resp.status # an int<br />
<br />
# Got a response, now decide how to act upon it<br />
if status in redirect:<br />
location = resp.getheader('Location')<br />
uri = urlparse.urljoin(uri, location)<br />
host, port, path = parseuri(uri)<br />
<br />
# We may have to authenticate again<br />
if authorization:<br />
authorization = None<br />
<br />
elif status in authenticate:<br />
# If we've done this already, break<br />
if authorization:<br />
# barf("Going around in authentication circles")<br />
<br />
barf("Authentication failed")<br />
<br />
if not (username and password):<br />
barf("Need a username and password to authenticate with")<br />
<br />
# Get the scheme: Basic or Digest?<br />
wwwauth = resp.msg['www-authenticate'] # We may need this again<br />
wauth = wwwauth.lstrip(' \t') # Hence use wauth not wwwauth here<br />
wauth = wwwauth.replace('\t', ' ')<br />
i = wauth.index(' ')<br />
scheme = wauth[:i].lower()<br />
<br />
if scheme in set(['basic', 'digest','Basic','Digest']):<br />
if verbose:<br />
msg = "Performing %s Authentication..." % scheme.capitalize()<br />
else: barf("Unknown authentication scheme: %s" % scheme)<br />
<br />
if scheme == 'basic' or scheme == 'Basic':<br />
userpass = username + ':' + password<br />
userpass = userpass.encode('base64').strip()<br />
authorized, authorization = True, 'Basic ' + userpass<br />
<br />
elif scheme == 'digest':<br />
if verbose:<br />
msg = "uses fragile, undocumented features in urllib2"<br />
<br />
print >> sys.stderr, "Warning! Digest Auth %s" % msg<br />
<br />
import urllib2 # See warning above<br />
<br />
passwd = type('Password', (object,), {<br />
'find_user_password': lambda self, *args: (username, password),<br />
'add_password': lambda self, *args: None<br />
})()<br />
<br />
req = type('Request', (object,), {<br />
'get_full_url': lambda self: uri,<br />
'has_data': lambda self: None,<br />
'get_method': lambda self: 'PUT',<br />
'get_selector': lambda self: path<br />
})()<br />
<br />
# Cf. urllib2.AbstractDigestAuthHandler.retry_http_digest_auth<br />
auth = urllib2.AbstractDigestAuthHandler(passwd)<br />
token, challenge = wwwauth.split(' ', 1)<br />
chal = urllib2.parse_keqv_list(urllib2.parse_http_list(challenge))<br />
userpass = auth.get_authorization(req, chal)<br />
authorized, authorization = True, 'Digest ' + userpass<br />
<br />
elif status in okay:<br />
if (username and password) and (not authorized):<br />
msg = "Warning! The supplied username and password went unused"<br />
print msg<br />
<br />
if verbose:<br />
resultLine = "Success! Resource %s"<br />
statuses = {200: 'modified', 201: 'created', 204: 'modified'}<br />
print resultLine % statuses[status]<br />
<br />
statusLine = "Response-Status: %s %s"<br />
print statusLine % (status, resp.reason)<br />
<br />
body = resp.read(58)<br />
body = body.rstrip('\r\n')<br />
body = body.encode('string_escape')<br />
<br />
if len(body) >= 58:<br />
body = body[:57] + '[...]'<br />
<br />
bodyLine = 'Response-Body: "%s"'<br />
print bodyLine % body<br />
break<br />
<br />
# @@ raise PutError, do the catching in main?<br />
else: barf('Got "%s %s"' % (status, resp.reason))<br />
<br />
tries += 1<br />
if tries >= 50:<br />
barf("Too many redirects")<br />
<br />
return status, resp<br />
<br />
def putname(fn, uri, username=None, password=None):<br />
"""HTTP PUT the file with filename fn to uri, with optional auth data."""<br />
auth = {'username': username, 'password': password}<br />
<br />
if fn != '-':<br />
f = open(fn, 'rb')<br />
status, resp = putfile(f, uri, **auth)<br />
f.close()<br />
else: status, resp = putfile(sys.stdin, uri, **auth)<br />
<br />
return status, resp<br />
<br />
def put(s, uri, username=None, password=None):<br />
"""HTTP PUT the string s to uri, with optional auth data."""<br />
try: from cStringIO import StringIO<br />
except ImportError:<br />
from StringIO import StringIO<br />
<br />
f = StringIO(s)<br />
f.seek(0)<br />
status, resp = putfile(f, uri, username=username, password=password)<br />
f.close()<br />
<br />
return status, conn<br />
<br />
def main(argv=None):<br />
usage = ('%prog [options] filename uri\n' +<br />
'The filename may be - for stdin\n' +<br />
'Use command line password at your own risk!')<br />
<br />
parser = OptionParser(usage=usage)<br />
parser.add_option('-u', '--username', help='HTTP Auth username')<br />
parser.add_option('-p', '--password', help='HTTP Auth password')<br />
parser.add_option('-q', '--quiet', action='store_true', help="shhh!")<br />
options, args = parser.parse_args(argv)<br />
<br />
if len(args) != 2:<br />
parser.error("Requires two arguments, filename and uri")<br />
<br />
fn, uri = args<br />
if not uri.startswith('http:'):<br />
parser.error("The uri argument must start with 'http:'")<br />
<br />
if options.username and not options.password or \<br />
options.password and not options.username:<br />
parser.error("Must have both username and password or neither")<br />
<br />
global verbose<br />
verbose = (not options.quiet)<br />
<br />
auth = {'username': options.username, 'password': options.password}<br />
putname(fn, uri, **auth)<br />
<br />
if __name__ == '__main__':<br />
main()</div>Newaccthttps://public.kitware.com/Wiki/index.php?title=ParaView:pvpython&diff=18276ParaView:pvpython2009-12-16T09:41:37Z<p>Newacct: </p>
<hr />
<div>----<br />
<font color="red">'''OBSOLETE: This has been replaced by the [[ParaView/Python Scripting|Python Scripting Manual]]'''</font><br />
----<br />
<br />
=servermanager module=<br />
The document below is for the deprecated paraview module. An up-to-date document for the new servermanager module can be found [[media:servermanager2.pdf|here]].<br />
<br />
=paraview module (<em>deprecated</em>)=<br />
<br />
This documents the '''paraview''' module available for python programmers.<br />
<br />
=Getting Started=<br />
One has to use either the '''pvpython''' executable or the python console provided by the ParaView3 application to use this module. One cannot simply import this module in the standard python interpretor. This is because the module does not include any server manager initialization which is essesential for the paraview client. For the purposes of this document, unless otherwise stated, when we say '''pvpython''' we imply the pvpython interpretor or the python console in ParaView3 application.<br />
<br />
To use paraview, simply import the paraview module.<br />
import paraview<br />
<br />
pvpython setups up the environment paths so that the paraview module is located automatically.<br />
<br />
=Connections=<br />
ParaView client cannot work without a server connection. The server connection can be a connection to an actual remove server or a builtin server. By default, there is no connection, hence the user must set up a connection first. paraview module provides ''connect'' function to create built-in, server, as well as data-server-render-server connections.<br />
<br />
To create a built in connection, use connect with no arguments as follows:<br />
connection = paraview.Connect()<br />
<br />
To connect to a server, we can do:<br />
connection = paraview.Connect("hostname", 11111)<br />
<br />
To connect to a data-server and a render server, we do:<br />
connection = paraview.Connect("data-server-hostname", 11111, "render-server-hostname, 22222)<br />
<br />
11111 and 22222 are tcp/ip port ids and should be replaced by appropriate values. All the above methods return a pyConnection object which encapsulates the ConnectionID used by server manager as well as the meta data about the connection such as host name etc etc. The connection ID is accessible as (use print to see the value):<br />
connection.ID<br />
<br />
The paraview module provides function that take this connection object as an argument. For most of such functions, the connection argument is optional. When not present, the connection set as the '''ActiveConnection''' for the module, if any, is used. To change the active connection one can do:<br />
<br />
paraview.ActiveConnection = connection<br />
<br />
To disconnect, we can do:<br />
paraview.Disconnect(connection)<br />
<br />
=Builder Functions=<br />
The paraview module provides several convenience functions that can be used to create/register proxies, create render modules, displays etc. All the functions that return a proxy return a pyProxy wrapper vtkSMProxy object. pyProxy wrapper is explained later.<br />
<br />
==CreateProxy==<br />
This function creates a proxy. The arguments are:<br />
{| cellpadding="2" cellspacing="4" style="backround:#efefef" <br />
|-<br />
! style="background:#abcdef" | Argument<br />
! style="background:#abcdef" | Description<br />
|-<br />
| xml_group <br />
| group of the proxy type to create (see [[ProxyXMLName]])<br />
|-<br />
| xml_name <br />
| name of the proxy type to create (see [[ProxyXMLName]])<br />
|-<br />
| register_group (optional) <br />
| group under which to register the proxy. If None, the proxy is not registered with the proxy manager. Note that if sharing a session with the ParaView GUI, it is required to register sources and filters in the sources group. Otherwise, the GUI will not recognize the proxy.<br />
|-<br />
| register_name (optional) <br />
| name with which to register the proxy. If None, and register_group is not-None then a proxy is registered with a name created using the proxy's SelfID. <br />
|-<br />
| connection (optional) <br />
| connection on which to create the proxy. If None, then the '''ActiveConnection''' is used.<br />
|}<br />
<br />
==CreateRenderWindow==<br />
This function creates a new render window. It takes connection as the only optional argument. If not specified, '''ActiveConnection''' is used as the connection on which to create the render module. The type of the render module created depends on the type of the connection. This function also registers the render module with the proxy manager.<br />
<br />
==CreateDisplay==<br />
This function creates a new display for a proxy suitable for a particular render module and also adds the display to the render module.<br />
{| cellpadding="2" cellspacing="4" style="backround:#efefef" <br />
|-<br />
! style="background:#abcdef" | Argument<br />
! style="background:#abcdef" | Description<br />
|-<br />
| proxy <br />
| proxy to create the display for.<br />
|-<br />
| renModule <br />
| render module to which the display gets added.<br />
|}<br />
This function also registers the display under "displays" group.<br />
<br />
==Examples==<br />
===Simple Sphere===<br />
import paraview<br />
# create a built in connection and make it the active connection.<br />
paraview.ActiveConnection = paraview.Connect()<br />
# create a sphere and register it under sources.<br />
sphere = paraview.CreateProxy("sources","SphereSource","sources")<br />
# create a render module.<br />
renModule = paraview.CreateRenderWindow()<br />
# create a display<br />
display = paraview.CreateDisplay(sphere, renModule)<br />
# reset camera<br />
renModule.ResetCamera()<br />
# render.<br />
renModule.StillRender()<br />
<br />
='''pyProxy''': wrapper for ''vtkSMProxy''=<br />
One can create a vtkSMProxy object in python as<br />
proxy = paraview.vtkSMProxy()<br />
<br />
However, the API for accessing properties from a proxy is cumbersome. One has to get the property with the correct name using vtkSMProxy::GetProperty() then get/set elements on this property. To simplify the python API, we provide pyProxy class as a wrapper to a vtkSMProxy object. One can wrap an existing vtkSMProxy object as follows:<br />
pyproxy = pyProxy(proxy)<br />
# pyproxy.SMProxy == proxy<br />
The original vtkSMProxy object is always accessible using the member ''SMProxy'' on the pyProxy object. Any method call not defined by pyProxy is passed on to the internal vtkSMProxy object, so one rarely needs to access the SMProxy attribute. eg.<br />
pyproxy.UpdateVTKObjects() <==> pyproxy.SMProxy.UpdateVTKObjects()<br />
<br />
==Set/Get API for properties==<br />
pyProxy simplifies property access. <br />
To set a property with name "Radius" on a pyproxy we can do:<br />
pyproxy.SetRadius(12.0) <br />
pyproxy.SetCenter(0,0,0)<br />
instead of<br />
proxy.GetProperty("Radius").SetElement(0, 12.0)<br />
proxy.GetProperty("Center").SetElement(0, 0)<br />
proxy.GetProperty("Center").SetElement(1, 0)<br />
proxy.GetProperty("Center").SetElement(2, 0)<br />
<br />
Similarly to get current property values we can do:<br />
value_list1 = pyproxy.GetRadius()<br />
value_list2 = pyproxy.GetCenter()<br />
<br />
Note that these methods returns python list of values of the property. In case of Radius, the value_list1 will just have a single element, while in case of Center, the list will have 3 values.<br />
<br />
The ''Set'' API works even for proxy properties. Thus to set the input for a filter proxy, we can do<br />
pyproxy.SetInput(pyproxy2)<br />
<br />
Keep in mind that the properties of a proxy are not pushed to the server until UpdateVTKObjects() is called. The only exception to this rule is the convenience function InvokeCommand(). A command is a property that has no values but is used to invoke a method such as Render(). InvokeCommand() will force the server to execute a command:<br />
pyproxy.InvokeCommand("StillRender")<br />
<br />
==AddTo/RemoveFrom for proxy properties==<br />
For a proxy property, the pyProxy class defines ''AddTo'' and ''RemoveFrom'' methods as well. eg. to add a proxy to the ''Displays'' property on a proxy, we can do<br />
pyproxy.AddToDisplays(pyproxy2)<br />
Similarly to remove a proxy from the proxy property Displays, we do<br />
pyproxy.RemoveFromDisplays(pyproxy2)<br />
<br />
In all the above methods where the argument can be a proxy, it can either be a vtkSMProxy or a wrapped pyProxy object.<br />
<br />
==ListProperties==<br />
pyProxy.ListProperties() can be used to obtain a list of property names provided by the proxy.<br />
<br />
==Property Iterators==<br />
pyProxy wrapper also provides iterators that iterate over all (exposed) properties of the proxy. eg:<br />
for smproperty in pyproxy:<br />
print smproperty<br />
<br />
One can explicitly obtain an iterator from the pyproxy object as well. The advantage of doing so is that one can query the iterator for the key (or exposed property name) of the property during each iteration. eg:<br />
iter = iter(pyproxy) # or iter = paraview.pyPropertyIterator(proxy)<br />
for smproperty in iter:<br />
print "Proxy: %s" % iter.GetProxy() # proxy (or subproxy) to which the property belongs. <br />
print "Property Name: %s" % iter.GetKey() # name of the property.<br />
pass # iter.GetProperty() == smproperty<br />
<br />
==Documentation==<br />
To obtain documentation from a proxy, we can do:<br />
smdoc = pyproxy.GetDocumentation() # returns a vtkSMDocumentation object for the proxy.<br />
print smdoc.GetLongHelp()<br />
print smdoc.GetShortHelp()<br />
print smdoc.GetDescription()<br />
<br />
To get property documentation, we can do:<br />
for smproperty in pyproxy:<br />
smdoc = smproperty.GetDocumentation()<br />
<br />
Alternative, documentation can be obtained from the Proxy Manager without instantiating a proxy, as explained later.<br />
<br />
='''pyProxyManager''': wrapper for ''vtkSMProxyManager''=<br />
<br />
Similar to pyProxy, this is a wrapper for the vtkSMProxyManager. It overrides vtkSMProxyManager methods that return proxies so that the returned values are pyProxy objects wrapped around the vtkSMProxy objects returned by vtkSMProxyManager. Additionally, this class provides iterators to iterate over registered proxies, proxy definitions, compound proxy definitions etc.<br />
<br />
==GetProxiesOnConnection(connection)==<br />
This method returns a list of proxies register with the proxy manager that are on a particular connection. The connection is passed as an argument.<br />
<br />
==GetProxiesInGroup(groupname, connection=None)==<br />
This method returns a list of proxies registered in a particular group, which is passed as an argument. If the optional argument connection is present, then only those proxies that belong to the group and are on the connection are returned.<br />
<br />
==ListProperties(groupname, proxyname)==<br />
Returns a list of exposed properties provided by a proxy of the given type. This allows the user to query the proxy manager for properties of proxy without creating an instance of it.<br />
<br />
==Registered Proxy Iterators==<br />
One can iterate over all registered proxies simply as:<br />
for proxy in pypxm:<br />
print proxy.GetXMLName()<br />
The iterator is a pyProxyIterator object, which is a wrapper around vtkSMProxyIterator. The wrapper is essential to implement the python iterator protocol.<br />
iter(pypxm) <===> pyProxyIterator()<br />
===group_iter(groupname, connection=None)===<br />
Returns an iterator object (pyProxyIterator) that iterates over all registered proxies in the given group. If connection is non-None, then the proxies not on the connection are skipped. eg.<br />
iter = pypxm.group_iter("sources",paraview.ActiveConnection) # all proxies in "sources" group, on the ActiveConnection.<br />
for proxy in iter:<br />
print "%s.%s" % (iter.GetGroup(), iter.GetKey())<br />
print iter.GetProxy() # iter.GetProxy() == proxy<br />
The pyProxyIterator provides access to the groupname and name with which the current proxy is registered.<br />
<br />
===connection_iter(connection)===<br />
Returns an iterator object (pyProxyIterator) that iterates over all registered proxies on a particular connection.<br />
<br />
==Proxy Definition Iterators==<br />
To iterate over all proxy definitions known to the proxy manager, one can use the definition_iter() method. eg. to iterate over all know types of filters:<br />
for definition in paraview.pyProxyManager().definition_iter("filters"): <br />
print "%s : %s" % (definition["group"], definition["key"])<br />
The group name argument is optional, when not specified, it will iterate over all known groups as well. Note that the definition iterator returns a dict with two keys:<br />
'''group''' and '''key'''. The value of '''group''' is the definitions group name while that of '''key''' is the definitions proxy type name.<br />
<br />
==Documentation==<br />
Here's a small example for obtain documentation for all known proxy types and all of their exposed properties without explicitly instantiating the proxies.<br />
pypxm = paraview.pyProxyManager()<br />
for definition in pypxm.definition_iter("filters"):<br />
group = definition["group"]<br />
key = definition["key"]<br />
print "%s : %s" % (group, key)<br />
proxy_doc = pypxm.GetProxyDocumentation(group,key)<br />
print proxy_doc.GetDescription()<br />
property_list = pypxm.ListProperties(group, key)<br />
for property_name in property_list:<br />
property_doc = pypxm.GetPropertyDocumentation(group, key, property_name)<br />
if property_doc:<br />
print property_name<br />
print property_doc.GetDescription()<br />
=Examples=<br />
==Exodus Reader==<br />
<br />
import paraview<br />
# Create default builtin connection<br />
paraview.ActiveConnection = paraview.Connect()<br />
<br />
# Create the reader proxy.<br />
reader = paraview.CreateProxy("sources", "ExodusReader", "sources")<br />
reader.SetFileName("/home/myself/Datasets/Exodus/can.ex2")<br />
reader.UpdateVTKObjects()<br />
<br />
# Create render window<br />
renWin = paraview.CreateRenderWindow()<br />
# create and add display<br />
display = paraview.CreateDisplay(reader, renWin)<br />
# render<br />
renWin.ResetCamera()<br />
renWin.StillRender()<br />
<br />
# Update all information properties. <br />
reader.UpdatePropertyInformation()<br />
# Get the timestep available in the data set.<br />
time_step_range = reader.GetTimeStepRangeInfo()<br />
print "TimeStep Range: %s" % str(time_step_range)<br />
# Get the point arrays available.<br />
point_array_info = reader.GetPointArrayInfo()<br />
print "Point Arrays: %s" % str(point_array_info)<br />
<br />
# Set timestep to last.<br />
reader.SetTimeStep(time_step_range[1])<br />
# Enable the first point array.<br />
reader.SetPointArrayStatus(point_array_info[0], point_array_info[1]);<br />
reader.UpdateVTKObjects()<br />
<br />
renWin.ResetCamera()<br />
renWin.StillRender()<br />
{{ParaView/Template/Footer}}</div>Newaccthttps://public.kitware.com/Wiki/index.php?title=ParaView/Python_Scripting&diff=18275ParaView/Python Scripting2009-12-16T09:39:53Z<p>Newacct: </p>
<hr />
<div>NOTE: This document if based on ParaView 3.6 or higher. If you are using 3.4, go to the history page and select the version from May 13, 2009.<br />
<br />
=ParaView and Python=<br />
ParaView offers rich scripting support through Python. This support is available as part of the ParaView client (paraview), an MPI-enabled batch application (pvbatch), the ParaView python client (pvpython) or any other Python-enabled application. Using Python, users and developers can gain access to the ParaView engine called Server Manager.<br />
<br />
''Note: Server Manager is a library that is designed to make it easy to build distributed client-server applications.''<br />
<br />
This document is a short introduction to ParaView's Python interface. You may also visit the [[Python recipes]] page for some examples.<br />
<br />
=Quick Start - a Tutorial=<br />
==Getting Started==<br />
<br />
To start interacting with the Server Manager, you have to load the "simple" module. This module can be loaded from any python interpreter as long as the necessary files are in PYTHONPATH. These files are the shared libraries located in the paraview binary directory and python modules in the paraview directory: paraview/simple.py, paraview/vtk.py etc. You can also use either pvpython (for stand-alone or client/server execution), pvbatch (for non-interactive, distributed batch processing) or the python shell invoked from Tools -> Python Shell using the ParaView client to execute Python scripts. You do not have to set PYTHONPATH when using these.<br />
In this tutorial, I will be using the python integrated development environment IDLE. My PYTHONPATH is set to the following. <br />
<br />
/Users/berk/work/paraview3-build/bin:/Users/berk/work/paraview3-build/Utilities/VTKPythonWrapping<br />
<br />
You may also need to set your path variable for searching for shared libraries (i.e. PATH on Windows and LD_LIBRARY_PATH on Unix/Linux/Mac). The corresponding LD_LIBRARY_PATH would be:<br />
/Users/berk/work/paraview3-build/bin<br />
<br />
(Under WindowsXP for a debug build of paraview, I set BOTH my PATH and PYTHONPATH environment variables to include ${BUILD}/bin/Debug and ${BUILD}/Utilities/VTKPythonWrapping to make it work.<br />
--[[User:DaveDemarle|DaveDemarle]] 21:09, 29 June 2009 (UTC))<br />
<br />
This is on my Mac and using the build tree. In IDLE, let’s start by loading the servermanager module.<br />
<br />
<source lang="python"><br />
>>> from paraview.simple import *<br />
</source><br />
<br />
Note: Importing the paraview module directly is deprecated although still possible for backwards compatibility. This document refers to the simple module alone. <br />
<br />
In this example, we will use ParaView in the stand-alone mode. Connecting to a ParaView server running on a cluster is covered later in this document.<br />
<br />
==Creating a Pipeline==<br />
<br />
The simple module contains many functions to instantiate sources, filters and other related objects.. You can get a list of object this module can create from ParaView's online help (from help menu or here: http://paraview.org/OnlineHelpCurrent/)<br />
<br />
Let’s start by creating a Cone object:<br />
<br />
<source lang="python"><br />
>>> cone = Cone()<br />
</source><br />
<br />
You can get some documentation about the cone object using help().<br />
<br />
<source lang="python"><br />
>>> help(cone)<br />
Help on Cone in module paraview.servermanager object:<br />
<br />
class Cone(SourceProxy)<br />
| The Cone source can be used to add a polygonal cone to the 3D scene. The output of the <br />
Cone source is polygonal data.<br />
| <br />
| Method resolution order:<br />
| Cone<br />
| SourceProxy<br />
| Proxy<br />
| __builtin__.object<br />
| <br />
| Methods defined here:<br />
| <br />
| Initialize = aInitialize(self, connection=None)<br />
| <br />
| ----------------------------------------------------------------------<br />
| Data descriptors defined here:<br />
| <br />
| Capping<br />
| If this property is set to 1, the base of the cone will be capped with a filled polygon. <br />
Otherwise, the base of the cone will be open.<br />
| <br />
| Center<br />
| This property specifies the center of the cone.<br />
| <br />
| Direction<br />
| Set the orientation vector of the cone. The vector does not have to be normalized. The cone <br />
will point in the direction specified.<br />
| <br />
| Height<br />
| This property specifies the height of the cone.<br />
| <br />
| Radius<br />
| This property specifies the radius of the base of the cone.<br />
| <br />
| Resolution<br />
| This property indicates the number of divisions around the cone. The higher this number, the <br />
closer the polygonal approximation will come to representing a cone, and the more polygons it will <br />
contain.<br />
| <br />
|... <br />
</source><br />
<br />
This gives you a full list of properties. Let’s check what the resolution property is set to.<br />
<br />
<source lang="python"><br />
>>> cone.Resolution<br />
6<br />
</source><br />
<br />
You can increase the resolution as shown below.<br />
<br />
<source lang="python"><br />
>>> cone.Resolution = 32<br />
</source><br />
<br />
Alternatively, we could have specified a value for resolution when creating the object.<br />
<br />
<source lang="python"><br />
>>> cone = Cone(Resolution=32)<br />
</source><br />
<br />
You can assign values to any number of properties during construction using keyword arguments.<br />
Let’s also change the center.<br />
<br />
<source lang="python"><br />
>>> cone.Center<br />
[0.0, 0.0, 0.0]<br />
>>> cone.Center = [1, 2, 3]<br />
</source><br />
<br />
Vector properties such as this one support setting and getting of individual elements as well as slices (ranges of elements).<br />
<br />
<source lang="python"><br />
>>> cone.Center[0:2] = [2, 4]<br />
>>> cone.Center<br />
[2.0, 4.0, 3.0]<br />
</source><br />
<br />
Next, let’s apply a shrink filter to the cone:<br />
<br />
<source lang="python"><br />
>>> shrinkFilter = Shrink(cone)<br />
>>> shrinkFilter.Input<br />
<paraview.servermanager.Cone object at 0xaf701f0><br />
</source><br />
<br />
At this point, if you are interested in getting some information about the output of the shrink filter, you can force it to update (which will also cause the execution of the cone source). For details about VTK's demand-driven pipeline model used by ParaView, see one of the VTK books.<br />
<br />
<source lang="python"><br />
>>> shrinkFilter.UpdatePipeline()<br />
>>> shrinkFilter.GetDataInformation().GetNumberOfCells()<br />
33L<br />
>>> shrinkFilter.GetDataInformation().GetNumberOfPoints()<br />
128L<br />
</source><br />
<br />
We will cover the DataInformation class in more detail later.<br />
<br />
==Rendering==<br />
<br />
Now that we created a small pipeline, let’s render the result. You will need two objects to render the output of an algorithm in a scene: a representation and a view. A representation is responsible for taking a data object and rendering it in a view. A view is responsible for managing a render context and a collection of representations. Simple creates a view by default. The representation object is created automatically with Show().<br />
<br />
<source lang="python"><br />
>>> Show(shrinkFilter)<br />
>>> Render()<br />
</source><br />
<br />
Et voila:<br />
<br />
[[Image:Servermanager_snapshot.png|center]]<br />
<br />
In the example above, we assigned the value returned by Cone() and Shrink() to Python variables and used them to build our pipeline. ParaView keeps track of the last pipeline object created by the user. This allows us to accomplish everything we did above using the following code.<br />
<br />
<source lang="python"><br />
>>> from paraview.simple import *<br />
# Create a cone and assign it as the active object<br />
>>> Cone()<br />
<paraview.servermanager.Cone object at 0x2910f0><br />
# Set a property of the active object<br />
>>> SetProperties(Resolution=32)<br />
# Apply the shrink filter to the active object<br />
# Shrink is now active<br />
>>> Shrink() <br />
<paraview.servermanager.Shrink object at 0xaf64050><br />
# Show shrink<br />
>>> Show() <br />
<paraview.servermanager.UnstructuredGridRepresentation object at 0xaf57f90><br />
# Render the active view<br />
>>> Render() <br />
<paraview.servermanager.RenderView object at 0xaf57ff0><br />
</source><br />
<br />
This was a quick introduction to the paraview.simple module. In the following sections, we will discuss the Python interface in more detail and introduce more advanced concepts.<br />
<br />
=paraview.simple Module=<br />
<br />
The simple module is a ParaView component written using Python on top of the Server Manager C++ library. Its purpose is to make it easier to create ParaView data analysis and visualization pipelines using Python. The simple module can be loaded from Python interpreters running in several applications.<br />
<br />
* pvpython: The pvpython application, distributed with the ParaView application suite, is a Python client to the ParaView servers. It supports interactive execution as well as batch execution.<br />
<br />
* pvbatch: The pvbatch application, also distributed with the ParaView application suite, is a Python application designed to run batch scripts on distributed servers. When ParaView is compiled with MPI, pvbatch can be launched as an MPI program. In this mode, the first node will load a Python script specified as a command-line argument and execute it using a special built-in connection on all nodes. This application does not support interactive execution.<br />
<br />
* paraview: Python scripts can be run from the paraview client using the Python shell that is invoked from Tools -> Python Shell. The Python shell supports interactive mode as well as loading of scripts from file.<br />
<br />
* External Python interpreter: Any Python-capable application can load the paraview.simple module if the right environment is configured. For this to work, you either have to install the paraview Python modules (including the right shared libraries) somewhere in sys.path or you have to set PYTHONPATH to point to the right locations. <br />
<br />
==Overview==<br />
<br />
The paraview.simple module contains several Python classes designed to be Python-friendly as well as all classes wrapped from the C++ Server Manager library. The following sections cover the usage of this module and occasionally the paraview.servermanager module which is lower level.<br />
<br />
==Connecting to a Server==<br />
<br />
ParaView can run in two modes: stand-alone and client/server where the server is usually a visualization cluster. In this section, we discuss how to establish a connection to a server when using ParaView in the client/server mode. If you are using the ParaView graphical interface, you should use Connect from the File menu to connect to a server. If you are using ParaView from a Python shell (not the Python console that is part of the graphical interface), you need to use servermanager.Connect() to connect a server. <em>Note: you cannot connect to the ParaView application from a stand-alone Python shell. You can only connect to a server.</em> This method takes 4 arguments, all of which have default values.<br />
<br />
<source lang="python"><br />
def Connect(ds_host=None, ds_port=11111, rs_host=None, rs_port=11111)<br />
</source><br />
<br />
When connecting to a server (pvserver), specify only the first 2 arguments. These are the server name (or IP address) and port number.<br />
<br />
When connecting to a data-server/render-server pair, you have to specify all four arguments. The first 2 are the host name (or IP address) and port number of the data server, the last 2 those of the render server.<br />
Here are some examples.<br />
<br />
<source lang="python"><br />
# Connect to pvserver running on amber1 (first node of our test cluster)<br />
# using the default port 11111<br />
>>> Connect(‘amber1’)<br />
<br />
# Connect to pvdataserver running on the amber cluster, pvrenderserver <br />
# running on Berk’s desktop<br />
>>> Connect(‘amber1’, 12000, ‘kamino’, 11111)<br />
</source><br />
<br />
Note: Connect() will return None on failure. To be safe, you should check the return value of Connect().<br />
<br />
==Getting Help==<br />
<br />
You can access the documentation of all Proxy types by using Python's built-in help.<br />
<br />
<source lang="python"><br />
>>> help(paraview.simple.Cone)<br />
Help on function CreateObject in module paraview.simple:<br />
<br />
CreateObject(*input, **params)<br />
The Cone source can be used to add a polygonal cone to the 3D scene. The output of the <br />
Cone source is polygonal data.<br />
</source><br />
<br />
To get the full documentation, you have to create an instance.<br />
<br />
<source lang="python"><br />
>>> c = Cone()<br />
>>> help(c)<br />
</source><br />
<br />
This documentation is automatically generated from the Server Manager configuration files and is identical to the class documentation found under the paraview Help menu as well as here http://paraview.org/OnlineHelpCurrent/.<br />
Beyond this document and the online help, there are a few useful documentation sources.<br />
<br />
* The ParaView Guide: http://www.kitware.com/products/paraviewguide.html<br />
<br />
* The ParaView Wiki: http://paraview.org/Wiki/ParaView<br />
<br />
* The ParaView source documentation: http://www.paraview.org/doc/ <br />
<br />
<br />
If you are interested in learning more about the Visualization Toolkit that is at the foundation of ParaView, visit http://vtk.org.<br />
<br />
=Proxies and Properties=<br />
==Proxies==<br />
<br />
The VTK Server Manager design uses the Proxy design pattern (''See Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides for details''). Quoting from Wikipedia: “A proxy, in its most general form, is a class functioning as an interface to another thing. The other thing could be anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate”. In the case of Server Manager, a Proxy object acts as a proxy to one or more VTK objects. Most of the time, these are server-side objects and are distributed to the server nodes. Proxy objects allow you to interact with these object as if you directly have access to them, manipulate them and obtain information about them. When creating visualization pipelines, you create proxies instead of VTK objects. <br />
<br />
<source lang="python"><br />
>>> sphereSource = vtk.vtkSphereSource() # VTK-Python script<br />
<br />
>>> sphereSourceP = Sphere() # ParaView script<br />
</source><br />
<br />
A proxy also provides an interface to modify the properties of the objects it maintains. For example, instead of<br />
<br />
<source lang="python"><br />
>>> sphereSource.SetCenter(1.0, 1.0, 0.0)<br />
</source><br />
<br />
you can write the following.<br />
<br />
<source lang="python"><br />
>>> sphere.Center = [1.0, 1.0, 0.0]<br />
</source><br />
<br />
When a pipeline object proxy is created, it is set as the active object. You can also set an object as the active one. This is equivalent to clicking on an object in the pipeline browser.<br />
<br />
<source lang="python"><br />
>>> c = Cone()<br />
<paraview.servermanager.Cone object at 0xaf73090><br />
>>> GetActiveSource()<br />
<paraview.servermanager.Cone object at 0xaf73090><br />
>>> Shrink()<br />
<paraview.servermanager.Shrink object at 0xb4f8610><br />
# Make the cone active<br />
>>> SetActiveSource(c)<br />
</source><br />
<br />
When dealing with objects created through the graphical interface or by loading a state, it is useful to be able to search through existing pipeline objects. To accomplish this, you can use GetSources() and FindSource(). GetSources() returns a dictionnary of (name, id), object pairs. Since multiple objects can have the same name, the (name,id) pair identifies objects uniquely. FindSource() returns an object given its name. If there are more than one objects with the same name, the first one is returned.<br />
<br />
<source lang="python"><br />
>>> Cone()<br />
<paraview.servermanager.Cone object at 0xaf73090><br />
>>> GetActiveSource()<br />
<paraview.servermanager.Cone object at 0xaf73090><br />
>>> Shrink()<br />
<paraview.servermanager.Shrink object at 0xb4f8610><br />
>>> SetActiveSource(c)<br />
</source><br />
<br />
To delete pipeline objects, you need to use the Delete() function. Simple letting a Python variable go out of scope is not enough to delete the object. Following the example above<br />
<br />
<source lang="python"><br />
# Delete the cone source<br />
>>> Delete(c)<br />
# To fully remove the cone from memory, get rid of the<br />
# variable too<br />
>>> del c<br />
</source><br />
<br />
==Properties==<br />
<br />
Property objects are used to read and modify the properties of pipeline objects. Each proxy has a list of properties defined in the Server Manager configuration files. The property interface of the Server Manager C++ library is somewhat cumbersome. Here is how you can set the radius property of a sphere source.<br />
<br />
<source lang="python"><br />
>>> rp = sphere.GetProperty("Radius")<br />
>>> rp.SetElement(0, 2)<br />
1<br />
>>> sphere.UpdateProperty("Radius")<br />
</source><br />
<br />
The servermanager module makes property access much easier by defining Python property accessors for property objects:<br />
<br />
<source lang="python"><br />
>>> sphere.Radius = 3<br />
</source><br />
<br />
Here Radius is a Python property which, when a value is assigned to it, calls sphere.SetPropertyWithName("Radius",3). Properties can also passed to the function creating the object:<br />
<br />
<source lang="python"><br />
>>> cone = Cone(Radius=0.5, Center=[1, 0.5, 0])<br />
<paraview.servermanager.Cone object at 0xaf73090><br />
</source><br />
<br />
You can also use the SetProperties() function to set property values.<br />
<br />
<source lang="python"><br />
>>> SetProperties(cone, Radius=0.2, Center=[2, 0.5, 0])<br />
</source><br />
<br />
If the first argument is not specified, the active object is used. You also use SetDisplayProperties() and SetViewProperties() to set display (representation) and view properties respectively.<br />
<br />
All Property classes define the following methods.<br />
<br />
* __len__() <br />
* __getitem__()<br />
* __setitem__()<br />
* __getslice__()<br />
* __setslice__()<br />
* GetData()<br />
* SetData(). <br />
<br />
Therefore, all of the following are supported.<br />
<br />
<source lang="python"><br />
>>> sphere.Center<br />
[0.0, 0.0, 0.0]<br />
>>> sphere.Center[0] = 1<br />
>>> sphere.Center[0:3] = [1,2,3]<br />
>>> sphere.Center[0:3]<br />
[1.0, 2.0, 3.0]<br />
>>> len(sphere.Center)<br />
3<br />
</source><br />
<br />
ProxyProperty and InputProperty also define <br />
<br />
* append()<br />
* __delitem__()<br />
* __delslice__()<br />
<br />
to support del() and append(), similar to Python list objects.<br />
<br />
VectorProperty is used for scalars, vectors and lists of integer and floating point numbers as well as <br />
strings. Most properties of this type are simple. Examples include Sphere.Radius (double scalar), Sphere.Center (vector of doubles), a2DGlyph.Filled (boolean), a2DGlyph.GlyphType (enumeration), a3DText.Text (string) and Contour.Isosurfaces (list of doubles). Some properties may be more complicated because they map to C++ methods with mixed argument types. Two good examples of this case are Glyph.Scalars and ExodusIIReader.PointVariables.<br />
<br />
<source lang="python"><br />
>>> reader = ExodusIIReader(FileName='.../can.ex2')<br />
# These variables are currently selected<br />
>>> reader.PointVariables<br />
['DISPL', 'VEL', 'ACCL']<br />
# These are available in the file<br />
>>> reader.PointVariables.Available<br />
['DISPL', 'VEL', 'ACCL']<br />
# Enable the DISPL array only<br />
>>> reader.PointVariables = ['DISPL']<br />
# Force read<br />
>>> reader.UpdatePipeline()<br />
# Now check the output. Note: GlobalNodeId is generated automatically by the reader.<br />
>>> reader.PointData[:]<br />
[Array: GlobalNodeId, Array: PedigreeNodeId, Array: DISPL]<br />
</source><br />
<br />
This example demonstrates the use of ExodusIIReader.PointVariables. This is a VectorProperty that represents a list of array names. The underlying C++ function has a signature of SetPointResultArrayStatus( const char* name, int flag ). This method is usually called once per array to enable or disable it (i.e. to set whether the reader will read a particular array).<br />
<br />
Glyph.Scalars is a bit more complicated. This property allows the developer to select the scalar array with which to scale the glyphs.<br />
<br />
<source lang="python"><br />
>>> sph = Sphere()<br />
>>> elev=Elevation(sph)<br />
# Glyph the points of the sphere with spheres<br />
>>> glyph=Glyph(elev, GlyphType='Sphere')<br />
# Scale the glyph with the Elevation array<br />
>>> glyph.Scalars = 'Elevation'<br />
>>> glyph.Scalars<br />
['POINTS', 'Elevation']<br />
# The above shows the association of the array as well as its name.<br />
# In this case, the array is associated with POINTS as it has to be<br />
# since Glyph cannot scale by cell arrays. We could have done:<br />
>>> glyph.Scalars = ['POINTS', 'Elevation']<br />
# Enable scaling by scalars<br />
>>> glyph.ScaleMode = 'scalar'<br />
</source><br />
<br />
Here the property Scalars maps to SetInputArrayToProcess( int idx, int port, int connection, int fieldAssociation, const char *name ) which has four integer arguments (some of which are enumeration) and 1 string argument (''see vtkAlgorithm documentation for details'').<br />
<br />
Properties are either regular (push) or information (pull) properties. Information properties do not have a VTK method associated with them and are responsible for getting information from the server. A good example of an information property is TimestepValues which returns all time steps available in a file (if the reader supports time).<br />
<br />
<source lang="python"><br />
>>> reader = ExodusIIReader(FileName='.../can.ex2')<br />
>>> reader.TimestepValues<br />
[0.0, 0.00010007373930420727, 0.00019990510190837085, 0.00029996439116075635, 0.00040008654468692839,<br />
0.00049991923151537776, 0.00059993512695655227, 0.00070004, ...]<br />
</source><br />
<br />
You can obtain a list of properties a proxy supports by using help(). However, this does not allow introspection programmatically. If you need to obtain information about a proxy’s properties programmatically, you can use a property iterator:<br />
<br />
<source lang="python"><br />
>>> for prop in glyph:<br />
print type(prop), prop.GetXMLLabel()<br />
<br />
<class 'paraview.servermanager.InputProperty'> Input<br />
<class 'paraview.servermanager.VectorProperty'> Maximum Number of Points<br />
<class 'paraview.servermanager.VectorProperty'> Random Mode<br />
<class 'paraview.servermanager.ArraySelectionProperty'> Scalars<br />
<class 'paraview.servermanager.ArraySelectionProperty'> Vectors<br />
<class 'paraview.servermanager.VectorProperty'> Orient<br />
<class 'paraview.servermanager.VectorProperty'> Set Scale Factor<br />
<class 'paraview.servermanager.EnumerationProperty'> Scale Mode<br />
<class 'paraview.servermanager.InputProperty'> Glyph Type<br />
<class 'paraview.servermanager.VectorProperty'> Mask Points<br />
</source><br />
<br />
The XMLLabel is the text display by the graphical user interface. Note that there is a direct mapping from the XMLLabel to the property name. If you remove all spaces from the label, you get the property name. You can use the PropertyIterator object directly.<br />
<br />
<source lang="python"><br />
>>> it = iter(s)<br />
>>> for i in it:<br />
print it.GetKey(), it.GetProperty()<br />
</source><br />
<br />
==Domains==<br />
<br />
The Server Manager provides information about values that are valid for properties. The main use of this information is for the user interface to provide good ranges and choices in enumeration. However, some of this information is also very useful for introspection. For example, enumeration properties look like simple integer properties unless a (value, name) pair is associated with them. The Server Manager uses Domain objects to store this information. The contents of domains may be loaded from xml configuration files or computed automatically. Let’s look at an example.<br />
<br />
<source lang="python"><br />
>>> s = Sphere()<br />
>>> Show(s)<br />
>>> dp = GetDisplayProperties(s)<br />
>>> dp.Representation<br />
'Surface'<br />
# The current representation type is Surface. What other types<br />
# are available?<br />
>>> dp.GetProperty("Representation").Available<br />
['Outline', 'Points', 'Wireframe', 'Surface', 'Surface With Edges']<br />
# Choose outline<br />
>>> dp.Representation = 'Outline'<br />
</source><br />
<br />
==Source Proxies==<br />
<br />
Source proxies are proxies that represent pipeline objects (''For more information about VTK pipelines, see the VTK books: http://vtk.org/buy-books.php''). They have special properties to connect them as well as special method to query the meta-data of their output. To connect a source proxy to another, use one of its input properties.<br />
<br />
<source lang="python"><br />
# Either<br />
>>> glyph = Glyph(elev)<br />
# or<br />
>>> glyph.Input = elev<br />
</source><br />
<br />
The SourceProxy class provides several additional properties and methods that are specific to pipelines (See vtkSMSourceProxy documentation for a full list).<br />
* UpdatePipelineInformation(): This method calls UpdateInformation() on the VTK algorithm. It also calls UpdatePropertyInformation() to update any information properties.<br />
* UpdatePipeline(): This method calls Update() on the VTK algorithm causing a pipeline execution if the pipeline changed. Another way of causing pipeline updates is to render. The render view updates all connected pipelines.<br />
* GetDataInformation(): This method is used to obtain meta-data about one output. It is discussed further below.<br />
* PointData and CellData properties discussed below.<br />
<br />
There are two common ways of getting meta-data information from a proxy: information properties and DataInformation. Information properties are updated automatically every time UpdatePropertyInformation() and UpdatePipelineInformation() are called. All you have to do is read the data from the property as usual. To get a DataInformation object from a source proxy use GetDataInformation(port=0). By default, this method returns data information for the first output. You can pass an optional port number to get information for another output. You can get detailed documentation on DataInformation by using help() and by reading online documentation for vtkPVDataInformation (''http://www.paraview.org/doc/nightly/html/classvtkPVDataInformation.html''). Here are the use of some common methods.<br />
<br />
<source lang="python"><br />
>>> di = glyph.GetDataInformation(0)<br />
>>> di<br />
<paraview.servermanager.DataInformation object at 0x2d0920d0><br />
>>> glyph.UpdatePipeline()<br />
# Get the data type.<br />
>>> di.GetDataClassName()<br />
'vtkPolyData'<br />
# Get information about point data. <br />
>>> pdi = di.PointData<br />
# We are now directly accessing the wrapper for a VTK class<br />
>>> len(pdi)<br />
1<br />
# Get information for a point array<br />
>>> ai = pdi[0]<br />
>>> ai.GetRange(0)<br />
(0.0, 0.5)<br />
</source><br />
<br />
When meta-data is not enough and you need access to the raw data, you can use Fetch() to bring it to the client side. Note that this function is provided by the servermanager module. Fetch() has three modes:<br />
<br />
*Append all of the data together and bring it to the client (only available for polygonal and unstructured datasets). Note: Do not do this if data is large otherwise the client will run out of memory.<br />
<br />
*Bring data from a given process to the client.<br />
<br />
*Use a reduction algorithm and bring its output to the client. For example, find the minimum value of an attribute.<br />
<br />
Here is a demonstration.<br />
<br />
<source lang="python"><br />
>>> from paraview.simple import *<br />
>>> Connect("kamino")<br />
Connection (kamino:11111)<br />
>>> s = Sphere()<br />
# Get the whole sphere. DO NOT DO THIS IF THE DATA IS LARGE otherwise<br />
# the client will run out of memory.<br />
>>> allsphere = servermanager.Fetch(s)<br />
getting appended<br />
use append poly data filter<br />
>>> allsphere.GetNumberOfPolys()<br />
96<br />
# Get the piece of the sphere on process 0.<br />
>>> onesphere = servermanager.Fetch(s, 0)<br />
getting node 0<br />
>>> onesphere.GetNumberOfPolys()<br />
48<br />
# Apply the elevation filter so that we have a useful scalar array.<br />
>>> elev = Elevation(s)<br />
# We will use the MinMax algorithm to compute the minimum value of<br />
# elevation. MinMax will be first applied on each processor. The results<br />
# will then be gathered to the first node. MinMax will be then applied<br />
# to the gathered results.<br />
# We first create MinMax without an input.<br />
>>> mm = MinMax(None)<br />
# Set it to compute min<br />
>>> mm.Operation = "MIN"<br />
# Get the minimum<br />
>>> mindata = servermanager.Fetch(elev, mm, mm)<br />
applying operation<br />
# The result is a vtkPolyData with one point<br />
>>> mindata.GetPointData().GetNumberOfArrays()<br />
2<br />
>>> a0 = mindata.GetPointData().GetArray(1)<br />
>>> a0.GetName()<br />
'Elevation'<br />
>>> a0.GetTuple1(0)<br />
0.0<br />
</source><br />
<br />
==Representations and Views==<br />
<br />
Once a pipeline is created, it can be rendered using representations and views. A view is essentially a “window” in which multiple representations can be displayed. When the view is a VTK view (such as RenderView), this corresponds to a collection of objects including vtkRenderers and a vtkRenderWindow. However, there is no requirement for a view to be a VTK view or to render anything. A representation is a collection of objects, usually a pipeline, that takes a data object, converts it to something that can be rendered and renders it. When the view is a VTK view, this corresponds to a collection of objects including geometry filters, level-of-detail algorithms, vtkMappers and vtkActors. The simple module automatically creates a view after connecting to a server (including the built-in connection when using the stand-alone mode). Furthermore, the simple module creates a representation the first time a pipeline object is displayed with Show().<br />
It is easy to create new views.<br />
<br />
<source lang="python"><br />
>>> view = CreateRenderView()<br />
</source><br />
<br />
CreateRenderView() is a special method that creates the render view appropriate for the ActiveConnection (or for another connection specified as an argument). It returns a sub-class of Proxy. Like the constructor of Proxy, it can take an arbitrary number of keyword arguments to set initial values for properties. Note that ParaView makes the view that was created last the active view. When using Show() without a view argument, the pipeline is shown in the active view. You can get a list of views as well as the active view as follows<br />
<br />
<source lang="python"><br />
>>> GetRenderViews()<br />
[<paraview.servermanager.RenderView object at 0xaf64ef0>, <paraview.servermanager.RenderView object at 0xaf64b70>]<br />
>>> GetActiveView()<br />
<paraview.servermanager.RenderView object at 0xaf64b70><br />
</source><br />
<br />
You can also change the active view using SetActiveView().<br />
<br />
Once you have a render view, you can use pass it to show in order to select in which view a pipeline object is displayed. You can also pass it to Render() to select which view is rendered.<br />
<br />
<source lang="python"><br />
>>> Show(elev, GetRenderViews()[1])<br />
<paraview.servermanager.GeometryRepresentation object at 0xaf64e30><br />
>>> Render(GetRenderViews()[1])<br />
</source><br />
<br />
Notice that Show() returns a representation object (aka DisplayProperties in the simple module). This object can be used to manipulate how the pipeline object is displayed in the view. You can also access the display properties of an object using GetDisplayProperties().<br />
<br />
<source lang="python"><br />
>>> dp = GetDisplayProperties(elev)<br />
>>> dp<br />
<paraview.servermanager.GeometryRepresentation object at 0xaf649d0><br />
</source><br />
<br />
Display properties and views have a large number of documented properties some of which are poorly documented. We will cover some them here.<br />
<br />
<source lang="python"><br />
>>> from paraview.simple import *<br />
# Create a simple pipeline<br />
>>> sph = Sphere()<br />
>>> elev = Elevation(sph)<br />
>>> Show(elev)<br />
>>> Render()<br />
# Set the representation type of elev<br />
>>> dp = GetDisplayProperties(elev)<br />
>>> dp.Representation = 'Points'<br />
# Here is how you get the list of representation types<br />
>>> dp.GetProperty("Representation").Available<br />
['Outline', 'Points', 'Wireframe', 'Surface', 'Surface With Edges']<br />
>>> Render()<br />
# Change the representation to wireframe<br />
>>> dp.Representation = 'Wireframe'<br />
>>> Render()<br />
# Let’s get some information about the output of the elevation<br />
# filter. We want to color the representation by one of it’s<br />
# arrays.<br />
# Second array = Elevation. Interesting. Let’s use this one.<br />
>>> ai = elev.PointData[1]<br />
>>> ai.GetName()<br />
'Elevation'<br />
# What is its range?<br />
>>> ai.GetRange()<br />
(0.0, 0.5)<br />
# To color the representation by an array, we need to first create<br />
# a lookup table. We use the range of the Elevation array<br />
>>> dp.LookupTable = MakeBlueToRedLT(0, 0.5)<br />
>>> dp.ColorAttributeType = 'POINT_DATA'<br />
>>> dp.ColorArrayName = 'Elevation' # color by Elevation<br />
>>> Render()<br />
</source><br />
<br />
Here is the result:<br />
<br />
[[Image:SMView.png|center]]<br />
<br />
<br />
Once you create a scene, you will probably want to interact with the camera and ResetCamera() is likely to be insufficient. In this case, you can directly get the camera from the view and manipulate it. GetActiveCamera() returns a VTK object (not a proxy) with which you can interact.<br />
<br />
<source lang="python"><br />
>>> camera = GetActiveCamera()<br />
>>> camera<br />
<libvtkCommonPython.vtkCamera vtkobject at 0xe290><br />
>>> camera.Elevation(45)<br />
>>> Render()<br />
</source><br />
<br />
Another common thing to do is to save the view as an image. For this purpose, you can use the WriteImage() method provided by the view:<br />
<br />
<source lang="python"><br />
>> WriteImage("/Users/berk/image.png")<br />
</source><br />
<br />
The resulting image.png looks like this. See the documentation for WriteImage() for details on choosing file type as well as a magnification factor to save images larger than the view size.<br />
<br />
[[Image:Image.jpg|center]]<br />
<br />
=Advanced Concepts=<br />
<br />
==Loading State and Manipulating It==<br />
<br />
Let’s say you created a complicated visualization using the paraview application and now you want to make slight changes to it and run it in a loop as a batch script. What do you do? The best way of dealing with this is to save your visualization state and then load it from Python. Let’s say you have a state file saved as myteststate.pvsm:<br />
<br />
<source lang="python"><br />
>>> from paraview.simple import *<br />
# Load the state<br />
>>> servermanager.LoadState("/Users/berk/myteststate.pvsm")<br />
# Make sure that the view in the state is the active one<br />
>>> SetActiveView(GetRenderView())<br />
# Now render<br />
>>> Render()<br />
# Get the list of sources<br />
>>> GetSources()<br />
{('Sphere1', '5'): <paraview.servermanager.Sphere object at 0xaf80e30>, <br />
('Shrink1', '11'): <paraview.servermanager.Shrink object at 0xaf80df0>, <br />
('Cone1', '8'): <paraview.servermanager.Cone object at 0xaf80cf0>}<br />
# Change the resolution of the cone and render again<br />
>>> FindSource("Cone1").Resolution = 32<br />
>>> Render()<br />
</source><br />
<br />
You can also save state.<br />
<br />
<source lang="python"><br />
>>> from paraview.simple import *<br />
>>> sph = Sphere()<br />
>>> Render()<br />
>>> servermanager.SaveState("/Users/berk/pythonstate.pvsm")<br />
</source><br />
<br />
==Dealing with Time==<br />
<br />
If a reader or a filter supports time, it is easy to request a certain time step from Python. All time requests are set on views, which then propagate them to the representations which then propagate them to the visualization pipeline. Here is an example demonstrating how a time request can be made.<br />
<br />
<source lang="python"><br />
>>> Show(ExodusIIReader(FileName=".../can.ex2"))<br />
>>> Render()<br />
# Get a nice view angle<br />
>>> cam = GetActiveCamera()<br />
>>> cam.Elevation(45)<br />
>>> Render()<br />
# Check the current view time<br />
>>> view = GetActiveView()<br />
>>> view.ViewTime<br />
0.0<br />
>>> reader = GetActiveSource()<br />
>>> reader.TimestepValues<br />
[0.0, 0.00010007373930420727, 0.00019990510190837085, <br />
0.00029996439116075635, 0.00040008654468692839, <br />
...]<br />
>>> tsteps = reader.TimestepValues<br />
# Let’s be fancy and use a time annotation filter. This will show the<br />
# current time value of the reader as text in the corner of the view.<br />
>>> annTime = AnnotateTimeFilter(reader)<br />
# Show the filter<br />
>>> Show(annTime)<br />
# Look at a few time steps. Note that the time value is requested not<br />
# the time step index.<br />
>>> view.ViewTime = tsteps[2]<br />
>>> Render()<br />
>>> view.ViewTime = tsteps[4]<br />
>>> Render()<br />
</source><br />
<br />
==Animating==<br />
<br />
Server Manager has a complicated animation engine based on keyframes and scenes. This section will introduce a few simple ways of animating your visualization. <br />
If you have a time-aware reader, you can animate it with AnimateReader().<br />
<br />
<source lang="python"><br />
>>> reader = ExodusIIReader(“.../can.ex2”)<br />
>>> Show(reader)<br />
>>> Render()<br />
>>> c = GetActiveCamera()<br />
>>> c.Elevation(95)<br />
# Animate over all time steps. Note that we are not passing the optional<br />
# 3rd argument here. If you pass a filename as the 3rd argument, <br />
# AnimateReader will create a movie.<br />
>>> AnimateReader(reader)<br />
# Save the animation to an avi file<br />
>>> AnimateReader(reader, filename=".../movie.avi")<br />
</source><br />
<br />
To animate properties other than time, you can use regular keyframes.<br />
<br />
<source lang="python"><br />
>>> Sphere()<br />
>>> Show()<br />
>>> Render()<br />
<br />
# Create an animation scene<br />
>>> scene = servermanager.animation.AnimationScene()<br />
# Add one view<br />
>>> scene.ViewModules = [GetActiveView()]<br />
<br />
# Create a cue to animate the StartTheta property<br />
>>> cue = servermanager.animation.KeyFrameAnimationCue()<br />
>>> cue.AnimatedProxy = GetActiveSource()<br />
>>> cue.AnimatedPropertyName = "StartTheta"<br />
# Add it to the scene's cues<br />
>>> scene.Cues = [cue]<br />
<br />
# Create 2 keyframes for the StartTheta track<br />
>>> keyf0 = servermanager.animation.CompositeKeyFrame()<br />
>>> keyf0.Interpolation = 'Ramp'<br />
# At time = 0, value = 0<br />
>>> keyf0.KeyTime = 0<br />
>>> keyf0.KeyValues= [0]<br />
<br />
>>> keyf1 = servermanager.animation.CompositeKeyFrame()<br />
# At time = 1.0, value = 200<br />
>>> keyf1.KeyTime = 1.0<br />
>>> keyf1.KeyValues= [200]<br />
<br />
# Add keyframes.<br />
>>> cue.KeyFrames = [keyf0, keyf1]<br />
<br />
>>> scene.Play()<br />
<br />
# Some properties you can change<br />
#<br />
# Number of frames used in Sequence mode<br />
# scene.NumberOfFrames = 100<br />
#<br />
# Or you can use real time mode<br />
# scene.PlayMode = 'Real Time'<br />
# scene.Duration = 20<br />
</source><br />
<br />
{{ParaView/Template/Footer}}</div>Newaccthttps://public.kitware.com/Wiki/index.php?title=ParaView/Simple_ParaView_3_Python_Filters&diff=17819ParaView/Simple ParaView 3 Python Filters2009-12-03T07:38:18Z<p>Newacct: </p>
<hr />
<div>== Examples of Filters Programmed using the Python Programmable Filter ==<br />
<br />
It would be nice, if you have written a possibly useful pp-filter, if you would add the code to this page. Here are some simple examples. <br />
<br />
<font color=blue>'''Note:''' These scripts are meant to be used at values for the '''Script''' paramaters for '''Programmable Filter''' or '''Programmable Source''' as identified by the title. These will not directly work from the python shell or pvpython.</font><br />
<br />
==CSV Reader (Source) ==<br />
<source lang="python"><br />
# This source reads a text file and produces a data set<br />
# The file is of the form (where [denotes optional and repeatable]:<br />
# X,Y,Z[,ARRAYNAME]<br />
# x0,y0,z0[,value]<br />
# x1,y1,z1[,value]<br />
# ...<br />
from paraview import vtk<br />
import os<br />
pts = vtk.vtkPoints()<br />
firstline = True<br />
filename = os.path.normcase("c:/datafile.txt")<br />
f = open(filename)<br />
pdo = self.GetOutput()<br />
for line in f:<br />
if firstline:<br />
#skip first line, presumed to be a header<br />
firstline = False<br />
for pos,word in enumerate(line.split(",")):<br />
if pos > 2:<br />
newArray = vtk.vtkDoubleArray()<br />
newArray.SetName(word)<br />
newArray.SetNumberOfComponents(1)<br />
pdo.GetPointData().AddArray(newArray)<br />
else:<br />
for pos,word in enumerate(line.split(",")):<br />
print word<br />
if pos == 0:<br />
x = float(word)<br />
if pos == 1:<br />
y = float(word)<br />
if pos == 2:<br />
z = float(word)<br />
if pos > 2:<br />
array = pdo.GetPointData().GetArray(pos-3)<br />
array.InsertNextValue(float(word))<br />
pts.InsertNextPoint(x,y,z)<br />
pdo.SetPoints(pts)<br />
</source><br />
<br />
==Tetrahedra Volume (Filter) ==<br />
<source lang="python"><br />
# This filter computes the volume of the tetrahedra in an unstructured mesh:<br />
pdi = self.GetInput()<br />
pdo = self.GetOutput()<br />
newData = vtk.vtkDoubleArray()<br />
newData.SetName("Volume")<br />
numTets = pdi.GetNumberOfCells()<br />
for i in range(numTets):<br />
cell = pdi.GetCell(i)<br />
p1 = pdi.GetPoint(cell.GetPointId(0))<br />
p2 = pdi.GetPoint(cell.GetPointId(1))<br />
p3 = pdi.GetPoint(cell.GetPointId(2))<br />
p4 = pdi.GetPoint(cell.GetPointId(3))<br />
volume = vtk.vtkTetra.ComputeVolume(p1,p2,p3,p4)<br />
newData.InsertNextValue(volume)<br />
pdo.GetCellData().AddArray(newData)<br />
</source><br />
<br />
==Tetrahedra Radius (Filter) ==<br />
<source lang="python"><br />
# This filter computes the radius h of the tetrahedra in an unstructured mesh:<br />
# Adapted by Johan Jansson (jjan@csc.kth.se) <br />
from math import *<br />
pdi = self.GetInput()<br />
pdo = self.GetOutput()<br />
newData = vtk.vtkDoubleArray()<br />
newData.SetName("h")<br />
numTets = pdi.GetNumberOfCells()<br />
for i in range(numTets):<br />
cell = pdi.GetCell(i)<br />
p1 = pdi.GetPoint(cell.GetPointId(0))<br />
p2 = pdi.GetPoint(cell.GetPointId(1))<br />
p3 = pdi.GetPoint(cell.GetPointId(2))<br />
p4 = pdi.GetPoint(cell.GetPointId(3))<br />
c = [0.0, 0.0, 0.0]<br />
h = vtk.vtkTetra.Circumsphere(p1,p2,p3,p4,c)<br />
# VTK actually computes the square<br />
h = sqrt(h)<br />
newData.InsertNextValue(h)<br />
pdo.GetCellData().AddArray(newData)<br />
</source><br />
<br />
==Flip Tetrahedra (Filter)==<br />
<source lang="python"><br />
# This filter flips the tetrahedra (useful, if you have different convention of <br />
# tet orientation than VTK, and wish to use the vtkMeshQuality filter).<br />
pdi = self.GetInput()<br />
pdo = self.GetOutput()<br />
numTets = pdi.GetNumberOfCells()<br />
newcells = vtk.vtkCellArray()<br />
for i in range(numTets):<br />
cell = pdi.GetCell(i)<br />
i1 = cell.GetPointId(0)<br />
i2 = cell.GetPointId(1)<br />
i3 = cell.GetPointId(2)<br />
i4 = cell.GetPointId(3)<br />
newcells.InsertNextCell(4)<br />
newcells.InsertCellPoint(i1)<br />
newcells.InsertCellPoint(i2)<br />
newcells.InsertCellPoint(i4)<br />
newcells.InsertCellPoint(i3)<br />
pdo.SetCells( 10, newcells )<br />
</source><br />
<br />
<br />
==Helix (Source)==<br />
This is intended as the Python script for a 'Programmable Source'. It generates a helix with two sets of scalar data defined along the helix. The scalar data can be visualized using filters such as the 'tube' filter where the scalar value is represented as a color. The scalar called 'First Property' or the scalar called 'Second Property' can be chosen from the 'Display' tab of the 'tube' filter under the 'Color by' option. This lists the available scalars that are defined at points along the helix.<br />
<source lang="python"><br />
#This script generates a helix curve.<br />
#This is intended as the script of a 'Programmable Source'<br />
import math<br />
<br />
numPts = 80.0 # Points along Helix<br />
length = 8.0 # Length of Helix<br />
rounds = 3.0 # Number of times around <br />
<br />
#Get a vtk.PolyData object for the output<br />
pdo = self.GetPolyDataOutput()<br />
<br />
#This will store the points for the Helix<br />
newPts = vtk.vtkPoints()<br />
<br />
#Associate scalar values with the points.<br />
#Also set the name for the scalar that will be<br />
#visible in Paraview dropdown lists for setting<br />
#color along the helix.<br />
vals1 = vtk.vtkDoubleArray()<br />
vals1.SetName('First Property')<br />
vals2 = vtk.vtkDoubleArray()<br />
vals2.SetName('Second Property')<br />
<br />
for i in range(numPts):<br />
#Generate the Points along the Helix<br />
x = i*length/numPts<br />
y = math.sin(i*rounds*2*math.pi/numPts)<br />
z = math.cos(i*rounds*2*math.pi/numPts)<br />
#Insert the Points into the vtkPoints object<br />
#The first parameter indicates the reference.<br />
#value for the point. Here we add the sequentially.<br />
#Note that the first point is at index 0 (not 1).<br />
newPts.InsertPoint(i, x,y,z)<br />
<br />
#Order of Scalars should match order Pts were added<br />
vals1.InsertNextValue(i)<br />
vals2.InsertNextValue(math.sin(i*2.0*math.pi/numPts)) <br />
<br />
#Add the points to the vtkPolyData object<br />
#Right now the points are not associated with a line - <br />
#it is just a set of unconnected points. We need to<br />
#create a 'cell' object that ties points together<br />
#to make, in this case, a curve. This is done below.<br />
#A 'cell' is just an object that tell how points are<br />
#connected to make a 1D, 2D, or 3D object.<br />
pdo.SetPoints(newPts) <br />
<br />
# Add the scalar point data<br />
pdo.GetPointData().SetScalars(vals1) #'First Property' scalar<br />
pdo.GetPointData().AddArray(vals2) #'Second Property' scalar<br />
<br />
#Make a vtkPolyLine which holds the info necessary<br />
#to create a curve composed of line segments. This<br />
#really just hold constructor data that will be passed<br />
#to vtkPolyData to add a new line.<br />
aPolyLine = vtk.vtkPolyLine()<br />
<br />
#Indicate the number of points along the line<br />
aPolyLine.GetPointIds().SetNumberOfIds(numPts)<br />
for i in range(numPts):<br />
#Add the points to the line. The first value indicates<br />
#the order of the point on the line. The second value<br />
#is a reference to a point in a vtkPoints object. Depends<br />
#on the order that Points were added to vtkPoints object.<br />
#Note that this will not be associated with actual points<br />
#until it is added to a vtkPolyData object which holds a<br />
#vtkPoints object.<br />
aPolyLine.GetPointIds().SetId(i, i)<br />
<br />
#Allocate the number of 'cells' that will be added. We are just<br />
#adding one vtkPolyLine 'cell' to the vtkPolyData object.<br />
pdo.Allocate(1, 1) <br />
<br />
#Add the poly line 'cell' to the vtkPolyData object.<br />
pdo.InsertNextCell(aPolyLine.GetCellType(), aPolyLine.GetPointIds()) <br />
<br />
#The Helix is ready to plot! Click 'Apply'.<br />
</source><br />
{{ParaView/Template/Footer}}</div>Newaccthttps://public.kitware.com/Wiki/index.php?title=CDash:Dart2AndCDashSubmission&diff=17447CDash:Dart2AndCDashSubmission2009-11-17T09:43:41Z<p>Newacct: </p>
<hr />
<div>[[CDash | < CDash Main Page]]<br />
<br />
== Setting up dual Dart2 and CDash Submissions ==<br />
If you are moving from Dart2 to CDash you may want to submit to both dashboards in parallel for a while, before switching solely to CDash.<br />
<br />
The following shows how to setup CTest to use a trigger script, which in turn does a submit to both Dart2 (via XML-RPC) and CDash (via HTTP).<br />
<br />
Note: This method doesn't support submission of Dart2 notes files.<br />
<br />
Configure CTest to use a trigger script:<br />
<br />
SET (CTEST_DROP_METHOD "http")<br />
SET (CTEST_DROP_SITE "mysite.org")<br />
SET (CTEST_DROP_LOCATION "/cgi-bin/HTTPUploadDartFile.cgi")<br />
SET (CTEST_TRIGGER_SITE "http://${DROP_SITE}/cgi-bin/TriggerSiteDart2AndCDash.cgi")<br />
<br />
Both <tt>HTTPUploadDartFile.cgi</tt> and <tt>TriggerSiteDart2AndCDash.cgi</tt> have a hard coded path that may require editing: <tt>/srv/dart2/incoming</tt><br />
<br />
''This current implementation only supports a single hard coded project in <tt>TriggerSiteDart2AndCDash.cgi</tt>. You can of course create a specific trigger site per project to workaround this.''<br />
<br />
=== HTTPUploadDartFile.cgi ===<br />
<br />
#!/usr/bin/env python<br />
#<br />
# Script that will upload files to specified directory on the server, where<br />
# triggering script will find it.<br />
#<br />
# Installation:<br />
# Place this script in your cgi-bin area.<br />
# Change the variable "incoming_directory" to match your<br />
# installation.<br />
###<br />
<br />
import cgi<br />
import re<br />
import sys<br />
import os<br />
<br />
print "Content-type: text/html"<br />
print<br />
<br />
done = 0<br />
<br />
incoming_directory = '/srv/dart2/incoming'<br />
<br />
form = cgi.FieldStorage()<br />
<br />
# Debug<br />
#try:<br />
# tmpfile = open("/tmp/http_upload_log_file.log", "w")<br />
# tmpfile.write(`form`)<br />
# tmpfile.close()<br />
#except Exception: pass<br />
<br />
FileData = ""<br />
FileName = ""<br />
<br />
# process form<br />
if type(form.value) == type("foo"):<br />
if "QUERY_STRING" in os.environ:<br />
dt = cgi.parse_qs(os.environ["QUERY_STRING"])<br />
if "FileName" in dt:<br />
FileName = dt["FileName"][0]<br />
FileData = form.value<br />
elif "FileName" in form:<br />
FileName = form["FileName"].value<br />
if "FileData" in form:<br />
FileData = "form"<br />
<br />
# verify file specified<br />
if not FileData or not FileName:<br />
print "Please send file. "<br />
print "FileName has to contain file name"<br />
print "FileData has to contain file content"<br />
print form<br />
sys.exit(0)<br />
<br />
print "Received file: " + FileName<br />
<br />
# check if valid file name<br />
filename = re.sub("[/\\|:%%]", "_", FileName)<br />
if re.match(".+___.+___[0-9]{8}-[0-9]{4}-(Experimental|Nightly|Continuous)___XML___(Update|Configure|Build|Test|Coverage|Purify).xml", filename):<br />
print "Correct file name"<br />
else:<br />
print "Can only upload files with format:"<br />
print "<site>___<BuildType>___<TAG>-<TestType>___XML___<File>.xml"<br />
sys.exit(0)<br />
<br />
# get the file data<br />
file_lines = ""<br />
if FileData == "form":<br />
fileitem = form["FileData"]<br />
if fileitem.file:<br />
file_lines = fileitem.file.read()<br />
else:<br />
print "Not a file"<br />
else:<br />
file_lines = FileData<br />
<br />
# write to a file on disk<br />
if file_lines:<br />
file = open(incoming_directory + "/" + filename, "w")<br />
if not file:<br />
print "Cannot create file: %s/%s" % ( incoming_directory, filename )<br />
sys.exit(0)<br />
file.write(file_lines)<br />
file.close()<br />
print "Thank you for the file"<br />
done = 1<br />
<br />
if not done:<br />
print "Problem summiting data"<br />
<br />
=== TriggerSiteDart2AndCDash.cgi ===<br />
Note: If the script fails it will create log files in <tt>/tmp/tmp*.html</tt>.<br />
<br />
#!/usr/bin/env python<br />
#<br />
# Script that will resubmit incoming testing results to<br />
# Dart2 (via XMLRPC) and CDash (via HTTP).<br />
#<br />
# This scripts intended use is to allow the transition from<br />
# Dart2 to CDash, by allowing both to be run in parallel.<br />
#<br />
###<br />
<br />
import cgi<br />
import cgitb; cgitb.enable(display=0, logdir="/tmp")<br />
<br />
import sys<br />
import os<br />
import xmlrpclib<br />
import put<br />
<br />
def Trigger(dart2Url, cdashUrl, projectName, dropLocation):<br />
print "Content-Type: text/html"<br />
print<br />
<br />
form = cgi.FieldStorage()<br />
xmlfile = ""<br />
if "xmlfile" in form:<br />
xmlfile = form["xmlfile"].value<br />
<br />
if not xmlfile:<br />
print "No submission file"<br />
sys.exit(1)<br />
<br />
ipfile = dropLocation + xmlfile<br />
<br />
try:<br />
dart2Server = xmlrpclib.ServerProxy(dart2Url + projectName + "/Command/")<br />
<br />
try:<br />
fp = open(ipfile)<br />
content = fp.read()<br />
bin = xmlrpclib.Binary(content)<br />
print "Server responded: [%s]" % dart2Server.Submit.put(bin)<br />
fp.close()<br />
except Exception, v:<br />
print "ERROR", v<br />
print "Unexpected error:", sys.exc_info()<br />
except:<br />
print "Problem submitting XML-RPC for the file: %s" % xmlfile<br />
<br />
try:<br />
cdashServer = cdashUrl + "CDash/submit.php?project=" + projectName<br />
<br />
f = open(ipfile, 'rb')<br />
put.putfile(f, cdashServer)<br />
f.close()<br />
except:<br />
print "Problem submitting HTTP for the file: %s" % xmlfile<br />
<br />
os.unlink(ipfile)<br />
<br />
<br />
if __name__ == "__main__":<br />
# Ensure all paths have a trailing slash<br />
# Dart2 URL, CDash URL, project, incoming directory<br />
Trigger("http://localhost:8081/", "http://localhost/", "MyProject", "/srv/dart2/incoming/")<br />
<br />
=== put.py ===<br />
<br />
Note: This version of ''put'' requires Apache2 (for chunking).<br />
<br />
#!/usr/bin/env python<br />
"""<br />
put.py - Python HTTP PUT Client<br />
Author: Sean B. Palmer, inamidst.com<br />
<br />
Basic API usage, once with optional auth:<br />
<br />
import put<br />
put.putname('test.txt', 'http://example.org/test')<br />
<br />
f = open('test.txt', 'rb')<br />
put.putfile(f, 'http://example.org/test')<br />
f.close()<br />
<br />
bytes = open('test.txt', 'rb').read()<br />
auth = {'username': 'myuser', 'password': 'mypass'}<br />
put.put(bytes, 'http://example.org/test', **auth)<br />
"""<br />
<br />
import sys, httplib, urlparse<br />
from optparse import OptionParser<br />
<br />
# True by default when running as a script<br />
# Otherwise, we turn the noise off...<br />
verbose = True<br />
<br />
def barf(msg):<br />
print >> sys.stderr, "Error! %s" % msg<br />
sys.exit(1)<br />
<br />
if sys.version_info < (2, 4):<br />
barf("Requires Python 2.4+")<br />
<br />
def parseuri(uri):<br />
"""Parse URI, return (host, port, path) tuple.<br />
<br />
>>> parseuri('http://example.org/testing?somequery#frag')<br />
('example.org', 80, '/testing?somequery')<br />
>>> parseuri('http://example.net:8080/test.html')<br />
('example.net', 8080, '/test.html')<br />
"""<br />
<br />
scheme, netplace, path, query, fragid = urlparse.urlsplit(uri)<br />
<br />
if ':' in netplace:<br />
host, port = netplace.split(':', 2)<br />
port = int(port)<br />
else: host, port = netplace, 80<br />
<br />
if query: path += '?' + query<br />
<br />
return host, port, path<br />
<br />
def putfile(f, uri, username=None, password=None):<br />
"""HTTP PUT the file f to uri, with optional auth data."""<br />
host, port, path = parseuri(uri)<br />
<br />
redirect = set([301, 302, 307])<br />
authenticate = set([401])<br />
okay = set([200, 201, 204])<br />
<br />
authorized = False<br />
authorization = None<br />
tries = 0<br />
<br />
while True:<br />
# Attempt to HTTP PUT the data<br />
h = httplib.HTTPConnection(host, port)<br />
<br />
h.putrequest('PUT', path)<br />
<br />
h.putheader('User-Agent', 'put.py/1.0')<br />
h.putheader('Connection', 'keep-alive')<br />
h.putheader('Transfer-Encoding', 'chunked')<br />
h.putheader('Expect', '100-continue')<br />
h.putheader('Accept', '*/*')<br />
if authorization:<br />
h.putheader('Authorization', authorization)<br />
h.endheaders()<br />
<br />
# Chunked transfer encoding<br />
# Cf. 'All HTTP/1.1 applications MUST be able to receive and<br />
# decode the "chunked" transfer-coding'<br />
# - http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html<br />
while True:<br />
bytes = f.read(2048)<br />
if not bytes: break<br />
length = len(bytes)<br />
h.send('%X\r\n' % length)<br />
h.send(bytes + '\r\n')<br />
h.send('0\r\n\r\n')<br />
f.seek(0);<br />
<br />
resp = h.getresponse()<br />
status = resp.status # an int<br />
<br />
# Got a response, now decide how to act upon it<br />
if status in redirect:<br />
location = resp.getheader('Location')<br />
uri = urlparse.urljoin(uri, location)<br />
host, port, path = parseuri(uri)<br />
<br />
# We may have to authenticate again<br />
if authorization:<br />
authorization = None<br />
<br />
elif status in authenticate:<br />
# If we've done this already, break<br />
if authorization:<br />
# barf("Going around in authentication circles")<br />
<br />
barf("Authentication failed")<br />
<br />
if not (username and password):<br />
barf("Need a username and password to authenticate with")<br />
<br />
# Get the scheme: Basic or Digest?<br />
wwwauth = resp.msg['www-authenticate'] # We may need this again<br />
wauth = wwwauth.lstrip(' \t') # Hence use wauth not wwwauth here<br />
wauth = wwwauth.replace('\t', ' ')<br />
i = wauth.index(' ')<br />
scheme = wauth[:i].lower()<br />
<br />
if scheme in set(['basic', 'digest','Basic','Digest']):<br />
if verbose:<br />
msg = "Performing %s Authentication..." % scheme.capitalize()<br />
else: barf("Unknown authentication scheme: %s" % scheme)<br />
<br />
if scheme == 'basic' or scheme == 'Basic':<br />
import base64<br />
userpass = username + ':' + password<br />
userpass = base64.encodestring(userpass).strip()<br />
authorized, authorization = True, 'Basic ' + userpass<br />
<br />
elif scheme == 'digest':<br />
if verbose:<br />
msg = "uses fragile, undocumented features in urllib2"<br />
<br />
print >> sys.stderr, "Warning! Digest Auth %s" % msg<br />
<br />
import urllib2 # See warning above<br />
<br />
passwd = type('Password', (object,), {<br />
'find_user_password': lambda self, *args: (username, password),<br />
'add_password': lambda self, *args: None<br />
})()<br />
<br />
req = type('Request', (object,), {<br />
'get_full_url': lambda self: uri,<br />
'has_data': lambda self: None,<br />
'get_method': lambda self: 'PUT',<br />
'get_selector': lambda self: path<br />
})()<br />
<br />
# Cf. urllib2.AbstractDigestAuthHandler.retry_http_digest_auth<br />
auth = urllib2.AbstractDigestAuthHandler(passwd)<br />
token, challenge = wwwauth.split(' ', 1)<br />
chal = urllib2.parse_keqv_list(urllib2.parse_http_list(challenge))<br />
userpass = auth.get_authorization(req, chal)<br />
authorized, authorization = True, 'Digest ' + userpass<br />
<br />
elif status in okay:<br />
if (username and password) and (not authorized):<br />
msg = "Warning! The supplied username and password went unused"<br />
print msg<br />
<br />
if verbose:<br />
resultLine = "Success! Resource %s"<br />
statuses = {200: 'modified', 201: 'created', 204: 'modified'}<br />
print resultLine % statuses[status]<br />
<br />
statusLine = "Response-Status: %s %s"<br />
print statusLine % (status, resp.reason)<br />
<br />
body = resp.read(58)<br />
body = body.rstrip('\r\n')<br />
body = body.encode('string_escape')<br />
<br />
if len(body) >= 58:<br />
body = body[:57] + '[...]'<br />
<br />
bodyLine = 'Response-Body: "%s"'<br />
print bodyLine % body<br />
break<br />
<br />
# @@ raise PutError, do the catching in main?<br />
else: barf('Got "%s %s"' % (status, resp.reason))<br />
<br />
tries += 1<br />
if tries >= 50:<br />
barf("Too many redirects")<br />
<br />
return status, resp<br />
<br />
def putname(fn, uri, username=None, password=None):<br />
"""HTTP PUT the file with filename fn to uri, with optional auth data."""<br />
auth = {'username': username, 'password': password}<br />
<br />
if fn != '-':<br />
f = open(fn, 'rb')<br />
status, resp = putfile(f, uri, **auth)<br />
f.close()<br />
else: status, resp = putfile(sys.stdin, uri, **auth)<br />
<br />
return status, resp<br />
<br />
def put(s, uri, username=None, password=None):<br />
"""HTTP PUT the string s to uri, with optional auth data."""<br />
try: from cStringIO import StringIO<br />
except ImportError:<br />
from StringIO import StringIO<br />
<br />
f = StringIO(s)<br />
f.seek(0)<br />
status, resp = putfile(f, uri, username=username, password=password)<br />
f.close()<br />
<br />
return status, conn<br />
<br />
def main(argv=None):<br />
usage = ('%prog [options] filename uri\n' +<br />
'The filename may be - for stdin\n' +<br />
'Use command line password at your own risk!')<br />
<br />
parser = OptionParser(usage=usage)<br />
parser.add_option('-u', '--username', help='HTTP Auth username')<br />
parser.add_option('-p', '--password', help='HTTP Auth password')<br />
parser.add_option('-q', '--quiet', action='store_true', help="shhh!")<br />
options, args = parser.parse_args(argv)<br />
<br />
if len(args) != 2:<br />
parser.error("Requires two arguments, filename and uri")<br />
<br />
fn, uri = args<br />
if not uri.startswith('http:'):<br />
parser.error("The uri argument must start with 'http:'")<br />
<br />
if ((options.username and not options.password) or<br />
(options.password and not options.username)):<br />
parser.error("Must have both username and password or neither")<br />
<br />
global verbose<br />
verbose = (not options.quiet)<br />
<br />
auth = {'username': options.username, 'password': options.password}<br />
putname(fn, uri, **auth)<br />
<br />
if __name__ == '__main__':<br />
main()</div>Newaccthttps://public.kitware.com/Wiki/index.php?title=CDash:Dart2AndCDashSubmission&diff=17049CDash:Dart2AndCDashSubmission2009-10-23T00:48:38Z<p>Newacct: </p>
<hr />
<div>[[CDash | < CDash Main Page]]<br />
<br />
== Setting up dual Dart2 and CDash Submissions ==<br />
If you are moving from Dart2 to CDash you may want to submit to both dashboards in parallel for a while, before switching solely to CDash.<br />
<br />
The following shows how to setup CTest to use a trigger script, which in turn does a submit to both Dart2 (via XML-RPC) and CDash (via HTTP).<br />
<br />
Note: This method doesn't support submission of Dart2 notes files.<br />
<br />
Configure CTest to use a trigger script:<br />
<br />
SET (CTEST_DROP_METHOD "http")<br />
SET (CTEST_DROP_SITE "mysite.org")<br />
SET (CTEST_DROP_LOCATION "/cgi-bin/HTTPUploadDartFile.cgi")<br />
SET (CTEST_TRIGGER_SITE "http://${DROP_SITE}/cgi-bin/TriggerSiteDart2AndCDash.cgi")<br />
<br />
Both <tt>HTTPUploadDartFile.cgi</tt> and <tt>TriggerSiteDart2AndCDash.cgi</tt> have a hard coded path that may require editing: <tt>/srv/dart2/incoming</tt><br />
<br />
''This current implementation only supports a single hard coded project in <tt>TriggerSiteDart2AndCDash.cgi</tt>. You can of course create a specific trigger site per project to workaround this.''<br />
<br />
=== HTTPUploadDartFile.cgi ===<br />
<br />
#!/usr/bin/env python<br />
#<br />
# Script that will upload files to specified directory on the server, where<br />
# triggering script will find it.<br />
#<br />
# Installation:<br />
# Place this script in your cgi-bin area.<br />
# Change the variable "incoming_directory" to match your<br />
# installation.<br />
###<br />
<br />
import cgi<br />
import re<br />
import sys<br />
import os<br />
import string<br />
<br />
print "Content-type: text/html"<br />
print<br />
<br />
done = 0<br />
<br />
incoming_directory = '/srv/dart2/incoming'<br />
<br />
form = cgi.FieldStorage()<br />
<br />
# Debug<br />
#try:<br />
# tmpfile = open("/tmp/http_upload_log_file.log", "w")<br />
# tmpfile.write(`form`)<br />
# tmpfile.close()<br />
#except Exception: pass<br />
<br />
FileData = ""<br />
FileName = ""<br />
<br />
# process form<br />
if type(form.value) == type("foo"):<br />
if "QUERY_STRING" in os.environ:<br />
dt = cgi.parse_qs(os.environ["QUERY_STRING"])<br />
if "FileName" in dt:<br />
FileName = dt["FileName"][0]<br />
FileData = form.value<br />
elif "FileName" in form:<br />
FileName = form["FileName"].value<br />
if "FileData" in form:<br />
FileData = "form"<br />
<br />
# verify file specified<br />
if not FileData or not FileName:<br />
print "Please send file. "<br />
print "FileName has to contain file name"<br />
print "FileData has to contain file content"<br />
print form<br />
sys.exit(0)<br />
<br />
print "Received file: " + FileName<br />
<br />
# check if valid file name<br />
filename = re.sub("[/\\|:%%]", "_", FileName)<br />
if re.match(".+___.+___[0-9]{8}-[0-9]{4}-(Experimental|Nightly|Continuous)___XML___(Update|Configure|Build|Test|Coverage|Purify).xml", filename):<br />
print "Correct file name"<br />
else:<br />
print "Can only upload files with format:"<br />
print "<site>___<BuildType>___<TAG>-<TestType>___XML___<File>.xml"<br />
sys.exit(0)<br />
<br />
# get the file data<br />
file_lines = ""<br />
if FileData == "form":<br />
fileitem = form["FileData"]<br />
if fileitem.file:<br />
file_lines = fileitem.file.read()<br />
else:<br />
print "Not a file"<br />
else:<br />
file_lines = FileData<br />
<br />
# write to a file on disk<br />
if file_lines:<br />
file = open(incoming_directory + "/" + filename, "w")<br />
if not file:<br />
print "Cannot create file: %s/%s" % ( incoming_directory, filename )<br />
sys.exit(0)<br />
file.write(file_lines)<br />
file.close()<br />
print "Thank you for the file"<br />
done = 1<br />
<br />
if not done:<br />
print "Problem summiting data"<br />
<br />
=== TriggerSiteDart2AndCDash.cgi ===<br />
Note: If the script fails it will create log files in <tt>/tmp/tmp*.html</tt>.<br />
<br />
#!/usr/bin/env python<br />
#<br />
# Script that will resubmit incoming testing results to<br />
# Dart2 (via XMLRPC) and CDash (via HTTP).<br />
#<br />
# This scripts intended use is to allow the transition from<br />
# Dart2 to CDash, by allowing both to be run in parallel.<br />
#<br />
###<br />
<br />
import cgi<br />
import cgitb; cgitb.enable(display=0, logdir="/tmp")<br />
<br />
import sys<br />
import os<br />
import xmlrpclib<br />
import put<br />
<br />
def Trigger(dart2Url, cdashUrl, projectName, dropLocation):<br />
print "Content-Type: text/html"<br />
print<br />
<br />
form = cgi.FieldStorage()<br />
xmlfile = ""<br />
if "xmlfile" in form:<br />
xmlfile = form["xmlfile"].value<br />
<br />
if not xmlfile:<br />
print "No submission file"<br />
sys.exit(1)<br />
<br />
ipfile = dropLocation + xmlfile<br />
<br />
try:<br />
dart2Server = xmlrpclib.ServerProxy(dart2Url + projectName + "/Command/")<br />
<br />
try:<br />
fp = open(ipfile)<br />
content = fp.read()<br />
bin = xmlrpclib.Binary(content)<br />
print "Server responded: [%s]" % dart2Server.Submit.put(bin)<br />
fp.close()<br />
except Exception, v:<br />
print "ERROR", v<br />
print "Unexpected error:", sys.exc_info()<br />
except:<br />
print "Problem submitting XML-RPC for the file: %s" % xmlfile<br />
<br />
try:<br />
cdashServer = cdashUrl + "CDash/submit.php?project=" + projectName<br />
<br />
f = open(ipfile, 'rb')<br />
put.putfile(f, cdashServer)<br />
f.close()<br />
except:<br />
print "Problem submitting HTTP for the file: %s" % xmlfile<br />
<br />
os.unlink(ipfile)<br />
<br />
<br />
if __name__ == "__main__":<br />
# Ensure all paths have a trailing slash<br />
# Dart2 URL, CDash URL, project, incoming directory<br />
Trigger("http://localhost:8081/", "http://localhost/", "MyProject", "/srv/dart2/incoming/")<br />
<br />
=== put.py ===<br />
<br />
Note: This version of ''put'' requires Apache2 (for chunking).<br />
<br />
#!/usr/bin/env python<br />
"""<br />
put.py - Python HTTP PUT Client<br />
Author: Sean B. Palmer, inamidst.com<br />
<br />
Basic API usage, once with optional auth:<br />
<br />
import put<br />
put.putname('test.txt', 'http://example.org/test')<br />
<br />
f = open('test.txt', 'rb')<br />
put.putfile(f, 'http://example.org/test')<br />
f.close()<br />
<br />
bytes = open('test.txt', 'rb').read()<br />
auth = {'username': 'myuser', 'password': 'mypass'}<br />
put.put(bytes, 'http://example.org/test', **auth)<br />
"""<br />
<br />
import sys, httplib, urlparse<br />
from optparse import OptionParser<br />
<br />
# True by default when running as a script<br />
# Otherwise, we turn the noise off...<br />
verbose = True<br />
<br />
def barf(msg):<br />
print >> sys.stderr, "Error! %s" % msg<br />
sys.exit(1)<br />
<br />
if sys.version_info < (2, 4):<br />
barf("Requires Python 2.4+")<br />
<br />
def parseuri(uri):<br />
"""Parse URI, return (host, port, path) tuple.<br />
<br />
>>> parseuri('http://example.org/testing?somequery#frag')<br />
('example.org', 80, '/testing?somequery')<br />
>>> parseuri('http://example.net:8080/test.html')<br />
('example.net', 8080, '/test.html')<br />
"""<br />
<br />
scheme, netplace, path, query, fragid = urlparse.urlsplit(uri)<br />
<br />
if ':' in netplace:<br />
host, port = netplace.split(':', 2)<br />
port = int(port)<br />
else: host, port = netplace, 80<br />
<br />
if query: path += '?' + query<br />
<br />
return host, port, path<br />
<br />
def putfile(f, uri, username=None, password=None):<br />
"""HTTP PUT the file f to uri, with optional auth data."""<br />
host, port, path = parseuri(uri)<br />
<br />
redirect = set([301, 302, 307])<br />
authenticate = set([401])<br />
okay = set([200, 201, 204])<br />
<br />
authorized = False<br />
authorization = None<br />
tries = 0<br />
<br />
while True:<br />
# Attempt to HTTP PUT the data<br />
h = httplib.HTTPConnection(host, port)<br />
<br />
h.putrequest('PUT', path)<br />
<br />
h.putheader('User-Agent', 'put.py/1.0')<br />
h.putheader('Connection', 'keep-alive')<br />
h.putheader('Transfer-Encoding', 'chunked')<br />
h.putheader('Expect', '100-continue')<br />
h.putheader('Accept', '*/*')<br />
if authorization:<br />
h.putheader('Authorization', authorization)<br />
h.endheaders()<br />
<br />
# Chunked transfer encoding<br />
# Cf. 'All HTTP/1.1 applications MUST be able to receive and<br />
# decode the "chunked" transfer-coding'<br />
# - http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html<br />
while True:<br />
bytes = f.read(2048)<br />
if not bytes: break<br />
length = len(bytes)<br />
h.send('%X\r\n' % length)<br />
h.send(bytes + '\r\n')<br />
h.send('0\r\n\r\n')<br />
f.seek(0);<br />
<br />
resp = h.getresponse()<br />
status = resp.status # an int<br />
<br />
# Got a response, now decide how to act upon it<br />
if status in redirect:<br />
location = resp.getheader('Location')<br />
uri = urlparse.urljoin(uri, location)<br />
host, port, path = parseuri(uri)<br />
<br />
# We may have to authenticate again<br />
if authorization:<br />
authorization = None<br />
<br />
elif status in authenticate:<br />
# If we've done this already, break<br />
if authorization:<br />
# barf("Going around in authentication circles")<br />
<br />
barf("Authentication failed")<br />
<br />
if not (username and password):<br />
barf("Need a username and password to authenticate with")<br />
<br />
# Get the scheme: Basic or Digest?<br />
wwwauth = resp.msg['www-authenticate'] # We may need this again<br />
wauth = wwwauth.lstrip(' \t') # Hence use wauth not wwwauth here<br />
wauth = wwwauth.replace('\t', ' ')<br />
i = wauth.index(' ')<br />
scheme = wauth[:i].lower()<br />
<br />
if scheme in set(['basic', 'digest','Basic','Digest']):<br />
if verbose:<br />
msg = "Performing %s Authentication..." % scheme.capitalize()<br />
else: barf("Unknown authentication scheme: %s" % scheme)<br />
<br />
if scheme == 'basic' or scheme == 'Basic':<br />
import base64<br />
userpass = username + ':' + password<br />
userpass = base64.encodestring(userpass).strip()<br />
authorized, authorization = True, 'Basic ' + userpass<br />
<br />
elif scheme == 'digest':<br />
if verbose:<br />
msg = "uses fragile, undocumented features in urllib2"<br />
<br />
print >> sys.stderr, "Warning! Digest Auth %s" % msg<br />
<br />
import urllib2 # See warning above<br />
<br />
passwd = type('Password', (object,), {<br />
'find_user_password': lambda self, *args: (username, password),<br />
'add_password': lambda self, *args: None<br />
})()<br />
<br />
req = type('Request', (object,), {<br />
'get_full_url': lambda self: uri,<br />
'has_data': lambda self: None,<br />
'get_method': lambda self: 'PUT',<br />
'get_selector': lambda self: path<br />
})()<br />
<br />
# Cf. urllib2.AbstractDigestAuthHandler.retry_http_digest_auth<br />
auth = urllib2.AbstractDigestAuthHandler(passwd)<br />
token, challenge = wwwauth.split(' ', 1)<br />
chal = urllib2.parse_keqv_list(urllib2.parse_http_list(challenge))<br />
userpass = auth.get_authorization(req, chal)<br />
authorized, authorization = True, 'Digest ' + userpass<br />
<br />
elif status in okay:<br />
if (username and password) and (not authorized):<br />
msg = "Warning! The supplied username and password went unused"<br />
print msg<br />
<br />
if verbose:<br />
resultLine = "Success! Resource %s"<br />
statuses = {200: 'modified', 201: 'created', 204: 'modified'}<br />
print resultLine % statuses[status]<br />
<br />
statusLine = "Response-Status: %s %s"<br />
print statusLine % (status, resp.reason)<br />
<br />
body = resp.read(58)<br />
body = body.rstrip('\r\n')<br />
body = body.encode('string_escape')<br />
<br />
if len(body) >= 58:<br />
body = body[:57] + '[...]'<br />
<br />
bodyLine = 'Response-Body: "%s"'<br />
print bodyLine % body<br />
break<br />
<br />
# @@ raise PutError, do the catching in main?<br />
else: barf('Got "%s %s"' % (status, resp.reason))<br />
<br />
tries += 1<br />
if tries >= 50:<br />
barf("Too many redirects")<br />
<br />
return status, resp<br />
<br />
def putname(fn, uri, username=None, password=None):<br />
"""HTTP PUT the file with filename fn to uri, with optional auth data."""<br />
auth = {'username': username, 'password': password}<br />
<br />
if fn != '-':<br />
f = open(fn, 'rb')<br />
status, resp = putfile(f, uri, **auth)<br />
f.close()<br />
else: status, resp = putfile(sys.stdin, uri, **auth)<br />
<br />
return status, resp<br />
<br />
def put(s, uri, username=None, password=None):<br />
"""HTTP PUT the string s to uri, with optional auth data."""<br />
try: from cStringIO import StringIO<br />
except ImportError:<br />
from StringIO import StringIO<br />
<br />
f = StringIO(s)<br />
f.seek(0)<br />
status, resp = putfile(f, uri, username=username, password=password)<br />
f.close()<br />
<br />
return status, conn<br />
<br />
def main(argv=None):<br />
usage = ('%prog [options] filename uri\n' +<br />
'The filename may be - for stdin\n' +<br />
'Use command line password at your own risk!')<br />
<br />
parser = OptionParser(usage=usage)<br />
parser.add_option('-u', '--username', help='HTTP Auth username')<br />
parser.add_option('-p', '--password', help='HTTP Auth password')<br />
parser.add_option('-q', '--quiet', action='store_true', help="shhh!")<br />
options, args = parser.parse_args(argv)<br />
<br />
if len(args) != 2:<br />
parser.error("Requires two arguments, filename and uri")<br />
<br />
fn, uri = args<br />
if not uri.startswith('http:'):<br />
parser.error("The uri argument must start with 'http:'")<br />
<br />
if ((options.username and not options.password) or<br />
(options.password and not options.username)):<br />
parser.error("Must have both username and password or neither")<br />
<br />
global verbose<br />
verbose = (not options.quiet)<br />
<br />
auth = {'username': options.username, 'password': options.password}<br />
putname(fn, uri, **auth)<br />
<br />
if __name__ == '__main__':<br />
main()</div>Newacct