laura is hosted by Hepforge, IPPP Durham
Laura++  3.6.0
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauSimFitCoordinator.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2013 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 "LauSimFitCoordinator.hh"
30 
31 #include "LauAbsFitter.hh"
32 #include "LauFitNtuple.hh"
33 #include "LauFitter.hh"
34 #include "LauFormulaPar.hh"
35 #include "LauParamFixed.hh"
36 #include "LauParameter.hh"
37 
38 #include "TMath.h"
39 #include "TMatrixD.h"
40 #include "TMessage.h"
41 #include "TMonitor.h"
42 #include "TObjArray.h"
43 #include "TObjString.h"
44 #include "TServerSocket.h"
45 #include "TSocket.h"
46 #include "TSystem.h"
47 
48 #include <cstdlib>
49 #include <iostream>
50 #include <limits>
51 
52 LauSimFitCoordinator::LauSimFitCoordinator( UInt_t numTasks, UInt_t port ) :
53  nTasks_( numTasks ),
54  reqPort_( port ),
55  socketMonitor_( 0 ),
56  messageFromTask_( 0 ),
57  fitNtuple_( 0 )
58 {
59  messagesToTasks_.resize( nTasks_ );
60  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
61  messagesToTasks_[iTask] = new TMessage();
62  }
63 }
64 
66 {
67  delete socketMonitor_;
68  socketMonitor_ = 0;
69 
70  // Tell all tasks that they are finished and delete corresponding socket
71  TString msgStr( "Finish" );
72  TMessage message( kMESS_STRING );
73  message.WriteTString( msgStr );
74  for ( std::vector<TSocket*>::iterator iter = socketTasks_.begin(); iter != socketTasks_.end();
75  ++iter ) {
76  ( *iter )->Send( message );
77  ( *iter )->Close();
78  delete ( *iter );
79  }
80  socketTasks_.clear();
81 
82  // Remove all fit parameters
83  for ( std::vector<LauParameter*>::iterator iter = params_.begin(); iter != params_.end();
84  ++iter ) {
85  delete *iter;
86  }
87  params_.clear();
88 
89  for ( std::vector<Double_t*>::iterator iter = vectorPar_.begin(); iter != vectorPar_.end();
90  ++iter ) {
91  delete[] ( *iter );
92  }
93  vectorPar_.clear();
94 
95  delete messageFromTask_;
96  messageFromTask_ = 0;
97 
98  for ( std::vector<TMessage*>::iterator iter = messagesToTasks_.begin();
99  iter != messagesToTasks_.end();
100  ++iter ) {
101  delete ( *iter );
102  }
103  messagesToTasks_.clear();
104 
105  delete fitNtuple_;
106 }
107 
109 {
110  if ( socketMonitor_ != 0 ) {
111  std::cerr << "ERROR in LauSimFitCoordinator::initSockets : Sockets already initialised."
112  << std::endl;
113  return;
114  }
115 
116  //initialise socket connection, then accept a connection and return a full-duplex communication socket.
117  socketMonitor_ = new TMonitor();
118 
119  TServerSocket* ss = new TServerSocket( reqPort_, kFALSE );
120  UInt_t actual_port = ss->GetLocalPort();
121 
122  std::cout << "INFO in LauSimFitCoordinator::initSockets : Waiting for connection with "
123  << nTasks_ << " tasks on port " << actual_port << std::endl;
124 
125  socketTasks_.resize( nTasks_ );
126  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
127  socketTasks_[iTask] = ss->Accept();
128  std::cout << " : Added task " << iTask << std::endl;
129  }
130 
131  // tell the clients to start
132  std::cout << "INFO in LauSimFitCoordinator::initSockets : Initialising tasks" << std::endl;
133  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
134 
135  TMessage message( kMESS_ANY );
136  message.WriteUInt( iTask );
137  message.WriteUInt( nTasks_ );
138  message.WriteBool( this->useAsymmFitErrors() );
139 
140  socketTasks_[iTask]->Send( message );
141 
142  socketMonitor_->Add( socketTasks_[iTask] );
143  }
144  std::cout << " : Now start fit\n" << std::endl;
145 
146  ss->Close();
147  delete ss;
148 }
149 
150 /*
151  * 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
152  * 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
153  * 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
154  *
155 void LauSimFitCoordinator::getParametersFromTasksFirstTime()
156 {
157  taskIndices_.resize( nTasks_ );
158 
159  TSocket* sActive(0);
160  for ( UInt_t iTask(0); iTask<nTasks_; ++iTask ) {
161  // Send a message to the task, requesting the list of parameter names
162  TString msgStr = "Parameter Names";
163  TMessage message( kMESS_STRING );
164  message.WriteTString( msgStr );
165  socketTasks_[iTask]->Send(message);
166 
167  // Wait to receive the response and check that it has come from the task we just requested from
168  sActive = socketMonitor_->Select();
169  if ( sActive != socketTasks_[iTask] ) {
170  std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Received message from a different task than expected!" << std::endl;
171  gSystem->Exit(1);
172  }
173 
174  // Read the object and extract the parameter names
175  socketTasks_[iTask]->Recv( messageFromTask_ );
176  TObjArray * objarray = dynamic_cast<TObjArray*>( messageFromTask_->ReadObject( messageFromTask_->GetClass() ) );
177  if ( ! objarray ) {
178  std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Error reading parameter names from task" << std::endl;
179  gSystem->Exit(1);
180  }
181 
182  Int_t nPars = objarray->GetEntries();
183  for ( Int_t iPar(0); iPar < nPars; ++iPar ) {
184  TObjString* objstring = dynamic_cast<TObjString*>( (*objarray)[iPar] );
185  if ( ! objstring ) {
186  std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Error reading parameter names from task" << std::endl;
187  gSystem->Exit(1);
188  }
189  TString parname = objstring->GetString();
190 
191  std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname );
192  if ( iter != parIndices_.end() ) {
193  UInt_t index = iter->second;
194  taskIndices_[iTask].push_back( index );
195  } else {
196  UInt_t index = parIndices_.size();
197  parIndices_.insert( std::make_pair( parname, index ) );
198  parNames_.insert( std::make_pair( index, parname ) );
199  taskIndices_[iTask].push_back( index );
200  }
201  }
202 
203  delete objarray; objarray = 0;
204  delete messageFromTask_; messageFromTask_ = 0;
205  }
206 
207  UInt_t nPars = parNames_.size();
208  parValues_.resize( nPars );
209 }
210 */
211 
213 {
214  if ( socketMonitor_ == 0 ) {
215  std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasks : Sockets not initialised."
216  << std::endl;
217  return;
218  }
219 
220  if ( params_.empty() ) {
222 
223  // Add variables to Gaussian constrain to a list
224  this->addConParameters();
225  } else {
227  }
228 }
229 
231 {
232  TSocket* sActive( 0 );
233 
234  // Construct a message, requesting the list of parameter names
235  TString msgStr = "Send Parameters";
236  TMessage message( kMESS_STRING );
237  message.WriteTString( msgStr );
238 
239  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
240  // Send the message to the task
241  socketTasks_[iTask]->Send( message );
242 
243  // Wait to receive the response and check that it has come from the task we just requested from
244  sActive = socketMonitor_->Select();
245  if ( sActive != socketTasks_[iTask] ) {
246  std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Received message from a different task than expected!"
247  << std::endl;
248  gSystem->Exit( 1 );
249  }
250 
251  // Read the object and extract the parameter names
252  socketTasks_[iTask]->Recv( messageFromTask_ );
253  TObjArray* objarray = dynamic_cast<TObjArray*>(
254  messageFromTask_->ReadObject( messageFromTask_->GetClass() ) );
255  if ( ! objarray ) {
256  std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Error reading parameter names from task"
257  << std::endl;
258  gSystem->Exit( 1 );
259  }
260 
261  // We want to auto-delete the supplied parameters since we only copy their values in this case
262  objarray->SetOwner( kTRUE );
263 
264  const UInt_t nPars = objarray->GetEntries();
265  if ( nPars != taskIndices_[iTask].size() ) {
266  std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Unexpected number of parameters received from task"
267  << std::endl;
268  gSystem->Exit( 1 );
269  }
270 
271  for ( UInt_t iPar( 0 ); iPar < nPars; ++iPar ) {
272  LauParameter* parameter = dynamic_cast<LauParameter*>( ( *objarray )[iPar] );
273  if ( ! parameter ) {
274  std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Error reading parameter from task"
275  << std::endl;
276  gSystem->Exit( 1 );
277  }
278 
279  TString parname = parameter->name();
280  Double_t parvalue = parameter->initValue();
281 
282  std::map<TString, UInt_t>::iterator iter = parIndices_.find( parname );
283  if ( iter == parIndices_.end() ) {
284  std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Unexpected parameter name received from task"
285  << std::endl;
286  gSystem->Exit( 1 );
287  }
288 
289  const UInt_t index = iter->second;
290  if ( taskIndices_[iTask][iPar] != index ) {
291  std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Unexpected parameter received from task"
292  << std::endl;
293  gSystem->Exit( 1 );
294  }
295 
296  params_[index]->initValue( parvalue );
297  parValues_[index] = parvalue;
298  vectorPar_[iTask][iPar] = parvalue;
299  this->checkParameter( parameter, index );
300  }
301 
302  delete objarray;
303  objarray = 0;
304  delete messageFromTask_;
305  messageFromTask_ = 0;
306  }
307 }
308 
310 {
311  taskIndices_.resize( nTasks_ );
312  taskFreeIndices_.resize( nTasks_ );
313  vectorPar_.resize( nTasks_ );
314  vectorRes_.resize( nTasks_ );
315 
316  TSocket* sActive( 0 );
317 
318  // Construct a message, requesting the list of parameter names
319  TString msgStr = "Send Parameters";
320  TMessage message( kMESS_STRING );
321  message.WriteTString( msgStr );
322 
323  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
324  // Send the message to the task
325  socketTasks_[iTask]->Send( message );
326 
327  // Wait to receive the response and check that it has come from the task we just requested from
328  sActive = socketMonitor_->Select();
329  if ( sActive != socketTasks_[iTask] ) {
330  std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Received message from a different task than expected!"
331  << std::endl;
332  gSystem->Exit( 1 );
333  }
334 
335  // Read the object and extract the parameter names
336  socketTasks_[iTask]->Recv( messageFromTask_ );
337  TObjArray* objarray = dynamic_cast<TObjArray*>(
338  messageFromTask_->ReadObject( messageFromTask_->GetClass() ) );
339  if ( ! objarray ) {
340  std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Error reading parameters from task"
341  << std::endl;
342  gSystem->Exit( 1 );
343  }
344 
345  const UInt_t nPars = objarray->GetEntries();
346 
347  vectorPar_[iTask] = new Double_t[nPars];
348 
349  for ( UInt_t iPar( 0 ); iPar < nPars; ++iPar ) {
350  LauParameter* parameter = dynamic_cast<LauParameter*>( ( *objarray )[iPar] );
351  if ( ! parameter ) {
352  std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Error reading parameter from task"
353  << std::endl;
354  gSystem->Exit( 1 );
355  }
356 
357  TString parname = parameter->name();
358  Double_t parvalue = parameter->initValue();
359  Bool_t parfixed = parameter->fixed();
360 
361  std::map<TString, UInt_t>::iterator iter = parIndices_.find( parname );
362  if ( iter != parIndices_.end() ) {
363  UInt_t index = iter->second;
364  taskIndices_[iTask].push_back( index );
365  if ( ! parfixed ) {
366  taskFreeIndices_[iTask].push_back( index );
367  }
368  this->checkParameter( parameter, index );
369  } else {
370  UInt_t index = parIndices_.size();
371  parIndices_.insert( std::make_pair( parname, index ) );
372  parNames_.insert( std::make_pair( index, parname ) );
373  taskIndices_[iTask].push_back( index );
374  if ( ! parfixed ) {
375  taskFreeIndices_[iTask].push_back( index );
376  }
377  params_.push_back( parameter );
378  parValues_.push_back( parvalue );
379  }
380  vectorPar_[iTask][iPar] = parvalue;
381  }
382 
383  delete objarray;
384  objarray = 0;
385  delete messageFromTask_;
386  messageFromTask_ = 0;
387  }
388 }
389 
391 {
392  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
393  const std::vector<UInt_t>& indices = taskIndices_[iTask];
394 
395  std::cout << "INFO in LauSimFitCoordinator::printParInfo : Task " << iTask
396  << " has the following parameters:\n";
397  for ( std::vector<UInt_t>::const_iterator iter = indices.begin(); iter != indices.end();
398  ++iter ) {
399  const TString& parName = parNames_.find( *iter )->second;
400  Double_t parValue = parValues_[*iter];
401  const LauParameter* par = params_[*iter];
402  if ( par->name() != parName || par->initValue() != parValue ) {
403  std::cerr << "ERROR in LauSimFitCoordinator::printParInfo : Discrepancy in parameter name and value records, this is very strange!!"
404  << std::endl;
405  }
406 
407  std::cout << " : " << parName << " = " << parValue
408  << " and has index " << *iter << "\n";
409  }
410 
411  std::cout << std::endl;
412  }
413 
414  std::cout << "INFO in LauSimFitCoordinator::printParInfo : "
415  << "There are " << params_.size() << " parameters in total" << std::endl;
416 }
417 
418 void LauSimFitCoordinator::checkParameter( const LauParameter* param, UInt_t index ) const
419 {
420  const LauParameter* storedPar = params_[index];
421 
422  TString parName = storedPar->name();
423  if ( param->name() != parName ) {
424  std::cerr << "ERROR in LauSimFitCoordinator::checkParameter : Parameter name is different!! This shouldn't happen!!"
425  << std::endl;
426  }
427  if ( param->initValue() != storedPar->initValue() ) {
428  std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Initial value for parameter "
429  << parName
430  << " is different, will use the value first set: " << storedPar->initValue()
431  << std::endl;
432  }
433  if ( param->minValue() != storedPar->minValue() ) {
434  std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Minimum allowed value for parameter "
435  << parName
436  << " is different, will use the value first set: " << storedPar->minValue()
437  << std::endl;
438  }
439  if ( param->maxValue() != storedPar->maxValue() ) {
440  std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Maximum allowed value for parameter "
441  << parName
442  << " is different, will use the value first set: " << storedPar->maxValue()
443  << std::endl;
444  }
445  if ( param->fixed() != storedPar->fixed() ) {
446  std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Fixed/floating property of parameter "
447  << parName << " is different, will use the value first set: "
448  << ( storedPar->fixed() ? "fixed" : "floating" ) << std::endl;
449  }
450  if ( param->secondStage() != storedPar->secondStage() ) {
451  std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Second stage property of parameter "
452  << parName << " is different, will use the value first set: "
453  << ( storedPar->secondStage() ? "true" : "false" ) << std::endl;
454  }
455 }
456 
458 {
459  this->initSockets();
460 }
461 
462 void LauSimFitCoordinator::runSimFit( const TString& fitNtupleFileName,
463  const Bool_t useAsymmErrors,
464  const Bool_t doTwoStageFit )
465 {
466  // Routine to perform the total fit.
467 
468  // First, initialise
469  this->useAsymmFitErrors( useAsymmErrors );
470  this->twoStageFit( doTwoStageFit );
471  this->initialise();
472 
473  const UInt_t nExp { this->nExpt() };
474  const UInt_t firstExp { this->firstExpt() };
475  const Bool_t isToy { this->toyExpts() };
476 
477  std::cout << "INFO in LauSimFitCoordinator::runSimFit : First experiment = " << firstExp
478  << std::endl;
479  std::cout << "INFO in LauSimFitCoordinator::runSimFit : Number of experiments = " << nExp
480  << std::endl;
481  std::cout << "INFO in LauSimFitCoordinator::runSimFit : Is toy MC = "
482  << ( isToy ? "True" : "False" ) << std::endl;
483 
484  // Start the cumulative timer
485  cumulTimer_.Start();
486 
487  this->resetFitCounters();
488 
489  // Create and setup the fit results ntuple
490  std::cout << "INFO in LauSimFitCoordinator::runSimFit : Creating fit ntuple." << std::endl;
491  if ( fitNtuple_ != 0 ) {
492  delete fitNtuple_;
493  fitNtuple_ = 0;
494  }
495  fitNtuple_ = new LauFitNtuple( fitNtupleFileName, useAsymmErrors );
496 
497  // Loop over the number of experiments
498  for ( UInt_t iExp = firstExp; iExp < ( firstExp + nExp ); ++iExp ) {
499 
500  // Start the timer to see how long each fit takes
501  timer_.Start();
502 
503  this->setCurrentExperiment( iExp );
504 
505  // Instruct the tasks to read the data for this experiment
506  Bool_t readOK = this->readData();
507  if ( ! readOK ) {
508  std::cerr << "ERROR in LauSimFitCoordinator::runSimFit : One or more tasks reported problems with reading data for experiment "
509  << iExp << ", skipping..." << std::endl;
510  timer_.Stop();
511  continue;
512  }
513 
514  // Instruct the tasks to perform the caching
515  this->cacheInputData();
516 
517  // Do the fit
518  this->fitExpt();
519 
520  // Stop the timer and see how long the program took so far
521  timer_.Stop();
522  timer_.Print();
523 
524  // Instruct the tasks to finalise the results
525  this->finalise();
526  }
527 
528  // Print out total timing info.
529  std::cout << "INFO in LauSimFitCoordinator::runSimFit : Cumulative timing:" << std::endl;
530  cumulTimer_.Stop();
531  cumulTimer_.Print();
532 
533  // Print out stats on OK fits.
534  const UInt_t nOKFits = this->numberOKFits();
535  const UInt_t nBadFits = this->numberBadFits();
536  std::cout << "INFO in LauSimFitCoordinator::runSimFit : Number of OK Fits = " << nOKFits
537  << std::endl;
538  std::cout << "INFO in LauSimFitCoordinator::runSimFit : Number of Failed Fits = " << nBadFits
539  << std::endl;
540  Double_t fitEff( 0.0 );
541  if ( nExp != 0 ) {
542  fitEff = nOKFits / ( 1.0 * nExp );
543  }
544  std::cout << "INFO in LauSimFitCoordinator::runSimFit : Fit efficiency = " << fitEff * 100.0
545  << "%." << std::endl;
546 
547  // Instruct the tasks to write out any fit results (ntuples etc...).
548  this->writeOutResults();
549 }
550 
551 void LauSimFitCoordinator::withinAsymErrorCalc( const Bool_t inAsymErrCalc )
552 {
553  this->LauFitObject::withinAsymErrorCalc( inAsymErrCalc );
554 
555  if ( socketMonitor_ == 0 ) {
556  std::cerr << "ERROR in LauSimFitCoordinator::withinAsymErrorCalc : Sockets not initialised."
557  << std::endl;
558  return;
559  }
560 
561  // Construct a message, informing the tasks whether or not we are now within the asymmetric error calculation
562  TString msgStr( "Asym Error Calc" );
563  const Bool_t asymErrorCalc( this->withinAsymErrorCalc() );
564  TMessage message( kMESS_STRING );
565  message.WriteTString( msgStr );
566  message.WriteBool( asymErrorCalc );
567 
568  // Send the message to the tasks
569  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
570  socketTasks_[iTask]->Send( message );
571  }
572 
573  TSocket* sActive( 0 );
574  UInt_t responsesReceived( 0 );
575  while ( responsesReceived != nTasks_ ) {
576 
577  // Get the next queued response
578  sActive = socketMonitor_->Select();
579 
580  // Extract from the message the ID of the task and the number of events read
581  Bool_t response( kTRUE );
582  UInt_t iTask( 0 );
583  sActive->Recv( messageFromTask_ );
584  messageFromTask_->ReadUInt( iTask );
585  messageFromTask_->ReadBool( response );
586 
587  if ( response != asymErrorCalc ) {
588  std::cerr << "WARNING in LauSimFitCoordinator::withinAsymErrorCalc : Problem informing task "
589  << iTask << std::endl;
590  }
591 
592  ++responsesReceived;
593  }
594 }
595 
597 {
598  if ( socketMonitor_ == 0 ) {
599  std::cerr << "ERROR in LauSimFitCoordinator::readData : Sockets not initialised."
600  << std::endl;
601  return kFALSE;
602  }
603 
604  // Construct a message, requesting to read the data for the given experiment
605  TString msgStr( "Read Expt" );
606  const UInt_t iExp( this->iExpt() );
607  TMessage message( kMESS_STRING );
608  message.WriteTString( msgStr );
609  message.WriteUInt( iExp );
610 
611  // Send the message to the tasks
612  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
613  socketTasks_[iTask]->Send( message );
614  }
615 
616  TSocket* sActive( 0 );
617  UInt_t responsesReceived( 0 );
618  Bool_t ok( kTRUE );
619  while ( responsesReceived != nTasks_ ) {
620 
621  // Get the next queued response
622  sActive = socketMonitor_->Select();
623 
624  // Extract from the message the ID of the task and the number of events read
625  sActive->Recv( messageFromTask_ );
626  UInt_t iTask( 0 );
627  UInt_t nEvents( 0 );
628  messageFromTask_->ReadUInt( iTask );
629  messageFromTask_->ReadUInt( nEvents );
630 
631  if ( nEvents <= 0 ) {
632  std::cerr << "ERROR in LauSimFitCoordinator::readData : Task " << iTask
633  << " reports no events found for experiment " << iExp << std::endl;
634  ok = kFALSE;
635  } else {
636  std::cerr << "INFO in LauSimFitCoordinator::readData : Task " << iTask << " reports "
637  << nEvents << " events found for experiment " << iExp << std::endl;
638  }
639 
640  ++responsesReceived;
641  }
642 
643  return ok;
644 }
645 
647 {
648  if ( socketMonitor_ == 0 ) {
649  std::cerr << "ERROR in LauSimFitCoordinator::cacheInputData : Sockets not initialised."
650  << std::endl;
651  return kFALSE;
652  }
653 
654  // Construct a message, requesting it to read the data for the given experiment
655  TString msgStr( "Cache" );
656  TMessage message( kMESS_STRING );
657  message.WriteTString( msgStr );
658 
659  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
660  // Send the message to the task
661  socketTasks_[iTask]->Send( message );
662  }
663 
664  TSocket* sActive( 0 );
665  UInt_t responsesReceived( 0 );
666  Bool_t allOK( kTRUE );
667  while ( responsesReceived != nTasks_ ) {
668 
669  // Get the next queued response
670  sActive = socketMonitor_->Select();
671 
672  // Extract from the message the ID of the task and the success/failure flag
673  sActive->Recv( messageFromTask_ );
674  UInt_t iTask( 0 );
675  Bool_t ok( kTRUE );
676  messageFromTask_->ReadUInt( iTask );
677  messageFromTask_->ReadBool( ok );
678 
679  if ( ! ok ) {
680  std::cerr << "ERROR in LauSimFitCoordinator::cacheInputData : Task " << iTask
681  << " reports an error performing caching" << std::endl;
682  allOK = kFALSE;
683  }
684 
685  ++responsesReceived;
686  }
687 
688  return allOK;
689 }
690 
692 {
693  this->getParametersFromTasks();
694  this->printParInfo();
695 }
696 
698 {
699  // Routine to perform the actual fit for the given experiment
700 
701  // Instruct the tasks to update initial fit parameters if required (e.g. if using random numbers).
702  this->checkInitFitParams();
703 
704  // If we're fitting toy experiments then re-generate the means of any constraints
706 
707  // Initialise the fitter
711 
712  this->startNewFit( LauFitter::fitter().nParameters(), LauFitter::fitter().nFreeParameters() );
713 
714  // Now ready for minimisation step
715  std::cout << "\nINFO in LauSimFitCoordinator::fitExpt : Start minimisation...\n";
717 
718  // If we're doing a two stage fit we can now release (i.e. float)
719  // the 2nd stage parameters and re-fit
720  if ( this->twoStageFit() ) {
721  if ( fitResult.status != 3 ) {
722  std::cerr << "ERROR in LauSimFitCoordinator:fitExpt : Not running second stage fit since first stage failed."
723  << std::endl;
725  } else {
727  this->startNewFit( LauFitter::fitter().nParameters(),
728  LauFitter::fitter().nFreeParameters() );
729  fitResult = LauFitter::fitter().minimise();
730  }
731  }
732 
733  const TMatrixD& covMat = LauFitter::fitter().covarianceMatrix();
734  this->storeFitStatus( fitResult, covMat );
735 
736  // Store the final fit results and errors into protected internal vectors that
737  // all sub-classes can use within their own finalFitResults implementation
738  // used below (e.g. putting them into an ntuple in a root file)
740 }
741 
742 void LauSimFitCoordinator::setParsFromMinuit( Double_t* par, Int_t npar )
743 {
744  // This function sets the internal parameters based on the values
745  // that Minuit is using when trying to minimise the total likelihood function.
746 
747  // MINOS reports different numbers of free parameters depending on the
748  // situation, so disable this check
749  if ( ! this->withinAsymErrorCalc() ) {
750  const UInt_t nFreePars = this->nFreeParams();
751  if ( static_cast<UInt_t>( npar ) != nFreePars ) {
752  std::cerr << "ERROR in LauSimFitCoordinator::setParsFromMinuit : Unexpected number of free parameters: "
753  << npar << ".\n";
754  std::cerr << " Expected: " << nFreePars
755  << ".\n"
756  << std::endl;
757  gSystem->Exit( EXIT_FAILURE );
758  }
759  }
760 
761  // Despite npar being the number of free parameters
762  // the par array actually contains all the parameters,
763  // free and floating...
764  // Update all the parameters with their new values.
765  // Change the value in the array to be sent out to the tasks and the
766  // parameters themselves (so that constraints are correctly calculated)
767  for ( UInt_t i( 0 ); i < this->nTotParams(); ++i ) {
768  if ( ! params_[i]->fixed() ) {
769  parValues_[i] = par[i];
770  params_[i]->value( par[i] );
771  }
772  }
773 }
774 
776 {
777  if ( socketMonitor_ == 0 ) {
778  std::cerr << "ERROR in LauSimFitCoordinator::getTotNegLogLikelihood : Sockets not initialised."
779  << std::endl;
780  return 0.0;
781  }
782 
783  // Send current values of the parameters to the tasks.
784  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
785 
786  std::vector<UInt_t>& indices = taskIndices_[iTask];
787  std::vector<UInt_t>& freeIndices = taskFreeIndices_[iTask];
788  UInt_t nPars = indices.size();
789  UInt_t nFreePars = freeIndices.size();
790  for ( UInt_t iPar( 0 ); iPar < nPars; ++iPar ) {
791  vectorPar_[iTask][iPar] = parValues_[indices[iPar]];
792  }
793 
794  TMessage* message = messagesToTasks_[iTask];
795  message->Reset( kMESS_ANY );
796  message->WriteUInt( nPars );
797  message->WriteUInt( nFreePars );
798  message->WriteFastArray( vectorPar_[iTask], nPars );
799 
800  socketTasks_[iTask]->Send( *message );
801  }
802 
803  Double_t negLogLike( 0.0 );
804  TSocket* sActive( 0 );
805  UInt_t responsesReceived( 0 );
806  Bool_t allOK( kTRUE );
807  while ( responsesReceived != nTasks_ ) {
808 
809  sActive = socketMonitor_->Select();
810  sActive->Recv( messageFromTask_ );
811 
812  messageFromTask_->ReadDouble( vectorRes_[responsesReceived] );
813 
814  Double_t& nLL = vectorRes_[responsesReceived];
815  if ( nLL == 0.0 || TMath::IsNaN( nLL ) || ! TMath::Finite( nLL ) ) {
816  allOK = kFALSE;
817  }
818 
819  negLogLike += vectorRes_[responsesReceived];
820 
821  ++responsesReceived;
822  }
823 
824  // Calculate any penalty terms from Gaussian constrained variables
825  const auto& multiDimCons = this->multiDimConstraints();
826  if ( ! conVars_.empty() || ! multiDimCons.empty() ) {
827  negLogLike += this->getLogLikelihoodPenalty();
828  }
829 
830  const Double_t worstNegLogLike = -1.0 * this->worstLogLike();
831  if ( ! allOK ) {
832  std::cerr << "WARNING in LauSimFitCoordinator::getTotNegLogLikelihood : Strange NLL value returned by one or more tasks\n";
833  std::cerr << " : Returning worst NLL found so far to force MINUIT out of this region."
834  << std::endl;
835  negLogLike = worstNegLogLike;
836  } else if ( negLogLike > worstNegLogLike ) {
837  this->worstLogLike( -negLogLike );
838  }
839 
840  return negLogLike;
841 }
842 
844 {
845  Double_t penalty { 0.0 };
846 
847  for ( LauAbsRValue* par : conVars_ ) {
848  penalty += par->constraintPenalty();
849  }
850 
851  auto& multiDimCons = this->multiDimConstraints();
852  for ( auto& constraint : multiDimCons ) {
853  penalty += constraint.constraintPenalty();
854  }
855 
856  return penalty;
857 }
858 
860 {
861  // Add penalties from the constraints to fit parameters
862 
863  // First, constraints on the fit parameters themselves
864  for ( LauParameter* param : params_ ) {
865  if ( param->gaussConstraint() ) {
866  conVars_.push_back( param );
867  std::cout << "INFO in LauSimFitCoordinator::addConParameters : Added Gaussian constraint to parameter "
868  << param->name() << std::endl;
869  }
870  }
871 
872  // Second, constraints on arbitrary combinations
873  auto& conStore = this->formulaConstraints();
874  for ( auto& constraint : conStore ) {
875  std::vector<LauParameter*> params;
876  for ( const auto& name : constraint.conPars_ ) {
877  for ( LauParameter* par : params_ ) {
878  if ( par->name() == name ) {
879  params.push_back( par );
880  }
881  }
882  }
883 
884  // If the parameters are not found, skip it
885  if ( params.size() != constraint.conPars_.size() ) {
886  std::cerr << "WARNING in LauSimFitCoordinator::addConParameters: Could not find parameters to constrain in the formula... skipping"
887  << std::endl;
888  continue;
889  }
890 
891  constraint.formulaPar_ =
892  std::make_unique<LauFormulaPar>( constraint.formula_, constraint.formula_, params );
893  constraint.formulaPar_->addGaussianConstraint( constraint.mean_, constraint.width_ );
894 
895  conVars_.push_back( constraint.formulaPar_.get() );
896 
897  std::cout << "INFO in LauSimFitCoordinator::addConParameters : Added Gaussian constraint to formula\n";
898  std::cout << " : Formula: "
899  << constraint.formula_ << std::endl;
900  for ( LauParameter* param : params ) {
901  std::cout << " : Parameter: "
902  << param->name() << std::endl;
903  }
904  }
905 
906  // Thirdly, add n-dimensional constraints
907  auto& multiDimCons = this->multiDimConstraints();
908  for ( auto& constraint : multiDimCons ) {
909  for ( auto& parname : constraint.conPars_ ) {
910  for ( auto& fitPar : params_ ) {
911  if ( parname == fitPar->name() ) {
912  // Check parameters do not have a 1D Gaussian constraint applied
913  if ( fitPar->gaussConstraint() ) {
914  std::cerr << "ERROR in LauSimFitCoordinator::addConParameters: parameter in n-dimensional constraint already has a 1d constraint applied"
915  << std::endl;
916  gSystem->Exit( EXIT_FAILURE );
917  }
918  constraint.conLauPars_.push_back( fitPar );
919  }
920  }
921  }
922  if ( constraint.conLauPars_.size() != constraint.conPars_.size() ) {
923  std::cerr << "Error in LauSimFitCoordinator::addConParameters : Could not match parameter names for n-dimensional constraint"
924  << std::endl;
925  gSystem->Exit( EXIT_FAILURE );
926  }
927  }
928 }
929 
931 {
932  if ( socketMonitor_ == 0 ) {
933  std::cerr << "ERROR in LauSimFitCoordinator::finalise : Sockets not initialised."
934  << std::endl;
935  return kFALSE;
936  }
937 
938  // Prepare the covariance matrices
939  const TMatrixD& covMatrix = this->covarianceMatrix();
940  covMatrices_.resize( nTasks_ );
941 
942  LauParamFixed pred;
943 
944  std::map<UInt_t, UInt_t> freeParIndices;
945 
946  UInt_t counter( 0 );
947  for ( UInt_t iPar( 0 ); iPar < this->nTotParams(); ++iPar ) {
948  const LauParameter* par = params_[iPar];
949  if ( ! pred( par ) ) {
950  freeParIndices.insert( std::make_pair( iPar, counter ) );
951  ++counter;
952  }
953  }
954 
955  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
956  const UInt_t nPar = taskIndices_[iTask].size();
957 
958  std::vector<UInt_t> freeIndices;
959  freeIndices.reserve( nPar );
960 
961  for ( UInt_t iPar( 0 ); iPar < nPar; ++iPar ) {
962  UInt_t index = taskIndices_[iTask][iPar];
963  std::map<UInt_t, UInt_t>::iterator freeIter = freeParIndices.find( index );
964  if ( freeIter == freeParIndices.end() ) {
965  continue;
966  }
967  UInt_t freeIndex = freeIter->second;
968  freeIndices.push_back( freeIndex );
969  }
970 
971  const UInt_t nFreePars = freeIndices.size();
972  TMatrixD& covMat = covMatrices_[iTask];
973  covMat.ResizeTo( nFreePars, nFreePars );
974 
975  for ( UInt_t iPar( 0 ); iPar < nFreePars; ++iPar ) {
976  for ( UInt_t jPar( 0 ); jPar < nFreePars; ++jPar ) {
977  UInt_t i = freeIndices[iPar];
978  UInt_t j = freeIndices[jPar];
979  covMat( iPar, jPar ) = covMatrix( i, j );
980  }
981  }
982  }
983 
984  // The array to hold the parameters
985  TObjArray array;
986 
987  // Send messages to all tasks containing the final parameters and fit status, NLL
988  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
989 
990  array.Clear();
991 
992  std::vector<UInt_t>& indices = taskIndices_[iTask];
993  UInt_t nPars = indices.size();
994  for ( UInt_t iPar( 0 ); iPar < nPars; ++iPar ) {
995  array.Add( params_[indices[iPar]] );
996  }
997 
998  const Int_t status = this->statusCode();
999  const Double_t NLL = this->nll();
1000  const Double_t EDM = this->edm();
1001  TMatrixD& covMat = covMatrices_[iTask];
1002 
1003  TMessage* message = messagesToTasks_[iTask];
1004  message->Reset( kMESS_OBJECT );
1005  message->WriteInt( status );
1006  message->WriteDouble( NLL );
1007  message->WriteDouble( EDM );
1008  message->WriteObject( &array );
1009  message->WriteObject( &covMat );
1010 
1011  socketTasks_[iTask]->Send( *message );
1012  }
1013 
1014  TSocket* sActive( 0 );
1015  UInt_t responsesReceived( 0 );
1016  Bool_t allOK( kTRUE );
1017  while ( responsesReceived != nTasks_ ) {
1018 
1019  // Get the next queued response
1020  sActive = socketMonitor_->Select();
1021 
1022  // Extract from the message the ID of the task and the number of events read
1023  sActive->Recv( messageFromTask_ );
1024  UInt_t iTask( 0 );
1025  Bool_t ok( kTRUE );
1026  messageFromTask_->ReadUInt( iTask );
1027  messageFromTask_->ReadBool( ok );
1028 
1029  if ( ok ) {
1030  TObjArray* objarray = dynamic_cast<TObjArray*>(
1031  messageFromTask_->ReadObject( messageFromTask_->GetClass() ) );
1032  if ( ! objarray ) {
1033  std::cerr << "ERROR in LauSimFitCoordinator::finalise : Error reading finalised parameters from task"
1034  << std::endl;
1035  allOK = kFALSE;
1036  } else {
1037  // We want to auto-delete the supplied parameters since we only copy their values in this case
1038  objarray->SetOwner( kTRUE );
1039 
1040  const UInt_t nPars = objarray->GetEntries();
1041  if ( nPars != taskIndices_[iTask].size() ) {
1042  std::cerr << "ERROR in LauSimFitCoordinator::finalise : Unexpected number of finalised parameters received from task"
1043  << std::endl;
1044  allOK = kFALSE;
1045  } else {
1046  for ( UInt_t iPar( 0 ); iPar < nPars; ++iPar ) {
1047  LauParameter* parameter = dynamic_cast<LauParameter*>( ( *objarray )[iPar] );
1048  if ( ! parameter ) {
1049  std::cerr
1050  << "ERROR in LauSimFitCoordinator::finalise : Error reading parameter from task"
1051  << std::endl;
1052  allOK = kFALSE;
1053  continue;
1054  }
1055 
1056  TString parname = parameter->name();
1057 
1058  std::map<TString, UInt_t>::iterator iter = parIndices_.find( parname );
1059  if ( iter == parIndices_.end() ) {
1060  std::cerr
1061  << "ERROR in LauSimFitCoordinator::finalise : Unexpected parameter name received from task"
1062  << std::endl;
1063  allOK = kFALSE;
1064  continue;
1065  }
1066 
1067  const UInt_t index = iter->second;
1068  if ( taskIndices_[iTask][iPar] != index ) {
1069  std::cerr
1070  << "ERROR in LauSimFitCoordinator::finalise : Unexpected parameter received from task"
1071  << std::endl;
1072  allOK = kFALSE;
1073  continue;
1074  }
1075 
1076  Double_t parvalue = parameter->value();
1077  params_[index]->value( parvalue );
1078  parValues_[index] = parvalue;
1079  vectorPar_[iTask][iPar] = parvalue;
1080  }
1081  }
1082  delete objarray;
1083  }
1084  } else {
1085  std::cerr << "ERROR in LauSimFitCoordinator::finalise : Task " << iTask
1086  << " reports an error performing finalisation" << std::endl;
1087  allOK = kFALSE;
1088  }
1089 
1090  ++responsesReceived;
1091  }
1092 
1093  // Fill our ntuple as well
1094  if ( fitNtuple_ != 0 ) {
1095  for ( std::vector<LauParameter*>::iterator iter = params_.begin(); iter != params_.end();
1096  ++iter ) {
1097  if ( ! ( *iter )->fixed() ) {
1098  ( *iter )->updatePull();
1099  }
1100  }
1102  fitNtuple_->storeCorrMatrix( this->iExpt(), this->fitStatus(), this->covarianceMatrix() );
1104  }
1105 
1106  return allOK;
1107 }
1108 
1110 {
1111  if ( socketMonitor_ == 0 ) {
1112  std::cerr << "ERROR in LauSimFitCoordinator::writeOutResults : Sockets not initialised."
1113  << std::endl;
1114  return kFALSE;
1115  }
1116 
1117  // Construct a message, requesting to write out the fit results
1118  TString msgStr( "Write Results" );
1119  TMessage message( kMESS_STRING );
1120  message.WriteTString( msgStr );
1121 
1122  // Send the message to the tasks
1123  for ( UInt_t iTask( 0 ); iTask < nTasks_; ++iTask ) {
1124  socketTasks_[iTask]->Send( message );
1125  }
1126 
1127  TSocket* sActive( 0 );
1128  UInt_t responsesReceived( 0 );
1129  Bool_t allOK( kTRUE );
1130  while ( responsesReceived != nTasks_ ) {
1131 
1132  // Get the next queued response
1133  sActive = socketMonitor_->Select();
1134 
1135  // Extract from the message the ID of the task and the number of events read
1136  sActive->Recv( messageFromTask_ );
1137  UInt_t iTask( 0 );
1138  Bool_t ok( kTRUE );
1139  messageFromTask_->ReadUInt( iTask );
1140  messageFromTask_->ReadBool( ok );
1141 
1142  if ( ! ok ) {
1143  std::cerr << "ERROR in LauSimFitCoordinator::writeOutResults : Task " << iTask
1144  << " reports an error performing finalisation" << std::endl;
1145  allOK = kFALSE;
1146  }
1147 
1148  ++responsesReceived;
1149  }
1150 
1151  // Write out our ntuple as well
1152  if ( fitNtuple_ != 0 ) {
1154  }
1155 
1156  return allOK;
1157 }
void fitExpt()
Perform the fit for the current experiment.
Bool_t finalise()
Return the final parameters to the tasks and instruct them to perform their finalisation.
virtual void setParsFromMinuit(Double_t *par, Int_t npar)
This function sets the parameter values from Minuit.
UInt_t numberOKFits() const
Access the number of successful fits.
File containing declaration of LauFitter class.
Class for defining the fit parameter objects.
Definition: LauParameter.hh:49
Struct to store fit status information.
Definition: LauAbsFitter.hh:54
std::vector< TMatrixD > covMatrices_
The covariance sub-matrices for each task.
Double_t value() const
The value of the parameter.
File containing declaration of LauAbsFitter class.
std::vector< Double_t > parValues_
Parameter values.
UInt_t firstExpt() const
Obtain the number of the first experiment.
void printParInfo() const
Print information on the parameters.
Bool_t toyExpts() const
Obtain whether this is toy.
File containing declaration of LauParamFixed class.
std::vector< std::vector< UInt_t > > taskFreeIndices_
Lists of indices of free parameters for each task.
const UInt_t reqPort_
The requested port.
File containing declaration of LauParameter class.
File containing declaration of LauFitNtuple class.
TStopwatch timer_
The fit timer.
Bool_t useAsymmFitErrors() const
Report whether or not calculation of asymmetric errors is enabled.
Definition: LauFitObject.hh:60
std::vector< LauParameter * > params_
Parameters.
Bool_t readData()
Instruct the tasks to read the input data for the given experiment.
static LauAbsFitter & fitter()
Method that provides access to the singleton fitter.
Definition: LauFitter.cc:75
void storeFitStatus(const LauAbsFitter::FitStatus &status, const TMatrixD &covMatrix)
Store fit status information.
Definition: LauFitObject.cc:93
UInt_t numberBadFits() const
Access the number of failed fits.
const std::set< TString > & multiDimConstrainedPars() const
Const access to the parameter names used in ND constraints.
Double_t minValue() const
The minimum value allowed for the parameter.
void resetFitCounters()
Reset the good/bad fit counters.
Definition: LauFitObject.cc:76
virtual Bool_t useAsymmFitErrors() const =0
Determine whether calculation of asymmetric errors is enabled.
const std::vector< MultiDimConstraint > & multiDimConstraints() const
Const access to the ND constraints store.
std::vector< std::vector< UInt_t > > taskIndices_
Lists of indices for each task.
void initSockets()
Initialise socket connections for the tasks.
void getParametersFromTasksFirstTime()
Determine the parameter names and initial values from all tasks.
void storeCorrMatrix(const UInt_t iExpt, const LauAbsFitter::FitStatus &fitStatus, const TMatrixD &covMatrix)
Store the correlation matrix and other fit information.
Definition: LauFitNtuple.cc:76
std::vector< LauAbsRValue * > conVars_
Gaussian constraints.
const LauAbsFitter::FitStatus & fitStatus() const
Access the fit status information.
Bool_t secondStage() const
Check whether the parameter should be floated only in the second stage of a two stage fit.
virtual Bool_t twoStageFit() const =0
Determine whether the two-stage fit is enabled.
Bool_t cacheInputData()
Instruct the tasks to perform the caching.
void generateConstraintMeans(std::vector< LauAbsRValue * > &conVars)
Generate per-experiment mean for each Gaussian constraint.
TMessage * messageFromTask_
Message from tasks to the coordinator.
virtual const FitStatus & minimise()=0
Perform the minimisation of the fit function.
const std::vector< FormulaConstraint > & formulaConstraints() const
Const access to the formula constraints store.
virtual const TMatrixD & covarianceMatrix() const =0
Retrieve the fit covariance matrix.
Bool_t withinAsymErrorCalc() const
Query whether the fit is calculating the asymmetric errors.
Definition: LauFitObject.hh:94
void getParametersFromTasks()
Determine/update the parameter initial values from all tasks.
UInt_t iExpt() const
Obtain the number of the current experiment.
virtual ~LauSimFitCoordinator()
Destructor.
LauSimFitCoordinator(UInt_t numTasks, UInt_t port=9090)
Constructor.
Double_t maxValue() const
The maximum value allowed for the parameter.
friend class LauFitNtuple
LauFitNtuple is a friend class.
void addConParameters()
Add parameters to the list of Gaussian constrained parameters.
Int_t statusCode() const
Access the fit status code.
void writeOutFitResults()
Write out fit results.
Bool_t fixed() const
Check whether the parameter is fixed or floated.
std::vector< Double_t * > vectorPar_
Parameter values to send to the tasks.
void checkParameter(const LauParameter *param, UInt_t index) const
Check for compatibility between two same-named parameters, which should therefore be identical.
std::vector< Double_t > vectorRes_
Likelihood values returned from the tasks.
Pure abstract base class for defining a parameter containing an R value.
Definition: LauAbsRValue.hh:45
void runSimFit(const TString &fitNtupleFileName, const Bool_t useAsymmErrors=kFALSE, const Bool_t doTwoStageFit=kFALSE)
Run the fit.
const TString & name() const
The parameter name.
Double_t edm() const
Access the current EDM value.
TStopwatch cumulTimer_
The total fit timer.
Predicate to allow counting of the number of fixed parameters.
TMonitor * socketMonitor_
Parallel setup monitor.
void startNewFit(const UInt_t nPars, const UInt_t nFreePars)
Indicate the start of a new fit.
Definition: LauFitObject.cc:83
LauFitNtuple * fitNtuple_
The fit results ntuple.
void storeParsAndErrors(const std::vector< LauParameter * > &fitVars, const std::set< TString > &constrainedVars, const std::vector< LauParameter > &extraVars)
Store parameters and their errors.
virtual Double_t getTotNegLogLikelihood()
Calculate the new value of the negative log likelihood.
const TMatrixD & covarianceMatrix() const
Access the fit covariance matrix.
void checkInitFitParams()
Instruct the tasks to update the initial fit parameter values, if required.
UInt_t nExpt() const
Obtain the number of experiments.
void updateParametersFromTasks()
Update and verify the parameter initial values from all tasks.
const UInt_t nTasks_
The number of tasks.
std::vector< TMessage * > messagesToTasks_
Messages to tasks.
Double_t getLogLikelihoodPenalty()
Calculate the penalty terms to the log likelihood from Gaussian constraints.
virtual void initialise(LauFitObject *fitObj, const std::vector< LauParameter * > &parameters)=0
Initialise the fitter, setting the information on the parameters.
Double_t nll() const
Access the current NLL value.
void updateFitNtuple()
Update the fit ntuple.
UInt_t nTotParams() const
Access the total number of fit parameters.
Bool_t twoStageFit() const
Report whether the two-stage fit is enabled.
Definition: LauFitObject.hh:76
Int_t status
The status code of the fit.
Definition: LauAbsFitter.hh:56
File containing declaration of LauFormulaPar class.
std::vector< TSocket * > socketTasks_
Sockets for each of the tasks.
std::map< UInt_t, TString > parNames_
Reverse map of index in the values vector to parameter names.
File containing declaration of LauSimFitCoordinator class.
void initialise()
Initialise.
Double_t initValue() const
The initial value of the parameter.
void setCurrentExperiment(const UInt_t curExpt)
Set the ID of the current experiment.
Bool_t writeOutResults()
Instruct the tasks to write out the fit results.
virtual void releaseSecondStageParameters()=0
Release parameters marked as "second stage".
std::map< TString, UInt_t > parIndices_
Map of parameter names to index in the values vector.
virtual void updateParameters()=0
Update the values and errors of the parameters based on the fit minimum.
Double_t worstLogLike() const
Access the worst log likelihood found so far.
UInt_t nFreeParams() const
Access the total number of fit parameters.