]> Creatis software - clitk.git/blobdiff - vv/vvMainWindow.cxx
Correct 'else'
[clitk.git] / vv / vvMainWindow.cxx
index 5c7bbfd76f3ccb531c54b1ae01fe0b0d0358b33e..af39d3e15fb1eda8910f965b8d31566d16f93bd2 100644 (file)
@@ -48,6 +48,7 @@ It is distributed under dual licence
 #include "vvSaveState.h"
 #include "vvReadState.h"
 #include "clitkConfiguration.h"
+#include "clitkMatrix.h"
 
 // ITK include
 #include <itkImage.h>
@@ -88,6 +89,7 @@ It is distributed under dual licence
 
 // Standard includes
 #include <iostream>
+#include <fstream>
 #include <sstream>
 #include <iomanip>
 
@@ -101,9 +103,9 @@ It is distributed under dual licence
 #define COLUMN_IMAGE_NAME 7
 
 #ifdef CLITK_PRIVATE_FEATURES
-#define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr *.refscan *.nii.gz *.usf)"
+#define EXTENSIONS "Images ( *.bmp *.dcm *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr *.refscan *.nii.gz *.usf *.svl)"
 #else
-#define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr *.refscan *.nii.gz)"
+#define EXTENSIONS "Images ( *.bmp *.dcm *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr *.refscan *.nii.gz)"
 #endif
 
 
@@ -276,7 +278,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(actionWarp_image_with_vector_field,SIGNAL(triggered()),this,SLOT(WarpImage()));
   connect(actionLoad_images,SIGNAL(triggered()),this,SLOT(OpenImages()));
   connect(actionOpen_Dicom,SIGNAL(triggered()),this,SLOT(OpenDicom()));
-  connect(actionOpen_Dicom_Struct,SIGNAL(triggered()),this,SLOT(OpenDCStructContour()));
+  //  connect(actionOpen_Dicom_Struct,SIGNAL(triggered()),this,SLOT(OpenDCStructContour()));
   connect(actionOpen_VTK_contour,SIGNAL(triggered()),this,SLOT(OpenVTKContour()));
   connect(actionOpen_Multiple_Images_As_One,SIGNAL(triggered()),this,SLOT(MergeImages()));
   connect(actionSlice_Image_As_Multiple_Images,SIGNAL(triggered()),this,SLOT(SliceImages()));
@@ -294,7 +296,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(actionDocumentation,SIGNAL(triggered()),this,SLOT(ShowDocumentation()));
   connect(actionRegister_vv,SIGNAL(triggered()),this,SLOT(PopupRegisterForm()));
 
-  connect(overlayPanel, SIGNAL(FusionSequenceSignalButtonPressed()), this, SLOT(SelectFusionSequenceTemporalSignal()));
+  connect(overlayPanel, SIGNAL(FusionSequenceCorrespondancesButtonPressed()), this, SLOT(SelectFusionSequenceCorrespondances()));
 
 
   ///////////////////////////////////////////////
@@ -460,7 +462,7 @@ void vvMainWindow::AddContour(int image_index, vvMesh::Pointer contour, bool pro
   brush.setColor(QColor(contour->r*255,contour->g*255,contour->b*255));
   brush.setStyle(Qt::SolidPattern);
   item->setData(COLUMN_IMAGE_NAME,Qt::BackgroundRole,brush);
-  item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,contour->structure_name.c_str());
+  //  item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,contour->structure_name.c_str());
 
   for (int j = 1; j <= 4; j++)
     item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(image_index)->data(j,Qt::CheckStateRole));
@@ -738,7 +740,7 @@ void vvMainWindow::OpenDicom()
 {
   std::vector<std::string> files;
 
-  std::cout << "dicomSeriesSelector " << std::endl;
+  //std::cout << "dicomSeriesSelector " << std::endl;
   if (dicomSeriesSelector->exec() == QDialog::Accepted) {
     files = *(dicomSeriesSelector->GetFilenames());
     LoadImages(files, vvImageReader::DICOM);
@@ -1003,7 +1005,7 @@ void vvMainWindow::CurrentImageChanged(std::string id)
                                       mSlicerManagers[selected]->GetTSlice());
   landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
   landmarksPanel->SetCurrentImage(mSlicerManagers[selected]->GetFileName().c_str());
-  
+
   emit SelectedImageHasChanged(mSlicerManagers[selected]);
 }
 //------------------------------------------------------------------------------
