60 #include <QApplication>
61 #include <QProgressBar>
62 #include <QDesktopWidget>
63 #include <QMouseEvent>
64 #include <QWheelEvent>
68 #include <QStringList>
69 #include <QMessageBox>
70 #include <QCommandLineParser>
72 #include <Inventor/C/errors/debugerror.h>
73 #include <Inventor/Qt/SoQt.h>
88 std::vector<std::string>
vec;
90 vec.push_back(
str.toStdString());
124 #endif // BUILDVP1LIGHT
185 if (
event->type()==QEvent::MouseButtonPress
186 ||
event->type()==QEvent::MouseButtonDblClick
187 ||
event->type()==QEvent::Wheel) {
188 QTime
t = QTime::currentTime();
194 QMouseEvent*mouseEvent =
dynamic_cast<QMouseEvent*
>(
event);
196 txt =
event->type()==QEvent::MouseButtonDblClick?
"Dbl-click"
197 :(mouseEvent->button()&Qt::LeftButton?
"Left-click"
198 :(mouseEvent->button()&Qt::RightButton?
"Right-click":
"Middle-click"));
200 QWheelEvent * wheelEvent =
dynamic_cast<QWheelEvent*
>(
event);
204 txt =
"Unknown event";
210 QLabel *
label =
new QLabel(txt,0,
Qt::Tool|Qt::FramelessWindowHint
211 |Qt::X11BypassWindowManagerHint|Qt::WindowStaysOnTopHint);
212 label->setStyleSheet(
"background-color: yellow;color: black;"
213 "font: bold 140%;border: 2px solid black");
215 label->setFrameStyle(QFrame::StyledPanel);
216 label->setAttribute(Qt::WA_ShowWithoutActivating);
217 label->setFocusPolicy(Qt::NoFocus);
220 QTimer::singleShot(0,
label,SLOT(show()));
221 QTimer::singleShot(500,
label, SLOT(deleteLater()));
236 ISvcLocator* svcLocator,
269 connect(
m_d->
mainwindow->
tabManager(),SIGNAL(visibleChannelsChanged(
const QSet<IVP1ChannelWidget*>&,
const QSet<IVP1ChannelWidget*>&,
const double&)),
270 m_d->
prioritiser,SLOT(visibleChannelsChanged(
const QSet<IVP1ChannelWidget*>&,
const QSet<IVP1ChannelWidget*>&,
const double&)));
279 qDebug() <<
"VP1ExecutionScheduler:: Do we run in 'batch' mode?" << batchMode;
307 #if defined BUILDVP1LIGHT
313 if (checkDisplayMouseClicks) {
325 connect(
auth,SIGNAL(authenticationSuccessful(QNetworkAccessManager*)),
326 availEvtsHttps,SLOT(
start(QNetworkAccessManager*)));
327 connect(availEvtsHttps,SIGNAL(freshEventsChanged()),
352 ISvcLocator* svcLocator,
354 QStringList joboptions,
355 QString initialCruiseMode,
356 unsigned initialCruiseSeconds,
357 QString singleEventSource,
358 QString singleEventLocalTmpDir,
359 unsigned localFileCacheLimit,
360 QStringList availableLocalInputDirectories )
369 if (alternative.isEmpty()) {
370 VP1Msg::message(
"ERROR: The DISPLAY environment variable is "+QString(unset?
"not set":
"empty")+
".");
371 VP1Msg::message(
"This might be because something else in Athena has disabled it.");
373 "the DISPLAY_ORIG environment variable to the contents of DISPLAY before launching your job.");
377 VP1Msg::message(
"For the current job, I will try with DISPLAY=\":0.0\", which is the correct value when running locally.");
380 VP1Msg::message(
"WARNING: The DISPLAY environment variable is "+QString(unset?
"not set":
"empty")+
". Setting to value found in DISPLAY_ORIG");
382 VP1Msg::message(
"WARNING: Setting DISPLAY variable to '"+alternative+
"'");
388 QCoreApplication::setOrganizationName(
"ATLAS");
389 #if defined BUILDVP1LIGHT
390 QCoreApplication::setApplicationName(
"VP1Light");
392 QCoreApplication::setApplicationName(
"VP1");
394 QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
400 VP1Msg::message(
"VP1ExecutionScheduler::init ERROR: QApplication already initialized. Expect problems!!!");
404 static char execpath[] =
"/some/fake/executable/vp1";
405 static char *
argv[2];
419 if (!singleEventSource.isEmpty()&&!singleEventLocalTmpDir.isEmpty()) {
420 const bool httpmode = singleEventSource.startsWith(
"http://");
421 const bool httpsmode = singleEventSource.startsWith(
"https://");
424 availEvents =
new VP1AvailEvtsHttp(singleEventSource, 60, 30*60, singleEventLocalTmpDir,localFileCacheLimit);
425 }
else if(httpsmode) {
426 availEvents =
new VP1AvailEvtsHttps(singleEventSource, 1000, 30*60, singleEventLocalTmpDir,localFileCacheLimit);
429 singleEventLocalTmpDir,localFileCacheLimit);
430 static_cast<VP1AvailEvtsLocalDir*
>(availEvents)->setAvailableSourceDirectories(availableLocalInputDirectories);
439 if (joboptions.empty()) {
442 qDebug() <<
"config files: " << joboptions;
443 for (QString
opt : joboptions)
448 if (joboptions.size() != 0 ) {
453 if (batchNevents > 0 ) {
460 if (scheduler->
m_d->
mainwindow->tabWidget_central->count()<=1) {
461 if (initialCruiseMode==
"TAB") {
462 VP1Msg::message(
"ERROR: Can not start in cruisemode TAB unless there are at least 2 tabs loaded from initial .vp1 files. Reverting to cruise mode NONE.");
463 initialCruiseMode=
"NONE";
464 }
else if (initialCruiseMode==
"BOTH") {
465 VP1Msg::message(
"ERROR: Can not start in cruisemode BOTH unless there are at least 2 tabs loaded from initial .vp1 files. Reverting to cruise mode EVENT.");
466 initialCruiseMode=
"EVENT";
471 if (initialCruiseMode==
"EVENT") {
473 scheduler->
m_d->
mainwindow->radioButton_cruise_event->setChecked(
true);
474 scheduler->
m_d->
mainwindow->pushButton_cruise->setChecked(
true);
476 }
else if (initialCruiseMode==
"TAB") {
478 scheduler->
m_d->
mainwindow->radioButton_cruise_tab->setChecked(
true);
479 scheduler->
m_d->
mainwindow->pushButton_cruise->setChecked(
true);
480 }
else if (initialCruiseMode==
"BOTH") {
482 scheduler->
m_d->
mainwindow->radioButton_cruise_both->setChecked(
true);
483 scheduler->
m_d->
mainwindow->pushButton_cruise->setChecked(
true);
485 if (initialCruiseMode!=
"NONE")
486 VP1Msg::message(
"ERROR: unknown initial cruise mode "+initialCruiseMode+
" (valid are NONE/EVENT/TAB/BOTH). Assuming NONE.");
488 scheduler->
m_d->
mainwindow->radioButton_cruise_event->setChecked(
true);
489 scheduler->
m_d->
mainwindow->pushButton_cruise->setChecked(
false);
494 int cruisesecs = ( initialCruiseSeconds == 0 ? 0 :
497 static_cast<int>(initialCruiseSeconds))));
499 scheduler->
m_d->
mainwindow->spinBox_cruise->setValue(cruisesecs);
508 #if defined BUILDVP1LIGHT
515 QMessageBox::information(0,
"End of job reached",Qt::convertFromPlainText(
"Job about to end.\n\nThis is most"
516 " likely since there are no more available events to process."),QMessageBox::Ok,QMessageBox::Ok);
521 qApp->processEvents();
533 const QString quickExitEnv(
"VP1_HARD_EXIT_AT_END");
535 #if defined BUILDVP1LIGHT
541 if (checkHardExitAtEnd) {
542 VP1Msg::message(
"Hard job exit (unset "+quickExitEnv+
" to disable this behaviour).");
596 #if defined BUILDVP1LIGHT
598 if ( !firstlaunch ) {
599 if ( (getEvtNr() >= 0) && (getEvtNr() < m_totEvtNr) ) {
604 if((*itsys)->name()==
"Analysis"){
609 else if ( (getEvtNr() < 0) && (getEvtNr() >= m_totEvtNr) ) {
611 msgBox.setWindowTitle(
"No more events");
612 msgBox.setText(
"There are no more events in this file. Returning to previous event.");
613 msgBox.setIcon(QMessageBox::Icon::Information);
640 qApp->processEvents();
652 VP1Msg::messageDebug(
"User chose 'batch' and 'batch-random-config'. So we now replace the configuration with a random one from the input set...");
674 m_d->
mainwindow->groupBox_channelcontrols->setEnabled(
false);
693 qApp->processEvents(QEventLoop::ExcludeUserInputEvents|QEventLoop::ExcludeSocketNotifiers);
702 cw->goingToNextEvent();
705 qApp->processEvents(QEventLoop::ExcludeUserInputEvents|QEventLoop::ExcludeSocketNotifiers);
719 assert(!
s->isRefreshing());
721 QString
base = QString(
s->name())+
" from channel "+
s->channel()->unique_name();
725 s->disallowUpdateGUI();
728 m_d->
mainwindow->statusBar()->showMessage(
"Post-erase update to channel ["+
base+
"]" );
729 s->channel()->systemErased(
s);
741 assert(
s->isRefreshing());
769 std::set<IVP1System*>::const_iterator
it,
itE = cw->
systems().end();
771 qInfo() <<
"System name:" << (*it)->name();
776 #endif // BUILDVP1LIGHT
785 std::set<IVP1System*>::const_iterator
it,
itE = cw->
systems().end();
806 QString sysname =
s->name();
818 QString
base = QString(
s->name())+
" from channel "+
s->channel()->unique_name();
822 s->setRefreshing(
true);
824 s->channel()->emitRefreshInfoChanged();
827 s->setRefreshing(
false);
828 s->disallowUpdateGUI();
830 m_d->
mainwindow->statusBar()->showMessage(
"Post-refresh update to channel ["+
base+
"]" );
831 s->channel()->systemRefreshed(
s);
840 s->channel()->emitRefreshInfoChanged();
846 s->channel()->lastOfActiveSystemsRefreshed();
915 QApplication::quit();
926 QApplication::quit();
946 QString chnlname =
s->name().toLower();
947 VP1Msg::messageDebug(
"VP1ExecutionScheduler::saveSnaphsotToFile() - taking the snapshot of the channel " + chnlname );
962 if ( ! (batchOutFolder ==
"") ) {
991 struct tm human_evtimestamp;
992 localtime_r(&t_evttimestamp, &human_evtimestamp);
994 std::ostringstream h_evtimestamp_ostri;
995 h_evtimestamp_ostri << 1900 + human_evtimestamp.tm_year
996 <<
"-" << 1 + human_evtimestamp.tm_mon
997 <<
"-" << human_evtimestamp.tm_mday
998 <<
"T" << human_evtimestamp.tm_hour <<
"-" << human_evtimestamp.tm_min <<
"-" << human_evtimestamp.tm_sec <<
"CEST";
1000 std::string h_evtimestamp_str = h_evtimestamp_ostri.str();
1001 QString h_evtimestamp = QString::fromStdString(h_evtimestamp_str);
1005 time_t t_timestamp =
time(0);
1007 localtime_r(&t_timestamp, <m);
1015 std::ostringstream ostri_unix;
1016 ostri_unix << t_timestamp;
1018 std::ostringstream ostri;
1019 ostri << 1900 + ltm.tm_year
1020 <<
"-" << 1 + ltm.tm_mon
1021 <<
"-" << ltm.tm_mday
1022 <<
"T" << ltm.tm_hour <<
"-" << ltm.tm_min <<
"-" << ltm.tm_sec <<
"CEST";
1024 std::string unixTimestamp = ostri_unix.str();
1025 std::string humanTimestamp = ostri.str();
1026 QString q_unixTimestamp = QString::fromStdString(unixTimestamp);
1027 QString q_humanTimestamp = QString::fromStdString(humanTimestamp);
1037 QString
filename =
folder +
"vp1_batch_snapshot_r" + runnumb +
"_ev" + evnumb +
"_evtime_H" + h_evtimestamp +
"_U" + evtimestamp +
"___imgtime_H" + q_humanTimestamp +
"_U" + q_unixTimestamp +
".png";
1040 QPixmap pm =
s->channel()->getSnapshot();
1050 QString latestImageFileName = currentsaveimagepath + QString(
"latest_vp1image");
1051 QFile latestImage(latestImageFileName);
1052 if(latestImage.exists() && !latestImage.remove())
1053 throw std::runtime_error(
"Unable to overwrite the existing latest image file");
1054 if(!latestImage.open(QIODevice::WriteOnly | QIODevice::Text))
1055 throw std::runtime_error(
"Unable to create new latest image file");
1056 latestImage.write(
filename.toStdString().c_str());
1057 latestImage.close();
1078 for (itsys = cw->
systems().begin();itsys!=itsysE;++itsys) {
1080 connect((*itsys),SIGNAL(sysmessage(
const QString&)),
m_d->
mainwindow,SLOT(systemAddToMessageBox(
const QString&)));
1083 for (itsys = cw->
systems().begin();itsys!=itsysE;++itsys) {
1084 (*itsys)->setCanRegisterController(
true);
1086 (*itsys)->setCanRegisterController(
false);
1115 cw->setUpdatesEnabled(
false);
1119 for (itsys = cw->
systems().begin();itsys!=itsysE;++itsys) {
1120 (*itsys)->blockSignals(
true);
1121 disconnect(*itsys,0,0,0);
1123 cw->blockSignals(
true);
1124 disconnect(cw,0,0,0);
1127 for (itsys = cw->
systems().begin();itsys!=itsysE;++itsys) {
1134 for (itsys = cw->
systems().begin();itsys!=itsysE;++itsys) {
1136 (*itsys)->uncreate();
1157 QSet<QWidget*> w_ignore;
1158 #if QTCORE_VERSION >= 0x050E00
1159 QList<QWidget*> widgets = QApplication::allWidgets();
1160 QSet<QWidget*> wl (widgets.begin(), widgets.end());
1162 QSet<QWidget*> wl = QApplication::allWidgets().toSet();
1164 w_ignore<<qApp->desktop();
1165 for (QObject*o : qApp->children()) {
1166 if (o->isWidgetType())
1167 w_ignore << static_cast<QWidget*>(o);
1169 for (QWidget *
w : wl) {
1170 if (
w->objectName().startsWith(
"internal clipboard"))
1172 if (
w->objectName()==
"empty_widget")
1175 wl.subtract(w_ignore);
1177 std::cout<<std::endl;
1178 std::cout<<
"VP1 WARNING: "<<wl.count()<<
" widget"<<(wl.count()>1?
"s":
"")<<
" left at end of job:"<<std::endl;
1180 for (QWidget*
w : wl) {
1181 std::cout<<++
i<<
") Address="<<
w<<
", ObjectName="<<
w->objectName().toStdString()<<
", ClassName="<<
w->metaObject()->className()<<std::endl;
1183 std::cout<<std::endl;
1192 std::set<IVP1System*>::const_iterator
it,
itE = cw->
systems().end();
1201 QString
name = QString((*it)->name());
1204 std::cout <<
i <<
" - name: " <<
name.toStdString() <<
" - active: " <<
active.toStdString() <<
" - refreshed: " << state.toStdString() << std::endl;
1219 if (!scheduler->hasAllActiveSystemsRefreshed(cw))
1228 if (!scheduler->hasAllActiveSystemsRefreshed(cw))
1238 if (cruisemode==
NONE||!scheduler->hasAllActiveSystemsRefreshed(cw))
1241 if (cruisemode==
EVENT) {
1243 if (!mainwindow->tabManager()->isVisible(cw)||!allVisibleRefreshed())
1246 assert(!cruisetimer->isActive());
1247 cruisetimer->start(mainwindow->spinBox_cruise->value()*1000);
1249 }
else if (cruisemode==
TAB) {
1250 if (cruisetab_waitingtoproceed) {
1254 if (allSoonVisibleRefreshed()) {
1255 mainwindow->tabManager()->showNextTab();
1256 cruisetab_waitingtoproceed=
false;
1258 if (allVisibleRefreshed())
1259 cruisetimer->start(mainwindow->spinBox_cruise->value()*1000);
1264 if (!mainwindow->tabManager()->isVisible(cw)||!allVisibleRefreshed())
1267 assert(!cruisetimer->isActive());
1268 cruisetimer->start(mainwindow->spinBox_cruise->value()*1000);
1274 assert(cruisemode==
BOTH);
1275 assert(0&&
"not implemented");
1283 if (cruisetimer->isActive())
1284 cruisetimer->stop();
1285 cruisetab_waitingtoproceed=
false;
1289 switch (cruisemode) {
1294 if (allVisibleRefreshed())
1295 cruisetimer->start(mainwindow->spinBox_cruise->value()*1000);
1300 if (allVisibleRefreshed())
1301 cruisetimer->start(mainwindow->spinBox_cruise->value()*1000);
1308 assert(0&&
"UNKNOWN CRUISE MODE");
1344 assert(0&&
"should never happen");
1362 assert(0&&
"Not implemented");
1366 assert(0&&
"UNKNOWN CRUISE MODE");
1389 #ifdef BUILDVP1LIGHT
1390 void VP1ExecutionScheduler::loadEvent(){
1392 const char* appName =
"VP1Light";
1403 QSettings settings(
"ATLAS",
"VP1Light");
1404 std::string
path = settings.value(
"aod/path").toString().toStdString();
1407 m_ifile = ::TFile::Open(
path.c_str(),
"READ" );
1413 if( !m_event->readFrom( m_ifile ).isSuccess() ) {
1420 if( m_event->getEntry( 0 ) < 0 ) {
1427 m_event->getEntry( m_evtNr );
1430 QStringList jetList;
1431 QStringList vertexList;
1432 QStringList otherList;
1433 QStringList caloClusterList;
1434 QStringList trackParticleList;
1435 QStringList muonList;
1436 QStringList electronList;
1440 TTree*
ct = (TTree*)m_ifile->Get(
"CollectionTree");
1441 m_totEvtNr =
ct->GetEntriesFast();
1442 for (
int i = 0;
i<
ct->GetListOfBranches()->GetEntries();
i++){
1443 std::string
className =
ct->GetBranch(
ct->GetListOfBranches()->At(
i)->GetName())->GetClassName();
1447 vertexList <<
ct->GetListOfBranches()->At(
i)->GetName();
1450 otherList <<
ct->GetListOfBranches()->At(
i)->GetName();
1453 jetList <<
ct->GetListOfBranches()->At(
i)->GetName();
1456 caloClusterList <<
ct->GetListOfBranches()->At(
i)->GetName();
1458 if(
split(
className,
"_v[1-9]")==
"DataVector<xAOD::TrackParticle>"){
1459 trackParticleList <<
ct->GetListOfBranches()->At(
i)->GetName();
1462 muonList <<
ct->GetListOfBranches()->At(
i)->GetName();
1465 electronList <<
ct->GetListOfBranches()->At(
i)->GetName();
1470 m_list.append(vertexList);
1471 m_list.append(otherList);
1472 m_list.append(jetList);
1473 m_list.append(caloClusterList);
1474 m_list.append(trackParticleList);
1475 m_list.append(muonList);
1476 m_list.append(electronList);
1480 if( !m_event->retrieve (eventInfo,
"EventInfo").isSuccess() ) {
1489 m_d->
mainwindow->pushButton_eventselect->setText(currentEvt);
1494 sys->setEvent(m_event);
1495 sys->setObjectList(m_list);
1502 std::vector<std::string>
vec = {
first, last};
1504 for (
unsigned int i=0;
i<
vec.size();
i++){
1505 list << QString::fromStdString(
vec[
i]);
1507 return list.join(
"");
1509 #endif // BUILDVP1LIGHT