diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/files.cmake b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/files.cmake
index 8d551b3b8e..ee77a40cef 100644
--- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/files.cmake
+++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/files.cmake
@@ -1,98 +1,102 @@
SET(SRC_CPP_FILES
QmitkODFDetailsWidget.cpp
QmitkODFRenderWidget.cpp
QmitkPartialVolumeAnalysisWidget.cpp
QmitkIVIMWidget.cpp
)
SET(INTERNAL_CPP_FILES
mitkPluginActivator.cpp
QmitkQBallReconstructionView.cpp
QmitkPreprocessingView.cpp
QmitkDiffusionDicomImportView.cpp
QmitkDiffusionQuantificationView.cpp
QmitkTensorReconstructionView.cpp
QmitkDiffusionImagingPublicPerspective.cpp
QmitkControlVisualizationPropertiesView.cpp
QmitkODFDetailsView.cpp
QmitkGibbsTrackingView.cpp
+ QmitkStochasticFiberTrackingView.cpp
QmitkFiberBundleOperationsView.cpp
QmitkFiberBundleDeveloperView.cpp
QmitkPartialVolumeAnalysisView.cpp
QmitkIVIMView.cpp
QmitkScreenshotMaker.cpp
)
SET(UI_FILES
src/internal/QmitkQBallReconstructionViewControls.ui
src/internal/QmitkPreprocessingViewControls.ui
src/internal/QmitkDiffusionDicomImportViewControls.ui
src/internal/QmitkDiffusionQuantificationViewControls.ui
src/internal/QmitkTensorReconstructionViewControls.ui
src/internal/QmitkControlVisualizationPropertiesViewControls.ui
src/internal/QmitkODFDetailsViewControls.ui
src/internal/QmitkGibbsTrackingViewControls.ui
+ src/internal/QmitkStochasticFiberTrackingViewControls.ui
src/internal/QmitkFiberBundleOperationsViewControls.ui
src/internal/QmitkFiberBundleDeveloperViewControls.ui
src/internal/QmitkPartialVolumeAnalysisViewControls.ui
src/internal/QmitkIVIMViewControls.ui
src/internal/QmitkScreenshotMakerControls.ui
)
SET(MOC_H_FILES
src/internal/mitkPluginActivator.h
src/internal/QmitkQBallReconstructionView.h
src/internal/QmitkPreprocessingView.h
src/internal/QmitkDiffusionDicomImportView.h
src/internal/QmitkDiffusionImagingPublicPerspective.h
src/internal/QmitkDiffusionQuantificationView.h
src/internal/QmitkTensorReconstructionView.h
src/internal/QmitkControlVisualizationPropertiesView.h
src/internal/QmitkODFDetailsView.h
src/QmitkODFRenderWidget.h
src/QmitkODFDetailsWidget.h
src/internal/QmitkGibbsTrackingView.h
+ src/internal/QmitkStochasticFiberTrackingView.h
src/internal/QmitkFiberBundleOperationsView.h
src/internal/QmitkFiberBundleDeveloperView.h
src/internal/QmitkPartialVolumeAnalysisView.h
src/QmitkPartialVolumeAnalysisWidget.h
src/internal/QmitkIVIMView.h
src/internal/QmitkScreenshotMaker.h
)
SET(CACHED_RESOURCE_FILES
# list of resource files which can be used by the plug-in
# system without loading the plug-ins shared library,
# for example the icon used in the menu and tabs for the
# plug-in views in the workbench
plugin.xml
resources/preprocessing.png
resources/dwiimport.png
resources/quantification.png
resources/reconodf.png
resources/recontensor.png
resources/vizControls.png
resources/OdfDetails.png
resources/GibbsTracking.png
resources/FiberBundleOperations.png
resources/PartialVolumeAnalysis_24.png
resources/IVIM_48.png
resources/screenshot_maker.png
+ resources/stochFB.png
)
SET(QRC_FILES
# uncomment the following line if you want to use Qt resources
resources/QmitkDiffusionImaging.qrc
)
SET(CPP_FILES )
foreach(file ${SRC_CPP_FILES})
SET(CPP_FILES ${CPP_FILES} src/${file})
endforeach(file ${SRC_CPP_FILES})
foreach(file ${INTERNAL_CPP_FILES})
SET(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach(file ${INTERNAL_CPP_FILES})
diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/plugin.xml b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/plugin.xml
index 424de4d1b8..40aead2ee8 100644
--- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/plugin.xml
+++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/plugin.xml
@@ -1,103 +1,110 @@
+
+
+
+
diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/resources/QmitkDiffusionImaging.qrc b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/resources/QmitkDiffusionImaging.qrc
index 36cf2a9503..40c7714242 100644
--- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/resources/QmitkDiffusionImaging.qrc
+++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/resources/QmitkDiffusionImaging.qrc
@@ -1,32 +1,33 @@
qball.png
tensor.png
dwi.png
dwiimport.png
quantification.png
reconodf.png
recontensor.png
texIntONIcon.png
texIntOFFIcon.png
vizControls.png
Refresh_48.png
QBallData24.png
glyphsoff_C.png
glyphsoff_S.png
glyphsoff_T.png
glyphson_C.png
glyphson_S.png
glyphson_T.png
FiberBundle.png
+ FiberBundleX.png
rectangle.png
circle.png
polygon.png
color24.gif
color48.gif
color64.gif
crosshair.png
paint2.png
IVIM_48.png
diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/resources/stochFB.png b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/resources/stochFB.png
new file mode 100644
index 0000000000..26477610ed
Binary files /dev/null and b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/resources/stochFB.png differ
diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.cpp b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.cpp
new file mode 100644
index 0000000000..9873a691d2
--- /dev/null
+++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.cpp
@@ -0,0 +1,670 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Language: C++
+Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $
+Version: $Revision: 21975 $
+
+Copyright (c) German Cancer Research Center, Division of Medical and
+Biological Informatics. All rights reserved.
+See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+
+This software is distributed WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+
+
+// Blueberry
+#include
+#include
+#include "berryIStructuredSelection.h"
+
+
+// Qmitk
+#include "QmitkStochasticFiberTrackingView.h"
+#include "QmitkStdMultiWidget.h"
+
+// Qt
+#include
+
+//MITK
+//#include "mitkNodePredicateProperty.h"
+//#include "mitkNodePredicateAND.h"
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+const std::string QmitkStochasticFiberTrackingView::VIEW_ID = "org.mitk.views.stochasticfibertracking";
+const std::string id_DataManager = "org.mitk.views.datamanager";
+using namespace berry;
+
+// Strings for Data handling
+const QString qDiffStr = "DiffusionImage";
+const QString qStatusErr = "[Err]";
+const QString qStatusOk = "[OK]";
+const QString qSeed = "Seed";
+
+
+//*****PERSONAL REMINDER******
+//##############################
+/* THIS CLASS IS A MESS!!
+ * CLEANUP IN PROGRESS...
+ */
+//##############################
+
+
+
+
+QmitkStochasticFiberTrackingView::QmitkStochasticFiberTrackingView()
+: QmitkFunctionality()
+, m_Controls( 0 )
+, m_MultiWidget( NULL )
+{
+}
+
+// Destructor
+QmitkStochasticFiberTrackingView::~QmitkStochasticFiberTrackingView()
+{
+
+}
+
+
+void QmitkStochasticFiberTrackingView::CreateQtPartControl( QWidget *parent )
+{
+ // build up qt view, unless already done
+ if ( !m_Controls )
+ {
+ // create GUI widgets from the Qt Designer's .ui file
+ m_Controls = new Ui::QmitkStochasticFiberTrackingViewControls;
+ m_Controls->setupUi( parent );
+
+ // set tableWidget column with
+ m_Controls->tableWidget->setColumnWidth(0,38);
+ m_Controls->tableWidget->setColumnWidth(1,250);
+ m_Controls->tableWidget->setEnabled(false);
+ m_Controls->tableWidget->setLineWidth(0);
+
+ connect( m_Controls->commandLinkButton, SIGNAL(clicked()), this, SLOT(DoFiberTracking()) );
+ //connect( m_Controls->comboBox_fiberAlgo, SIGNAL(selected()), this, SLOT(handleAlgoSelection() );
+
+
+ }
+}
+
+void QmitkStochasticFiberTrackingView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
+{
+ m_MultiWidget = &stdMultiWidget;
+}
+
+
+void QmitkStochasticFiberTrackingView::StdMultiWidgetNotAvailable()
+{
+ m_MultiWidget = NULL;
+}
+
+/* This method refreshes the Status-Message and its corresponding filename of tableWidget
+ Input: tmpVec: contains either dwi-image-DataNode or seedImage-DataNodes
+ tmpStatus: flag if dataNode-vector contains correct nodes or not */
+void QmitkStochasticFiberTrackingView::refreshTableWidget(std::vector tmpVec , QString tmpStatus)
+{
+
+ for(int idw=0; idw<(int)tmpVec.size(); idw++){
+ mitk::DataNode::Pointer tmpnode;
+ QTableWidgetItem *itemStatus = new QTableWidgetItem;
+ QTableWidgetItem *itemText = new QTableWidgetItem;
+ tmpnode = tmpVec.at(idw);
+ itemText->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ itemText->setText( tmpnode->GetName().c_str() );
+ itemStatus->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter);
+ itemStatus->setText(tmpStatus);
+ if(tmpStatus.compare(qStatusErr) == 0){
+ itemText->setTextColor(QColor(90, 0, 3, 255));
+ itemStatus->setTextColor(QColor(90, 0, 3, 255));
+ }else{
+ itemText->setTextColor(QColor(92, 198, 10, 255));
+ itemStatus->setTextColor(QColor(92, 198, 10, 255));
+ }
+ /* take next available row */
+ int row = m_Controls->tableWidget->rowCount();
+ m_Controls->tableWidget->insertRow(row);
+ m_Controls->tableWidget->setItem(row,0,itemStatus);
+ m_Controls->tableWidget->setItem(row,1,itemText);
+
+ }
+
+}
+
+/* This method checks if given node is validSeed image*/
+bool QmitkStochasticFiberTrackingView::checkSeedROI( mitk::DataNode::Pointer node )
+{
+ bool isSeed = false;
+ QString qClassName = node->GetData()->GetNameOfClass();
+
+ /* propValue contains the result after calling GetPropertyValue
+ success contains the bool if desired propertyname is available or not */
+ bool propValue = false;
+ bool success = node->GetPropertyValue("binary",propValue);
+
+ if(qClassName.compare("Image") == 0 && success == true && propValue == true)
+ isSeed = true;
+
+ return isSeed;
+}
+/* This method checks if given node is dwi image*/
+bool QmitkStochasticFiberTrackingView::checkDWIType( mitk::DataNode::Pointer node )
+{
+ bool isDwi = false;
+ QString qClassName = node->GetData()->GetNameOfClass(); // ie. TensorImage or DiffusionImage
+ if(qClassName.compare(qDiffStr) == 0)
+ isDwi = true;
+
+ return isDwi;
+
+}
+
+/* OnSelectionChanged is registered to SelectionService, therefore no need to
+ implement SelectionService Listener explicitly */
+
+void QmitkStochasticFiberTrackingView::OnSelectionChanged( std::vector nodes )
+{
+ //++++++++RESET GUI AND POINTER VECTORS+++++++++++++++
+ /* clear GUI tableWidget */
+ for( int i=m_Controls->tableWidget->rowCount(); i >= 0; --i)
+ {
+ m_Controls->tableWidget->removeRow(i);
+ }
+
+ /* reset DWI selection vector */
+ vPselDWImg.clear();
+ vSeedROI.clear();
+ //+++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ //############### HOMELAND SECURITY ################################
+ /* When selection not empty, extract data of interest,
+ otherwise return */
+ if(!nodes.empty()){
+
+ /* Flag to set commandButton enabled or not
+ keep flag true until selection is not DWIImage */
+ bool flag_execFTComd = true;
+
+ /* checkpoint for singe Seedpoint track */
+ // singleSeedpoint is depricated
+ // m_singleSeedpoint = false; //for debugging singleSeedpoint is init here, otherwise get boolean from GUI
+
+ for( std::vector::iterator it = nodes.begin();
+ it != nodes.end(); ++it )
+ {
+ //flags needed for algorithm execution logic
+ bool isDWI = false;
+ bool isSeed = false;
+ mitk::DataNode::Pointer node = *it;
+ if( node.IsNotNull() && dynamic_cast(node->GetData()) )
+ {
+ /* Check and sort image types */
+ isDWI = checkDWIType(node);
+ if( isDWI ){
+ vPselDWImg.push_back(*it);
+
+ } else if(!m_singleSeedpoint){
+ isSeed = checkSeedROI(node);
+ if( isSeed )
+ vSeedROI.push_back(*it);
+
+ } //else single seedPoint
+
+ } //end if node.IsNotNull && dynamic_cast mitkImage
+ } //end node iterator
+
+
+ //############### BORDER CONTROL ################################
+ /* ++++++++ Logic to en/disable execution of Algorithm +++++++++++
+ Requirements: 1 dwi Image, >=1 Seedimage(s) or 1 single seedpoint */
+ if(vPselDWImg.size() > 1){
+ flag_execFTComd = false;
+ std::cout << "TODO GUI Warning, too much dwi images selected \n";
+ refreshTableWidget(vPselDWImg, qStatusErr);
+
+ }else if(vPselDWImg.empty()){
+ flag_execFTComd = false;
+ std::cout << "TODO GUI Warning, NO dwi image selected \n";
+
+ }else{ // exactly 1 node in vector
+ flag_execFTComd = true;
+ refreshTableWidget(vPselDWImg, qStatusOk);
+ }
+
+ if(!m_singleSeedpoint){
+ //no manual selection
+
+ if(vSeedROI.empty()){
+ flag_execFTComd = false;
+ std::cout << "TODO GUI Warning, NO seed image selected \n";
+ }else{
+ //color seedImages green
+ refreshTableWidget(vSeedROI, qSeed);
+ }
+
+ }
+
+ /* Logic to Dis-/Enable Execute-FiberTracking-Button */
+ if (m_Controls->commandLinkButton->isEnabled())
+ {
+ if(!flag_execFTComd)
+ m_Controls->commandLinkButton->setEnabled(false);
+
+ } else if(flag_execFTComd){
+
+ m_Controls->commandLinkButton->setEnabled(true);
+ }
+ } else { // else statement of " if node.isEmpty() "
+
+ /* Selection from datamanager is empty
+ therefore set commandButton disable if necessary */
+ if(m_Controls->commandLinkButton->isEnabled())
+ {
+ m_Controls->commandLinkButton->setEnabled(false);
+ return;
+ }
+ }
+
+}
+
+
+
+void QmitkStochasticFiberTrackingView::DoFiberTracking()
+{
+
+ // for debugging use only first image node
+ mitk::DataNode::Pointer SpDWI = vPselDWImg.at(0);
+
+
+
+
+ // cast node to compatible type
+ mitk::DiffusionImage::Pointer dwiImg = dynamic_cast< mitk::DiffusionImage* >( SpDWI->GetData() );
+
+ /* get Gradients/Direction of dwi */
+ itk::VectorContainer< unsigned int, vnl_vector_fixed >::Pointer Pdir = dwiImg->GetDirections();
+
+ /* bValueContainer, Container includes b-values according to corresponding gradient-direction*/
+ PTFilterType::bValueContainerType::Pointer vecCont = PTFilterType::bValueContainerType::New();
+
+ /* for each gradient set b-Value; for 0-gradient set b-value eq. 0 */
+ for ( int i=0; i<(int)Pdir->size(); ++i)
+ {
+ vnl_vector_fixed valsGrad = Pdir->at(i);
+ if (valsGrad.get(0) == 0 && valsGrad.get(1) == 0 && valsGrad.get(2) == 0)
+ { //set 0-Gradient to bValue 0
+ vecCont->InsertElement(i,0);
+ }else{
+ vecCont->InsertElement(i,dwiImg->GetB_Value());
+ }
+ }
+
+ /* former variant without setting 0-Gradient to 0
+ for(int i=0; iGetDirections()->Size(); i++)
+ vecCont->InsertElement(i,dwiImg->GetB_Value());
+ */
+
+ /* define measurement frame (identity-matrix 3x3) */
+ PTFilterType::MeasurementFrameType measurement_frame;
+ measurement_frame.set_identity();
+
+ /* generate white matterImage */
+ FloatImageType::Pointer wmImage = FloatImageType::New();
+ wmImage->SetSpacing( dwiImg->GetVectorImage()->GetSpacing() );
+ wmImage->SetOrigin( dwiImg->GetVectorImage()->GetOrigin() );
+ wmImage->SetDirection( dwiImg->GetVectorImage()->GetDirection() );
+ wmImage->SetLargestPossibleRegion( dwiImg->GetVectorImage()->GetLargestPossibleRegion() );
+ wmImage->SetBufferedRegion( wmImage->GetLargestPossibleRegion() );
+ wmImage->SetRequestedRegion( wmImage->GetLargestPossibleRegion() );
+ wmImage->Allocate();
+
+ itk::ImageRegionIterator ot(wmImage, wmImage->GetLargestPossibleRegion() );
+ while (!ot.IsAtEnd())
+ {
+ ot.Set(1);
+ ++ot;
+ }
+
+ /* init TractographyFilter, note: it's a smartpointer */
+ PTFilterType::Pointer ptfilterPtr = PTFilterType::New();
+
+ ptfilterPtr->SetInput(dwiImg->GetVectorImage().GetPointer());
+ ptfilterPtr->SetbValues(vecCont);
+ ptfilterPtr->SetGradients(Pdir);
+ ptfilterPtr->SetMeasurementFrame(measurement_frame);
+ ptfilterPtr->SetWhiteMatterProbabilityImageInput(wmImage);
+ /*** get parameters from GUI ... TODO check validity during user input ***/
+ ptfilterPtr->SetTotalTracts(m_Controls->lineEdit_totalTracts->text().toInt());
+ ptfilterPtr->SetMaxLikelihoodCacheSize(m_Controls->lineEdit_likelihood_cache->text().toInt());
+ ptfilterPtr->SetMaxTractLength(m_Controls->lineEdit_maxTractLength->text().toInt());
+
+
+ /* define seed Index manual */
+ //PTFilterType::InputDWIImageType::IndexType seedIdx;
+ //seedIdx[0] = m_Controls->lineEdit_seedIndex1->text().toInt();
+ //seedIdx[1] = m_Controls->lineEdit_seedIndex2->text().toInt();
+ //seedIdx[2] = m_Controls->lineEdit_seedIndex3->text().toInt();
+
+
+
+
+
+ /* SEEDPOINT/REGION PREPARATION */
+ m_tractcontainer = PTFilterType::TractContainerType::New();
+
+
+
+ //int seedROIcnt = vSeedROI.size();
+
+ // ############## SEED OPERATIONS ########
+ // todo iterate over all seed ROIs
+ /// for(int si=0; si(SpSeedR->GetData());
+
+ /* nice structure of fibers in datamanager */
+/* mitk::DataNode::Pointer roiParentNode;
+ roiParentNode = mitk::DataNode::New();
+ roiParentNode->SetName("FiberBundle_ROI_1");
+ roiParentNode->SetData(mitkSeed);
+ roiParentNode->SetVisibility(true);
+
+ GetDataStorage()->Add(roiParentNode);*/
+
+
+
+ //itk::Image< char, 3 >
+ mitk::ImageToItk< itk::Image< unsigned char, 3 > >::Pointer binaryImageToItk1 = mitk::ImageToItk< itk::Image< unsigned char, 3 > >::New();
+ binaryImageToItk1->SetInput( mitkSeed );
+ binaryImageToItk1->Update();
+
+
+
+ itk::ImageRegionConstIterator< BinaryImageType > it(binaryImageToItk1->GetOutput(), binaryImageToItk1->GetOutput()->GetRequestedRegion());
+ it.Begin();
+
+ while(!it.IsAtEnd())
+ {
+ itk::ImageConstIterator::PixelType tmpPxValue = it.Get();
+
+ if(tmpPxValue != 0){
+ itk::ImageRegionConstIterator< BinaryImageType >::IndexType seedIdx = it.GetIndex();
+ ptfilterPtr->SetSeedIndex(seedIdx);
+ ptfilterPtr->Update();
+
+ /* get results from Filter */
+ /* write each single tract into member container */
+ PTFilterType::TractContainerType::Pointer container_tmp = ptfilterPtr->GetOutputTractContainer();
+ CImageType::Pointer cmap = ptfilterPtr->GetOutput();
+
+ PTFilterType::TractContainerType::Iterator elIt = container_tmp->Begin();
+ PTFilterType::TractContainerType::Iterator end = container_tmp->End();
+
+ while( elIt != end ){
+ PTFilterType::TractContainerType::Element tract_tmp = elIt.Value();
+ m_tractcontainer->InsertElement(m_tractcontainer->Size(),tract_tmp);
+ ++elIt;
+ }
+ }
+ ++it;
+
+ }
+ // }
+
+ /* allocate the VTK Polydata to output the tracts */
+ vtkSmartPointer pts = vtkSmartPointer::New();
+
+ vtkSmartPointer cells = vtkSmartPointer::New();
+
+ float bounds[] = {0,0,0};
+ bounds[0] = dwiImg->GetLargestPossibleRegion().GetSize().GetElement(0);
+ bounds[1] = dwiImg->GetLargestPossibleRegion().GetSize().GetElement(1);
+ bounds[2] = dwiImg->GetLargestPossibleRegion().GetSize().GetElement(2);
+
+
+
+ mitk::FiberBundle::Pointer transformer = mitk::FiberBundle::New();
+ transformer->additkStochTractContainer(m_tractcontainer);
+ transformer->initFiberGroup();
+ transformer->SetGeometry(dwiImg->GetGeometry());
+ transformer->SetBounds(bounds);
+
+
+ //transformer->debug_members();
+
+ //testing, get dti Fibers out of group
+ mitk::FiberBundle::FiberGroupType::Pointer fiberBundle = transformer->GetGroupFiberBundle();
+ mitk::FiberBundle::ChildrenListType *fibersList = fiberBundle->GetChildren();
+ for(mitk::FiberBundle::ChildrenListType::iterator itFibers = fibersList->begin();
+ itFibers != fibersList->end();
+ ++itFibers)
+ {
+ //we know we have DTITubeSpatialObjects stored in List
+ DTITubeType::Pointer dtiTract = dynamic_cast (itFibers->GetPointer());
+
+
+ }
+
+ mitk::DataNode::Pointer fbNode;
+ fbNode = mitk::DataNode::New();
+ fbNode->SetData(transformer);
+ fbNode->SetName("GroupFinberBundle");
+ fbNode->SetVisibility(true);
+ GetDataStorage()->Add(fbNode);
+
+ for( int i=0; i<(int)m_tractcontainer->Size(); i++ )
+ {
+
+ /* for each iteration create a new dtiTube containing a list of its points */
+ DTITubeType::Pointer dtiTube = DTITubeType::New();
+ DTITubeType::PointListType list;
+
+ mitk::PointSet::Pointer pointSet = mitk::PointSet::New();
+ mitk::Point3D point;
+
+ PTFilterType::TractContainerType::Element tract =
+ m_tractcontainer->GetElement(i);
+ PTFilterType::TractContainerType::Element::ObjectType::VertexListType::ConstPointer vertexlist =
+ tract->GetVertexList();
+
+ /* create VTK points and PolyLine */
+
+ vtkSmartPointer polyLine = vtkSmartPointer::New();
+ polyLine->GetPointIds()->SetNumberOfIds((int)vertexlist->Size());
+
+ unsigned long pntIdxHelper = pts->GetNumberOfPoints();
+
+ for( int j=0; j<(int)vertexlist->Size(); j++){
+
+ PTFilterType::TractContainerType::Element::ObjectType::VertexListType::Element vertex =
+ vertexlist->GetElement(j);
+
+ float vertex_f[3] = {(float)vertex[0],(float)vertex[1],(float)vertex[2]};
+ mitk::Point3D world(vertex_f);
+
+ dwiImg->GetGeometry()->IndexToWorld(world, point);
+
+ /* VTK add Points */
+ double vertex_d[3] = {(double)vertex[0],(double)vertex[1],(double)vertex[2]};
+ pts->InsertNextPoint(vertex_d);
+ polyLine->GetPointIds()->SetId(j,j+pntIdxHelper);
+
+
+ }
+
+
+ /* dtiTubes
+ dtiTube->GetProperty()->SetName("dtiTube");
+ dtiTube->SetId(i);
+ dtiTube->SetPoints(list);
+ myFiberScene->AddSpatialObject(dtiTube);*/
+
+
+ /* VTK add line */
+ cells->InsertNextCell(polyLine);
+
+
+
+ /*mitk::DataNode::Pointer curveNode;
+ curveNode = mitk::DataNode::New();
+ curveNode->SetData(spline);
+ curveNode->SetName("Fiber");
+ curveNode->SetVisibility(true);
+ GetDataStorage()->Add(curveNode, roiParentNode);
+ */
+
+ mitk::Point3D newIdx3D;
+
+
+ // std::cout << "cross position world: " << m_MultiWidget->GetCrossPosition() << "\n" ;
+ // std::cout << "cross position index: " << newIdx3D << "\n" ;
+
+
+ }
+
+
+ /*
+ //////////////
+ // Klaus' Code
+
+ //////////////////////
+ // Generate RGBA Image
+ typedef itk::RGBAPixel OutPixType;
+
+ // run generator
+ typedef itk::TractsToProbabilityImageFilter ImageGeneratorType;
+ ImageGeneratorType::Pointer generator = ImageGeneratorType::New();
+ generator->SetInput(wmImage);
+ generator->SetTractContainer(m_tractcontainer);
+ generator->SetUpsamplingFactor(20);
+ generator->SetMinTractLength(10);
+ //generator->Update();
+
+ // get result
+ typedef itk::Image OutType;
+ OutType::Pointer outImg = generator->GetOutput();
+
+ mitk::Image::Pointer img = mitk::Image::New();
+ img->InitializeByItk(outImg.GetPointer());
+ img->SetVolume(outImg->GetBufferPointer());
+
+ // write to datastorage
+ mitk::DataNode::Pointer node1 = mitk::DataNode::New();
+ node1->SetData(img);
+ node1->SetName("RgbImage");
+ node1->SetVisibility(true);
+
+ mitk::LevelWindow opaclevwin;
+ opaclevwin.SetRangeMinMax(0,255);
+ opaclevwin.SetWindowBounds(0,0);
+ mitk::LevelWindowProperty::Pointer prop = mitk::LevelWindowProperty::New(opaclevwin);
+ node1->AddProperty( "opaclevelwindow", prop );
+
+ GetDataStorage()->Add(node1);
+
+ ///////////////////////////////
+ // Generate unsigned char Image
+ typedef unsigned char OutPixType2;
+
+ // run generator
+ typedef itk::TractsToProbabilityImageFilter ImageGeneratorType2;
+ ImageGeneratorType2::Pointer generator2 = ImageGeneratorType2::New();
+ generator2->SetInput(wmImage);
+ generator2->SetTractContainer(m_tractcontainer);
+ generator2->SetUpsamplingFactor(20);
+ generator2->SetMinTractLength(10);
+ generator2->Update();
+
+ // get result
+ typedef itk::Image OutType2;
+ OutType2::Pointer outImg2 = generator2->GetOutput();
+
+ mitk::Image::Pointer img2 = mitk::Image::New();
+ img2->InitializeByItk(outImg2.GetPointer());
+ img2->SetVolume(outImg2->GetBufferPointer());
+
+ // to datastorage
+ mitk::DataNode::Pointer node2 = mitk::DataNode::New();
+ node2->SetData(img2);
+ node2->SetName("ProbImage");
+ node2->SetVisibility(true);
+
+ mitk::LevelWindow opaclevwin2;
+ opaclevwin2.SetRangeMinMax(0,255);
+ opaclevwin2.SetWindowBounds(0,0);
+ mitk::LevelWindowProperty::Pointer prop2 = mitk::LevelWindowProperty::New(opaclevwin2);
+ node2->AddProperty( "opaclevelwindow", prop2 );
+
+ GetDataStorage()->Add(node2);
+ */
+
+ GetDataStorage()->Modified();
+
+ m_MultiWidget->RequestUpdate();
+
+
+ /*
+ vtkSmartPointer linesPolyData = vtkSmartPointer::New();
+
+ linesPolyData->SetPoints(pts);
+ linesPolyData->SetLines(cells);
+
+ //setup actor and mapper
+ vtkSmartPointer mapper =
+ vtkSmartPointer::New();
+ mapper->SetInput(linesPolyData);
+
+ vtkSmartPointer actor =
+ vtkSmartPointer::New();
+ actor->SetMapper(mapper);
+
+ //setup render window, renderer, and interactor
+ vtkSmartPointer renderer =
+ vtkSmartPointer::New();
+ vtkSmartPointer renderWindow =
+ vtkSmartPointer::New();
+ renderWindow->AddRenderer(renderer);
+ vtkSmartPointer renderWindowInteractor =
+ vtkSmartPointer::New();
+ renderWindowInteractor->SetRenderWindow(renderWindow);
+ renderer->AddActor(actor);
+
+ renderWindow->Render();
+ renderWindowInteractor->Start();
+
+ */
+
+}
+
+
diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.h b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.h
new file mode 100644
index 0000000000..4595c0560a
--- /dev/null
+++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.h
@@ -0,0 +1,125 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Language: C++
+Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $
+Version: $Revision: 21975 $
+
+Copyright (c) German Cancer Research Center, Division of Medical and
+Biological Informatics. All rights reserved.
+See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+
+This software is distributed WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+
+#ifndef QmitkStochasticFiberTrackingView_h
+#define QmitkStochasticFiberTrackingView_h
+
+#include
+#include
+
+
+#include
+#include
+
+#include "ui_QmitkStochasticFiberTrackingViewControls.h"
+
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+
+
+
+
+
+//define the input/output types
+typedef itk::VectorImage< short int, 3 > DWIVectorImageType;
+typedef itk::Image< float, 3 > FloatImageType;
+typedef itk::Image< unsigned int, 3 > CImageType;
+typedef itk::StochasticTractographyFilter< DWIVectorImageType, FloatImageType, CImageType > PTFilterType;
+typedef itk::DTITubeSpatialObject<3> DTITubeType;
+typedef itk::DTITubeSpatialObjectPoint<3> DTITubePointType;
+typedef itk::SceneSpatialObject<3> SceneSpatialObjectType;
+
+/*!
+\brief QmitkFiberTrackingView
+
+\warning This application module is not yet documented. Use "svn blame/praise/annotate" and ask the author to provide basic documentation.
+
+\sa QmitkFunctionality
+\ingroup Functionalities
+*/
+class /*MitkDiffusionImaging_EXPORT*/ QmitkStochasticFiberTrackingView : public QmitkFunctionality
+{
+
+
+ // this is needed for all Qt objects that should have a Qt meta-object
+ // (everything that derives from QObject and wants to have signal/slots)
+ Q_OBJECT
+
+public:
+
+ static const std::string VIEW_ID;
+
+ QmitkStochasticFiberTrackingView();
+ virtual ~QmitkStochasticFiberTrackingView();
+
+ virtual void CreateQtPartControl(QWidget *parent);
+
+ virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget);
+ virtual void StdMultiWidgetNotAvailable();
+
+ protected slots:
+
+ /// \brief Called when the user clicks the GUI button
+ void DoFiberTracking();
+// void handleAlgoSelection();
+
+
+
+protected:
+
+ /// \brief called by QmitkFunctionality when DataManager's selection has changed
+ virtual void OnSelectionChanged( std::vector nodes );
+
+ Ui::QmitkStochasticFiberTrackingViewControls* m_Controls;
+
+ QmitkStdMultiWidget* m_MultiWidget;
+
+private:
+
+
+// \brief vector containing related (DiffusionImage) nodes of interest
+ std::vector vPselDWImg;
+// \brief vector containing SeedRegions(binary) nodes of interest
+ std::vector vSeedROI;
+
+// \brief flag to de-/activate manual seedPoint index-coordinates
+ bool m_singleSeedpoint;
+ bool checkDWIType( mitk::DataNode::Pointer );
+ void refreshTableWidget(std::vector , QString );
+ bool checkSeedROI( mitk::DataNode::Pointer );
+ typedef itk::Image< unsigned char, 3 > BinaryImageType;
+ // \brief container storing all found tracts
+ PTFilterType::TractContainerType::Pointer m_tractcontainer;
+
+
+};
+
+
+
+#endif // _QMITKFIBERTRACKINGVIEW_H_INCLUDED
+
diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingViewControls.ui b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingViewControls.ui
new file mode 100644
index 0000000000..e6b0666041
--- /dev/null
+++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingViewControls.ui
@@ -0,0 +1,155 @@
+
+
+ QmitkStochasticFiberTrackingViewControls
+
+
+
+ 0
+ 0
+ 254
+ 331
+
+
+
+
+ 0
+ 0
+
+
+
+ QmitkTemplate
+
+
+ -
+
+
+ Selected Image(s)
+
+
+
+ -
+
+
+ true
+
+
+
+ 204
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ true
+
+
+ Qt::NoPen
+
+
+ true
+
+
+
+ Status
+
+
+
+
+ FileName
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 12
+ 20
+
+
+
+
+ -
+
+
+ false
+
+
+ Execute FibreTracking
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 220
+
+
+
+
+ -
+
+
+ Tract_len
+
+
+
+ -
+
+
+ 50
+
+
+
+ -
+
+
+ TotalTracts
+
+
+
+ -
+
+
+ 1
+
+
+
+ -
+
+
+ Lkhd cache
+
+
+
+ -
+
+
+ 500
+
+
+
+
+
+
+
+ tableWidget
+ commandLinkButton
+
+
+
+
diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp
index 96a030db11..97a8407366 100644
--- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp
+++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp
@@ -1,50 +1,52 @@
#include "mitkPluginActivator.h"
#include
#include "src/internal/QmitkDiffusionImagingPublicPerspective.h"
#include "src/internal/QmitkQBallReconstructionView.h"
#include "src/internal/QmitkPreprocessingView.h"
#include "src/internal/QmitkDiffusionDicomImportView.h"
#include "src/internal/QmitkDiffusionQuantificationView.h"
#include "src/internal/QmitkTensorReconstructionView.h"
#include "src/internal/QmitkControlVisualizationPropertiesView.h"
#include "src/internal/QmitkODFDetailsView.h"
#include "src/internal/QmitkGibbsTrackingView.h"
+#include "src/internal/QmitkStochasticFiberTrackingView.h"
#include "src/internal/QmitkFiberBundleOperationsView.h"
#include "src/internal/QmitkFiberBundleDeveloperView.h"
#include "src/internal/QmitkPartialVolumeAnalysisView.h"
#include "src/internal/QmitkIVIMView.h"
#include "src/internal/QmitkScreenshotMaker.h"
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionImagingPublicPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkQBallReconstructionView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkPreprocessingView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionDicomImport, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionQuantificationView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkTensorReconstructionView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkControlVisualizationPropertiesView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkODFDetailsView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkGibbsTrackingView, context)
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkStochasticFiberTrackingView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberBundleOperationsView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberBundleDeveloperView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkPartialVolumeAnalysisView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkIVIMView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkScreenshotMaker, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
Q_EXPORT_PLUGIN2(org_mitk_gui_qt_diffusionimaging, mitk::PluginActivator)
diff --git a/Modules/DiffusionImaging/Tractography/StochasticTracking/StochasticTractographyFilter.cxx b/Modules/DiffusionImaging/Tractography/StochasticTracking/StochasticTractographyFilter.cxx
new file mode 100644
index 0000000000..791e62590f
--- /dev/null
+++ b/Modules/DiffusionImaging/Tractography/StochasticTracking/StochasticTractographyFilter.cxx
@@ -0,0 +1,570 @@
+#include "itkStochasticTractographyFilter.h"
+#include "itkVectorImage.h"
+#include "itkImageSeriesReader.h" //this is needed for itk::ExposeMetaData()
+#include "itkImageFileReader.h"
+#include "itkImageFileWriter.h"
+#include "itkMetaDataDictionary.h"
+#include "itkAddImageFilter.h"
+#include "itkUnaryFunctorImageFilter.h"
+#include
+#include
+#include "itkImageRegionConstIterator.h"
+#include "StochasticTractographyFilterCLP.h"
+#include "itkTensorFractionalAnisotropyImageFilter.h"
+#include "itkPathIterator.h"
+#include
+#include
+
+std::string stripExtension(const std::string& fileName){
+ const int length = fileName.length();
+ for (int i=0; i!=length; ++i){
+ if (fileName[i]=='.'){
+ return fileName.substr(0,i);
+ }
+ }
+ return fileName;
+}
+
+
+template< class TTOContainerType >
+bool SamplingDirections(const char* fn, typename TTOContainerType::Pointer directions){
+ char str[100];
+ double x,y,z;
+ std::ifstream m_file;
+ typename TTOContainerType::Element direction;
+
+ //open the file
+ m_file.open(fn);
+ if(!m_file.is_open()){
+ std::cerr<<"Problems opening: "<< fn << std::endl;
+ return false;
+ }
+ else{
+ //load file info into valid itk representation
+ //assume all entries in the file describe a vector of length 1
+ //each line is arranged [x, y, z]
+ unsigned int directioncount=0;
+
+ while(!m_file.getline(str, 100, '\n').eof()){
+ for(int i=0;i<3;i++){
+ sscanf(str,"%lf %lf %lf",&x,&y,&z);
+ direction[0]=x;
+ direction[1]=y;
+ direction[2]=z;
+ }
+ directions->InsertElement(directioncount++,direction);
+ }
+ }
+
+ //close file
+ m_file.close();
+ return true;
+}
+
+template< class TractContainerType >
+bool WriteTractContainerToFile( const char* fn, TractContainerType* tractcontainer ){
+ std::ofstream tractfile( fn, std::ios::out | std::ios::binary );
+ tractfile.seekp(0);
+ if(tractfile.is_open()){
+ for(int i=0; iSize(); i++ ){
+ typename TractContainerType::Element tract =
+ tractcontainer->GetElement(i);
+
+ typename TractContainerType::Element::ObjectType::VertexListType::ConstPointer vertexlist =
+ tract->GetVertexList();
+
+ for(int j=0; jSize(); j++){
+ typename TractContainerType::Element::ObjectType::VertexListType::Element vertex =
+ vertexlist->GetElement(j);
+ tractfile.write((char*)&vertex[0], sizeof(vertex[0]));
+ tractfile.write((char*)&vertex[1], sizeof(vertex[1]));
+ tractfile.write((char*)&vertex[2], sizeof(vertex[2]));
+ }
+ double endoftractsymbol = 0.0;
+ tractfile.write((char*)&endoftractsymbol, sizeof(endoftractsymbol));
+ tractfile.write((char*)&endoftractsymbol, sizeof(endoftractsymbol));
+ tractfile.write((char*)&endoftractsymbol, sizeof(endoftractsymbol));
+ }
+
+ tractfile.close();
+ return true;
+ }
+ else{
+ std::cerr<<"Problems opening file to write tracts\n";
+ return false;
+ }
+}
+template< class FAContainerType >
+bool WriteScalarContainerToFile( const char* fn, FAContainerType* facontainer ){
+ std::ofstream fafile( fn, std::ios::out );
+ std::locale C("C"); // define standard locale
+ fafile.imbue(C); // switch the stream to standard locale
+
+ if(fafile.is_open()){
+ for(int i=0; iSize(); i++){
+ fafile<GetElement(i)<
+class ZeroDWITest
+{
+public:
+ ZeroDWITest() {};
+ ~ZeroDWITest() {};
+ bool operator!=( const ZeroDWITest & ) const
+ {
+ return false;
+ }
+ bool operator==( const ZeroDWITest & other ) const
+ {
+ return !(*this != other);
+ }
+ inline TOutput operator()( const TInput & A )
+ {
+ /*for(int i=0;i
+class ScalarMultiply
+{
+public:
+ ScalarMultiply() {};
+ ~ScalarMultiply() {};
+ bool operator!=( const ScalarMultiply & ) const
+ {
+ return false;
+ }
+ bool operator==( const ScalarMultiply & other ) const
+ {
+ return !(*this != other);
+ }
+ inline TOutput operator()( const TInput & A )
+ {
+ /*for(int i=0;i DWIVectorImageType;
+ typedef itk::Image< float, 3 > WMPImageType;
+ typedef itk::Image< short int, 3 > ROIImageType;
+ typedef itk::Image< unsigned int, 3 > CImageType;
+
+ //define an iterator for the ROI image
+ typedef itk::ImageRegionConstIterator< ROIImageType > ROIImageIteratorType;
+
+ //define reader and writer
+ typedef itk::ImageFileReader< DWIVectorImageType > DWIVectorImageReaderType;
+ typedef itk::ImageFileReader< WMPImageType > WMPImageReaderType;
+ typedef itk::ImageFileReader< ROIImageType > ROIImageReaderType;
+ typedef itk::ImageFileWriter< CImageType > CImageWriterType;
+ typedef itk::ImageFileWriter< WMPImageType > WMPImageWriterType;
+
+ //define metadata dictionary types
+ typedef itk::MetaDataDictionary DictionaryType;
+ typedef DictionaryType::ConstIterator DictionaryIteratorType;
+
+ //define a probabilistic tractography filter type and associated bValue,
+ //gradient direction, and measurement frame types
+ typedef itk::StochasticTractographyFilter< DWIVectorImageType, WMPImageType,
+ CImageType >
+ PTFilterType;
+ typedef PTFilterType::bValueContainerType bValueContainerType;
+ typedef PTFilterType::GradientDirectionContainerType GDContainerType;
+ typedef PTFilterType::MeasurementFrameType MeasurementFrameType;
+
+ //define a filter to generate a mask image that excludes zero dwi values
+ typedef Functor::ZeroDWITest< DWIVectorImageType::PixelType, WMPImageType::PixelType >
+ ZeroDWITestType;
+ typedef itk::UnaryFunctorImageFilter< DWIVectorImageType, WMPImageType,
+ ZeroDWITestType > ExcludeZeroDWIFilterType;
+
+ //FA stuff
+ typedef itk::Image< double, 3 > FAImageType;
+ typedef itk::TensorFractionalAnisotropyImageFilter< PTFilterType::OutputTensorImageType,
+ FAImageType > FAFilterType;
+ typedef itk::ImageFileWriter< FAImageType > FAImageWriterType;
+
+ //define a filter to multiply a FA image by 1000
+ typedef Functor::ScalarMultiply< FAImageType::PixelType, FAImageType::PixelType >
+ ScalarMultiplyType;
+ typedef itk::UnaryFunctorImageFilter< FAImageType, FAImageType,
+ ScalarMultiplyType > MultiplyFAFilterType;
+
+ //define AddImageFilterType to accumulate the connectivity maps of the pixels in the ROI
+ typedef itk::AddImageFilter< CImageType, CImageType, CImageType> AddImageFilterType;
+
+ //parse command line arguments
+ //if(argc < 3){
+ // std::cerr << "Usage: " << argv[0];
+ // std::cerr<< " DWIFile(.nhdr) ROIFile(.nhdr) ConnectivityFile(.nhdr) ";
+ // std::cerr<< "LabelNumber NumberOfTracts MaxTractLength MaxLikelihoodCacheSize\n";
+ // return EXIT_FAILURE;
+ //}
+ /*
+ char* dwifilename = argv[1];
+ char* roifilename = argv[2];
+ char* cfilename = argv[3];
+ unsigned int labelnumber = atoi(argv[4]);
+ unsigned int totaltracts = atoi(argv[5]);
+ unsigned int maxtractlength = atoi(argv[6]);
+ unsigned int maxlikelihoodcachesize = atoi(argv[7]);
+ */
+ //setup output stat files
+ std::string fafilename = outputprefix + "_CONDFAValues.txt";
+ //sprintf( fafilename, "%s_CONDFAValues.txt", outputprefix.c_str() );
+ std::string lengthfilename = outputprefix + "_CONDLENGTHValues.txt";
+ //sprintf( lengthfilename, "%s_CONDLENGTHValues.txt", outputprefix.c_str() );
+
+ //open these files
+ std::ofstream fafile( fafilename.c_str() );
+ std::locale C("C"); // define standard locale
+ fafile.imbue(C); // switch the stream to standard locale
+
+ if(!fafile.is_open()){
+ std::cerr<<"Could not open FA file!\n";
+ return EXIT_FAILURE;
+ }
+
+ std::ofstream lengthfile( lengthfilename.c_str() );
+ lengthfile.imbue(C); // switch the stream to standard locale
+ //if(!lengthfile.is_open()){
+ // std::cerr<<"Could not open Length file!\n";
+ // return EXIT_FAILURE;
+ // }
+
+ //read in the DWI image
+ DWIVectorImageReaderType::Pointer dwireaderPtr = DWIVectorImageReaderType::New();
+ dwireaderPtr->SetFileName(dwifilename);
+ dwireaderPtr->Update();
+
+ //Obtain bValue, gradient directions and measurement frame from metadata dictionary
+ DictionaryType& dictionary = dwireaderPtr->GetMetaDataDictionary();
+ bValueContainerType::Pointer bValuesPtr = bValueContainerType::New();
+ MeasurementFrameType measurement_frame;
+ GDContainerType::Pointer gradientsPtr = GDContainerType::New();
+ bValueContainerType::Element scaling_bValue = 0;
+ GDContainerType::Element g_i;
+
+ //bad choice of variable names: dictit->first refers to the key in the Map
+ //dictit->second refers to the Value associated with that Key
+ for(DictionaryIteratorType dictit = dictionary.Begin();
+ dictit!=dictionary.End();
+ ++dictit){
+ if(dictit->first.find("DWMRI_gradient") != std::string::npos){
+ std::string metaDataValue;
+ itk::ExposeMetaData< std::string > (dictionary, dictit->first, metaDataValue);
+ sscanf(metaDataValue.c_str(), "%lf %lf %lf\n", &g_i[0], &g_i[1], &g_i[2]);
+ //normalize the gradient vector
+ gradientsPtr->InsertElement( gradientsPtr->Size(), g_i.normalize() );
+ }
+ else if(dictit->first.find("DWMRI_b-value") != std::string::npos){
+ std::string metaDataValue;
+ itk::ExposeMetaData< std::string >(dictionary, dictit->first, metaDataValue);
+ scaling_bValue = atof(metaDataValue.c_str());
+ }
+ else if(dictit->first.find("NRRD_measurement frame") != std::string::npos){
+ std::vector< std::vector < double > > metaDataValue;
+ itk::ExposeMetaData< std::vector< std::vector > >
+ (dictionary, dictit->first, metaDataValue);
+ for(int i=0;i<3;i++){
+ for(int j=0;j<3;j++)
+ measurement_frame(i,j) = metaDataValue[j][i];
+ }
+ }
+ else{
+ std::cout << dictit->first << std::endl;
+ }
+ }
+
+ //check to see if bValue, gradients, or measurement frame is missing
+ if(scaling_bValue == 0){
+ std::cerr << "scaling_bValue should never be 0, possibly not found in Nrrd header\n";
+ return EXIT_FAILURE;
+ }
+ else if(gradientsPtr->Size() == 0){
+ std::cerr <<"no gradients were found!";
+ return EXIT_FAILURE;
+ }
+ else if(measurement_frame.size() == 0){
+ std::cerr <<"no measurement frame was found!";
+ return EXIT_FAILURE;
+ }
+ //correct the measurement frame
+
+ std::cout << scaling_bValue << std::endl;
+ for(unsigned int i=0; iSize(); i++)
+ std::cout << gradientsPtr->GetElement(i) << std::endl;
+
+ //std::cout << measurement_frame <Size() ;i++){
+ if(gradientsPtr->GetElement(i).squared_magnitude() == 0){
+ bValuesPtr->InsertElement(i, 0);
+ }
+ else{
+ //this matters in the calculations for the constrained model but not the tensor model
+ //since a gradient direction of all zeros handles it
+ bValuesPtr->InsertElement(i, scaling_bValue);
+ }
+ }
+
+ //setup the ROI image reader
+ ROIImageReaderType::Pointer roireaderPtr = ROIImageReaderType::New();
+ roireaderPtr->SetFileName(roifilename);
+ roireaderPtr->Update();
+
+ //setup the white matter probability image reader
+ WMPImageReaderType::Pointer wmpreader = WMPImageReaderType::New();
+ wmpreader->SetFileName(wmpfilename);
+ wmpreader->Update();
+
+ //optionally set the origins of these images to be the same as the DWI
+ if(recenteroriginswitch==true){
+ roireaderPtr->GetOutput()->SetOrigin( dwireaderPtr->GetOutput()->GetOrigin() );
+ wmpreader->GetOutput()->SetOrigin( dwireaderPtr->GetOutput()->GetOrigin() );
+ }
+ /*
+ //set list of directions
+ typedef PTFilterType::TractOrientationContainerType TOCType;
+ TOCType::Pointer directionsPtr = TOCType::New();
+
+ if(SamplingDirections("SD.txt", directionsPtr));
+ else return EXIT_FAILURE;
+ */
+ /*
+ //write out the directions
+ std::ofstream outfile("crapola.txt");
+
+
+ for(int i=0; iSize(); i++){
+ TOCType::Element dir = directionsPtr->GetElement(i);
+ outfile<<"{"<SetInput( dwireaderPtr->GetOutput() );
+ //std::cout<<"Start mask image\n";
+ //write out the mask image
+ //MaskImageWriterType::Pointer maskwriterPtr = MaskImageWriterType::New();
+ //maskwriterPtr->SetInput( ezdwifilter->GetOutput() );
+ //maskwriterPtr->SetFileName( "maskimage.nhdr" );
+ //maskwriterPtr->Update();
+ //std::cout<<"Finish the mask image\n";
+
+ std::cout<<"Create PTFilter\n";
+ //Setup the PTFilter
+ PTFilterType::Pointer ptfilterPtr = PTFilterType::New();
+ ptfilterPtr->SetInput( dwireaderPtr->GetOutput() );
+ //ptfilterPtr->SetMaskImageInput( ezdwifilter->GetOutput() );
+ ptfilterPtr->SetWhiteMatterProbabilityImageInput( wmpreader->GetOutput() );
+ ptfilterPtr->SetbValues(bValuesPtr);
+ ptfilterPtr->SetGradients( gradientsPtr );
+ ptfilterPtr->SetMeasurementFrame( measurement_frame );
+ //ptfilterPtr->SetSampleDirections(directionsPtr);
+ ptfilterPtr->SetMaxTractLength( maxtractlength );
+ ptfilterPtr->SetTotalTracts( totaltracts );
+ ptfilterPtr->SetMaxLikelihoodCacheSize( maxlikelihoodcachesize );
+ if(totalthreads!=0) ptfilterPtr->SetNumberOfThreads( totalthreads );
+
+ //calculate the tensor image
+ ptfilterPtr->GenerateTensorImageOutput();
+
+ //Setup the FAImageFilter
+ FAFilterType::Pointer fafilter = FAFilterType::New();
+
+ fafilter->SetInput( ptfilterPtr->GetOutputTensorImage() );
+ fafilter->Update();
+
+ //Setup the FA container to hold FA values for tracts of interest
+ typedef itk::VectorContainer< unsigned int, double > FAContainerType;
+ //FAContainerType::Pointer facontainer = FAContainerType::New();
+
+ //Setup the length container to hold lengths for tracts of interest
+ typedef itk::VectorContainer< unsigned int, unsigned int > LengthContainerType;
+ //LengthContainerType::Pointer lengthcontainer = LengthContainerType::New();
+
+ //Setup the AddImageFilter
+ AddImageFilterType::Pointer addimagefilterPtr = AddImageFilterType::New();
+
+ //Create a zeroed Connectivity Image
+ CImageType::Pointer accumulatedcimagePtr = CImageType::New();
+ accumulatedcimagePtr->CopyInformation( dwireaderPtr->GetOutput() );
+ accumulatedcimagePtr->SetBufferedRegion( dwireaderPtr->GetOutput()->GetBufferedRegion() );
+ accumulatedcimagePtr->SetRequestedRegion( dwireaderPtr->GetOutput()->GetRequestedRegion() );
+ accumulatedcimagePtr->Allocate();
+ accumulatedcimagePtr->FillBuffer(0);
+
+ //Create another Connectivity Map for just the tracts
+ //which make it to the second ROI
+ CImageType::Pointer conditionedcimagePtr = CImageType::New();
+ conditionedcimagePtr->CopyInformation( dwireaderPtr->GetOutput() );
+ conditionedcimagePtr->SetBufferedRegion( dwireaderPtr->GetOutput()->GetBufferedRegion() );
+ conditionedcimagePtr->SetRequestedRegion( dwireaderPtr->GetOutput()->GetRequestedRegion() );
+ conditionedcimagePtr->Allocate();
+ conditionedcimagePtr->FillBuffer(0);
+
+ //graft this onto the output of the addimagefilter
+ addimagefilterPtr->GraftOutput(accumulatedcimagePtr);
+ addimagefilterPtr->SetInput1(ptfilterPtr->GetOutput());
+ addimagefilterPtr->SetInput2(addimagefilterPtr->GetOutput());
+
+ ROIImageIteratorType ROIImageIt( roireaderPtr->GetOutput(),
+ roireaderPtr->GetOutput()->GetRequestedRegion() );
+ for(ROIImageIt.GoToBegin(); !ROIImageIt.IsAtEnd(); ++ROIImageIt){
+ if(ROIImageIt.Get() == labelnumber){
+ std::cout << "PixelIndex: "<< ROIImageIt.GetIndex() << std::endl;
+ ptfilterPtr->SetSeedIndex( ROIImageIt.GetIndex() );
+ //ptfilterPtr->GenerateTractContainerOutput();
+ //write out the tract info
+
+ //WriteTractContainerToFile( filename, ptfilterPtr->GetOutputTractContainer() );
+ addimagefilterPtr->Update();
+
+ std::cout<<"Calculate Statistics\n";
+ //calculate the FA stats for tracts which pass through a second ROI
+ PTFilterType::TractContainerType::Pointer tractcontainer =
+ ptfilterPtr->GetOutputTractContainer();
+
+ typedef itk::PathIterator< ROIImageType, PTFilterType::TractType >
+ ROITractIteratorType;
+
+ for(int i=0; iSize(); i++ ){
+ PTFilterType::TractType::Pointer currtract = tractcontainer->GetElement(i);
+ ROITractIteratorType roitractIt( roireaderPtr->GetOutput(),
+ currtract );
+
+ for(roitractIt.GoToBegin(); !roitractIt.IsAtEnd(); ++roitractIt){
+ if(roitractIt.Get() == endlabelnumber){
+ double accumFA=0;
+ unsigned int stepcount=0;
+ //integrate fa along length of tract
+ for(double t=0; tEndOfInput(); t+=0.2){
+ stepcount++;
+ //std::cout<GetOutput()->GetPixel(roitractIt.GetIndex())<GetOutput()->GetPixel(currtract->EvaluateToIndex(t));
+ }
+ fafile<GetElement(i)->EndOfInput()<InsertElement( lengthcontainer->Size(),
+ //(unsigned int) tractcontainer->GetElement(i)->EndOfInput() );
+ //facontainer->InsertElement( facontainer->Size(), accumFA/((double)stepcount) );
+
+ //color in the tracts
+ for(roitractIt.GoToBegin(); !roitractIt.IsAtEnd(); ++roitractIt){
+ conditionedcimagePtr->GetPixel(roitractIt.GetIndex())++;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ std::cout<<"DWI image origin:"<< dwireaderPtr->GetOutput()->GetOrigin() <GetOutput()->GetOrigin() <GetOutput()->GetOrigin() <SetInput( accumulatedcimagePtr );
+ writerPtr->SetFileName( cfilename.c_str() );
+ writerPtr->Update();
+
+ //Write out TensorImage
+ std::string tensorimagefilename = outputprefix + "_TENSOR.nhdr";
+ //sprintf(tensorimagefilename, "%s_TENSOR.nhdr", outputprefix.c_str() );
+ typedef itk::ImageFileWriter< PTFilterType::OutputTensorImageType > TensorImageWriterType;
+ TensorImageWriterType::Pointer tensorwriter = TensorImageWriterType::New();
+ tensorwriter->SetInput( ptfilterPtr->GetOutputTensorImage() );
+ tensorwriter->SetFileName( tensorimagefilename.c_str() );
+ tensorwriter->Update();
+
+ //Create a default Mask Image which
+ //excludes DWI pixels which contain values that are zero
+ MultiplyFAFilterType::Pointer multFAfilter = MultiplyFAFilterType::New();
+ multFAfilter->SetInput( fafilter->GetOutput() );
+ //write out the FA image
+ std::string faimagefilename = outputprefix + "_FA.nhdr";
+ //sprintf(faimagefilename, "%s_FA.nhdr", outputprefix.c_str() );
+ FAImageWriterType::Pointer fawriter = FAImageWriterType::New();
+ fawriter->SetInput( multFAfilter->GetOutput() );
+ fawriter->SetFileName( faimagefilename.c_str() );
+ fawriter->Update();
+
+ //Write out the conditioned connectivity map
+ CImageWriterType::Pointer condcmapwriterPtr = CImageWriterType::New();
+ condcmapwriterPtr->SetInput( conditionedcimagePtr );
+ std::string condcmapfilename = outputprefix + "_COND.nhdr";
+ //sprintf(condcmapfilename, "%s_COND.nhdr", outputprefix.c_str());
+ condcmapwriterPtr->SetFileName( condcmapfilename );
+ condcmapwriterPtr->Update();
+ }
+ //close files
+ fafile.close();
+ lengthfile.close();
+ if(fafile.fail() || lengthfile.fail() ){
+ std::cerr<<"Error closing text files\n";
+ return EXIT_FAILURE;
+ }
+ //Write out FA container
+ //char fafilename[100];
+ //sprintf( fafilename, "%s_CONDFAValues.txt", outputprefix.c_str() );
+ //WriteScalarContainerToFile< FAContainerType >( fafilename, facontainer );
+
+ //Write out tract length container
+ //char lengthfilename[100];
+ //sprintf( lengthfilename, "%s_CONDLENGTHValues.txt", outputprefix.c_str() );
+ //WriteScalarContainerToFile< LengthContainerType >( lengthfilename, lengthcontainer );
+ return EXIT_SUCCESS;
+}
diff --git a/Modules/DiffusionImaging/Tractography/StochasticTracking/StochasticTractographyFilter.xml b/Modules/DiffusionImaging/Tractography/StochasticTracking/StochasticTractographyFilter.xml
new file mode 100644
index 0000000000..6b797da757
--- /dev/null
+++ b/Modules/DiffusionImaging/Tractography/StochasticTracking/StochasticTractographyFilter.xml
@@ -0,0 +1,160 @@
+
+
+ filtering
+ Stochastic Tractography Filter
+
+ Generates a map of connectivity probabilities from a DWI volume.
+
+ 1.0
+
+
+ Tri Ngo
+
+
+
+
+ Parameters for the Stochastic Tractography algorithm
+
+
+
+ labelnumber
+ l
+ labelnumber
+ Label Number to use as seed points
+
+ 0
+
+ 0
+ 1
+
+
+
+
+ endlabelnumber
+ e
+ endlabelnumber
+ Label Number to use as end region
+
+ 1
+
+ 0
+ 1
+
+
+
+
+ totaltracts
+ t
+ totaltracts
+ Number of Sample Tracts
+
+ 100
+
+ 0
+ 1
+
+
+
+
+ maxtractlength
+ m
+ maxtractlength
+ Maximum Length of Sample Tract
+
+ 100
+
+ 0
+ 1
+
+
+
+ stepsize
+ s
+ stepsize
+ The length of each segment of the tract in mm
+
+ 1
+
+ 0.1
+ 0.1
+
+
+
+ maxlikelihoodcachesize
+ c
+ maxlikelihoodcachesize
+ Maximum Size of Likelihood Cache
+
+ 100
+
+ 0
+ 1
+
+
+
+ outputprefix
+ o
+ outputprefix
+ Prefix for the output files
+
+ "Output"
+
+
+ outputimageswitch
+ i
+ false
+ outputimageswitch
+
+ Output Tensor, FA maps and Connectivity Maps
+
+
+ recenteroriginswitch
+ r
+ false
+ recenteroriginswitch
+
+ Ignore the origins of the ROI and WM mask and set it to be the same as the DWI image origin
+
+
+ totalthreads
+ j
+ totalthreads
+ Total number of threads to use. Default value of zero sets number of threads to number of CPUs
+
+ 0
+
+ 0
+ 1
+
+
+
+
+
+
+ Input/output parameters
+
+ dwifilename
+
+ input
+ 0
+ Input DWI volume to be filtered
+
+
+ wmpfilename
+
+ input
+ 1
+ Input Mask volume that provides the probability that the voxel is white matter
+
+
+ roifilename
+
+ input
+ 2
+ Input ROI volume used to seed algorithm
+
+
+
+
diff --git a/Modules/DiffusionImaging/Tractography/StochasticTracking/itkSlowPolyLineParametricPath.h b/Modules/DiffusionImaging/Tractography/StochasticTracking/itkSlowPolyLineParametricPath.h
new file mode 100644
index 0000000000..e4b0f53d37
--- /dev/null
+++ b/Modules/DiffusionImaging/Tractography/StochasticTracking/itkSlowPolyLineParametricPath.h
@@ -0,0 +1,112 @@
+#ifndef _itkSlowPolyLineParametricPathPath_h
+#define _itkSlowPolyLineParametricPathPath_h
+
+#include "itkPolyLineParametricPath.h"
+#include "itkVectorContainer.h"
+#include "itkContinuousIndex.h"
+#include "itkIndex.h"
+#include "itkOffset.h"
+#include "itkVector.h"
+
+namespace itk
+{
+
+
+/** \class SlowPolyLineParametricPath
+ * \brief Represent a path of line segments through ND Space
+ *
+ * This class is intended to represent parametric paths through an image, where
+ * the paths are composed of line segments. Each line segment traverses one
+ * unit of input. A classic application of this class is the representation of
+ * contours in 2D images, especially when the contours only need to be
+ * approximately correct. Another use of a path is to guide the movement of an
+ * iterator through an image.
+ *
+ * \sa EllipseParametricPath
+ * \sa FourierSeriesPath
+ * \sa OrthogonallyCorrectedParametricPath
+ * \sa ParametricPath
+ * \sa ChainCodePath
+ * \sa Path
+ * \sa ContinuousIndex
+ * \sa Index
+ * \sa Offset
+ * \sa Vector
+ *
+ * \ingroup PathObjects
+ */
+template
+class ITK_EXPORT SlowPolyLineParametricPath : public
+PolyLineParametricPath< VDimension >
+{
+public:
+ /** Standard class typedefs. */
+ typedef SlowPolyLineParametricPath Self;
+ typedef PolyLineParametricPath Superclass;
+ typedef SmartPointer Pointer;
+ typedef SmartPointer ConstPointer;
+
+ /** Run-time type information (and related methods). */
+ itkTypeMacro(SlowPolyLineParametricPath, PolyLineParametricPath);
+
+ /** Input type */
+ typedef typename Superclass::InputType InputType;
+
+ /** Output type */
+ typedef typename Superclass::OutputType OutputType;
+
+
+ /** Basic data-structure types used */
+ typedef typename Superclass::ContinuousIndexType ContinuousIndexType;
+ typedef typename Superclass::IndexType IndexType;
+ typedef typename Superclass::OffsetType OffsetType;
+ typedef typename Superclass::PointType PointType;
+ typedef typename Superclass::VectorType VectorType;
+ typedef typename Superclass::VertexType VertexType;
+ typedef typename Superclass::VertexListType VertexListType;
+ typedef typename Superclass::VertexListPointer VertexListPointer;
+
+ /** Increment the input variable passed by reference such that the ND index of
+ * the path moves to its next vertex-connected (8-connected in 2D) neighbor.
+ * Return the Index-space offset of the path from its prior input to its new
+ * input. If the path is unable to increment, input is not changed and an
+ * offset of Zero is returned. Children are not required to implement bounds
+ * checking.
+ *
+ * This is a fairly slow, iterative algorithm that numerically converges to
+ * the next index along the path, in a vertex-connected (8-connected in 2D)
+ * fashion. When possible, children of this class should overload this
+ * function with something more efficient.
+ *
+ * WARNING: This default implementation REQUIRES that the ND endpoint of
+ * the path be either unique or coincident only with the startpoint, since it
+ * uses the endpoint as a stopping condition. */
+ virtual OffsetType IncrementInput(InputType & input) const;
+
+
+ ///** Evaluate the first derivative of the ND output with respect to the 1D
+ // * input. This is an exact, algebraic function. */
+ //virtual VectorType EvaluateDerivative(const InputType & input) const;
+
+
+ /** New() method for dynamic construction */
+ itkNewMacro( Self );
+
+
+protected:
+ SlowPolyLineParametricPath();
+ ~SlowPolyLineParametricPath(){}
+ void PrintSelf(std::ostream& os, Indent indent) const;
+
+private:
+ SlowPolyLineParametricPath(const Self&); //purposely not implemented
+ void operator=(const Self&); //purposely not implemented
+};
+
+} // namespace itk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "itkSlowPolyLineParametricPath.txx"
+#endif
+
+#endif
diff --git a/Modules/DiffusionImaging/Tractography/StochasticTracking/itkSlowPolyLineParametricPath.txx b/Modules/DiffusionImaging/Tractography/StochasticTracking/itkSlowPolyLineParametricPath.txx
new file mode 100644
index 0000000000..e0852d1614
--- /dev/null
+++ b/Modules/DiffusionImaging/Tractography/StochasticTracking/itkSlowPolyLineParametricPath.txx
@@ -0,0 +1,115 @@
+#ifndef _itkSlowPolyLineParametricPath_txx
+#define _itkSlowPolyLineParametricPath_txx
+
+#include "itkSlowPolyLineParametricPath.h"
+#include
+
+
+
+namespace itk
+{
+
+//template
+//typename SlowPolyLineParametricPath::VectorType
+//SlowPolyLineParametricPath
+//::EvaluateDerivative(const InputType & input) const
+//{
+//}
+
+
+
+/**
+ * Constructor
+ */
+template
+SlowPolyLineParametricPath
+::SlowPolyLineParametricPath()
+{
+ this->SetDefaultInputStepSize( 0.3 );
+}
+
+
+template
+typename SlowPolyLineParametricPath::OffsetType
+SlowPolyLineParametricPath
+::IncrementInput(InputType & input) const
+{
+ int iterationCount;
+ bool tooSmall;
+ bool tooBig;
+ InputType inputStepSize;
+ InputType finalInputValue;
+ OffsetType offset;
+ IndexType currentImageIndex;
+ IndexType nextImageIndex;
+ IndexType finalImageIndex;
+
+ iterationCount = 0;
+ inputStepSize = this->GetDefaultInputStepSize();
+
+ // Are we already at (or past) the end of the input?
+ finalInputValue = this->EndOfInput();
+ currentImageIndex = this->EvaluateToIndex( input );
+ finalImageIndex = this->EvaluateToIndex( finalInputValue );
+ offset = finalImageIndex - currentImageIndex;
+ if( ( offset == this->GetZeroOffset() && input != this->StartOfInput() ) ||
+ ( input >=finalInputValue ) )
+ {
+ return this->GetZeroOffset();
+ }
+
+ do
+ {
+ if( iterationCount++ > 10000 ) {itkExceptionMacro(<<"Too many iterations");}
+
+ nextImageIndex = this->EvaluateToIndex( input + inputStepSize );
+ offset = nextImageIndex - currentImageIndex;
+
+ tooBig = false;
+ tooSmall = ( offset == this->GetZeroOffset() );
+ if( tooSmall )
+ {
+ // increase the input step size, but don't go past the end of the input
+ inputStepSize *= 2;
+ if( (input + inputStepSize) >= finalInputValue ){
+ //inputStepSize = finalInputValue - input;
+ inputStepSize += this->GetDefaultInputStepSize();
+ }
+ }
+ else
+ {
+ // Search for an offset dimension that is too big
+ for( unsigned int i=0; i= 2 || offset[i] <= -2 );
+ }
+
+ if( tooBig ){
+ //inputStepSize /= 1.5;
+ inputStepSize -= (this->GetDefaultInputStepSize()/0.5);
+ }
+ }
+ }
+ while( tooSmall || tooBig );
+
+ input += inputStepSize;
+ return offset;
+}
+
+
+/**
+ * Standard "PrintSelf" method
+ */
+template
+void
+SlowPolyLineParametricPath
+::PrintSelf( std::ostream& os, Indent indent) const
+{
+ Superclass::PrintSelf( os, indent );
+}
+
+
+
+} // end namespaceitk
+
+#endif
diff --git a/Modules/DiffusionImaging/Tractography/StochasticTracking/itkStochasticTractographyFilter_SD.txx b/Modules/DiffusionImaging/Tractography/StochasticTracking/itkStochasticTractographyFilter_SD.txx
new file mode 100644
index 0000000000..a849e86119
--- /dev/null
+++ b/Modules/DiffusionImaging/Tractography/StochasticTracking/itkStochasticTractographyFilter_SD.txx
@@ -0,0 +1,2586 @@
+#include "itkStochasticTractographyFilter.h"
+
+namespace itk{
+
+template< class TInputDWIImage, class TInputMaskImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputMaskImage, TOutputConnectivityImage >
+::LoadDefaultSampleDirections( void ){
+ const unsigned int totalsd = 2562;
+ double sdarray[totalsd][3] = {
+ {0.850651, 0.525731, 6.12323e-17},
+ {-0.850651, 0.525731, 6.12323e-17},
+ {-0.850651 , -0.525731, 6.12323e-17},
+ {0.850651, -0.525731, 6.12323e-17},
+ {0.525731, 0, 0.850651},
+ {0.525731, 0, -0.850651},
+ {-0.525731, 6.43835e-17, -0.850651},
+ {-0.525731, 6.43835e-17, 0.850651},
+ {5.20873e-17, 0.850651, 0.525731},
+ {5.20873e-17, -0.850651, 0.525731},
+ {5.20873e-17, -0.850651, -0.525731},
+ {5.20873e-17, 0.850651, -0.525731},
+ {0, 0, 1},
+ {-0.309017, 0.5, 0.809017 },
+ {0.309017, 0.5, 0.809017},
+ {0.309017, -0.5, 0.809017},
+ {-0.309017, -0.5, 0.809017},
+ {0.309017, 0.5, -0.809017},
+ {-0.309017, 0.5, -0.809017},
+ {1.22465e-16, 0, -1},
+ {-0.309017 , -0.5, -0.809017},
+ {0.309017, -0.5, -0.809017},
+ {1, 0, 6.12323e-17},
+ {0.809017, -0.309017, 0.5},
+ {0.809017, 0.309017, 0.5},
+ {0.809017, 0.309017, -0.5},
+ {0.809017, -0.309017, -0.5 },
+ {-1, 1.22465e-16, 6.12323e-17},
+ {-0.809017, 0.309017, 0.5},
+ {-0.809017, -0.309017, 0.5},
+ {-0.809017, -0.309017, -0.5},
+ {-0.809017, 0.309017, -0.5},
+ {6.12323e-17, 1, 6.12323e-17 },
+ {0.5, 0.809017, -0.309017},
+ {0.5, 0.809017, 0.309017},
+ {-0.5, 0.809017, 0.309017},
+ {-0.5, 0.809017, -0.309017},
+ {0.5, -0.809017, 0.309017},
+ {0.5, -0.809017, -0.309017},
+ { 6.12323e-17, -1, 6.12323e-17},
+ {-0.5, -0.809017, -0.309017},
+ {-0.5, -0.809017, 0.309017},
+ {0.273267, 0, 0.961938},
+ {0.16246, 0.262866, 0.951057},
+ {0.433889, 0.259892, 0.862668},
+ {- 0.273267, 3.34655e-17, 0.961938},
+ {-0.433889, 0.259892, 0.862668},
+ {-0.16246, 0.262866, 0.951057},
+ {-8.4544e-17, 0.525731, 0.850651},
+ {-0.160622, 0.702046, 0.69378},
+ {0.160622, 0.702046, 0.69378},
+ {0.433889, -0.259892, 0.862668},
+ {0.16246, -0.262866, 0.951057},
+ {0.160622, -0.702046, 0.69378},
+ {-0.160622, -0.702046, 0.69378},
+ {-8.4544e-17, -0.525731, 0.850651},
+ {-0.16246 , -0.262866, 0.951057},
+ {-0.433889, -0.259892, 0.862668},
+ {0.433889, 0.259892, -0.862668},
+ {0.16246, 0.262866, -0.951057},
+ {0.273267, 0, -0.961938},
+ {0.160622, 0.702046, -0.69378},
+ {- 0.160622, 0.702046, -0.69378},
+ {-8.4544e-17, 0.525731, -0.850651},
+ {-0.16246, 0.262866, -0.951057},
+ {-0.433889, 0.259892, -0.862668},
+ {-0.273267, 3.34655e-17, -0.961938},
+ {0.16246, -0.262866 , -0.951057},
+ {0.433889, -0.259892, -0.862668},
+ {-0.433889, -0.259892, -0.862668},
+ {-0.16246, -0.262866, -0.951057},
+ {-8.4544e-17, -0.525731, -0.850651},
+ {-0.160622, -0.702046, -0.69378},
+ {0.160622, -0.702046, -0.69378},
+ {0.961938, 0.273267, 6.12323e-17},
+ {0.951057, 0.16246, 0.262866},
+ {0.862668, 0.433889, 0.259892},
+ {0.961938, -0.273267, 6.12323e-17},
+ {0.862668, - 0.433889, 0.259892},
+ {0.951057, -0.16246, 0.262866},
+ {0.850651, 0, 0.525731},
+ {0.69378, -0.160622, 0.702046},
+ {0.69378, 0.160622, 0.702046},
+ {0.862668, 0.433889, -0.259892},
+ {0.951057 , 0.16246, -0.262866},
+ {0.69378, 0.160622, -0.702046},
+ {0.69378, -0.160622, -0.702046},
+ {0.850651, 0, -0.525731},
+ {0.951057, -0.16246, -0.262866},
+ {0.862668, -0.433889, -0.259892},
+ {- 0.961938, -0.273267, 6.12323e-17},
+ {-0.951057, -0.16246, 0.262866},
+ {-0.862668, -0.433889, 0.259892},
+ {-0.961938, 0.273267, 6.12323e-17},
+ {-0.862668, 0.433889, 0.259892},
+ {-0.951057, 0.16246 , 0.262866},
+ {-0.850651, 1.04175e-16, 0.525731},
+ {-0.69378, 0.160622, 0.702046},
+ {-0.69378, -0.160622, 0.702046},
+ {-0.862668, -0.433889, -0.259892},
+ {-0.951057, -0.16246, -0.262866},
+ {-0.69378, -0.160622, -0.702046},
+ {-0.69378, 0.160622, -0.702046},
+ {-0.850651, 1.04175e-16, -0.525731},
+ {-0.951057, 0.16246, -0.262866},
+ {-0.862668, 0.433889, -0.259892},
+ {5.89017e-17 , 0.961938, 0.273267},
+ {0.262866, 0.951057, 0.16246},
+ {0.259892, 0.862668, 0.433889},
+ {5.89017e-17, 0.961938, -0.273267},
+ {0.259892, 0.862668, -0.433889},
+ {0.262866, 0.951057, -0.16246},
+ {0.525731, 0.850651, -1.60812e-16},
+ {0.702046, 0.69378, -0.160622},
+ {0.702046, 0.69378, 0.160622},
+ {-0.259892, 0.862668, 0.433889},
+ {-0.262866, 0.951057, 0.16246},
+ {-0.702046, 0.69378 , 0.160622},
+ {-0.702046, 0.69378, -0.160622},
+ {-0.525731, 0.850651, -1.60812e-16},
+ {-0.262866, 0.951057, -0.16246},
+ {-0.259892, 0.862668, -0.433889},
+ {0.259892, -0.862668, 0.433889},
+ {0.262866, -0.951057, 0.16246},
+ {5.89017e-17, -0.961938, 0.273267},
+ {0.702046, -0.69378, 0.160622},
+ {0.702046, -0.69378, -0.160622},
+ {0.525731, -0.850651, -1.60812e-16},
+ {0.262866, - 0.951057, -0.16246},
+ {0.259892, -0.862668, -0.433889},
+ {5.89017e-17, -0.961938, -0.273267},
+ {-0.262866, -0.951057, 0.16246},
+ {-0.259892, -0.862668, 0.433889},
+ {-0.259892, -0.862668, -0.433889 },
+ {-0.262866, -0.951057, -0.16246},
+ {-0.525731, -0.850651, -1.60812e-16},
+ {-0.702046, -0.69378, -0.160622},
+ {-0.702046, -0.69378, 0.160622},
+ {0.425325, 0.688191, 0.587785},
+ {0.688191 , 0.587785, 0.425325},
+ {0.587785, 0.425325, 0.688191},
+ {0.425325, 0.688191, -0.587785},
+ {0.587785, 0.425325, -0.688191},
+ {0.688191, 0.587785, -0.425325},
+ {0.587785, -0.425325, 0.688191},
+ {0.688191, -0.587785, 0.425325},
+ {0.425325, -0.688191, 0.587785},
+ {0.587785, -0.425325, -0.688191},
+ {0.425325, -0.688191, -0.587785},
+ {0.688191, -0.587785, -0.425325},
+ {-0.587785 , 0.425325, 0.688191},
+ {-0.688191, 0.587785, 0.425325},
+ {-0.425325, 0.688191, 0.587785},
+ {-0.587785, 0.425325, -0.688191},
+ {-0.425325, 0.688191, -0.587785},
+ {-0.688191, 0.587785, -0.425325 },
+ {-0.587785, -0.425325, 0.688191},
+ {-0.425325, -0.688191, 0.587785},
+ {-0.688191, -0.587785, 0.425325},
+ {-0.587785, -0.425325, -0.688191},
+ {-0.688191, -0.587785, -0.425325},
+ {-0.425325 , -0.688191, -0.587785},
+ {0.403355, 0, 0.915043},
+ {0.358229, 0.131655, 0.924305},
+ {0.484442, 0.1312, 0.864929},
+ {0.137952, 0, 0.990439},
+ {0.0822425, 0.133071, 0.987688},
+ {0.220117 , 0.132792, 0.966393},
+ {0.301259, 0.264083, 0.916244},
+ {0.238677, 0.386187, 0.891007},
+ {0.375039, 0.383614, 0.843911},
+ {-0.137952, 1.68943e-17, 0.990439},
+ {-0.220117, 0.132792, 0.966393},
+ {-0.0822425, 0.133071, 0.987688},
+ {-0.403355, 4.93968e-17, 0.915043},
+ {-0.484442, 0.1312, 0.864929},
+ {-0.358229, 0.131655, 0.924305},
+ {-0.301259, 0.264083, 0.916244},
+ {-0.375039, 0.383614, 0.843911},
+ {-0.238677, 0.386187, 0.891007},
+ {0.156434, 0.519258, 0.840178},
+ {0.0811419, 0.62024, 0.780204},
+ {0.237086, 0.606825, 0.758652},
+ {-0.156434, 0.519258, 0.840178},
+ {-0.237086, 0.606825, 0.758652},
+ {-0.0811419, 0.62024, 0.780204},
+ {-1.14383e-16, 0.711282, 0.702907},
+ {-0.0810863, 0.783843, 0.615642},
+ {0.0810863, 0.783843, 0.615642},
+ {-4.28411e-17 , 0.266405, 0.963861},
+ {-0.0823236, 0.399607, 0.912982},
+ {0.0823236, 0.399607, 0.912982},
+ {0.484442, -0.1312, 0.864929},
+ {0.358229, -0.131655, 0.924305},
+ {0.375039, -0.383614, 0.843911},
+ {0.238677, -0.386187, 0.891007},
+ {0.301259, -0.264083, 0.916244},
+ {0.220117, -0.132792, 0.966393},
+ {0.0822425, -0.133071, 0.987688},
+ {0.237086, -0.606825, 0.758652},
+ {0.0811419, - 0.62024, 0.780204},
+ {0.156434, -0.519258, 0.840178},
+ {0.0810863, -0.783843, 0.615642},
+ {-0.0810863, -0.783843, 0.615642},
+ {-1.14383e-16, -0.711282, 0.702907},
+ {-0.0811419, -0.62024, 0.780204 },
+ {-0.237086, -0.606825, 0.758652},
+ {-0.156434, -0.519258, 0.840178},
+ {-0.0822425, -0.133071, 0.987688},
+ {-0.220117, -0.132792, 0.966393},
+ {-0.238677, -0.386187, 0.891007},
+ {-0.375039 , -0.383614, 0.843911},
+ {-0.301259, -0.264083, 0.916244},
+ {-0.358229, -0.131655, 0.924305},
+ {-0.484442, -0.1312, 0.864929},
+ {0.0823236, -0.399607, 0.912982},
+ {-0.0823236, -0.399607, 0.912982 },
+ {-4.28411e-17, -0.266405, 0.963861},
+ {0.484442, 0.1312, -0.864929},
+ {0.358229, 0.131655, -0.924305},
+ {0.403355, 0, -0.915043},
+ {0.375039, 0.383614, -0.843911},
+ {0.238677, 0.386187 , -0.891007},
+ {0.301259, 0.264083, -0.916244},
+ {0.220117, 0.132792, -0.966393},
+ {0.0822425, 0.133071, -0.987688},
+ {0.137952, 0, -0.990439},
+ {0.237086, 0.606825, -0.758652},
+ {0.0811419 , 0.62024, -0.780204},
+ {0.156434, 0.519258, -0.840178},
+ {0.0810863, 0.783843, -0.615642},
+ {-0.0810863, 0.783843, -0.615642},
+ {4.35534e-17, 0.711282, -0.702907},
+ {-0.0811419, 0.62024, -0.780204 },
+ {-0.237086, 0.606825, -0.758652},
+ {-0.156434, 0.519258, -0.840178},
+ {-0.0822425, 0.133071, -0.987688},
+ {-0.220117, 0.132792, -0.966393},
+ {-0.137952, 1.68943e-17, -0.990439},
+ {- 0.238677, 0.386187, -0.891007},
+ {-0.375039, 0.383614, -0.843911},
+ {-0.301259, 0.264083, -0.916244},
+ {-0.358229, 0.131655, -0.924305},
+ {-0.484442, 0.1312, -0.864929},
+ {-0.403355, 4.93968e-17 , -0.915043},
+ {0.0823236, 0.399607, -0.912982},
+ {-0.0823236, 0.399607, -0.912982},
+ {1.63126e-17, 0.266405, -0.963861},
+ {0.358229, -0.131655, -0.924305},
+ {0.484442, -0.1312, -0.864929},
+ {0.0822425, -0.133071, -0.987688},
+ {0.220117, -0.132792, -0.966393},
+ {0.301259, -0.264083, -0.916244},
+ {0.238677, -0.386187, -0.891007},
+ {0.375039, -0.383614, -0.843911},
+ {-0.220117, - 0.132792, -0.966393},
+ {-0.0822425, -0.133071, -0.987688},
+ {-0.484442, -0.1312, -0.864929},
+ {-0.358229, -0.131655, -0.924305},
+ {-0.301259, -0.264083, -0.916244},
+ {-0.375039, -0.383614, -0.843911 },
+ {-0.238677, -0.386187, -0.891007},
+ {0.156434, -0.519258, -0.840178},
+ {0.0811419, -0.62024, -0.780204},
+ {0.237086, -0.606825, -0.758652},
+ {-0.156434, -0.519258, -0.840178},
+ {-0.237086 , -0.606825, -0.758652},
+ {-0.0811419, -0.62024, -0.780204},
+ {4.35534e-17, -0.711282, -0.702907},
+ {-0.0810863, -0.783843, -0.615642},
+ {0.0810863, -0.783843, -0.615642},
+ {1.63126e-17, -0.266405 , -0.963861},
+ {-0.0823236, -0.399607, -0.912982},
+ {0.0823236, -0.399607, -0.912982},
+ {0.915043, 0.403355, 6.12323e-17},
+ {0.924305, 0.358229, 0.131655},
+ {0.864929, 0.484442, 0.1312},
+ { 0.990439, 0.137952, 6.12323e-17},
+ {0.987688, 0.0822425, 0.133071},
+ {0.966393, 0.220117, 0.132792},
+ {0.916244, 0.301259, 0.264083},
+ {0.891007, 0.238677, 0.386187},
+ {0.843911, 0.375039, 0.383614 },
+ {0.990439, -0.137952, 6.12323e-17},
+ {0.966393, -0.220117, 0.132792},
+ {0.987688, -0.0822425, 0.133071},
+ {0.915043, -0.403355, 6.12323e-17},
+ {0.864929, -0.484442, 0.1312},
+ {0.924305 , -0.358229, 0.131655},
+ {0.916244, -0.301259, 0.264083},
+ {0.843911, -0.375039, 0.383614},
+ {0.891007, -0.238677, 0.386187},
+ {0.840178, 0.156434, 0.519258},
+ {0.780204, 0.0811419, 0.62024},
+ {0.758652, 0.237086, 0.606825},
+ {0.840178, -0.156434, 0.519258},
+ {0.758652, -0.237086, 0.606825},
+ {0.780204, -0.0811419, 0.62024},
+ {0.702907, 0, 0.711282},
+ {0.615642, -0.0810863, 0.783843},
+ {0.615642, 0.0810863, 0.783843},
+ {0.963861, 0, 0.266405},
+ {0.912982, -0.0823236, 0.399607},
+ {0.912982, 0.0823236, 0.399607},
+ {0.864929, 0.484442, -0.1312},
+ {0.924305, 0.358229 , -0.131655},
+ {0.843911, 0.375039, -0.383614},
+ {0.891007, 0.238677, -0.386187},
+ {0.916244, 0.301259, -0.264083},
+ {0.966393, 0.220117, -0.132792},
+ {0.987688, 0.0822425, -0.133071},
+ { 0.758652, 0.237086, -0.606825},
+ {0.780204, 0.0811419, -0.62024},
+ {0.840178, 0.156434, -0.519258},
+ {0.615642, 0.0810863, -0.783843},
+ {0.615642, -0.0810863, -0.783843},
+ {0.702907, 0, -0.711282 },
+ {0.780204, -0.0811419, -0.62024},
+ {0.758652, -0.237086, -0.606825},
+ {0.840178, -0.156434, -0.519258},
+ {0.987688, -0.0822425, -0.133071},
+ {0.966393, -0.220117, -0.132792},
+ {0.891007 , -0.238677, -0.386187},
+ {0.843911, -0.375039, -0.383614},
+ {0.916244, -0.301259, -0.264083},
+ {0.924305, -0.358229, -0.131655},
+ {0.864929, -0.484442, -0.1312},
+ {0.912982, 0.0823236, -0.399607 },
+ {0.912982, -0.0823236, -0.399607},
+ {0.963861, 0, -0.266405},
+ {-0.915043, -0.403355, 6.12323e-17},
+ {-0.924305, -0.358229, 0.131655},
+ {-0.864929, -0.484442, 0.1312},
+ {-0.990439, - 0.137952, 6.12323e-17},
+ {-0.987688, -0.0822425, 0.133071},
+ {-0.966393, -0.220117, 0.132792},
+ {-0.916244, -0.301259, 0.264083},
+ {-0.891007, -0.238677, 0.386187},
+ {-0.843911, -0.375039, 0.383614 },
+ {-0.990439, 0.137952, 6.12323e-17},
+ {-0.966393, 0.220117, 0.132792},
+ {-0.987688, 0.0822425, 0.133071},
+ {-0.915043, 0.403355, 6.12323e-17},
+ {-0.864929, 0.484442, 0.1312},
+ {-0.924305 , 0.358229, 0.131655},
+ {-0.916244, 0.301259, 0.264083},
+ {-0.843911, 0.375039, 0.383614},
+ {-0.891007, 0.238677, 0.386187},
+ {-0.840178, -0.156434, 0.519258},
+ {-0.780204, -0.0811419, 0.62024 },
+ {-0.758652, -0.237086, 0.606825},
+ {-0.840178, 0.156434, 0.519258},
+ {-0.758652, 0.237086, 0.606825},
+ {-0.780204, 0.0811419, 0.62024},
+ {-0.702907, 8.60813e-17, 0.711282},
+ {-0.615642 , 0.0810863, 0.783843},
+ {-0.615642, -0.0810863, 0.783843},
+ {-0.963861, 1.18039e-16, 0.266405},
+ {-0.912982, 0.0823236, 0.399607},
+ {-0.912982, -0.0823236, 0.399607},
+ {-0.864929, -0.484442, - 0.1312},
+ {-0.924305, -0.358229, -0.131655},
+ {-0.843911, -0.375039, -0.383614},
+ {-0.891007, -0.238677, -0.386187},
+ {-0.916244, -0.301259, -0.264083},
+ {-0.966393, -0.220117, -0.132792},
+ {-0.987688, -0.0822425, -0.133071},
+ {-0.758652, -0.237086, -0.606825},
+ {-0.780204, -0.0811419, -0.62024},
+ {-0.840178, -0.156434, -0.519258},
+ {-0.615642, -0.0810863, -0.783843},
+ {-0.615642 , 0.0810863, -0.783843},
+ {-0.702907, 8.60813e-17, -0.711282},
+ {-0.780204, 0.0811419, -0.62024},
+ {-0.758652, 0.237086, -0.606825},
+ {-0.840178, 0.156434, -0.519258},
+ {-0.987688, 0.0822425, - 0.133071},
+ {-0.966393, 0.220117, -0.132792},
+ {-0.891007, 0.238677, -0.386187},
+ {-0.843911, 0.375039, -0.383614},
+ {-0.916244, 0.301259, -0.264083},
+ {-0.924305, 0.358229, -0.131655},
+ {- 0.864929, 0.484442, -0.1312},
+ {-0.912982, -0.0823236, -0.399607},
+ {-0.912982, 0.0823236, -0.399607},
+ {-0.963861, 1.18039e-16, -0.266405},
+ {5.60302e-17, 0.915043, 0.403355},
+ {0.131655, 0.924305 , 0.358229},
+ {0.1312, 0.864929, 0.484442},
+ {6.06469e-17, 0.990439, 0.137952},
+ {0.133071, 0.987688, 0.0822425},
+ {0.132792, 0.966393, 0.220117},
+ {0.264083, 0.916244, 0.301259},
+ {0.386187 , 0.891007, 0.238677},
+ {0.383614, 0.843911, 0.375039},
+ {6.06469e-17, 0.990439, -0.137952},
+ {0.132792, 0.966393, -0.220117},
+ {0.133071, 0.987688, -0.0822425},
+ {5.60302e-17, 0.915043, -0.403355 },
+ {0.1312, 0.864929, -0.484442},
+ {0.131655, 0.924305, -0.358229},
+ {0.264083, 0.916244, -0.301259},
+ {0.383614, 0.843911, -0.375039},
+ {0.386187, 0.891007, -0.238677},
+ {0.519258, 0.840178 , 0.156434},
+ {0.62024, 0.780204, 0.0811419},
+ {0.606825, 0.758652, 0.237086},
+ {0.519258, 0.840178, -0.156434},
+ {0.606825, 0.758652, -0.237086},
+ {0.62024, 0.780204, -0.0811419},
+ {0.711282 , 0.702907, -1.60812e-16},
+ {0.783843, 0.615642, -0.0810863},
+ {0.783843, 0.615642, 0.0810863},
+ {0.266405, 0.963861, -1.60812e-16},
+ {0.399607, 0.912982, -0.0823236},
+ {0.399607, 0.912982, 0.0823236 },
+ {-0.1312, 0.864929, 0.484442},
+ {-0.131655, 0.924305, 0.358229},
+ {-0.383614, 0.843911, 0.375039},
+ {-0.386187, 0.891007, 0.238677},
+ {-0.264083, 0.916244, 0.301259},
+ {-0.132792, 0.966393 , 0.220117},
+ {-0.133071, 0.987688, 0.0822425},
+ {-0.606825, 0.758652, 0.237086},
+ {-0.62024, 0.780204, 0.0811419},
+ {-0.519258, 0.840178, 0.156434},
+ {-0.783843, 0.615642, 0.0810863},
+ {- 0.783843, 0.615642, -0.0810863},
+ {-0.711282, 0.702907, -1.60812e-16},
+ {-0.62024, 0.780204, -0.0811419},
+ {-0.606825, 0.758652, -0.237086},
+ {-0.519258, 0.840178, -0.156434},
+ {-0.133071, 0.987688 , -0.0822425},
+ {-0.132792, 0.966393, -0.220117},
+ {-0.386187, 0.891007, -0.238677},
+ {-0.383614, 0.843911, -0.375039},
+ {-0.264083, 0.916244, -0.301259},
+ {-0.131655, 0.924305, -0.358229},
+ {-0.1312, 0.864929, -0.484442},
+ {-0.399607, 0.912982, 0.0823236},
+ {-0.399607, 0.912982, -0.0823236},
+ {-0.266405, 0.963861, -1.60812e-16},
+ {0.1312, -0.864929, 0.484442},
+ {0.131655, -0.924305 , 0.358229},
+ {5.60302e-17, -0.915043, 0.403355},
+ {0.383614, -0.843911, 0.375039},
+ {0.386187, -0.891007, 0.238677},
+ {0.264083, -0.916244, 0.301259},
+ {0.132792, -0.966393, 0.220117},
+ { 0.133071, -0.987688, 0.0822425},
+ {6.06469e-17, -0.990439, 0.137952},
+ {0.606825, -0.758652, 0.237086},
+ {0.62024, -0.780204, 0.0811419},
+ {0.519258, -0.840178, 0.156434},
+ {0.783843, -0.615642 , 0.0810863},
+ {0.783843, -0.615642, -0.0810863},
+ {0.711282, -0.702907, -1.60812e-16},
+ {0.62024, -0.780204, -0.0811419},
+ {0.606825, -0.758652, -0.237086},
+ {0.519258, -0.840178, -0.156434},
+ {0.133071, -0.987688, -0.0822425},
+ {0.132792, -0.966393, -0.220117},
+ {6.06469e-17, -0.990439, -0.137952},
+ {0.386187, -0.891007, -0.238677},
+ {0.383614, -0.843911, -0.375039},
+ {0.264083 , -0.916244, -0.301259},
+ {0.131655, -0.924305, -0.358229},
+ {0.1312, -0.864929, -0.484442},
+ {5.60302e-17, -0.915043, -0.403355},
+ {0.399607, -0.912982, 0.0823236},
+ {0.399607, -0.912982, -0.0823236 },
+ {0.266405, -0.963861, -1.60812e-16},
+ {-0.131655, -0.924305, 0.358229},
+ {-0.1312, -0.864929, 0.484442},
+ {-0.133071, -0.987688, 0.0822425},
+ {-0.132792, -0.966393, 0.220117},
+ {-0.264083 , -0.916244, 0.301259},
+ {-0.386187, -0.891007, 0.238677},
+ {-0.383614, -0.843911, 0.375039},
+ {-0.132792, -0.966393, -0.220117},
+ {-0.133071, -0.987688, -0.0822425},
+ {-0.1312, -0.864929, -0.484442 },
+ {-0.131655, -0.924305, -0.358229},
+ {-0.264083, -0.916244, -0.301259},
+ {-0.383614, -0.843911, -0.375039},
+ {-0.386187, -0.891007, -0.238677},
+ {-0.519258, -0.840178, 0.156434},
+ {- 0.62024, -0.780204, 0.0811419},
+ {-0.606825, -0.758652, 0.237086},
+ {-0.519258, -0.840178, -0.156434},
+ {-0.606825, -0.758652, -0.237086},
+ {-0.62024, -0.780204, -0.0811419},
+ {-0.711282, -0.702907 , -1.60812e-16},
+ {-0.783843, -0.615642, -0.0810863},
+ {-0.783843, -0.615642, 0.0810863},
+ {-0.266405, -0.963861, -1.60812e-16},
+ {-0.399607, -0.912982, -0.0823236},
+ {-0.399607, -0.912982, 0.0823236 },
+ {0.213023, 0.792649, 0.571252},
+ {0.46843, 0.757935, 0.453991},
+ {0.346153, 0.783452, 0.516122},
+ {0.296005, 0.70231, 0.647412},
+ {0.371748, 0.601501, 0.707107},
+ {0.70231, 0.647412 , 0.296005},
+ {0.601501, 0.707107, 0.371748},
+ {0.792649, 0.571252, 0.213023},
+ {0.783452, 0.516122, 0.346153},
+ {0.757935, 0.453991, 0.46843},
+ {0.453991, 0.46843, 0.757935},
+ {0.516122 , 0.346153, 0.783452},
+ {0.707107, 0.371748, 0.601501},
+ {0.647412, 0.296005, 0.70231},
+ {0.571252, 0.213023, 0.792649},
+ {0.564254, 0.646578, 0.513375},
+ {0.646578, 0.513375, 0.564254},
+ { 0.513375, 0.564254, 0.646578},
+ {0.213023, 0.792649, -0.571252},
+ {0.371748, 0.601501, -0.707107},
+ {0.296005, 0.70231, -0.647412},
+ {0.346153, 0.783452, -0.516122},
+ {0.46843, 0.757935, -0.453991 },
+ {0.516122, 0.346153, -0.783452},
+ {0.453991, 0.46843, -0.757935},
+ {0.571252, 0.213023, -0.792649},
+ {0.647412, 0.296005, -0.70231},
+ {0.707107, 0.371748, -0.601501},
+ {0.601501, 0.707107 , -0.371748},
+ {0.70231, 0.647412, -0.296005},
+ {0.757935, 0.453991, -0.46843},
+ {0.783452, 0.516122, -0.346153},
+ {0.792649, 0.571252, -0.213023},
+ {0.513375, 0.564254, -0.646578},
+ {0.646578 , 0.513375, -0.564254},
+ {0.564254, 0.646578, -0.513375},
+ {0.571252, -0.213023, 0.792649},
+ {0.707107, -0.371748, 0.601501},
+ {0.647412, -0.296005, 0.70231},
+ {0.516122, -0.346153, 0.783452},
+ {0.453991, -0.46843, 0.757935},
+ {0.783452, -0.516122, 0.346153},
+ {0.757935, -0.453991, 0.46843},
+ {0.792649, -0.571252, 0.213023},
+ {0.70231, -0.647412, 0.296005},
+ {0.601501, -0.707107 , 0.371748},
+ {0.371748, -0.601501, 0.707107},
+ {0.296005, -0.70231, 0.647412},
+ {0.46843, -0.757935, 0.453991},
+ {0.346153, -0.783452, 0.516122},
+ {0.213023, -0.792649, 0.571252},
+ {0.646578 , -0.513375, 0.564254},
+ {0.564254, -0.646578, 0.513375},
+ {0.513375, -0.564254, 0.646578},
+ {0.571252, -0.213023, -0.792649},
+ {0.453991, -0.46843, -0.757935},
+ {0.516122, -0.346153, -0.783452 },
+ {0.647412, -0.296005, -0.70231},
+ {0.707107, -0.371748, -0.601501},
+ {0.296005, -0.70231, -0.647412},
+ {0.371748, -0.601501, -0.707107},
+ {0.213023, -0.792649, -0.571252},
+ {0.346153 , -0.783452, -0.516122},
+ {0.46843, -0.757935, -0.453991},
+ {0.757935, -0.453991, -0.46843},
+ {0.783452, -0.516122, -0.346153},
+ {0.601501, -0.707107, -0.371748},
+ {0.70231, -0.647412, -0.296005 },
+ {0.792649, -0.571252, -0.213023},
+ {0.513375, -0.564254, -0.646578},
+ {0.564254, -0.646578, -0.513375},
+ {0.646578, -0.513375, -0.564254},
+ {-0.571252, 0.213023, 0.792649},
+ {-0.707107 , 0.371748, 0.601501},
+ {-0.647412, 0.296005, 0.70231},
+ {-0.516122, 0.346153, 0.783452},
+ {-0.453991, 0.46843, 0.757935},
+ {-0.783452, 0.516122, 0.346153},
+ {-0.757935, 0.453991, 0.46843},
+ {-0.792649, 0.571252, 0.213023},
+ {-0.70231, 0.647412, 0.296005},
+ {-0.601501, 0.707107, 0.371748},
+ {-0.371748, 0.601501, 0.707107},
+ {-0.296005, 0.70231, 0.647412},
+ {-0.46843, 0.757935 , 0.453991},
+ {-0.346153, 0.783452, 0.516122},
+ {-0.213023, 0.792649, 0.571252},
+ {-0.646578, 0.513375, 0.564254},
+ {-0.564254, 0.646578, 0.513375},
+ {-0.513375, 0.564254, 0.646578},
+ {- 0.571252, 0.213023, -0.792649},
+ {-0.453991, 0.46843, -0.757935},
+ {-0.516122, 0.346153, -0.783452},
+ {-0.647412, 0.296005, -0.70231},
+ {-0.707107, 0.371748, -0.601501},
+ {-0.296005, 0.70231, - 0.647412},
+ {-0.371748, 0.601501, -0.707107},
+ {-0.213023, 0.792649, -0.571252},
+ {-0.346153, 0.783452, -0.516122},
+ {-0.46843, 0.757935, -0.453991},
+ {-0.757935, 0.453991, -0.46843},
+ {- 0.783452, 0.516122, -0.346153},
+ {-0.601501, 0.707107, -0.371748},
+ {-0.70231, 0.647412, -0.296005},
+ {-0.792649, 0.571252, -0.213023},
+ {-0.513375, 0.564254, -0.646578},
+ {-0.564254, 0.646578 , -0.513375},
+ {-0.646578, 0.513375, -0.564254},
+ {-0.571252, -0.213023, 0.792649},
+ {-0.453991, -0.46843, 0.757935},
+ {-0.516122, -0.346153, 0.783452},
+ {-0.647412, -0.296005, 0.70231},
+ {- 0.707107, -0.371748, 0.601501},
+ {-0.296005, -0.70231, 0.647412},
+ {-0.371748, -0.601501, 0.707107},
+ {-0.213023, -0.792649, 0.571252},
+ {-0.346153, -0.783452, 0.516122},
+ {-0.46843, -0.757935 , 0.453991},
+ {-0.757935, -0.453991, 0.46843},
+ {-0.783452, -0.516122, 0.346153},
+ {-0.601501, -0.707107, 0.371748},
+ {-0.70231, -0.647412, 0.296005},
+ {-0.792649, -0.571252, 0.213023},
+ {- 0.513375, -0.564254, 0.646578},
+ {-0.564254, -0.646578, 0.513375},
+ {-0.646578, -0.513375, 0.564254},
+ {-0.571252, -0.213023, -0.792649},
+ {-0.707107, -0.371748, -0.601501},
+ {-0.647412, -0.296005 , -0.70231},
+ {-0.516122, -0.346153, -0.783452},
+ {-0.453991, -0.46843, -0.757935},
+ {-0.783452, -0.516122, -0.346153},
+ {-0.757935, -0.453991, -0.46843},
+ {-0.792649, -0.571252, -0.213023},
+ {-0.70231, -0.647412, -0.296005},
+ {-0.601501, -0.707107, -0.371748},
+ {-0.371748, -0.601501, -0.707107},
+ {-0.296005, -0.70231, -0.647412},
+ {-0.46843, -0.757935, -0.453991},
+ {-0.346153 , -0.783452, -0.516122},
+ {-0.213023, -0.792649, -0.571252},
+ {-0.646578, -0.513375, -0.564254},
+ {-0.564254, -0.646578, -0.513375},
+ {-0.513375, -0.564254, -0.646578},
+ {0.465658, 0, 0.884965 },
+ {0.445365, 0.0658169, 0.892927},
+ {0.506298, 0.0657576, 0.859848},
+ {0.339123, 0, 0.940742},
+ {0.316778, 0.0660424, 0.946198},
+ {0.381722, 0.0659884, 0.921919},
+ {0.422364, 0.131749 , 0.896801},
+ {0.397351, 0.196412, 0.896401},
+ {0.460267, 0.196015, 0.865871},
+ {0.206103, 0, 0.97853},
+ {0.179596, 0.0666044, 0.981483},
+ {0.247326, 0.0665669, 0.966643},
+ {0.0691416, 0, 0.997607},
+ {0.0412484, 0.0667413, 0.996917},
+ {0.110385, 0.0667094, 0.991648},
+ {0.151549, 0.133256, 0.979426},
+ {0.122729, 0.19858, 0.97237},
+ {0.19178, 0.198337, 0.961188},
+ {0.368518 , 0.262661, 0.891742},
+ {0.339209, 0.324864, 0.882837},
+ {0.405434, 0.322525, 0.855337},
+ {0.232455, 0.264151, 0.93605},
+ {0.201189, 0.32553, 0.92388},
+ {0.270627, 0.325929, 0.905832},
+ { 0.307659, 0.385906, 0.869725},
+ {0.274694, 0.444464, 0.85264},
+ {0.342848, 0.442867, 0.828447},
+ {0.289929, 0.13257, 0.947822},
+ {0.26155, 0.199094, 0.944433},
+ {0.330607, 0.198387, 0.922682},
+ {-0.0691416, 8.4674e-18, 0.997607},
+ {-0.110385, 0.0667094, 0.991648},
+ {-0.0412484, 0.0667413, 0.996917},
+ {-0.206103, 2.52403e-17, 0.97853},
+ {-0.247326, 0.0665669, 0.966643},
+ {-0.179596 , 0.0666044, 0.981483},
+ {-0.151549, 0.133256, 0.979426},
+ {-0.19178, 0.198337, 0.961188},
+ {-0.122729, 0.19858, 0.97237},
+ {-0.339123, 4.15305e-17, 0.940742},
+ {-0.381722, 0.0659884, 0.921919 },
+ {-0.316778, 0.0660424, 0.946198},
+ {-0.465658, 5.70266e-17, 0.884965},
+ {-0.506298, 0.0657576, 0.859848},
+ {-0.445365, 0.0658169, 0.892927},
+ {-0.422364, 0.131749, 0.896801},
+ {-0.460267 , 0.196015, 0.865871},
+ {-0.397351, 0.196412, 0.896401},
+ {-0.232455, 0.264151, 0.93605},
+ {-0.270627, 0.325929, 0.905832},
+ {-0.201189, 0.32553, 0.92388},
+ {-0.368518, 0.262661, 0.891742},
+ {-0.405434, 0.322525, 0.855337},
+ {-0.339209, 0.324864, 0.882837},
+ {-0.307659, 0.385906, 0.869725},
+ {-0.342848, 0.442867, 0.828447},
+ {-0.274694, 0.444464, 0.85264},
+ {-0.289929, 0.13257 , 0.947822},
+ {-0.330607, 0.198387, 0.922682},
+ {-0.26155, 0.199094, 0.944433},
+ {0.233445, 0.511205, 0.827147},
+ {0.197274, 0.564513, 0.801504},
+ {0.273707, 0.55474, 0.785715},
+ {0.0784591 , 0.52411, 0.848029},
+ {0.0406752, 0.574458, 0.817523},
+ {0.119078, 0.57114, 0.812169},
+ {0.159613, 0.615456, 0.771841},
+ {0.121193, 0.662842, 0.738886},
+ {0.199331, 0.656006, 0.727958},
+ {- 0.0784591, 0.52411, 0.848029},
+ {-0.119078, 0.57114, 0.812169},
+ {-0.0406752, 0.574458, 0.817523},
+ {-0.233445, 0.511205, 0.827147},
+ {-0.273707, 0.55474, 0.785715},
+ {-0.197274, 0.564513, 0.801504 },
+ {-0.159613, 0.615456, 0.771841},
+ {-0.199331, 0.656006, 0.727958},
+ {-0.121193, 0.662842, 0.738886},
+ {0.080573, 0.708969, 0.700622},
+ {0.0406421, 0.749387, 0.660884},
+ {0.121144, 0.744727 , 0.656282},
+ {-0.080573, 0.708969, 0.700622},
+ {-0.121144, 0.744727, 0.656282},
+ {-0.0406421, 0.749387, 0.660884},
+ {-1.26468e-16, 0.786433, 0.617676},
+ {-0.0406404, 0.819207, 0.572056},
+ {0.0406404, 0.819207, 0.572056},
+ {-1.00072e-16, 0.622292, 0.782786},
+ {-0.0406771, 0.667502, 0.743496},
+ {0.0406771, 0.667502, 0.743496},
+ {-2.14722e-17, 0.133523, 0.991046},
+ {-0.0815011 , 0.265518, 0.960655},
+ {-0.0412509, 0.200368, 0.978852},
+ {0.0412509, 0.200368, 0.978852},
+ {0.0815011, 0.265518, 0.960655},
+ {-0.161006, 0.394136, 0.904839},
+ {-0.1228, 0.332342, 0.93513},
+ {-0.198227, 0.454262, 0.868534},
+ {-0.119755, 0.460882, 0.879345},
+ {-0.0412992, 0.464213, 0.88476},
+ {0.1228, 0.332342, 0.93513},
+ {0.161006, 0.394136, 0.904839},
+ {0.0412992, 0.464213, 0.88476},
+ {0.119755, 0.460882, 0.879345},
+ {0.198227, 0.454262, 0.868534},
+ {-0.041302, 0.33414, 0.941618},
+ {-6.44806e-17, 0.400968, 0.916092},
+ {0.041302, 0.33414, 0.941618},
+ {0.506298 , -0.0657576, 0.859848},
+ {0.445365, -0.0658169, 0.892927},
+ {0.460267, -0.196015, 0.865871},
+ {0.397351, -0.196412, 0.896401},
+ {0.422364, -0.131749, 0.896801},
+ {0.381722, -0.0659884, 0.921919 },
+ {0.316778, -0.0660424, 0.946198},
+ {0.405434, -0.322525, 0.855337},
+ {0.339209, -0.324864, 0.882837},
+ {0.368518, -0.262661, 0.891742},
+ {0.342848, -0.442867, 0.828447},
+ {0.274694, - 0.444464, 0.85264},
+ {0.307659, -0.385906, 0.869725},
+ {0.270627, -0.325929, 0.905832},
+ {0.201189, -0.32553, 0.92388},
+ {0.232455, -0.264151, 0.93605},
+ {0.247326, -0.0665669, 0.966643},
+ {0.179596, -0.0666044, 0.981483},
+ {0.19178, -0.198337, 0.961188},
+ {0.122729, -0.19858, 0.97237},
+ {0.151549, -0.133256, 0.979426},
+ {0.110385, -0.0667094, 0.991648},
+ {0.0412484, -0.0667413 , 0.996917},
+ {0.330607, -0.198387, 0.922682},
+ {0.26155, -0.199094, 0.944433},
+ {0.289929, -0.13257, 0.947822},
+ {0.273707, -0.55474, 0.785715},
+ {0.197274, -0.564513, 0.801504},
+ {0.233445 , -0.511205, 0.827147},
+ {0.199331, -0.656006, 0.727958},
+ {0.121193, -0.662842, 0.738886},
+ {0.159613, -0.615456, 0.771841},
+ {0.119078, -0.57114, 0.812169},
+ {0.0406752, -0.574458, 0.817523 },
+ {0.0784591, -0.52411, 0.848029},
+ {0.121144, -0.744727, 0.656282},
+ {0.0406421, -0.749387, 0.660884},
+ {0.080573, -0.708969, 0.700622},
+ {0.0406404, -0.819207, 0.572056},
+ {-0.0406404 , -0.819207, 0.572056},
+ {-1.26468e-16, -0.786433, 0.617676},
+ {-0.0406421, -0.749387, 0.660884},
+ {-0.121144, -0.744727, 0.656282},
+ {-0.080573, -0.708969, 0.700622},
+ {-0.0406752, -0.574458 , 0.817523},
+ {-0.119078, -0.57114, 0.812169},
+ {-0.0784591, -0.52411, 0.848029},
+ {-0.121193, -0.662842, 0.738886},
+ {-0.199331, -0.656006, 0.727958},
+ {-0.159613, -0.615456, 0.771841},
+ {- 0.197274, -0.564513, 0.801504},
+ {-0.273707, -0.55474, 0.785715},
+ {-0.233445, -0.511205, 0.827147},
+ {0.0406771, -0.667502, 0.743496},
+ {-0.0406771, -0.667502, 0.743496},
+ {-1.00072e-16, -0.622292 , 0.782786},
+ {-0.0412484, -0.0667413, 0.996917},
+ {-0.110385, -0.0667094, 0.991648},
+ {-0.122729, -0.19858, 0.97237},
+ {-0.19178, -0.198337, 0.961188},
+ {-0.151549, -0.133256, 0.979426},
+ {-0.179596, -0.0666044, 0.981483},
+ {-0.247326, -0.0665669, 0.966643},
+ {-0.201189, -0.32553, 0.92388},
+ {-0.270627, -0.325929, 0.905832},
+ {-0.232455, -0.264151, 0.93605},
+ {-0.274694, - 0.444464, 0.85264},
+ {-0.342848, -0.442867, 0.828447},
+ {-0.307659, -0.385906, 0.869725},
+ {-0.339209, -0.324864, 0.882837},
+ {-0.405434, -0.322525, 0.855337},
+ {-0.368518, -0.262661, 0.891742 },
+ {-0.316778, -0.0660424, 0.946198},
+ {-0.381722, -0.0659884, 0.921919},
+ {-0.397351, -0.196412, 0.896401},
+ {-0.460267, -0.196015, 0.865871},
+ {-0.422364, -0.131749, 0.896801},
+ {-0.445365 , -0.0658169, 0.892927},
+ {-0.506298, -0.0657576, 0.859848},
+ {-0.26155, -0.199094, 0.944433},
+ {-0.330607, -0.198387, 0.922682},
+ {-0.289929, -0.13257, 0.947822},
+ {0.198227, -0.454262, 0.868534 },
+ {0.0412992, -0.464213, 0.88476},
+ {0.119755, -0.460882, 0.879345},
+ {0.161006, -0.394136, 0.904839},
+ {0.1228, -0.332342, 0.93513},
+ {-0.119755, -0.460882, 0.879345},
+ {-0.0412992, - 0.464213, 0.88476},
+ {-0.198227, -0.454262, 0.868534},
+ {-0.161006, -0.394136, 0.904839},
+ {-0.1228, -0.332342, 0.93513},
+ {0.0815011, -0.265518, 0.960655},
+ {0.0412509, -0.200368, 0.978852},
+ {-0.0815011, -0.265518, 0.960655},
+ {-0.0412509, -0.200368, 0.978852},
+ {-2.14722e-17, -0.133523, 0.991046},
+ {-6.44806e-17, -0.400968, 0.916092},
+ {-0.041302, -0.33414, 0.941618},
+ { 0.041302, -0.33414, 0.941618},
+ {0.506298, 0.0657576, -0.859848},
+ {0.445365, 0.0658169, -0.892927},
+ {0.465658, 0, -0.884965},
+ {0.460267, 0.196015, -0.865871},
+ {0.397351, 0.196412, -0.896401 },
+ {0.422364, 0.131749, -0.896801},
+ {0.381722, 0.0659884, -0.921919},
+ {0.316778, 0.0660424, -0.946198},
+ {0.339123, 0, -0.940742},
+ {0.405434, 0.322525, -0.855337},
+ {0.339209, 0.324864 , -0.882837},
+ {0.368518, 0.262661, -0.891742},
+ {0.342848, 0.442867, -0.828447},
+ {0.274694, 0.444464, -0.85264},
+ {0.307659, 0.385906, -0.869725},
+ {0.270627, 0.325929, -0.905832},
+ { 0.201189, 0.32553, -0.92388},
+ {0.232455, 0.264151, -0.93605},
+ {0.247326, 0.0665669, -0.966643},
+ {0.179596, 0.0666044, -0.981483},
+ {0.206103, 0, -0.97853},
+ {0.19178, 0.198337, -0.961188},
+ {0.122729, 0.19858, -0.97237},
+ {0.151549, 0.133256, -0.979426},
+ {0.110385, 0.0667094, -0.991648},
+ {0.0412484, 0.0667413, -0.996917},
+ {0.0691416, 0, -0.997607},
+ {0.330607, 0.198387 , -0.922682},
+ {0.26155, 0.199094, -0.944433},
+ {0.289929, 0.13257, -0.947822},
+ {0.273707, 0.55474, -0.785715},
+ {0.197274, 0.564513, -0.801504},
+ {0.233445, 0.511205, -0.827147},
+ {0.199331 , 0.656006, -0.727958},
+ {0.121193, 0.662842, -0.738886},
+ {0.159613, 0.615456, -0.771841},
+ {0.119078, 0.57114, -0.812169},
+ {0.0406752, 0.574458, -0.817523},
+ {0.0784591, 0.52411, -0.848029 },
+ {0.121144, 0.744727, -0.656282},
+ {0.0406421, 0.749387, -0.660884},
+ {0.080573, 0.708969, -0.700622},
+ {0.0406404, 0.819207, -0.572056},
+ {-0.0406404, 0.819207, -0.572056},
+ {-1.26468e-16 , 0.786433, -0.617676},
+ {-0.0406421, 0.749387, -0.660884},
+ {-0.121144, 0.744727, -0.656282},
+ {-0.080573, 0.708969, -0.700622},
+ {-0.0406752, 0.574458, -0.817523},
+ {-0.119078, 0.57114, -0.812169 },
+ {-0.0784591, 0.52411, -0.848029},
+ {-0.121193, 0.662842, -0.738886},
+ {-0.199331, 0.656006, -0.727958},
+ {-0.159613, 0.615456, -0.771841},
+ {-0.197274, 0.564513, -0.801504},
+ {-0.273707 , 0.55474, -0.785715},
+ {-0.233445, 0.511205, -0.827147},
+ {0.0406771, 0.667502, -0.743496},
+ {-0.0406771, 0.667502, -0.743496},
+ {-1.00072e-16, 0.622292, -0.782786},
+ {-0.0412484, 0.0667413, - 0.996917},
+ {-0.110385, 0.0667094, -0.991648},
+ {-0.0691416, 8.4674e-18, -0.997607},
+ {-0.122729, 0.19858, -0.97237},
+ {-0.19178, 0.198337, -0.961188},
+ {-0.151549, 0.133256, -0.979426},
+ {- 0.179596, 0.0666044, -0.981483},
+ {-0.247326, 0.0665669, -0.966643},
+ {-0.206103, 2.52403e-17, -0.97853},
+ {-0.201189, 0.32553, -0.92388},
+ {-0.270627, 0.325929, -0.905832},
+ {-0.232455, 0.264151 , -0.93605},
+ {-0.274694, 0.444464, -0.85264},
+ {-0.342848, 0.442867, -0.828447},
+ {-0.307659, 0.385906, -0.869725},
+ {-0.339209, 0.324864, -0.882837},
+ {-0.405434, 0.322525, -0.855337},
+ {- 0.368518, 0.262661, -0.891742},
+ {-0.316778, 0.0660424, -0.946198},
+ {-0.381722, 0.0659884, -0.921919},
+ {-0.339123, 4.15305e-17, -0.940742},
+ {-0.397351, 0.196412, -0.896401},
+ {-0.460267, 0.196015 , -0.865871},
+ {-0.422364, 0.131749, -0.896801},
+ {-0.445365, 0.0658169, -0.892927},
+ {-0.506298, 0.0657576, -0.859848},
+ {-0.465658, 5.70266e-17, -0.884965},
+ {-0.26155, 0.199094, -0.944433},
+ {-0.330607, 0.198387, -0.922682},
+ {-0.289929, 0.13257, -0.947822},
+ {0.198227, 0.454262, -0.868534},
+ {0.0412992, 0.464213, -0.88476},
+ {0.119755, 0.460882, -0.879345},
+ {0.161006, 0.394136 , -0.904839},
+ {0.1228, 0.332342, -0.93513},
+ {-0.119755, 0.460882, -0.879345},
+ {-0.0412992, 0.464213, -0.88476},
+ {-0.198227, 0.454262, -0.868534},
+ {-0.161006, 0.394136, -0.904839},
+ {- 0.1228, 0.332342, -0.93513},
+ {0.0815011, 0.265518, -0.960655},
+ {0.0412509, 0.200368, -0.978852},
+ {-0.0815011, 0.265518, -0.960655},
+ {-0.0412509, 0.200368, -0.978852},
+ {3.78241e-17, 0.133523 , -0.991046},
+ {-6.44806e-17, 0.400968, -0.916092},
+ {-0.041302, 0.33414, -0.941618},
+ {0.041302, 0.33414, -0.941618},
+ {0.445365, -0.0658169, -0.892927},
+ {0.506298, -0.0657576, -0.859848},
+ {0.316778, -0.0660424, -0.946198},
+ {0.381722, -0.0659884, -0.921919},
+ {0.422364, -0.131749, -0.896801},
+ {0.397351, -0.196412, -0.896401},
+ {0.460267, -0.196015, -0.865871},
+ {0.179596, - 0.0666044, -0.981483},
+ {0.247326, -0.0665669, -0.966643},
+ {0.0412484, -0.0667413, -0.996917},
+ {0.110385, -0.0667094, -0.991648},
+ {0.151549, -0.133256, -0.979426},
+ {0.122729, -0.19858, -0.97237 },
+ {0.19178, -0.198337, -0.961188},
+ {0.368518, -0.262661, -0.891742},
+ {0.339209, -0.324864, -0.882837},
+ {0.405434, -0.322525, -0.855337},
+ {0.232455, -0.264151, -0.93605},
+ {0.201189 , -0.32553, -0.92388},
+ {0.270627, -0.325929, -0.905832},
+ {0.307659, -0.385906, -0.869725},
+ {0.274694, -0.444464, -0.85264},
+ {0.342848, -0.442867, -0.828447},
+ {0.289929, -0.13257, -0.947822 },
+ {0.26155, -0.199094, -0.944433},
+ {0.330607, -0.198387, -0.922682},
+ {-0.110385, -0.0667094, -0.991648},
+ {-0.0412484, -0.0667413, -0.996917},
+ {-0.247326, -0.0665669, -0.966643},
+ {- 0.179596, -0.0666044, -0.981483},
+ {-0.151549, -0.133256, -0.979426},
+ {-0.19178, -0.198337, -0.961188},
+ {-0.122729, -0.19858, -0.97237},
+ {-0.381722, -0.0659884, -0.921919},
+ {-0.316778, -0.0660424 , -0.946198},
+ {-0.506298, -0.0657576, -0.859848},
+ {-0.445365, -0.0658169, -0.892927},
+ {-0.422364, -0.131749, -0.896801},
+ {-0.460267, -0.196015, -0.865871},
+ {-0.397351, -0.196412, -0.896401 },
+ {-0.232455, -0.264151, -0.93605},
+ {-0.270627, -0.325929, -0.905832},
+ {-0.201189, -0.32553, -0.92388},
+ {-0.368518, -0.262661, -0.891742},
+ {-0.405434, -0.322525, -0.855337},
+ {-0.339209 , -0.324864, -0.882837},
+ {-0.307659, -0.385906, -0.869725},
+ {-0.342848, -0.442867, -0.828447},
+ {-0.274694, -0.444464, -0.85264},
+ {-0.289929, -0.13257, -0.947822},
+ {-0.330607, -0.198387, - 0.922682},
+ {-0.26155, -0.199094, -0.944433},
+ {0.233445, -0.511205, -0.827147},
+ {0.197274, -0.564513, -0.801504},
+ {0.273707, -0.55474, -0.785715},
+ {0.0784591, -0.52411, -0.848029},
+ { 0.0406752, -0.574458, -0.817523},
+ {0.119078, -0.57114, -0.812169},
+ {0.159613, -0.615456, -0.771841},
+ {0.121193, -0.662842, -0.738886},
+ {0.199331, -0.656006, -0.727958},
+ {-0.0784591, -0.52411 , -0.848029},
+ {-0.119078, -0.57114, -0.812169},
+ {-0.0406752, -0.574458, -0.817523},
+ {-0.233445, -0.511205, -0.827147},
+ {-0.273707, -0.55474, -0.785715},
+ {-0.197274, -0.564513, -0.801504},
+ {-0.159613, -0.615456, -0.771841},
+ {-0.199331, -0.656006, -0.727958},
+ {-0.121193, -0.662842, -0.738886},
+ {0.080573, -0.708969, -0.700622},
+ {0.0406421, -0.749387, -0.660884},
+ {0.121144 , -0.744727, -0.656282},
+ {-0.080573, -0.708969, -0.700622},
+ {-0.121144, -0.744727, -0.656282},
+ {-0.0406421, -0.749387, -0.660884},
+ {-1.26468e-16, -0.786433, -0.617676},
+ {-0.0406404, -0.819207 , -0.572056},
+ {0.0406404, -0.819207, -0.572056},
+ {-1.00072e-16, -0.622292, -0.782786},
+ {-0.0406771, -0.667502, -0.743496},
+ {0.0406771, -0.667502, -0.743496},
+ {3.78241e-17, -0.133523, -0.991046 },
+ {-0.0815011, -0.265518, -0.960655},
+ {-0.0412509, -0.200368, -0.978852},
+ {0.0412509, -0.200368, -0.978852},
+ {0.0815011, -0.265518, -0.960655},
+ {-0.161006, -0.394136, -0.904839},
+ {- 0.1228, -0.332342, -0.93513},
+ {-0.198227, -0.454262, -0.868534},
+ {-0.119755, -0.460882, -0.879345},
+ {-0.0412992, -0.464213, -0.88476},
+ {0.1228, -0.332342, -0.93513},
+ {0.161006, -0.394136 , -0.904839},
+ {0.0412992, -0.464213, -0.88476},
+ {0.119755, -0.460882, -0.879345},
+ {0.198227, -0.454262, -0.868534},
+ {-0.041302, -0.33414, -0.941618},
+ {-6.44806e-17, -0.400968, -0.916092},
+ {0.041302, -0.33414, -0.941618},
+ {0.884965, 0.465658, 6.12323e-17},
+ {0.892927, 0.445365, 0.0658169},
+ {0.859848, 0.506298, 0.0657576},
+ {0.940742, 0.339123, 6.12323e-17},
+ {0.946198 , 0.316778, 0.0660424},
+ {0.921919, 0.381722, 0.0659884},
+ {0.896801, 0.422364, 0.131749},
+ {0.896401, 0.397351, 0.196412},
+ {0.865871, 0.460267, 0.196015},
+ {0.97853, 0.206103, 6.12323e-17},
+ {0.981483, 0.179596, 0.0666044},
+ {0.966643, 0.247326, 0.0665669},
+ {0.997607, 0.0691416, 6.12323e-17},
+ {0.996917, 0.0412484, 0.0667413},
+ {0.991648, 0.110385, 0.0667094},
+ {0.979426 , 0.151549, 0.133256},
+ {0.97237, 0.122729, 0.19858},
+ {0.961188, 0.19178, 0.198337},
+ {0.891742, 0.368518, 0.262661},
+ {0.882837, 0.339209, 0.324864},
+ {0.855337, 0.405434, 0.322525},
+ { 0.93605, 0.232455, 0.264151},
+ {0.92388, 0.201189, 0.32553},
+ {0.905832, 0.270627, 0.325929},
+ {0.869725, 0.307659, 0.385906},
+ {0.85264, 0.274694, 0.444464},
+ {0.828447, 0.342848, 0.442867},
+ {0.947822, 0.289929, 0.13257},
+ {0.944433, 0.26155, 0.199094},
+ {0.922682, 0.330607, 0.198387},
+ {0.997607, -0.0691416, 6.12323e-17},
+ {0.991648, -0.110385, 0.0667094},
+ {0.996917, -0.0412484 , 0.0667413},
+ {0.97853, -0.206103, 6.12323e-17},
+ {0.966643, -0.247326, 0.0665669},
+ {0.981483, -0.179596, 0.0666044},
+ {0.979426, -0.151549, 0.133256},
+ {0.961188, -0.19178, 0.198337},
+ { 0.97237, -0.122729, 0.19858},
+ {0.940742, -0.339123, 6.12323e-17},
+ {0.921919, -0.381722, 0.0659884},
+ {0.946198, -0.316778, 0.0660424},
+ {0.884965, -0.465658, 6.12323e-17},
+ {0.859848, -0.506298 , 0.0657576},
+ {0.892927, -0.445365, 0.0658169},
+ {0.896801, -0.422364, 0.131749},
+ {0.865871, -0.460267, 0.196015},
+ {0.896401, -0.397351, 0.196412},
+ {0.93605, -0.232455, 0.264151},
+ { 0.905832, -0.270627, 0.325929},
+ {0.92388, -0.201189, 0.32553},
+ {0.891742, -0.368518, 0.262661},
+ {0.855337, -0.405434, 0.322525},
+ {0.882837, -0.339209, 0.324864},
+ {0.869725, -0.307659, 0.385906 },
+ {0.828447, -0.342848, 0.442867},
+ {0.85264, -0.274694, 0.444464},
+ {0.947822, -0.289929, 0.13257},
+ {0.922682, -0.330607, 0.198387},
+ {0.944433, -0.26155, 0.199094},
+ {0.827147, 0.233445 , 0.511205},
+ {0.801504, 0.197274, 0.564513},
+ {0.785715, 0.273707, 0.55474},
+ {0.848029, 0.0784591, 0.52411},
+ {0.817523, 0.0406752, 0.574458},
+ {0.812169, 0.119078, 0.57114},
+ {0.771841 , 0.159613, 0.615456},
+ {0.738886, 0.121193, 0.662842},
+ {0.727958, 0.199331, 0.656006},
+ {0.848029, -0.0784591, 0.52411},
+ {0.812169, -0.119078, 0.57114},
+ {0.817523, -0.0406752, 0.574458},
+ {0.827147, -0.233445, 0.511205},
+ {0.785715, -0.273707, 0.55474},
+ {0.801504, -0.197274, 0.564513},
+ {0.771841, -0.159613, 0.615456},
+ {0.727958, -0.199331, 0.656006},
+ {0.738886, -0.121193 , 0.662842},
+ {0.700622, 0.080573, 0.708969},
+ {0.660884, 0.0406421, 0.749387},
+ {0.656282, 0.121144, 0.744727},
+ {0.700622, -0.080573, 0.708969},
+ {0.656282, -0.121144, 0.744727},
+ {0.660884 , -0.0406421, 0.749387},
+ {0.617676, 0, 0.786433},
+ {0.572056, -0.0406404, 0.819207},
+ {0.572056, 0.0406404, 0.819207},
+ {0.782786, 0, 0.622292},
+ {0.743496, -0.0406771, 0.667502},
+ {0.743496 , 0.0406771, 0.667502},
+ {0.991046, 0, 0.133523},
+ {0.960655, -0.0815011, 0.265518},
+ {0.978852, -0.0412509, 0.200368},
+ {0.978852, 0.0412509, 0.200368},
+ {0.960655, 0.0815011, 0.265518},
+ {0.904839, -0.161006, 0.394136},
+ {0.93513, -0.1228, 0.332342},
+ {0.868534, -0.198227, 0.454262},
+ {0.879345, -0.119755, 0.460882},
+ {0.88476, -0.0412992, 0.464213},
+ {0.93513, 0.1228, 0.332342 },
+ {0.904839, 0.161006, 0.394136},
+ {0.88476, 0.0412992, 0.464213},
+ {0.879345, 0.119755, 0.460882},
+ {0.868534, 0.198227, 0.454262},
+ {0.941618, -0.041302, 0.33414},
+ {0.916092, 0, 0.400968 },
+ {0.941618, 0.041302, 0.33414},
+ {0.859848, 0.506298, -0.0657576},
+ {0.892927, 0.445365, -0.0658169},
+ {0.865871, 0.460267, -0.196015},
+ {0.896401, 0.397351, -0.196412},
+ {0.896801, 0.422364, -0.131749},
+ {0.921919, 0.381722, -0.0659884},
+ {0.946198, 0.316778, -0.0660424},
+ {0.855337, 0.405434, -0.322525},
+ {0.882837, 0.339209, -0.324864},
+ {0.891742, 0.368518, -0.262661 },
+ {0.828447, 0.342848, -0.442867},
+ {0.85264, 0.274694, -0.444464},
+ {0.869725, 0.307659, -0.385906},
+ {0.905832, 0.270627, -0.325929},
+ {0.92388, 0.201189, -0.32553},
+ {0.93605, 0.232455 , -0.264151},
+ {0.966643, 0.247326, -0.0665669},
+ {0.981483, 0.179596, -0.0666044},
+ {0.961188, 0.19178, -0.198337},
+ {0.97237, 0.122729, -0.19858},
+ {0.979426, 0.151549, -0.133256},
+ { 0.991648, 0.110385, -0.0667094},
+ {0.996917, 0.0412484, -0.0667413},
+ {0.922682, 0.330607, -0.198387},
+ {0.944433, 0.26155, -0.199094},
+ {0.947822, 0.289929, -0.13257},
+ {0.785715, 0.273707, - 0.55474},
+ {0.801504, 0.197274, -0.564513},
+ {0.827147, 0.233445, -0.511205},
+ {0.727958, 0.199331, -0.656006},
+ {0.738886, 0.121193, -0.662842},
+ {0.771841, 0.159613, -0.615456},
+ {0.812169 , 0.119078, -0.57114},
+ {0.817523, 0.0406752, -0.574458},
+ {0.848029, 0.0784591, -0.52411},
+ {0.656282, 0.121144, -0.744727},
+ {0.660884, 0.0406421, -0.749387},
+ {0.700622, 0.080573, -0.708969 },
+ {0.572056, 0.0406404, -0.819207},
+ {0.572056, -0.0406404, -0.819207},
+ {0.617676, 0, -0.786433},
+ {0.660884, -0.0406421, -0.749387},
+ {0.656282, -0.121144, -0.744727},
+ {0.700622, - 0.080573, -0.708969},
+ {0.817523, -0.0406752, -0.574458},
+ {0.812169, -0.119078, -0.57114},
+ {0.848029, -0.0784591, -0.52411},
+ {0.738886, -0.121193, -0.662842},
+ {0.727958, -0.199331, -0.656006 },
+ {0.771841, -0.159613, -0.615456},
+ {0.801504, -0.197274, -0.564513},
+ {0.785715, -0.273707, -0.55474},
+ {0.827147, -0.233445, -0.511205},
+ {0.743496, 0.0406771, -0.667502},
+ {0.743496 , -0.0406771, -0.667502},
+ {0.782786, 0, -0.622292},
+ {0.996917, -0.0412484, -0.0667413},
+ {0.991648, -0.110385, -0.0667094},
+ {0.97237, -0.122729, -0.19858},
+ {0.961188, -0.19178, -0.198337},
+ {0.979426, -0.151549, -0.133256},
+ {0.981483, -0.179596, -0.0666044},
+ {0.966643, -0.247326, -0.0665669},
+ {0.92388, -0.201189, -0.32553},
+ {0.905832, -0.270627, -0.325929},
+ {0.93605 , -0.232455, -0.264151},
+ {0.85264, -0.274694, -0.444464},
+ {0.828447, -0.342848, -0.442867},
+ {0.869725, -0.307659, -0.385906},
+ {0.882837, -0.339209, -0.324864},
+ {0.855337, -0.405434, -0.322525 },
+ {0.891742, -0.368518, -0.262661},
+ {0.946198, -0.316778, -0.0660424},
+ {0.921919, -0.381722, -0.0659884},
+ {0.896401, -0.397351, -0.196412},
+ {0.865871, -0.460267, -0.196015},
+ {0.896801 , -0.422364, -0.131749},
+ {0.892927, -0.445365, -0.0658169},
+ {0.859848, -0.506298, -0.0657576},
+ {0.944433, -0.26155, -0.199094},
+ {0.922682, -0.330607, -0.198387},
+ {0.947822, -0.289929, -0.13257 },
+ {0.868534, 0.198227, -0.454262},
+ {0.88476, 0.0412992, -0.464213},
+ {0.879345, 0.119755, -0.460882},
+ {0.904839, 0.161006, -0.394136},
+ {0.93513, 0.1228, -0.332342},
+ {0.879345, -0.119755 , -0.460882},
+ {0.88476, -0.0412992, -0.464213},
+ {0.868534, -0.198227, -0.454262},
+ {0.904839, -0.161006, -0.394136},
+ {0.93513, -0.1228, -0.332342},
+ {0.960655, 0.0815011, -0.265518},
+ { 0.978852, 0.0412509, -0.200368},
+ {0.960655, -0.0815011, -0.265518},
+ {0.978852, -0.0412509, -0.200368},
+ {0.991046, 0, -0.133523},
+ {0.916092, 0, -0.400968},
+ {0.941618, -0.041302, -0.33414},
+ {0.941618, 0.041302, -0.33414},
+ {-0.884965, -0.465658, 6.12323e-17},
+ {-0.892927, -0.445365, 0.0658169},
+ {-0.859848, -0.506298, 0.0657576},
+ {-0.940742, -0.339123, 6.12323e-17},
+ {- 0.946198, -0.316778, 0.0660424},
+ {-0.921919, -0.381722, 0.0659884},
+ {-0.896801, -0.422364, 0.131749},
+ {-0.896401, -0.397351, 0.196412},
+ {-0.865871, -0.460267, 0.196015},
+ {-0.97853, -0.206103 , 6.12323e-17},
+ {-0.981483, -0.179596, 0.0666044},
+ {-0.966643, -0.247326, 0.0665669},
+ {-0.997607, -0.0691416, 6.12323e-17},
+ {-0.996917, -0.0412484, 0.0667413},
+ {-0.991648, -0.110385, 0.0667094 },
+ {-0.979426, -0.151549, 0.133256},
+ {-0.97237, -0.122729, 0.19858},
+ {-0.961188, -0.19178, 0.198337},
+ {-0.891742, -0.368518, 0.262661},
+ {-0.882837, -0.339209, 0.324864},
+ {-0.855337 , -0.405434, 0.322525},
+ {-0.93605, -0.232455, 0.264151},
+ {-0.92388, -0.201189, 0.32553},
+ {-0.905832, -0.270627, 0.325929},
+ {-0.869725, -0.307659, 0.385906},
+ {-0.85264, -0.274694, 0.444464 },
+ {-0.828447, -0.342848, 0.442867},
+ {-0.947822, -0.289929, 0.13257},
+ {-0.944433, -0.26155, 0.199094},
+ {-0.922682, -0.330607, 0.198387},
+ {-0.997607, 0.0691416, 6.12323e-17},
+ {-0.991648 , 0.110385, 0.0667094},
+ {-0.996917, 0.0412484, 0.0667413},
+ {-0.97853, 0.206103, 6.12323e-17},
+ {-0.966643, 0.247326, 0.0665669},
+ {-0.981483, 0.179596, 0.0666044},
+ {-0.979426, 0.151549, 0.133256 },
+ {-0.961188, 0.19178, 0.198337},
+ {-0.97237, 0.122729, 0.19858},
+ {-0.940742, 0.339123, 6.12323e-17},
+ {-0.921919, 0.381722, 0.0659884},
+ {-0.946198, 0.316778, 0.0660424},
+ {-0.884965 , 0.465658, 6.12323e-17},
+ {-0.859848, 0.506298, 0.0657576},
+ {-0.892927, 0.445365, 0.0658169},
+ {-0.896801, 0.422364, 0.131749},
+ {-0.865871, 0.460267, 0.196015},
+ {-0.896401, 0.397351, 0.196412 },
+ {-0.93605, 0.232455, 0.264151},
+ {-0.905832, 0.270627, 0.325929},
+ {-0.92388, 0.201189, 0.32553},
+ {-0.891742, 0.368518, 0.262661},
+ {-0.855337, 0.405434, 0.322525},
+ {-0.882837, 0.339209 , 0.324864},
+ {-0.869725, 0.307659, 0.385906},
+ {-0.828447, 0.342848, 0.442867},
+ {-0.85264, 0.274694, 0.444464},
+ {-0.947822, 0.289929, 0.13257},
+ {-0.922682, 0.330607, 0.198387},
+ {-0.944433 , 0.26155, 0.199094},
+ {-0.827147, -0.233445, 0.511205},
+ {-0.801504, -0.197274, 0.564513},
+ {-0.785715, -0.273707, 0.55474},
+ {-0.848029, -0.0784591, 0.52411},
+ {-0.817523, -0.0406752, 0.574458 },
+ {-0.812169, -0.119078, 0.57114},
+ {-0.771841, -0.159613, 0.615456},
+ {-0.738886, -0.121193, 0.662842},
+ {-0.727958, -0.199331, 0.656006},
+ {-0.848029, 0.0784591, 0.52411},
+ {-0.812169 , 0.119078, 0.57114},
+ {-0.817523, 0.0406752, 0.574458},
+ {-0.827147, 0.233445, 0.511205},
+ {-0.785715, 0.273707, 0.55474},
+ {-0.801504, 0.197274, 0.564513},
+ {-0.771841, 0.159613, 0.615456},
+ {-0.727958, 0.199331, 0.656006},
+ {-0.738886, 0.121193, 0.662842},
+ {-0.700622, -0.080573, 0.708969},
+ {-0.660884, -0.0406421, 0.749387},
+ {-0.656282, -0.121144, 0.744727},
+ {-0.700622 , 0.080573, 0.708969},
+ {-0.656282, 0.121144, 0.744727},
+ {-0.660884, 0.0406421, 0.749387},
+ {-0.617676, 7.56435e-17, 0.786433},
+ {-0.572056, 0.0406404, 0.819207},
+ {-0.572056, -0.0406404, 0.819207 },
+ {-0.782786, 9.58636e-17, 0.622292},
+ {-0.743496, 0.0406771, 0.667502},
+ {-0.743496, -0.0406771, 0.667502},
+ {-0.991046, 1.21368e-16, 0.133523},
+ {-0.960655, 0.0815011, 0.265518},
+ {- 0.978852, 0.0412509, 0.200368},
+ {-0.978852, -0.0412509, 0.200368},
+ {-0.960655, -0.0815011, 0.265518},
+ {-0.904839, 0.161006, 0.394136},
+ {-0.93513, 0.1228, 0.332342},
+ {-0.868534, 0.198227, 0.454262},
+ {-0.879345, 0.119755, 0.460882},
+ {-0.88476, 0.0412992, 0.464213},
+ {-0.93513, -0.1228, 0.332342},
+ {-0.904839, -0.161006, 0.394136},
+ {-0.88476, -0.0412992, 0.464213},
+ {-0.879345 , -0.119755, 0.460882},
+ {-0.868534, -0.198227, 0.454262},
+ {-0.941618, 0.041302, 0.33414},
+ {-0.916092, 1.12189e-16, 0.400968},
+ {-0.941618, -0.041302, 0.33414},
+ {-0.859848, -0.506298, -0.0657576 },
+ {-0.892927, -0.445365, -0.0658169},
+ {-0.865871, -0.460267, -0.196015},
+ {-0.896401, -0.397351, -0.196412},
+ {-0.896801, -0.422364, -0.131749},
+ {-0.921919, -0.381722, -0.0659884},
+ {- 0.946198, -0.316778, -0.0660424},
+ {-0.855337, -0.405434, -0.322525},
+ {-0.882837, -0.339209, -0.324864},
+ {-0.891742, -0.368518, -0.262661},
+ {-0.828447, -0.342848, -0.442867},
+ {-0.85264, - 0.274694, -0.444464},
+ {-0.869725, -0.307659, -0.385906},
+ {-0.905832, -0.270627, -0.325929},
+ {-0.92388, -0.201189, -0.32553},
+ {-0.93605, -0.232455, -0.264151},
+ {-0.966643, -0.247326, -0.0665669 },
+ {-0.981483, -0.179596, -0.0666044},
+ {-0.961188, -0.19178, -0.198337},
+ {-0.97237, -0.122729, -0.19858},
+ {-0.979426, -0.151549, -0.133256},
+ {-0.991648, -0.110385, -0.0667094},
+ {- 0.996917, -0.0412484, -0.0667413},
+ {-0.922682, -0.330607, -0.198387},
+ {-0.944433, -0.26155, -0.199094},
+ {-0.947822, -0.289929, -0.13257},
+ {-0.785715, -0.273707, -0.55474},
+ {-0.801504, -0.197274 , -0.564513},
+ {-0.827147, -0.233445, -0.511205},
+ {-0.727958, -0.199331, -0.656006},
+ {-0.738886, -0.121193, -0.662842},
+ {-0.771841, -0.159613, -0.615456},
+ {-0.812169, -0.119078, -0.57114},
+ {-0.817523, -0.0406752, -0.574458},
+ {-0.848029, -0.0784591, -0.52411},
+ {-0.656282, -0.121144, -0.744727},
+ {-0.660884, -0.0406421, -0.749387},
+ {-0.700622, -0.080573, -0.708969},
+ {- 0.572056, -0.0406404, -0.819207},
+ {-0.572056, 0.0406404, -0.819207},
+ {-0.617676, 7.56435e-17, -0.786433},
+ {-0.660884, 0.0406421, -0.749387},
+ {-0.656282, 0.121144, -0.744727},
+ {-0.700622, 0.080573, -0.708969},
+ {-0.817523, 0.0406752, -0.574458},
+ {-0.812169, 0.119078, -0.57114},
+ {-0.848029, 0.0784591, -0.52411},
+ {-0.738886, 0.121193, -0.662842},
+ {-0.727958, 0.199331, -0.656006 },
+ {-0.771841, 0.159613, -0.615456},
+ {-0.801504, 0.197274, -0.564513},
+ {-0.785715, 0.273707, -0.55474},
+ {-0.827147, 0.233445, -0.511205},
+ {-0.743496, -0.0406771, -0.667502},
+ {-0.743496 , 0.0406771, -0.667502},
+ {-0.782786, 9.58636e-17, -0.622292},
+ {-0.996917, 0.0412484, -0.0667413},
+ {-0.991648, 0.110385, -0.0667094},
+ {-0.97237, 0.122729, -0.19858},
+ {-0.961188, 0.19178, - 0.198337},
+ {-0.979426, 0.151549, -0.133256},
+ {-0.981483, 0.179596, -0.0666044},
+ {-0.966643, 0.247326, -0.0665669},
+ {-0.92388, 0.201189, -0.32553},
+ {-0.905832, 0.270627, -0.325929},
+ {- 0.93605, 0.232455, -0.264151},
+ {-0.85264, 0.274694, -0.444464},
+ {-0.828447, 0.342848, -0.442867},
+ {-0.869725, 0.307659, -0.385906},
+ {-0.882837, 0.339209, -0.324864},
+ {-0.855337, 0.405434 , -0.322525},
+ {-0.891742, 0.368518, -0.262661},
+ {-0.946198, 0.316778, -0.0660424},
+ {-0.921919, 0.381722, -0.0659884},
+ {-0.896401, 0.397351, -0.196412},
+ {-0.865871, 0.460267, -0.196015},
+ {-0.896801, 0.422364, -0.131749},
+ {-0.892927, 0.445365, -0.0658169},
+ {-0.859848, 0.506298, -0.0657576},
+ {-0.944433, 0.26155, -0.199094},
+ {-0.922682, 0.330607, -0.198387},
+ {-0.947822, 0.289929, -0.13257},
+ {-0.868534, -0.198227, -0.454262},
+ {-0.88476, -0.0412992, -0.464213},
+ {-0.879345, -0.119755, -0.460882},
+ {-0.904839, -0.161006, -0.394136},
+ {-0.93513, -0.1228, -0.332342 },
+ {-0.879345, 0.119755, -0.460882},
+ {-0.88476, 0.0412992, -0.464213},
+ {-0.868534, 0.198227, -0.454262},
+ {-0.904839, 0.161006, -0.394136},
+ {-0.93513, 0.1228, -0.332342},
+ {-0.960655 , -0.0815011, -0.265518},
+ {-0.978852, -0.0412509, -0.200368},
+ {-0.960655, 0.0815011, -0.265518},
+ {-0.978852, 0.0412509, -0.200368},
+ {-0.991046, 1.21368e-16, -0.133523},
+ {-0.916092, 1.12189e-16 , -0.400968},
+ {-0.941618, 0.041302, -0.33414},
+ {-0.941618, -0.041302, -0.33414},
+ {5.41885e-17, 0.884965, 0.465658},
+ {0.0658169, 0.892927, 0.445365},
+ {0.0657576, 0.859848, 0.506298},
+ { 5.76038e-17, 0.940742, 0.339123},
+ {0.0660424, 0.946198, 0.316778},
+ {0.0659884, 0.921919, 0.381722},
+ {0.131749, 0.896801, 0.422364},
+ {0.196412, 0.896401, 0.397351},
+ {0.196015, 0.865871, 0.460267 },
+ {5.99177e-17, 0.97853, 0.206103},
+ {0.0666044, 0.981483, 0.179596},
+ {0.0665669, 0.966643, 0.247326},
+ {6.10858e-17, 0.997607, 0.0691416},
+ {0.0667413, 0.996917, 0.0412484},
+ {0.0667094 , 0.991648, 0.110385},
+ {0.133256, 0.979426, 0.151549},
+ {0.19858, 0.97237, 0.122729},
+ {0.198337, 0.961188, 0.19178},
+ {0.262661, 0.891742, 0.368518},
+ {0.324864, 0.882837, 0.339209},
+ { 0.322525, 0.855337, 0.405434},
+ {0.264151, 0.93605, 0.232455},
+ {0.32553, 0.92388, 0.201189},
+ {0.325929, 0.905832, 0.270627},
+ {0.385906, 0.869725, 0.307659},
+ {0.444464, 0.85264, 0.274694},
+ {0.442867, 0.828447, 0.342848},
+ {0.13257, 0.947822, 0.289929},
+ {0.199094, 0.944433, 0.26155},
+ {0.198387, 0.922682, 0.330607},
+ {6.10858e-17, 0.997607, -0.0691416},
+ {0.0667094, 0.991648 , -0.110385},
+ {0.0667413, 0.996917, -0.0412484},
+ {5.99177e-17, 0.97853, -0.206103},
+ {0.0665669, 0.966643, -0.247326},
+ {0.0666044, 0.981483, -0.179596},
+ {0.133256, 0.979426, -0.151549},
+ {0.198337, 0.961188, -0.19178},
+ {0.19858, 0.97237, -0.122729},
+ {5.76038e-17, 0.940742, -0.339123},
+ {0.0659884, 0.921919, -0.381722},
+ {0.0660424, 0.946198, -0.316778},
+ {5.41885e-17, 0.884965 , -0.465658},
+ {0.0657576, 0.859848, -0.506298},
+ {0.0658169, 0.892927, -0.445365},
+ {0.131749, 0.896801, -0.422364},
+ {0.196015, 0.865871, -0.460267},
+ {0.196412, 0.896401, -0.397351},
+ { 0.264151, 0.93605, -0.232455},
+ {0.325929, 0.905832, -0.270627},
+ {0.32553, 0.92388, -0.201189},
+ {0.262661, 0.891742, -0.368518},
+ {0.322525, 0.855337, -0.405434},
+ {0.324864, 0.882837, -0.339209 },
+ {0.385906, 0.869725, -0.307659},
+ {0.442867, 0.828447, -0.342848},
+ {0.444464, 0.85264, -0.274694},
+ {0.13257, 0.947822, -0.289929},
+ {0.198387, 0.922682, -0.330607},
+ {0.199094, 0.944433 , -0.26155},
+ {0.511205, 0.827147, 0.233445},
+ {0.564513, 0.801504, 0.197274},
+ {0.55474, 0.785715, 0.273707},
+ {0.52411, 0.848029, 0.0784591},
+ {0.574458, 0.817523, 0.0406752},
+ {0.57114 , 0.812169, 0.119078},
+ {0.615456, 0.771841, 0.159613},
+ {0.662842, 0.738886, 0.121193},
+ {0.656006, 0.727958, 0.199331},
+ {0.52411, 0.848029, -0.0784591},
+ {0.57114, 0.812169, -0.119078},
+ {0.574458, 0.817523, -0.0406752},
+ {0.511205, 0.827147, -0.233445},
+ {0.55474, 0.785715, -0.273707},
+ {0.564513, 0.801504, -0.197274},
+ {0.615456, 0.771841, -0.159613},
+ {0.656006, 0.727958 , -0.199331},
+ {0.662842, 0.738886, -0.121193},
+ {0.708969, 0.700622, 0.080573},
+ {0.749387, 0.660884, 0.0406421},
+ {0.744727, 0.656282, 0.121144},
+ {0.708969, 0.700622, -0.080573},
+ {0.744727 , 0.656282, -0.121144},
+ {0.749387, 0.660884, -0.0406421},
+ {0.786433, 0.617676, -1.60812e-16},
+ {0.819207, 0.572056, -0.0406404},
+ {0.819207, 0.572056, 0.0406404},
+ {0.622292, 0.782786, -1.60812e-16 },
+ {0.667502, 0.743496, -0.0406771},
+ {0.667502, 0.743496, 0.0406771},
+ {0.133523, 0.991046, -1.60812e-16},
+ {0.265518, 0.960655, -0.0815011},
+ {0.200368, 0.978852, -0.0412509},
+ {0.200368 , 0.978852, 0.0412509},
+ {0.265518, 0.960655, 0.0815011},
+ {0.394136, 0.904839, -0.161006},
+ {0.332342, 0.93513, -0.1228},
+ {0.454262, 0.868534, -0.198227},
+ {0.460882, 0.879345, -0.119755},
+ {0.464213, 0.88476, -0.0412992},
+ {0.332342, 0.93513, 0.1228},
+ {0.394136, 0.904839, 0.161006},
+ {0.464213, 0.88476, 0.0412992},
+ {0.460882, 0.879345, 0.119755},
+ {0.454262, 0.868534, 0.198227 },
+ {0.33414, 0.941618, -0.041302},
+ {0.400968, 0.916092, -1.60812e-16},
+ {0.33414, 0.941618, 0.041302},
+ {-0.0657576, 0.859848, 0.506298},
+ {-0.0658169, 0.892927, 0.445365},
+ {-0.196015 , 0.865871, 0.460267},
+ {-0.196412, 0.896401, 0.397351},
+ {-0.131749, 0.896801, 0.422364},
+ {-0.0659884, 0.921919, 0.381722},
+ {-0.0660424, 0.946198, 0.316778},
+ {-0.322525, 0.855337, 0.405434 },
+ {-0.324864, 0.882837, 0.339209},
+ {-0.262661, 0.891742, 0.368518},
+ {-0.442867, 0.828447, 0.342848},
+ {-0.444464, 0.85264, 0.274694},
+ {-0.385906, 0.869725, 0.307659},
+ {-0.325929, 0.905832, 0.270627},
+ {-0.32553, 0.92388, 0.201189},
+ {-0.264151, 0.93605, 0.232455},
+ {-0.0665669, 0.966643, 0.247326},
+ {-0.0666044, 0.981483, 0.179596},
+ {-0.198337, 0.961188, 0.19178},
+ {-0.19858, 0.97237, 0.122729},
+ {-0.133256, 0.979426, 0.151549},
+ {-0.0667094, 0.991648, 0.110385},
+ {-0.0667413, 0.996917, 0.0412484},
+ {-0.198387, 0.922682, 0.330607},
+ {-0.199094, 0.944433 , 0.26155},
+ {-0.13257, 0.947822, 0.289929},
+ {-0.55474, 0.785715, 0.273707},
+ {-0.564513, 0.801504, 0.197274},
+ {-0.511205, 0.827147, 0.233445},
+ {-0.656006, 0.727958, 0.199331},
+ {-0.662842 , 0.738886, 0.121193},
+ {-0.615456, 0.771841, 0.159613},
+ {-0.57114, 0.812169, 0.119078},
+ {-0.574458, 0.817523, 0.0406752},
+ {-0.52411, 0.848029, 0.0784591},
+ {-0.744727, 0.656282, 0.121144},
+ {-0.749387, 0.660884, 0.0406421},
+ {-0.708969, 0.700622, 0.080573},
+ {-0.819207, 0.572056, 0.0406404},
+ {-0.819207, 0.572056, -0.0406404},
+ {-0.786433, 0.617676, -1.60812e-16},
+ {-0.749387 , 0.660884, -0.0406421},
+ {-0.744727, 0.656282, -0.121144},
+ {-0.708969, 0.700622, -0.080573},
+ {-0.574458, 0.817523, -0.0406752},
+ {-0.57114, 0.812169, -0.119078},
+ {-0.52411, 0.848029, -0.0784591 },
+ {-0.662842, 0.738886, -0.121193},
+ {-0.656006, 0.727958, -0.199331},
+ {-0.615456, 0.771841, -0.159613},
+ {-0.564513, 0.801504, -0.197274},
+ {-0.55474, 0.785715, -0.273707},
+ {-0.511205 , 0.827147, -0.233445},
+ {-0.667502, 0.743496, 0.0406771},
+ {-0.667502, 0.743496, -0.0406771},
+ {-0.622292, 0.782786, -1.60812e-16},
+ {-0.0667413, 0.996917, -0.0412484},
+ {-0.0667094, 0.991648 , -0.110385},
+ {-0.19858, 0.97237, -0.122729},
+ {-0.198337, 0.961188, -0.19178},
+ {-0.133256, 0.979426, -0.151549},
+ {-0.0666044, 0.981483, -0.179596},
+ {-0.0665669, 0.966643, -0.247326},
+ {-0.32553, 0.92388, -0.201189},
+ {-0.325929, 0.905832, -0.270627},
+ {-0.264151, 0.93605, -0.232455},
+ {-0.444464, 0.85264, -0.274694},
+ {-0.442867, 0.828447, -0.342848},
+ {-0.385906, 0.869725 , -0.307659},
+ {-0.324864, 0.882837, -0.339209},
+ {-0.322525, 0.855337, -0.405434},
+ {-0.262661, 0.891742, -0.368518},
+ {-0.0660424, 0.946198, -0.316778},
+ {-0.0659884, 0.921919, -0.381722},
+ {-0.196412, 0.896401, -0.397351},
+ {-0.196015, 0.865871, -0.460267},
+ {-0.131749, 0.896801, -0.422364},
+ {-0.0658169, 0.892927, -0.445365},
+ {-0.0657576, 0.859848, -0.506298},
+ {-0.199094 , 0.944433, -0.26155},
+ {-0.198387, 0.922682, -0.330607},
+ {-0.13257, 0.947822, -0.289929},
+ {-0.454262, 0.868534, 0.198227},
+ {-0.464213, 0.88476, 0.0412992},
+ {-0.460882, 0.879345, 0.119755 },
+ {-0.394136, 0.904839, 0.161006},
+ {-0.332342, 0.93513, 0.1228},
+ {-0.460882, 0.879345, -0.119755},
+ {-0.464213, 0.88476, -0.0412992},
+ {-0.454262, 0.868534, -0.198227},
+ {-0.394136, 0.904839, -0.161006},
+ {-0.332342, 0.93513, -0.1228},
+ {-0.265518, 0.960655, 0.0815011},
+ {-0.200368, 0.978852, 0.0412509},
+ {-0.265518, 0.960655, -0.0815011},
+ {-0.200368, 0.978852, -0.0412509 },
+ {-0.133523, 0.991046, -1.60812e-16},
+ {-0.400968, 0.916092, -1.60812e-16},
+ {-0.33414, 0.941618, -0.041302},
+ {-0.33414, 0.941618, 0.041302},
+ {0.0657576, -0.859848, 0.506298},
+ {0.0658169 , -0.892927, 0.445365},
+ {5.41885e-17, -0.884965, 0.465658},
+ {0.196015, -0.865871, 0.460267},
+ {0.196412, -0.896401, 0.397351},
+ {0.131749, -0.896801, 0.422364},
+ {0.0659884, -0.921919, 0.381722 },
+ {0.0660424, -0.946198, 0.316778},
+ {5.76038e-17, -0.940742, 0.339123},
+ {0.322525, -0.855337, 0.405434},
+ {0.324864, -0.882837, 0.339209},
+ {0.262661, -0.891742, 0.368518},
+ {0.442867 , -0.828447, 0.342848},
+ {0.444464, -0.85264, 0.274694},
+ {0.385906, -0.869725, 0.307659},
+ {0.325929, -0.905832, 0.270627},
+ {0.32553, -0.92388, 0.201189},
+ {0.264151, -0.93605, 0.232455},
+ {0.0665669, -0.966643, 0.247326},
+ {0.0666044, -0.981483, 0.179596},
+ {5.99177e-17, -0.97853, 0.206103},
+ {0.198337, -0.961188, 0.19178},
+ {0.19858, -0.97237, 0.122729},
+ {0.133256, -0.979426 , 0.151549},
+ {0.0667094, -0.991648, 0.110385},
+ {0.0667413, -0.996917, 0.0412484},
+ {6.10858e-17, -0.997607, 0.0691416},
+ {0.198387, -0.922682, 0.330607},
+ {0.199094, -0.944433, 0.26155},
+ {0.13257, -0.947822, 0.289929},
+ {0.55474, -0.785715, 0.273707},
+ {0.564513, -0.801504, 0.197274},
+ {0.511205, -0.827147, 0.233445},
+ {0.656006, -0.727958, 0.199331},
+ {0.662842, -0.738886 , 0.121193},
+ {0.615456, -0.771841, 0.159613},
+ {0.57114, -0.812169, 0.119078},
+ {0.574458, -0.817523, 0.0406752},
+ {0.52411, -0.848029, 0.0784591},
+ {0.744727, -0.656282, 0.121144},
+ { 0.749387, -0.660884, 0.0406421},
+ {0.708969, -0.700622, 0.080573},
+ {0.819207, -0.572056, 0.0406404},
+ {0.819207, -0.572056, -0.0406404},
+ {0.786433, -0.617676, -1.60812e-16},
+ {0.749387, -0.660884 , -0.0406421},
+ {0.744727, -0.656282, -0.121144},
+ {0.708969, -0.700622, -0.080573},
+ {0.574458, -0.817523, -0.0406752},
+ {0.57114, -0.812169, -0.119078},
+ {0.52411, -0.848029, -0.0784591},
+ {0.662842, -0.738886, -0.121193},
+ {0.656006, -0.727958, -0.199331},
+ {0.615456, -0.771841, -0.159613},
+ {0.564513, -0.801504, -0.197274},
+ {0.55474, -0.785715, -0.273707},
+ {0.511205, -0.827147 , -0.233445},
+ {0.667502, -0.743496, 0.0406771},
+ {0.667502, -0.743496, -0.0406771},
+ {0.622292, -0.782786, -1.60812e-16},
+ {0.0667413, -0.996917, -0.0412484},
+ {0.0667094, -0.991648, -0.110385 },
+ {6.10858e-17, -0.997607, -0.0691416},
+ {0.19858, -0.97237, -0.122729},
+ {0.198337, -0.961188, -0.19178},
+ {0.133256, -0.979426, -0.151549},
+ {0.0666044, -0.981483, -0.179596},
+ {0.0665669 , -0.966643, -0.247326},
+ {5.99177e-17, -0.97853, -0.206103},
+ {0.32553, -0.92388, -0.201189},
+ {0.325929, -0.905832, -0.270627},
+ {0.264151, -0.93605, -0.232455},
+ {0.444464, -0.85264, -0.274694 },
+ {0.442867, -0.828447, -0.342848},
+ {0.385906, -0.869725, -0.307659},
+ {0.324864, -0.882837, -0.339209},
+ {0.322525, -0.855337, -0.405434},
+ {0.262661, -0.891742, -0.368518},
+ {0.0660424 , -0.946198, -0.316778},
+ {0.0659884, -0.921919, -0.381722},
+ {5.76038e-17, -0.940742, -0.339123},
+ {0.196412, -0.896401, -0.397351},
+ {0.196015, -0.865871, -0.460267},
+ {0.131749, -0.896801, - 0.422364},
+ {0.0658169, -0.892927, -0.445365},
+ {0.0657576, -0.859848, -0.506298},
+ {5.41885e-17, -0.884965, -0.465658},
+ {0.199094, -0.944433, -0.26155},
+ {0.198387, -0.922682, -0.330607},
+ {0.13257, -0.947822, -0.289929},
+ {0.454262, -0.868534, 0.198227},
+ {0.464213, -0.88476, 0.0412992},
+ {0.460882, -0.879345, 0.119755},
+ {0.394136, -0.904839, 0.161006},
+ {0.332342, -0.93513 , 0.1228},
+ {0.460882, -0.879345, -0.119755},
+ {0.464213, -0.88476, -0.0412992},
+ {0.454262, -0.868534, -0.198227},
+ {0.394136, -0.904839, -0.161006},
+ {0.332342, -0.93513, -0.1228},
+ { 0.265518, -0.960655, 0.0815011},
+ {0.200368, -0.978852, 0.0412509},
+ {0.265518, -0.960655, -0.0815011},
+ {0.200368, -0.978852, -0.0412509},
+ {0.133523, -0.991046, -1.60812e-16},
+ {0.400968, - 0.916092, -1.60812e-16},
+ {0.33414, -0.941618, -0.041302},
+ {0.33414, -0.941618, 0.041302},
+ {-0.0658169, -0.892927, 0.445365},
+ {-0.0657576, -0.859848, 0.506298},
+ {-0.0660424, -0.946198, 0.316778 },
+ {-0.0659884, -0.921919, 0.381722},
+ {-0.131749, -0.896801, 0.422364},
+ {-0.196412, -0.896401, 0.397351},
+ {-0.196015, -0.865871, 0.460267},
+ {-0.0666044, -0.981483, 0.179596},
+ {-0.0665669 , -0.966643, 0.247326},
+ {-0.0667413, -0.996917, 0.0412484},
+ {-0.0667094, -0.991648, 0.110385},
+ {-0.133256, -0.979426, 0.151549},
+ {-0.19858, -0.97237, 0.122729},
+ {-0.198337, -0.961188, 0.19178 },
+ {-0.262661, -0.891742, 0.368518},
+ {-0.324864, -0.882837, 0.339209},
+ {-0.322525, -0.855337, 0.405434},
+ {-0.264151, -0.93605, 0.232455},
+ {-0.32553, -0.92388, 0.201189},
+ {-0.325929 , -0.905832, 0.270627},
+ {-0.385906, -0.869725, 0.307659},
+ {-0.444464, -0.85264, 0.274694},
+ {-0.442867, -0.828447, 0.342848},
+ {-0.13257, -0.947822, 0.289929},
+ {-0.199094, -0.944433, 0.26155 },
+ {-0.198387, -0.922682, 0.330607},
+ {-0.0667094, -0.991648, -0.110385},
+ {-0.0667413, -0.996917, -0.0412484},
+ {-0.0665669, -0.966643, -0.247326},
+ {-0.0666044, -0.981483, -0.179596},
+ {- 0.133256, -0.979426, -0.151549},
+ {-0.198337, -0.961188, -0.19178},
+ {-0.19858, -0.97237, -0.122729},
+ {-0.0659884, -0.921919, -0.381722},
+ {-0.0660424, -0.946198, -0.316778},
+ {-0.0657576, - 0.859848, -0.506298},
+ {-0.0658169, -0.892927, -0.445365},
+ {-0.131749, -0.896801, -0.422364},
+ {-0.196015, -0.865871, -0.460267},
+ {-0.196412, -0.896401, -0.397351},
+ {-0.264151, -0.93605, - 0.232455},
+ {-0.325929, -0.905832, -0.270627},
+ {-0.32553, -0.92388, -0.201189},
+ {-0.262661, -0.891742, -0.368518},
+ {-0.322525, -0.855337, -0.405434},
+ {-0.324864, -0.882837, -0.339209},
+ {-0.385906, -0.869725, -0.307659},
+ {-0.442867, -0.828447, -0.342848},
+ {-0.444464, -0.85264, -0.274694},
+ {-0.13257, -0.947822, -0.289929},
+ {-0.198387, -0.922682, -0.330607},
+ {-0.199094 , -0.944433, -0.26155},
+ {-0.511205, -0.827147, 0.233445},
+ {-0.564513, -0.801504, 0.197274},
+ {-0.55474, -0.785715, 0.273707},
+ {-0.52411, -0.848029, 0.0784591},
+ {-0.574458, -0.817523, 0.0406752 },
+ {-0.57114, -0.812169, 0.119078},
+ {-0.615456, -0.771841, 0.159613},
+ {-0.662842, -0.738886, 0.121193},
+ {-0.656006, -0.727958, 0.199331},
+ {-0.52411, -0.848029, -0.0784591},
+ {-0.57114 , -0.812169, -0.119078},
+ {-0.574458, -0.817523, -0.0406752},
+ {-0.511205, -0.827147, -0.233445},
+ {-0.55474, -0.785715, -0.273707},
+ {-0.564513, -0.801504, -0.197274},
+ {-0.615456, -0.771841 , -0.159613},
+ {-0.656006, -0.727958, -0.199331},
+ {-0.662842, -0.738886, -0.121193},
+ {-0.708969, -0.700622, 0.080573},
+ {-0.749387, -0.660884, 0.0406421},
+ {-0.744727, -0.656282, 0.121144},
+ {-0.708969, -0.700622, -0.080573},
+ {-0.744727, -0.656282, -0.121144},
+ {-0.749387, -0.660884, -0.0406421},
+ {-0.786433, -0.617676, -1.60812e-16},
+ {-0.819207, -0.572056, -0.0406404},
+ {- 0.819207, -0.572056, 0.0406404},
+ {-0.622292, -0.782786, -1.60812e-16},
+ {-0.667502, -0.743496, -0.0406771},
+ {-0.667502, -0.743496, 0.0406771},
+ {-0.133523, -0.991046, -1.60812e-16},
+ {-0.265518 , -0.960655, -0.0815011},
+ {-0.200368, -0.978852, -0.0412509},
+ {-0.200368, -0.978852, 0.0412509},
+ {-0.265518, -0.960655, 0.0815011},
+ {-0.394136, -0.904839, -0.161006},
+ {-0.332342, -0.93513 , -0.1228},
+ {-0.454262, -0.868534, -0.198227},
+ {-0.460882, -0.879345, -0.119755},
+ {-0.464213, -0.88476, -0.0412992},
+ {-0.332342, -0.93513, 0.1228},
+ {-0.394136, -0.904839, 0.161006},
+ {- 0.464213, -0.88476, 0.0412992},
+ {-0.460882, -0.879345, 0.119755},
+ {-0.454262, -0.868534, 0.198227},
+ {-0.33414, -0.941618, -0.041302},
+ {-0.400968, -0.916092, -1.60812e-16},
+ {-0.33414, -0.941618 , 0.041302},
+ {0.106494, 0.82711, 0.551859},
+ {0.237229, 0.830359, 0.504209},
+ {0.172532, 0.830812, 0.529135},
+ {0.147414, 0.79017, 0.594895},
+ {0.187432, 0.749786, 0.634579},
+ {0.366027 , 0.816233, 0.446977},
+ {0.303801, 0.825175, 0.476226},
+ {0.485712, 0.785899, 0.382683},
+ {0.427135, 0.803016, 0.415597},
+ {0.408286, 0.772575, 0.48624},
+ {0.448259, 0.725299, 0.522499},
+ { 0.38673, 0.737712, 0.553372},
+ {0.2289, 0.703983, 0.672319},
+ {0.267381, 0.65662, 0.705236},
+ {0.361592, 0.697037, 0.619186},
+ {0.399769, 0.64684, 0.649448},
+ {0.334692, 0.653497, 0.678913},
+ {0.305212, 0.605741, 0.734794},
+ {0.341435, 0.552454, 0.760406},
+ {0.280319, 0.790112, 0.545109},
+ {0.322141, 0.745338, 0.583691},
+ {0.25518, 0.749435, 0.610926},
+ {0.605741, 0.734794, 0.305212 },
+ {0.552454, 0.760406, 0.341435},
+ {0.703983, 0.672319, 0.2289},
+ {0.65662, 0.705236, 0.267381},
+ {0.653497, 0.678913, 0.334692},
+ {0.697037, 0.619186, 0.361592},
+ {0.64684, 0.649448, 0.399769},
+ {0.79017, 0.594895, 0.147414},
+ {0.749786, 0.634579, 0.187432},
+ {0.82711, 0.551859, 0.106494},
+ {0.830812, 0.529135, 0.172532},
+ {0.830359, 0.504209, 0.237229},
+ {0.737712, 0.553372, 0.38673},
+ {0.772575, 0.48624, 0.408286},
+ {0.725299, 0.522499, 0.448259},
+ {0.825175, 0.476226, 0.303801},
+ {0.816233, 0.446977, 0.366027},
+ {0.803016, 0.415597, 0.427135},
+ { 0.785899, 0.382683, 0.485712},
+ {0.749435, 0.610926, 0.25518},
+ {0.790112, 0.545109, 0.280319},
+ {0.745338, 0.583691, 0.322141},
+ {0.382683, 0.485712, 0.785899},
+ {0.415597, 0.427135, 0.803016 },
+ {0.522499, 0.448259, 0.725299},
+ {0.553372, 0.38673, 0.737712},
+ {0.48624, 0.408286, 0.772575},
+ {0.446977, 0.366027, 0.816233},
+ {0.476226, 0.303801, 0.825175},
+ {0.649448, 0.399769 , 0.64684},
+ {0.678913, 0.334692, 0.653497},
+ {0.619186, 0.361592, 0.697037},
+ {0.760406, 0.341435, 0.552454},
+ {0.734794, 0.305212, 0.605741},
+ {0.705236, 0.267381, 0.65662},
+ {0.672319 , 0.2289, 0.703983},
+ {0.504209, 0.237229, 0.830359},
+ {0.529135, 0.172532, 0.830812},
+ {0.634579, 0.187432, 0.749786},
+ {0.594895, 0.147414, 0.79017},
+ {0.551859, 0.106494, 0.82711},
+ { 0.583691, 0.322141, 0.745338},
+ {0.610926, 0.25518, 0.749435},
+ {0.545109, 0.280319, 0.790112},
+ {0.536784, 0.735011, 0.414273},
+ {0.628313, 0.619242, 0.470917},
+ {0.584716, 0.678977, 0.443957 },
+ {0.51797, 0.704471, 0.485208},
+ {0.496441, 0.669612, 0.552418},
+ {0.704471, 0.485208, 0.51797},
+ {0.669612, 0.552418, 0.496441},
+ {0.735011, 0.414273, 0.536784},
+ {0.678977, 0.443957 , 0.584716},
+ {0.619242, 0.470917, 0.628313},
+ {0.470917, 0.628313, 0.619242},
+ {0.443957, 0.584716, 0.678977},
+ {0.552418, 0.496441, 0.669612},
+ {0.485208, 0.51797, 0.704471},
+ {0.414273 , 0.536784, 0.735011},
+ {0.607478, 0.581952, 0.54065},
+ {0.581952, 0.54065, 0.607478},
+ {0.54065, 0.607478, 0.581952},
+ {0.106494, 0.82711, -0.551859},
+ {0.187432, 0.749786, -0.634579},
+ { 0.147414, 0.79017, -0.594895},
+ {0.172532, 0.830812, -0.529135},
+ {0.237229, 0.830359, -0.504209},
+ {0.267381, 0.65662, -0.705236},
+ {0.2289, 0.703983, -0.672319},
+ {0.341435, 0.552454, -0.760406 },
+ {0.305212, 0.605741, -0.734794},
+ {0.334692, 0.653497, -0.678913},
+ {0.399769, 0.64684, -0.649448},
+ {0.361592, 0.697037, -0.619186},
+ {0.303801, 0.825175, -0.476226},
+ {0.366027, 0.816233 , -0.446977},
+ {0.38673, 0.737712, -0.553372},
+ {0.448259, 0.725299, -0.522499},
+ {0.408286, 0.772575, -0.48624},
+ {0.427135, 0.803016, -0.415597},
+ {0.485712, 0.785899, -0.382683},
+ {0.25518 , 0.749435, -0.610926},
+ {0.322141, 0.745338, -0.583691},
+ {0.280319, 0.790112, -0.545109},
+ {0.415597, 0.427135, -0.803016},
+ {0.382683, 0.485712, -0.785899},
+ {0.476226, 0.303801, -0.825175 },
+ {0.446977, 0.366027, -0.816233},
+ {0.48624, 0.408286, -0.772575},
+ {0.553372, 0.38673, -0.737712},
+ {0.522499, 0.448259, -0.725299},
+ {0.529135, 0.172532, -0.830812},
+ {0.504209, 0.237229 , -0.830359},
+ {0.551859, 0.106494, -0.82711},
+ {0.594895, 0.147414, -0.79017},
+ {0.634579, 0.187432, -0.749786},
+ {0.619186, 0.361592, -0.697037},
+ {0.678913, 0.334692, -0.653497},
+ {0.649448 , 0.399769, -0.64684},
+ {0.672319, 0.2289, -0.703983},
+ {0.705236, 0.267381, -0.65662},
+ {0.734794, 0.305212, -0.605741},
+ {0.760406, 0.341435, -0.552454},
+ {0.545109, 0.280319, -0.790112},
+ {0.610926, 0.25518, -0.749435},
+ {0.583691, 0.322141, -0.745338},
+ {0.552454, 0.760406, -0.341435},
+ {0.605741, 0.734794, -0.305212},
+ {0.64684, 0.649448, -0.399769},
+ {0.697037, 0.619186 , -0.361592},
+ {0.653497, 0.678913, -0.334692},
+ {0.65662, 0.705236, -0.267381},
+ {0.703983, 0.672319, -0.2289},
+ {0.725299, 0.522499, -0.448259},
+ {0.772575, 0.48624, -0.408286},
+ {0.737712 , 0.553372, -0.38673},
+ {0.785899, 0.382683, -0.485712},
+ {0.803016, 0.415597, -0.427135},
+ {0.816233, 0.446977, -0.366027},
+ {0.825175, 0.476226, -0.303801},
+ {0.749786, 0.634579, -0.187432},
+ {0.79017, 0.594895, -0.147414},
+ {0.830359, 0.504209, -0.237229},
+ {0.830812, 0.529135, -0.172532},
+ {0.82711, 0.551859, -0.106494},
+ {0.745338, 0.583691, -0.322141},
+ {0.790112, 0.545109 , -0.280319},
+ {0.749435, 0.610926, -0.25518},
+ {0.414273, 0.536784, -0.735011},
+ {0.552418, 0.496441, -0.669612},
+ {0.485208, 0.51797, -0.704471},
+ {0.443957, 0.584716, -0.678977},
+ {0.470917 , 0.628313, -0.619242},
+ {0.678977, 0.443957, -0.584716},
+ {0.619242, 0.470917, -0.628313},
+ {0.735011, 0.414273, -0.536784},
+ {0.704471, 0.485208, -0.51797},
+ {0.669612, 0.552418, -0.496441},
+ {0.496441, 0.669612, -0.552418},
+ {0.51797, 0.704471, -0.485208},
+ {0.628313, 0.619242, -0.470917},
+ {0.584716, 0.678977, -0.443957},
+ {0.536784, 0.735011, -0.414273},
+ {0.581952, 0.54065 , -0.607478},
+ {0.607478, 0.581952, -0.54065},
+ {0.54065, 0.607478, -0.581952},
+ {0.551859, -0.106494, 0.82711},
+ {0.634579, -0.187432, 0.749786},
+ {0.594895, -0.147414, 0.79017},
+ {0.529135 , -0.172532, 0.830812},
+ {0.504209, -0.237229, 0.830359},
+ {0.705236, -0.267381, 0.65662},
+ {0.672319, -0.2289, 0.703983},
+ {0.760406, -0.341435, 0.552454},
+ {0.734794, -0.305212, 0.605741},
+ {0.678913, -0.334692, 0.653497},
+ {0.649448, -0.399769, 0.64684},
+ {0.619186, -0.361592, 0.697037},
+ {0.476226, -0.303801, 0.825175},
+ {0.446977, -0.366027, 0.816233},
+ {0.553372, -0.38673 , 0.737712},
+ {0.522499, -0.448259, 0.725299},
+ {0.48624, -0.408286, 0.772575},
+ {0.415597, -0.427135, 0.803016},
+ {0.382683, -0.485712, 0.785899},
+ {0.610926, -0.25518, 0.749435},
+ {0.583691 , -0.322141, 0.745338},
+ {0.545109, -0.280319, 0.790112},
+ {0.803016, -0.415597, 0.427135},
+ {0.785899, -0.382683, 0.485712},
+ {0.825175, -0.476226, 0.303801},
+ {0.816233, -0.446977, 0.366027 },
+ {0.772575, -0.48624, 0.408286},
+ {0.737712, -0.553372, 0.38673},
+ {0.725299, -0.522499, 0.448259},
+ {0.830812, -0.529135, 0.172532},
+ {0.830359, -0.504209, 0.237229},
+ {0.82711, -0.551859 , 0.106494},
+ {0.79017, -0.594895, 0.147414},
+ {0.749786, -0.634579, 0.187432},
+ {0.697037, -0.619186, 0.361592},
+ {0.653497, -0.678913, 0.334692},
+ {0.64684, -0.649448, 0.399769},
+ {0.703983 , -0.672319, 0.2289},
+ {0.65662, -0.705236, 0.267381},
+ {0.605741, -0.734794, 0.305212},
+ {0.552454, -0.760406, 0.341435},
+ {0.790112, -0.545109, 0.280319},
+ {0.749435, -0.610926, 0.25518},
+ {0.745338, -0.583691, 0.322141},
+ {0.341435, -0.552454, 0.760406},
+ {0.305212, -0.605741, 0.734794},
+ {0.399769, -0.64684, 0.649448},
+ {0.361592, -0.697037, 0.619186},
+ {0.334692, -0.653497 , 0.678913},
+ {0.267381, -0.65662, 0.705236},
+ {0.2289, -0.703983, 0.672319},
+ {0.448259, -0.725299, 0.522499},
+ {0.408286, -0.772575, 0.48624},
+ {0.38673, -0.737712, 0.553372},
+ {0.485712 , -0.785899, 0.382683},
+ {0.427135, -0.803016, 0.415597},
+ {0.366027, -0.816233, 0.446977},
+ {0.303801, -0.825175, 0.476226},
+ {0.187432, -0.749786, 0.634579},
+ {0.147414, -0.79017, 0.594895},
+ {0.237229, -0.830359, 0.504209},
+ {0.172532, -0.830812, 0.529135},
+ {0.106494, -0.82711, 0.551859},
+ {0.322141, -0.745338, 0.583691},
+ {0.280319, -0.790112, 0.545109},
+ {0.25518, -0.749435 , 0.610926},
+ {0.735011, -0.414273, 0.536784},
+ {0.669612, -0.552418, 0.496441},
+ {0.704471, -0.485208, 0.51797},
+ {0.678977, -0.443957, 0.584716},
+ {0.619242, -0.470917, 0.628313},
+ {0.584716 , -0.678977, 0.443957},
+ {0.628313, -0.619242, 0.470917},
+ {0.536784, -0.735011, 0.414273},
+ {0.51797, -0.704471, 0.485208},
+ {0.496441, -0.669612, 0.552418},
+ {0.552418, -0.496441, 0.669612},
+ {0.485208, -0.51797, 0.704471},
+ {0.470917, -0.628313, 0.619242},
+ {0.443957, -0.584716, 0.678977},
+ {0.414273, -0.536784, 0.735011},
+ {0.607478, -0.581952, 0.54065},
+ {0.54065, -0.607478 , 0.581952},
+ {0.581952, -0.54065, 0.607478},
+ {0.551859, -0.106494, -0.82711},
+ {0.504209, -0.237229, -0.830359},
+ {0.529135, -0.172532, -0.830812},
+ {0.594895, -0.147414, -0.79017},
+ { 0.634579, -0.187432, -0.749786},
+ {0.446977, -0.366027, -0.816233},
+ {0.476226, -0.303801, -0.825175},
+ {0.382683, -0.485712, -0.785899},
+ {0.415597, -0.427135, -0.803016},
+ {0.48624, -0.408286 , -0.772575},
+ {0.522499, -0.448259, -0.725299},
+ {0.553372, -0.38673, -0.737712},
+ {0.672319, -0.2289, -0.703983},
+ {0.705236, -0.267381, -0.65662},
+ {0.619186, -0.361592, -0.697037},
+ { 0.649448, -0.399769, -0.64684},
+ {0.678913, -0.334692, -0.653497},
+ {0.734794, -0.305212, -0.605741},
+ {0.760406, -0.341435, -0.552454},
+ {0.545109, -0.280319, -0.790112},
+ {0.583691, -0.322141 , -0.745338},
+ {0.610926, -0.25518, -0.749435},
+ {0.305212, -0.605741, -0.734794},
+ {0.341435, -0.552454, -0.760406},
+ {0.2289, -0.703983, -0.672319},
+ {0.267381, -0.65662, -0.705236},
+ { 0.334692, -0.653497, -0.678913},
+ {0.361592, -0.697037, -0.619186},
+ {0.399769, -0.64684, -0.649448},
+ {0.147414, -0.79017, -0.594895},
+ {0.187432, -0.749786, -0.634579},
+ {0.106494, -0.82711 , -0.551859},
+ {0.172532, -0.830812, -0.529135},
+ {0.237229, -0.830359, -0.504209},
+ {0.38673, -0.737712, -0.553372},
+ {0.408286, -0.772575, -0.48624},
+ {0.448259, -0.725299, -0.522499},
+ { 0.303801, -0.825175, -0.476226},
+ {0.366027, -0.816233, -0.446977},
+ {0.427135, -0.803016, -0.415597},
+ {0.485712, -0.785899, -0.382683},
+ {0.25518, -0.749435, -0.610926},
+ {0.280319, -0.790112 , -0.545109},
+ {0.322141, -0.745338, -0.583691},
+ {0.785899, -0.382683, -0.485712},
+ {0.803016, -0.415597, -0.427135},
+ {0.725299, -0.522499, -0.448259},
+ {0.737712, -0.553372, -0.38673},
+ {0.772575, -0.48624, -0.408286},
+ {0.816233, -0.446977, -0.366027},
+ {0.825175, -0.476226, -0.303801},
+ {0.64684, -0.649448, -0.399769},
+ {0.653497, -0.678913, -0.334692},
+ {0.697037, -0.619186 , -0.361592},
+ {0.552454, -0.760406, -0.341435},
+ {0.605741, -0.734794, -0.305212},
+ {0.65662, -0.705236, -0.267381},
+ {0.703983, -0.672319, -0.2289},
+ {0.830359, -0.504209, -0.237229},
+ { 0.830812, -0.529135, -0.172532},
+ {0.749786, -0.634579, -0.187432},
+ {0.79017, -0.594895, -0.147414},
+ {0.82711, -0.551859, -0.106494},
+ {0.745338, -0.583691, -0.322141},
+ {0.749435, -0.610926 , -0.25518},
+ {0.790112, -0.545109, -0.280319},
+ {0.414273, -0.536784, -0.735011},
+ {0.470917, -0.628313, -0.619242},
+ {0.443957, -0.584716, -0.678977},
+ {0.485208, -0.51797, -0.704471},
+ { 0.552418, -0.496441, -0.669612},
+ {0.51797, -0.704471, -0.485208},
+ {0.496441, -0.669612, -0.552418},
+ {0.536784, -0.735011, -0.414273},
+ {0.584716, -0.678977, -0.443957},
+ {0.628313, -0.619242 , -0.470917},
+ {0.619242, -0.470917, -0.628313},
+ {0.678977, -0.443957, -0.584716},
+ {0.669612, -0.552418, -0.496441},
+ {0.704471, -0.485208, -0.51797},
+ {0.735011, -0.414273, -0.536784},
+ {0.54065, -0.607478, -0.581952},
+ {0.607478, -0.581952, -0.54065},
+ {0.581952, -0.54065, -0.607478},
+ {-0.551859, 0.106494, 0.82711},
+ {-0.634579, 0.187432, 0.749786},
+ {-0.594895, 0.147414 , 0.79017},
+ {-0.529135, 0.172532, 0.830812},
+ {-0.504209, 0.237229, 0.830359},
+ {-0.705236, 0.267381, 0.65662},
+ {-0.672319, 0.2289, 0.703983},
+ {-0.760406, 0.341435, 0.552454},
+ {-0.734794 , 0.305212, 0.605741},
+ {-0.678913, 0.334692, 0.653497},
+ {-0.649448, 0.399769, 0.64684},
+ {-0.619186, 0.361592, 0.697037},
+ {-0.476226, 0.303801, 0.825175},
+ {-0.446977, 0.366027, 0.816233},
+ {-0.553372, 0.38673, 0.737712},
+ {-0.522499, 0.448259, 0.725299},
+ {-0.48624, 0.408286, 0.772575},
+ {-0.415597, 0.427135, 0.803016},
+ {-0.382683, 0.485712, 0.785899},
+ {-0.610926, 0.25518 , 0.749435},
+ {-0.583691, 0.322141, 0.745338},
+ {-0.545109, 0.280319, 0.790112},
+ {-0.803016, 0.415597, 0.427135},
+ {-0.785899, 0.382683, 0.485712},
+ {-0.825175, 0.476226, 0.303801},
+ {- 0.816233, 0.446977, 0.366027},
+ {-0.772575, 0.48624, 0.408286},
+ {-0.737712, 0.553372, 0.38673},
+ {-0.725299, 0.522499, 0.448259},
+ {-0.830812, 0.529135, 0.172532},
+ {-0.830359, 0.504209, 0.237229 },
+ {-0.82711, 0.551859, 0.106494},
+ {-0.79017, 0.594895, 0.147414},
+ {-0.749786, 0.634579, 0.187432},
+ {-0.697037, 0.619186, 0.361592},
+ {-0.653497, 0.678913, 0.334692},
+ {-0.64684, 0.649448 , 0.399769},
+ {-0.703983, 0.672319, 0.2289},
+ {-0.65662, 0.705236, 0.267381},
+ {-0.605741, 0.734794, 0.305212},
+ {-0.552454, 0.760406, 0.341435},
+ {-0.790112, 0.545109, 0.280319},
+ {-0.749435 , 0.610926, 0.25518},
+ {-0.745338, 0.583691, 0.322141},
+ {-0.341435, 0.552454, 0.760406},
+ {-0.305212, 0.605741, 0.734794},
+ {-0.399769, 0.64684, 0.649448},
+ {-0.361592, 0.697037, 0.619186},
+ {-0.334692, 0.653497, 0.678913},
+ {-0.267381, 0.65662, 0.705236},
+ {-0.2289, 0.703983, 0.672319},
+ {-0.448259, 0.725299, 0.522499},
+ {-0.408286, 0.772575, 0.48624},
+ {-0.38673, 0.737712, 0.553372},
+ {-0.485712, 0.785899, 0.382683},
+ {-0.427135, 0.803016, 0.415597},
+ {-0.366027, 0.816233, 0.446977},
+ {-0.303801, 0.825175, 0.476226},
+ {-0.187432, 0.749786, 0.634579},
+ {-0.147414 , 0.79017, 0.594895},
+ {-0.237229, 0.830359, 0.504209},
+ {-0.172532, 0.830812, 0.529135},
+ {-0.106494, 0.82711, 0.551859},
+ {-0.322141, 0.745338, 0.583691},
+ {-0.280319, 0.790112, 0.545109},
+ {-0.25518, 0.749435, 0.610926},
+ {-0.735011, 0.414273, 0.536784},
+ {-0.669612, 0.552418, 0.496441},
+ {-0.704471, 0.485208, 0.51797},
+ {-0.678977, 0.443957, 0.584716},
+ {-0.619242, 0.470917 , 0.628313},
+ {-0.584716, 0.678977, 0.443957},
+ {-0.628313, 0.619242, 0.470917},
+ {-0.536784, 0.735011, 0.414273},
+ {-0.51797, 0.704471, 0.485208},
+ {-0.496441, 0.669612, 0.552418},
+ {- 0.552418, 0.496441, 0.669612},
+ {-0.485208, 0.51797, 0.704471},
+ {-0.470917, 0.628313, 0.619242},
+ {-0.443957, 0.584716, 0.678977},
+ {-0.414273, 0.536784, 0.735011},
+ {-0.607478, 0.581952, 0.54065 },
+ {-0.54065, 0.607478, 0.581952},
+ {-0.581952, 0.54065, 0.607478},
+ {-0.551859, 0.106494, -0.82711},
+ {-0.504209, 0.237229, -0.830359},
+ {-0.529135, 0.172532, -0.830812},
+ {-0.594895, 0.147414, -0.79017},
+ {-0.634579, 0.187432, -0.749786},
+ {-0.446977, 0.366027, -0.816233},
+ {-0.476226, 0.303801, -0.825175},
+ {-0.382683, 0.485712, -0.785899},
+ {-0.415597, 0.427135, -0.803016 },
+ {-0.48624, 0.408286, -0.772575},
+ {-0.522499, 0.448259, -0.725299},
+ {-0.553372, 0.38673, -0.737712},
+ {-0.672319, 0.2289, -0.703983},
+ {-0.705236, 0.267381, -0.65662},
+ {-0.619186, 0.361592, -0.697037},
+ {-0.649448, 0.399769, -0.64684},
+ {-0.678913, 0.334692, -0.653497},
+ {-0.734794, 0.305212, -0.605741},
+ {-0.760406, 0.341435, -0.552454},
+ {-0.545109, 0.280319, -0.790112 },
+ {-0.583691, 0.322141, -0.745338},
+ {-0.610926, 0.25518, -0.749435},
+ {-0.305212, 0.605741, -0.734794},
+ {-0.341435, 0.552454, -0.760406},
+ {-0.2289, 0.703983, -0.672319},
+ {-0.267381 , 0.65662, -0.705236},
+ {-0.334692, 0.653497, -0.678913},
+ {-0.361592, 0.697037, -0.619186},
+ {-0.399769, 0.64684, -0.649448},
+ {-0.147414, 0.79017, -0.594895},
+ {-0.187432, 0.749786, -0.634579 },
+ {-0.106494, 0.82711, -0.551859},
+ {-0.172532, 0.830812, -0.529135},
+ {-0.237229, 0.830359, -0.504209},
+ {-0.38673, 0.737712, -0.553372},
+ {-0.408286, 0.772575, -0.48624},
+ {-0.448259 , 0.725299, -0.522499},
+ {-0.303801, 0.825175, -0.476226},
+ {-0.366027, 0.816233, -0.446977},
+ {-0.427135, 0.803016, -0.415597},
+ {-0.485712, 0.785899, -0.382683},
+ {-0.25518, 0.749435, -0.610926 },
+ {-0.280319, 0.790112, -0.545109},
+ {-0.322141, 0.745338, -0.583691},
+ {-0.785899, 0.382683, -0.485712},
+ {-0.803016, 0.415597, -0.427135},
+ {-0.725299, 0.522499, -0.448259},
+ {-0.737712 , 0.553372, -0.38673},
+ {-0.772575, 0.48624, -0.408286},
+ {-0.816233, 0.446977, -0.366027},
+ {-0.825175, 0.476226, -0.303801},
+ {-0.64684, 0.649448, -0.399769},
+ {-0.653497, 0.678913, -0.334692 },
+ {-0.697037, 0.619186, -0.361592},
+ {-0.552454, 0.760406, -0.341435},
+ {-0.605741, 0.734794, -0.305212},
+ {-0.65662, 0.705236, -0.267381},
+ {-0.703983, 0.672319, -0.2289},
+ {-0.830359 , 0.504209, -0.237229},
+ {-0.830812, 0.529135, -0.172532},
+ {-0.749786, 0.634579, -0.187432},
+ {-0.79017, 0.594895, -0.147414},
+ {-0.82711, 0.551859, -0.106494},
+ {-0.745338, 0.583691, -0.322141 },
+ {-0.749435, 0.610926, -0.25518},
+ {-0.790112, 0.545109, -0.280319},
+ {-0.414273, 0.536784, -0.735011},
+ {-0.470917, 0.628313, -0.619242},
+ {-0.443957, 0.584716, -0.678977},
+ {-0.485208 , 0.51797, -0.704471},
+ {-0.552418, 0.496441, -0.669612},
+ {-0.51797, 0.704471, -0.485208},
+ {-0.496441, 0.669612, -0.552418},
+ {-0.536784, 0.735011, -0.414273},
+ {-0.584716, 0.678977, -0.443957 },
+ {-0.628313, 0.619242, -0.470917},
+ {-0.619242, 0.470917, -0.628313},
+ {-0.678977, 0.443957, -0.584716},
+ {-0.669612, 0.552418, -0.496441},
+ {-0.704471, 0.485208, -0.51797},
+ {-0.735011 , 0.414273, -0.536784},
+ {-0.54065, 0.607478, -0.581952},
+ {-0.607478, 0.581952, -0.54065},
+ {-0.581952, 0.54065, -0.607478},
+ {-0.551859, -0.106494, 0.82711},
+ {-0.504209, -0.237229, 0.830359 },
+ {-0.529135, -0.172532, 0.830812},
+ {-0.594895, -0.147414, 0.79017},
+ {-0.634579, -0.187432, 0.749786},
+ {-0.446977, -0.366027, 0.816233},
+ {-0.476226, -0.303801, 0.825175},
+ {-0.382683 , -0.485712, 0.785899},
+ {-0.415597, -0.427135, 0.803016},
+ {-0.48624, -0.408286, 0.772575},
+ {-0.522499, -0.448259, 0.725299},
+ {-0.553372, -0.38673, 0.737712},
+ {-0.672319, -0.2289, 0.703983 },
+ {-0.705236, -0.267381, 0.65662},
+ {-0.619186, -0.361592, 0.697037},
+ {-0.649448, -0.399769, 0.64684},
+ {-0.678913, -0.334692, 0.653497},
+ {-0.734794, -0.305212, 0.605741},
+ {-0.760406 , -0.341435, 0.552454},
+ {-0.545109, -0.280319, 0.790112},
+ {-0.583691, -0.322141, 0.745338},
+ {-0.610926, -0.25518, 0.749435},
+ {-0.305212, -0.605741, 0.734794},
+ {-0.341435, -0.552454, 0.760406 },
+ {-0.2289, -0.703983, 0.672319},
+ {-0.267381, -0.65662, 0.705236},
+ {-0.334692, -0.653497, 0.678913},
+ {-0.361592, -0.697037, 0.619186},
+ {-0.399769, -0.64684, 0.649448},
+ {-0.147414 , -0.79017, 0.594895},
+ {-0.187432, -0.749786, 0.634579},
+ {-0.106494, -0.82711, 0.551859},
+ {-0.172532, -0.830812, 0.529135},
+ {-0.237229, -0.830359, 0.504209},
+ {-0.38673, -0.737712, 0.553372 },
+ {-0.408286, -0.772575, 0.48624},
+ {-0.448259, -0.725299, 0.522499},
+ {-0.303801, -0.825175, 0.476226},
+ {-0.366027, -0.816233, 0.446977},
+ {-0.427135, -0.803016, 0.415597},
+ {-0.485712 , -0.785899, 0.382683},
+ {-0.25518, -0.749435, 0.610926},
+ {-0.280319, -0.790112, 0.545109},
+ {-0.322141, -0.745338, 0.583691},
+ {-0.785899, -0.382683, 0.485712},
+ {-0.803016, -0.415597, 0.427135 },
+ {-0.725299, -0.522499, 0.448259},
+ {-0.737712, -0.553372, 0.38673},
+ {-0.772575, -0.48624, 0.408286},
+ {-0.816233, -0.446977, 0.366027},
+ {-0.825175, -0.476226, 0.303801},
+ {-0.64684 , -0.649448, 0.399769},
+ {-0.653497, -0.678913, 0.334692},
+ {-0.697037, -0.619186, 0.361592},
+ {-0.552454, -0.760406, 0.341435},
+ {-0.605741, -0.734794, 0.305212},
+ {-0.65662, -0.705236, 0.267381 },
+ {-0.703983, -0.672319, 0.2289},
+ {-0.830359, -0.504209, 0.237229},
+ {-0.830812, -0.529135, 0.172532},
+ {-0.749786, -0.634579, 0.187432},
+ {-0.79017, -0.594895, 0.147414},
+ {-0.82711 , -0.551859, 0.106494},
+ {-0.745338, -0.583691, 0.322141},
+ {-0.749435, -0.610926, 0.25518},
+ {-0.790112, -0.545109, 0.280319},
+ {-0.414273, -0.536784, 0.735011},
+ {-0.470917, -0.628313, 0.619242 },
+ {-0.443957, -0.584716, 0.678977},
+ {-0.485208, -0.51797, 0.704471},
+ {-0.552418, -0.496441, 0.669612},
+ {-0.51797, -0.704471, 0.485208},
+ {-0.496441, -0.669612, 0.552418},
+ {-0.536784 , -0.735011, 0.414273},
+ {-0.584716, -0.678977, 0.443957},
+ {-0.628313, -0.619242, 0.470917},
+ {-0.619242, -0.470917, 0.628313},
+ {-0.678977, -0.443957, 0.584716},
+ {-0.669612, -0.552418, 0.496441 },
+ {-0.704471, -0.485208, 0.51797},
+ {-0.735011, -0.414273, 0.536784},
+ {-0.54065, -0.607478, 0.581952},
+ {-0.607478, -0.581952, 0.54065},
+ {-0.581952, -0.54065, 0.607478},
+ {-0.551859 , -0.106494, -0.82711},
+ {-0.634579, -0.187432, -0.749786},
+ {-0.594895, -0.147414, -0.79017},
+ {-0.529135, -0.172532, -0.830812},
+ {-0.504209, -0.237229, -0.830359},
+ {-0.705236, -0.267381, - 0.65662},
+ {-0.672319, -0.2289, -0.703983},
+ {-0.760406, -0.341435, -0.552454},
+ {-0.734794, -0.305212, -0.605741},
+ {-0.678913, -0.334692, -0.653497},
+ {-0.649448, -0.399769, -0.64684},
+ {- 0.619186, -0.361592, -0.697037},
+ {-0.476226, -0.303801, -0.825175},
+ {-0.446977, -0.366027, -0.816233},
+ {-0.553372, -0.38673, -0.737712},
+ {-0.522499, -0.448259, -0.725299},
+ {-0.48624, -0.408286 , -0.772575},
+ {-0.415597, -0.427135, -0.803016},
+ {-0.382683, -0.485712, -0.785899},
+ {-0.610926, -0.25518, -0.749435},
+ {-0.583691, -0.322141, -0.745338},
+ {-0.545109, -0.280319, -0.790112},
+ {-0.803016, -0.415597, -0.427135},
+ {-0.785899, -0.382683, -0.485712},
+ {-0.825175, -0.476226, -0.303801},
+ {-0.816233, -0.446977, -0.366027},
+ {-0.772575, -0.48624, -0.408286},
+ {-0.737712 , -0.553372, -0.38673},
+ {-0.725299, -0.522499, -0.448259},
+ {-0.830812, -0.529135, -0.172532},
+ {-0.830359, -0.504209, -0.237229},
+ {-0.82711, -0.551859, -0.106494},
+ {-0.79017, -0.594895, - 0.147414},
+ {-0.749786, -0.634579, -0.187432},
+ {-0.697037, -0.619186, -0.361592},
+ {-0.653497, -0.678913, -0.334692},
+ {-0.64684, -0.649448, -0.399769},
+ {-0.703983, -0.672319, -0.2289},
+ {-0.65662, -0.705236, -0.267381},
+ {-0.605741, -0.734794, -0.305212},
+ {-0.552454, -0.760406, -0.341435},
+ {-0.790112, -0.545109, -0.280319},
+ {-0.749435, -0.610926, -0.25518},
+ {-0.745338 , -0.583691, -0.322141},
+ {-0.341435, -0.552454, -0.760406},
+ {-0.305212, -0.605741, -0.734794},
+ {-0.399769, -0.64684, -0.649448},
+ {-0.361592, -0.697037, -0.619186},
+ {-0.334692, -0.653497, - 0.678913},
+ {-0.267381, -0.65662, -0.705236},
+ {-0.2289, -0.703983, -0.672319},
+ {-0.448259, -0.725299, -0.522499},
+ {-0.408286, -0.772575, -0.48624},
+ {-0.38673, -0.737712, -0.553372},
+ {- 0.485712, -0.785899, -0.382683},
+ {-0.427135, -0.803016, -0.415597},
+ {-0.366027, -0.816233, -0.446977},
+ {-0.303801, -0.825175, -0.476226},
+ {-0.187432, -0.749786, -0.634579},
+ {-0.147414, - 0.79017, -0.594895},
+ {-0.237229, -0.830359, -0.504209},
+ {-0.172532, -0.830812, -0.529135},
+ {-0.106494, -0.82711, -0.551859},
+ {-0.322141, -0.745338, -0.583691},
+ {-0.280319, -0.790112, -0.545109 },
+ {-0.25518, -0.749435, -0.610926},
+ {-0.735011, -0.414273, -0.536784},
+ {-0.669612, -0.552418, -0.496441},
+ {-0.704471, -0.485208, -0.51797},
+ {-0.678977, -0.443957, -0.584716},
+ {-0.619242 , -0.470917, -0.628313},
+ {-0.584716, -0.678977, -0.443957},
+ {-0.628313, -0.619242, -0.470917},
+ {-0.536784, -0.735011, -0.414273},
+ {-0.51797, -0.704471, -0.485208},
+ {-0.496441, -0.669612, - 0.552418},
+ {-0.552418, -0.496441, -0.669612},
+ {-0.485208, -0.51797, -0.704471},
+ {-0.470917, -0.628313, -0.619242},
+ {-0.443957, -0.584716, -0.678977},
+ {-0.414273, -0.536784, -0.735011},
+ {-0.607478, -0.581952, -0.54065},
+ {-0.54065, -0.607478, -0.581952},
+ {-0.581952, -0.54065, -0.607478}
+ };
+ TractOrientationContainerType::Pointer sdcontainerptr =
+ TractOrientationContainerType::New();
+
+ for(unsigned int i = 0; iInsertElement(i, dir);
+ }
+
+ this->SetSampleDirections( sdcontainerptr );
+}
+
+}
diff --git a/Modules/DiffusionImaging/Tractography/itkStochasticTractographyFilter.h b/Modules/DiffusionImaging/Tractography/itkStochasticTractographyFilter.h
new file mode 100644
index 0000000000..cc5ffbacaa
--- /dev/null
+++ b/Modules/DiffusionImaging/Tractography/itkStochasticTractographyFilter.h
@@ -0,0 +1,286 @@
+#ifndef __itkStochasticTractographyFilter_h__
+#define __itkStochasticTractographyFilter_h__
+
+#include "itkImageToImageFilter.h"
+#include "vnl/vnl_random.h"
+#include "vnl/vnl_vector_fixed.h"
+#include "vnl/vnl_matrix.h"
+#include "itkArray.h"
+#include "itkVectorContainer.h"
+#include "vnl/algo/vnl_qr.h"
+#include "itkVariableLengthVector.h"
+#include "StochasticTracking/itkSlowPolyLineParametricPath.h"
+#include "itkSimpleFastMutexLock.h"
+#include "itkRealTimeClock.h"
+#include "itkDiffusionTensor3D.h"
+#include
+
+namespace itk{
+
+/**Types for Probability Distribution **/
+typedef Image< Array< double >, 3 > ProbabilityDistributionImageType;
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage,
+ class TOutputConnectivityImage >
+class ITK_EXPORT StochasticTractographyFilter :
+ public ImageToImageFilter< TInputDWIImage,
+ TOutputConnectivityImage >{
+public:
+ typedef StochasticTractographyFilter Self;
+ typedef ImageToImageFilter< TInputDWIImage,
+ TOutputConnectivityImage > Superclass;
+ typedef SmartPointer< Self > Pointer;
+ typedef SmartPointer< const Self > ConstPointer;
+
+ itkNewMacro(Self);
+ itkTypeMacro( StochasticTractographyFilter,
+ ImageToImageFilter );
+
+ /** Types for the DWI Input Image **/
+ typedef TInputDWIImage InputDWIImageType;
+
+ /** Types for the Connectivity Output Image**/
+ typedef TOutputConnectivityImage OutputConnectivityImageType;
+
+ /** Types for the Mask Image **/
+ typedef TInputWhiteMatterProbabilityImage InputWhiteMatterProbabilityImageType;
+
+ /** Tract Types **/
+ typedef SlowPolyLineParametricPath< 3 > TractType;
+
+ /** Types for the TractContainer **/
+ typedef VectorContainer< unsigned int, typename TractType::Pointer >
+ TractContainerType;
+
+ /** Types for Tensor Output Image **/
+ typedef Image< DiffusionTensor3D< double >, 3 > OutputTensorImageType;
+
+ /** Types for the Image-wide Magnetic Field Gradient Directions **/
+ typedef VectorContainer< unsigned int, vnl_vector_fixed< double, 3 > >
+ GradientDirectionContainerType;
+
+ /** Types for the Image-wide bValues **/
+ typedef double bValueType;
+ typedef VectorContainer< unsigned int, bValueType > bValueContainerType;
+
+ /** Types for the Measurement Frame of the Gradients **/
+ typedef vnl_matrix_fixed< double, 3, 3 > MeasurementFrameType;
+
+ /** Type for the sample directions **/
+ typedef VectorContainer< unsigned int, vnl_vector_fixed< double, 3 > >
+ TractOrientationContainerType;
+
+ /** the number of Tracts to generate **/
+ itkSetMacro( TotalTracts, unsigned int);
+ itkGetMacro( TotalTracts, unsigned int);
+
+ /** the maximum length of Tract **/
+ itkSetMacro( MaxTractLength, unsigned int );
+ itkGetMacro( MaxTractLength, unsigned int );
+
+ /** Set/Get bvalues **/
+ itkSetConstObjectMacro( bValues, bValueContainerType );
+ itkGetConstObjectMacro( bValues, bValueContainerType );
+
+ /** Set/Get of gradient directions **/
+ itkSetConstObjectMacro( Gradients, GradientDirectionContainerType );
+ itkGetConstObjectMacro( Gradients, GradientDirectionContainerType );
+
+ /** Set/Get the White Matter Probability Input image **/
+ /* At each voxel specifies the probability of a mylinated fiber existing
+ at that location. This probability is interpreted to be the probability
+ that a fiber tract passes through that region.
+ */
+ itkSetInputMacro(WhiteMatterProbabilityImage, InputWhiteMatterProbabilityImageType, 1);
+ itkGetInputMacro(WhiteMatterProbabilityImage, InputWhiteMatterProbabilityImageType, 1);
+
+ //overide the built in set input function
+ //we need to create a new cache everytime we change the input image
+ //but we need to preserve it when the input image is the same
+ void SetInput( typename InputDWIImageType::Pointer dwiimagePtr ){
+ Superclass::SetInput( dwiimagePtr );
+ //update the likelihood cache
+ this->m_LikelihoodCachePtr = ProbabilityDistributionImageType::New();
+ this->m_LikelihoodCachePtr->CopyInformation( this->GetInput() );
+ this->m_LikelihoodCachePtr->SetBufferedRegion( this->GetInput()->GetBufferedRegion() );
+ this->m_LikelihoodCachePtr->SetRequestedRegion( this->GetInput()->GetRequestedRegion() );
+ this->m_LikelihoodCachePtr->Allocate();
+ this->m_CurrentLikelihoodCacheElements = 0;
+ //update the likelihoodcache mutex image
+ this->m_LikelihoodCacheMutexImagePtr = LikelihoodCacheMutexImageType::New();
+ this->m_LikelihoodCacheMutexImagePtr->CopyInformation( this->GetInput() );
+ this->m_LikelihoodCacheMutexImagePtr->SetBufferedRegion( this->GetInput()->GetBufferedRegion() );
+ this->m_LikelihoodCacheMutexImagePtr->SetRequestedRegion( this->GetInput()->GetRequestedRegion() );
+ this->m_LikelihoodCacheMutexImagePtr->Allocate();
+ }
+
+ /** Set/Get the seed index **/
+ itkSetMacro( SeedIndex, typename InputDWIImageType::IndexType );
+ itkGetMacro( SeedIndex, typename InputDWIImageType::IndexType );
+
+ /** Set/Get the list of directions to sample **/
+ itkSetConstObjectMacro( SampleDirections, TractOrientationContainerType );
+ itkGetConstObjectMacro( SampleDirections, TractOrientationContainerType );
+
+ /** Set/Get the Measurement Frame **/
+ itkSetMacro( MeasurementFrame, MeasurementFrameType );
+ itkGetMacro( MeasurementFrame, MeasurementFrameType );
+
+ /** Set/Get the Maximum Likelihood Cache Size, the max num. of cached voxels **/
+ itkSetMacro( MaxLikelihoodCacheSize, unsigned int );
+ itkGetMacro( MaxLikelihoodCacheSize, unsigned int );
+
+ /** Get the Tracts that are generated **/
+ itkGetObjectMacro( OutputTractContainer, TractContainerType );
+
+ /** Get TensorImage **/
+ itkGetObjectMacro( OutputTensorImage, OutputTensorImageType );
+
+ void GenerateData();
+ void GenerateTractContainerOutput( void );
+ void GenerateTensorImageOutput( void );
+
+protected:
+ /** Convenience Types used only inside the filter **/
+
+ /**Types for the parameters of the Tensor Model **/
+ typedef vnl_vector_fixed< double, 7 > TensorModelParamType;
+
+ /**Types for the parameters of the Constrained Model **/
+ typedef vnl_vector_fixed< double, 6 > ConstrainedModelParamType;
+
+ /**Type to hold generated DWI values**/
+ typedef Image< VariableLengthVector< double >, 3 > DWIVectorImageType;
+
+ /**Types for Probability Distribution **/
+ typedef Image< Array< double >, 3 > ProbabilityDistributionImageType;
+
+ /** Types for the Image of Mutexes of the Likelihood distribution **/
+ typedef Image< SimpleFastMutexLock, 3 > LikelihoodCacheMutexImageType;
+
+ StochasticTractographyFilter();
+ virtual ~StochasticTractographyFilter();
+
+ /** Load the default Sample Directions**/
+ void LoadDefaultSampleDirections( void );
+
+ /** Randomly chose a neighboring pixel weighted on distance **/
+ void ProbabilisticallyInterpolate( vnl_random& randomgenerator,
+ const TractType::ContinuousIndexType& cindex,
+ typename InputDWIImageType::IndexType& index);
+
+ /** Functions and data related to fitting the tensor model at each pixel **/
+ void UpdateGradientDirections(void);
+ void UpdateTensorModelFittingMatrices( void );
+ void CalculateTensorModelParameters( const DWIVectorImageType::PixelType& dwivalues,
+ vnl_diag_matrix& W,
+ TensorModelParamType& tensormodelparams);
+
+ void CalculateConstrainedModelParameters( const TensorModelParamType& tensormodelparams,
+ ConstrainedModelParamType& constrainedmodelparams);
+
+ void CalculateNoiseFreeDWIFromConstrainedModel( const ConstrainedModelParamType& constrainedmodelparams,
+ DWIVectorImageType::PixelType& noisefreedwi);
+
+ void CalculateResidualVariance( const DWIVectorImageType::PixelType& noisydwi,
+ const DWIVectorImageType::PixelType& noisefreedwi,
+ const vnl_diag_matrix< double >& W,
+ const unsigned int numberofparameters,
+ double& residualvariance);
+
+ void CalculateLikelihood( const DWIVectorImageType::PixelType &dwipixel,
+ TractOrientationContainerType::ConstPointer orientations,
+ ProbabilityDistributionImageType::PixelType& likelihood);
+
+ void CalculatePrior( TractOrientationContainerType::Element v_prev,
+ TractOrientationContainerType::ConstPointer orientations,
+ ProbabilityDistributionImageType::PixelType& prior );
+
+ void CalculatePosterior( const ProbabilityDistributionImageType::PixelType& likelihood,
+ const ProbabilityDistributionImageType::PixelType& prior,
+ ProbabilityDistributionImageType::PixelType& posterior);
+
+ void SampleTractOrientation( vnl_random& randomgenerator,
+ const ProbabilityDistributionImageType::PixelType& posterior,
+ TractOrientationContainerType::ConstPointer orientations,
+ TractOrientationContainerType::Element& choosendirection );
+
+ void StochasticTractGeneration( typename InputDWIImageType::ConstPointer dwiimagePtr,
+ typename InputWhiteMatterProbabilityImageType::ConstPointer maskimagePtr,
+ typename InputDWIImageType::IndexType seedindex,
+ unsigned long randomseed,
+ TractType::Pointer tract );
+
+ /** Callback routine used by the threading library. This routine just calls
+ the ThreadedGenerateData method after setting the correct region for this
+ thread. **/
+ static ITK_THREAD_RETURN_TYPE StochasticTractGenerationCallback( void *arg );
+
+ struct StochasticTractGenerationCallbackStruct{
+ Pointer Filter;
+ };
+
+ /** Thread Safe Function to check/update an entry in the likelihood cache **/
+ ProbabilityDistributionImageType::PixelType&
+ AccessLikelihoodCache( typename InputDWIImageType::IndexType index );
+ /** Thread Safe Function to delegate a tract and obtain a randomseed to start tracking **/
+ bool DelegateTract(unsigned long& randomseed);
+ /** Function to write a tract to the connectivity map **/
+ void TractContainerToConnectivityMap(TractContainerType::Pointer tractcontainer);
+ /** Thread Safe Function to store a tract to a TractContainer **/
+ void StoreTract(TractType::Pointer tract);
+ /** Randomly samples the existence of a fiber tract in the current voxel **/
+ bool FiberExistenceTest( vnl_random& randomgenerator,
+ typename InputWhiteMatterProbabilityImageType::ConstPointer wmpimage,
+ typename InputWhiteMatterProbabilityImageType::IndexType index );
+
+
+
+ MeasurementFrameType m_MeasurementFrame;
+
+ LikelihoodCacheMutexImageType::Pointer m_LikelihoodCacheMutexImagePtr;
+ unsigned int m_TotalTracts;
+ unsigned int m_MaxTractLength;
+ GradientDirectionContainerType::ConstPointer m_Gradients;
+
+ GradientDirectionContainerType::Pointer m_TransformedGradients;
+ bValueContainerType::ConstPointer m_bValues;
+
+ typename InputDWIImageType::IndexType m_SeedIndex;
+ TractOrientationContainerType::ConstPointer m_SampleDirections;
+
+ //these will be the same for every pixel in the image so
+ //go ahead and do a QR decomposition to optimize the
+ //LS fitting process for estimating the weighing matrix W
+ //in this case we solve instead:
+ //R*Beta = Q'logPhi
+ vnl_matrix< double >* m_A;
+ vnl_qr< double >* m_Aqr;
+ ProbabilityDistributionImageType::Pointer m_LikelihoodCachePtr;
+
+ unsigned long m_MaxLikelihoodCacheSize; //in Megabytes
+ unsigned long m_MaxLikelihoodCacheElements; //in Elements (Voxels)
+ unsigned long m_CurrentLikelihoodCacheElements;
+ SimpleFastMutexLock m_LikelihoodCacheMutex;
+
+ RealTimeClock::Pointer m_ClockPtr;
+ unsigned int m_TotalDelegatedTracts;
+ SimpleFastMutexLock m_TotalDelegatedTractsMutex;
+
+ //unsigned long m_RandomSeed;
+ SimpleFastMutexLock m_OutputImageMutex;
+ TractContainerType::Pointer m_OutputTractContainer;
+ SimpleFastMutexLock m_OutputTractContainerMutex;
+
+ OutputTensorImageType::Pointer m_OutputTensorImage;
+ vnl_random m_RandomGenerator;
+};
+
+}
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "itkStochasticTractographyFilter.txx"
+#include "StochasticTracking/itkStochasticTractographyFilter_SD.txx"
+#endif
+
+#endif
diff --git a/Modules/DiffusionImaging/Tractography/itkStochasticTractographyFilter.txx b/Modules/DiffusionImaging/Tractography/itkStochasticTractographyFilter.txx
new file mode 100644
index 0000000000..810d70b3c0
--- /dev/null
+++ b/Modules/DiffusionImaging/Tractography/itkStochasticTractographyFilter.txx
@@ -0,0 +1,685 @@
+#include "itkStochasticTractographyFilter.h"
+#include "vnl/vnl_math.h"
+#include "vnl/vnl_matrix_fixed.h"
+#include "vnl/vnl_vector_fixed.h"
+#include "vnl/vnl_matrix.h"
+#include "vnl/vnl_sym_matrix.h"
+#include "vnl/vnl_vector.h"
+#include "vnl/vnl_diag_matrix.h"
+#include "vnl/algo/vnl_qr.h"
+//#include "vnl/algo/vnl_svd.h"
+#include "vnl/algo/vnl_matrix_inverse.h"
+//#include "vnl/algo/vnl_symmetric_eigensystem.h"
+#include "itkSymmetricEigenAnalysis.h"
+#include "vnl/vnl_transpose.h"
+#include "itkVariableSizeMatrix.h"
+#include "itkPathIterator.h"
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIterator.h"
+#include "itkImageRegionConstIteratorWithIndex.h"
+
+namespace itk{
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::StochasticTractographyFilter():
+ m_TotalTracts(0),m_MaxTractLength(0),m_Gradients(NULL), m_TransformedGradients(NULL),m_bValues(NULL),
+ m_SampleDirections(NULL), m_A(NULL), m_Aqr(NULL), m_LikelihoodCachePtr(NULL),
+ m_MaxLikelihoodCacheSize(0), m_CurrentLikelihoodCacheElements(0),
+ m_ClockPtr(NULL), m_TotalDelegatedTracts(0), m_OutputTractContainer(NULL){
+ this->m_SeedIndex[0]=0;
+ this->m_SeedIndex[1]=0;
+ this->m_SeedIndex[2]=0;
+ this->m_MeasurementFrame.set_identity();
+ this->SetNumberOfRequiredInputs(2); //Filter needs a DWI image and a Mask Image
+
+
+ m_ClockPtr = RealTimeClock::New();
+ this->m_RandomGenerator.reseed( ((unsigned long) this->m_ClockPtr->GetTimeStamp()) );
+ //load in default sample directions
+ this->LoadDefaultSampleDirections();
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::~StochasticTractographyFilter(){
+ delete this->m_A;
+ delete this->m_Aqr;
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::ProbabilisticallyInterpolate( vnl_random& randomgenerator,
+ const TractType::ContinuousIndexType& cindex,
+ typename InputDWIImageType::IndexType& index){
+
+ for(int i=0; i<3; i++){
+ if ((vcl_ceil(cindex[i]+vnl_math::eps)-cindex[i]) < randomgenerator.drand64())
+ index[i]=(int)vcl_ceil(cindex[i]);
+ else index[i]=(int)vcl_floor(cindex[i]);
+ }
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::UpdateGradientDirections(void){
+ //the gradient direction is transformed into IJK space
+ //by moving into the image space and then to IJK space
+
+ this->m_TransformedGradients = GradientDirectionContainerType::New();
+ unsigned int N = this->m_Gradients->Size();
+ for(unsigned int i=0; im_MeasurementFrame *
+ this->m_Gradients->GetElement(i);
+
+ /** The correction to LPS space is not neccessary as of itk 3.2 **/
+ //g_i[0] = -g_i[0];
+ //g_i[1] = -g_i[1];
+ g_i = this->GetInput()->GetDirection().GetInverse() * g_i;
+ this->m_TransformedGradients->InsertElement(i, g_i);
+ }
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::UpdateTensorModelFittingMatrices( void ){
+ //std::cout<<"UpdateTensorFittingMatrix\n";
+ //estimate the parameters using linear LS estimation
+ //using convention specified by Salvador
+ //solve for Beta in: logPhi=X*Beta
+ //number of rows of the matrix depends on the number of inputs,
+ //i.e. the number of measurements of the voxel (n)
+ unsigned int N = this->m_TransformedGradients->Size();
+
+ if(this->m_A!=NULL)
+ delete this->m_A;
+ this->m_A = new vnl_matrix< double >(N, 7); //potential memory leak here
+ vnl_matrix< double >& A = *(this->m_A);
+
+ for(unsigned int j=0; j< N ; j++){
+ GradientDirectionContainerType::Element g = m_TransformedGradients->GetElement(j);
+ const bValueType& b_i = m_bValues->GetElement(j);
+
+ A(j,0)=1.0;
+ A(j,1)=-1*b_i*(g[0]*g[0]);
+ A(j,2)=-1*b_i*(g[1]*g[1]);
+ A(j,3)=-1*b_i*(g[2]*g[2]);
+ A(j,4)=-1*b_i*(2*g[0]*g[1]);
+ A(j,5)=-1*b_i*(2*g[0]*g[2]);
+ A(j,6)=-1*b_i*(2*g[1]*g[2]);
+ }
+
+ //Store a QR decomposition to quickly estimate
+ //the weighing matrix for each voxel
+ if(this->m_Aqr!=NULL)
+ delete this->m_Aqr;
+ this->m_Aqr = new vnl_qr< double >(A); //potential memory leak here
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::CalculateTensorModelParameters( const DWIVectorImageType::PixelType& dwivalues,
+ vnl_diag_matrix& W,
+ TensorModelParamType& tensormodelparams){
+
+ unsigned int N = this->m_TransformedGradients->Size();
+
+ //setup const references for code clarity
+ const vnl_matrix< double >& A = *(this->m_A);
+ const vnl_qr< double >& Aqr = *(this->m_Aqr);
+
+ //vnl_vector is used because the itk vector is limited in its methods and does not
+ //contain an internal vnl class like VariableSizematrix
+ //also itk_matrix has methods which are compatible with vnl_vectors
+ vnl_vector< double > logPhi( N );
+
+ for(unsigned int j=0; j< N ; j++){
+ //fill up the logPhi vector using log(dwi) values
+ logPhi.put(j, vcl_log(static_cast(dwivalues[j]) + vnl_math::eps));
+ }
+
+ /** Find WLS estimate of the parameters of the Tensor model **/
+
+ // First estimate W by LS estimation of the intensities
+ //vnl_matrix< double > Q = Aqr.Q();
+ //vnl_vector< double > QtB = Aqr.Q().transpose()*logPhi;
+ //vnl_vector< double > QTB = Aqr.QtB(logPhi);
+ //vnl_matrix< double > R = Aqr.R();
+ W = A* vnl_qr< double >(Aqr.R()).solve(Aqr.QtB(logPhi));
+ //W = A * Aqr.solve(logPhi);
+ for(vnl_diag_matrix< double >::iterator i = W.begin();i!=W.end(); i++){
+ *i = vcl_exp( *i );
+ }
+
+ // Now solve for parameters using the estimated weighing matrix
+ tensormodelparams = vnl_qr< double >((W*A).transpose()*W*A).solve(
+ (W*A).transpose()*W*logPhi);
+ //int a;
+ //tensormodelparams = vnl_qr< double >((W*A)).solve(W*logPhi);
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::CalculateConstrainedModelParameters( const TensorModelParamType& tensormodelparams,
+ ConstrainedModelParamType& constrainedmodelparams){
+
+ vnl_sym_matrix< double > D( 3, 0 );
+ double alpha =0;
+ double beta=0;
+ //set the tensor model parameters into a Diffusion tensor
+ D(0,0) = tensormodelparams[1];
+ D(0,1) = tensormodelparams[4];
+ D(0,2) = tensormodelparams[5];
+ D(1,0) = tensormodelparams[4];
+ D(1,1) = tensormodelparams[2];
+ D(1,2) = tensormodelparams[6];
+ D(2,0) = tensormodelparams[5];
+ D(2,1) = tensormodelparams[6];
+ D(2,2) = tensormodelparams[3];
+
+ //pass through the no gradient intensity Z_0 and
+ //calculate alpha, beta and v hat (the eigenvector
+ //associated with the largest eigenvalue)
+ vnl_matrix_fixed< double, 3, 3 > S(0.0);
+ vnl_vector_fixed< double, 3 > Lambda(0.0);
+ SymmetricEigenAnalysis< vnl_sym_matrix< double >,
+ vnl_vector_fixed< double, 3 >, vnl_matrix_fixed< double, 3, 3 > >
+ eigensystem( 3 );
+ eigensystem.ComputeEigenValuesAndVectors( D, Lambda, S );
+
+ //need to take abs to get rid of negative eigenvalues
+ alpha = (vcl_abs(Lambda[0]) + vcl_abs(Lambda[1])) / 2;
+ beta = vcl_abs(Lambda[2]) - alpha;
+
+ constrainedmodelparams[0] = tensormodelparams[0];
+ constrainedmodelparams[1] = alpha;
+ constrainedmodelparams[2] = beta;
+ constrainedmodelparams[3] = S[2][0];
+ constrainedmodelparams[4] = S[2][1];
+ constrainedmodelparams[5] = S[2][2];
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::CalculateNoiseFreeDWIFromConstrainedModel( const ConstrainedModelParamType& constrainedmodelparams,
+ DWIVectorImageType::PixelType& noisefreedwi){
+
+ unsigned int N = this->m_TransformedGradients->Size();
+ const double& z_0 = constrainedmodelparams[0];
+ const double& alpha = constrainedmodelparams[1];
+ const double& beta = constrainedmodelparams[2];
+ TractOrientationContainerType::Element v_hat( constrainedmodelparams[3],
+ constrainedmodelparams[4],
+ constrainedmodelparams[5]);
+
+ for(unsigned int i=0; i < N ; i++ ){
+ const double& b_i = this->m_bValues->GetElement(i);
+ const GradientDirectionContainerType::Element& g_i =
+ this->m_TransformedGradients->GetElement(i);
+
+ noisefreedwi.SetElement(i,
+ vcl_exp(z_0-(alpha*b_i+beta*b_i*vnl_math_sqr(dot_product(g_i, v_hat)))));
+ }
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::CalculateResidualVariance( const DWIVectorImageType::PixelType& noisydwi,
+ const DWIVectorImageType::PixelType& noisefreedwi,
+ const vnl_diag_matrix< double >& W,
+ const unsigned int numberofparameters,
+ double& residualvariance){
+
+ unsigned int N = this->m_TransformedGradients->Size();
+
+ residualvariance=0;
+
+ /** Not sure if we should be taking difference of log or nonlog intensities **/
+ /** residual variance is too low if we take the difference of log intensities **/
+ /** perhaps using WLS will correct this problem **/
+ for(unsigned int i=0; i
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::CalculateLikelihood( const DWIVectorImageType::PixelType &dwipixel,
+ TractOrientationContainerType::ConstPointer orientations,
+ ProbabilityDistributionImageType::PixelType& likelihood){
+
+ unsigned int N = this->m_TransformedGradients->Size();
+ TensorModelParamType tensorparams( 0.0 );
+ vnl_diag_matrix< double > W(N,0);
+ ConstrainedModelParamType constrainedparams( 0.0 );
+ DWIVectorImageType::PixelType noisefreedwi(N);
+ double residualvariance=0;
+ double jointlikelihood=1;
+
+ CalculateTensorModelParameters( dwipixel, W, tensorparams );
+ CalculateConstrainedModelParameters( tensorparams, constrainedparams );
+ CalculateNoiseFreeDWIFromConstrainedModel( constrainedparams, noisefreedwi );
+ CalculateResidualVariance( dwipixel, noisefreedwi, W, 6, residualvariance );
+
+ for(unsigned int i=0; i < orientations->Size(); i++){
+ /** Vary the entry corresponding to the estimated
+ Tract orientation over the selected sample directions,
+ while preserving the best estimate for the other parameters **/
+ TractOrientationContainerType::Element currentdir = orientations->GetElement(i);
+
+ /** Incorporate the current sample direction into the secondary parameters **/
+ constrainedparams[3]=currentdir[0];
+ constrainedparams[4]=currentdir[1];
+ constrainedparams[5]=currentdir[2];
+
+ /** Obtain the estimated
+ intensity for this choice of Tract direction **/
+ CalculateNoiseFreeDWIFromConstrainedModel(constrainedparams, noisefreedwi);
+
+ jointlikelihood = 1.0;
+ for(unsigned int j=0; j
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::CalculatePrior( TractOrientationContainerType::Element v_prev,
+ TractOrientationContainerType::ConstPointer orientations,
+ ProbabilityDistributionImageType::PixelType& prior ){
+
+ const double gamma = 1;
+
+ for(unsigned int i=0; i < orientations->Size(); i++){
+ if(v_prev.squared_magnitude()==0){
+ prior[i]=1.0;
+ }
+ else{
+ prior[i] = dot_product(orientations->GetElement(i),v_prev);;
+ if(prior[i]<0){
+ prior[i]=0;
+ }
+ else{
+ prior[i]=vcl_pow(prior[i],gamma);
+ }
+ }
+ }
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::CalculatePosterior( const ProbabilityDistributionImageType::PixelType& likelihood,
+ const ProbabilityDistributionImageType::PixelType& prior,
+ ProbabilityDistributionImageType::PixelType& posterior){
+
+ double sum=0;
+ for(unsigned int i=0; i
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::SampleTractOrientation( vnl_random& randomgenerator,
+ const ProbabilityDistributionImageType::PixelType& posterior,
+ TractOrientationContainerType::ConstPointer orientations,
+ TractOrientationContainerType::Element& choosendirection ){
+
+ double randomnum = randomgenerator.drand64();
+ int i=0;
+ double cumsum=0;
+
+ //will crash in the unlikely case that 0 was choosen as the randomnum
+ while(cumsum < randomnum){
+ cumsum+=posterior[i];
+ i++;
+ }
+ choosendirection = orientations->GetElement(i-1);
+
+ //std::cout<< "cumsum: " << cumsum<
+bool
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::FiberExistenceTest( vnl_random& randomgenerator,
+ typename InputWhiteMatterProbabilityImageType::ConstPointer wmpimage,
+ typename InputWhiteMatterProbabilityImageType::IndexType index ){
+ double randomnum = randomgenerator.drand64();
+ if( randomnum < wmpimage->GetPixel( index ) )
+ return true;
+ else
+ return false;
+}
+//the seedindex is in continuous IJK coordinates
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::StochasticTractGeneration( typename InputDWIImageType::ConstPointer dwiimagePtr,
+ typename InputWhiteMatterProbabilityImageType::ConstPointer wmpimagePtr,
+ typename InputDWIImageType::IndexType seedindex,
+ unsigned long randomseed,
+ TractType::Pointer tract){
+
+ TractType::ContinuousIndexType cindex_curr = seedindex;
+ typename InputDWIImageType::IndexType index_curr = {{0,0,0}};
+ ProbabilityDistributionImageType::PixelType
+ prior_curr(this->m_SampleDirections->Size());
+ ProbabilityDistributionImageType::PixelType
+ posterior_curr(this->m_SampleDirections->Size());
+ TractOrientationContainerType::Element v_curr(0,0,0);
+ TractOrientationContainerType::Element v_prev(0,0,0);
+
+ tract->Initialize();
+ vnl_random randomgenerator(randomseed);
+ //std::cout<m_MaxTractLength; j++){
+ this->ProbabilisticallyInterpolate( randomgenerator, cindex_curr, index_curr );
+
+ if(!dwiimagePtr->GetLargestPossibleRegion().IsInside(index_curr)){
+ break;
+ }
+
+ if( FiberExistenceTest( randomgenerator, wmpimagePtr, index_curr ) ){
+ tract->AddVertex(cindex_curr);
+
+ this->CalculatePrior( v_prev, this->m_SampleDirections, prior_curr);
+
+ const ProbabilityDistributionImageType::PixelType&
+ cachelikelihood_curr = this->AccessLikelihoodCache(index_curr);
+
+ if( cachelikelihood_curr.GetSize() != 0){
+ //use the cached direction
+ this->CalculatePosterior( cachelikelihood_curr, prior_curr, posterior_curr);
+ }
+ else{
+ //do the likelihood calculation and discard
+ //std::cout<<"Cache Miss!\n";
+ ProbabilityDistributionImageType::PixelType
+ likelihood_curr_temp(this->m_SampleDirections->Size());
+
+ this->CalculateLikelihood(static_cast< DWIVectorImageType::PixelType >(
+ dwiimagePtr->GetPixel(index_curr)),
+ this->m_SampleDirections,
+ likelihood_curr_temp);
+ this->CalculatePosterior( likelihood_curr_temp, prior_curr, posterior_curr);
+ }
+ this->SampleTractOrientation(randomgenerator, posterior_curr,
+ this->m_SampleDirections, v_curr);
+
+ //takes into account voxels of different sizes
+ //converts from a step length of 1 mm to the corresponding length in IJK space
+ const typename InputDWIImageType::SpacingType& spacing = dwiimagePtr->GetSpacing();
+ cindex_curr[0]+=v_curr[0]/spacing[0];
+ cindex_curr[1]+=v_curr[1]/spacing[1];
+ cindex_curr[2]+=v_curr[2]/spacing[2];
+ v_prev=v_curr;
+ }
+ else{
+ //fiber doesn't exist in this voxel
+ //std::cout<<"Stopped Tracking: No Fiber in this Voxel\n";
+ break;
+ }
+ }
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::GenerateTractContainerOutput(){
+ //allocate tractcontainer
+ this->m_OutputTractContainer = TractContainerType::New();
+
+ this->UpdateGradientDirections();
+ this->UpdateTensorModelFittingMatrices();
+ this->m_TotalDelegatedTracts = 0;
+
+ //calculate the number of voxels to cache from Megabyte memory size limit
+ ProbabilityDistributionImageType::PixelType
+ element(this->GetSampleDirections()->Size());
+ unsigned long elementsize = sizeof(ProbabilityDistributionImageType::PixelType) +
+ sizeof(double)*element.Size();
+ this->m_MaxLikelihoodCacheElements =
+ (this->m_MaxLikelihoodCacheSize*1048576)/elementsize;
+ std::cout << "MaxLikelhoodCacheElements: "
+ << this->m_MaxLikelihoodCacheElements
+ << std::endl;
+
+ //setup the multithreader
+ StochasticTractGenerationCallbackStruct data;
+ data.Filter = this;
+ this->GetMultiThreader()->SetSingleMethod( StochasticTractGenerationCallback,
+ &data );
+ this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfThreads());
+ std::cout<<"Number of Threads: " << this->GetMultiThreader()->GetNumberOfThreads() << std::endl;
+ //start the multithreaded execution
+ this->GetMultiThreader()->SingleMethodExecute();
+ std::cout<< "CurrentLikelihoodCacheElements: " <<
+ this->m_CurrentLikelihoodCacheElements << std::endl;
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::GenerateData(){
+ //Generate the tracts
+ this->GenerateTractContainerOutput();
+
+ //allocate outputs
+ this->AllocateOutputs();
+
+ //write tracts to output image
+ this->TractContainerToConnectivityMap(this->m_OutputTractContainer);
+
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+ITK_THREAD_RETURN_TYPE
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::StochasticTractGenerationCallback( void *arg )
+{
+ StochasticTractGenerationCallbackStruct* str=
+ (StochasticTractGenerationCallbackStruct *)
+ (((MultiThreader::ThreadInfoStruct *)(arg))->UserData);
+
+ typename InputDWIImageType::ConstPointer inputDWIImagePtr = str->Filter->GetInput();
+ typename InputWhiteMatterProbabilityImageType::ConstPointer inputWMPImage =
+ str->Filter->GetWhiteMatterProbabilityImageInput();
+
+ unsigned long randomseed=0;
+
+ while(str->Filter->DelegateTract(randomseed)){
+ //std::cout<Filter->StochasticTractGeneration( inputDWIImagePtr,
+ inputWMPImage,
+ str->Filter->GetSeedIndex(),
+ randomseed,
+ tract);
+
+ //only store tract if it is of nonzero length
+ if( tract->GetVertexList()->Size() > 4 ){
+ //std::cout<<"Storing tract\n";
+ str->Filter->StoreTract(tract);
+ }
+ else{
+ //std::cout<<"Not Storing Tract\n";
+ }
+ }
+ return ITK_THREAD_RETURN_VALUE;
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+ProbabilityDistributionImageType::PixelType&
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::AccessLikelihoodCache( typename InputDWIImageType::IndexType index )
+{
+ this->m_LikelihoodCacheMutexImagePtr->GetPixel(index).Lock();
+
+ ProbabilityDistributionImageType::PixelType& likelihood =
+ m_LikelihoodCachePtr->GetPixel( index );
+ typename InputDWIImageType::ConstPointer inputDWIImagePtr = this->GetInput();
+
+ if( likelihood.GetSize() !=0){
+ //entry found in cache
+ this->m_LikelihoodCacheMutexImagePtr->GetPixel(index).Unlock();
+ return likelihood;
+ }
+ //we need to lock m_CurrentLikelihoodCacheElements as well but not crucial right now
+ else if( this->m_CurrentLikelihoodCacheElements < this->m_MaxLikelihoodCacheElements ){
+ //entry not found in cache but we have space to store it
+ likelihood.SetSize(this->m_SampleDirections->Size());
+
+ this->CalculateLikelihood(static_cast< DWIVectorImageType::PixelType >(
+ inputDWIImagePtr->GetPixel(index)),
+ this->m_SampleDirections,
+ likelihood);
+ this->m_CurrentLikelihoodCacheElements++;
+
+ this->m_LikelihoodCacheMutexImagePtr->GetPixel(index).Unlock();
+ return likelihood;
+ }
+ else{
+ //entry not found in cache and no space to store it
+ this->m_LikelihoodCacheMutexImagePtr->GetPixel(index).Unlock();
+ return likelihood;
+ }
+
+
+ this->m_LikelihoodCacheMutexImagePtr->GetPixel(index).Unlock();
+
+ // dummy
+ return likelihood;
+
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+bool
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::DelegateTract(unsigned long& randomseed){
+ bool success = false;
+ this->m_TotalDelegatedTractsMutex.Lock();
+ if(this->m_TotalDelegatedTracts < this->m_TotalTracts){
+ randomseed = this->m_RandomGenerator.lrand32();
+ this->m_TotalDelegatedTracts++;
+ success = true;
+ //a tract was successfully delegated
+ }
+ else success = false; //all tracts have been delegated
+ this->m_TotalDelegatedTractsMutex.Unlock();
+
+ return success;
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::TractContainerToConnectivityMap(TractContainerType::Pointer tractcontainer){
+ //zero the output image
+ typename OutputConnectivityImageType::Pointer outputPtr = this->GetOutput();
+ outputPtr->FillBuffer(0);
+
+ typedef PathIterator< OutputConnectivityImageType, TractType > OutputTractIteratorType;
+
+ for(unsigned int i=0; iSize(); i++ ){
+ TractType::Pointer tract = tractcontainer->GetElement(i);
+ //std::cout<< tract->EndOfInput() <
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::StoreTract(TractType::Pointer tract){
+ this->m_OutputTractContainerMutex.Lock();
+ this->m_OutputTractContainer->InsertElement(
+ this->m_OutputTractContainer->Size(),
+ tract);
+ this->m_OutputTractContainerMutex.Unlock();
+}
+
+template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage >
+void
+StochasticTractographyFilter< TInputDWIImage, TInputWhiteMatterProbabilityImage, TOutputConnectivityImage >
+::GenerateTensorImageOutput(void){
+ this->UpdateGradientDirections();
+ this->UpdateTensorModelFittingMatrices();
+
+ //allocate the tensor image
+ this->m_OutputTensorImage = OutputTensorImageType::New();
+ m_OutputTensorImage->CopyInformation( this->GetInput() );
+ m_OutputTensorImage->SetBufferedRegion( this->GetInput()->GetBufferedRegion() );
+ m_OutputTensorImage->SetRequestedRegion( this->GetInput()->GetRequestedRegion() );
+ m_OutputTensorImage->Allocate();
+
+ //define an iterator for the input and output images
+ typedef itk::ImageRegionConstIterator< InputDWIImageType > DWIImageIteratorType;
+ typedef itk::ImageRegionIterator< OutputTensorImageType > TensorImageIteratorType;
+
+ DWIImageIteratorType
+ inputDWIit( this->GetInput(), m_OutputTensorImage->GetRequestedRegion() );
+
+ TensorImageIteratorType outputtensorit
+ ( m_OutputTensorImage, m_OutputTensorImage->GetRequestedRegion() );
+
+ unsigned int N = this->m_TransformedGradients->Size();
+ TensorModelParamType tensormodelparams( 0.0 );
+ vnl_diag_matrix< double > W(N,0);
+
+ for(inputDWIit.GoToBegin(), outputtensorit.GoToBegin();
+ !outputtensorit.IsAtEnd(); ++inputDWIit, ++outputtensorit){
+ CalculateTensorModelParameters( inputDWIit.Get(),
+ W, tensormodelparams);
+
+ OutputTensorImageType::PixelType& D = outputtensorit.Value();
+ //set the tensor model parameters into a Diffusion tensor
+ D(0,0) = tensormodelparams[1];
+ D(0,1) = tensormodelparams[4];
+ D(0,2) = tensormodelparams[5];
+ D(1,0) = tensormodelparams[4];
+ D(1,1) = tensormodelparams[2];
+ D(1,2) = tensormodelparams[6];
+ D(2,0) = tensormodelparams[5];
+ D(2,1) = tensormodelparams[6];
+ D(2,2) = tensormodelparams[3];
+
+ //std::cout< DWI
IODataStructures/DiffusionWeightedImages/mitkDiffusionImageHeaderInformation.cpp
IODataStructures/DiffusionWeightedImages/mitkDiffusionImageSource.cpp
IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageReader.cpp
IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageWriter.cpp
IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageIOFactory.cpp
IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageWriterFactory.cpp
IODataStructures/DiffusionWeightedImages/mitkDiffusionImageSerializer.cpp
# DataStructures -> QBall
IODataStructures/QBallImages/mitkQBallImageSource.cpp
IODataStructures/QBallImages/mitkNrrdQBallImageReader.cpp
IODataStructures/QBallImages/mitkNrrdQBallImageWriter.cpp
IODataStructures/QBallImages/mitkNrrdQBallImageIOFactory.cpp
IODataStructures/QBallImages/mitkNrrdQBallImageWriterFactory.cpp
IODataStructures/QBallImages/mitkQBallImage.cpp
IODataStructures/QBallImages/mitkQBallImageSerializer.cpp
# DataStructures -> Tensor
IODataStructures/TensorImages/mitkTensorImageSource.cpp
IODataStructures/TensorImages/mitkNrrdTensorImageReader.cpp
IODataStructures/TensorImages/mitkNrrdTensorImageWriter.cpp
IODataStructures/TensorImages/mitkNrrdTensorImageIOFactory.cpp
IODataStructures/TensorImages/mitkNrrdTensorImageWriterFactory.cpp
IODataStructures/TensorImages/mitkTensorImage.cpp
IODataStructures/TensorImages/mitkTensorImageSerializer.cpp
# DataStructures -> FiberBundle
IODataStructures/FiberBundle/mitkFiberBundle.cpp
IODataStructures/FiberBundle/mitkFiberBundleWriter.cpp
IODataStructures/FiberBundle/mitkFiberBundleReader.cpp
IODataStructures/FiberBundle/mitkFiberBundleIOFactory.cpp
IODataStructures/FiberBundle/mitkFiberBundleWriterFactory.cpp
IODataStructures/FiberBundle/mitkFiberBundleSerializer.cpp
IODataStructures/FiberBundle/mitkParticle.cpp
IODataStructures/FiberBundle/mitkParticleGrid.cpp
# DataStructures -> FiberBundleX
IODataStructures/FiberBundleX/mitkFiberBundleX.cpp
IODataStructures/FiberBundleX/mitkFiberBundleXWriter.cpp
IODataStructures/FiberBundleX/mitkFiberBundleXReader.cpp
IODataStructures/FiberBundleX/mitkFiberBundleXIOFactory.cpp
IODataStructures/FiberBundleX/mitkFiberBundleXWriterFactory.cpp
IODataStructures/FiberBundleX/mitkFiberBundleXSerializer.cpp
IODataStructures/FiberBundleX/mitkFiberBundleXThreadMonitor.cpp
# DataStructures -> PlanarFigureComposite
IODataStructures/PlanarFigureComposite/mitkPlanarFigureComposite.cpp
# DataStructures -> Tbss
IODataStructures/TbssImages/mitkTbssImageSource.cpp
IODataStructures/TbssImages/mitkNrrdTbssImageReader.cpp
IODataStructures/TbssImages/mitkNrrdTbssImageIOFactory.cpp
IODataStructures/TbssImages/mitkTbssImage.cpp
IODataStructures/TbssImages/mitkNrrdTbssImageWriter.cpp
IODataStructures/TbssImages/mitkNrrdTbssImageWriterFactory.cpp
# Rendering
Rendering/vtkMaskedProgrammableGlyphFilter.cpp
Rendering/mitkCompositeMapper.cpp
Rendering/mitkVectorImageVtkGlyphMapper3D.cpp
Rendering/vtkOdfSource.cxx
Rendering/vtkThickPlane.cxx
Rendering/mitkOdfNormalizationMethodProperty.cpp
Rendering/mitkOdfScaleByProperty.cpp
Rendering/mitkFiberBundleMapper2D.cpp
Rendering/mitkFiberBundleMapper3D.cpp
Rendering/mitkFiberBundleXMapper3D.cpp
Rendering/mitkFiberBundleXThreadMonitorMapper3D.cpp
# Interactions
Interactions/mitkFiberBundleInteractor.cpp
# Algorithms
Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.cpp
Algorithms/mitkPartialVolumeAnalysisClusteringCalculator.cpp
+
+ # Tractography
+ Tractography/itkStochasticTractographyFilter.h
)
SET(H_FILES
# Rendering
Rendering/mitkDiffusionImageMapper.h
Rendering/mitkOdfVtkMapper2D.h
Rendering/mitkFiberBundleMapper2D.h
Rendering/mitkFiberBundleMapper3D.h
Rendering/mitkFiberBundleXMapper3D.h
Rendering/mitkFiberBundleXThreadMonitorMapper3D.h
# Reconstruction
Reconstruction/itkDiffusionQballReconstructionImageFilter.h
Reconstruction/mitkTeemDiffusionTensor3DReconstructionImageFilter.h
Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.h
Reconstruction/itkPointShell.h
Reconstruction/itkOrientationDistributionFunction.h
Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h
Reconstruction/itkRegularizedIVIMLocalVariationImageFilter.h
Reconstruction/itkRegularizedIVIMReconstructionFilter.h
Reconstruction/itkRegularizedIVIMReconstructionSingleIteration.h
# IO Datastructures
IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h
IODataStructures/FiberBundle/itkSlowPolyLineParametricPath.h
IODataStructures/TbssImages/mitkTbssImage.h
# DataStructures -> FiberBundleX
IODataStructures/FiberBundleX/mitkFiberBundleX.h
IODataStructures/FiberBundleX/mitkFiberBundleXWriter.h
IODataStructures/FiberBundleX/mitkFiberBundleXReader.h
IODataStructures/FiberBundleX/mitkFiberBundleXIOFactory.h
IODataStructures/FiberBundleX/mitkFiberBundleXWriterFactory.h
IODataStructures/FiberBundleX/mitkFiberBundleXSerializer.h
IODataStructures/FiberBundleX/mitkFiberBundleXThreadMonitor.h
# Tractography
Tractography/itkGibbsTrackingFilter.h
+ Tractography/itkStochasticTractographyFilter.h
# Algorithms
Algorithms/itkDiffusionQballGeneralizedFaImageFilter.h
Algorithms/itkDiffusionQballPrepareVisualizationImageFilter.h
Algorithms/itkTensorDerivedMeasurementsFilter.h
Algorithms/itkBrainMaskExtractionImageFilter.h
Algorithms/itkB0ImageExtractionImageFilter.h
Algorithms/itkTensorImageToDiffusionImageFilter.h
Algorithms/itkTensorToL2NormImageFilter.h
Algorithms/itkTractsToProbabilityImageFilter.h
Algorithms/itkTractsToFiberEndingsImageFilter.h
Algorithms/itkGaussianInterpolateImageFunction.h
Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.h
Algorithms/mitkPartialVolumeAnalysisClusteringCalculator.h
Algorithms/itkDiffusionTensorPrincipleDirectionImageFilter.h
Algorithms/itkCartesianToPolarVectorImageFilter.h
Algorithms/itkPolarToCartesianVectorImageFilter.h
)
SET( TOOL_FILES
)
IF(WIN32)
ENDIF(WIN32)
#MITK_MULTIPLEX_PICTYPE( Algorithms/mitkImageRegistrationMethod-TYPE.cpp )