@@ -1133,6 +1135,9 @@ void vvMainWindow::ImageInfoChanged()
     dim += pixelType + ")";
 
     infoPanel->setFileName(image);
+    std::string creationImageTimeValue("No creation time");
+    itk::ExposeMetaData< std::string > (*imageSelected->GetFirstMetaDataDictionary(), "creationImageTime", creationImageTimeValue);
+    infoPanel->setImageCreationTime(QString(creationImageTimeValue.c_str()));
     infoPanel->setDimension(dim);
     infoPanel->setSizePixel(GetVectorIntAsString(inputSize));
     infoPanel->setSizeMM(GetVectorDoubleAsString(sizeMM));
@@ -1141,7 +1146,7 @@ void vvMainWindow::ImageInfoChanged()
     infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")");
 
     transformation = imageSelected->GetTransform()[tSlice]->GetMatrix();
-    infoPanel->setTransformation(Get4x4MatrixDoubleAsString(transformation));
+    infoPanel->setTransformation(clitk::Get4x4MatrixDoubleAsString(transformation).c_str());
 
     landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
                                         mSlicerManagers[index]->GetTSlice());
@@ -1163,12 +1168,12 @@ void vvMainWindow::ImageInfoChanged()
 //     infoPanel->setOrigin(GetVectorDoubleAsString(origin));
 //     infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing));
 //     infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")");
-// 
+//
 //     landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
 //                                         mSlicerManagers[index]->GetTSlice());
 //     landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
 //     landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
-// 
+//
 //     overlayPanel->getCurrentImageName(mSlicerManagers[index]->GetFileName().c_str());
 //     for (int i = 0; i < 4; i++) {
 //       if (DataTree->selectedItems()[0]->data(i+1,Qt::CheckStateRole).toInt() > 0 || i == 3) {
@@ -1339,38 +1344,6 @@ QString vvMainWindow::GetSizeInBytes(unsigned long size)
 }
 //------------------------------------------------------------------------------
 
-//------------------------------------------------------------------------------
-QString vvMainWindow::Get4x4MatrixDoubleAsString(vtkSmartPointer<vtkMatrix4x4> matrix, const int precision)
-{
-  std::ostringstream strmatrix;
-
-  // Figure out the number of digits of the integer part of the largest absolute value
-  // for each column
-  unsigned width[4];
-  for (unsigned int j = 0; j < 4; j++){
-    double absmax = 0.;
-    for (unsigned int i = 0; i < 4; i++)
-      absmax = std::max(absmax, vnl_math_abs(matrix->GetElement(i, j)));
-    unsigned ndigits = (unsigned)std::max(0.,std::log10(absmax))+1;
-    width[j] = precision+ndigits+3;
-  }
-
-  // Output with correct width, aligned to the right
-  for (unsigned int i = 0; i < 4; i++) {
-    for (unsigned int j = 0; j < 4; j++) {
-      strmatrix.setf(ios::fixed,ios::floatfield);
-      strmatrix.precision(precision);
-      strmatrix.fill(' ');
-      strmatrix.width(width[j]);
-      strmatrix << std::right << matrix->GetElement(i, j);
-    }
-    strmatrix << std::endl;
-  }
-  QString result = strmatrix.str().c_str();
-  return result;
-}
-//------------------------------------------------------------------------------
-
 //------------------------------------------------------------------------------
 QString vvMainWindow::GetVectorDoubleAsString(std::vector<double> vectorDouble)
 {
@@ -1471,7 +1444,7 @@ void vvMainWindow::DisplayChanged(QTreeWidgetItem *clickedItem, int column)
       clickedParentItem->setData(column, Qt::CheckStateRole, vis?2:0);
 
       // Children
-      std::map<std::string, int> actorTypeCounts;      
+      std::map<std::string, int> actorTypeCounts;
       for (int iChild = 0; iChild < clickedParentItem->childCount(); iChild++) {
         QTreeWidgetItem* currentChildItem = clickedParentItem->child(iChild);
         std::string actorType = currentChildItem->data(1,Qt::UserRole).toString().toStdString();
@@ -1500,6 +1473,7 @@ void vvMainWindow::InitSlicers()
     mSlicerManagers.back()->SetSlicerWindow(1,NEViewWidget->GetRenderWindow());
     mSlicerManagers.back()->SetSlicerWindow(2,SOViewWidget->GetRenderWindow());
     mSlicerManagers.back()->SetSlicerWindow(3,SEViewWidget->GetRenderWindow());
+    mSlicerManagers.back()->Render(); // SR: displayed #slice is wrong without this
   }
 }
 
