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 )