]> Creatis software - clitk.git/blobdiff - vv/vvMainWindow.cxx
continued the fusion sequence visualization mode
[clitk.git] / vv / vvMainWindow.cxx
index 46b0ecbb2fd9f2bb1a7656876978d531c734631c..cde6d50ada2dd6e719bb98a4bda9915b83fb393c 100644 (file)
 #define COLUMN_RELOAD_IMAGE 6
 #define COLUMN_IMAGE_NAME 7
 
-#define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr)"
+#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)"
+#else
+#define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr *.refscan *.nii.gz)"
+#endif
+
 
 /*Data Tree values
   0,Qt::UserRole full filename
@@ -176,6 +181,10 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   contextMenu.addAction(actionAdd_fusion_image);
   contextActions.push_back(actionAdd_fusion_image);
 
+  contextMenu.addAction(actionAdd_USSequence_toCT);
+  contextActions.push_back(actionAdd_USSequence_toCT);
+
+
   contextMenu.addSeparator();
   QAction* actionResetMatrix = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/identity.png")),
                                                       tr("Reset transformation to identity"));
@@ -229,6 +238,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   actionSave_As->setEnabled(0);
   actionAdd_VF_to_current_Image->setEnabled(0);
   actionAdd_fusion_image->setEnabled(0);
+  actionAdd_USSequence_toCT->setEnabled(0);
 
   //init the sliders
   verticalSliders.push_back(NOVerticalSlider);
@@ -276,10 +286,15 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(actionExit,SIGNAL(triggered()),this,SLOT(close()));
   connect(actionAdd_VF_to_current_Image,SIGNAL(triggered()),this,SLOT(OpenField()));
   connect(actionAdd_fusion_image,SIGNAL(triggered()),this,SLOT(SelectFusionImage()));
-  connect(actionAdd_overlay_image_to_current_image,SIGNAL(triggered()), this,SLOT(SelectOverlayImage()));  connect(actionNavigation_Help,SIGNAL(triggered()),this,SLOT(ShowHelpDialog()));
+  connect(actionAdd_overlay_image_to_current_image,SIGNAL(triggered()), this,SLOT(SelectOverlayImage()));
+  connect(actionAdd_USSequence_toCT,SIGNAL(triggered()), this,SLOT(SelectFusionSequence()));
+  connect(actionNavigation_Help,SIGNAL(triggered()),this,SLOT(ShowHelpDialog()));
   connect(actionDocumentation,SIGNAL(triggered()),this,SLOT(ShowDocumentation()));
   connect(actionRegister_vv,SIGNAL(triggered()),this,SLOT(PopupRegisterForm()));
 
+  connect(overlayPanel, SIGNAL(FusionSequenceSignalButtonPressed()), this, SLOT(SelectFusionSequenceTemporalSignal()));
+
+
   ///////////////////////////////////////////////
   connect(actionSegmentation,SIGNAL(triggered()),this,SLOT(SegmentationOnCurrentImage()));
   connect(actionSurface_Viewer,SIGNAL(triggered()),this,SLOT(SurfaceViewerLaunch()));
@@ -305,13 +320,13 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(levelSpinBox,SIGNAL(editingFinished()),this,SLOT(WindowLevelEdited()));
   connect(colorMapComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(UpdateColorMap()));
   connect(presetComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(UpdateWindowLevel()));
+  connect(slicingPresetComboBox, SIGNAL(currentIndexChanged(int)),this,SLOT(UpdateSlicingPreset()));
   connect(inverseButton,SIGNAL(clicked()),this,SLOT(SwitchWindowLevel()));
   connect(applyWindowLevelToAllButton,SIGNAL(clicked()),this,SLOT(ApplyWindowLevelToAllImages()));
 
-
   connect(this,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(ShowContextMenu(QPoint)));
 
-  connect(linkPanel,SIGNAL(addLink(QString,QString)),this,SLOT(AddLink(QString,QString)));
+  connect(linkPanel,SIGNAL(addLink(QString,QString,bool)),this,SLOT(AddLink(QString,QString,bool)));
   connect(linkPanel,SIGNAL(removeLink(QString,QString)),this,SLOT(RemoveLink(QString,QString)));
   connect(overlayPanel,SIGNAL(VFPropertyUpdated(int,int,int,int,double,double,double)),this,SLOT(SetVFProperty(int,int,int,int,double,double,double)));
   connect(overlayPanel,SIGNAL(OverlayPropertyUpdated(int,int,double,double)),
@@ -320,6 +335,10 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
           this,SLOT(SetFusionProperty(int,int,int,double,double, bool)));
   connect(landmarksPanel,SIGNAL(UpdateRenderWindows()),this,SLOT(UpdateRenderWindows()));
 
+  connect(overlayPanel,SIGNAL(FusionSequencePropertyUpdated(int, bool, unsigned int, bool)),
+          this,SLOT(SetFusionSequenceProperty(int, bool,unsigned int, bool)));
+
+
   playMode = 0;//pause
   mFrameRate = 10;
   playButton->setEnabled(0);
@@ -356,6 +375,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   //timerMemory->setInterval(5);
   connect(timerMemory, SIGNAL(timeout()), this, SLOT(UpdateMemoryUsage()));
   timerMemory->start(2000);
+
 }
 //------------------------------------------------------------------------------
 void vvMainWindow::show()
@@ -699,51 +719,8 @@ void vvMainWindow::MergeImagesWithTime()
   mInputPathName = itksys::SystemTools::GetFilenamePath(files[0].toStdString()).c_str();
   std::vector<std::string> vector;
 
-  unsigned int currentDim = 0;
-  std::vector<double> currentSpacing;
-  std::vector<int> currentSize;
-  std::vector<double> currentOrigin;
-
-  for (int i = 0; i < files.size(); i++) {
-    itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
-                                         files[i].toStdString().c_str(), itk::ImageIOFactory::ReadMode);
-    if (reader) {
-      reader->SetFileName(files[i].toStdString().c_str());
-      reader->ReadImageInformation();
-      if (i == 0)
-        currentDim = reader->GetNumberOfDimensions();
-      bool IsOk = true;
-      for (unsigned int j = 0; j < currentDim; j++) {
-        if (i == 0) {
-          if (j == 0) {
-            currentSpacing.resize(currentDim);
-            currentSize.resize(currentDim);
-            currentOrigin.resize(currentDim);
-          }
-          currentOrigin[j] = reader->GetOrigin(j);
-          currentSpacing[j] = reader->GetSpacing(j);
-          currentSize[j] = reader->GetDimensions(j);
-        } else if (currentDim != reader->GetNumberOfDimensions()
-                   || currentSpacing[j] != reader->GetSpacing(j)
-                   || currentSize[j] != (int)reader->GetDimensions(j)
-                   || currentOrigin[j] != reader->GetOrigin(j)) {
-          QString error = "Cannot read file (too different from others ";
-          error += files[i].toStdString().c_str();
-          QMessageBox::information(this,tr("Reading problem"),error);
-          IsOk = false;
-          break;
-        }
-      }
-      if (IsOk)
-        vector.push_back(files[i].toStdString());
-    } else {
-      QString error = "Cannot read file info for ";
-      error += files[i].toStdString().c_str();
-      error += "\n";
-      error += "Maybe you're trying to open an image in an unsupported format?\n";
-      QMessageBox::information(this,tr("Reading problem"),error);
-    }
-  }
+  for (int i = 0; i < files.size(); i++)
+    vector.push_back(files[i].toStdString());
   sort(vector.begin(),vector.end());
   if (vector.size() > 1)
     LoadImages(vector, vvImageReader::MERGEDWITHTIME);
@@ -863,12 +840,11 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::Loa
   int numberofsuccesulreads=0;
   //open images as 1 or multiples
   for (int i = 0; i < fileSize; i++) {
-
     progress.SetText("Opening " + files[i]);
     progress.SetProgress(i,fileSize);
     qApp->processEvents();
 
-    for (unsigned int j = 0; j < nSlices[i]; j++) {
+       for (unsigned int j = 0; j < nSlices[i]; j++) {
       //read the image and put it in mSlicerManagers
       vvSlicerManager* imageManager = new vvSlicerManager(4);
       qApp->processEvents();
@@ -883,7 +859,8 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::Loa
       else {
         SetImageSucceed = imageManager->SetImages(files,filetype, number);
       }
-      if (!SetImageSucceed) {
+
+         if (!SetImageSucceed) {
         QApplication::restoreOverrideCursor();
         QString error = "Cannot open file \n";
         error += imageManager->GetLastError().c_str();
@@ -901,7 +878,7 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::Loa
         item->setToolTip(COLUMN_IMAGE_NAME, imageManager->GetListOfAbsoluteFilePathInOneString("image").c_str());
         qApp->processEvents();
 
-        //Create the buttons for reload and close
+               //Create the buttons for reload and close
         qApp->processEvents();
         QTreePushButton* cButton = new QTreePushButton;
         cButton->setItem(item);
@@ -924,13 +901,13 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::Loa
         DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
 
         //set the id of the image
-        QString id = files[i].c_str() + QString::number(mSlicerManagers.size()-1);
+        QString id = QDir::current().absoluteFilePath(files[i].c_str()) + QString::number(mSlicerManagers.size()-1);
         item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
         mSlicerManagers.back()->SetId(id.toStdString());
 
         linkPanel->addImage(imageManager->GetFileName(), id.toStdString());
 
-        connect(mSlicerManagers.back(), SIGNAL(currentImageChanged(std::string)),
+               connect(mSlicerManagers.back(), SIGNAL(currentImageChanged(std::string)),
                 this,SLOT(CurrentImageChanged(std::string)));
         connect(mSlicerManagers.back(), SIGNAL(currentPickedImageChanged(std::string)),
                 this, SLOT(CurrentPickedImageChanged(std::string)));
@@ -948,6 +925,8 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::Loa
                 this,SLOT(UpdateSlice(int,int)));
         connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
                 this,SLOT(UpdateTSlice(int, int)));
+        connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
+                this,SLOT(ImageInfoChanged()));
         connect(mSlicerManagers.back(), SIGNAL(UpdateSliceRange(int,int,int,int,int)),
                 this,SLOT(UpdateSliceRange(int,int,int,int,int)));
         connect(mSlicerManagers.back(), SIGNAL(UpdateLinkManager(std::string,int,double,double,double,int)),
@@ -957,7 +936,8 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::Loa
         connect(mSlicerManagers.back(), SIGNAL(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)),
                 this,SLOT(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)));
         connect(mSlicerManagers.back(),SIGNAL(LandmarkAdded()),landmarksPanel,SLOT(AddPoint()));
-        InitSlicers();
+
+               InitSlicers();
         numberofsuccesulreads++;
       }
     }
@@ -1049,6 +1029,7 @@ void vvMainWindow::ImageInfoChanged()
   actionAdd_VF_to_current_Image->setEnabled(1);
   actionAdd_fusion_image->setEnabled(1);
   actionAdd_overlay_image_to_current_image->setEnabled(1);
+  actionAdd_USSequence_toCT->setEnabled(1);
   actionNorth_East_Window->setEnabled(1);
   actionNorth_West_Window->setEnabled(1);
   actionSouth_East_Window->setEnabled(1);
@@ -1064,13 +1045,14 @@ void vvMainWindow::ImageInfoChanged()
     colorMapComboBox->setEnabled(1);
     for (int i = 0; i < DataTree->topLevelItem(index)->childCount(); i++) {
       if (DataTree->topLevelItem(index)->child(i)->data(1,Qt::UserRole).toString() == "overlay" ||
-          DataTree->topLevelItem(index)->child(i)->data(1,Qt::UserRole).toString() == "fusion") {
+          DataTree->topLevelItem(index)->child(i)->data(1,Qt::UserRole).toString() == "fusion" ||
+          DataTree->topLevelItem(index)->child(i)->data(1,Qt::UserRole).toString() == "fusionSequence") {
         colorMapComboBox->setEnabled(0);
         break;
       }
     }
 
-    std::vector<double> origin;
+       std::vector<double> origin;
     std::vector<double> inputSpacing;
     std::vector<int> inputSize;
     std::vector<double> sizeMM;
@@ -1080,7 +1062,9 @@ void vvMainWindow::ImageInfoChanged()
     QString inputSizeInBytes;
     QString image = DataTree->selectedItems()[0]->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString();
 
-    if (mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetVTKImages().size() > 1 || playMode == 1) {
+       int nframes = mSlicerManagers[index]->GetSlicer(0)->GetTMax();
+
+       if (nframes > 1 || playMode == 1) {
       playButton->setEnabled(1);
       frameRateLabel->setEnabled(1);
       frameRateSpinBox->setEnabled(1);
@@ -1093,24 +1077,35 @@ void vvMainWindow::ImageInfoChanged()
     //read image header
     int NPixel = 1;
 
+       int tSlice = 0;
     vvImage::Pointer imageSelected;
     if (DataTree->topLevelItem(index) == DataTree->selectedItems()[0]) {
       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
+      tSlice = mSlicerManagers[index]->GetSlicer(0)->GetTSlice();
     } else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "vector") {
       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetVF();
+      tSlice = mSlicerManagers[index]->GetSlicer(0)->GetOverlayTSlice();
     } else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "overlay") {
       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetOverlay();
+      tSlice = mSlicerManagers[index]->GetSlicer(0)->GetOverlayTSlice();
     } else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "fusion") {
-      imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetFusion();
+       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetFusion();
+       tSlice = mSlicerManagers[index]->GetSlicer(0)->GetFusionTSlice();
     }
+    else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "fusionSequence") {
+       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetFusion();
+       tSlice = mSlicerManagers[index]->GetSlicer(0)->GetFusionTSlice();
+       }
     else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "contour") {
-      imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
+       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
+       tSlice = mSlicerManagers[index]->GetSlicer(0)->GetTSlice();
     }
     else {
-      imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
+       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
+       tSlice = mSlicerManagers[index]->GetSlicer(0)->GetTSlice();
     }
 
-    dimension = imageSelected->GetNumberOfDimensions();
+       dimension = imageSelected->GetNumberOfDimensions();
     origin.resize(dimension);
     inputSpacing.resize(dimension);
     inputSize.resize(dimension);
@@ -1124,7 +1119,7 @@ void vvMainWindow::ImageInfoChanged()
       NPixel *= inputSize[i];
     }
     inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000);
-    
+
     QString dim = QString::number(dimension) + " (";
     dim += pixelType + ")";
 
@@ -1135,10 +1130,11 @@ void vvMainWindow::ImageInfoChanged()
     infoPanel->setOrigin(GetVectorDoubleAsString(origin));
     infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing));
     infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")");
-    transformation = imageSelected->GetTransform()->GetMatrix();
+
+       transformation = imageSelected->GetTransform()[tSlice]->GetMatrix();
     infoPanel->setTransformation(Get4x4MatrixDoubleAsString(transformation));
 
-    landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
+       landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
                                         mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetVTKImages().size());
     landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
     landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
@@ -1151,7 +1147,7 @@ void vvMainWindow::ImageInfoChanged()
       }
     }
 
-    infoPanel->setFileName(image);
+       infoPanel->setFileName(image);
     infoPanel->setDimension(dim);
     infoPanel->setSizePixel(GetVectorIntAsString(inputSize));
     infoPanel->setSizeMM(GetVectorDoubleAsString(sizeMM));
@@ -1171,9 +1167,11 @@ void vvMainWindow::ImageInfoChanged()
         break;
       }
     }
-    WindowLevelChanged();
+       WindowLevelChanged();
+
+       slicingPresetComboBox->setCurrentIndex(mSlicerManagers[index]->GetSlicingPreset());
 
-    if (mSlicerManagers[index]->GetSlicer(0)->GetVF()) {
+       if (mSlicerManagers[index]->GetSlicer(0)->GetVF()) {
       overlayPanel->getVFName(mSlicerManagers[index]->GetVFName().c_str());
       overlayPanel->getVFProperty(mSlicerManagers[index]->GetSlicer(0)->GetVFSubSampling(),
                                   mSlicerManagers[index]->GetSlicer(0)->GetVFScale(),
@@ -1187,8 +1185,8 @@ void vvMainWindow::ImageInfoChanged()
     } else {
       overlayPanel->getOverlayName(mSlicerManagers[index]->GetOverlayName().c_str());
     }
-    
-    if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
+       if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
       overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str());
     } else {
       overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str());
@@ -1229,25 +1227,70 @@ void vvMainWindow::ShowHelpDialog()
 //------------------------------------------------------------------------------
 void vvMainWindow::ChangeViewMode()
 {
-  QList<int> size;
+  typedef struct _SIZE{
+    QSplitter* splitter;
+    QList<int> size1, size2;
+    int cols[3];
+  }SplitterSize;
+  SplitterSize sizes[4];
+  sizes[0].splitter = OSplitter;
+  sizes[0].size1.push_back(1);
+  sizes[0].size1.push_back(0);
+  sizes[0].size2.push_back(1);
+  sizes[0].size2.push_back(0);
+  sizes[0].cols[0] = 2;
+  sizes[0].cols[1] = 3;
+  sizes[0].cols[2] = 4;
+
+  sizes[1].splitter = ESplitter;
+  sizes[1].size1.push_back(0);
+  sizes[1].size1.push_back(1);
+  sizes[1].size2.push_back(1);
+  sizes[1].size2.push_back(0);
+  sizes[1].cols[0] = 1;
+  sizes[1].cols[1] = 3;
+  sizes[1].cols[2] = 4;
+
+  sizes[2].splitter = OSplitter;
+  sizes[2].size1.push_back(1);
+  sizes[2].size1.push_back(0);
+  sizes[2].size2.push_back(0);
+  sizes[2].size2.push_back(1);
+  sizes[2].cols[0] = 1;
+  sizes[2].cols[1] = 2;
+  sizes[2].cols[2] = 4;
+
+  sizes[3].splitter = ESplitter;
+  sizes[3].size1.push_back(0);
+  sizes[3].size1.push_back(1);
+  sizes[3].size2.push_back(0);
+  sizes[3].size2.push_back(1);
+  sizes[3].cols[0] = 1;
+  sizes[3].cols[1] = 2;
+  sizes[3].cols[2] = 3;
+  
+  int slicer = mSlicerManagers[mCurrentPickedImageIndex]->GetSelectedSlicer();
   if (viewMode == 1) {
-    viewMode = 0;
-    size.push_back(1);
-    size.push_back(0);
-    splitter_3->setSizes(size);
-    OSplitter->setSizes(size);
-    DataTree->setColumnHidden(2,1);
-    DataTree->setColumnHidden(3,1);
-    DataTree->setColumnHidden(4,1);
+    if (slicer >= 0) {
+      viewMode = 0;
+      splitter_3->setSizes(sizes[slicer].size1);
+      sizes[slicer].splitter->setSizes(sizes[slicer].size2);
+      DataTree->setColumnHidden(sizes[slicer].cols[0],1);
+      DataTree->setColumnHidden(sizes[slicer].cols[1],1);
+      DataTree->setColumnHidden(sizes[slicer].cols[2],1);
+    }
   } else {
-    viewMode = 1;
-    size.push_back(1);
-    size.push_back(1);
-    splitter_3->setSizes(size);
-    OSplitter->setSizes(size);
-    DataTree->setColumnHidden(2,0);
-    DataTree->setColumnHidden(3,0);
-    DataTree->setColumnHidden(4,0);
+    QList<int> size;
+    if (slicer >= 0) {
+      viewMode = 1;
+      size.push_back(1);
+      size.push_back(1);
+      splitter_3->setSizes(size);
+      sizes[slicer].splitter->setSizes(size);
+      DataTree->setColumnHidden(sizes[slicer].cols[0],0);
+      DataTree->setColumnHidden(sizes[slicer].cols[1],0);
+      DataTree->setColumnHidden(sizes[slicer].cols[2],0);
+    }
   }
   UpdateRenderWindows();
   /*
@@ -1255,10 +1298,12 @@ void vvMainWindow::ChangeViewMode()
   ** the associated Slicer to redraw crosses.
   */
   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
