Changeset View
Changeset View
Standalone View
Standalone View
src/LauSimFitCoordinator.cc
- This file was moved from src/LauSimFitMaster.cc.
Show All 16 Lines | |||||
/* | /* | ||||
Laura++ package authors: | Laura++ package authors: | ||||
John Back | John Back | ||||
Paul Harrison | Paul Harrison | ||||
Thomas Latham | Thomas Latham | ||||
*/ | */ | ||||
/*! \file LauSimFitMaster.cc | /*! \file LauSimFitCoordinator.cc | ||||
\brief File containing implementation of LauSimFitMaster class. | \brief File containing implementation of LauSimFitCoordinator class. | ||||
*/ | */ | ||||
#include <cstdlib> | #include <cstdlib> | ||||
#include <iostream> | #include <iostream> | ||||
#include <limits> | #include <limits> | ||||
#include "TMath.h" | #include "TMath.h" | ||||
#include "TMatrixD.h" | #include "TMatrixD.h" | ||||
#include "TMessage.h" | #include "TMessage.h" | ||||
#include "TMonitor.h" | #include "TMonitor.h" | ||||
#include "TObjArray.h" | #include "TObjArray.h" | ||||
#include "TObjString.h" | #include "TObjString.h" | ||||
#include "TServerSocket.h" | #include "TServerSocket.h" | ||||
#include "TSocket.h" | #include "TSocket.h" | ||||
#include "TSystem.h" | #include "TSystem.h" | ||||
#include "LauAbsFitter.hh" | #include "LauAbsFitter.hh" | ||||
#include "LauFitNtuple.hh" | #include "LauFitNtuple.hh" | ||||
#include "LauFitter.hh" | #include "LauFitter.hh" | ||||
#include "LauFormulaPar.hh" | #include "LauFormulaPar.hh" | ||||
#include "LauParameter.hh" | #include "LauParameter.hh" | ||||
#include "LauParamFixed.hh" | #include "LauParamFixed.hh" | ||||
#include "LauSimFitMaster.hh" | #include "LauSimFitCoordinator.hh" | ||||
ClassImp(LauSimFitMaster) | ClassImp(LauSimFitCoordinator) | ||||
LauSimFitMaster::LauSimFitMaster( UInt_t numSlaves, UInt_t port ) : | LauSimFitCoordinator::LauSimFitCoordinator( UInt_t numTasks, UInt_t port ) : | ||||
nSlaves_(numSlaves), | nTasks_(numTasks), | ||||
reqPort_(port), | reqPort_(port), | ||||
socketMonitor_(0), | socketMonitor_(0), | ||||
messageFromSlave_(0), | messageFromTask_(0), | ||||
fitNtuple_(0) | fitNtuple_(0) | ||||
{ | { | ||||
messagesToSlaves_.resize( nSlaves_ ); | messagesToTasks_.resize( nTasks_ ); | ||||
for ( UInt_t iSlave(0); iSlave < nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask < nTasks_; ++iTask ) { | ||||
messagesToSlaves_[iSlave] = new TMessage(); | messagesToTasks_[iTask] = new TMessage(); | ||||
} | } | ||||
} | } | ||||
LauSimFitMaster::~LauSimFitMaster() | LauSimFitCoordinator::~LauSimFitCoordinator() | ||||
{ | { | ||||
delete socketMonitor_; socketMonitor_ = 0; | delete socketMonitor_; socketMonitor_ = 0; | ||||
// Tell all slaves that they are finished and delete corresponding socket | // Tell all tasks that they are finished and delete corresponding socket | ||||
TString msgStr("Finish"); | TString msgStr("Finish"); | ||||
TMessage message( kMESS_STRING ); | TMessage message( kMESS_STRING ); | ||||
message.WriteTString(msgStr); | message.WriteTString(msgStr); | ||||
for ( std::vector<TSocket*>::iterator iter = sSlaves_.begin(); iter != sSlaves_.end(); ++iter ) { | for ( std::vector<TSocket*>::iterator iter = socketTasks_.begin(); iter != socketTasks_.end(); ++iter ) { | ||||
(*iter)->Send(message); | (*iter)->Send(message); | ||||
(*iter)->Close(); | (*iter)->Close(); | ||||
delete (*iter); | delete (*iter); | ||||
} | } | ||||
sSlaves_.clear(); | socketTasks_.clear(); | ||||
// Remove the components created to apply constraints to fit parameters | // Remove the components created to apply constraints to fit parameters | ||||
for (std::vector<LauAbsRValue*>::iterator iter = conVars_.begin(); iter != conVars_.end(); ++iter){ | for (std::vector<LauAbsRValue*>::iterator iter = conVars_.begin(); iter != conVars_.end(); ++iter){ | ||||
if ( !(*iter)->isLValue() ){ | if ( !(*iter)->isLValue() ){ | ||||
delete (*iter); | delete (*iter); | ||||
(*iter) = 0; | (*iter) = 0; | ||||
} | } | ||||
} | } | ||||
conVars_.clear(); | conVars_.clear(); | ||||
// Remove all fit parameters | // Remove all fit parameters | ||||
for ( std::vector<LauParameter*>::iterator iter = params_.begin(); iter != params_.end(); ++iter ) { | for ( std::vector<LauParameter*>::iterator iter = params_.begin(); iter != params_.end(); ++iter ) { | ||||
delete *iter; | delete *iter; | ||||
} | } | ||||
params_.clear(); | params_.clear(); | ||||
for ( std::vector<Double_t*>::iterator iter = vectorPar_.begin(); iter != vectorPar_.end(); ++iter ) { | for ( std::vector<Double_t*>::iterator iter = vectorPar_.begin(); iter != vectorPar_.end(); ++iter ) { | ||||
delete[] (*iter); | delete[] (*iter); | ||||
} | } | ||||
vectorPar_.clear(); | vectorPar_.clear(); | ||||
delete messageFromSlave_; messageFromSlave_ = 0; | delete messageFromTask_; messageFromTask_ = 0; | ||||
for ( std::vector<TMessage*>::iterator iter = messagesToSlaves_.begin(); iter != messagesToSlaves_.end(); ++iter ) { | for ( std::vector<TMessage*>::iterator iter = messagesToTasks_.begin(); iter != messagesToTasks_.end(); ++iter ) { | ||||
delete (*iter); | delete (*iter); | ||||
} | } | ||||
messagesToSlaves_.clear(); | messagesToTasks_.clear(); | ||||
delete fitNtuple_; | delete fitNtuple_; | ||||
} | } | ||||
void LauSimFitMaster::initSockets() | void LauSimFitCoordinator::initSockets() | ||||
{ | { | ||||
if ( socketMonitor_ != 0 ) { | if ( socketMonitor_ != 0 ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::initSockets : Sockets already initialised." << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::initSockets : Sockets already initialised." << std::endl; | ||||
return; | return; | ||||
} | } | ||||
//initialise socket connection, then accept a connection and return a full-duplex communication socket. | //initialise socket connection, then accept a connection and return a full-duplex communication socket. | ||||
socketMonitor_ = new TMonitor(); | socketMonitor_ = new TMonitor(); | ||||
TServerSocket *ss = new TServerSocket( reqPort_, kFALSE ); | TServerSocket *ss = new TServerSocket( reqPort_, kFALSE ); | ||||
UInt_t actual_port = ss->GetLocalPort(); | UInt_t actual_port = ss->GetLocalPort(); | ||||
std::cout << "INFO in LauSimFitMaster::initSockets : Waiting for connection with " << nSlaves_ << " workers on port " << actual_port << std::endl; | std::cout << "INFO in LauSimFitCoordinator::initSockets : Waiting for connection with " << nTasks_ << " workers on port " << actual_port << std::endl; | ||||
sSlaves_.resize(nSlaves_); | socketTasks_.resize(nTasks_); | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
sSlaves_[iSlave] = ss->Accept(); | socketTasks_[iTask] = ss->Accept(); | ||||
std::cout << " : Added slave " << iSlave << std::endl; | std::cout << " : Added task " << iTask << std::endl; | ||||
} | } | ||||
// tell the clients to start | // tell the clients to start | ||||
std::cout << "INFO in LauSimFitMaster::initSockets : Initialising slaves" << std::endl; | std::cout << "INFO in LauSimFitCoordinator::initSockets : Initialising tasks" << std::endl; | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
TMessage message( kMESS_ANY ); | TMessage message( kMESS_ANY ); | ||||
message.WriteUInt(iSlave); | message.WriteUInt(iTask); | ||||
message.WriteUInt(nSlaves_); | message.WriteUInt(nTasks_); | ||||
message.WriteBool(this->useAsymmFitErrors()); | message.WriteBool(this->useAsymmFitErrors()); | ||||
sSlaves_[iSlave]->Send(message); | socketTasks_[iTask]->Send(message); | ||||
socketMonitor_->Add(sSlaves_[iSlave]); | socketMonitor_->Add(socketTasks_[iTask]); | ||||
} | } | ||||
std::cout << " : Now start fit\n" << std::endl; | std::cout << " : Now start fit\n" << std::endl; | ||||
ss->Close(); | ss->Close(); | ||||
delete ss; | delete ss; | ||||
} | } | ||||
/* | /* | ||||
* OLD VERSION THAT JUST GETS THE NAMES - COULD HAVE A SERIES OF EXCHANGES TO GET THE NAMES, INIT VALUES, RANGES, ETC. INSTEAD OF PASSING PARAMETERS | * OLD VERSION THAT JUST GETS THE NAMES - COULD HAVE A SERIES OF EXCHANGES TO GET THE NAMES, INIT VALUES, RANGES, ETC. INSTEAD OF PASSING PARAMETERS | ||||
* THIS INCREASES THE GENERALITY OF THE CODE, I.E. THERE IS NO NEED FOR THE SLAVES TO KNOW ANY LAURA++ CLASS BUT THIS ONE, BUT MAKES IT RATHER MORE DENSE | * THIS INCREASES THE GENERALITY OF THE CODE, I.E. THERE IS NO NEED FOR THE TASKS TO KNOW ANY LAURA++ CLASS BUT THIS ONE, BUT MAKES IT RATHER MORE DENSE | ||||
* FOR THE MOMENT I WILL STICK WITH THE METHOD OF PASSING LAUPARAMETER OBJECTS AROUND AND CONSIDER GOING BACK TO THIS GENERAL METHOD ONCE EVERYTHING IS WORKING | * FOR THE MOMENT I WILL STICK WITH THE METHOD OF PASSING LAUPARAMETER OBJECTS AROUND AND CONSIDER GOING BACK TO THIS GENERAL METHOD ONCE EVERYTHING IS WORKING | ||||
* | * | ||||
void LauSimFitMaster::getParametersFromSlavesFirstTime() | void LauSimFitCoordinator::getParametersFromTasksFirstTime() | ||||
{ | { | ||||
slaveIndices_.resize( nSlaves_ ); | taskIndices_.resize( nTasks_ ); | ||||
TSocket* sActive(0); | TSocket* sActive(0); | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
// Send a message to the slave, requesting the list of parameter names | // Send a message to the task, requesting the list of parameter names | ||||
TString msgStr = "Parameter Names"; | TString msgStr = "Parameter Names"; | ||||
TMessage message( kMESS_STRING ); | TMessage message( kMESS_STRING ); | ||||
message.WriteTString( msgStr ); | message.WriteTString( msgStr ); | ||||
sSlaves_[iSlave]->Send(message); | socketTasks_[iTask]->Send(message); | ||||
// Wait to receive the response and check that it has come from the slave we just requested from | // Wait to receive the response and check that it has come from the task we just requested from | ||||
sActive = socketMonitor_->Select(); | sActive = socketMonitor_->Select(); | ||||
if ( sActive != sSlaves_[iSlave] ) { | if ( sActive != socketTasks_[iTask] ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlavesFirstTime : Received message from a different slave than expected!" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Received message from a different task than expected!" << std::endl; | ||||
gSystem->Exit(1); | gSystem->Exit(1); | ||||
} | } | ||||
// Read the object and extract the parameter names | // Read the object and extract the parameter names | ||||
sSlaves_[iSlave]->Recv( messageFromSlave_ ); | socketTasks_[iTask]->Recv( messageFromTask_ ); | ||||
TObjArray * objarray = dynamic_cast<TObjArray*>( messageFromSlave_->ReadObject( messageFromSlave_->GetClass() ) ); | TObjArray * objarray = dynamic_cast<TObjArray*>( messageFromTask_->ReadObject( messageFromTask_->GetClass() ) ); | ||||
if ( ! objarray ) { | if ( ! objarray ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlavesFirstTime : Error reading parameter names from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Error reading parameter names from task" << std::endl; | ||||
gSystem->Exit(1); | gSystem->Exit(1); | ||||
} | } | ||||
Int_t nPars = objarray->GetEntries(); | Int_t nPars = objarray->GetEntries(); | ||||
for ( Int_t iPar(0); iPar < nPars; ++iPar ) { | for ( Int_t iPar(0); iPar < nPars; ++iPar ) { | ||||
TObjString* objstring = dynamic_cast<TObjString*>( (*objarray)[iPar] ); | TObjString* objstring = dynamic_cast<TObjString*>( (*objarray)[iPar] ); | ||||
if ( ! objstring ) { | if ( ! objstring ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlavesFirstTime : Error reading parameter names from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Error reading parameter names from task" << std::endl; | ||||
gSystem->Exit(1); | gSystem->Exit(1); | ||||
} | } | ||||
TString parname = objstring->GetString(); | TString parname = objstring->GetString(); | ||||
std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname ); | std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname ); | ||||
if ( iter != parIndices_.end() ) { | if ( iter != parIndices_.end() ) { | ||||
UInt_t index = iter->second; | UInt_t index = iter->second; | ||||
slaveIndices_[iSlave].push_back( index ); | taskIndices_[iTask].push_back( index ); | ||||
} else { | } else { | ||||
UInt_t index = parIndices_.size(); | UInt_t index = parIndices_.size(); | ||||
parIndices_.insert( std::make_pair( parname, index ) ); | parIndices_.insert( std::make_pair( parname, index ) ); | ||||
parNames_.insert( std::make_pair( index, parname ) ); | parNames_.insert( std::make_pair( index, parname ) ); | ||||
slaveIndices_[iSlave].push_back( index ); | taskIndices_[iTask].push_back( index ); | ||||
} | } | ||||
} | } | ||||
delete objarray; objarray = 0; | delete objarray; objarray = 0; | ||||
delete messageFromSlave_; messageFromSlave_ = 0; | delete messageFromTask_; messageFromTask_ = 0; | ||||
} | } | ||||
UInt_t nPars = parNames_.size(); | UInt_t nPars = parNames_.size(); | ||||
parValues_.resize( nPars ); | parValues_.resize( nPars ); | ||||
} | } | ||||
*/ | */ | ||||
void LauSimFitMaster::getParametersFromSlaves() | void LauSimFitCoordinator::getParametersFromTasks() | ||||
{ | { | ||||
if ( socketMonitor_ == 0 ) { | if ( socketMonitor_ == 0 ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlaves : Sockets not initialised." << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasks : Sockets not initialised." << std::endl; | ||||
return; | return; | ||||
} | } | ||||
if ( params_.empty() ) { | if ( params_.empty() ) { | ||||
this->getParametersFromSlavesFirstTime(); | this->getParametersFromTasksFirstTime(); | ||||
// Add variables to Gaussian constrain to a list | // Add variables to Gaussian constrain to a list | ||||
this->addConParameters(); | this->addConParameters(); | ||||
} else { | } else { | ||||
this->updateParametersFromSlaves(); | this->updateParametersFromTasks(); | ||||
} | } | ||||
} | } | ||||
void LauSimFitMaster::updateParametersFromSlaves() | void LauSimFitCoordinator::updateParametersFromTasks() | ||||
{ | { | ||||
TSocket* sActive(0); | TSocket* sActive(0); | ||||
// Construct a message, requesting the list of parameter names | // Construct a message, requesting the list of parameter names | ||||
TString msgStr = "Send Parameters"; | TString msgStr = "Send Parameters"; | ||||
TMessage message( kMESS_STRING ); | TMessage message( kMESS_STRING ); | ||||
message.WriteTString( msgStr ); | message.WriteTString( msgStr ); | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
// Send the message to the slave | // Send the message to the task | ||||
sSlaves_[iSlave]->Send(message); | socketTasks_[iTask]->Send(message); | ||||
// Wait to receive the response and check that it has come from the slave we just requested from | // Wait to receive the response and check that it has come from the task we just requested from | ||||
sActive = socketMonitor_->Select(); | sActive = socketMonitor_->Select(); | ||||
if ( sActive != sSlaves_[iSlave] ) { | if ( sActive != socketTasks_[iTask] ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::updateParametersFromSlaves : Received message from a different slave than expected!" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Received message from a different task than expected!" << std::endl; | ||||
gSystem->Exit(1); | gSystem->Exit(1); | ||||
} | } | ||||
// Read the object and extract the parameter names | // Read the object and extract the parameter names | ||||
sSlaves_[iSlave]->Recv( messageFromSlave_ ); | socketTasks_[iTask]->Recv( messageFromTask_ ); | ||||
TObjArray * objarray = dynamic_cast<TObjArray*>( messageFromSlave_->ReadObject( messageFromSlave_->GetClass() ) ); | TObjArray * objarray = dynamic_cast<TObjArray*>( messageFromTask_->ReadObject( messageFromTask_->GetClass() ) ); | ||||
if ( ! objarray ) { | if ( ! objarray ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::updateParametersFromSlaves : Error reading parameter names from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Error reading parameter names from task" << std::endl; | ||||
gSystem->Exit(1); | gSystem->Exit(1); | ||||
} | } | ||||
// We want to auto-delete the supplied parameters since we only copy their values in this case | // We want to auto-delete the supplied parameters since we only copy their values in this case | ||||
objarray->SetOwner(kTRUE); | objarray->SetOwner(kTRUE); | ||||
const UInt_t nPars = objarray->GetEntries(); | const UInt_t nPars = objarray->GetEntries(); | ||||
if ( nPars != slaveIndices_[iSlave].size() ) { | if ( nPars != taskIndices_[iTask].size() ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::updateParametersFromSlaves : Unexpected number of parameters received from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Unexpected number of parameters received from task" << std::endl; | ||||
gSystem->Exit(1); | gSystem->Exit(1); | ||||
} | } | ||||
for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { | for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { | ||||
LauParameter* parameter = dynamic_cast<LauParameter*>( (*objarray)[iPar] ); | LauParameter* parameter = dynamic_cast<LauParameter*>( (*objarray)[iPar] ); | ||||
if ( ! parameter ) { | if ( ! parameter ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::updateParametersFromSlaves : Error reading parameter from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Error reading parameter from task" << std::endl; | ||||
gSystem->Exit(1); | gSystem->Exit(1); | ||||
} | } | ||||
TString parname = parameter->name(); | TString parname = parameter->name(); | ||||
Double_t parvalue = parameter->initValue(); | Double_t parvalue = parameter->initValue(); | ||||
std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname ); | std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname ); | ||||
if ( iter == parIndices_.end() ) { | if ( iter == parIndices_.end() ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::updateParametersFromSlaves : Unexpected parameter name received from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Unexpected parameter name received from task" << std::endl; | ||||
gSystem->Exit(1); | gSystem->Exit(1); | ||||
} | } | ||||
const UInt_t index = iter->second; | const UInt_t index = iter->second; | ||||
if ( slaveIndices_[iSlave][iPar] != index ) { | if ( taskIndices_[iTask][iPar] != index ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::updateParametersFromSlaves : Unexpected parameter received from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Unexpected parameter received from task" << std::endl; | ||||
gSystem->Exit(1); | gSystem->Exit(1); | ||||
} | } | ||||
params_[index]->initValue( parvalue ); | params_[index]->initValue( parvalue ); | ||||
parValues_[index] = parvalue; | parValues_[index] = parvalue; | ||||
vectorPar_[iSlave][iPar] = parvalue; | vectorPar_[iTask][iPar] = parvalue; | ||||
this->checkParameter( parameter, index ); | this->checkParameter( parameter, index ); | ||||
} | } | ||||
delete objarray; objarray = 0; | delete objarray; objarray = 0; | ||||
delete messageFromSlave_; messageFromSlave_ = 0; | delete messageFromTask_; messageFromTask_ = 0; | ||||
} | } | ||||
} | } | ||||
void LauSimFitMaster::getParametersFromSlavesFirstTime() | void LauSimFitCoordinator::getParametersFromTasksFirstTime() | ||||
{ | { | ||||
slaveIndices_.resize( nSlaves_ ); | taskIndices_.resize( nTasks_ ); | ||||
slaveFreeIndices_.resize( nSlaves_ ); | taskFreeIndices_.resize( nTasks_ ); | ||||
vectorPar_.resize( nSlaves_ ); | vectorPar_.resize( nTasks_ ); | ||||
vectorRes_.resize( nSlaves_ ); | vectorRes_.resize( nTasks_ ); | ||||
TSocket* sActive(0); | TSocket* sActive(0); | ||||
// Construct a message, requesting the list of parameter names | // Construct a message, requesting the list of parameter names | ||||
TString msgStr = "Send Parameters"; | TString msgStr = "Send Parameters"; | ||||
TMessage message( kMESS_STRING ); | TMessage message( kMESS_STRING ); | ||||
message.WriteTString( msgStr ); | message.WriteTString( msgStr ); | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
// Send the message to the slave | // Send the message to the task | ||||
sSlaves_[iSlave]->Send(message); | socketTasks_[iTask]->Send(message); | ||||
// Wait to receive the response and check that it has come from the slave we just requested from | // Wait to receive the response and check that it has come from the task we just requested from | ||||
sActive = socketMonitor_->Select(); | sActive = socketMonitor_->Select(); | ||||
if ( sActive != sSlaves_[iSlave] ) { | if ( sActive != socketTasks_[iTask] ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlavesFirstTime : Received message from a different slave than expected!" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Received message from a different task than expected!" << std::endl; | ||||
gSystem->Exit(1); | gSystem->Exit(1); | ||||
} | } | ||||
// Read the object and extract the parameter names | // Read the object and extract the parameter names | ||||
sSlaves_[iSlave]->Recv( messageFromSlave_ ); | socketTasks_[iTask]->Recv( messageFromTask_ ); | ||||
TObjArray * objarray = dynamic_cast<TObjArray*>( messageFromSlave_->ReadObject( messageFromSlave_->GetClass() ) ); | TObjArray * objarray = dynamic_cast<TObjArray*>( messageFromTask_->ReadObject( messageFromTask_->GetClass() ) ); | ||||
if ( ! objarray ) { | if ( ! objarray ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlavesFirstTime : Error reading parameters from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Error reading parameters from task" << std::endl; | ||||
gSystem->Exit(1); | gSystem->Exit(1); | ||||
} | } | ||||
const UInt_t nPars = objarray->GetEntries(); | const UInt_t nPars = objarray->GetEntries(); | ||||
vectorPar_[iSlave] = new Double_t[nPars]; | vectorPar_[iTask] = new Double_t[nPars]; | ||||
for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { | for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { | ||||
LauParameter* parameter = dynamic_cast<LauParameter*>( (*objarray)[iPar] ); | LauParameter* parameter = dynamic_cast<LauParameter*>( (*objarray)[iPar] ); | ||||
if ( ! parameter ) { | if ( ! parameter ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlavesFirstTime : Error reading parameter from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Error reading parameter from task" << std::endl; | ||||
gSystem->Exit(1); | gSystem->Exit(1); | ||||
} | } | ||||
TString parname = parameter->name(); | TString parname = parameter->name(); | ||||
Double_t parvalue = parameter->initValue(); | Double_t parvalue = parameter->initValue(); | ||||
Bool_t parfixed = parameter->fixed(); | Bool_t parfixed = parameter->fixed(); | ||||
std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname ); | std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname ); | ||||
if ( iter != parIndices_.end() ) { | if ( iter != parIndices_.end() ) { | ||||
UInt_t index = iter->second; | UInt_t index = iter->second; | ||||
slaveIndices_[iSlave].push_back( index ); | taskIndices_[iTask].push_back( index ); | ||||
if ( ! parfixed ) { | if ( ! parfixed ) { | ||||
slaveFreeIndices_[iSlave].push_back( index ); | taskFreeIndices_[iTask].push_back( index ); | ||||
} | } | ||||
this->checkParameter( parameter, index ); | this->checkParameter( parameter, index ); | ||||
} else { | } else { | ||||
UInt_t index = parIndices_.size(); | UInt_t index = parIndices_.size(); | ||||
parIndices_.insert( std::make_pair( parname, index ) ); | parIndices_.insert( std::make_pair( parname, index ) ); | ||||
parNames_.insert( std::make_pair( index, parname ) ); | parNames_.insert( std::make_pair( index, parname ) ); | ||||
slaveIndices_[iSlave].push_back( index ); | taskIndices_[iTask].push_back( index ); | ||||
if ( ! parfixed ) { | if ( ! parfixed ) { | ||||
slaveFreeIndices_[iSlave].push_back( index ); | taskFreeIndices_[iTask].push_back( index ); | ||||
} | } | ||||
params_.push_back( parameter ); | params_.push_back( parameter ); | ||||
parValues_.push_back( parvalue ); | parValues_.push_back( parvalue ); | ||||
} | } | ||||
vectorPar_[iSlave][iPar] = parvalue; | vectorPar_[iTask][iPar] = parvalue; | ||||
} | } | ||||
delete objarray; objarray = 0; | delete objarray; objarray = 0; | ||||
delete messageFromSlave_; messageFromSlave_ = 0; | delete messageFromTask_; messageFromTask_ = 0; | ||||
} | } | ||||
} | } | ||||
void LauSimFitMaster::printParInfo() const | void LauSimFitCoordinator::printParInfo() const | ||||
{ | { | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
const std::vector<UInt_t>& indices = slaveIndices_[iSlave]; | const std::vector<UInt_t>& indices = taskIndices_[iTask]; | ||||
std::cout << "INFO in LauSimFitMaster::printParInfo : Slave " << iSlave << " has the following parameters:\n"; | std::cout << "INFO in LauSimFitCoordinator::printParInfo : Task " << iTask << " has the following parameters:\n"; | ||||
for ( std::vector<UInt_t>::const_iterator iter = indices.begin(); iter != indices.end(); ++iter ) { | for ( std::vector<UInt_t>::const_iterator iter = indices.begin(); iter != indices.end(); ++iter ) { | ||||
const TString& parName = parNames_.find(*iter)->second; | const TString& parName = parNames_.find(*iter)->second; | ||||
Double_t parValue = parValues_[*iter]; | Double_t parValue = parValues_[*iter]; | ||||
const LauParameter* par = params_[*iter]; | const LauParameter* par = params_[*iter]; | ||||
if ( par->name() != parName || par->initValue() != parValue ) { | if ( par->name() != parName || par->initValue() != parValue ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::printParInfo : Discrepancy in parameter name and value records, this is very strange!!" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::printParInfo : Discrepancy in parameter name and value records, this is very strange!!" << std::endl; | ||||
} | } | ||||
std::cout << " : " << parName << " = " << parValue << " and has index " << *iter << "\n"; | std::cout << " : " << parName << " = " << parValue << " and has index " << *iter << "\n"; | ||||
} | } | ||||
std::cout << std::endl; | std::cout << std::endl; | ||||
} | } | ||||
std::cout << "INFO in LauSimFitMaster::printParInfo : " << "There are " << params_.size() << " parameters in total" << std::endl; | std::cout << "INFO in LauSimFitCoordinator::printParInfo : " << "There are " << params_.size() << " parameters in total" << std::endl; | ||||
} | } | ||||
void LauSimFitMaster::checkParameter( const LauParameter* param, UInt_t index ) const | void LauSimFitCoordinator::checkParameter( const LauParameter* param, UInt_t index ) const | ||||
{ | { | ||||
const LauParameter* storedPar = params_[index]; | const LauParameter* storedPar = params_[index]; | ||||
TString parName = storedPar->name(); | TString parName = storedPar->name(); | ||||
if ( param->name() != parName ) { | if ( param->name() != parName ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::checkParameter : Parameter name is different!! This shouldn't happen!!" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::checkParameter : Parameter name is different!! This shouldn't happen!!" << std::endl; | ||||
} | } | ||||
if ( param->initValue() != storedPar->initValue() ) { | if ( param->initValue() != storedPar->initValue() ) { | ||||
std::cerr << "WARNING in LauSimFitMaster::checkParameter : Initial value for parameter " << parName << " is different, will use the value first set: " << storedPar->initValue() << std::endl; | std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Initial value for parameter " << parName << " is different, will use the value first set: " << storedPar->initValue() << std::endl; | ||||
} | } | ||||
if ( param->minValue() != storedPar->minValue() ) { | if ( param->minValue() != storedPar->minValue() ) { | ||||
std::cerr << "WARNING in LauSimFitMaster::checkParameter : Minimum allowed value for parameter " << parName << " is different, will use the value first set: " << storedPar->minValue() << std::endl; | std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Minimum allowed value for parameter " << parName << " is different, will use the value first set: " << storedPar->minValue() << std::endl; | ||||
} | } | ||||
if ( param->maxValue() != storedPar->maxValue() ) { | if ( param->maxValue() != storedPar->maxValue() ) { | ||||
std::cerr << "WARNING in LauSimFitMaster::checkParameter : Maximum allowed value for parameter " << parName << " is different, will use the value first set: " << storedPar->maxValue() << std::endl; | std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Maximum allowed value for parameter " << parName << " is different, will use the value first set: " << storedPar->maxValue() << std::endl; | ||||
} | } | ||||
if ( param->fixed() != storedPar->fixed() ) { | if ( param->fixed() != storedPar->fixed() ) { | ||||
std::cerr << "WARNING in LauSimFitMaster::checkParameter : Fixed/floating property of parameter " << parName << " is different, will use the value first set: " << (storedPar->fixed() ? "fixed" : "floating") << std::endl; | std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Fixed/floating property of parameter " << parName << " is different, will use the value first set: " << (storedPar->fixed() ? "fixed" : "floating") << std::endl; | ||||
} | } | ||||
if ( param->secondStage() != storedPar->secondStage() ) { | if ( param->secondStage() != storedPar->secondStage() ) { | ||||
std::cerr << "WARNING in LauSimFitMaster::checkParameter : Second stage property of parameter " << parName << " is different, will use the value first set: " << (storedPar->secondStage() ? "true" : "false") << std::endl; | std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Second stage property of parameter " << parName << " is different, will use the value first set: " << (storedPar->secondStage() ? "true" : "false") << std::endl; | ||||
} | } | ||||
} | } | ||||
void LauSimFitMaster::initialise() | void LauSimFitCoordinator::initialise() | ||||
{ | { | ||||
this->initSockets(); | this->initSockets(); | ||||
} | } | ||||
void LauSimFitMaster::runSimFit( const TString& fitNtupleFileName, const UInt_t nExp, const UInt_t firstExp, const Bool_t useAsymmErrors, const Bool_t doTwoStageFit ) | void LauSimFitCoordinator::runSimFit( const TString& fitNtupleFileName, const UInt_t nExp, const UInt_t firstExp, const Bool_t useAsymmErrors, const Bool_t doTwoStageFit ) | ||||
{ | { | ||||
// Routine to perform the total fit. | // Routine to perform the total fit. | ||||
// First, initialise | // First, initialise | ||||
this->useAsymmFitErrors(useAsymmErrors); | this->useAsymmFitErrors(useAsymmErrors); | ||||
this->twoStageFit(doTwoStageFit); | this->twoStageFit(doTwoStageFit); | ||||
this->initialise(); | this->initialise(); | ||||
std::cout << "INFO in LauSimFitMaster::runSimFit : First experiment = " << firstExp << std::endl; | std::cout << "INFO in LauSimFitCoordinator::runSimFit : First experiment = " << firstExp << std::endl; | ||||
std::cout << "INFO in LauSimFitMaster::runSimFit : Number of experiments = " << nExp << std::endl; | std::cout << "INFO in LauSimFitCoordinator::runSimFit : Number of experiments = " << nExp << std::endl; | ||||
// Start the cumulative timer | // Start the cumulative timer | ||||
cumulTimer_.Start(); | cumulTimer_.Start(); | ||||
this->resetFitCounters(); | this->resetFitCounters(); | ||||
// Create and setup the fit results ntuple | // Create and setup the fit results ntuple | ||||
std::cout << "INFO in LauSimFitMaster::runSimFit : Creating fit ntuple." << std::endl; | std::cout << "INFO in LauSimFitCoordinator::runSimFit : Creating fit ntuple." << std::endl; | ||||
if (fitNtuple_ != 0) {delete fitNtuple_; fitNtuple_ = 0;} | if (fitNtuple_ != 0) {delete fitNtuple_; fitNtuple_ = 0;} | ||||
fitNtuple_ = new LauFitNtuple(fitNtupleFileName, useAsymmErrors); | fitNtuple_ = new LauFitNtuple(fitNtupleFileName, useAsymmErrors); | ||||
// Loop over the number of experiments | // Loop over the number of experiments | ||||
for (UInt_t iExp = firstExp; iExp < (firstExp+nExp); ++iExp) { | for (UInt_t iExp = firstExp; iExp < (firstExp+nExp); ++iExp) { | ||||
// Start the timer to see how long each fit takes | // Start the timer to see how long each fit takes | ||||
timer_.Start(); | timer_.Start(); | ||||
this->setCurrentExperiment( iExp ); | this->setCurrentExperiment( iExp ); | ||||
// Instruct the slaves to read the data for this experiment | // Instruct the tasks to read the data for this experiment | ||||
Bool_t readOK = this->readData(); | Bool_t readOK = this->readData(); | ||||
if ( ! readOK ) { | if ( ! readOK ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::runSimFit : One or more slaves reported problems with reading data for experiment " << iExp << ", skipping..." << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::runSimFit : One or more tasks reported problems with reading data for experiment " << iExp << ", skipping..." << std::endl; | ||||
timer_.Stop(); | timer_.Stop(); | ||||
continue; | continue; | ||||
} | } | ||||
// Instruct the slaves to perform the caching | // Instruct the tasks to perform the caching | ||||
this->cacheInputData(); | this->cacheInputData(); | ||||
// Do the fit | // Do the fit | ||||
this->fitExpt(); | this->fitExpt(); | ||||
// Stop the timer and see how long the program took so far | // Stop the timer and see how long the program took so far | ||||
timer_.Stop(); | timer_.Stop(); | ||||
timer_.Print(); | timer_.Print(); | ||||
// Instruct the slaves to finalise the results | // Instruct the tasks to finalise the results | ||||
this->finalise(); | this->finalise(); | ||||
} | } | ||||
// Print out total timing info. | // Print out total timing info. | ||||
std::cout << "INFO in LauSimFitMaster::runSimFit : Cumulative timing:" << std::endl; | std::cout << "INFO in LauSimFitCoordinator::runSimFit : Cumulative timing:" << std::endl; | ||||
cumulTimer_.Stop(); | cumulTimer_.Stop(); | ||||
cumulTimer_.Print(); | cumulTimer_.Print(); | ||||
// Print out stats on OK fits. | // Print out stats on OK fits. | ||||
const UInt_t nOKFits = this->numberOKFits(); | const UInt_t nOKFits = this->numberOKFits(); | ||||
const UInt_t nBadFits = this->numberBadFits(); | const UInt_t nBadFits = this->numberBadFits(); | ||||
std::cout << "INFO in LauSimFitMaster::runSimFit : Number of OK Fits = " << nOKFits << std::endl; | std::cout << "INFO in LauSimFitCoordinator::runSimFit : Number of OK Fits = " << nOKFits << std::endl; | ||||
std::cout << "INFO in LauSimFitMaster::runSimFit : Number of Failed Fits = " << nBadFits << std::endl; | std::cout << "INFO in LauSimFitCoordinator::runSimFit : Number of Failed Fits = " << nBadFits << std::endl; | ||||
Double_t fitEff(0.0); | Double_t fitEff(0.0); | ||||
if (nExp != 0) {fitEff = nOKFits/(1.0*nExp);} | if (nExp != 0) {fitEff = nOKFits/(1.0*nExp);} | ||||
std::cout << "INFO in LauSimFitMaster::runSimFit : Fit efficiency = " << fitEff*100.0 << "%." << std::endl; | std::cout << "INFO in LauSimFitCoordinator::runSimFit : Fit efficiency = " << fitEff*100.0 << "%." << std::endl; | ||||
// Instruct the slaves to write out any fit results (ntuples etc...). | // Instruct the tasks to write out any fit results (ntuples etc...). | ||||
this->writeOutResults(); | this->writeOutResults(); | ||||
} | } | ||||
void LauSimFitMaster::withinAsymErrorCalc(const Bool_t inAsymErrCalc) | void LauSimFitCoordinator::withinAsymErrorCalc(const Bool_t inAsymErrCalc) | ||||
{ | { | ||||
this->LauFitObject::withinAsymErrorCalc(inAsymErrCalc); | this->LauFitObject::withinAsymErrorCalc(inAsymErrCalc); | ||||
if ( socketMonitor_ == 0 ) { | if ( socketMonitor_ == 0 ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::withinAsymErrorCalc : Sockets not initialised." << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::withinAsymErrorCalc : Sockets not initialised." << std::endl; | ||||
return; | return; | ||||
} | } | ||||
// Construct a message, informing the slaves whether or not we are now within the asymmetric error calculation | // Construct a message, informing the tasks whether or not we are now within the asymmetric error calculation | ||||
TString msgStr("Asym Error Calc"); | TString msgStr("Asym Error Calc"); | ||||
const Bool_t asymErrorCalc( this->withinAsymErrorCalc() ); | const Bool_t asymErrorCalc( this->withinAsymErrorCalc() ); | ||||
TMessage message( kMESS_STRING ); | TMessage message( kMESS_STRING ); | ||||
message.WriteTString( msgStr ); | message.WriteTString( msgStr ); | ||||
message.WriteBool( asymErrorCalc ); | message.WriteBool( asymErrorCalc ); | ||||
// Send the message to the slaves | // Send the message to the tasks | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
sSlaves_[iSlave]->Send(message); | socketTasks_[iTask]->Send(message); | ||||
} | } | ||||
TSocket* sActive(0); | TSocket* sActive(0); | ||||
UInt_t responsesReceived(0); | UInt_t responsesReceived(0); | ||||
while ( responsesReceived != nSlaves_ ) { | while ( responsesReceived != nTasks_ ) { | ||||
// Get the next queued response | // Get the next queued response | ||||
sActive = socketMonitor_->Select(); | sActive = socketMonitor_->Select(); | ||||
// Extract from the message the ID of the slave and the number of events read | // Extract from the message the ID of the task and the number of events read | ||||
Bool_t response(kTRUE); | Bool_t response(kTRUE); | ||||
UInt_t iSlave(0); | UInt_t iTask(0); | ||||
sActive->Recv( messageFromSlave_ ); | sActive->Recv( messageFromTask_ ); | ||||
messageFromSlave_->ReadUInt( iSlave ); | messageFromTask_->ReadUInt( iTask ); | ||||
messageFromSlave_->ReadBool( response ); | messageFromTask_->ReadBool( response ); | ||||
if ( response != asymErrorCalc ) { | if ( response != asymErrorCalc ) { | ||||
std::cerr << "WARNING in LauSimFitMaster::withinAsymErrorCalc : Problem informing slave " << iSlave << std::endl; | std::cerr << "WARNING in LauSimFitCoordinator::withinAsymErrorCalc : Problem informing task " << iTask << std::endl; | ||||
} | } | ||||
++responsesReceived; | ++responsesReceived; | ||||
} | } | ||||
} | } | ||||
Bool_t LauSimFitMaster::readData() | Bool_t LauSimFitCoordinator::readData() | ||||
{ | { | ||||
if ( socketMonitor_ == 0 ) { | if ( socketMonitor_ == 0 ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::readData : Sockets not initialised." << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::readData : Sockets not initialised." << std::endl; | ||||
return kFALSE; | return kFALSE; | ||||
} | } | ||||
// Construct a message, requesting to read the data for the given experiment | // Construct a message, requesting to read the data for the given experiment | ||||
TString msgStr("Read Expt"); | TString msgStr("Read Expt"); | ||||
const UInt_t iExp( this->iExpt() ); | const UInt_t iExp( this->iExpt() ); | ||||
TMessage message( kMESS_STRING ); | TMessage message( kMESS_STRING ); | ||||
message.WriteTString( msgStr ); | message.WriteTString( msgStr ); | ||||
message.WriteUInt( iExp ); | message.WriteUInt( iExp ); | ||||
// Send the message to the slaves | // Send the message to the tasks | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
sSlaves_[iSlave]->Send(message); | socketTasks_[iTask]->Send(message); | ||||
} | } | ||||
TSocket* sActive(0); | TSocket* sActive(0); | ||||
UInt_t responsesReceived(0); | UInt_t responsesReceived(0); | ||||
Bool_t ok(kTRUE); | Bool_t ok(kTRUE); | ||||
while ( responsesReceived != nSlaves_ ) { | while ( responsesReceived != nTasks_ ) { | ||||
// Get the next queued response | // Get the next queued response | ||||
sActive = socketMonitor_->Select(); | sActive = socketMonitor_->Select(); | ||||
// Extract from the message the ID of the slave and the number of events read | // Extract from the message the ID of the task and the number of events read | ||||
sActive->Recv( messageFromSlave_ ); | sActive->Recv( messageFromTask_ ); | ||||
UInt_t iSlave(0); | UInt_t iTask(0); | ||||
UInt_t nEvents(0); | UInt_t nEvents(0); | ||||
messageFromSlave_->ReadUInt( iSlave ); | messageFromTask_->ReadUInt( iTask ); | ||||
messageFromSlave_->ReadUInt( nEvents ); | messageFromTask_->ReadUInt( nEvents ); | ||||
if ( nEvents <= 0 ) { | if ( nEvents <= 0 ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::readData : Slave " << iSlave << " reports no events found for experiment " << iExp << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::readData : Task " << iTask << " reports no events found for experiment " << iExp << std::endl; | ||||
ok = kFALSE; | ok = kFALSE; | ||||
} else { | } else { | ||||
std::cerr << "INFO in LauSimFitMaster::readData : Slave " << iSlave << " reports " << nEvents << " events found for experiment " << iExp << std::endl; | std::cerr << "INFO in LauSimFitCoordinator::readData : Task " << iTask << " reports " << nEvents << " events found for experiment " << iExp << std::endl; | ||||
} | } | ||||
++responsesReceived; | ++responsesReceived; | ||||
} | } | ||||
return ok; | return ok; | ||||
} | } | ||||
Bool_t LauSimFitMaster::cacheInputData() | Bool_t LauSimFitCoordinator::cacheInputData() | ||||
{ | { | ||||
if ( socketMonitor_ == 0 ) { | if ( socketMonitor_ == 0 ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::cacheInputData : Sockets not initialised." << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::cacheInputData : Sockets not initialised." << std::endl; | ||||
return kFALSE; | return kFALSE; | ||||
} | } | ||||
// Construct a message, requesting it to read the data for the given experiment | // Construct a message, requesting it to read the data for the given experiment | ||||
TString msgStr("Cache"); | TString msgStr("Cache"); | ||||
TMessage message( kMESS_STRING ); | TMessage message( kMESS_STRING ); | ||||
message.WriteTString( msgStr ); | message.WriteTString( msgStr ); | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
// Send the message to the slave | // Send the message to the task | ||||
sSlaves_[iSlave]->Send(message); | socketTasks_[iTask]->Send(message); | ||||
} | } | ||||
TSocket* sActive(0); | TSocket* sActive(0); | ||||
UInt_t responsesReceived(0); | UInt_t responsesReceived(0); | ||||
Bool_t allOK(kTRUE); | Bool_t allOK(kTRUE); | ||||
while ( responsesReceived != nSlaves_ ) { | while ( responsesReceived != nTasks_ ) { | ||||
// Get the next queued response | // Get the next queued response | ||||
sActive = socketMonitor_->Select(); | sActive = socketMonitor_->Select(); | ||||
// Extract from the message the ID of the slave and the success/failure flag | // Extract from the message the ID of the task and the success/failure flag | ||||
sActive->Recv( messageFromSlave_ ); | sActive->Recv( messageFromTask_ ); | ||||
UInt_t iSlave(0); | UInt_t iTask(0); | ||||
Bool_t ok(kTRUE); | Bool_t ok(kTRUE); | ||||
messageFromSlave_->ReadUInt( iSlave ); | messageFromTask_->ReadUInt( iTask ); | ||||
messageFromSlave_->ReadBool( ok ); | messageFromTask_->ReadBool( ok ); | ||||
if ( ! ok ) { | if ( ! ok ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::cacheInputData : Slave " << iSlave << " reports an error performing caching" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::cacheInputData : Task " << iTask << " reports an error performing caching" << std::endl; | ||||
allOK = kFALSE; | allOK = kFALSE; | ||||
} | } | ||||
++responsesReceived; | ++responsesReceived; | ||||
} | } | ||||
return allOK; | return allOK; | ||||
} | } | ||||
void LauSimFitMaster::checkInitFitParams() | void LauSimFitCoordinator::checkInitFitParams() | ||||
{ | { | ||||
this->getParametersFromSlaves(); | this->getParametersFromTasks(); | ||||
this->printParInfo(); | this->printParInfo(); | ||||
} | } | ||||
void LauSimFitMaster::fitExpt() | void LauSimFitCoordinator::fitExpt() | ||||
{ | { | ||||
// Routine to perform the actual fit for the given experiment | // Routine to perform the actual fit for the given experiment | ||||
// Instruct the slaves to update initial fit parameters if required (e.g. if using random numbers). | // Instruct the tasks to update initial fit parameters if required (e.g. if using random numbers). | ||||
this->checkInitFitParams(); | this->checkInitFitParams(); | ||||
// Initialise the fitter | // Initialise the fitter | ||||
LauFitter::fitter()->useAsymmFitErrors( this->useAsymmFitErrors() ); | LauFitter::fitter()->useAsymmFitErrors( this->useAsymmFitErrors() ); | ||||
LauFitter::fitter()->twoStageFit( this->twoStageFit() ); | LauFitter::fitter()->twoStageFit( this->twoStageFit() ); | ||||
LauFitter::fitter()->initialise( this, params_ ); | LauFitter::fitter()->initialise( this, params_ ); | ||||
this->startNewFit( LauFitter::fitter()->nParameters(), LauFitter::fitter()->nFreeParameters() ); | this->startNewFit( LauFitter::fitter()->nParameters(), LauFitter::fitter()->nFreeParameters() ); | ||||
// Now ready for minimisation step | // Now ready for minimisation step | ||||
std::cout << "\nINFO in LauSimFitMaster::fitExpt : Start minimisation...\n"; | std::cout << "\nINFO in LauSimFitCoordinator::fitExpt : Start minimisation...\n"; | ||||
LauAbsFitter::FitStatus fitResult = LauFitter::fitter()->minimise(); | LauAbsFitter::FitStatus fitResult = LauFitter::fitter()->minimise(); | ||||
// If we're doing a two stage fit we can now release (i.e. float) | // If we're doing a two stage fit we can now release (i.e. float) | ||||
// the 2nd stage parameters and re-fit | // the 2nd stage parameters and re-fit | ||||
if (this->twoStageFit()) { | if (this->twoStageFit()) { | ||||
if ( fitResult.status != 3 ) { | if ( fitResult.status != 3 ) { | ||||
std::cerr << "ERROR in LauSimFitMaster:fitExpt : Not running second stage fit since first stage failed." << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator:fitExpt : Not running second stage fit since first stage failed." << std::endl; | ||||
LauFitter::fitter()->releaseSecondStageParameters(); | LauFitter::fitter()->releaseSecondStageParameters(); | ||||
} else { | } else { | ||||
LauFitter::fitter()->releaseSecondStageParameters(); | LauFitter::fitter()->releaseSecondStageParameters(); | ||||
this->startNewFit( LauFitter::fitter()->nParameters(), LauFitter::fitter()->nFreeParameters() ); | this->startNewFit( LauFitter::fitter()->nParameters(), LauFitter::fitter()->nFreeParameters() ); | ||||
fitResult = LauFitter::fitter()->minimise(); | fitResult = LauFitter::fitter()->minimise(); | ||||
} | } | ||||
} | } | ||||
const TMatrixD& covMat = LauFitter::fitter()->covarianceMatrix(); | const TMatrixD& covMat = LauFitter::fitter()->covarianceMatrix(); | ||||
this->storeFitStatus( fitResult, covMat ); | this->storeFitStatus( fitResult, covMat ); | ||||
// Store the final fit results and errors into protected internal vectors that | // Store the final fit results and errors into protected internal vectors that | ||||
// all sub-classes can use within their own finalFitResults implementation | // all sub-classes can use within their own finalFitResults implementation | ||||
// used below (e.g. putting them into an ntuple in a root file) | // used below (e.g. putting them into an ntuple in a root file) | ||||
LauFitter::fitter()->updateParameters(); | LauFitter::fitter()->updateParameters(); | ||||
} | } | ||||
void LauSimFitMaster::setParsFromMinuit(Double_t* par, Int_t npar) | void LauSimFitCoordinator::setParsFromMinuit(Double_t* par, Int_t npar) | ||||
{ | { | ||||
// This function sets the internal parameters based on the values | // This function sets the internal parameters based on the values | ||||
// that Minuit is using when trying to minimise the total likelihood function. | // that Minuit is using when trying to minimise the total likelihood function. | ||||
// MINOS reports different numbers of free parameters depending on the | // MINOS reports different numbers of free parameters depending on the | ||||
// situation, so disable this check | // situation, so disable this check | ||||
if ( ! this->withinAsymErrorCalc() ) { | if ( ! this->withinAsymErrorCalc() ) { | ||||
const UInt_t nFreePars = this->nFreeParams(); | const UInt_t nFreePars = this->nFreeParams(); | ||||
if (static_cast<UInt_t>(npar) != nFreePars) { | if (static_cast<UInt_t>(npar) != nFreePars) { | ||||
std::cerr << "ERROR in LauSimFitMaster::setParsFromMinuit : Unexpected number of free parameters: " << npar << ".\n"; | std::cerr << "ERROR in LauSimFitCoordinator::setParsFromMinuit : Unexpected number of free parameters: " << npar << ".\n"; | ||||
std::cerr << " Expected: " << nFreePars << ".\n" << std::endl; | std::cerr << " Expected: " << nFreePars << ".\n" << std::endl; | ||||
gSystem->Exit(EXIT_FAILURE); | gSystem->Exit(EXIT_FAILURE); | ||||
} | } | ||||
} | } | ||||
// Despite npar being the number of free parameters | // Despite npar being the number of free parameters | ||||
// the par array actually contains all the parameters, | // the par array actually contains all the parameters, | ||||
// free and floating... | // free and floating... | ||||
// Update all the parameters with their new values. | // Update all the parameters with their new values. | ||||
// Change the value in the array to be sent out to the slaves and the | // Change the value in the array to be sent out to the tasks and the | ||||
// parameters themselves (so that constraints are correctly calculated) | // parameters themselves (so that constraints are correctly calculated) | ||||
for (UInt_t i(0); i<this->nTotParams(); ++i) { | for (UInt_t i(0); i<this->nTotParams(); ++i) { | ||||
if (!params_[i]->fixed()) { | if (!params_[i]->fixed()) { | ||||
parValues_[i] = par[i]; | parValues_[i] = par[i]; | ||||
params_[i]->value(par[i]); | params_[i]->value(par[i]); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
Double_t LauSimFitMaster::getTotNegLogLikelihood() | Double_t LauSimFitCoordinator::getTotNegLogLikelihood() | ||||
{ | { | ||||
if ( socketMonitor_ == 0 ) { | if ( socketMonitor_ == 0 ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::getTotNegLogLikelihood : Sockets not initialised." << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::getTotNegLogLikelihood : Sockets not initialised." << std::endl; | ||||
return 0.0; | return 0.0; | ||||
} | } | ||||
// Send current values of the parameters to the slaves. | // Send current values of the parameters to the tasks. | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
std::vector<UInt_t>& indices = slaveIndices_[iSlave]; | std::vector<UInt_t>& indices = taskIndices_[iTask]; | ||||
std::vector<UInt_t>& freeIndices = slaveFreeIndices_[iSlave]; | std::vector<UInt_t>& freeIndices = taskFreeIndices_[iTask]; | ||||
UInt_t nPars = indices.size(); | UInt_t nPars = indices.size(); | ||||
UInt_t nFreePars = freeIndices.size(); | UInt_t nFreePars = freeIndices.size(); | ||||
for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { | for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { | ||||
vectorPar_[iSlave][iPar] = parValues_[ indices[iPar] ]; | vectorPar_[iTask][iPar] = parValues_[ indices[iPar] ]; | ||||
} | } | ||||
TMessage* message = messagesToSlaves_[iSlave]; | TMessage* message = messagesToTasks_[iTask]; | ||||
message->Reset( kMESS_ANY ); | message->Reset( kMESS_ANY ); | ||||
message->WriteUInt( nPars ); | message->WriteUInt( nPars ); | ||||
message->WriteUInt( nFreePars ); | message->WriteUInt( nFreePars ); | ||||
message->WriteFastArray( vectorPar_[iSlave], nPars ); | message->WriteFastArray( vectorPar_[iTask], nPars ); | ||||
sSlaves_[iSlave]->Send(*message); | socketTasks_[iTask]->Send(*message); | ||||
} | } | ||||
Double_t negLogLike(0.0); | Double_t negLogLike(0.0); | ||||
TSocket *sActive(0); | TSocket *sActive(0); | ||||
UInt_t responsesReceived(0); | UInt_t responsesReceived(0); | ||||
Bool_t allOK(kTRUE); | Bool_t allOK(kTRUE); | ||||
while ( responsesReceived != nSlaves_ ) { | while ( responsesReceived != nTasks_ ) { | ||||
sActive = socketMonitor_->Select(); | sActive = socketMonitor_->Select(); | ||||
sActive->Recv(messageFromSlave_); | sActive->Recv(messageFromTask_); | ||||
messageFromSlave_->ReadDouble( vectorRes_[responsesReceived] ); | messageFromTask_->ReadDouble( vectorRes_[responsesReceived] ); | ||||
Double_t& nLL = vectorRes_[responsesReceived]; | Double_t& nLL = vectorRes_[responsesReceived]; | ||||
if ( nLL == 0.0 || TMath::IsNaN(nLL) || !TMath::Finite(nLL) ) { | if ( nLL == 0.0 || TMath::IsNaN(nLL) || !TMath::Finite(nLL) ) { | ||||
allOK = kFALSE; | allOK = kFALSE; | ||||
} | } | ||||
negLogLike += vectorRes_[responsesReceived]; | negLogLike += vectorRes_[responsesReceived]; | ||||
++responsesReceived; | ++responsesReceived; | ||||
} | } | ||||
// Calculate any penalty terms from Gaussian constrained variables | // Calculate any penalty terms from Gaussian constrained variables | ||||
if ( ! conVars_.empty() ){ | if ( ! conVars_.empty() ){ | ||||
negLogLike += this->getLogLikelihoodPenalty(); | negLogLike += this->getLogLikelihoodPenalty(); | ||||
} | } | ||||
const Double_t worstNegLogLike = -1.0*this->worstLogLike(); | const Double_t worstNegLogLike = -1.0*this->worstLogLike(); | ||||
if ( ! allOK ) { | if ( ! allOK ) { | ||||
std::cerr << "WARNING in LauSimFitMaster::getTotNegLogLikelihood : Strange NLL value returned by one or more slaves\n"; | std::cerr << "WARNING in LauSimFitCoordinator::getTotNegLogLikelihood : Strange NLL value returned by one or more tasks\n"; | ||||
std::cerr << " : Returning worst NLL found so far to force MINUIT out of this region." << std::endl; | std::cerr << " : Returning worst NLL found so far to force MINUIT out of this region." << std::endl; | ||||
negLogLike = worstNegLogLike; | negLogLike = worstNegLogLike; | ||||
} else if ( negLogLike > worstNegLogLike ) { | } else if ( negLogLike > worstNegLogLike ) { | ||||
this->worstLogLike( -negLogLike ); | this->worstLogLike( -negLogLike ); | ||||
} | } | ||||
return negLogLike; | return negLogLike; | ||||
} | } | ||||
Double_t LauSimFitMaster::getLogLikelihoodPenalty() | Double_t LauSimFitCoordinator::getLogLikelihoodPenalty() | ||||
{ | { | ||||
Double_t penalty(0.0); | Double_t penalty(0.0); | ||||
for ( std::vector<LauAbsRValue*>::const_iterator iter = conVars_.begin(); iter != conVars_.end(); ++iter ) { | for ( std::vector<LauAbsRValue*>::const_iterator iter = conVars_.begin(); iter != conVars_.end(); ++iter ) { | ||||
Double_t val = (*iter)->unblindValue(); | Double_t val = (*iter)->unblindValue(); | ||||
Double_t mean = (*iter)->constraintMean(); | Double_t mean = (*iter)->constraintMean(); | ||||
Double_t width = (*iter)->constraintWidth(); | Double_t width = (*iter)->constraintWidth(); | ||||
Double_t term = ( val - mean )*( val - mean ); | Double_t term = ( val - mean )*( val - mean ); | ||||
penalty += term/( 2*width*width ); | penalty += term/( 2*width*width ); | ||||
} | } | ||||
return penalty; | return penalty; | ||||
} | } | ||||
void LauSimFitMaster::addConParameters() | void LauSimFitCoordinator::addConParameters() | ||||
{ | { | ||||
// Add penalties from the constraints to fit parameters | // Add penalties from the constraints to fit parameters | ||||
// First, constraints on the fit parameters themselves | // First, constraints on the fit parameters themselves | ||||
for ( std::vector<LauParameter*>::const_iterator iter = params_.begin(); iter != params_.end(); ++iter ) { | for ( std::vector<LauParameter*>::const_iterator iter = params_.begin(); iter != params_.end(); ++iter ) { | ||||
if ( (*iter)->gaussConstraint() ) { | if ( (*iter)->gaussConstraint() ) { | ||||
conVars_.push_back( *iter ); | conVars_.push_back( *iter ); | ||||
std::cout << "INFO in LauSimFitMaster::addConParameters : Added Gaussian constraint to parameter "<< (*iter)->name() << std::endl; | std::cout << "INFO in LauSimFitCoordinator::addConParameters : Added Gaussian constraint to parameter "<< (*iter)->name() << std::endl; | ||||
} | } | ||||
} | } | ||||
// Second, constraints on arbitrary combinations | // Second, constraints on arbitrary combinations | ||||
const std::vector<StoreConstraints>& storeCon = this->constraintsStore(); | const std::vector<StoreConstraints>& storeCon = this->constraintsStore(); | ||||
for ( std::vector<StoreConstraints>::const_iterator iter = storeCon.begin(); iter != storeCon.end(); ++iter ) { | for ( std::vector<StoreConstraints>::const_iterator iter = storeCon.begin(); iter != storeCon.end(); ++iter ) { | ||||
const std::vector<TString>& names = (*iter).conPars_; | const std::vector<TString>& names = (*iter).conPars_; | ||||
std::vector<LauParameter*> params; | std::vector<LauParameter*> params; | ||||
for ( std::vector<TString>::const_iterator iternames = names.begin(); iternames != names.end(); ++iternames ) { | for ( std::vector<TString>::const_iterator iternames = names.begin(); iternames != names.end(); ++iternames ) { | ||||
for ( std::vector<LauParameter*>::const_iterator iterfit = params_.begin(); iterfit != params_.end(); ++iterfit ) { | for ( std::vector<LauParameter*>::const_iterator iterfit = params_.begin(); iterfit != params_.end(); ++iterfit ) { | ||||
if ( (*iternames) == (*iterfit)->name() ){ | if ( (*iternames) == (*iterfit)->name() ){ | ||||
params.push_back(*iterfit); | params.push_back(*iterfit); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// If the parameters are not found, skip it | // If the parameters are not found, skip it | ||||
if ( params.size() != (*iter).conPars_.size() ) { | if ( params.size() != (*iter).conPars_.size() ) { | ||||
std::cerr << "WARNING in LauSimFitMaster::addConParameters: Could not find parameters to constrain in the formula... skipping" << std::endl; | std::cerr << "WARNING in LauSimFitCoordinator::addConParameters: Could not find parameters to constrain in the formula... skipping" << std::endl; | ||||
continue; | continue; | ||||
} | } | ||||
LauFormulaPar* formPar = new LauFormulaPar( (*iter).formula_, (*iter).formula_, params ); | LauFormulaPar* formPar = new LauFormulaPar( (*iter).formula_, (*iter).formula_, params ); | ||||
formPar->addGaussianConstraint( (*iter).mean_, (*iter).width_ ); | formPar->addGaussianConstraint( (*iter).mean_, (*iter).width_ ); | ||||
conVars_.push_back(formPar); | conVars_.push_back(formPar); | ||||
std::cout << "INFO in LauSimFitMaster::addConParameters : Added Gaussian constraint to formula\n"; | std::cout << "INFO in LauSimFitCoordinator::addConParameters : Added Gaussian constraint to formula\n"; | ||||
std::cout << " : Formula: " << (*iter).formula_ << std::endl; | std::cout << " : Formula: " << (*iter).formula_ << std::endl; | ||||
for ( std::vector<LauParameter*>::iterator iterparam = params.begin(); iterparam != params.end(); ++iterparam ) { | for ( std::vector<LauParameter*>::iterator iterparam = params.begin(); iterparam != params.end(); ++iterparam ) { | ||||
std::cout << " : Parameter: " << (*iterparam)->name() << std::endl; | std::cout << " : Parameter: " << (*iterparam)->name() << std::endl; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
Bool_t LauSimFitMaster::finalise() | Bool_t LauSimFitCoordinator::finalise() | ||||
{ | { | ||||
if ( socketMonitor_ == 0 ) { | if ( socketMonitor_ == 0 ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::finalise : Sockets not initialised." << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::finalise : Sockets not initialised." << std::endl; | ||||
return kFALSE; | return kFALSE; | ||||
} | } | ||||
// Prepare the covariance matrices | // Prepare the covariance matrices | ||||
const TMatrixD& covMatrix = this->covarianceMatrix(); | const TMatrixD& covMatrix = this->covarianceMatrix(); | ||||
covMatrices_.resize( nSlaves_ ); | covMatrices_.resize( nTasks_ ); | ||||
LauParamFixed pred; | LauParamFixed pred; | ||||
std::map<UInt_t,UInt_t> freeParIndices; | std::map<UInt_t,UInt_t> freeParIndices; | ||||
UInt_t counter(0); | UInt_t counter(0); | ||||
for ( UInt_t iPar(0); iPar < this->nTotParams(); ++iPar ) { | for ( UInt_t iPar(0); iPar < this->nTotParams(); ++iPar ) { | ||||
const LauParameter* par = params_[iPar]; | const LauParameter* par = params_[iPar]; | ||||
if ( ! pred(par) ) { | if ( ! pred(par) ) { | ||||
freeParIndices.insert( std::make_pair(iPar,counter) ); | freeParIndices.insert( std::make_pair(iPar,counter) ); | ||||
++counter; | ++counter; | ||||
} | } | ||||
} | } | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
const UInt_t nPar = slaveIndices_[iSlave].size(); | const UInt_t nPar = taskIndices_[iTask].size(); | ||||
std::vector<UInt_t> freeIndices; | std::vector<UInt_t> freeIndices; | ||||
freeIndices.reserve( nPar ); | freeIndices.reserve( nPar ); | ||||
for ( UInt_t iPar(0); iPar < nPar; ++iPar ) { | for ( UInt_t iPar(0); iPar < nPar; ++iPar ) { | ||||
UInt_t index = slaveIndices_[iSlave][iPar]; | UInt_t index = taskIndices_[iTask][iPar]; | ||||
std::map<UInt_t,UInt_t>::iterator freeIter = freeParIndices.find(index); | std::map<UInt_t,UInt_t>::iterator freeIter = freeParIndices.find(index); | ||||
if ( freeIter == freeParIndices.end() ) { | if ( freeIter == freeParIndices.end() ) { | ||||
continue; | continue; | ||||
} | } | ||||
UInt_t freeIndex = freeIter->second; | UInt_t freeIndex = freeIter->second; | ||||
freeIndices.push_back( freeIndex ); | freeIndices.push_back( freeIndex ); | ||||
} | } | ||||
const UInt_t nFreePars = freeIndices.size(); | const UInt_t nFreePars = freeIndices.size(); | ||||
TMatrixD& covMat = covMatrices_[iSlave]; | TMatrixD& covMat = covMatrices_[iTask]; | ||||
covMat.ResizeTo( nFreePars, nFreePars ); | covMat.ResizeTo( nFreePars, nFreePars ); | ||||
for ( UInt_t iPar(0); iPar < nFreePars; ++iPar ) { | for ( UInt_t iPar(0); iPar < nFreePars; ++iPar ) { | ||||
for ( UInt_t jPar(0); jPar < nFreePars; ++jPar ) { | for ( UInt_t jPar(0); jPar < nFreePars; ++jPar ) { | ||||
UInt_t i = freeIndices[iPar]; | UInt_t i = freeIndices[iPar]; | ||||
UInt_t j = freeIndices[jPar]; | UInt_t j = freeIndices[jPar]; | ||||
covMat( iPar, jPar ) = covMatrix( i, j ); | covMat( iPar, jPar ) = covMatrix( i, j ); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// The array to hold the parameters | // The array to hold the parameters | ||||
TObjArray array; | TObjArray array; | ||||
// Send messages to all slaves containing the final parameters and fit status, NLL | // Send messages to all tasks containing the final parameters and fit status, NLL | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
array.Clear(); | array.Clear(); | ||||
std::vector<UInt_t>& indices = slaveIndices_[iSlave]; | std::vector<UInt_t>& indices = taskIndices_[iTask]; | ||||
UInt_t nPars = indices.size(); | UInt_t nPars = indices.size(); | ||||
for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { | for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { | ||||
array.Add( params_[ indices[iPar] ] ); | array.Add( params_[ indices[iPar] ] ); | ||||
} | } | ||||
const Int_t status = this->statusCode(); | const Int_t status = this->statusCode(); | ||||
const Double_t NLL = this->nll(); | const Double_t NLL = this->nll(); | ||||
const Double_t EDM = this->edm(); | const Double_t EDM = this->edm(); | ||||
TMatrixD& covMat = covMatrices_[iSlave]; | TMatrixD& covMat = covMatrices_[iTask]; | ||||
TMessage* message = messagesToSlaves_[iSlave]; | TMessage* message = messagesToTasks_[iTask]; | ||||
message->Reset( kMESS_OBJECT ); | message->Reset( kMESS_OBJECT ); | ||||
message->WriteInt( status ); | message->WriteInt( status ); | ||||
message->WriteDouble( NLL ); | message->WriteDouble( NLL ); | ||||
message->WriteDouble( EDM ); | message->WriteDouble( EDM ); | ||||
message->WriteObject( &array ); | message->WriteObject( &array ); | ||||
message->WriteObject( &covMat ); | message->WriteObject( &covMat ); | ||||
sSlaves_[iSlave]->Send(*message); | socketTasks_[iTask]->Send(*message); | ||||
} | } | ||||
TSocket *sActive(0); | TSocket *sActive(0); | ||||
UInt_t responsesReceived(0); | UInt_t responsesReceived(0); | ||||
Bool_t allOK(kTRUE); | Bool_t allOK(kTRUE); | ||||
while ( responsesReceived != nSlaves_ ) { | while ( responsesReceived != nTasks_ ) { | ||||
// Get the next queued response | // Get the next queued response | ||||
sActive = socketMonitor_->Select(); | sActive = socketMonitor_->Select(); | ||||
// Extract from the message the ID of the slave and the number of events read | // Extract from the message the ID of the task and the number of events read | ||||
sActive->Recv( messageFromSlave_ ); | sActive->Recv( messageFromTask_ ); | ||||
UInt_t iSlave(0); | UInt_t iTask(0); | ||||
Bool_t ok(kTRUE); | Bool_t ok(kTRUE); | ||||
messageFromSlave_->ReadUInt( iSlave ); | messageFromTask_->ReadUInt( iTask ); | ||||
messageFromSlave_->ReadBool( ok ); | messageFromTask_->ReadBool( ok ); | ||||
if ( ok ) { | if ( ok ) { | ||||
TObjArray * objarray = dynamic_cast<TObjArray*>( messageFromSlave_->ReadObject( messageFromSlave_->GetClass() ) ); | TObjArray * objarray = dynamic_cast<TObjArray*>( messageFromTask_->ReadObject( messageFromTask_->GetClass() ) ); | ||||
if ( ! objarray ) { | if ( ! objarray ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::finalise : Error reading finalised parameters from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::finalise : Error reading finalised parameters from task" << std::endl; | ||||
allOK = kFALSE; | allOK = kFALSE; | ||||
} else { | } else { | ||||
// We want to auto-delete the supplied parameters since we only copy their values in this case | // We want to auto-delete the supplied parameters since we only copy their values in this case | ||||
objarray->SetOwner(kTRUE); | objarray->SetOwner(kTRUE); | ||||
const UInt_t nPars = objarray->GetEntries(); | const UInt_t nPars = objarray->GetEntries(); | ||||
if ( nPars != slaveIndices_[iSlave].size() ) { | if ( nPars != taskIndices_[iTask].size() ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::finalise : Unexpected number of finalised parameters received from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::finalise : Unexpected number of finalised parameters received from task" << std::endl; | ||||
allOK = kFALSE; | allOK = kFALSE; | ||||
} else { | } else { | ||||
for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { | for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { | ||||
LauParameter* parameter = dynamic_cast<LauParameter*>( (*objarray)[iPar] ); | LauParameter* parameter = dynamic_cast<LauParameter*>( (*objarray)[iPar] ); | ||||
if ( ! parameter ) { | if ( ! parameter ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::finalise : Error reading parameter from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::finalise : Error reading parameter from task" << std::endl; | ||||
allOK = kFALSE; | allOK = kFALSE; | ||||
continue; | continue; | ||||
} | } | ||||
TString parname = parameter->name(); | TString parname = parameter->name(); | ||||
std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname ); | std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname ); | ||||
if ( iter == parIndices_.end() ) { | if ( iter == parIndices_.end() ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::finalise : Unexpected parameter name received from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::finalise : Unexpected parameter name received from task" << std::endl; | ||||
allOK = kFALSE; | allOK = kFALSE; | ||||
continue; | continue; | ||||
} | } | ||||
const UInt_t index = iter->second; | const UInt_t index = iter->second; | ||||
if ( slaveIndices_[iSlave][iPar] != index ) { | if ( taskIndices_[iTask][iPar] != index ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::finalise : Unexpected parameter received from slave" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::finalise : Unexpected parameter received from task" << std::endl; | ||||
allOK = kFALSE; | allOK = kFALSE; | ||||
continue; | continue; | ||||
} | } | ||||
Double_t parvalue = parameter->value(); | Double_t parvalue = parameter->value(); | ||||
params_[index]->value( parvalue ); | params_[index]->value( parvalue ); | ||||
parValues_[index] = parvalue; | parValues_[index] = parvalue; | ||||
vectorPar_[iSlave][iPar] = parvalue; | vectorPar_[iTask][iPar] = parvalue; | ||||
} | } | ||||
} | } | ||||
delete objarray; | delete objarray; | ||||
} | } | ||||
} else { | } else { | ||||
std::cerr << "ERROR in LauSimFitMaster::finalise : Slave " << iSlave << " reports an error performing finalisation" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::finalise : Task " << iTask << " reports an error performing finalisation" << std::endl; | ||||
allOK = kFALSE; | allOK = kFALSE; | ||||
} | } | ||||
++responsesReceived; | ++responsesReceived; | ||||
} | } | ||||
// Fill our ntuple as well | // Fill our ntuple as well | ||||
if ( fitNtuple_ != 0 ) { | if ( fitNtuple_ != 0 ) { | ||||
for ( std::vector<LauParameter*>::iterator iter = params_.begin(); iter != params_.end(); ++iter ) { | for ( std::vector<LauParameter*>::iterator iter = params_.begin(); iter != params_.end(); ++iter ) { | ||||
if (!(*iter)->fixed()) { | if (!(*iter)->fixed()) { | ||||
(*iter)->updatePull(); | (*iter)->updatePull(); | ||||
} | } | ||||
} | } | ||||
std::vector<LauParameter> extraVars; | std::vector<LauParameter> extraVars; | ||||
fitNtuple_->storeParsAndErrors( params_, extraVars ); | fitNtuple_->storeParsAndErrors( params_, extraVars ); | ||||
fitNtuple_->storeCorrMatrix(this->iExpt(), this->fitStatus(), this->covarianceMatrix()); | fitNtuple_->storeCorrMatrix(this->iExpt(), this->fitStatus(), this->covarianceMatrix()); | ||||
fitNtuple_->updateFitNtuple(); | fitNtuple_->updateFitNtuple(); | ||||
} | } | ||||
return allOK; | return allOK; | ||||
} | } | ||||
Bool_t LauSimFitMaster::writeOutResults() | Bool_t LauSimFitCoordinator::writeOutResults() | ||||
{ | { | ||||
if ( socketMonitor_ == 0 ) { | if ( socketMonitor_ == 0 ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::writeOutResults : Sockets not initialised." << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::writeOutResults : Sockets not initialised." << std::endl; | ||||
return kFALSE; | return kFALSE; | ||||
} | } | ||||
// Construct a message, requesting to write out the fit results | // Construct a message, requesting to write out the fit results | ||||
TString msgStr("Write Results"); | TString msgStr("Write Results"); | ||||
TMessage message( kMESS_STRING ); | TMessage message( kMESS_STRING ); | ||||
message.WriteTString( msgStr ); | message.WriteTString( msgStr ); | ||||
// Send the message to the slaves | // Send the message to the tasks | ||||
for ( UInt_t iSlave(0); iSlave<nSlaves_; ++iSlave ) { | for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) { | ||||
sSlaves_[iSlave]->Send(message); | socketTasks_[iTask]->Send(message); | ||||
} | } | ||||
TSocket *sActive(0); | TSocket *sActive(0); | ||||
UInt_t responsesReceived(0); | UInt_t responsesReceived(0); | ||||
Bool_t allOK(kTRUE); | Bool_t allOK(kTRUE); | ||||
while ( responsesReceived != nSlaves_ ) { | while ( responsesReceived != nTasks_ ) { | ||||
// Get the next queued response | // Get the next queued response | ||||
sActive = socketMonitor_->Select(); | sActive = socketMonitor_->Select(); | ||||
// Extract from the message the ID of the slave and the number of events read | // Extract from the message the ID of the task and the number of events read | ||||
sActive->Recv( messageFromSlave_ ); | sActive->Recv( messageFromTask_ ); | ||||
UInt_t iSlave(0); | UInt_t iTask(0); | ||||
Bool_t ok(kTRUE); | Bool_t ok(kTRUE); | ||||
messageFromSlave_->ReadUInt( iSlave ); | messageFromTask_->ReadUInt( iTask ); | ||||
messageFromSlave_->ReadBool( ok ); | messageFromTask_->ReadBool( ok ); | ||||
if ( ! ok ) { | if ( ! ok ) { | ||||
std::cerr << "ERROR in LauSimFitMaster::writeOutResults : Slave " << iSlave << " reports an error performing finalisation" << std::endl; | std::cerr << "ERROR in LauSimFitCoordinator::writeOutResults : Task " << iTask << " reports an error performing finalisation" << std::endl; | ||||
allOK = kFALSE; | allOK = kFALSE; | ||||
} | } | ||||
++responsesReceived; | ++responsesReceived; | ||||
} | } | ||||
// Write out our ntuple as well | // Write out our ntuple as well | ||||
if (fitNtuple_ != 0) { | if (fitNtuple_ != 0) { | ||||
fitNtuple_->writeOutFitResults(); | fitNtuple_->writeOutFitResults(); | ||||
} | } | ||||
return allOK; | return allOK; | ||||
} | } | ||||