@@ -1589,7 +1563,7 @@ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column)
         if (DataTree->topLevelItem(index)->child(child) == item) break;
       }
       if (overlay_type=="fusionSequence") {
-        //removing the overlay sequence in a fusion sequence visualization mode 
+        //removing the overlay sequence in a fusion sequence visualization mode
         //reset the transforms
         overlayPanel->getFusionSequenceProperty(-1, false, 0, false);
 
@@ -1638,6 +1612,24 @@ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column)
       }
       //if the slicer manager was involved in a fusion sequence visualization...
       if ( mSlicerManagers[index]->IsInvolvedInFusionSequence() ) {
+        //in both cases, close the overlay: find it... and close it
+        //ideally, I should duplicate the code, and avoid calling CloseImage, since this pops up another interactive box
+        QTreeWidgetItem* overlayItem;
+        if (mSlicerManagers[index]->IsMainSequenceOfFusionSequence()) {
+          for (unsigned i=0 ; i<item->childCount() ; i++) {
+            overlayItem = item->child(i);
+            this->CloseImage( overlayItem, 0 );
+          }
+        }
+        else {
+          QTreeWidgetItem* linkedItem = this->GetItemFromSlicerManager( mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()] );
+          for (unsigned i=0 ; i<linkedItem->childCount() ; i++) {
+            overlayItem = linkedItem->child(i);
+            this->CloseImage( overlayItem, 0 );
+          }
+        }
+
+        /* -- this is normally already done when closing the overlay.
         //reset the transforms
         overlayPanel->getFusionSequenceProperty(-1, false, 0, false);
 
@@ -1649,8 +1641,7 @@ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column)
             mSlicerManagers[index]->GetSlicer(i)->SetFusionSequenceCode(-1);
             mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->GetSlicer(i)->SetFusionSequenceCode(-1);
         }
-        
-        //TODO: also remove the image overlaid with the main sequence, as it is becoming invalid...
+        */
       }
 
       linkPanel->removeImage(index);
@@ -1694,12 +1685,12 @@ void vvMainWindow::ReloadImage(QTreeWidgetItem* item, int column)
   else if (role == "fusionSequence") {
     //both versions of the secondary sequence must be updated.
     mSlicerManagers[index]->ReloadFusionSequence();
-    mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->Reload(); 
+    mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->Reload();
   }
   else {
     mSlicerManagers[index]->Reload();
     //if we update the secondary sequence, then the overlay of the main sequence should also be updated
-    if (mSlicerManagers[index]->IsSecondarySequenceOfFusionSequence()) mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->ReloadFusionSequence(); 
+    if (mSlicerManagers[index]->IsSecondarySequenceOfFusionSequence()) mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->ReloadFusionSequence();
   }
   // Update view and info
   ImageInfoChanged();
@@ -1768,7 +1759,7 @@ void vvMainWindow::WindowLevelChanged()
       mSlicerManagers[index]->GetFusionLevel());
     if (mSlicerManagers[index]->IsMainSequenceOfFusionSequence()) {
       overlayPanel->getFusionSequenceProperty(mSlicerManagers[index]->GetFusionSequenceFrameIndex(),
-        mSlicerManagers[index]->GetFusionSequenceSpatialSyncFlag(), 
+        mSlicerManagers[index]->GetFusionSequenceSpatialSyncFlag(),
         mSlicerManagers[index]->GetFusionSequenceNbFrames(),
         mSlicerManagers[index]->GetFusionSequenceTemporalSyncFlag());
     }
@@ -1782,7 +1773,7 @@ void vvMainWindow::WindowLevelChanged()
       mSlicerManagers[ind]->GetFusionWindow(),
       mSlicerManagers[ind]->GetFusionLevel());
     overlayPanel->getFusionSequenceProperty(mSlicerManagers[ind]->GetFusionSequenceFrameIndex(),
-      mSlicerManagers[ind]->GetFusionSequenceSpatialSyncFlag(), 
+      mSlicerManagers[ind]->GetFusionSequenceSpatialSyncFlag(),
       mSlicerManagers[ind]->GetFusionSequenceNbFrames(),
       mSlicerManagers[ind]->GetFusionSequenceTemporalSyncFlag());
   }