-    if (DataTree->topLevelItem(i)->data(COLUMN_UL_VIEW,Qt::CheckStateRole).toInt() > 1)
+//     if (DataTree->topLevelItem(i)->data(COLUMN_UL_VIEW,Qt::CheckStateRole).toInt() > 1)
       mSlicerManagers[i]->GetSlicer(0)->Render();
-    if (DataTree->topLevelItem(i)->data(COLUMN_DL_VIEW,Qt::CheckStateRole).toInt() > 1)
+      mSlicerManagers[i]->GetSlicer(1)->Render();
+//     if (DataTree->topLevelItem(i)->data(COLUMN_DL_VIEW,Qt::CheckStateRole).toInt() > 1)
       mSlicerManagers[i]->GetSlicer(2)->Render();
+      mSlicerManagers[i]->GetSlicer(3)->Render();
   }
 }
 //------------------------------------------------------------------------------
@@ -1344,6 +1389,7 @@ QString vvMainWindow::GetVectorIntAsString(std::vector<int> vectorInt)
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
+//this actually returns the SlicerManager index!
 int vvMainWindow::GetSlicerIndexFromItem(QTreeWidgetItem* item)
 {
   QString id = item->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
@@ -1462,13 +1508,13 @@ void vvMainWindow::InitDisplay()
       for (int i = 0; i < DataTree->topLevelItemCount(); i++) {
         mSlicerManagers[i]->SetInteractorStyleNavigator(j,style);
 
-        //select the image only if previous are not selected
+               //select the image only if previous are not selected
         if (DataTree->topLevelItem(i)->data(j+1,Qt::CheckStateRole).toInt() > 1) {
           mSlicerManagers[i]->UpdateSlicer(j,1);
-          AlreadySelected = true;
+                 AlreadySelected = true;
         } else if (i == DataTree->topLevelItemCount()-1 && !AlreadySelected) {
           if (DataTree->selectedItems().size() == 0)
-            DataTree->topLevelItem(i)->setSelected(1);
+            DataTree->topLevelItem(i)->setSelected(1); //RB: crash here when loading an image...
           DataTree->topLevelItem(i)->setData(j+1,Qt::CheckStateRole,2);
           mSlicerManagers[i]->UpdateSlicer(j,1);
           DisplaySliders(i,j);
@@ -1486,38 +1532,28 @@ void vvMainWindow::InitDisplay()
 //------------------------------------------------------------------------------
 void vvMainWindow::DisplaySliders(int slicer, int window)
 {
+  if(!mSlicerManagers[slicer]->GetSlicer(window)->GetRenderer()->GetDraw())
+    return;
+
   int range[2];
   mSlicerManagers[slicer]->GetSlicer(window)->GetSliceRange(range);
   int position = mSlicerManagers[slicer]->GetSlicer(window)->GetSlice();
-
-  int tRange[2];
-  tRange[0] = 0;
-  tRange[1] = mSlicerManagers[slicer]->GetSlicer(window)->GetTMax();
-  int tPosition = mSlicerManagers[slicer]->GetSlicer(window)->GetTSlice();
-  bool showHorizontal = false;
-  bool showVertical = false;
-  if (mSlicerManagers[slicer]->GetSlicer(window)->GetImage()->GetNumberOfDimensions() > 3
-      || (mSlicerManagers[slicer]->GetSlicer(window)->GetImage()->GetNumberOfDimensions() > 2
-          && mSlicerManagers[slicer]->GetType() != vvImageReader::IMAGEWITHTIME
-          && mSlicerManagers[slicer]->GetType() != vvImageReader::MERGEDWITHTIME))
-    showVertical = true;
-  if (mSlicerManagers[slicer]->GetSlicer(window)->GetImage()->GetNumberOfDimensions() > 3
-      || mSlicerManagers[slicer]->GetType() == vvImageReader::IMAGEWITHTIME
-      || mSlicerManagers[slicer]->GetType() == vvImageReader::MERGEDWITHTIME)
-    showHorizontal = true;
-
-  if (showVertical)
+  if (range[1]>0)
     verticalSliders[window]->show();
   else
     verticalSliders[window]->hide();
   verticalSliders[window]->setRange(range[0],range[1]);
   verticalSliders[window]->setValue(position);
 
-  if (showHorizontal)
+  int tRange[2];
+  tRange[0] = 0;
+  tRange[1] = mSlicerManagers[slicer]->GetSlicer(window)->GetTMax();
+  if (tRange[1]>0)
     horizontalSliders[window]->show();
   else
     horizontalSliders[window]->hide();
   horizontalSliders[window]->setRange(tRange[0],tRange[1]);
+  int tPosition = mSlicerManagers[slicer]->GetSlicer(window)->GetMaxCurrentTSlice();
   horizontalSliders[window]->setValue(tPosition);
 }
 //------------------------------------------------------------------------------
@@ -1543,6 +1579,16 @@ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column)
           overlay_index++;
         if (DataTree->topLevelItem(index)->child(child) == item) break;
       }
+         if (overlay_type=="fusionSequence") {
+                 //removing the overlay sequence in a fusion sequence visualization mode 
+                 //TODO: remove the synchronization (transform matrices, etc...)
+
+                 //=> unlink and untie the slicer managers
+                 mSlicerManagers[index]->SetFusionSequenceInvolvmentCode(-1);
+                 mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->SetFusionSequenceInvolvmentCode(-1);
+                 RemoveLink(mSlicerManagers[index]->GetId().c_str(), mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->GetId().c_str());
+
+         }
       mSlicerManagers[index]->RemoveActor(overlay_type, overlay_index-1);
       mSlicerManagers[index]->SetColorMap(0);
       DataTree->topLevelItem(index)->takeChild(DataTree->topLevelItem(index)->indexOfChild(item));
@@ -1578,6 +1624,17 @@ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column)
       }
       linkPanel->removeImage(index);
       mSlicerManagers[index]->RemoveActors();
