laura is hosted by Hepforge, IPPP Durham
Laura++  3.6.0
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauSimFitTask.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2015 University of Warwick
4 
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 */
17 
18 /*
19 Laura++ package authors:
20 John Back
21 Paul Harrison
22 Thomas Latham
23 */
24 
29 #include "LauSimFitTask.hh"
30 
31 #include "LauFitNtuple.hh"
32 
33 #include "TMatrixD.h"
34 #include "TMessage.h"
35 #include "TObjArray.h"
36 #include "TObjString.h"
37 #include "TSocket.h"
38 #include "TSystem.h"
39 
40 #include <cstdlib>
41 #include <iostream>
42 
44  socketCoordinator_( 0 ),
45  messageFromCoordinator_( 0 ),
46  taskId_( 0 ),
47  nTasks_( 0 ),
48  parValues_( 0 ),
49  fitNtuple_( 0 )
50 {
51 }
52 
54 {
55  delete socketCoordinator_;
57  delete[] parValues_;
58  delete fitNtuple_;
59 }
60 
61 void LauSimFitTask::runTask( const TString& dataFileName,
62  const TString& dataTreeName,
63  const TString& histFileName,
64  const TString& tableFileName,
65  const TString& addressCoordinator,
66  const UInt_t portCoordinator )
67 {
68  // Establish the connection to the coordinator process
69  this->connectToCoordinator( addressCoordinator, portCoordinator );
70 
71  // Initialise the fit model
72  this->initialise();
73 
74  // NB call to addConParameters() is intentionally not included here cf.
75  // LauAbsFitModel::run() since this has to be dealt with by the coordinator
76  // to avoid multiple inclusions of each penalty term
77  // Print a warning if constraints on combinations of parameters have been specified
78  const auto& storeCon = this->formulaConstraints();
79  if ( ! storeCon.empty() ) {
80  std::cerr << "WARNING in LauSimFitTask::runTask : Constraints have been added but these will be ignored - they should have been added to the coordinator process"
81  << std::endl;
82  }
83 
84  // Setup saving of fit results to ntuple/LaTeX table etc.
85  this->setupResultsOutputs( histFileName, tableFileName );
86 
87  // This reads in the given dataFile and creates an input
88  // fit data tree that stores them for all events and experiments.
89  Bool_t dataOK = this->verifyFitData( dataFileName, dataTreeName );
90  if ( ! dataOK ) {
91  std::cerr << "ERROR in LauSimFitTask::runTask : Problem caching the fit data." << std::endl;
92  return;
93  }
94 
95  // Now process the various requests from the coordinator
97 
98  std::cout << "INFO in LauSimFitTask::runTask : Fit task " << this->taskId()
99  << " has finished successfully" << std::endl;
100 }
101 
102 void LauSimFitTask::setupResultsOutputs( const TString& histFileName,
103  const TString& /*tableFileName*/ )
104 {
105  // Create and setup the fit results ntuple
106  std::cout << "INFO in LauSimFitTask::setupResultsOutputs : Creating fit ntuple." << std::endl;
107  if ( fitNtuple_ != 0 ) {
108  delete fitNtuple_;
109  fitNtuple_ = 0;
110  }
111  fitNtuple_ = new LauFitNtuple( histFileName, this->useAsymmFitErrors() );
112 }
113 
114 void LauSimFitTask::connectToCoordinator( const TString& addressCoordinator,
115  const UInt_t portCoordinator )
116 {
117  if ( socketCoordinator_ != 0 ) {
118  std::cerr << "ERROR in LauSimFitTask::connectToCoordinator : coordinator socket already present"
119  << std::endl;
120  return;
121  }
122 
123  // Open connection to coordinator
124  socketCoordinator_ = new TSocket( addressCoordinator, portCoordinator );
126 
127  messageFromCoordinator_->ReadUInt( taskId_ );
128  messageFromCoordinator_->ReadUInt( nTasks_ );
129 
130  Bool_t useAsymErrs( kFALSE );
131  messageFromCoordinator_->ReadBool( useAsymErrs );
132  this->useAsymmFitErrors( useAsymErrs );
133 
136 
137  std::cout << "INFO in LauSimFitTask::connectToCoordinator : Established connection to coordinator on port "
138  << portCoordinator << std::endl;
139  std::cout << " : We are task " << taskId_ << " of "
140  << nTasks_ << std::endl;
141  if ( useAsymErrs ) {
142  std::cout << " : The fit will determine asymmetric errors"
143  << std::endl;
144  }
145 }
146 
148 {
149  // Listen for requests from the coordinator and act accordingly
150 
151  TMessage messageToCoordinator( kMESS_ANY );
152 
153  while ( kTRUE ) {
154 
156 
157  if ( messageFromCoordinator_->What() == kMESS_STRING ) {
158 
159  TString msgStr;
160  messageFromCoordinator_->ReadTString( msgStr );
161 
162  std::cout << "INFO in LauSimFitTask::processCoordinatorRequests : Received message from coordinator: "
163  << msgStr << std::endl;
164 
165  if ( msgStr == "Send Parameters" ) {
166 
167  // Send the fit parameters
168 
169  TObjArray array;
170  this->prepareInitialParArray( array );
171 
172  // Create array to efficiently exchange parameter values with coordinator
173  if ( parValues_ != 0 ) {
174  delete[] parValues_;
175  parValues_ = 0;
176  }
177  UInt_t nPar = array.GetEntries();
178  parValues_ = new Double_t[nPar];
179 
180  messageToCoordinator.Reset( kMESS_OBJECT );
181  messageToCoordinator.WriteObject( &array );
182  socketCoordinator_->Send( messageToCoordinator );
183 
184  } else if ( msgStr == "Read Expt" ) {
185 
186  // Read the data for this experiment
187  UInt_t iExp( 0 );
188  messageFromCoordinator_->ReadUInt( iExp );
189 
190  this->setCurrentExperiment( iExp );
191 
192  UInt_t nEvents = this->readExperimentData();
193  if ( nEvents < 1 ) {
194  std::cerr << "WARNING in LauSimFitTask::processCoordinatorRequests : Zero events in experiment "
195  << iExp << ", the coordinator should skip this experiment..."
196  << std::endl;
197  }
198 
199  messageToCoordinator.Reset( kMESS_ANY );
200  messageToCoordinator.WriteUInt( taskId_ );
201  messageToCoordinator.WriteUInt( nEvents );
202  socketCoordinator_->Send( messageToCoordinator );
203 
204  } else if ( msgStr == "Cache" ) {
205 
206  // Perform the caching
207 
208  this->cacheInputFitVars();
209 
210  messageToCoordinator.Reset( kMESS_ANY );
211  messageToCoordinator.WriteUInt( taskId_ );
212  messageToCoordinator.WriteBool( kTRUE );
213  socketCoordinator_->Send( messageToCoordinator );
214 
215  } else if ( msgStr == "Asym Error Calc" ) {
216 
217  Bool_t asymErrorCalc( kFALSE );
218  messageFromCoordinator_->ReadBool( asymErrorCalc );
219  this->withinAsymErrorCalc( asymErrorCalc );
220 
221  messageToCoordinator.Reset( kMESS_ANY );
222  messageToCoordinator.WriteUInt( taskId_ );
223  messageToCoordinator.WriteBool( asymErrorCalc );
224  socketCoordinator_->Send( messageToCoordinator );
225 
226  } else if ( msgStr == "Write Results" ) {
227 
228  this->writeOutAllFitResults();
229 
230  messageToCoordinator.Reset( kMESS_ANY );
231  messageToCoordinator.WriteUInt( taskId_ );
232  messageToCoordinator.WriteBool( kTRUE );
233  socketCoordinator_->Send( messageToCoordinator );
234 
235  } else if ( msgStr == "Finish" ) {
236 
237  std::cout << "INFO in LauSimFitTask::processCoordinatorRequests : Message from coordinator to finish"
238  << std::endl;
239 
242 
243  break;
244 
245  } else {
246 
247  std::cerr << "ERROR in LauSimFitTask::processCoordinatorRequests : Unexpected message from coordinator"
248  << std::endl;
249  gSystem->Exit( EXIT_FAILURE );
250  }
251 
252  } else if ( messageFromCoordinator_->What() == kMESS_OBJECT ) {
253 
254  std::cout << "INFO in LauSimFitTask::processCoordinatorRequests : Received message from coordinator: Finalise"
255  << std::endl;
256 
257  Int_t status( 0 );
258  Double_t NLL( 0.0 );
259  Double_t EDM( 0.0 );
260  messageFromCoordinator_->ReadInt( status );
261  messageFromCoordinator_->ReadDouble( NLL );
262  messageFromCoordinator_->ReadDouble( EDM );
263 
264  TObjArray* objarray = dynamic_cast<TObjArray*>(
265  messageFromCoordinator_->ReadObject( messageFromCoordinator_->GetClass() ) );
266  if ( ! objarray ) {
267  std::cerr << "ERROR in LauSimFitTask::processCoordinatorRequests : Error reading parameters from coordinator"
268  << std::endl;
269  gSystem->Exit( EXIT_FAILURE );
270  }
271 
272  TMatrixD* covMat = dynamic_cast<TMatrixD*>(
273  messageFromCoordinator_->ReadObject( messageFromCoordinator_->GetClass() ) );
274  if ( ! covMat ) {
275  std::cerr << "ERROR in LauSimFitTask::processCoordinatorRequests : Error reading covariance matrix from coordinator"
276  << std::endl;
277  gSystem->Exit( EXIT_FAILURE );
278  }
279 
280  TObjArray array;
281  LauAbsFitter::FitStatus fitStat { status, NLL, EDM };
282  this->finaliseExperiment( fitStat, objarray, covMat, array );
283 
284  delete objarray;
285  objarray = 0;
286  delete covMat;
287  covMat = 0;
288 
289  // Send the finalised parameters back to the coordinator
290  messageToCoordinator.Reset( kMESS_ANY );
291  messageToCoordinator.WriteUInt( taskId_ );
292  messageToCoordinator.WriteBool( kTRUE );
293  messageToCoordinator.WriteObject( &array );
294  socketCoordinator_->Send( messageToCoordinator );
295 
296  } else if ( messageFromCoordinator_->What() == kMESS_ANY ) {
297 
298  UInt_t nPars( 0 );
299  UInt_t nFreePars( 0 );
300  messageFromCoordinator_->ReadUInt( nPars );
301  messageFromCoordinator_->ReadUInt( nFreePars );
302 
303  if ( nPars != this->nTotParams() ) {
304  std::cerr << "ERROR in LauSimFitTask::processCoordinatorRequests : Unexpected number of parameters received from coordinator"
305  << std::endl;
306  std::cerr << " : Received " << nPars
307  << " when expecting " << this->nTotParams() << std::endl;
308  gSystem->Exit( EXIT_FAILURE );
309  }
310 
311  messageFromCoordinator_->ReadFastArray( parValues_, nPars );
312 
313  this->setParsFromMinuit( parValues_, nFreePars );
314 
315  Double_t negLogLike = this->getTotNegLogLikelihood();
316 
317  messageToCoordinator.Reset( kMESS_ANY );
318  messageToCoordinator.WriteDouble( negLogLike );
319  socketCoordinator_->Send( messageToCoordinator );
320 
321  } else {
322  std::cerr << "ERROR in LauSimFitTask::processCoordinatorRequests : Unexpected message type"
323  << std::endl;
324  gSystem->Exit( EXIT_FAILURE );
325  }
326 
329  }
330 }
331 
333 {
334  // Write out histograms at end
335  if ( fitNtuple_ != 0 ) {
337  }
338 }
LauSimFitTask()
Constructor.
LauFitNtuple * fitNtuple_
The fit ntuple.
Struct to store fit status information.
Definition: LauAbsFitter.hh:54
virtual void setParsFromMinuit(Double_t *par, Int_t npar)=0
This function sets the parameter values from Minuit.
virtual void runTask(const TString &dataFileName, const TString &dataTreeName, const TString &histFileName, const TString &tableFileName="", const TString &addressCoordinator="localhost", const UInt_t portCoordinator=9090)
Start the task process for simultaneous fitting.
virtual ~LauSimFitTask()
Destructor.
TSocket * socketCoordinator_
A socket to enable parallel setup.
virtual Bool_t verifyFitData(const TString &dataFileName, const TString &dataTreeName)=0
Open the input file and verify that all required variables are present.
UInt_t taskId_
Task id number.
File containing declaration of LauFitNtuple class.
UInt_t nTasks_
The total number of tasks.
Bool_t useAsymmFitErrors() const
Report whether or not calculation of asymmetric errors is enabled.
Definition: LauFitObject.hh:60
virtual void initialise()=0
Initialise the fit model.
virtual UInt_t readExperimentData()=0
Read in the data for the current experiment.
virtual void prepareInitialParArray(TObjArray &array)=0
Package the initial fit parameters for transmission to the coordinator.
const std::vector< FormulaConstraint > & formulaConstraints() const
Const access to the formula constraints store.
virtual Double_t getTotNegLogLikelihood()=0
Calculates the total negative log-likelihood.
Bool_t withinAsymErrorCalc() const
Query whether the fit is calculating the asymmetric errors.
Definition: LauFitObject.hh:94
UInt_t taskId() const
Obtain the ID number of this task.
friend class LauFitNtuple
LauFitNtuple is a friend class.
void processCoordinatorRequests()
Listen for requests from the coordinator and act accordingly.
void writeOutFitResults()
Write out fit results.
virtual void cacheInputFitVars()=0
Cache the input data values to calculate the likelihood during the fit.
virtual void finaliseExperiment(const LauAbsFitter::FitStatus &fitStat, const TObjArray *parsFromCoordinator, const TMatrixD *covMat, TObjArray &parsToCoordinator)=0
Perform all finalisation actions.
Double_t * parValues_
Parameter values array (for reading from the coordinator)
virtual void writeOutAllFitResults()
Write out any fit results.
virtual void setupResultsOutputs(const TString &histFileName, const TString &tableFileName)
Setup saving of fit results to ntuple/LaTeX table etc.
File containing declaration of LauSimFitTask class.
void connectToCoordinator(const TString &addressCoordinator, const UInt_t portCoordinator)
Establish the connection to the coordinator process.
UInt_t nTotParams() const
Access the total number of fit parameters.
void setCurrentExperiment(const UInt_t curExpt)
Set the ID of the current experiment.
TMessage * messageFromCoordinator_
Message from coordinator to the tasks.