@@ -1867,12 +1858,22 @@ void vvMainWindow::ApplyWindowLevelToAllImages()
   double window = mSlicerManagers[index]->GetColorWindow();
   double level = mSlicerManagers[index]->GetColorLevel();
 
+  double fusWindow = mSlicerManagers[index]->GetFusionWindow();
+  double fusLevel = mSlicerManagers[index]->GetFusionLevel();
+
+  double overWindow = mSlicerManagers[index]->GetOverlayColorWindow();
+  double overLevel = mSlicerManagers[index]->GetOverlayColorLevel();
+
   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
     if (mSlicerManagers[i] == NULL)
       continue;
     mSlicerManagers[i]->SetColorWindow(window);
     mSlicerManagers[i]->SetColorLevel(level);
     mSlicerManagers[i]->SetPreset(WL_USER);
+    mSlicerManagers[i]->SetFusionWindow(fusWindow);
+    mSlicerManagers[i]->SetFusionLevel(fusLevel);
+    mSlicerManagers[i]->SetOverlayColorWindow(overWindow);
+    mSlicerManagers[i]->SetOverlayColorLevel(overLevel);
     mSlicerManagers[i]->Render();
   }
 }
@@ -2125,9 +2126,15 @@ void vvMainWindow::SelectFusionImage()
 
     QString Extensions = EXTENSIONS;
     Extensions += ";;All Files (*)";
-    QString file = QFileDialog::getOpenFileName(this,tr("Load Fusion image"),mInputPathName,Extensions);
-    if (!file.isEmpty())
-      AddFusionImage(index,file);
+    QStringList files = QFileDialog::getOpenFileNames(this,tr("Load Fusion image"),mInputPathName,Extensions);
+    if (files.isEmpty())
+      return;
+
+    std::vector<std::string> vecFileNames;
+    for (int i = 0; i < files.size(); i++) {
+      vecFileNames.push_back(files[i].toStdString());
+    }
+    AddFusionImage(index,vecFileNames,vvImageReader::IMAGE);
 }
 //------------------------------------------------------------------------------
 