+
+         //if the slicer manager was involved in a fusion sequence visualization...
+         if ( item->data(1,Qt::UserRole).toString().toStdString() == "fusionSequence" ) {
+                 //TODO
+                 //make sure both SlicerManager exit the FusionSequence visualization mode
+                 //disable the temporal and spatial sync? make sure we reset the spatial transforms to their initial states...
+                 mSlicerManagers[index]->SetFusionSequenceInvolvmentCode(-1);
+                 mSlicerManagers[mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()]->SetFusionSequenceInvolvmentCode(-1);
+         }
+
+         //remove the slicer manager
       delete mSlicerManagers[index];
       mSlicerManagers.erase(Manageriter);
 
@@ -1603,17 +1660,24 @@ void vvMainWindow::ReloadImage(QTreeWidgetItem* item, int column)
   int index = GetSlicerIndexFromItem(item);
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
   QString role=item->data(1,Qt::UserRole).toString();
-  if ( role == "vector"){
+  if ( role == "vector") {
     mSlicerManagers[index]->ReloadVF();
   }
-  else if (role == "overlay"){
+  else if (role == "overlay") {
     mSlicerManagers[index]->ReloadOverlay();
   }
-  else if (role == "fusion"){
+  else if (role == "fusion") {
     mSlicerManagers[index]->ReloadFusion();
   }
-  else{
+  else if (role == "fusionSequence") {
+    //both versions of the secondary sequence must be updated.
+    mSlicerManagers[index]->ReloadFusionSequence();
+    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(); 
   }
   // Update view and info
   ImageInfoChanged();
@@ -1670,15 +1734,38 @@ void vvMainWindow::WindowLevelChanged()
   else
     overlayPanel->getOverlayProperty(-1,0,0.,0.);
 
-  // Fusion image
-  if (mSlicerManagers[index]->GetSlicer(0)->GetFusion())
-    overlayPanel->getFusionProperty(mSlicerManagers[index]->GetFusionOpacity(),
-                                    mSlicerManagers[index]->GetFusionThresholdOpacity(),
-                                    mSlicerManagers[index]->GetFusionColorMap(),
-                                    mSlicerManagers[index]->GetFusionWindow(),
-                                    mSlicerManagers[index]->GetFusionLevel());
+  // Fusion & SequenceFusion image
+  if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
+         overlayPanel->getFusionProperty(mSlicerManagers[index]->GetFusionOpacity(),
+                 mSlicerManagers[index]->GetFusionThresholdOpacity(),
+                 mSlicerManagers[index]->GetFusionColorMap(),
+                 mSlicerManagers[index]->GetFusionWindow(),
+                 mSlicerManagers[index]->GetFusionLevel());
+         if (mSlicerManagers[index]->IsMainSequenceOfFusionSequence()) {
+                 overlayPanel->getFusionSequenceProperty(mSlicerManagers[index]->GetFusionSequenceFrameIndex(),
+                         mSlicerManagers[index]->GetFusionSequenceSpatialSyncFlag(), 
+                         mSlicerManagers[index]->GetFusionSequenceNbFrames(),
+                         mSlicerManagers[index]->GetFusionSequenceTemporalSyncFlag());
+         }
+  }
+  else if ( mSlicerManagers[index]->IsSecondarySequenceOfFusionSequence() ) {
+         //if the image is involved in a fusion sequence, preserve the overlay panel!
+         int ind = mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager();
+         overlayPanel->getFusionProperty(mSlicerManagers[ind]->GetFusionOpacity(),
+                 mSlicerManagers[ind]->GetFusionThresholdOpacity(),
+                 mSlicerManagers[ind]->GetFusionColorMap(),
+                 mSlicerManagers[ind]->GetFusionWindow(),
+                 mSlicerManagers[ind]->GetFusionLevel());
+         overlayPanel->getFusionSequenceProperty(mSlicerManagers[ind]->GetFusionSequenceFrameIndex(),
+                 mSlicerManagers[ind]->GetFusionSequenceSpatialSyncFlag(), 
+                 mSlicerManagers[ind]->GetFusionSequenceNbFrames(),
+                 mSlicerManagers[ind]->GetFusionSequenceTemporalSyncFlag());
+  }
   else
-    overlayPanel->getFusionProperty(-1, -1, -1, -1, -1);
+  {
+         overlayPanel->getFusionProperty(-1, -1, -1, -1, -1);
+         overlayPanel->getFusionSequenceProperty(-1, false, 0, false);
+  }
 }
 //------------------------------------------------------------------------------
 
@@ -1717,6 +1804,16 @@ void vvMainWindow::UpdateWindowLevel()
 }
 //------------------------------------------------------------------------------
 
+//------------------------------------------------------------------------------
+void vvMainWindow::UpdateSlicingPreset()
+{
+  if (DataTree->selectedItems().size()) {
+    int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+    mSlicerManagers[index]->SetSlicingPreset(vvSlicerManager::SlicingPresetType(slicingPresetComboBox->currentIndex()));
+  }
+}
+//------------------------------------------------------------------------------
+
 //------------------------------------------------------------------------------
 void vvMainWindow::UpdateColorMap()
 {
@@ -1757,19 +1854,44 @@ void vvMainWindow::ApplyWindowLevelToAllImages()
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::UpdateLinkManager(std::string id, int slicer, double x, double y, double z, int temps)
+void vvMainWindow::ApplyWindowToSetOfImages(double window, unsigned int indexMin, unsigned int indexMax)
 {
-  for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
-    if (mSlicerManagers[i]->GetId() == id) {
-      //mSlicerManagers[i]->SetTSlice(temps);
-      mSlicerManagers[i]->GetSlicer(slicer)->SetCurrentPosition(x,y,z,temps);
-      mSlicerManagers[i]->UpdateViews(0,slicer);
-      break;
-    }
+  for (unsigned int i = indexMin; i <= indexMax && i < mSlicerManagers.size(); i++) {
+    if (mSlicerManagers[i] == NULL)
+      continue;
+    mSlicerManagers[i]->SetColorWindow(window);
+    mSlicerManagers[i]->SetPreset(6);
+    mSlicerManagers[i]->Render();
   }
 }
 //------------------------------------------------------------------------------
 
+//------------------------------------------------------------------------------
+void vvMainWindow::ApplyLevelToSetOfImages(double level, unsigned int indexMin, unsigned int indexMax)
+{
+  for (unsigned int i = indexMin; i <= indexMax && i < mSlicerManagers.size(); i++) {
+    if (mSlicerManagers[i] == NULL)
+      continue;
+    mSlicerManagers[i]->SetColorLevel(level);
+    mSlicerManagers[i]->SetPreset(6);
+    mSlicerManagers[i]->Render();
+  }
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvMainWindow::UpdateLinkManager(std::string id, int slicer, double x, double y, double z, int temps)
+{
+       for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
+               if (mSlicerManagers[i]->GetId() == id) {
+                       mSlicerManagers[i]->GetSlicer(slicer)->SetCurrentPosition(x,y,z,temps);
+                       mSlicerManagers[i]->UpdateViews(0,slicer);
+                       break;
+               }
+       }
+}
+//------------------------------------------------------------------------------
+
 //------------------------------------------------------------------------------
 void vvMainWindow::UpdateLinkedNavigation(std::string id, vvSlicerManager * sm, vvSlicer* refSlicer)
 {
@@ -1841,21 +1963,28 @@ void vvMainWindow::SelectOverlayImage()
 
   QString Extensions = EXTENSIONS;
   Extensions += ";;All Files (*)";
-  QString file = QFileDialog::getOpenFileName(this,tr("Load Overlay image"),mInputPathName,Extensions);
-  if (!file.isEmpty())
-    AddOverlayImage(index,file);
+  QStringList files = QFileDialog::getOpenFileNames(this,tr("Load Overlay 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());
+  }
+  AddOverlayImage(index,vecFileNames,vvImageReader::IMAGE);
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::AddOverlayImage(int index, QString file)
+void vvMainWindow::AddOverlayImage(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());
     int dimension = reader->GetNumberOfDimensions();
@@ -1864,7 +1993,7 @@ void vvMainWindow::AddOverlayImage(int index, QString file)
     qApp->processEvents();
 
     std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str();
-    if (mSlicerManagers[index]->SetOverlay(file.toStdString(),dimension, component)) {
+    if (mSlicerManagers[index]->SetOverlay(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());
@@ -1908,6 +2037,10 @@ void vvMainWindow::AddOverlayImage(int index, QString file)
       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";
@@ -1956,7 +2089,8 @@ void vvMainWindow::SelectFusionImage()
 
   //check if one fusion image is added
   for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++)
-    if (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusion") {
+    if ( (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusion") ||
+       (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusionSequence") ) {
       QString error = "Cannot add more than one fusion image\n";
       error += "Please remove first ";
       error += DataTree->topLevelItem(index)->child(child)->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString();
@@ -2077,7 +2211,11 @@ void vvMainWindow::OpenField()
 
   QString Extensions = "Images ( *.mhd)";
   Extensions += ";;Images ( *.mha)";
-  Extensions += ";;Images ( *.vf)";
+  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())
     AddField(file,index);
@@ -2232,11 +2370,293 @@ void vvMainWindow::SetFusionProperty(int opacity, int thresOpacity, int colormap
     mSlicerManagers[index]->SetFusionLevel(level);
     mSlicerManagers[index]->SetFusionShowLegend(showLegend);
     mSlicerManagers[index]->SetColorMap(0);
-    mSlicerManagers[index]->Render();
+       mSlicerManagers[index]->Render();
   }
 }
 //------------------------------------------------------------------------------
 
+
+//------------------------------------------------------------------------------
+void vvMainWindow::SelectFusionSequence()
+{
+       //get the index of the slicer manager of the main sequence (CT)
+  int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+  //check if one overlay image is already associated
+  for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++)
+    if ( (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusion") ||
+       (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusionSequence") ) {
+      QString error = "Cannot add more than one compared image\n";
+      error += "Please remove first ";
+      error += DataTree->topLevelItem(index)->child(child)->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString();
+      QMessageBox::information(this,tr("Problem adding compared image !"),error);
+      return;
+    }
+
+  QString Extensions = EXTENSIONS;
+  Extensions += ";;All Files (*)";
+  QStringList files = QFileDialog::getOpenFileNames(this,tr("Load Overlay image sequence"),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());
+  }
+  //associate the secondary sequence (US) to the main one
+  AddFusionSequence(index,vecFileNames,vvImageReader::MERGEDWITHTIME);
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvMainWindow::SelectFusionSequenceTemporalSignal() {
+
+       //make sure the index is right?
+       //in the end, I should attach the temporal data to the right sequence!
+       int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+       //in case the other sequence got selected, make sure we select the primary sequence
+       if ( (!mSlicerManagers[index]->GetSlicer(0)->GetFusion()) && mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()>=0 ) {
+               index = mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager();
+       }
+
+       //open a dialog box to find a file
+       QString Extensions = EXTENSIONS;
+       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);
+       }
+       else {//else, send a message to signal the failure...
+               QString error = "The provided signal doesn't have the same duration as the sequence\n";
+               error += "Ignoring file: " + fileName;
+               QMessageBox::information(this,tr("Problem adding signal!"),error);
+               return;
+       }
+
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+//when this function is called index is the slicer manager index corresponding to the main sequence (CT)
+//the files behind fileNames points to the data for the secondary sequence
+void vvMainWindow::AddFusionSequence(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(fileNames[0].c_str());
+               reader->ReadImageInformation();
+               std::string component = reader->GetComponentTypeAsString(reader->GetComponentType());
+               int dimension = reader->GetNumberOfDimensions();
+               QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+               vvProgressDialog progress("Opening " + file.toStdString());
+               qApp->processEvents();
+
+               std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str();
+
+               if (mSlicerManagers[index]->SetFusionSequence(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("fusionSequence"));
+
+                       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("fusionSequence").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);
+
+                       //store the original transform matrix
+                       int indexParent = GetSlicerIndexFromItem( DataTree->topLevelItem(index) );
+                       mSlicerManagers[indexParent]->SetFusionSequenceMainTransformMatrix( mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[0]->GetMatrix() );
+
+                       //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);
+
+
+                       //This loads the secondary sequence (US) as an independent sequence
+                       LoadImages(fileNames, type);
+                       //reset the transforms to identiy
+                       for (unsigned i=0 ; i<mSlicerManagers.back()->GetImage()->GetTransform().size() ; i++) {
+                               mSlicerManagers.back()->GetImage()->GetTransform()[i]->Identity();
+                               mSlicerManagers.back()->GetImage()->GetTransform()[i]->Update();
+                       }
+
+                       //automatically link both images...
+                       AddLink(mSlicerManagers[indexParent]->GetId().c_str(), mSlicerManagers.back()->GetId().c_str(), false);
+
+                       //tie the main and secondary sequences by raising flags and informing each another of their respective SlicerManager indices
+                       mSlicerManagers[indexParent]->SetFusionSequenceIndexOfLinkedManager(mSlicerManagers.size()-1);
+                       mSlicerManagers[indexParent]->SetFusionSequenceInvolvmentCode(0); //main sequence
+                       mSlicerManagers.back()->SetFusionSequenceIndexOfLinkedManager(indexParent);
+                       mSlicerManagers.back()->SetFusionSequenceInvolvmentCode(1); //secondary sequence
+
+               } 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 sequence !"),"File doesn't exist!");
+               return;
+       }
+
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+//fusionSequenceFrameIndex and fusionSequenceNbFrames are relative to the secondary sequence (US)
+void vvMainWindow::SetFusionSequenceProperty(int fusionSequenceFrameIndex, bool spatialSyncFlag, unsigned int fusionSequenceNbFrames, bool temporalSyncFlag)
+{
+       int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+
+       //check if the focus moved to the linked sequence, and in this case, select the master sequence instead
+       if (!mSlicerManagers[index]->IsMainSequenceOfFusionSequence()) {
+               index = mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager();
+       }
+
+  int secondaryIndex = mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager();
+  if ( (!mSlicerManagers[index]->IsMainSequenceOfFusionSequence()) || 
+    (!mSlicerManagers[secondaryIndex]->IsSecondarySequenceOfFusionSequence()) ) 
+  {return;} //this should never happen, raise an exception?
+
+  if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
+    int indexParent = GetSlicerIndexFromItem( DataTree->topLevelItem(index) );
+//check whether this really makes sense to look at 'parentIndex'...
+std::cout<<"index = "<<index<<", indexParent = "<<     indexParent<<std::endl;
+
+    //if the spatialSync button is unchecked, then reposition the parent sequence (CT) in its original coordinate frame
+    if ( (!spatialSyncFlag) && (mSlicerManagers[index]->GetFusionSequenceSpatialSyncFlag()) ) {
+      for ( unsigned i=0 ; i<mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform().size() ; i++ ) {
+        mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->SetMatrix( mSlicerManagers[index]->GetFusionSequenceMainTransformMatrix() );
+        mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->Update();
+      }
+
+      for (int i=0; i<mSlicerManagers[indexParent]->GetNumberOfSlicers(); i++) {
+        mSlicerManagers[indexParent]->GetSlicer(i)->ForceUpdateDisplayExtent();
+        mSlicerManagers[indexParent]->GetSlicer(i)->Render();
+      }
+    }
+
+
+    //update the property values in the slicer manager
+    mSlicerManagers[index]->SetFusionSequenceLength(fusionSequenceNbFrames);
+    mSlicerManagers[index]->SetFusionSequenceSpatialSyncFlag(spatialSyncFlag);
+    mSlicerManagers[index]->SetFusionSequenceSpatialSyncFlag(temporalSyncFlag);
+    mSlicerManagers[index]->SetFusionSequenceFrameIndex(fusionSequenceFrameIndex);
+
+    //show the right frame of the US sequence
+    mSlicerManagers[index]->SetFusionSequenceTSlice(fusionSequenceFrameIndex);
+    //update the TSlice of the linked sequence if possible
+    mSlicerManagers[secondaryIndex]->SetTSlice(fusionSequenceFrameIndex, true);
+
+    //update the horizontal sliders of the main window
+    overlayPanel->updateFusionSequenceSliderValueFromWindow(fusionSequenceFrameIndex, false);
+
+    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
+
+        //and set it!
+        mSlicerManagers[index]->SetTSlice(mainSequenceFrameIndex, false);
+      }
+
+
+                       //Set the transform matrix of the parent sequence (typically CT / 4DCT)
+                       vtkSmartPointer<vtkMatrix4x4> tmpMat = vtkSmartPointer<vtkMatrix4x4>::New();
+                       vtkMatrix4x4::Invert( mSlicerManagers[index]->GetFusionSequenceInitialTransformMatrixAtFrame(fusionSequenceFrameIndex), tmpMat );
+                       for ( unsigned i=0 ; i<mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform().size() ; i++ ) {
+                               mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->SetMatrix( mSlicerManagers[index]->GetFusionSequenceMainTransformMatrix() );
+                               mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->PreMultiply();
+                               mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->Concatenate( tmpMat );
+                               mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->Update();
+                       }
+
+                       for (int i=0; i<mSlicerManagers[indexParent]->GetNumberOfSlicers(); i++) {
+                               mSlicerManagers[indexParent]->GetSlicer(i)->ForceUpdateDisplayExtent();
+                               mSlicerManagers[indexParent]->GetSlicer(i)->Render();
+                       }
+
+               }
+
+       }
+}
+//------------------------------------------------------------------------------
+
+
 //------------------------------------------------------------------------------
 void vvMainWindow::SaveAs()
 {
@@ -2304,7 +2724,8 @@ void vvMainWindow::SaveAs()
       bool bId = true;
       for(int i=0; i<4; i++)
         for(int j=0; j<4; j++) {
-          double elt = mSlicerManagers[index]->GetImage()->GetTransform()->GetMatrix()->GetElement(i,j);
+          // TODO SR and BP: check on the list of transforms and not the first only
+          double elt = mSlicerManagers[index]->GetImage()->GetTransform()[0]->GetMatrix()->GetElement(i,j);
           if(i==j && elt!=1.)
             bId = false;
           if(i!=j && elt!=0.)
@@ -2388,8 +2809,14 @@ void vvMainWindow::LinkAllImages()
 }
 
 //------------------------------------------------------------------------------
-void vvMainWindow::AddLink(QString image1,QString image2)
+void vvMainWindow::AddLink(QString image1,QString image2,bool fromPanel)
 {
+  if (!fromPanel) {
+    // delegate to linkPanel if call came from elsewhere...
+    linkPanel->addLinkFromIds(image1, image2);
+    return;
+  }
+  
   unsigned int sm1 = 0;
   unsigned int sm2 = 0;
 
@@ -2446,20 +2873,31 @@ void vvMainWindow::ChangeImageWithIndexOffset(vvSlicerManager *sm, int slicer, i
   DisplayChanged(item,slicer+1);
 }
 //------------------------------------------------------------------------------
-
 void vvMainWindow::HorizontalSliderMoved(int value,int column, int slicer_index)
 {
-  for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
-    if (DataTree->topLevelItem(i)->data(column,Qt::CheckStateRole).toInt() > 1) {
-      for (int j = 0; j < 4; j++) {
-        mSlicerManagers[i]->SetTSliceInSlicer(value,j);
-        //if (mSlicerManagers[i]->GetSlicer(j)->GetImageActor()->GetVisibility())
-        //UpdateTSlice(j,value);
-      }
-      mSlicerManagers[i]->GetSlicer(slicer_index)->Render();
-      break;
-    }
-  }
+       for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
+               if (DataTree->topLevelItem(i)->data(column,Qt::CheckStateRole).toInt() > 1) {
+
+                       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); }
+                               else { //if this is the primary sequence that has been modified
+                                       if (mSlicerManagers[i]->GetFusionSequenceTemporalSyncFlag()) {
+                                               //TODO: if temporal sync is active
+                                               //estimate a corresponding time index for the secondary (US) sequence, and update it accordingly.
+                                               int estimatedValue=0;
+                                               overlayPanel->updateFusionSequenceSliderValueFromWindow(estimatedValue, true);
+                                       }
+                               }
+                       }
+
+                       for (int j = 0; j < 4; j++) {
+                               mSlicerManagers[i]->SetTSliceInSlicer(value,j);
+                       }
+                       mSlicerManagers[i]->GetSlicer(slicer_index)->Render();
+                       break;
+               }
+       }
 }
 //------------------------------------------------------------------------------
 
