@@ -452,10 +452,10 @@ void MainWindow::loadPipelines() {
452
452
foreach (QString currentFpl, pipelines) {
453
453
// runPipelineMenu->addAction(QString::fromStdString(splitCustom(currentFpl.toStdString(), ".")[0]), this, &MainWindow::lowresSegmenter);
454
454
auto currentAction = runPipelineMenu->addAction (currentFpl); // QString::fromStdString(splitCustom(splitCustom(currentFpl.toStdString(), "/")[-1], ".")[0]));
455
- QObject::connect (currentAction, &QAction::triggered, std::bind (&MainWindow::runPipeline , this , cwd + " data/Pipelines/" + currentFpl.toStdString ()));
455
+ QObject::connect (currentAction, &QAction::triggered, std::bind (&MainWindow::runPipeline_wrapper , this , cwd + " data/Pipelines/" + currentFpl.toStdString ()));
456
456
457
457
// auto currentAction = runPipelineMenu->addAction(QString::fromStdString(splitCustom(someFile, ".")[0]));
458
- // QObject::connect(currentAction, &QAction::triggered, std::bind(&MainWindow::runPipeline , this, someFile));
458
+ // QObject::connect(currentAction, &QAction::triggered, std::bind(&MainWindow::runPipeline_wrapper , this, someFile));
459
459
}
460
460
}
461
461
@@ -2394,7 +2394,7 @@ void MainWindow::runForProject() {
2394
2394
for (const auto & item : m_runForProjectWsis) {
2395
2395
selectedFilesWidget->addItem (QString::fromStdString (item));
2396
2396
}
2397
- selectedFilesWidget->setMinimumWidth (selectedFilesWidget ->sizeHintForColumn (0 ));
2397
+ selectedFilesWidget->setMinimumWidth (allFilesWidget ->sizeHintForColumn (0 )); // set to use allFilesWidget size such that width always match
2398
2398
2399
2399
wsiDialogLayout->addWidget (allFilesWidget);
2400
2400
wsiDialogLayout->addWidget (buttonsWidget);
@@ -2502,13 +2502,13 @@ void MainWindow::addPipelines() {
2502
2502
}
2503
2503
}
2504
2504
// should update runPipelineMenu as new pipelines are being added
2505
- // runPipelineMenu->addAction(QString::fromStdString(splitCustom(someFile, ".")[0]), this, &MainWindow::runPipeline );
2505
+ // runPipelineMenu->addAction(QString::fromStdString(splitCustom(someFile, ".")[0]), this, &MainWindow::runPipeline_wrapper );
2506
2506
// auto currentAction = new QAction(QString::fromStdString(splitCustom(someFile, ".")[0]));
2507
2507
auto currentAction = runPipelineMenu->addAction (QString::fromStdString (splitCustom (someFile, " ." )[0 ]));
2508
- QObject::connect (currentAction, &QAction::triggered, std::bind (&MainWindow::runPipeline , this , someFile));
2508
+ QObject::connect (currentAction, &QAction::triggered, std::bind (&MainWindow::runPipeline_wrapper , this , someFile));
2509
2509
2510
2510
// auto currentAction = runPipelineMenu->addAction(currentFpl); //QString::fromStdString(splitCustom(splitCustom(currentFpl.toStdString(), "/")[-1], ".")[0]));
2511
- // QObject::connect(currentAction, &QAction::triggered, std::bind(&MainWindow::runPipeline , this, cwd + "data/Pipelines/" + currentFpl.toStdString()));
2511
+ // QObject::connect(currentAction, &QAction::triggered, std::bind(&MainWindow::runPipeline_wrapper , this, cwd + "data/Pipelines/" + currentFpl.toStdString()));
2512
2512
}
2513
2513
}
2514
2514
@@ -3097,127 +3097,121 @@ void MainWindow::runPipeline_wrapper(std::string path) {
3097
3097
currentWSIs = m_runForProjectWsis;
3098
3098
}
3099
3099
else {
3100
- currentWSIs.push_back (wsiList[curr_pos] );
3100
+ currentWSIs.push_back (filename );
3101
3101
}
3102
3102
3103
3103
auto progDialog = QProgressDialog (mWidget );
3104
3104
progDialog.setRange (0 , (int )currentWSIs.size () - 1 );
3105
- // progDialog.setContentsMargins(0, 0, 0, 0);
3106
3105
progDialog.setVisible (true );
3107
3106
progDialog.setModal (false );
3108
3107
progDialog.setLabelText (" Running pipeline across WSIs in project..." );
3109
- // QRect screenrect = mWidget->screen()[0].geometry();
3110
3108
progDialog.move (mWidget ->width () - progDialog.width () * 1.1 , progDialog.height () * 0.1 );
3111
3109
progDialog.show ();
3112
3110
3113
3111
QCoreApplication::processEvents (QEventLoop::AllEvents, 0 );
3114
3112
3115
- auto counter = 0 ;
3116
- for (const auto & currWSI : currentWSIs) {
3117
-
3118
- // if run for project is enabled, run the inference-export pipeline in a background thread, else don't
3119
- if (m_runForProject) {
3120
- std::atomic_bool stopped (false );
3121
- std::thread inferenceThread ([&, path]() {
3122
- runPipeline (path);
3123
- });
3124
- inferenceThread.detach ();
3113
+ // always run pipeline in background thread
3114
+ std::atomic_bool stopped (false );
3115
+ std::thread inferenceThread ([&, path, currentWSIs]() {
3116
+ auto counter = 0 ;
3117
+ for (const auto & currWSI : currentWSIs) {
3118
+ runPipeline (path, currWSI, counter);
3125
3119
}
3126
- else {
3127
- runPipeline (path );
3120
+ });
3121
+ inferenceThread. detach ( );
3128
3122
3129
- // now make it possible to edit prediction in the View Widget
3130
- // createDynamicViewWidget(modelMetadata["name"], someModelName);
3131
- }
3132
- }
3123
+ // now make it possible to edit prediction in the View Widget
3124
+ // createDynamicViewWidget(modelMetadata["name"], someModelName);
3133
3125
}
3134
3126
3135
- void MainWindow::runPipeline (std::string path) {
3127
+ void MainWindow::runPipeline (std::string path, std::string currWSI, int counter ) {
3136
3128
3137
- std::vector<std::string> currentWSIs;
3138
- if (m_runForProject) {
3139
- currentWSIs = m_runForProjectWsis;
3140
- }
3141
- else {
3142
- currentWSIs.push_back (filename);
3143
- }
3129
+ // setup paths for saving results
3130
+ QString wsiResultPath = (projectFolderName.toStdString () + " /results/" + splitCustom (splitCustom (currWSI, " /" ).back (), " ." )[0 ]).c_str ();
3131
+ wsiResultPath = wsiResultPath.replace (" //" , " /" );
3144
3132
3145
- auto progDialog = QProgressDialog (mWidget );
3146
- progDialog.setRange (0 , (int )currentWSIs.size () - 1 );
3147
- progDialog.setVisible (true );
3148
- progDialog.setModal (false );
3149
- progDialog.setLabelText (" Running pipeline across WSIs in project..." );
3150
- progDialog.move (mWidget ->width () - progDialog.width () * 1.1 , progDialog.height () * 0.1 );
3151
- progDialog.show ();
3133
+ // if folder does not exist, create one
3134
+ if (!QDir (wsiResultPath).exists ()) {
3135
+ QDir ().mkdir (wsiResultPath);
3136
+ }
3152
3137
3153
- QCoreApplication::processEvents (QEventLoop::AllEvents, 0 );
3138
+ // TODO: This now always saves result as TIFF, which is not correct. Need generic way of knowing which results that are exported and how to save these
3139
+ auto currPath = wsiResultPath.toStdString () + " /" + splitCustom (wsiResultPath.toStdString (), " /" ).back () + " .tiff" ;
3154
3140
3155
- auto counter = 0 ;
3156
- for (const auto & currWSI : currentWSIs) {
3141
+ // TODO: Perhaps use corresponding .txt-file to feed arguments in the pipeline
3142
+ // pipeline requires some user-defined inputs, e.g. which WSI to use (and which model?)
3143
+ std::map<std::string, std::string> arguments;
3144
+ arguments[" filename" ] = currWSI;
3145
+ arguments[" exportPath" ] = currPath;
3146
+ // arguments["modelPath"] = path;
3157
3147
3158
- // setup paths for saving results
3159
- std::cout << " Current save location: " << projectFolderName.toStdString () << std::endl;
3160
- QString wsiResultPath = (projectFolderName.toStdString () + " /results/" + splitCustom (splitCustom (currWSI, " /" ).back (), " ." )[0 ]).c_str ();
3161
- wsiResultPath = wsiResultPath.replace (" //" , " /" );
3148
+ // parse fpl-file, and run pipeline with corresponding input arguments
3149
+ auto pipeline = Pipeline (path, arguments);
3150
+ if (m_runForProject) {
3151
+ pipeline.parse ({}, false );
3152
+ }
3153
+ else {
3154
+ pipeline.parse ();
3155
+ }
3162
3156
3163
- // if folder does not exist, create one
3164
- if (!QDir (wsiResultPath).exists ()) {
3165
- QDir ().mkdir (wsiResultPath);
3157
+ // get and start running POs
3158
+ for (auto && po : pipeline.getProcessObjects ()) {
3159
+ if (po.second ->getNrOfOutputPorts () == 0 && std::dynamic_pointer_cast<Renderer>(po.second ) == nullptr ) {
3160
+ // Process object has no output ports, must add to window to make sure it is updated.
3161
+ reportInfo () << " Process object " << po.first << " had no output ports defined in pipeline, therefore adding to window so it is updated." << reportEnd ();
3162
+ addProcessObject (po.second );
3166
3163
}
3164
+ }
3167
3165
3168
- // TODO: This now always saves result as TIFF, which is not correct. Need generic way of knowing which results that are exported and how to save these
3169
- auto currPath = wsiResultPath.toStdString () + " /" + splitCustom (wsiResultPath.toStdString (), " /" ).back () + " .tiff" ;
3166
+ if (!m_runForProject) {
3167
+ // load renderers, if any
3168
+ for (const auto & renderer : pipeline.getRenderers ()) {
3169
+ auto currId = createRandomNumbers_ (8 );
3170
+ insertRenderer (" result_" + currId, renderer);
3171
+ createDynamicViewWidget (" result_" + currId, " result_" + currId);
3172
+ }
3173
+ }
3170
3174
3171
- // TODO: Perhaps use corresponding .txt-file to feed arguments in the pipeline
3172
- // pipeline requires some user-defined inputs, e.g. which WSI to use (and which model?)
3173
- std::map<std::string, std::string> arguments;
3174
- arguments[" filename" ] = filename;
3175
- arguments[" exportPath" ] = currPath;
3176
- // arguments["modelPath"] = path;
3175
+ if (m_runForProject) {
3176
+ // connect signal to update flag
3177
+ connect (this , &MainWindow::currentPipelineFinished, this , &MainWindow::_nextPipeline);
3178
+
3179
+ auto data = pipeline.getAllPipelineOutputData ([&, this ](float progress) {
3180
+ // this never runs? Why?
3181
+ std::cout << " Progress: " << 100 * progress << " %" << std::endl;
3182
+ if (int (progress) == 1 ) { // run until finished
3183
+ std::cout << " PIPELINE IS DONE --- STOP SIGNAL WAS EMITTED!" << std::endl;
3184
+ emit currentPipelineFinished ();
3185
+ }
3186
+ });
3187
+ std::cout << " Done" << std::endl;
3177
3188
3178
- // parse fpl-file, and run pipeline with corresponding input arguments
3179
- auto pipeline = Pipeline (path, arguments);
3180
- if (m_runForProject) {
3181
- pipeline.parse ({}, false );
3182
- }
3183
- else {
3184
- pipeline.parse ();
3185
- }
3189
+ // test if signal/slot stuff works -> WORKS!
3190
+ /*
3191
+ std::cout << "Current stop flag value: " << m_pipelineStopped << std::endl;
3192
+ emit currentPipelineFinished();
3193
+ std::cout << "After emit: " << m_pipelineStopped << std::endl;
3194
+ */
3186
3195
3187
- if (m_runForProject) {
3188
- auto data = pipeline.getAllPipelineOutputData ([](float progress) {
3189
- std::cout << " Progress: " << 100 * progress << " %" << std::endl;
3190
- });
3191
- std::cout << " Done" << std::endl;
3192
- }
3196
+ // while (!m_pipelineStopped) { QCoreApplication::processEvents(QEventLoop::AllEvents, 0); }; // perhaps need to force update if I do this? Why doesn't it update with this? Does it interact with the mainthread somehow?
3193
3197
3194
- // get and start running POs
3195
- for (auto && po : pipeline.getProcessObjects ()) {
3196
- if (po.second ->getNrOfOutputPorts () == 0 && std::dynamic_pointer_cast<Renderer>(po.second ) == nullptr ) {
3197
- // Process object has no output ports, must add to window to make sure it is updated.
3198
- reportInfo () << " Process object " << po.first << " had no output ports defined in pipeline, therefore adding to window so it is updated." << reportEnd ();
3199
- addProcessObject (po.second );
3200
- }
3201
- }
3198
+ m_pipelineStopped = false ; // reset when done
3199
+ }
3202
3200
3203
- if (!m_runForProject) {
3204
- // load renderers, if any
3205
- for (const auto & renderer : pipeline.getRenderers ()) {
3206
- auto currId = createRandomNumbers_ (8 );
3207
- insertRenderer (" result_" + currId, renderer);
3208
- createDynamicViewWidget (" result_" + currId, " result_" + currId);
3209
- }
3210
- }
3201
+ // update progress bar
3202
+ // progDialog.setValue(counter); // cannot update this in another thread -> should add some signal/slot stuff for this
3203
+ counter++;
3211
3204
3212
- // update progress bar
3213
- progDialog. setValue (counter );
3214
- counter++;
3205
+ // to render straight away (avoid waiting on all WSIs to be handled before rendering)
3206
+ QCoreApplication::processEvents (QEventLoop::AllEvents, 0 );
3207
+ }
3215
3208
3216
- // to render straight away (avoid waiting on all WSIs to be handled before rendering)
3217
- QCoreApplication::processEvents (QEventLoop::AllEvents, 0 ) ;
3218
- }
3209
+ void MainWindow::_nextPipeline () {
3210
+ std::cout << " ---FINALLY Done " << std::endl ;
3211
+ m_pipelineStopped = true ;
3219
3212
}
3220
3213
3214
+
3221
3215
// Setting parameters for different methods
3222
3216
std::map<std::string, std::string> MainWindow::setParameterDialog (std::map<std::string, std::string> modelMetadata, int *successFlag) {
3223
3217
QDialog paramDialog;
0 commit comments