@@ -2142,77 +2149,78 @@ void vvMainWindow::ResetTransformationToIdentity()
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::AddFusionImage(int index, QString file)
+void vvMainWindow::AddFusionImage(int index, std::vector<std::string> fileNames, vvImageReader::LoadedImageType type)
 {
+  QString file(fileNames[0].c_str());
   if (QFile::exists(file))
   {
     mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str();
     itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
       file.toStdString().c_str(), itk::ImageIOFactory::ReadMode);
-    reader->SetFileName(file.toStdString().c_str());
+    reader->SetFileName(fileNames[0].c_str());
     reader->ReadImageInformation();
     std::string component = reader->GetComponentTypeAsString(reader->GetComponentType());
-    if (reader) {
-      QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-      vvProgressDialog progress("Opening fusion");
-      qApp->processEvents();
+    int dimension = reader->GetNumberOfDimensions();
+    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+    vvProgressDialog progress("Opening fusion");
+    qApp->processEvents();
 
-      std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str();
-      if (mSlicerManagers[index]->SetFusion(file.toStdString(),
-        reader->GetNumberOfDimensions(), component)) {
-          //create an item in the tree with good settings
-          QTreeWidgetItem *item = new QTreeWidgetItem();
-          item->setData(0,Qt::UserRole,file.toStdString().c_str());
-          item->setData(1,Qt::UserRole,tr("fusion"));
-          QFileInfo fileinfo(filename.c_str()); //Do not show the path
+    std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str();
+    if (mSlicerManagers[index]->SetFusion(fileNames,dimension, component,type)) {
+      //create an item in the tree with good settings
+      QTreeWidgetItem *item = new QTreeWidgetItem();
+      item->setData(0,Qt::UserRole,file.toStdString().c_str());
+      item->setData(1,Qt::UserRole,tr("fusion"));
+      QFileInfo fileinfo(file); //Do not show the path
           item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
           item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("fusion").c_str());
           qApp->processEvents();
 
-          for (int j = 1; j <= 4; j++) {
-            item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
-          }
-
-          //Create the buttons for reload and close
-          qApp->processEvents();
-          QTreePushButton* cButton = new QTreePushButton;
-          cButton->setItem(item);
-          cButton->setColumn(COLUMN_CLOSE_IMAGE);
-          cButton->setToolTip(tr("close image"));
-          cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
-          connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
-            this,SLOT(CloseImage(QTreeWidgetItem*, int)));
-
-          QTreePushButton* rButton = new QTreePushButton;
-          rButton->setItem(item);
-          rButton->setColumn(COLUMN_RELOAD_IMAGE);
-          rButton->setToolTip(tr("reload image"));
-          rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
-          connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
-            this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
-
-          DataTree->topLevelItem(index)->setExpanded(1);
-          DataTree->topLevelItem(index)->addChild(item);
-          DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
-          DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
-
-          //set the id of the image
-          QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
-          item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
-          UpdateTree();
-          qApp->processEvents();
-          ImageInfoChanged();
-          QApplication::restoreOverrideCursor();
-      } else {
-        QApplication::restoreOverrideCursor();
-        QString error = "Cannot import the new image.\n";
-        error += mSlicerManagers[index]->GetLastError().c_str();
-        QMessageBox::information(this,tr("Problem reading image !"),error);
+      for (int j = 1; j <= 4; j++) {
+        item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
       }
+
+      //Create the buttons for reload and close
+      qApp->processEvents();
+      QTreePushButton* cButton = new QTreePushButton;
+      cButton->setItem(item);
+      cButton->setColumn(COLUMN_CLOSE_IMAGE);
+      cButton->setToolTip(tr("close image"));
+      cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
+      connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
+        this,SLOT(CloseImage(QTreeWidgetItem*, int)));
+
+      QTreePushButton* rButton = new QTreePushButton;
+      rButton->setItem(item);
+      rButton->setColumn(COLUMN_RELOAD_IMAGE);
+      rButton->setToolTip(tr("reload image"));
+      rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
+      connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
+        this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
+
+      DataTree->topLevelItem(index)->setExpanded(1);
+      DataTree->topLevelItem(index)->addChild(item);
+      DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
+      DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
+
+      //set the id of the image
+      QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
+      item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
+      UpdateTree();
+      qApp->processEvents();
+      ImageInfoChanged();
+      QApplication::restoreOverrideCursor();
+
+      // Update the display to update, e.g., the sliders
+      for(int i=0; i<4; i++)
+        DisplaySliders(index, i);
     } else {
+      QApplication::restoreOverrideCursor();
       QString error = "Cannot import the new image.\n";
+      error += mSlicerManagers[index]->GetLastError().c_str();
       QMessageBox::information(this,tr("Problem reading image !"),error);
     }
+    WindowLevelChanged();
   }
   else
     QMessageBox::information(this,tr("Problem reading Fusion !"),"File doesn't exist!");
@@ -2223,7 +2231,7 @@ void vvMainWindow::AddLandmarks(int index, std::vector<std::string> files)
 {
     if (!landmarksPanel->LoadFromFile(files))
       QMessageBox::information(this,tr("Problem reading Landmarks !"),"File doesn't exist!");
-    
+
     landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
     landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
 }
@@ -2242,12 +2250,12 @@ void vvMainWindow::OpenField()
       return;
     }
 
-    QString Extensions = "Images ( *.mhd)";
-    Extensions += ";;Images ( *.mha)";
-    Extensions += ";;VF Images ( *.vf)";
-    Extensions += ";;nii Images ( *.nii)";
-    Extensions += ";;nrrd Images ( *.nrrd)";
-    Extensions += ";;nhdr Images ( *.nhdr)";
+    QString Extensions = "Images ( *.mhd *.mha *.vf *.nii *.nrrd *.nhdr)";
+    // Extensions += ";;Images ( *.mha)";
+    // Extensions += ";;VF Images ( *.vf)";
+    // Extensions += ";;nii Images ( *.nii)";
+    // Extensions += ";;nrrd Images ( *.nrrd)";
+    // Extensions += ";;nhdr Images ( *.nhdr)";
     Extensions += ";;All Files (*)";
     QString file = QFileDialog::getOpenFileName(this,tr("Load deformation field"),mInputPathName,Extensions);
     if (!file.isEmpty())