@@ -2646,23 +3084,24 @@ void vvMainWindow::UpdateTSlice(int slicer, int slice)
 //------------------------------------------------------------------------------
 void vvMainWindow::UpdateSliceRange(int slicer, int min, int max, int tmin, int tmax)
 {
-  int position = int((min+max)/2);
+  //int position = int((min+max)/2);
+  int position = mSlicerManagers[mCurrentPickedImageIndex]->GetSlicer(slicer)->GetSlice();
   if (slicer == 0) {
-    NOVerticalSlider->setValue(position);
     NOVerticalSlider->setRange(min,max);
     NOHorizontalSlider->setRange(tmin,tmax);
+    NOVerticalSlider->setValue(position);
   } else if (slicer == 1) {
-    NEVerticalSlider->setValue(position);
     NEVerticalSlider->setRange(min,max);
     NEHorizontalSlider->setRange(tmin,tmax);
+    NEVerticalSlider->setValue(position);
   } else if (slicer == 2) {
-    SOVerticalSlider->setValue(position);
     SOVerticalSlider->setRange(min,max);
     SOHorizontalSlider->setRange(tmin,tmax);
+    SOVerticalSlider->setValue(position);
   } else if (slicer == 3) {
-    SEVerticalSlider->setValue(position);
     SEVerticalSlider->setRange(min,max);
     SEHorizontalSlider->setRange(tmin,tmax);
+    SEVerticalSlider->setValue(position);
   }
 }
 //------------------------------------------------------------------------------
