GOFIGURE2  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
QGoDBTrackManager.cxx
Go to the documentation of this file.
1 /*=========================================================================
2  Authors: The GoFigure Dev. Team.
3  at Megason Lab, Systems biology, Harvard Medical school, 2009-11
4 
5  Copyright (c) 2009-11, President and Fellows of Harvard College.
6  All rights reserved.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions are met:
10 
11  Redistributions of source code must retain the above copyright notice,
12  this list of conditions and the following disclaimer.
13  Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16  Neither the name of the President and Fellows of Harvard College
17  nor the names of its contributors may be used to endorse or promote
18  products derived from this software without specific prior written
19  permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
26  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 =========================================================================*/
34 
35 #include "QGoDBTrackManager.h"
36 #include "GoDBTrackRow.h"
37 #include "GoDBTrackFamilyRow.h"
38 #include <iostream>
39 #include <sstream>
40 
41 #include "TrackStructure.h"
42 #include "ConvertToStringHelper.h"
43 
44 
45 QGoDBTrackManager::QGoDBTrackManager(int iImgSessionID, QWidget *iparent) :
46  QGoDBTraceManager(), m_TrackContainerInfoForVisu(NULL)
47 {
48  this->SetInfo(iImgSessionID, iparent);
49  this->m_TWContainer = new GoDBTWContainerForTrack(iImgSessionID);
50 }
51 
52 //-------------------------------------------------------------------------
53 
54 //-------------------------------------------------------------------------
56 {
57  if ( this->m_TWContainer )
58  {
59  delete this->m_TWContainer;
60  }
61 }
62 
63 //-------------------------------------------------------------------------
64 
65 //-------------------------------------------------------------------------
67  TrackContainer *iContainerForVisu)
68 {
69  this->SetTracesInfoContainerForVisuTemplate< TrackContainer >(
70  iContainerForVisu, &this->m_TrackContainerInfoForVisu);
71 
73  SIGNAL( NeedMeshesInfoForImportedTrack(unsigned int) ),
74  this,
75  SIGNAL( NeedMeshesInfoForImportedTrack(unsigned int) ) );
76 }
77 
78 //-------------------------------------------------------------------------
79 
80 //-------------------------------------------------------------------------
82 {
83  this->m_TraceName = "track";
84  this->m_CollectionName = "lineage";
85  this->m_CollectionOf = "mesh";
86 }
87 
88 //-------------------------------------------------------------------------
89 
90 //-------------------------------------------------------------------------
92  vtkMySQLDatabase *iDatabaseConnector)
93 {
94  this->DisplayInfoForAllTracesTemplate< GoDBTWContainerForTrack >(
95  this->m_TWContainer, iDatabaseConnector, Qt::Unchecked);
96 }
97 
98 //-------------------------------------------------------------------------
99 
100 //-------------------------------------------------------------------------
102  vtkMySQLDatabase *iDatabaseConnector, const std::list<unsigned int> & iListTPs)
103 {
104  (void) iListTPs;
105  this->DisplayInfoForAllTraces(iDatabaseConnector);
106 }
107 
108 //-------------------------------------------------------------------------
109 
110 //-------------------------------------------------------------------------
112  vtkMySQLDatabase *iDatabaseConnector)
113 {
114  this->DisplayInfoAndLoadVisuContainerWithAllTraces< GoDBTWContainerForTrack >
115  (this->m_TWContainer, iDatabaseConnector);
116 }
117 
118 //-------------------------------------------------------------------------
119 
120 //-------------------------------------------------------------------------
122  vtkMySQLDatabase *iDatabaseConnector)
123 {
124  this->DisplayInfoForLastCreatedTraceTemplate< GoDBTWContainerForTrack >(
125  this->m_TWContainer, iDatabaseConnector);
126 }
127 
128 //-------------------------------------------------------------------------
129 
130 //-------------------------------------------------------------------------
132  vtkMySQLDatabase *iDatabaseConnector, int iTraceID)
133 {
134  this->DisplayInfoForExistingTraceTemplate< GoDBTWContainerForTrack >(
135  this->m_TWContainer, iDatabaseConnector, iTraceID);
136 }
137 
138 //-------------------------------------------------------------------------
139 
140 //-------------------------------------------------------------------------
142  vtkMySQLDatabase *iDatabaseConnector)
143 {
144  GoDBTrackRow NewTrack;
145  unsigned int NewTrackID =
147  iDatabaseConnector, *this->m_SelectedColorData, NewTrack);
148 
150  // pointer to double has to be deleted after usage...
151  double* color = this->GetVectorFromQColor(this->m_SelectedColorData->second);
153  NewTrackID, color, true);
154  delete[] color;
156  this->DisplayInfoForLastCreatedTrace(iDatabaseConnector);
157  NameWithColorData NewTrackData(ConvertToString< unsigned int >(NewTrackID),
158  this->m_SelectedColorData->second);
159  emit AddNewTraceIDInTS(NewTrackData);
160  return NewTrackID;
161 }
162 
163 //-------------------------------------------------------------------------
164 
165 //-------------------------------------------------------------------------
166 std::list< unsigned int > QGoDBTrackManager::UpdateTheTracesColor(
167  vtkMySQLDatabase *iDatabaseConnector)
168 {
170  TrackContainer >(iDatabaseConnector, this->m_TrackContainerInfoForVisu);
171 }
172 
173 //-------------------------------------------------------------------------
174 
175 //-------------------------------------------------------------------------
177  const std::vector< int > & iVectorImportedTraces,
178  vtkMySQLDatabase *iDatabaseConnector)
179 {
182  iVectorImportedTraces, iDatabaseConnector);
183  //call the TrackContainer to give him iVectorImportedTraces
184 }
185 
186 //-------------------------------------------------------------------------
187 
188 //-------------------------------------------------------------------------
189 void QGoDBTrackManager::DeleteCheckedTraces(vtkMySQLDatabase *iDatabaseConnector)
190 {
191  //if the tracks to be deleted belongs to some divisions, the divisions need to
192  //be deleted first:
193  std::list<unsigned int> ListDivisionsToDelete =
194  this->m_CollectionOfTraces->GetTrackFamilyID(iDatabaseConnector,
195  this->GetListHighlightedIDs() );
196  std::list<unsigned int>::iterator iter = ListDivisionsToDelete.begin();
197  std::list<unsigned int> TrackIDsWithNoLineage = std::list<unsigned int>();
198  std::list<unsigned int> LineagesToDelete = std::list<unsigned int>();
199  while( iter != ListDivisionsToDelete.end() )
200  {
201  if (*iter != 0)
202  {
204  GoDBTrackFamilyRow Division(*iter, this->m_DatabaseConnector);
205  this->DeleteOneDivision(Division, this->m_DatabaseConnector, TrackIDsWithNoLineage, LineagesToDelete);
206  }
207  ++iter;
208  }
209 
210  if (!TrackIDsWithNoLineage.empty() ) //set the lineageID to 0 and update the bounding boxes of the previous lineages
211  {
212  emit CheckedTracksToAddToSelectedLineage(TrackIDsWithNoLineage, 0, LineagesToDelete);
213  }
214 
216  this->DeleteTracesTemplate< TrackContainer >(this->m_DatabaseConnector,
218 }
219 
220 //-------------------------------------------------------------------------
221 
222 //-------------------------------------------------------------------------
223 void QGoDBTrackManager::DeleteListTraces(vtkMySQLDatabase *iDatabaseConnector,
224  const std::list< unsigned int > & iListTraces)
225 {
226  this->DeleteTracesTemplate< TrackContainer >(iDatabaseConnector,
227  this->m_TrackContainerInfoForVisu, iListTraces, false);
228 }
229 
230 //-------------------------------------------------------------------------
231 
232 //-------------------------------------------------------------------------
233 std::list< unsigned int > QGoDBTrackManager::GetListHighlightedIDs()
234 {
236 }
237 
238 //-------------------------------------------------------------------------
239 
240 //-------------------------------------------------------------------------
242  int iTraceID)
243 {
245 }
246 
247 //-------------------------------------------------------------------------
248 
249 //-------------------------------------------------------------------------
251 {
253  UpdateElementVisibilityWithGivenTraceID(iTraceID);
254 }
255 
256 //-------------------------------------------------------------------------
257 
258 //-------------------------------------------------------------------------
260  vtkMySQLDatabase *iDatabaseConnector,
261  std::list< unsigned int > iListTraceIDs)
262 {
263  this->GetTracesInfoFromDBAndModifyContainerForVisuTemplate< TrackContainer >(
264  this->m_TrackContainerInfoForVisu, iDatabaseConnector, iListTraceIDs);
265 }
266 
267 //-------------------------------------------------------------------------
268 // add pointer to structure instead
269 //-------------------------------------------------------------------------
271  vtkMySQLDatabase *iDatabaseConnector)
272 {
273  GoDBTrackRow TrackToSave(this->m_ImgSessionID);
274  unsigned int TrackID = this->m_TrackContainerInfoForVisu->m_CurrentElement.TraceID;
275 
276  if ( TrackID != 0 )
277  {
278  TrackToSave.SetValuesForSpecificID(TrackID, iDatabaseConnector);
279  }
280 
281  //save the track into the database
282  TrackToSave.SetThePointsFromPolydata(
284  TrackID = TrackToSave.SaveInDB(iDatabaseConnector);
285 
286  //save the track into the container:
288 
289  //calculate the values to be put in the table widget:
290  GoFigureTrackAttributes trackAttributes(
291  this->m_TrackContainerInfoForVisu->m_CurrentElement.ComputeAttributes() );
292  this->m_TWContainer->SetTrackAttributes(&trackAttributes);
293 
295 
296  //update the table widget:
297  if ( TrackID == 0 )
298  {
299  this->DisplayInfoForLastCreatedTrace(iDatabaseConnector);
300  }
301  else
302  {
303  this->DisplayInfoForExistingTrace(iDatabaseConnector, TrackID);
304  }
305 }
306 
307 //-------------------------------------------------------------------------
308 
309 //-------------------------------------------------------------------------
311  vtkMySQLDatabase *iDatabaseConnector, TrackStructure* iStructure)
312 {
313  GoDBTrackRow TrackToSave(this->m_ImgSessionID);
314  unsigned int TrackID = iStructure->TraceID;
315 
316  if ( TrackID != 0 )
317  {
318  TrackToSave.SetValuesForSpecificID(TrackID, iDatabaseConnector);
319  }
320 
321  //save the track into the database
322  TrackToSave.SetThePointsFromPolydata(iStructure->Nodes);
323  TrackID = TrackToSave.SaveInDB(iDatabaseConnector);
324 
325  //calculate the values to be put in the table widget:
326  GoFigureTrackAttributes trackAttributes( iStructure->ComputeAttributes() );
327  this->m_TWContainer->SetTrackAttributes(&trackAttributes);
328 
329  //update the table widget:
330  if ( TrackID == 0 )
331  {
332  this->DisplayInfoForLastCreatedTrace(iDatabaseConnector);
333  }
334  else
335  {
336  this->DisplayInfoForExistingTrace(iDatabaseConnector, TrackID);
337  }
338 }
339 //-------------------------------------------------------------------------
340 
341 //-------------------------------------------------------------------------
343  std::map< unsigned int, double * > iMeshesInfo,
344  vtkMySQLDatabase *iDatabaseConnector)
345 {
347  this->SaveTrackCurrentElement(iDatabaseConnector);
348 }
349 //-------------------------------------------------------------------------
350 
351 //-------------------------------------------------------------------------
352 void QGoDBTrackManager::UpdateTrackPolydataForVisu(vtkMySQLDatabase *iDatabaseConnector,
353  unsigned int iTrackID)
354 {
355  std::list< double * > ListCenters =
357  iDatabaseConnector, iTrackID);
358  TrackStructure* structure =
359  this->m_TrackContainerInfoForVisu->UpdatePointsForATrack(iTrackID, ListCenters);
360  SaveTrackStructure(iDatabaseConnector, structure);
361 }
362 //-------------------------------------------------------------------------
363 
364 //-------------------------------------------------------------------------
366  vtkMySQLDatabase *iDatabaseConnector,
367  const std::list< unsigned int > & iListTracesIDs)
368 {
369  QGoDBTraceManager::UpdateBoundingBoxes(iDatabaseConnector, iListTracesIDs, false);
370  std::list< unsigned int >::const_iterator iter = iListTracesIDs.begin();
371  while ( iter != iListTracesIDs.end() )
372  {
373  this->UpdateTrackPolydataForVisu(iDatabaseConnector, *iter);
374  ++iter;
375  }
376 }
377 
378 //-------------------------------------------------------------------------
380 {
381  this->SetColorCodingTemplate< TrackContainer >(
382  this->m_TrackContainerInfoForVisu, IsChecked);
383 }
384 
385 //-------------------------------------------------------------------------
386 
387 //-------------------------------------------------------------------------
389 {
391 
392  QMenu *SplitMergeMenu = new QMenu(tr("Split/Merge them"), iMenu);
393  SplitMergeMenu->addAction( tr("Using the Widget"),
394  this, SLOT( SplitMergeTrackWithWidget() ) );
395  SplitMergeMenu->addAction( tr("Split your track"), this, SLOT( TrackIDToEmit() ) );
396  SplitMergeMenu->addAction( tr("Merge your 2 tracks"), this, SLOT( MergeTracks() ) );
397  iMenu->addAction( SplitMergeMenu->menuAction() );
398 
399  this->m_CheckedTracesMenu->addAction( tr("Go to the end")
400  .arg( this->m_TraceName.c_str() ),
401  this, SLOT( GoToTrackEnd() ) );
402  this->m_CheckedTracesMenu->addAction( tr("Go to the beginning")
403  .arg( this->m_TraceName.c_str() ),
404  this, SLOT( GoToTrackBegin() ) );
405  this->m_CheckedTracesMenu->addAction( tr("Create a new division from checked %1s")
406  .arg( this->m_TraceName.c_str() ),
407  this, SLOT( CreateCorrespondingTrackFamily() ) );
408  this->m_CheckedTracesMenu->addAction( tr("Delete the division for this tracks") ,
409  this, SLOT( DeleteTheDivisions() ) );
410 }
411 
412 //-------------------------------------------------------------------------
413 
414 //--------------------------------------------------------------------------
416 {
417  std::list< unsigned int > HighlightedTrackIDs =
419 
420  if ( HighlightedTrackIDs.size() != 1 )
421  {
422  QMessageBox msgBox;
423  msgBox.setText(
424  tr("Please check one and only one Track to split") );
425  msgBox.exec();
426  }
427  else
428  {
430  std::list<unsigned int> list_meshes =
432  HighlightedTrackIDs);
433  emit TrackToSplit( HighlightedTrackIDs.front(), list_meshes );
435  }
436 }
437 
438 //-------------------------------------------------------------------------
439 
440 //-------------------------------------------------------------------------
442 {
443  std::list< unsigned int > HighlightedTrackIDs =
445 
446  if ( HighlightedTrackIDs.size() == 0 )
447  {
448  QMessageBox msgBox;
449  msgBox.setText(
450  tr("Please check at least one Track to be visualized in the widget") );
451  msgBox.exec();
452  }
453  else
454  {
455  emit TrackIDToBeModifiedWithWidget(HighlightedTrackIDs);
456  }
457 }
458 
459 //-------------------------------------------------------------------------
460 
461 //-------------------------------------------------------------------------
463  GoFigureTrackAttributes *iTrackAttributes, unsigned int iTrackID)
464 {
465  if ( iTrackAttributes != 0 )
466  {
467  int timeInterval = m_TrackContainerInfoForVisu->getTimeInterval();
468 
469  assert( timeInterval != 0 );
470 
471  std::vector< std::string > ColumnNames (9);
472  std::vector< std::string > Values (9);
473 
474  ColumnNames.at(0) = "Deplacement";
475  Values.at(0) = ConvertToString< double >(iTrackAttributes->total_length);
476  ColumnNames.at(1) = "Distance";
477  Values.at(1) = ConvertToString< double >(iTrackAttributes->distance);
478  ColumnNames.at(2) = "Theta";
479  Values.at(2) = ConvertToString< double >(iTrackAttributes->theta);
480  ColumnNames.at(3) = "Phi";
481  Values.at(3) = ConvertToString< double >(iTrackAttributes->phi);
482  ColumnNames.at(4) = "AvgSpeed";
483  Values.at(4) = ConvertToString< double >
484  (iTrackAttributes->avg_speed / static_cast< double >( timeInterval ));
485  ColumnNames.at(5) = "MaxSpeed";
486  Values.at(5) = ConvertToString< double >
487  (iTrackAttributes->max_speed / static_cast< double >( timeInterval ));
488  ColumnNames.at(6) = "AvgVolume";
489  Values.at(6) = ConvertToString< double >(iTrackAttributes->avg_volume);
490  ColumnNames.at(7) = "NumberOfMeshes";
491  Values.at(7) = ConvertToString< unsigned int >(iTrackAttributes->number_meshes);
492  ColumnNames.at(8) = "Tmax - Tmin";
493  Values.at(8) = ConvertToString< unsigned int >(iTrackAttributes->temporal_extent);
494 
495  this->m_Table->AddValuesForID(ColumnNames, Values, iTrackID, "trackID");
496  }
497 }
498 
499 //-------------------------------------------------------------------------
500 
501 //-------------------------------------------------------------------------
503 {
504 
505  std::list< unsigned int > CheckedTrack =
507  if ( CheckedTrack.size() != 2 )
508  {
509  QMessageBox msgBox;
510  msgBox.setText(
511  tr("Please check two and only two tracks to be merged") );
512  msgBox.exec();
513  }
514  else
515  {
517  unsigned int TrackIDToKeep = 0;
518  unsigned int TrackIDToDelete = 0;
519  if ( this->CheckOverlappingTracks(CheckedTrack, TrackIDToKeep,
520  TrackIDToDelete, this->m_DatabaseConnector) )
521  {
522  QMessageBox msgBox;
523  msgBox.setText(
524  tr("The two tracks are overlapping, it is not possible to merge them !!") );
525  msgBox.exec();
526  }
527  else
528  {
529  //if first is mother of a lineage, doin't do anything
530  bool isMother =
531  this->isMother(this->m_DatabaseConnector, TrackIDToDelete);
532 
533  if(isMother)
534  {
536  QMessageBox msgBox;
537  msgBox.setText(
538  tr("The first track is already a mother track !!") );
539  msgBox.exec();
540  return;
541  }
542 
543  // if second is dauther of a lineage, don't do anything
544  std::vector<unsigned int> family1 =
545  this->GetTrackFamily(this->m_DatabaseConnector, TrackIDToKeep);
546 
547  if(family1.size() > 0)
548  {
550  QMessageBox msgBox;
551  msgBox.setText(
552  tr("The second track is already a daughter track !!") );
553  msgBox.exec();
554  return;
555  }
556 
557  // delete smallest track (in time)
558  // strategy:
559  // 1-delete previous division
560  // 2-create new track
561  // 3-create new division
562  // therefore we ensure to have a correct lineage tree
563  unsigned int oldMotherID = 0;
564  unsigned int oldDaughter = 0;
565  // delete mother division
566  std::vector<unsigned int> family =
567  this->GetTrackFamily(this->m_DatabaseConnector, TrackIDToDelete);
568 
569  // if track belongs to a lineage
570  if(family.size() > 0)
571  {
572  oldMotherID = family[1];
573  if(family[2] == TrackIDToDelete)
574  {
575  oldDaughter = family[3];
576  }
577  else
578  {
579  oldDaughter = family[2];
580  }
581 
582  // Delete old track mother division
583  std::list<unsigned int> oldList;
584  oldList.push_back(oldMotherID);
585  this->DeleteTheDivisions(oldList);
586  }
587  // connection is closed above...
589  // merge
590  std::list< unsigned int > TraceIDToDelete;
591  TraceIDToDelete.push_back(TrackIDToDelete);
592  std::list< unsigned int > MeshesBelongingToTrackToDelete =
594  this->m_DatabaseConnector, TraceIDToDelete);
595  this->DeleteListTraces(this->m_DatabaseConnector, TraceIDToDelete);
596  emit MeshesToAddToTrack(MeshesBelongingToTrackToDelete, TrackIDToKeep);
597 
598  // if track belongs to a lineage
599  if(family.size() > 0)
600  {
601  // Create division old mother and new daughter
602  std::list<unsigned int> newdaughter;
603  newdaughter.push_back(oldMotherID);
604  newdaughter.push_back(oldDaughter);
605  newdaughter.push_back(TrackIDToKeep);
606  this->CreateCorrespondingTrackFamily(newdaughter);
607  }
608  }
610  }
611 }
612 
613 //-------------------------------------------------------------------------
614 
615 //-------------------------------------------------------------------------
617  std::list< unsigned int > iTrackIDs, unsigned int & ioTraceIDToKeep,
618  unsigned int & ioTraceIDToDelete, vtkMySQLDatabase *iDatabaseConnector)
619 {
620  unsigned int TraceID1 = 0, TraceID2 = 0;
621  unsigned int TimePointMin1 = 0, TimePointMin2 = 0, TimePointMax1 = 0,
622  TimePointMax2 = 0;
623  bool oTracksOverlapping = true;
624 
625  std::list< unsigned int >::iterator iter = iTrackIDs.begin();
626  if ( iter == iTrackIDs.end() )
627  {
628  std::cout << "Pb, there should have been 2 tracks instead of 0 in this method" << std::endl;
629  return oTracksOverlapping;
630  }
631  TraceID1 = *iter;
632  TimePointMin1 = this->m_CollectionOfTraces->GetBoundedBoxTimePoint(
633  iDatabaseConnector, TraceID1, true);
634  TimePointMax1 = this->m_CollectionOfTraces->GetBoundedBoxTimePoint(
635  iDatabaseConnector, TraceID1, false);
636  ++iter;
637  if ( iter == iTrackIDs.end() )
638  {
639  std::cout << "Pb, there should have been 2 tracks instead of 1 in this method" << std::endl;
640  return oTracksOverlapping;
641  }
642 
643  TraceID2 = *iter;
644  TimePointMin2 = this->m_CollectionOfTraces->GetBoundedBoxTimePoint(
645  iDatabaseConnector, TraceID2, true);
646  TimePointMax2 = this->m_CollectionOfTraces->GetBoundedBoxTimePoint(
647  iDatabaseConnector, TraceID2, false);
648 
649  if ( TimePointMin2 > TimePointMax1 )
650  {
651  oTracksOverlapping = false;
652  ioTraceIDToKeep = TraceID2;
653  ioTraceIDToDelete = TraceID1;
654  }
655 
656  if ( TimePointMin1 > TimePointMax2 )
657  {
658  oTracksOverlapping = false;
659  ioTraceIDToKeep = TraceID1;
660  ioTraceIDToDelete = TraceID2;
661  }
662 
663  return oTracksOverlapping;
664 }
665 //-------------------------------------------------------------------------
666 
667 //-------------------------------------------------------------------------
668 void QGoDBTrackManager::CreateCorrespondingTrackFamily( std::list<unsigned int> iDivisions )
669 {
670  int MotherID = 0;
671  std::list<unsigned int> DaughtersIDs = std::list<unsigned int>();
672  std::list<unsigned int> CheckedTracks;
673 
674  if(iDivisions.size())
675  {
676  CheckedTracks = iDivisions;
677  }
678  else
679  {
680  CheckedTracks =
681  this->GetListHighlightedIDs();
682  }
683 
684  if (CheckedTracks.size() != 3)
685  {
686  QMessageBox msgBox;
687  msgBox.setText(
688  tr("Please select 3 tracks to add your division") );
689  msgBox.exec();
690  return;
691  }
694  CheckedTracks, MotherID, DaughtersIDs) )
695  {
696  int TrackFamilyID = this->CreateTrackFamily(this->m_DatabaseConnector,
697  MotherID, DaughtersIDs);
698  if (TrackFamilyID != -1)
699  {
700  //check the lineageID of the mother:
701  std::list<unsigned int> TrackID;
702  TrackID.push_back(MotherID);
703  std::list<unsigned int> LineageIDToCheck =
705  //update the trackFamilyID for the daughters:
706  std::list<unsigned int>::iterator iter = DaughtersIDs.begin();
707  while(iter != DaughtersIDs.end() )
708  {
710  *iter, TrackFamilyID);
711  ++iter;
712  }
713  //if the daughters belongs to other lineages, they need to be deleted and all the tracks belonging
714  //to these lineages have to be added to the DaughtersIDs list to be added to the mother lineage
715  std::list<unsigned int> PreviousLineagesToDelete =
716  this->GetTrackIDFromDaughtersFamilies(this->m_DatabaseConnector, DaughtersIDs);
717  if (!LineageIDToCheck.empty())
718  {
719  //the mother track already belong to the lineage, need to add the daughters and her families:
720  emit CheckedTracksToAddToSelectedLineage(DaughtersIDs, LineageIDToCheck.front(),
721  PreviousLineagesToDelete);
722  }
723  else
724  {
725  //need to add to the new lineage the mother track, the daughters and her families:
726  DaughtersIDs.push_back(MotherID);
727  emit NewLineageToCreateFromTracks(DaughtersIDs, MotherID, PreviousLineagesToDelete);
728  }
729  }
730  }
732 }
733 
734 //-------------------------------------------------------------------------
735 
736 //-------------------------------------------------------------------------
738  vtkMySQLDatabase* iDatabaseConnector,
739  const std::list<unsigned int> & iListTracksID,
740  int &ioMotherID,
741  std::list<unsigned int> & ioDaughtersID)
742 {
743  //get the trackid with the lowest timepoint and check that there is only one:
745  iDatabaseConnector,iListTracksID);
746  if (ioMotherID == -1)
747  {
748  QMessageBox msgBox;
749  msgBox.setText(
750  tr("Can not create the division as two of your selected tracks can be the mother") );
751  msgBox.exec();
752  return false;
753  }
754  //check that none of the 2 others tracks overlap the mother:
755  std::list<unsigned int>::const_iterator iter = iListTracksID.begin();
756  //to change: modify the method CheckOverlappingTracks:
757  unsigned int ioTraceIDToKeep = 0;
758  unsigned int ioTraceIDToDelete = 0;
759  while(iter != iListTracksID.end())
760  {
761  if (*iter != static_cast<unsigned int>(ioMotherID) )
762  {
763  std::list<unsigned int> TracksOverlappingToCheck;
764  TracksOverlappingToCheck.push_back(ioMotherID);
765  TracksOverlappingToCheck.push_back(*iter);
766  if (this->CheckOverlappingTracks(TracksOverlappingToCheck,
767  ioTraceIDToKeep, ioTraceIDToDelete, iDatabaseConnector) )
768  {
769  QMessageBox msgBox;
770  msgBox.setText(
771  tr("Can not create the division as one daughter is overlapping the mother") );
772  msgBox.exec();
773  return false;
774  }
775  ioDaughtersID.push_back(*iter);
776  }
777  ++iter;
778  }
779  return true;
780 }
781 
782 //-------------------------------------------------------------------------
783 
784 //-------------------------------------------------------------------------
785 int QGoDBTrackManager::CreateTrackFamily(vtkMySQLDatabase* iDatabaseConnector,
786  unsigned int iMotherTrackID, const std::list<unsigned int> & iDaughtersID)
787 {
788  int oTrackFamilyID = -1;
789  //check that the mother is not already a mother in a trackfamily:
790  GoDBTrackFamilyRow TrackFamily;
791  TrackFamily.SetField<unsigned int>("TrackIDMother", iMotherTrackID);
792  if (TrackFamily.DoesThisTrackFamilyAlreadyExists(iDatabaseConnector) != -1)
793  {
794  QMessageBox msgBox;
795  msgBox.setText(
796  tr("Can not create the division as the Mother track is already mother of other daugthers") );
797  msgBox.exec();
798  return oTrackFamilyID;
799  }
800  if(iDaughtersID.size() != 2)
801  {
802  std::cout<<"Pb, there is more than 2 daughters to create the division !!";
803  std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__;
804  std::cout << std::endl;
805  return oTrackFamilyID;
806  }
807  std::list<unsigned int>::const_iterator iter = iDaughtersID.begin();
808  unsigned int TrackIDDaughterOne = *iter;
809  ++iter;
810  unsigned int TrackIDDaughterTwo = *iter;
811  TrackFamily.SetField<unsigned int>("TrackIDDaughter1", TrackIDDaughterOne);
812 
813  TrackFamily.SetField<unsigned int>("TrackIDDaughter2", TrackIDDaughterTwo);
814  this->m_TrackContainerInfoForVisu->AddDivision(iMotherTrackID, TrackIDDaughterOne,
815  TrackIDDaughterTwo);
816  return TrackFamily.SaveInDB(iDatabaseConnector);
817 }
818 //-------------------------------------------------------------------------
819 
820 //-------------------------------------------------------------------------
822  vtkMySQLDatabase* iDatabaseConnector,
823  unsigned int iDaughterID, unsigned int iTrackFamilyID)
824 {
825  GoDBTrackRow Daughter;
826  Daughter.SetValuesForSpecificID(iDaughterID, iDatabaseConnector);
827  Daughter.SetField<unsigned int>("TrackFamilyID", iTrackFamilyID);
828  Daughter.SaveInDB(iDatabaseConnector);
829 }
830 //-------------------------------------------------------------------------
831 
832 //-------------------------------------------------------------------------
834  vtkMySQLDatabase* iDatabaseConnector,
835  std::list<unsigned int> &ioTrackIDsOfTheFamilies)
836 {
837  //delete the daughtersLineageID then as they are useless:
838  std::list<unsigned int> DaughtersLineageID =
839  this->m_CollectionOfTraces->GetListCollectionIDs(iDatabaseConnector,
840  ioTrackIDsOfTheFamilies);
841 
842  std::list<unsigned int> FirstDaugthersIDs = ioTrackIDsOfTheFamilies;
843  std::list<unsigned int>::iterator iter = FirstDaugthersIDs.begin();
844  ioTrackIDsOfTheFamilies.clear(); //in order not to have twice the daughtersIDs
845 
846  while(iter != FirstDaugthersIDs.end() )
847  {
848  std::list<unsigned int> ListDaughterID;
849  ListDaughterID.push_back(*iter);
850  std::list<unsigned int> LineageIDofDaughter =
851  this->m_CollectionOfTraces->GetListCollectionIDs(iDatabaseConnector, ListDaughterID);
852  if (LineageIDofDaughter.empty()) //need to put back the ID of the daughter as it won't be returned by the query
853  {
854  ioTrackIDsOfTheFamilies.push_back(*iter);
855  }
856  else
857  {
858  std::list<unsigned int> CollectionID;
859  CollectionID.push_back(LineageIDofDaughter.front());
860  std::list<unsigned int> TrackIDsofTheFamily =
862  iDatabaseConnector, CollectionID);
863  std::list<unsigned int>::iterator iterTrackIDs = TrackIDsofTheFamily.begin();
864  while (iterTrackIDs != TrackIDsofTheFamily.end() )
865  {
866  ioTrackIDsOfTheFamilies.push_back(*iterTrackIDs);
867  ++iterTrackIDs;
868  }
869  }
870  ++iter;
871  }
872 
873  return DaughtersLineageID;
874 }
875 //-------------------------------------------------------------------------
876 
877 //-------------------------------------------------------------------------
879  vtkMySQLDatabase *iDatabaseConnector)
880 {
881  std::list<unsigned int> ListTrackIDs =
882  this->m_CollectionOfTraces->GetTrackFamilyDataFromDB(iDatabaseConnector);
883  this->m_TrackContainerInfoForVisu->SetListOfDivisions(ListTrackIDs);
884 }
885 //-------------------------------------------------------------------------
886 
887 //-------------------------------------------------------------------------
888 void QGoDBTrackManager::DeleteTheDivisions(std::list<unsigned int> iDivisions)
889 {
890  //check that the selected traces are all mother, if not message in the status bar:
891  std::list<unsigned int> TrackIDNotMother = std::list<unsigned int>();
892  std::list<unsigned int> CheckedTracks;
893 
894  if(iDivisions.size())
895  {
896  CheckedTracks = iDivisions;
897  }
898  else
899  {
900  CheckedTracks =
902  }
903 
904  std::list<unsigned int> TrackIDsWithNoLineage = std::list<unsigned int>();
905  std::list<unsigned int> LineagesToDelete = std::list<unsigned int>();
906  if (CheckedTracks.empty() )
907  {
908  QMessageBox msgBox;
909  msgBox.setText(
910  tr("Please select the MotherTracks you want the divisions to be deleted") );
911  msgBox.exec();
912  return;
913  }
914  std::list<unsigned int>::iterator iter = CheckedTracks.begin();
915  while (iter != CheckedTracks.end())
916  {
918  GoDBTrackFamilyRow Division;
919  Division.SetField("TrackIDMother", *iter);
920  int TrackFamilyToDelete = Division.DoesThisTrackFamilyAlreadyExists(this->m_DatabaseConnector);
921  if (TrackFamilyToDelete == -1) //the selected track is not a mother
922  {
923  TrackIDNotMother.push_back(*iter);
924  }
925  else
926  {
927  Division.SetValuesForSpecificID(TrackFamilyToDelete, this->m_DatabaseConnector); //set the value of the existing TrackFamily
928  this->DeleteOneDivision(Division, this->m_DatabaseConnector, TrackIDsWithNoLineage, LineagesToDelete );
929  }
930  ++iter;
931  }
932 
933  this->PrintAMessageForTracksWithNoDivision(TrackIDNotMother);
934 
935  if (!TrackIDsWithNoLineage.empty() ) //set the lineageID to 0 and update the bounding boxes of the previous lineages
936  {
937  emit CheckedTracksToAddToSelectedLineage(TrackIDsWithNoLineage, 0, LineagesToDelete);
938  }
939 }
940 //-------------------------------------------------------------------------
941 
942 //-------------------------------------------------------------------------
944  vtkMySQLDatabase* iDatabaseConnector,
945  std::list<unsigned int> &ioTrackIDsNoLineage,
946  std::list<unsigned int> &ioMotherLineageToDelete)
947 {
948  std::list<unsigned int> DaughtersIDs;
949  DaughtersIDs.push_back( iDivision.GetMapValue<unsigned int>("TrackIDDaughter1") );
950  DaughtersIDs.push_back( iDivision.GetMapValue<unsigned int>("TrackIDDaughter2") );
951  int MotherID = iDivision.GetMapValue<int>("TrackIDMother");
952  bool IsPartOfBiggerLineage = true;
953 
954  if (!this->IsTheTrackADaughter(MotherID, this->m_DatabaseConnector) ) // set the lineageID to 0
955  {
956  ioTrackIDsNoLineage.push_back(MotherID);
957  IsPartOfBiggerLineage = false;
958  }
959 
960  //delete the division from the database:
961  iDivision.DeleteFromDB(this->m_DatabaseConnector);
962 
963  //update the different values for the daughters of the division:
964  this->UpdateFormerDaughtersOfADeletedDivision(DaughtersIDs, ioTrackIDsNoLineage,
965  IsPartOfBiggerLineage);
966 
967  //delete the division from the visu:
968  this->m_TrackContainerInfoForVisu->DeleteADivision( MotherID );
969 
970  if (!IsPartOfBiggerLineage) //the mother is not a daughter and the daughters are not mother, the lineage need to be deleted
971  {
973  GoDBTrackRow Mother(MotherID, this->m_DatabaseConnector);
975  ioMotherLineageToDelete.push_back(Mother.GetMapValue<unsigned int>("lineageID") );
976  }
977 }
978 //-------------------------------------------------------------------------
979 
980 //-------------------------------------------------------------------------
982  std::list<unsigned int> iDaughtersID,
983  std::list<unsigned int> &ioTrackIDsNoLineage,
984  bool &ioPartOfHigherLineage)
985 {
986  std::list<unsigned int>::iterator iter = iDaughtersID.begin();
987  while (iter != iDaughtersID.end() )
988  {
989  if (*iter != 0)
990  {
993  if (this->IsTheTrackAMother(*iter, this->m_DatabaseConnector) )
994  {
996  this->m_DatabaseConnector, ioPartOfHigherLineage);
997  }
998  else
999  {
1000  ioTrackIDsNoLineage.push_back(*iter);
1001  }
1002  }
1003  ++iter;
1004  }
1006 }
1007 //-------------------------------------------------------------------------
1008 
1009 //-------------------------------------------------------------------------
1011  std::list<unsigned int> iTracksNoDivision)
1012 {
1013  if (!iTracksNoDivision.empty() )
1014  {
1015  std::string Message = "Nothing has been done for these tracks ";
1016  std::list<unsigned int>::iterator iter = iTracksNoDivision.begin();
1017  while (iter != iTracksNoDivision.end() )
1018  {
1019  Message += ConvertToString<unsigned int>(*iter);
1020  Message += ", ";
1021  ++iter;
1022  }
1023  Message += "because they are not mothers of any divisions";
1024  emit PrintMessage(Message.c_str());
1025  }
1026 }
1027 //-------------------------------------------------------------------------
1028 
1029 //-------------------------------------------------------------------------
1030 unsigned int QGoDBTrackManager::IsTheTrackAMother(unsigned int iDaughterID,
1031  vtkMySQLDatabase* iDatabaseConnector)
1032 {
1033  GoDBTrackFamilyRow Family;
1034  Family.SetField<unsigned int>("TrackIDMother", iDaughterID);
1035 
1036  int TrackFamilyID = Family.DoesThisTrackFamilyAlreadyExists(iDatabaseConnector);
1037  if (TrackFamilyID != -1)
1038  {
1039  return static_cast< unsigned int >( TrackFamilyID );
1040  }
1041  return 0;
1042 }
1043 //-------------------------------------------------------------------------
1044 
1045 //-------------------------------------------------------------------------
1046 unsigned int QGoDBTrackManager::IsTheTrackADaughter(unsigned int iTrackID,
1047  vtkMySQLDatabase* iDatabaseConnector)
1048 {
1049  GoDBTrackRow Track(iTrackID, iDatabaseConnector);
1050  return ss_atoi<unsigned int> (Track.GetMapValue("TrackFamilyID") );
1051 }
1052 //-------------------------------------------------------------------------
1053 
1054 //-------------------------------------------------------------------------
1056  unsigned int iDaughterID, vtkMySQLDatabase* iDatabaseConnector,
1057  bool &ioPartOfHigherLineage)
1058 {
1059  //GoDBTrackRow Daughter(iDaughterID, iDatabaseConnector);
1060  std::list<unsigned int> PreviousLineageToDelete = std::list<unsigned int>();
1061  if (!ioPartOfHigherLineage) //the lineage should not be deleted if higher tracks belong to it
1062  {
1063  GoDBTrackRow Daughter(iDaughterID, iDatabaseConnector);
1064  PreviousLineageToDelete.push_back( Daughter.GetMapValue<unsigned int>("lineageID") );
1065  //get the previous lineage ID of the daughter
1066  ioPartOfHigherLineage = true; // the second daughter will have a lineage set to 0 anyway
1067  }
1068 
1069  //get all the tracks daugthers of the DaughterID:
1070  std::list<unsigned int> TracksIDs = this->m_TrackContainerInfoForVisu->GetSubLineage(iDaughterID);
1071  if (TracksIDs.size() > 1)
1072  {
1073  emit NewLineageToCreateFromTracks(TracksIDs, iDaughterID, PreviousLineageToDelete); //need to create a new lineage with
1074  //the family of the daughter
1075  }
1076 }
1077 //-------------------------------------------------------------------------
1078 
1079 //-------------------------------------------------------------------------
1081  vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID,
1082  unsigned int iMeshTimePoint,
1083  std::list<unsigned int> &ioMotherTrackDivisionToUpdate)
1084 {
1085  std::string Message = "";
1086  unsigned int TrackMinTimePoint =
1087  this->m_CollectionOfTraces->GetBoundedBoxTimePoint(iDatabaseConnector, iTrackID, true);
1088  unsigned int TrackMaxTimePoint =
1089  this->m_CollectionOfTraces->GetBoundedBoxTimePoint(iDatabaseConnector, iTrackID, false);
1090  //if the mesh inside the bounding box of the track, no pb:
1091  if (iMeshTimePoint > TrackMinTimePoint && iMeshTimePoint < TrackMaxTimePoint)
1092  {
1093  return Message;
1094  }
1095 
1096  unsigned int DivisionIDTrackIsAMother = this->IsTheTrackAMother(iTrackID, iDatabaseConnector);
1097  unsigned int DivisionIDTrackIsADaughter = this->IsTheTrackADaughter(iTrackID, iDatabaseConnector);
1098  //if the track doesn't belong to any division, no pb:
1099  if (!DivisionIDTrackIsAMother && !DivisionIDTrackIsADaughter)
1100  {
1101  return Message;
1102  }
1103 
1104  if (DivisionIDTrackIsAMother)
1105  {
1106  if (iMeshTimePoint >= TrackMinTimePoint)
1107  {
1108  //check that the meshtimepoint < timepoint min daughter if not, message
1109  unsigned int DivisionToUpdate = this->CheckBoundingBoxDivisionAsAMother(
1110  iDatabaseConnector, iMeshTimePoint, DivisionIDTrackIsAMother );
1111  if (DivisionToUpdate != 0)
1112  {
1113  ioMotherTrackDivisionToUpdate.push_back(DivisionToUpdate);
1114  }
1115  else
1116  {
1117  Message = "The mesh will not belong to any track as there is a problem with the division";
1118  return Message;
1119  }
1120  }
1121  }
1122 
1123  if (DivisionIDTrackIsADaughter)
1124  {
1125  if (iMeshTimePoint > TrackMaxTimePoint)
1126  {
1127  return Message;
1128  }
1129  //check that the meshtimepoint > timepoint max mother if not, message
1130  unsigned int DivisionToUpdate =
1131  this->CheckBoundingBoxDivisionAsADaughter(iDatabaseConnector, iMeshTimePoint,
1132  DivisionIDTrackIsADaughter);
1133  if (DivisionToUpdate != 0)
1134  {
1135  ioMotherTrackDivisionToUpdate.push_back(DivisionToUpdate);
1136  }
1137  else
1138  {
1139  Message = "The mesh will not belong to any track as there is a problem with the division";
1140  return Message;
1141  }
1142  }
1143  return Message;
1144 }
1145 //-------------------------------------------------------------------------
1146 
1147 //-------------------------------------------------------------------------
1149  vtkMySQLDatabase* iDatabaseConnector, unsigned int iTimePoint, unsigned int iTrackFamilyID )
1150 {
1151  if(iTrackFamilyID != 0)
1152  {
1153  GoDBTrackFamilyRow Division(iTrackFamilyID, iDatabaseConnector);
1154  if ( (iTimePoint < this->m_CollectionOfTraces->GetBoundedBoxTimePoint(
1155  iDatabaseConnector, Division.GetMapValue<unsigned int>("TrackIDDaughter1") )
1156  && (iTimePoint < this->m_CollectionOfTraces->GetBoundedBoxTimePoint(
1157  iDatabaseConnector, Division.GetMapValue<unsigned int>("TrackIDDaughter2") ) ) ) )
1158  {
1159  return Division.GetMapValue<unsigned int>("TrackIDMother");
1160  }
1161  return 0;
1162  }
1163  return 0;
1164 }
1165 //-------------------------------------------------------------------------
1166 
1167 //-------------------------------------------------------------------------
1169  vtkMySQLDatabase* iDatabaseConnector, unsigned int iTimePoint, unsigned int iTrackFamilyID )
1170 {
1171  if (iTrackFamilyID != 0)
1172  {
1173  GoDBTrackFamilyRow Division(iTrackFamilyID, iDatabaseConnector);
1174  if ( iTimePoint > this->m_CollectionOfTraces->GetBoundedBoxTimePoint(
1175  iDatabaseConnector, Division.GetMapValue<unsigned int>("TrackIDMother") ) )
1176  {
1177  return Division.GetMapValue<unsigned int>("TrackIDMother");
1178  }
1179  return 0;
1180  }
1181  return 0;
1182 }
1183 //-------------------------------------------------------------------------
1184 
1185 //-------------------------------------------------------------------------
1187  vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID )
1188 {
1189  std::list<unsigned int> Tracks;
1190  Tracks.push_back(iTrackID);
1191  std::list<unsigned int> oDivisionIDs = this->m_CollectionOfTraces->GetTrackFamilyID(
1192  iDatabaseConnector, Tracks );
1193  return oDivisionIDs;
1194 }
1195 //-------------------------------------------------------------------------
1196 
1197 //-------------------------------------------------------------------------
1198 void QGoDBTrackManager::UpdateDivisions(const std::list<unsigned int> & iListMotherTrackIDs)
1199 {
1200  std::list<unsigned int>::const_iterator iter = iListMotherTrackIDs.begin();
1201  while (iter != iListMotherTrackIDs.end() )
1202  {
1204  ++iter;
1205  }
1206 }
1207 //-------------------------------------------------------------------------
1208 
1209 //-------------------------------------------------------------------------
1211 AddVolume(const unsigned int& iTrackID, const double& iVolume)
1212 {
1213  this->m_TrackContainerInfoForVisu->AddVolume(iTrackID, iVolume);
1214 }
1215 //-------------------------------------------------------------------------
1216 
1217 //-------------------------------------------------------------------------
1218 void
1220 AddVolumes(const std::list< std::pair<unsigned int, double> > & iVolumes)
1221 {
1222  std::list< std::pair<unsigned int, double> >::const_iterator it =
1223  iVolumes.begin();
1224  while(it != iVolumes.end())
1225  {
1226  this->m_TrackContainerInfoForVisu->AddVolume((*it).first, (*it).second);
1227  ++it;
1228  }
1229 }
1230 //-------------------------------------------------------------------------
1231 
1232 //-------------------------------------------------------------------------
1233 void
1235 RemoveVolumes(const std::list< std::pair<unsigned int, double> > & iVolumes)
1236 {
1237  std::list< std::pair<unsigned int, double> >::const_iterator it =
1238  iVolumes.begin();
1239  while(it != iVolumes.end())
1240  {
1241  this->m_TrackContainerInfoForVisu->AddVolume((*it).first, (-1)*((*it).second));
1242  ++it;
1243  }
1244 }
1245 //-------------------------------------------------------------------------
1246 
1247 //-------------------------------------------------------------------------
1248 void
1250 AddVolumes(const std::list< std::pair<unsigned int, double> > & iVolumes,
1251  unsigned int iTrackID)
1252 {
1253  std::list< std::pair<unsigned int, double> >::const_iterator it =
1254  iVolumes.begin();
1255  while(it != iVolumes.end())
1256  {
1257  this->m_TrackContainerInfoForVisu->AddVolume(iTrackID, (*it).second);
1258  ++it;
1259  }
1260 }
1261 //-------------------------------------------------------------------------
1262 
1263 //-------------------------------------------------------------------------
1264 void
1266 RemoveVolumes(const std::list< std::pair<unsigned int, double> > & iVolumes,
1267  unsigned int iTrackID)
1268 {
1269  std::list< std::pair<unsigned int, double> >::const_iterator it =
1270  iVolumes.begin();
1271  while(it != iVolumes.end())
1272  {
1273  this->m_TrackContainerInfoForVisu->AddVolume(iTrackID, (-1)*((*it).second));
1274  ++it;
1275  }
1276 }
1277 //-------------------------------------------------------------------------
1278 
1279 //------------------------------------------------------------------------
1281 {
1282  // open db connection
1284 
1285  // make sure only one trace is checked
1286  std::list< unsigned int > ListCheckedTraces =
1287  this->GetListHighlightedIDs();
1288  if ( ListCheckedTraces.size() != 1 )
1289  {
1290  QMessageBox msgBox;
1291  msgBox.setText(
1292  tr("Please select one and only one %1 to go to")
1293  .arg( this->m_TraceName.c_str() ) );
1294  msgBox.exec();
1295  return;
1296  }
1297 
1298  //get last point of the trace from db
1299  std::stringstream points( this->m_CollectionOfTraces->GetPoints(
1300  this->m_DatabaseConnector,
1301  this->m_TraceName,
1302  ListCheckedTraces.front()) );
1303 
1304  int numberOfPoints = 0;
1305  int count = 1;
1306  points >> numberOfPoints;
1307 
1308  if( numberOfPoints > 0)
1309  {
1310  // go to the last point
1311  double point = 0.0;
1312  while( count < numberOfPoints )
1313  {
1314  points >> point;
1315  points >> point;
1316  points >> point;
1317  points >> point;
1318  ++count;
1319  }
1320 
1321  double x = 0;
1322  points >> x;
1323  double y = 0;
1324  points >> y;
1325  double z = 0;
1326  points >> z;
1327  double t = 0;
1328  points >> t;
1329 
1330  emit NeedToGoToTheRealLocation( x,y,z, static_cast<int>(t) );
1331  }
1332 
1333  // close db connection
1335 }
1336 //-------------------------------------------------------------------------
1337 
1338 //------------------------------------------------------------------------
1340 {
1341  // open db connection
1343 
1344  // make sure only one trace is checked
1345  std::list< unsigned int > ListCheckedTraces =
1346  this->GetListHighlightedIDs();
1347  if ( ListCheckedTraces.size() != 1 )
1348  {
1349  QMessageBox msgBox;
1350  msgBox.setText(
1351  tr("Please select one and only one %1 to go to")
1352  .arg( this->m_TraceName.c_str() ) );
1353  msgBox.exec();
1354  return;
1355  }
1356 
1357  //get last point of the trace from db
1358  std::stringstream points( this->m_CollectionOfTraces->GetPoints(
1359  this->m_DatabaseConnector,
1360  this->m_TraceName,
1361  ListCheckedTraces.front()) );
1362 
1363  int numberOfPoints = 0;
1364  points >> numberOfPoints;
1365 
1366  if( numberOfPoints > 0)
1367  {
1368  double x = 0;
1369  points >> x;
1370  double y = 0;
1371  points >> y;
1372  double z = 0;
1373  points >> z;
1374  double t = 0;
1375  points >> t;
1376 
1377  // go to the last point of the track
1378  emit NeedToGoToTheRealLocation( x,y,z, static_cast<int>(t) );
1379  }
1380 
1381  // close db connection
1383 }
1384 //-------------------------------------------------------------------------
1385 
1386 //------------------------------------------------------------------------
1387 std::vector<unsigned int>
1388 QGoDBTrackManager::GetTrackFamily(vtkMySQLDatabase* iDatabaseConnector,
1389  unsigned int iTrackID)
1390 {
1391  return this->m_CollectionOfTraces->GetTrackFamily(iDatabaseConnector,
1392  iTrackID);
1393 }
1394 //-------------------------------------------------------------------------
1395 
1396 //------------------------------------------------------------------------
1397 bool
1398 QGoDBTrackManager::isMother(vtkMySQLDatabase* iDatabaseConnector,
1399  unsigned int iTrackID)
1400 {
1401  return this->m_CollectionOfTraces->isMother(iDatabaseConnector,
1402  iTrackID);
1403 }
1404 //-------------------------------------------------------------------------
void TrackIDToBeModifiedWithWidget(std::list< unsigned int > iListTracksID)
void SaveTrackStructure(vtkMySQLDatabase *iDatabaseConnector, TrackStructure *iStructure)
virtual void DisplayInfoForLastCreatedTrace(vtkMySQLDatabase *iDatabaseConnector)
Virtual pure method: get the data needed from the database for the last created trace and display the...
virtual void UpdateHighlightedElementsInVisuContainer(int iTraceID)
std::list< unsigned int > GetDivisionIDsTheTrackBelongsTo(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID)
get the division IDs the track belongs to as a mother or as a daughter
int CreateCollectionWithNoTracesNoPoints(vtkMySQLDatabase *iDatabaseConnector, NameWithColorData iColor, T iNewCollection, int iTimePoint=-1)
save the collection in the database after getting an empty bounding box and return the corresponding ...
virtual void SetColorCoding(bool IsChecked)
bool IdentifyMotherDaughtersToCreateTrackFamily(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > &iListTracksID, int &ioMotherID, std::list< unsigned int > &ioDaughtersID)
get the trackID with the lowest timepoint as the mother trackID, if several tracks have the lowest ti...
virtual void UpdateVisibleElementsInVisuContainer(int iTraceID)
void CreateALineageWithFormerDaughterOfADeletedDivision(unsigned int iDaughterID, vtkMySQLDatabase *iDatabaseConnector, bool &ioPartOfHigherLineage)
set the trackfamilyID of the daughter to 0, get all the tracks with the same lineage and emit a signa...
int CreateTrackFamily(vtkMySQLDatabase *iDatabaseConnector, unsigned int iMotherTrackID, const std::list< unsigned int > &iDaughtersID)
check that the mothertrackID is not already a mother in another trackfamily, create the trackfamily i...
void AddVolumes(const std::list< std::pair< unsigned int, double > > &iVolumes)
Modify volume of the given track ID.
std::list< double * > GetCoordinateCenterBoundingBox(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTraceID)
return a list of the coordinates of all the centers of the bounding boxes for all the collectionOf co...
virtual void UpdateBoundingBoxes(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > &iListTracesIDs, bool UpdateTW=true)
update in the database the bounding boxes corresponding to the TracesIDs and update the corresponding...
virtual void SetCollectionsTraceNames()
virtual pure method: set the std::string class members
void UpdateCurrentElementFromDB(unsigned int iTraceID, double irgba[4], bool IsVisible=false)
Update Current Element from te database.
GoFigureTrackAttributes ComputeAttributes() const
void DeleteFromDB(vtkMySQLDatabase *iDatabaseConnector)
delete from the database the row which has the same TableID
Definition: GoDBRow.cxx:273
void DisplayOnlyCalculatedValuesForExistingTrack(GoFigureTrackAttributes *iTrackAttributes, unsigned int iTrackID)
display in the TW the values extracted from iTrackAttributes called when loading all tracks from data...
std::string m_CollectionName
unsigned int CreateNewTrackWithNoMesh(vtkMySQLDatabase *iDatabaseConnector)
create a new track with no mesh and no points in the database, add it in the TW and in the visu conta...
int GetTraceIDWithLowestTimePoint(vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs)
return the traceID with the lowest timepoint or -1 if there is not only one that have the lowest time...
unsigned int GetBoundedBoxTimePoint(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTraceID, bool MinTimePoint=true)
get the timepoint min or max for the trace
void addAction(QAction *action)
void TrackToSplit(unsigned int iTrackID, std::list< unsigned int > iListMeshIDs)
Abstract class inherited by QGoDBContourManager,Mesh,Track,Lineage.
void AddNewTraceIDInTS(std::pair< std::string, QColor > iTraceToAddData)
signal emitted when a new trace is created that need to be added in the trace settings widget...
void NewLineageToCreateFromTracks(std::list< unsigned int > iCheckedTracksIDs, unsigned int iTrackIDRoot, std::list< unsigned > iLineagesToDelete)
NameWithColorData * m_SelectedColorData
void UpdateFormerDaughtersOfADeletedDivision(std::list< unsigned int > iDaughtersID, std::list< unsigned int > &ioTrackIDsNoLineage, bool &ioPartOfHigherLineage)
check if the daughters are mothers, if yes, create a new lineage for them, if not, update the track familyID to 0 and fill the ioTrackIDsNoLineage with them, if ioPartOfHigherLineage is false, delete the lineage after creating a new one for the daughter family if the daughter is a mother and set the ioPartOfHigherLineage to true
virtual bool SetValuesForSpecificID(int ID, vtkMySQLDatabase *iDatabaseConnector)
get the data from the database corresponding to the specific ID and put them in the map ...
Definition: GoDBRow.cxx:209
void MeshesToAddToTrack(std::list< unsigned int > iListMeshes, unsigned int iTrackID)
int SaveInDB(vtkMySQLDatabase *DatabaseConnector)
int DoesThisTrackFamilyAlreadyExists(vtkMySQLDatabase *DatabaseConnector)
check if the track family already exists in the database, if yes, return the corresponding ID...
void SplitMergeTrackWithWidget()
get the trackIDs checked in the TW that will be modified with the widget and emit a signal with them ...
QString tr(const char *sourceText, const char *disambiguation, int n)
std::string m_CollectionOf
void DisplayInfoAndLoadVisuContainerForAllTracks(vtkMySQLDatabase *iDatabaseConnector)
get all the data from the database to load all the tracks for the imagingsession into the table widge...
void UpdateTrackFamilyIDForDaughter(vtkMySQLDatabase *iDatabaseConnector, unsigned int iDaughterID, unsigned int iTrackFamilyID)
update the trackFamilyID in the database for the track corresponding to iDaughterID, if the trackfamilyID is 0, then the lineageID will be set to 0 also for this track
unsigned int IsTheTrackADaughter(unsigned int iTrackID, vtkMySQLDatabase *iDatabaseConnector)
return the trackfamilyID of the division the track is a daughter of or 0 if the track is not a daught...
manages a map with keys matching fields of the gofiguredatabase TrackFamily table and values of the m...
void DeleteADivision(const unsigned int &iMotherID)
std::string GetPoints(vtkMySQLDatabase *iDatabaseConnector, std::string iTraceName, unsigned int iTraceID)
virtual void UpdateTWAndContainerForImportedTraces(const std::vector< int > &iVectorImportedTraces, vtkMySQLDatabase *iDatabaseConnector)
get the data needed from the database for the imported traces,display them in new inserted rows of th...
virtual void DeleteCheckedTraces(vtkMySQLDatabase *iDatabaseConnector)
delete the checked traces from the database, the TW and the container for visu
TrackContainer * m_TrackContainerInfoForVisu
virtual void DisplayInfoForAllTraces(vtkMySQLDatabase *iDatabaseConnector)
Virtual pure method: get the data needed from the database and display them in the m_Table for all tr...
double * GetVectorFromQColor(QColor iColor)
return a double rgba[4] from a QColor
std::list< unsigned int > GetListTracesIDsFromThisCollectionOf(vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraces)
get the list of IDs belonging to the iListTraces as collectionof
void UpdateTWAndContainerWithImportedTracesTemplate(T *iTWContainer, const std::vector< int > &iVectorTraceIDs, vtkMySQLDatabase *iDatabaseConnector)
update for the imported traces the table widget and the database info of the container for visu...
void LoadInfoVisuContainerForTrackFamilies(vtkMySQLDatabase *iDatabaseConnector)
get all the data from the database of the track family table and give the corresponding info to the t...
bool SetValuesForSpecificID(int ID, vtkMySQLDatabase *iDatabaseConnector)
This class describes the specificities of the GoDBTWContainerForTrackLineage for track.
this class manages the map with the keys matching the fields of the Track gofiguredatabase table and ...
Definition: GoDBTrackRow.h:49
std::list< unsigned int > GetListCollectionIDs(vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTracesIDs, bool ExcludeZero=true, bool Distinct=true)
get the list of IDs that are collection of iListTraces
std::list< unsigned int > GetListTracesIDsFromThisCollectionOf(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > &iListTraces)
get the collectionOf IDs for the TracesIDs found in iListTraces
void RemoveVolumes(const std::list< std::pair< unsigned int, double > > &iVolumes)
Modify volume of the given track ID.
bool CheckOverlappingTracks(std::list< unsigned int > iTrackIDs, unsigned int &ioTraceIDToKeep, unsigned int &ioTraceIDToDelete, vtkMySQLDatabase *iDatabaseConnector)
check that the 2 tracks are not overloaping, if not, return the trackID to keep for the merge and the...
std::list< unsigned int > GetHighlightedElementsTraceID()
Get the list of highlighted elements TraceID.
void ImportTrackInCurrentElement(std::map< unsigned int, double * > &iMeshes)
Update the current element map then polydata.
Structure which represent a track, and used for interaction between Visualization and TableWidget...
void setText(const QString &text)
QGoDBTrackManager(int iImgSessionID, QWidget *iparent)
bool isMother(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID)
std::list< unsigned int > GetTrackFamilyDataFromDB(vtkMySQLDatabase *iDatabaseConnector)
void CreateCorrespondingTrackFamily(std::list< unsigned int > iDivisions=std::list< unsigned int >())
slot called when the user chose &quot;Create a new division from checked tracks&quot;
virtual int SaveInDB(vtkMySQLDatabase *DatabaseConnector)
save the row in the database if the TraceID is set to &quot;0&quot;, update the existing traceRow if the TraceI...
void CheckedTracksToAddToSelectedLineage(std::list< unsigned int > iDaughtersID, unsigned int iLineageID, std::list< unsigned > iLineagesToDelete)
void AddActionsContextMenu(QMenu *iMenu)
void SetInfo(unsigned int iImgSessionID, QWidget *iParent)
set the variables class members
void SetTracksInfoContainerForVisu(TrackContainer *iContainerForVisu)
set the m_TrackContainerInfoForVisu to the iContainerForVisu
unsigned int TraceID
void NeedToGetDatabaseConnection()
void PrintMessage(QString iMessage, int iTimeOut=0)
vtkPolyData * Nodes
void SetListOfDivisions(std::list< unsigned int > &iListOfDivisions)
void AddVolume(const unsigned int &iTrackID, const double &iVolume)
Modify volume of the given track ID.
std::list< unsigned int > GetSubLineage(const unsigned int &iTrackID)
std::list< unsigned int > UpdateTheTracesColorTemplate(vtkMySQLDatabase *iDatabaseConnector, C *iContainerInfoForVisu)
update the visu container, the database and the TW with the user selected color for the highlighted t...
std::list< unsigned int > UpdateTheTracesColor(vtkMySQLDatabase *iDatabaseConnector)
virtual pure. update the color of the checked traces in the database, the visu container and the TW a...
void NeedToGoToTheRealLocation(double, double, double, int)
virtual void DisplayInfoForExistingTrace(vtkMySQLDatabase *iDatabaseConnector, int iTraceID)
Virtual pure method: get the data needed from the database for the existing trace with iTraceID and u...
std::list< unsigned int > GetTrackIDFromDaughtersFamilies(vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > &ioTrackIDsOfTheFamilies)
get the lineage ids of the 2 daughters, then get all the tracks belonging to these 2 lineages and pus...
std::list< unsigned int > GetTraceIDsBelongingToCollectionID(vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs, unsigned int iCollectionID)
get the tracesIDs contained in iListTraceIDs that have iCollectionID as a collectionID ...
unsigned int CheckBoundingBoxDivisionAsAMother(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTimePoint, unsigned int iTrackFamilyID)
check that the iTimePoint is &lt; to the mintimepoint of the daughter from the division where trackID is...
void SaveTrackCurrentElement(vtkMySQLDatabase *iDatabaseConnector)
create or update the track contained in the current element of the track container into the database...
void MergeTracks()
check that only 2 tracks are checked in the TW, if not display a message to the user, check that the 2 tracks are not overlapping, if yes, display a message to the user, get the meshes of the track with the lowest timepoints, delete this track and send a signal for the list of meshes of the previous track to be reassigned to the track with the highest timepoints
void ResetCurrentElement()
Reset Current Element to a default state.
MultiIndexContainerElementType m_CurrentElement
Current Element of the trace type.
void DeleteOneDivision(GoDBTrackFamilyRow iDivision, vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > &ioTrackIDsNoLineage, std::list< unsigned int > &ioMotherLineageToDelete)
set the trackfamilyid of the daughters to 0, delete the trackfamily from the database and from the vi...
void UpdatePointsOfCurrentElementForImportedTrack(std::map< unsigned int, double * > iMeshesInfo, vtkMySQLDatabase *iDatabaseConnector)
update the points of the imported track in current_element with the info from the meshes and save the...
void SetField(const std::string &key, const T &value)
convert the value into a string and assign it to the key in the map
Definition: GoDBRow.h:73
std::list< unsigned int > GetTrackFamilyID(vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTrackIDs)
return the trackFamilyIDs the track belongs to (as a mother or as a daughter)
void UpdateBoundingBoxes(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > &iListTracesIDs)
void SetTrackAttributes(GoFigureTrackAttributes *iTrackAttributes)
set m_TrackAttributes to iTrackAttributes, needs to be called before displaying the volume...
Wraps a boost multi index container of TrackStructure. This class intends to synchronize Track repres...
void DeleteListTraces(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > &iListTraces)
delete the traces of the list from the database, the TW and the container for visu ...
unsigned int CheckBoundingBoxDivisionAsADaughter(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTimePoint, unsigned int iTrackFamilyID)
check that the iTimePoint is &gt; to the maxtimepoint of the mother from the division where trackID is a...
std::vector< unsigned int > GetTrackFamily(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID)
TrackStructure * UpdatePointsForATrack(const unsigned int &iTrackID, std::list< double * > &iListCenterBoundingBoxes)
get the element with iTrackID into the current element, remove it from the container, recalculate the points from the iListCenterBoundingBox and emit a signal for the current element to be saved into the database
GoDBTWContainerForTrack * m_TWContainer
void CreateDivisionPolydata(const unsigned int &iMother)
bool isMother(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID)
void UpdateDivisions(const std::list< unsigned int > &iListMotherTrackIDs)
update the track container for visu and consequently the divisions in the visu
void DeleteTheDivisions(std::list< unsigned int > iDivisions=std::list< unsigned int >())
slot called when the user chose &quot;Delete the division for this tracks&quot;
void TrackIDToEmit()
check that there is only one checked track in the TW and emit a signal with it as the checked mesh is...
virtual std::list< unsigned int > GetListHighlightedIDs()
std::pair< std::string, QColor > NameWithColorData
void AddValuesForID(const std::vector< std::string > &iColumnsNames, const std::vector< std::string > &iValues, unsigned int iID, const std::string &iColumnNameForTraceID)
add values in the table for the corresponding traceID and column names
void AddDivision(const unsigned int &iMotherID, const unsigned int &iDaughter1ID, const unsigned int &iDaughter2ID, const bool &iVisible=true)
void AddVolume(const unsigned int &iTrackID, const double &iVolume)
QAction * menuAction() const
void UpdateTrackPolydataForVisu(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID)
get the center of bounding boxes from the database for the meshes belonging to the iTrackID...
void NeedMeshesInfoForImportedTrack(unsigned int iTrackID)
virtual void GetTracesInfoFromDBAndModifyContainerForVisu(vtkMySQLDatabase *iDatabaseConnector, std::list< unsigned int > iListTraceIDs=std::list< unsigned int >())
get the info needed from the database to update the container for visu
QGoTableWidget * m_Table
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
virtual void DisplayInfoForTracesForSpecificTPs(vtkMySQLDatabase *iDatabaseConnector, const std::list< unsigned int > &iListTPs)
vtkMySQLDatabase * m_DatabaseConnector
void DBConnectionNotNeededAnymore()
std::vector< unsigned int > GetTrackFamily(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID)
virtual void AddActionsContextMenu(QMenu *iMenu)
std::string GetMapValue(const std::string &key)
return the value for the field map[key] after having removed the " at the beginning and at the end of...
Definition: GoDBRow.cxx:174
unsigned int IsTheTrackAMother(unsigned int iDaughterID, vtkMySQLDatabase *iDatabaseConnector)
return the trackfamilyID of the division the track is a mother of or 0 if the track is not a mother ...
void SetThePointsFromPolydata(vtkPolyData *iTrackVisu)
convert the iTrackVisu into a string and set the field &#39;points&#39; of the map
std::string CheckMeshCanBeAddedToTrack(vtkMySQLDatabase *iDatabaseConnector, unsigned int iTrackID, unsigned int iMeshTimePoint, std::list< unsigned int > &ioMotherTrackDivisionToUpdate)
check if the track belongs to a division and if it is possible to add the mesh without making the tra...
void PrintAMessageForTracksWithNoDivision(std::list< unsigned int > iTracksNoDivision)
build a message for the user to know which ones of the selected tracks have no division and emit a si...
GoDBCollectionOfTraces * m_CollectionOfTraces
void InsertCurrentElement()
Insert Current Element in the container.
bool UpdateElementHighlightingWithGivenTraceID(const unsigned int &iId)
Update element highlighting given it TraceId.