@@ -2443,7 +2451,7 @@ void vvMainWindow::SelectFusionSequence()
 
 
 //------------------------------------------------------------------------------
-void vvMainWindow::SelectFusionSequenceTemporalSignal() {
+void vvMainWindow::SelectFusionSequenceCorrespondances() {
 
   //make sure the index is right?
   //in the end, I should attach the temporal data to the right sequence!
@@ -2454,35 +2462,51 @@ void vvMainWindow::SelectFusionSequenceTemporalSignal() {
   }
 
   //open a dialog box to find a file
-  QString Extensions = EXTENSIONS;
-  Extensions += ";;All Files (*)";
+  //QString Extensions = EXTENSIONS;
+  QString Extensions = ";;All Files (*)";
   QString fileName = QFileDialog::getOpenFileName(this,tr("Load respiratory signal for fused sequence"),mInputPathName,Extensions);
   if (fileName.isNull())
     return;
 
   //read it as a vector of values
-  std::vector<double> signal;
-  //...TODO, look for itk functions that can do that... vnl in the worst case.
-  signal.push_back(1);signal.push_back(2);
-
-  //TODO: instead: if the loaded signal is longer, just crop it...
-  //this allows loading only the first few frames when testing.
-  //->maybe raise a message that this behavior may be unsafe...
-
-  //if compatible with the fused image sequence (number of images = number of entries), enable the temporalSync
-  if ( signal.size() >= mSlicerManagers[index]->GetFusionSequenceNbFrames()) {
-    //for convenience, associate this sequence to both the current slicer manager, and to the linked one
-    mSlicerManagers[index]->SetFusionSequenceTemporalSignal(signal);
-    mSlicerManagers[ mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager() ]->SetFusionSequenceTemporalSignal(signal);
-    overlayPanel->enableFusionSequenceTemporalSync();
-    QMessageBox::information(this,tr("Adding signal"),"would add the signal from file: "+ fileName);
+  vnl_vector<double> tmpVect;
+
+  std::ifstream file;
+  file.open(fileName.toStdString().c_str());
+  tmpVect.read_ascii(file);
+  file.close();
+
+  //if compatible with the fused image sequence (number of entries = nb of entries in main sequence + nb of entries in joint sequence), enable the temporalSync
+  bool signalOK = true;
+  unsigned nbFrameMain = mSlicerManagers[index]->GetImage()->GetTransform().size();
+  unsigned nbFrameSecondary = mSlicerManagers[index]->GetFusionSequenceNbFrames();
+std::cout<<"nbFrameMain = "<<nbFrameMain<<", nbFrameSecondary= "<<nbFrameSecondary<<", signal size: "<<tmpVect.size()<<std::endl;
+  std::vector<unsigned> temporalCorrespondances;
+  if ( tmpVect.size() == nbFrameMain + nbFrameSecondary ) {
+    for (unsigned i=0 ; i<tmpVect.size() ; i++) {
+      if (i<nbFrameMain) { //first part of the file: i -> index in secondary seq.
+        if ( tmpVect(i)<nbFrameSecondary ) temporalCorrespondances.push_back(tmpVect(i));
+        else { signalOK=false; break; } //pointing outside the secondary sequence...
+      }
+      else { //first part of the file -> index in secondary seq.
+        if ( tmpVect(i)<nbFrameMain ) temporalCorrespondances.push_back(tmpVect(i));
+        else { signalOK=false; break; } //pointing outside the secondary sequence...
+      }
+    }
   }
-  else {//else, send a message to signal the failure...
-    QString error = "The provided signal doesn't have the same duration as the sequence\n";
+  else {signalOK=false;}
+  if (!signalOK) {//else, send a message to signal the failure...
+    QString error = "The provided temporal correspondances is invalid - check tooltip.\n";
     error += "Ignoring file: " + fileName;
-    QMessageBox::information(this,tr("Problem adding signal!"),error);
+    QMessageBox::information(this,tr("Problem adding temporal correspondances!"),error);
     return;
   }
+  else {
+    //for convenience, associate this sequence to both the current slicer manager, and to the linked one
+    mSlicerManagers[index]->SetFusionSequenceCorrespondances(temporalCorrespondances);
+    mSlicerManagers[ mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager() ]->SetFusionSequenceCorrespondances(temporalCorrespondances);
+    overlayPanel->enableFusionSequenceTemporalSync();
+  }
 
 }
 //------------------------------------------------------------------------------
@@ -2499,6 +2523,7 @@ void vvMainWindow::AddFusionSequence(int index, std::vector<std::string> fileNam
     mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str();
     itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
       file.toStdString().c_str(), itk::ImageIOFactory::ReadMode);
+    std::sort (fileNames.begin(), fileNames.end());//make sure the files are sorted.
     reader->SetFileName(fileNames[0].c_str());
     reader->ReadImageInformation();
     std::string component = reader->GetComponentTypeAsString(reader->GetComponentType());
@@ -2566,8 +2591,15 @@ void vvMainWindow::AddFusionSequence(int index, std::vector<std::string> fileNam
 
       //This loads the secondary sequence (US) as an independent sequence
       LoadImages(fileNames, type);
-      //reset the transforms to identiy
+      //reset the transforms to identity
+      //FIX -- and set the thickness of the US slices to a large value (necessary for visualization purposes...)
+      double sp_x, sp_y, sp_z;
+      mSlicerManagers[indexParent]->GetImage()->GetVTKImages()[0]->GetSpacing(sp_x, sp_y, sp_z);
+      sp_z = std::max(sp_x, std::max(sp_y, sp_z)) + 0.5; //
       for (unsigned i=0 ; i<mSlicerManagers.back()->GetImage()->GetTransform().size() ; i++) {
+        sp_x = mSlicerManagers.back()->GetImage()->GetVTKImages()[i]->GetSpacing()[0];
+        sp_y = mSlicerManagers.back()->GetImage()->GetVTKImages()[i]->GetSpacing()[1];
+        mSlicerManagers.back()->GetImage()->GetVTKImages()[i]->SetSpacing( sp_x, sp_y, sp_z);
         mSlicerManagers.back()->GetImage()->GetTransform()[i]->Identity();
         mSlicerManagers.back()->GetImage()->GetTransform()[i]->Update();
       }
@@ -2590,7 +2622,7 @@ void vvMainWindow::AddFusionSequence(int index, std::vector<std::string> fileNam
       error += mSlicerManagers[index]->GetLastError().c_str();
       QMessageBox::information(this,tr("Problem reading image !"),error);
     }
-    //WindowLevelChanged();
+    WindowLevelChanged();
     ImageInfoChanged(); //this internally calls WindowLevelChanged...
   }
   else {
@@ -2608,7 +2640,7 @@ void vvMainWindow::SetFusionSequenceProperty(int fusionSequenceFrameIndex, bool
 {
   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
 
-  if (!mSlicerManagers[index]->IsInvolvedInFusionSequence()) return; 
+  if (!mSlicerManagers[index]->IsInvolvedInFusionSequence()) return;
 
   //check if the focus moved to the linked sequence, and in this case, select the master sequence instead
   if (!mSlicerManagers[index]->IsMainSequenceOfFusionSequence()) {
@@ -2616,8 +2648,8 @@ void vvMainWindow::SetFusionSequenceProperty(int fusionSequenceFrameIndex, bool
   }
   int secondaryIndex = mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager();
   if (secondaryIndex==-1) return; //this should never happen
-  if ( (!mSlicerManagers[index]->IsMainSequenceOfFusionSequence()) || 
-    (!mSlicerManagers[secondaryIndex]->IsSecondarySequenceOfFusionSequence()) ) 
+  if ( (!mSlicerManagers[index]->IsMainSequenceOfFusionSequence()) ||
+    (!mSlicerManagers[secondaryIndex]->IsSecondarySequenceOfFusionSequence()) )
   {return;} //this should never happen, raise an exception?
 
   if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
@@ -2651,21 +2683,13 @@ void vvMainWindow::SetFusionSequenceProperty(int fusionSequenceFrameIndex, bool
     if (spatialSyncFlag) { //reslice the CT
 
       if (temporalSyncFlag) { //do the temporal synchronisation
-        //TODO: add the temporal synchronisation stuff
-        //if the button is checked, get the phase of the requested US frame from the available signal
-        //and select the corresponding one in the CT. (check the one just before, and the one just after, and select the closest)
-
-        //TODO: do it also the other way around, when modifying the time index related to CT, select a close frame
-        //this should not be done here directly, but the code should be inspired from the one here
-        //->find a good US frame such that when calling this function with this US frame, it produces the expected result
-
-
-        //TODO: select the right CT image to display
         int mainSequenceFrameIndex=0;
         //estimate the TSlice to set to the CT
-
+        unsigned nbFramesMain = mSlicerManagers[index]->GetImage()->GetTransform().size();
+        mainSequenceFrameIndex = mSlicerManagers[index]->GetFusionSequenceCorrespondances()[ nbFramesMain + fusionSequenceFrameIndex];
         //and set it!
         mSlicerManagers[index]->SetTSlice(mainSequenceFrameIndex, false);
+        //warning, there is a loopback, and modification of the TSlice in main sequence forces an update of the TSlice in secondary, etc...
       }
 
 
@@ -2914,19 +2938,20 @@ void vvMainWindow::HorizontalSliderMoved(int value,int column, int slicer_index)
       //i is the SlicerManager that is in charge of this slicer.
       if (mSlicerManagers[i]->IsInvolvedInFusionSequence()) {
         //if the slicerManager is involved in a fusionSequence as the secondary sequence, then update the slider position in the overlay panel and everything accordingly
-        if (mSlicerManagers[i]->IsSecondarySequenceOfFusionSequence()) { 
-          overlayPanel->updateFusionSequenceSliderValueFromWindow(value, true); 
+        if (mSlicerManagers[i]->IsSecondarySequenceOfFusionSequence()) {
+          overlayPanel->updateFusionSequenceSliderValueFromWindow(value, true);
         }
         else { //if this is the primary sequence that has been modified
-          if (mSlicerManagers[i]->GetFusionSequenceTemporalSyncFlag()) {            
+          if (mSlicerManagers[i]->GetFusionSequenceTemporalSyncFlag()) {
             //WARNING: for some obscure reason, there are problems when accessing mSlicerManagers[mSlicerManagers[i]->GetFusionSequenceIndexOfLinkedManager()]->GetFusionSequenceFrameIndex();
 
-            //int estimatedValue=mSlicerManagers[mSlicerManagers[i]->GetFusionSequenceIndexOfLinkedManager()]->GetFusionSequenceFrameIndex();
             int estimatedValue=0;
-            //TODO: if temporal sync is active
             //estimate a corresponding time index for the secondary (US) sequence, and update it accordingly.
-            //estimatedValue = ...
-            overlayPanel->updateFusionSequenceSliderValueFromWindow(estimatedValue, true);
+            estimatedValue = mSlicerManagers[i]->GetFusionSequenceCorrespondances()[ value ];
+            //TODO: at the moment, there is a loop in TSlice modifications
+            //modifying sequence 1 causes seq 2 to update, which in turns update seq1...
+            //I disable control on seq1 at the moment.
+            //overlayPanel->updateFusionSequenceSliderValueFromWindow(estimatedValue, true);
           }
         }
       }
@@ -3221,9 +3246,9 @@ void vvMainWindow::SaveScreenshotAllSlices()
     // Change the slice
     slicer->SetSlice(i); // -> change the slice of the current slicer
     SM->UpdateSlice(0); // --> this one emit UpdateSlice
-    QCoreApplication::flush(); // -> needed to force display of contours 
+    QCoreApplication::flush(); // -> needed to force display of contours
 
-    // Screenshot  
+    // Screenshot
     vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
     windowToImageFilter->SetInput(renderWindow);
     windowToImageFilter->SetMagnification(1);
@@ -3237,7 +3262,7 @@ void vvMainWindow::SaveScreenshotAllSlices()
     if (i<100) num = "0"+num;
     if (i<1000) num = "0"+num;
 
-    fn = itksys::SystemTools::GetFilenamePath(filename.toStdString()) + "/"+ fn 
+    fn = itksys::SystemTools::GetFilenamePath(filename.toStdString()) + "/"+ fn
       + "_" + num + itksys::SystemTools::GetFilenameLastExtension(filename.toStdString());
     writer->SetFileName(fn.c_str());
     writer->SetInput(windowToImageFilter->GetOutput());
@@ -3633,4 +3658,3 @@ void vvMainWindow::UpdateCurrentSlicer()
   mSlicerManagerCurrentIndex = index;
 }
 //------------------------------------------------------------------------------
-