@@ -2870,9 +3309,8 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget)
       vidwriter->SetInput(image);
       vidwriter->SetFileName(fileName.toStdString().c_str());
       vidwriter->Start();
-      vvImage * vvImg = mSlicerManagers[smIndex]->GetImage();
-      int nSlice = vvImg->GetVTKImages().size();
-      for(int i=0; i<nSlice; i++) {
+      int nSlice = mSlicerManagers[smIndex]->GetSlicer(0)->GetTMax();
+      for(int i=0; i<=nSlice; i++) {
         mSlicerManagers[smIndex]->SetNextTSlice(0);
         vtkSmartPointer<vtkWindowToImageFilter> w2i = vtkSmartPointer<vtkWindowToImageFilter>::New();
         w2i->SetInput(widget->GetRenderWindow());
@@ -2920,7 +3358,7 @@ void vvMainWindow::PlayPause()
     int image_number=DataTree->topLevelItemCount();
     bool has_temporal;
     for (int i=0; i<image_number; i++)
-      if (mSlicerManagers[i]->GetImage()->GetVTKImages().size() > 1) {
+      if (mSlicerManagers[i]->GetSlicer(0)->GetTMax() > 0) {
         has_temporal=true;
         break;
       }
@@ -2941,7 +3379,7 @@ void vvMainWindow::PlayNext()
     ///Only play one slicer per SM, and only if the SM is being displayed
     for (int i=0; i<image_number; i++)
       for (int j=0; j<4; j++)
-        if (mSlicerManagers[i]->GetImage()->GetVTKImages().size() > 1 &&
+        if (mSlicerManagers[i]->GetSlicer(0)->GetTMax() > 0 &&
             DataTree->topLevelItem(i)->data(j+1,Qt::CheckStateRole).toInt() > 0) {
           mSlicerManagers[i]->SetNextTSlice(j);
           break;
@@ -2964,6 +3402,12 @@ void vvMainWindow::ShowLastImage()
 //------------------------------------------------------------------------------
 void vvMainWindow::UpdateRenderWindows()
 {
+  for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
+    mSlicerManagers[i]->GetSlicer(0)->UpdateLandmarks();
+    mSlicerManagers[i]->GetSlicer(1)->UpdateLandmarks();
+    mSlicerManagers[i]->GetSlicer(2)->UpdateLandmarks();
+    mSlicerManagers[i]->GetSlicer(3)->UpdateLandmarks();
+  }
   if (NOViewWidget->GetRenderWindow()) NOViewWidget->GetRenderWindow()->Render();
   if (NEViewWidget->GetRenderWindow()) NEViewWidget->GetRenderWindow()->Render();
   if (SOViewWidget->GetRenderWindow()) SOViewWidget->GetRenderWindow()->Render();
@@ -3050,7 +3494,7 @@ vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filen
   DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
 
   //set the id of the image
-  QString id = slicer_manager->GetFileName().c_str() + QString::number(mSlicerManagers.size()-1);
+  QString id = QDir::current().absoluteFilePath(slicer_manager->GetFileName().c_str()) + QString::number(mSlicerManagers.size()-1);
   item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
   mSlicerManagers.back()->SetId(id.toStdString());
 
@@ -3068,13 +3512,17 @@ vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filen
   connect(mSlicerManagers.back(), SIGNAL(UpdateOverlay(int, double, double)),
           this, SLOT(OverlayChanged(int,double,double)));
   connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)),
-          this, SLOT(FusionChanged(int,double)));
+                 this, SLOT(FusionChanged(int,double)));
+  //connect(mSlicerManagers.back(), SIGNAL(UpdateFusionSequence(int, bool, unsigned int)),
+               //  this, SLOT(FusionSequenceChanged(int, bool, unsigned int)));
   connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged()),
           this,SLOT(WindowLevelChanged()));
   connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)),
           this,SLOT(UpdateSlice(int,int)));
   connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
           this,SLOT(UpdateTSlice(int, int)));
+  connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
+          this,SLOT(ImageInfoChanged()));
   connect(mSlicerManagers.back(), SIGNAL(UpdateSliceRange(int,int,int,int,int)),
           this,SLOT(UpdateSliceRange(int,int,int,int,int)));
   connect(mSlicerManagers.back(), SIGNAL(UpdateLinkManager(std::string,int,double,double,double,int)),
@@ -3084,6 +3532,8 @@ vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filen
   connect(mSlicerManagers.back(), SIGNAL(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)),
           this,SLOT(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)));
   connect(mSlicerManagers.back(), SIGNAL(LandmarkAdded()),landmarksPanel,SLOT(AddPoint()));
+  
+
   UpdateTree();
   qApp->processEvents();
   InitSlicers();