laura is hosted by Hepforge, IPPP Durham
Laura++  3.6.0
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauSPlot.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2006 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 
33 /**********************************************************************
34  * *
35  * Copyright (c) 2005 ROOT Foundation, CERN/PH-SFT *
36  * *
37  **********************************************************************/
38 
39 #include <cfloat>
40 #include <iostream>
41 #include <vector>
42 using std::cerr;
43 using std::cout;
44 using std::endl;
45 
46 #include "LauSPlot.hh"
47 
48 #include "TEventList.h"
49 #include "TFile.h"
50 #include "TLeaf.h"
51 #include "TMath.h"
52 #include "TObjArray.h"
53 #include "TSystem.h"
54 #include "TTree.h"
55 #include "TVirtualFitter.h"
56 
57 extern void Yields( Int_t&, Double_t*, Double_t& f, Double_t* x, Int_t iflag );
58 
59 LauSPlot::LauSPlot( const TString& fileName,
60  const TString& treeName,
61  Int_t firstExpt,
62  Int_t nExpt,
63  const NameSet& variableNames,
64  const NumbMap& freeSpecies,
65  const NumbMap& fixdSpecies,
66  const TwoDMap& twodimPDFs,
67  Bool_t sigSplit,
68  Bool_t scfDPSmeared ) :
69  fileName_( fileName ),
70  inputTreeName_( treeName ),
71  cnTreeName_( "" ),
72  sweightTreeName_( "" ),
73  file_( 0 ),
74  inputTree_( 0 ),
75  cnTree_( 0 ),
76  sweightTree_( 0 ),
77  eventList_( 0 ),
78  variableNames_( variableNames ),
79  freeSpecies_( freeSpecies ),
80  fixdSpecies_( fixdSpecies ),
81  origFreeSpecies_( freeSpecies ),
82  origFixdSpecies_( fixdSpecies ),
83  twodimPDFs_( twodimPDFs ),
84  signalSplit_( sigSplit ),
85  scfDPSmear_( scfDPSmeared ),
86  readInput_( kFALSE ),
87  definedCNBranches_( kFALSE ),
88  definedSWeightBranches_( kFALSE ),
89  firstExpt_( firstExpt ),
90  nExpt_( nExpt ),
91  iExpt_( 0 ),
92  nEvents_( 0 ),
93  nDiscVars_( variableNames.size() ),
94  nFreeSpecies_( freeSpecies.size() ),
95  nFixdSpecies_( fixdSpecies.size() ),
96  nSpecies_( freeSpecies.size() + fixdSpecies.size() )
97 {
98  this->openInputFileAndTree();
99  this->readInputInfo();
100  this->createSWeightTree();
101  if ( nFixdSpecies_ > 0 ) {
102  this->createCNTree();
103  }
104 }
105 
107 {
108  // seems that closing the file deletes the tree
109  // so only delete if the file is still open
110  if ( file_ && file_->IsOpen() ) {
111  delete inputTree_;
112  inputTree_ = 0;
113  delete sweightTree_;
114  sweightTree_ = 0;
115  delete cnTree_;
116  cnTree_ = 0;
117  }
118  delete file_;
119  file_ = 0;
120 }
121 
123 {
124  // first check whether we've already opened up the file or not
125  if ( ! file_ ) {
126  // if not, first check the filename and if all ok create the file
127  if ( fileName_ == "" ) {
128  cerr << "ERROR in LauSPlot::createFileAndTree : Bad filename supplied, not creating file or tree."
129  << endl;
130  return;
131  }
132  file_ = TFile::Open( fileName_, "update" );
133  if ( ! file_ || file_->IsZombie() || ! file_->IsWritable() ) {
134  cerr << "ERROR in LauSPlot::createFileAndTree : Problem opening file \"" << fileName_
135  << "\" for updating, can't do anything." << endl;
136  return;
137  }
138  }
139  // next open the input tree for reading
140  if ( ! inputTree_ ) {
141  file_->cd();
142  inputTree_ = dynamic_cast<TTree*>( file_->Get( inputTreeName_ ) );
143  inputTree_->SetDirectory( file_ );
144  }
145 }
146 
148 {
149  // Read the tree and then setup the maps so we know which leaves to
150  // read from the tree to get the various PDF values
151 
152  Bool_t inputOK = this->readInputLeaves();
153  if ( ! inputOK ) {
154  this->readInput( inputOK );
155  return;
156  }
157 
158  inputOK = this->checkLeaves();
159  this->readInput( inputOK );
160  return;
161 }
162 
164 {
165  // Read all the leaves in the tree and store them in the leaves map
166 
167  if ( ! inputTree_ ) {
168  cerr << "ERROR in LauSPlot::readInputInfo : Invalid pointer to data tree." << endl;
169  return kFALSE;
170  }
171 
172  Int_t nBranches = inputTree_ ? static_cast<Int_t>( inputTree_->GetNbranches() ) : 0;
173  TObjArray* pLeaves = inputTree_->GetListOfLeaves();
174  if ( ! pLeaves ) {
175  cerr << "ERROR in LauSPlot::readInputInfo : Problem retrieving leaves from the tree." << endl;
176  return kFALSE;
177  }
178  TObjArray& leaves = *pLeaves;
179 
180  if ( nBranches > leaves.GetSize() ) {
181  cerr << "ERROR in LauSPlot::readInputInfo : List of leaves is smaller than number of branches - this is strange!"
182  << endl;
183  return kFALSE;
184  }
185 
186  for ( Int_t iLeaf = 0; iLeaf < nBranches; ++iLeaf ) {
187 
188  TLeaf* leaf = dynamic_cast<TLeaf*>( leaves[iLeaf] );
189 
190  // we can't deal with arrays
191  Int_t size = leaf->GetNdata();
192  if ( size != 1 ) {
193  cerr << "ERROR in LauSPlot::readInputInfo : Tree has array branches, can't deal with those."
194  << endl;
195  return kFALSE;
196  }
197 
198  // find the name of the leaf
199  TString name = leaf->GetName();
200 
201  // initialise an entry in the maps to hold the value
202  leaves_[name] = leaf;
203  }
204 
205  return kTRUE;
206 }
207 
208 Bool_t LauSPlot::checkLeaves() const
209 {
210  // Analyse the names of the leaves to check that we have a leaf for
211  // all bits of information we require, i.e. a likelihood value for
212  // each combination of variable and species
213 
214  // If we have 2D PDFs then we have to look for some extra leaves
215  for ( TwoDMap::const_iterator twodim_iter = twodimPDFs_.begin(); twodim_iter != twodimPDFs_.end();
216  ++twodim_iter ) {
217 
218  const TString& specName = twodim_iter->first;
219  const TString& firstVarName = twodim_iter->second.first;
220  const TString& secondVarName = twodim_iter->second.second;
221 
222  TString expectedName( specName );
223  expectedName += firstVarName;
224  expectedName += secondVarName;
225  expectedName += "Like";
226 
227  Bool_t found( kFALSE );
228  for ( LeafMap::const_iterator leaf_iter = leaves_.begin(); leaf_iter != leaves_.end();
229  ++leaf_iter ) {
230  const TString& leafName = leaf_iter->first;
231  const TLeaf* leaf = leaf_iter->second;
232 
233  if ( ( leafName == expectedName ) && ( leaf != 0 ) ) {
234  found = kTRUE;
235  break;
236  }
237  }
238 
239  if ( ! found ) {
240  cerr << "ERROR in LauSPlot::checkLeaves : Could not find expected leaf \""
241  << expectedName << "\"." << endl;
242  return kFALSE;
243  }
244  }
245 
246  // Search for all other "standard" leaves, i.e. <species><var>Like
247 
248  for ( NumbMap::const_iterator fixd_iter = fixdSpecies_.begin(); fixd_iter != fixdSpecies_.end();
249  ++fixd_iter ) {
250 
251  const TString& specName = fixd_iter->first;
252 
253  // if the signal is split we need to do a dedicated search
254  // for sigTM and sigSCF, so skip the signal here
255  if ( specName == "sig" && this->signalSplit() ) {
256  continue;
257  }
258 
259  for ( NameSet::const_iterator vars_iter = variableNames_.begin();
260  vars_iter != variableNames_.end();
261  ++vars_iter ) {
262  const TString& varName = ( *vars_iter );
263  TString expectedName( specName );
264  expectedName += varName;
265  expectedName += "Like";
266  Bool_t found( kFALSE );
267  for ( LeafMap::const_iterator leaf_iter = leaves_.begin(); leaf_iter != leaves_.end();
268  ++leaf_iter ) {
269  const TString& leafName = leaf_iter->first;
270  const TLeaf* leaf = leaf_iter->second;
271 
272  if ( ( leafName == expectedName ) && ( leaf != 0 ) ) {
273  found = kTRUE;
274  break;
275  }
276  }
277 
278  if ( ! found ) {
279  cerr << "ERROR in LauSPlot::checkLeaves : Could not find expected leaf \""
280  << expectedName << "\"." << endl;
281  return kFALSE;
282  }
283  }
284  }
285 
286  for ( NumbMap::const_iterator free_iter = freeSpecies_.begin(); free_iter != freeSpecies_.end();
287  ++free_iter ) {
288 
289  const TString& specName = free_iter->first;
290 
291  // if the signal is split we need to do a dedicated search
292  // for sigTM and sigSCF, so skip the signal here
293  if ( specName == "sig" && this->signalSplit() ) {
294  continue;
295  }
296 
297  for ( NameSet::const_iterator vars_iter = variableNames_.begin();
298  vars_iter != variableNames_.end();
299  ++vars_iter ) {
300  const TString& varName = ( *vars_iter );
301  TString expectedName( specName );
302  expectedName += varName;
303  expectedName += "Like";
304  Bool_t found( kFALSE );
305  for ( LeafMap::const_iterator leaf_iter = leaves_.begin(); leaf_iter != leaves_.end();
306  ++leaf_iter ) {
307  const TString& leafName = leaf_iter->first;
308  const TLeaf* leaf = leaf_iter->second;
309 
310  if ( ( leafName == expectedName ) && ( leaf != 0 ) ) {
311  found = kTRUE;
312  break;
313  }
314  }
315 
316  if ( ! found ) {
317  cerr << "ERROR in LauSPlot::checkLeaves : Could not find expected leaf \""
318  << expectedName << "\"." << endl;
319  return kFALSE;
320  }
321  }
322  }
323 
324  if ( this->signalSplit() ) {
325 
326  // now need to search for the sigTM and sigSCF leaves
327 
328  for ( NameSet::const_iterator vars_iter = variableNames_.begin();
329  vars_iter != variableNames_.end();
330  ++vars_iter ) {
331  const TString& varName = ( *vars_iter );
332  TString expectedName( "sigTM" );
333  expectedName += varName;
334  expectedName += "Like";
335  Bool_t found( kFALSE );
336  for ( LeafMap::const_iterator leaf_iter = leaves_.begin(); leaf_iter != leaves_.end();
337  ++leaf_iter ) {
338  const TString& leafName = leaf_iter->first;
339  const TLeaf* leaf = leaf_iter->second;
340 
341  if ( ( leafName == expectedName ) && ( leaf != 0 ) ) {
342  found = kTRUE;
343  break;
344  }
345  }
346 
347  if ( ! found ) {
348  cerr << "ERROR in LauSPlot::checkLeaves : Could not find expected leaf \""
349  << expectedName << "\"." << endl;
350  return kFALSE;
351  }
352 
353  expectedName = "sigSCF";
354  expectedName += varName;
355  expectedName += "Like";
356  found = kFALSE;
357  for ( LeafMap::const_iterator leaf_iter = leaves_.begin(); leaf_iter != leaves_.end();
358  ++leaf_iter ) {
359  const TString& leafName = leaf_iter->first;
360  const TLeaf* leaf = leaf_iter->second;
361 
362  if ( ( leafName == expectedName ) && ( leaf != 0 ) ) {
363  found = kTRUE;
364  break;
365  }
366  }
367 
368  if ( ! found ) {
369  cerr << "ERROR in LauSPlot::checkLeaves : Could not find expected leaf \""
370  << expectedName << "\"." << endl;
371  return kFALSE;
372  }
373 
374  expectedName = "sigSCFFrac";
375  found = kFALSE;
376  for ( LeafMap::const_iterator leaf_iter = leaves_.begin(); leaf_iter != leaves_.end();
377  ++leaf_iter ) {
378  const TString& leafName = leaf_iter->first;
379  const TLeaf* leaf = leaf_iter->second;
380 
381  if ( ( leafName == expectedName ) && ( leaf != 0 ) ) {
382  found = kTRUE;
383  break;
384  }
385  }
386 
387  if ( ! found ) {
388  cerr << "ERROR in LauSPlot::checkLeaves : Could not find expected leaf \""
389  << expectedName << "\"." << endl;
390  return kFALSE;
391  }
392  }
393  }
394 
395  return kTRUE;
396 }
397 
399 {
400  // check whether we've already created the tree
401  if ( ! cnTree_ ) {
402  // if not change to the file's directory and create the tree
404  cnTreeName_ += "_cNCoeffs";
405  file_->cd();
406  cnTree_ = new TTree( cnTreeName_, cnTreeName_ );
407  cnTree_->SetDirectory( file_ );
408  this->definedCNBranches( kFALSE );
409  }
410 }
411 
413 {
414  // check whether we've already created the tree
415  if ( ! sweightTree_ ) {
416  // if not change to the file's directory and create the tree
418  sweightTreeName_ += "_sWeights";
419  file_->cd();
421  sweightTree_->SetDirectory( file_ );
422  this->definedSWeightBranches( kFALSE );
423  }
424 }
425 
427 {
428  if ( this->definedCNBranches() ) {
429  cerr << "ERROR in LauSPlot::defineCNBranches : Already defined branches, not doing it again."
430  << endl;
431  return;
432  }
433  if ( cN_.empty() ) {
434  cerr << "ERROR in LauSPlot::defineCNBranches : No entries in the cN container, can't define branches."
435  << endl;
436  return;
437  }
438  if ( ! cnTree_ ) {
439  cerr << "ERROR in LauSPlot::defineCNBranches : Invalid pointer to the tree, can't define branches."
440  << endl;
441  return;
442  }
443 
444  // In the cN tree there is one entry per experiment, so need to know the experiment number.
445  cnTree_->Branch( "iExpt", &iExpt_, "iExpt/I" );
446 
447  for ( std::map<TString, NumbMap>::iterator excl_iter = cN_.begin(); excl_iter != cN_.end();
448  ++excl_iter ) {
449  const TString& exclName = excl_iter->first;
450  NumbMap& species = excl_iter->second;
451  for ( NumbMap::iterator spec_iter = species.begin(); spec_iter != species.end();
452  ++spec_iter ) {
453  const TString& specName = spec_iter->first;
454  Double_t* pointer = &( spec_iter->second );
455  TString name( specName );
456  name += "_cN";
457  if ( exclName == "none" ) {
458  name += "_all";
459  } else {
460  name += "_no";
461  name += exclName;
462  }
463  TString thirdPart( name );
464  thirdPart += "/D";
465  cnTree_->Branch( name, pointer, thirdPart );
466  }
467  }
468  this->definedCNBranches( kTRUE );
469 }
470 
472 {
473  if ( this->definedSWeightBranches() ) {
474  cerr << "ERROR in LauSPlot::defineSWeightBranches : Already defined branches, not doing it again."
475  << endl;
476  return;
477  }
478  if ( sWeights_.empty() ) {
479  cerr << "ERROR in LauSPlot::defineSWeightBranches : No entries in the sWeights container, can't define branches."
480  << endl;
481  return;
482  }
483  if ( ! sweightTree_ ) {
484  cerr << "ERROR in LauSPlot::defineSWeightBranches : Invalid pointer to the tree, can't define branches."
485  << endl;
486  return;
487  }
488 
489  for ( std::map<TString, NumbMap>::iterator excl_iter = sWeightsCurrent_.begin();
490  excl_iter != sWeightsCurrent_.end();
491  ++excl_iter ) {
492  const TString& exclName = excl_iter->first;
493  NumbMap& species = excl_iter->second;
494  for ( NumbMap::iterator spec_iter = species.begin(); spec_iter != species.end();
495  ++spec_iter ) {
496  const TString& specName = spec_iter->first;
497  Double_t* pointer = &( spec_iter->second );
498  TString name( specName );
499  name += "_sWeight";
500  if ( exclName == "none" ) {
501  name += "_all";
502  } else {
503  name += "_no";
504  name += exclName;
505  }
506  TString thirdPart( name );
507  thirdPart += "/D";
508  sweightTree_->Branch( name, pointer, thirdPart );
509  }
510  }
511  this->definedSWeightBranches( kTRUE );
512 }
513 
514 void LauSPlot::setExperiment( Int_t iExpt )
515 {
516  if ( ! inputTree_ ) {
517  cerr << "ERROR in LauSPlot::setExperiment : Invalid pointer to data tree." << endl;
518  return;
519  }
520 
521  // create the event list if we haven't already done so
522  if ( ! eventList_ ) {
523  eventList_ = new TEventList( "splotelist", "splotelist" );
524  eventList_->SetDirectory( file_ );
525  }
526 
527  // fill the event list with this experiment's events
528  TString listName( eventList_->GetName() );
529  listName.Prepend( ">>" );
530  TString selection( "iExpt==" );
531  selection += iExpt;
532  cout << "LauSPlot::setExperiment : Setting tree to experiment number " << iExpt << "." << endl;
533  inputTree_->Draw( listName, selection );
534 
535  // find how many events there are
536  nEvents_ = eventList_->GetN();
537  cout << " Found " << nEvents_ << " events." << endl;
538 
539  // make sure we have enough space in the per-event value vectors
540  pdfTot_.clear();
541  pdfTot_.resize( nEvents_ );
542  discPdf_.clear();
543  discPdf_.resize( nEvents_ );
544  scfFrac_.clear();
545  scfFrac_.resize( nEvents_ );
546  sWeights_.clear();
547  sWeights_.resize( nEvents_ );
548 
549  // read the info for this experiment
550  this->readExpt();
551 }
552 
554 {
555  for ( Int_t iEvt( 0 ); iEvt < nEvents_; ++iEvt ) {
556  // Find which entry from the full tree contains the requested event
557  Long64_t iEntry = eventList_ ? eventList_->GetEntry( iEvt ) : iEvt;
558  if ( iEntry < 0 ) { // this shouldn't happen, but just in case...
559  cerr << "ERROR in LauSPlot::readExpt : Problem retrieving event." << endl;
560  gSystem->Exit( EXIT_FAILURE );
561  }
562 
563  // Then retrieve that entry from the tree
564  inputTree_->GetEntry( iEntry );
565 
566  // If needed retrieve the SCF fraction values
567  if ( this->signalSplit() ) {
568  for ( LeafMap::const_iterator leaf_iter = leaves_.begin(); leaf_iter != leaves_.end();
569  ++leaf_iter ) {
570  const TString& leafName = leaf_iter->first;
571  const TLeaf* leaf = leaf_iter->second;
572  if ( ( leafName == "sigSCFFrac" ) && ( leaf != 0 ) ) {
573  scfFrac_[iEvt] = leaf->GetValue();
574  break;
575  }
576  }
577  }
578 
579  // Copy the leaf values into discPdf_
580  for ( TwoDMap::const_iterator twodim_iter = twodimPDFs_.begin();
581  twodim_iter != twodimPDFs_.end();
582  ++twodim_iter ) {
583  const TString& specName = twodim_iter->first;
584  const TString& firstVarName = twodim_iter->second.first;
585  const TString& secondVarName = twodim_iter->second.second;
586 
587  TString varName = firstVarName + secondVarName;
588 
589  TString expectedName( specName );
590  expectedName += varName;
591  expectedName += "Like";
592 
593  for ( LeafMap::const_iterator leaf_iter = leaves_.begin(); leaf_iter != leaves_.end();
594  ++leaf_iter ) {
595  const TString& leafName = leaf_iter->first;
596  const TLeaf* leaf = leaf_iter->second;
597  if ( ( leafName == expectedName ) && ( leaf != 0 ) ) {
598  discPdf_[iEvt][specName][varName] = leaf->GetValue();
599  break;
600  }
601  }
602  }
603 
604  Bool_t needSignalSearch( kFALSE );
605  for ( NumbMap::const_iterator fixd_iter = fixdSpecies_.begin();
606  fixd_iter != fixdSpecies_.end();
607  ++fixd_iter ) {
608  const TString& specName = fixd_iter->first;
609 
610  // if the signal is split we need to do a dedicated search
611  // for sigTM and sigSCF, so skip the signal here
612  if ( specName == "sig" && this->signalSplit() ) {
613  needSignalSearch = kTRUE;
614  continue;
615  }
616 
617  for ( NameSet::const_iterator vars_iter = variableNames_.begin();
618  vars_iter != variableNames_.end();
619  ++vars_iter ) {
620  const TString& varName = ( *vars_iter );
621  TString expectedName( specName );
622  expectedName += varName;
623  expectedName += "Like";
624  for ( LeafMap::const_iterator leaf_iter = leaves_.begin(); leaf_iter != leaves_.end();
625  ++leaf_iter ) {
626  const TString& leafName = leaf_iter->first;
627  const TLeaf* leaf = leaf_iter->second;
628  if ( ( leafName == expectedName ) && ( leaf != 0 ) ) {
629  discPdf_[iEvt][specName][varName] = leaf->GetValue();
630  break;
631  }
632  }
633  }
634  }
635 
636  for ( NumbMap::const_iterator free_iter = freeSpecies_.begin();
637  free_iter != freeSpecies_.end();
638  ++free_iter ) {
639  const TString& specName = free_iter->first;
640 
641  // if the signal is split we need to do a dedicated search
642  // for sigTM and sigSCF, so skip the signal here
643  if ( specName == "sig" && this->signalSplit() ) {
644  needSignalSearch = kTRUE;
645  continue;
646  }
647 
648  for ( NameSet::const_iterator vars_iter = variableNames_.begin();
649  vars_iter != variableNames_.end();
650  ++vars_iter ) {
651  const TString& varName = ( *vars_iter );
652  TString expectedName( specName );
653  expectedName += varName;
654  expectedName += "Like";
655  for ( LeafMap::const_iterator leaf_iter = leaves_.begin(); leaf_iter != leaves_.end();
656  ++leaf_iter ) {
657  const TString& leafName = leaf_iter->first;
658  const TLeaf* leaf = leaf_iter->second;
659  if ( ( leafName == expectedName ) && ( leaf != 0 ) ) {
660  discPdf_[iEvt][specName][varName] = leaf->GetValue();
661  break;
662  }
663  }
664  }
665  }
666 
667  if ( needSignalSearch ) {
668  for ( NameSet::const_iterator vars_iter = variableNames_.begin();
669  vars_iter != variableNames_.end();
670  ++vars_iter ) {
671  const TString& varName = ( *vars_iter );
672  TString specName( "sigTM" );
673  TString expectedName( specName );
674  expectedName += varName;
675  expectedName += "Like";
676  for ( LeafMap::const_iterator leaf_iter = leaves_.begin(); leaf_iter != leaves_.end();
677  ++leaf_iter ) {
678  const TString& leafName = leaf_iter->first;
679  const TLeaf* leaf = leaf_iter->second;
680  if ( ( leafName == expectedName ) && ( leaf != 0 ) ) {
681  discPdf_[iEvt][specName][varName] = leaf->GetValue();
682  break;
683  }
684  }
685  specName = "sigSCF";
686  expectedName = specName;
687  expectedName += varName;
688  expectedName += "Like";
689  for ( LeafMap::const_iterator leaf_iter = leaves_.begin(); leaf_iter != leaves_.end();
690  ++leaf_iter ) {
691  const TString& leafName = leaf_iter->first;
692  const TLeaf* leaf = leaf_iter->second;
693  if ( ( leafName == expectedName ) && ( leaf != 0 ) ) {
694  discPdf_[iEvt][specName][varName] = leaf->GetValue();
695  break;
696  }
697  }
698  }
699  }
700  }
701 }
702 
703 void LauSPlot::runCalculations( const TString& option )
704 {
705  // Calculates the sWeights and cN coeffs
706  // The option controls the print level:
707  // "Q" - no print out (default)
708  // "V" - prints the estimated # of events in species
709  // "VV" - as "V" + the MINUIT printing + sums of weights for control
710 
711  if ( ! this->readInput() ) {
712  cerr << "ERROR in LauSPlot::runCalculations : The input ntuple has not been successfully read, can't calculate anything."
713  << endl;
714  return;
715  }
716 
717  if ( freeSpecies_.empty() ) {
718  cerr << "ERROR in LauSPlot::runCalculations : Numbers of events in species have not been set."
719  << endl;
720  return;
721  }
722 
723  TString opt( option );
724  opt.ToUpper();
725  opt.ReplaceAll( "VV", "W" );
726 
727  // Make sure that global fitter is MINUIT
728  this->checkFitter();
729 
730  // Loop over experiments
731  for ( iExpt_ = firstExpt_; iExpt_ < ( firstExpt_ + nExpt_ ); ++iExpt_ ) {
732 
733  this->setExperiment( iExpt_ );
734 
735  if ( nEvents_ < 1 ) {
736  cerr << "ERROR in LauSPlot::runCalculations : Zero events in experiment " << iExpt_
737  << ", skipping..." << endl;
738  continue;
739  }
740 
741  // Now loop over the PDFs to exclude, including the case where none are to be excluded.
742  NameSet excludePdf;
743  if ( variableNames_.size() < 2 ) {
744  excludePdf.insert( "none" );
745  } else {
746  excludePdf = variableNames_;
747  excludePdf.insert( "none" );
748  }
749 
750  for ( NameSet::const_iterator excl_iter = excludePdf.begin(); excl_iter != excludePdf.end();
751  ++excl_iter ) {
752 
753  const TString& exclName = ( *excl_iter );
754 
755  cout << "LauSPlot::runCalculations : Calculating sWeights, excluding PDF: " << exclName
756  << "." << endl;
757 
758  // Calculate the per-event total PDF values for each species.
759  this->calcTotPDFValues( exclName );
760 
761  // Reset the fitter
762  this->initialiseFitter( opt );
763 
764  // Set the parameters to their initial values
765  this->setFitParameters();
766 
767  // Run the fit
768  this->runFit();
769 
770  // Get the fitted parameter values back
771  this->retrieveFittedParameters( opt );
772 
773  // Get the covariance matrix
774  Bool_t covMatOK = this->calcCovMatrix();
775  Double_t* covmat( 0 );
776  if ( ! covMatOK ) {
777  TVirtualFitter* fitter = TVirtualFitter::GetFitter();
778  covmat = fitter->GetCovarianceMatrix();
779  }
780  if ( opt.Contains( "W" ) ) {
781  this->printCovMatrixElements( covmat );
782  }
783 
784  // calculate the cN and sWeights from the covariance matrix
785  if ( nFixdSpecies_ > 0 ) {
786  this->calcCNCoeffs( exclName, covmat );
787  }
788  this->calcSWeights( exclName, covmat );
789 
790  // print verbose info if required
791  if ( opt.Contains( "W" ) ) {
792  this->printSumOfWeights( exclName );
793  }
794  }
795 
796  // Finally fill all the branches for this experiment
797  if ( nFixdSpecies_ > 0 ) {
798  this->fillCNBranches();
799  }
800  this->fillSWeightBranches();
801  }
802 }
803 
805 {
806  TString minuitName( "TFitter" );
807  TVirtualFitter* fitter = TVirtualFitter::GetFitter();
808  if ( fitter ) {
809  TString fitterName( fitter->IsA()->GetName() );
810  if ( fitterName != minuitName ) {
811  delete fitter;
812  fitter = 0;
813  }
814  }
815  fitter = TVirtualFitter::Fitter( 0 );
816 }
817 
818 void LauSPlot::initialiseFitter( const TString& opt )
819 {
820  TVirtualFitter* fitter = TVirtualFitter::GetFitter();
821  fitter->Clear();
822  fitter->SetFCN( Yields );
823  fitter->SetObjectFit( this );
824 
825  // Set the print level
826  Double_t arglist[10];
827  if ( opt.Contains( "Q" ) ) {
828  arglist[0] = -1;
829  }
830  if ( opt.Contains( "V" ) ) {
831  arglist[0] = 0;
832  }
833  if ( opt.Contains( "W" ) ) {
834  arglist[0] = 1;
835  }
836  fitter->ExecuteCommand( "SET PRINT", arglist, 1 );
837 
838  // Need to set the "SET ERR" command to +0.5 for +/-1 sigma errors
839  // for maximum likelihood fit.
840  arglist[0] = 0.5;
841  fitter->ExecuteCommand( "SET ERR", arglist, 1 );
842 }
843 
845 {
846  TVirtualFitter* fitter = TVirtualFitter::GetFitter();
847 
848  // must add the parameters in the same order as they are stored in pdfTot_
849  Int_t ispecies( 0 );
850  const NumbMap& species = pdfTot_.front();
851 
852  for ( NumbMap::const_iterator spec_iter = species.begin(); spec_iter != species.end();
853  ++spec_iter ) {
854  const TString& name( spec_iter->first );
855 
856  // starting parameters should be the original values,
857  // not those that came out of the last fit
858  NumbMap::const_iterator free_iter = origFreeSpecies_.find( name );
859  NumbMap::const_iterator fixd_iter = origFixdSpecies_.find( name );
860  Bool_t fixed = fixd_iter != origFixdSpecies_.end();
861 
862  Double_t value( 0.0 );
863  if ( fixed ) {
864  value = fixd_iter->second;
865  } else {
866  value = free_iter->second;
867  }
868  fitter->SetParameter( ispecies, name, value, 1, 0, 0 );
869  if ( fixed ) {
870  fitter->FixParameter( ispecies );
871  }
872  ++ispecies;
873  }
874 }
875 
877 {
878  TVirtualFitter* fitter = TVirtualFitter::GetFitter();
879 
880  Double_t arglist[10];
881  arglist[0] = 1000 * nFreeSpecies_; // maximum iterations
882  arglist[1] = 0.05; // tolerance : min EDM = 0.001*tolerance
883 
884  // Execute MIGRAD
885  Int_t fitStatus = fitter->ExecuteCommand( "MIGRAD", arglist, 2 );
886 
887  if ( fitStatus != 0 ) {
888  cerr << "ERROR in LauSPlot::runFit : Error during MIGRAD minimisation." << endl;
889  } else {
890  // Execute HESSE
891  fitStatus = fitter->ExecuteCommand( "HESSE", arglist, 1 );
892  if ( fitStatus != 0 ) {
893  cerr << "ERROR in LauSPlot::runFit : Error during HESSE error calculation." << endl;
894  }
895  }
896 }
897 
898 void LauSPlot::printCovMatrixElements( const Double_t* covmat ) const
899 {
900  Int_t a( 0 );
901  cout << endl;
902  for ( NumbMap::const_iterator iter_a = freeSpecies_.begin(); iter_a != freeSpecies_.end();
903  ++iter_a ) {
904  Int_t b( 0 );
905  for ( NumbMap::const_iterator iter_b = freeSpecies_.begin(); iter_b != freeSpecies_.end();
906  ++iter_b ) {
907  if ( covmat ) {
908  cout << "CovMat Elem: [" << iter_a->first << "," << iter_b->first
909  << "] = " << covmat[a * nSpecies_ + b] << endl;
910  } else {
911  cout << "CovMat Elem: [" << iter_a->first << "," << iter_b->first
912  << "] = " << covMat_( a, b ) << endl;
913  }
914  ++b;
915  }
916  ++a;
917  }
918  cout << endl;
919 
920  if ( ! covmat ) {
921  covMat_.Print();
922  }
923 }
924 
925 void LauSPlot::retrieveFittedParameters( const TString& opt )
926 {
927  TVirtualFitter* fitter = TVirtualFitter::GetFitter();
928 
929  // remember fit parameters are in same order as in pdfTot_
930  Int_t ispecies( 0 );
931  const NumbMap& species = pdfTot_.front();
932 
933  for ( NumbMap::const_iterator spec_iter = species.begin(); spec_iter != species.end();
934  ++spec_iter ) {
935  const TString& name( spec_iter->first );
936  NumbMap::iterator free_iter = freeSpecies_.find( name );
937  if ( free_iter != freeSpecies_.end() ) {
938  free_iter->second = fitter->GetParameter( ispecies );
939  if ( ! opt.Contains( "Q" ) ) {
940  cout << "Estimated # of events in species " << name << " = " << free_iter->second
941  << endl;
942  }
943  }
944  ++ispecies;
945  }
946  if ( ! opt.Contains( "Q" ) ) {
947  cout << endl;
948  }
949 }
950 
951 void LauSPlot::printSumOfWeights( const TString& exclName ) const
952 {
953  for ( NumbMap::const_iterator spec_iter = freeSpecies_.begin(); spec_iter != freeSpecies_.end();
954  ++spec_iter ) {
955  const TString& specName = spec_iter->first;
956  Double_t sumweight( 0.0 );
957  for ( Int_t iEvt( 0 ); iEvt < nEvents_; ++iEvt ) {
958  const NumbMap& specWeightMap = sWeights_[iEvt].find( exclName )->second;
959  Double_t weight = specWeightMap.find( specName )->second;
960  sumweight += weight;
961  }
962  cout << "Sum of sWeights for species \"" << specName << "\" = " << sumweight << endl;
963  }
964  cout << endl;
965 }
966 
968 {
969  // Calculate our inverse covariance matrix from the various PDFs
970 
971  TMatrixD invMatrix( nFreeSpecies_, nFreeSpecies_ );
972 
973  // First calculate the denominator, which is common to all elements
974  std::vector<Double_t> denominator( nEvents_ );
975  for ( Int_t iEvt( 0 ); iEvt < nEvents_; ++iEvt ) {
976  denominator[iEvt] = 0.0;
977  for ( NumbMap::const_iterator spec_iter = freeSpecies_.begin();
978  spec_iter != freeSpecies_.end();
979  ++spec_iter ) {
980  const TString& specName = spec_iter->first;
981  Double_t specNumEvents = spec_iter->second;
982  denominator[iEvt] += specNumEvents * pdfTot_[iEvt][specName];
983  }
984  for ( NumbMap::const_iterator spec_iter = fixdSpecies_.begin();
985  spec_iter != fixdSpecies_.end();
986  ++spec_iter ) {
987  const TString& specName = spec_iter->first;
988  Double_t specNumEvents = spec_iter->second;
989  denominator[iEvt] += specNumEvents * pdfTot_[iEvt][specName];
990  }
991  // Square to get the final denominator
992  denominator[iEvt] *= denominator[iEvt];
993  }
994 
995  // Then calculate each element
996  Int_t i( 0 );
997  for ( NumbMap::const_iterator spec_iter_i = freeSpecies_.begin();
998  spec_iter_i != freeSpecies_.end();
999  ++spec_iter_i ) {
1000  const TString& specName_i = spec_iter_i->first;
1001  Int_t j( 0 );
1002  for ( NumbMap::const_iterator spec_iter_j = freeSpecies_.begin();
1003  spec_iter_j != freeSpecies_.end();
1004  ++spec_iter_j ) {
1005  const TString& specName_j = spec_iter_j->first;
1006  invMatrix( i, j ) = 0.0;
1007  for ( Int_t iEvt( 0 ); iEvt < nEvents_; ++iEvt ) {
1008  Double_t numerator = pdfTot_[iEvt][specName_i] * pdfTot_[iEvt][specName_j];
1009  invMatrix( i, j ) += numerator / denominator[iEvt];
1010  }
1011  ++j;
1012  }
1013  ++i;
1014  }
1015 
1016  // Check for a singular matrix
1017  if ( invMatrix.Determinant() < 1e-15 ) {
1018  cerr << "ERROR in LauSPlot::calcCovMatrix : Calculated inverse covariance matrix is singular, can't invert it."
1019  << endl;
1020  return kFALSE;
1021  }
1022 
1023  // Invert and store in the covariance matrix
1024  covMat_.ResizeTo( nFreeSpecies_, nFreeSpecies_ );
1025  covMat_ = TMatrixD( TMatrixD::kInverted, invMatrix );
1026 
1027  return kTRUE;
1028 }
1029 
1030 void LauSPlot::calcTotPDFValues( const TString& exclName )
1031 {
1032  for ( Int_t iEvt( 0 ); iEvt < nEvents_; iEvt++ ) {
1033 
1034  Bool_t needSignalSearch( kFALSE );
1035 
1036  for ( NumbMap::const_iterator spec_iter = fixdSpecies_.begin();
1037  spec_iter != fixdSpecies_.end();
1038  ++spec_iter ) {
1039  const TString& specName = spec_iter->first;
1040 
1041  // if the signal is split we need to do a dedicated search
1042  // for sigTM and sigSCF, so skip the signal here
1043  if ( specName == "sig" && this->signalSplit() ) {
1044  needSignalSearch = kTRUE;
1045  continue;
1046  }
1047 
1048  pdfTot_[iEvt][specName] = 1.0;
1049 
1050  // loop through the 2D histo list
1051  NameSet skipList;
1052  for ( TwoDMap::const_iterator twodim_iter = twodimPDFs_.begin();
1053  twodim_iter != twodimPDFs_.end();
1054  ++twodim_iter ) {
1055  // if the entry doesn't refer to this
1056  // species then skip on
1057  if ( specName != twodim_iter->first ) {
1058  continue;
1059  }
1060 
1061  // retrieve the two variable names
1062  const TString& firstVarName = twodim_iter->second.first;
1063  const TString& secondVarName = twodim_iter->second.second;
1064  if ( firstVarName != exclName && secondVarName != exclName ) {
1065  // if neither name is the one being excluded then...
1066  // add them both to the skip list
1067  skipList.insert( firstVarName );
1068  skipList.insert( secondVarName );
1069  // and multiply the total by the combined PDF value
1070  TString varName = firstVarName + secondVarName;
1071  pdfTot_[iEvt][specName] *= discPdf_[iEvt][specName][varName];
1072  }
1073  }
1074 
1075  // loop through all the variables
1076  for ( NameSet::const_iterator var_iter = variableNames_.begin();
1077  var_iter != variableNames_.end();
1078  ++var_iter ) {
1079  const TString& varName = ( *var_iter );
1080  // if the variable isn't the one being excluded
1081  if ( exclName != varName ) {
1082  // and it's not involved in a 2D PDF
1083  if ( skipList.find( varName ) == skipList.end() ) {
1084  // multiply the total by its PDF value
1085  pdfTot_[iEvt][specName] *= discPdf_[iEvt][specName][varName];
1086  }
1087  }
1088  }
1089  }
1090 
1091  for ( NumbMap::const_iterator spec_iter = freeSpecies_.begin();
1092  spec_iter != freeSpecies_.end();
1093  ++spec_iter ) {
1094  const TString& specName = spec_iter->first;
1095 
1096  // if the signal is split we need to do a dedicated search
1097  // for sigTM and sigSCF, so skip the signal here
1098  if ( specName == "sig" && this->signalSplit() ) {
1099  needSignalSearch = kTRUE;
1100  continue;
1101  }
1102 
1103  pdfTot_[iEvt][specName] = 1.0;
1104 
1105  // loop through the 2D histo list
1106  NameSet skipList;
1107  for ( TwoDMap::const_iterator twodim_iter = twodimPDFs_.begin();
1108  twodim_iter != twodimPDFs_.end();
1109  ++twodim_iter ) {
1110  // if the entry doesn't refer to this
1111  // species then skip on
1112  if ( specName != twodim_iter->first ) {
1113  continue;
1114  }
1115 
1116  // retrieve the two variable names
1117  const TString& firstVarName = twodim_iter->second.first;
1118  const TString& secondVarName = twodim_iter->second.second;
1119  if ( firstVarName != exclName && secondVarName != exclName ) {
1120  // if neither name is the one being excluded then...
1121  // add them both to the skip list
1122  skipList.insert( firstVarName );
1123  skipList.insert( secondVarName );
1124  // and multiply the total by the combined PDF value
1125  TString varName = firstVarName + secondVarName;
1126  pdfTot_[iEvt][specName] *= discPdf_[iEvt][specName][varName];
1127  }
1128  }
1129 
1130  // loop through all the variables
1131  for ( NameSet::const_iterator var_iter = variableNames_.begin();
1132  var_iter != variableNames_.end();
1133  ++var_iter ) {
1134  const TString& varName = ( *var_iter );
1135  // if the variable isn't the one being excluded
1136  if ( exclName != varName ) {
1137  // and it's not involved in a 2D PDF
1138  if ( skipList.find( varName ) == skipList.end() ) {
1139  // multiply the total by its PDF value
1140  pdfTot_[iEvt][specName] *= discPdf_[iEvt][specName][varName];
1141  }
1142  }
1143  }
1144  }
1145 
1146  if ( needSignalSearch ) {
1147 
1148  // loop through the 2D histo list
1149  TString specName( "sigTM" );
1150  Double_t tmPDFVal( 1.0 );
1151  NameSet skipList;
1152  for ( TwoDMap::const_iterator twodim_iter = twodimPDFs_.begin();
1153  twodim_iter != twodimPDFs_.end();
1154  ++twodim_iter ) {
1155  // if the entry doesn't refer to this
1156  // species then skip on
1157  if ( specName != twodim_iter->first ) {
1158  continue;
1159  }
1160 
1161  // retrieve the two variable names
1162  const TString& firstVarName = twodim_iter->second.first;
1163  const TString& secondVarName = twodim_iter->second.second;
1164  if ( firstVarName != exclName && secondVarName != exclName ) {
1165  // if neither name is the one being excluded then...
1166  // add them both to the skip list
1167  skipList.insert( firstVarName );
1168  skipList.insert( secondVarName );
1169  // and multiply the total by the combined PDF value
1170  TString varName = firstVarName + secondVarName;
1171  tmPDFVal *= discPdf_[iEvt][specName][varName];
1172  }
1173  }
1174 
1175  // loop through all the variables
1176  for ( NameSet::const_iterator var_iter = variableNames_.begin();
1177  var_iter != variableNames_.end();
1178  ++var_iter ) {
1179  const TString& varName = ( *var_iter );
1180  // if the variable isn't the one being excluded
1181  if ( exclName != varName ) {
1182  // and it's not involved in a 2D PDF
1183  if ( skipList.find( varName ) == skipList.end() ) {
1184  // multiply the total by its PDF value
1185  tmPDFVal *= discPdf_[iEvt][specName][varName];
1186  }
1187  }
1188  }
1189 
1190  tmPDFVal *= ( 1.0 - scfFrac_[iEvt] );
1191 
1192  // loop through the 2D histo list
1193  specName = "sigSCF";
1194  Double_t scfPDFVal( 1.0 );
1195  skipList.clear();
1196  for ( TwoDMap::const_iterator twodim_iter = twodimPDFs_.begin();
1197  twodim_iter != twodimPDFs_.end();
1198  ++twodim_iter ) {
1199  // if the entry doesn't refer to this
1200  // species then skip on
1201  if ( specName != twodim_iter->first ) {
1202  continue;
1203  }
1204 
1205  // retrieve the two variable names
1206  const TString& firstVarName = twodim_iter->second.first;
1207  const TString& secondVarName = twodim_iter->second.second;
1208  if ( firstVarName != exclName && secondVarName != exclName ) {
1209  // if neither name is the one being excluded then...
1210  // add them both to the skip list
1211  skipList.insert( firstVarName );
1212  skipList.insert( secondVarName );
1213  // and multiply the total by the combined PDF value
1214  TString varName = firstVarName + secondVarName;
1215  scfPDFVal *= discPdf_[iEvt][specName][varName];
1216  }
1217  }
1218 
1219  // loop through all the variables
1220  for ( NameSet::const_iterator var_iter = variableNames_.begin();
1221  var_iter != variableNames_.end();
1222  ++var_iter ) {
1223  const TString& varName = ( *var_iter );
1224  // if the variable isn't the one being excluded
1225  if ( exclName != varName ) {
1226  // and it's not involved in a 2D PDF
1227  if ( skipList.find( varName ) == skipList.end() ) {
1228  // multiply the total by its PDF value
1229  scfPDFVal *= discPdf_[iEvt][specName][varName];
1230  }
1231  }
1232  }
1233 
1234  if ( exclName == "DP" || ! this->scfDPSmear() ) {
1235  scfPDFVal *= scfFrac_[iEvt];
1236  }
1237 
1238  pdfTot_[iEvt]["sig"] = tmPDFVal + scfPDFVal;
1239  }
1240  }
1241 }
1242 
1243 void LauSPlot::calcCNCoeffs( const TString& exclName, const Double_t* covmat )
1244 {
1245  // Computes the cN for the extended sPlots from the covariance matrix
1246 
1247  if ( nFixdSpecies_ <= 0 ) {
1248  return;
1249  }
1250 
1251  Int_t species_n( 0 );
1252  for ( NumbMap::const_iterator iter_n = freeSpecies_.begin(); iter_n != freeSpecies_.end();
1253  ++iter_n ) {
1254  Int_t species_j( 0 );
1255  const TString& specName = iter_n->first;
1256  Double_t value = iter_n->second;
1257  cN_[exclName][specName] = value;
1258  for ( NumbMap::const_iterator iter_j = freeSpecies_.begin(); iter_j != freeSpecies_.end();
1259  ++iter_j ) {
1260  if ( covmat ) {
1261  cN_[exclName][specName] -= covmat[species_n * nSpecies_ + species_j];
1262  } else {
1263  cN_[exclName][specName] -= covMat_( species_n, species_j );
1264  }
1265  ++species_j;
1266  }
1267  ++species_n;
1268  }
1269 }
1270 
1271 void LauSPlot::calcSWeights( const TString& exclName, Double_t* covmat )
1272 {
1273  // Computes the sWeights from the covariance matrix
1274  // NB for the extended sPlot the sum in the denominator is still over all species,
1275  // while that in the numerator is only over the free species.
1276  // Similarly the sWeights can only be calculated for the free species.
1277 
1278  Double_t numerator( 0.0 ), denominator( 0.0 );
1279  for ( Int_t iEvent = 0; iEvent < nEvents_; ++iEvent ) {
1280  denominator = 0.0;
1281  for ( NumbMap::const_iterator free_iter = freeSpecies_.begin();
1282  free_iter != freeSpecies_.end();
1283  ++free_iter ) {
1284  denominator += free_iter->second * pdfTot_[iEvent][free_iter->first];
1285  }
1286  for ( NumbMap::const_iterator fixd_iter = fixdSpecies_.begin();
1287  fixd_iter != fixdSpecies_.end();
1288  ++fixd_iter ) {
1289  denominator += fixd_iter->second * pdfTot_[iEvent][fixd_iter->first];
1290  }
1291  Int_t species_n( 0 );
1292  for ( NumbMap::const_iterator iter_n = freeSpecies_.begin(); iter_n != freeSpecies_.end();
1293  ++iter_n ) {
1294  numerator = 0.0;
1295  Int_t species_j( 0 );
1296  for ( NumbMap::const_iterator iter_j = freeSpecies_.begin(); iter_j != freeSpecies_.end();
1297  ++iter_j ) {
1298  if ( covmat ) {
1299  numerator += covmat[species_n * nSpecies_ + species_j] *
1300  pdfTot_[iEvent][iter_j->first];
1301  } else {
1302  numerator += covMat_( species_n, species_j ) * pdfTot_[iEvent][iter_j->first];
1303  }
1304  ++species_j;
1305  }
1306  sWeights_[iEvent][exclName][iter_n->first] = numerator / denominator;
1307  ++species_n;
1308  }
1309  }
1310 }
1311 
1313 {
1314  if ( ! cnTree_ ) {
1315  cerr << "ERROR in LauSPlot::fillCNBranches : Tree not created, cannot fill branches." << endl;
1316  return;
1317  } else if ( ! this->definedCNBranches() ) {
1318  this->defineCNBranches();
1319  }
1320  cnTree_->Fill();
1321 }
1322 
1324 {
1325  if ( ! sweightTree_ ) {
1326  cerr << "ERROR in LauSPlot::fillSWeightBranches : Tree not created, cannot fill branches."
1327  << endl;
1328  return;
1329  } else if ( sWeights_.empty() ) {
1330  cerr << "ERROR in LauSPlot::fillSWeightBranches : No sWeights calculated, can't fill branches."
1331  << endl;
1332  return;
1333  } else if ( ! this->definedSWeightBranches() ) {
1334  this->copyEventWeights( 0 );
1335  this->defineSWeightBranches();
1336  }
1337 
1338  for ( Int_t iEvent = 0; iEvent < nEvents_; ++iEvent ) {
1339  this->copyEventWeights( iEvent );
1340  sweightTree_->Fill();
1341  }
1342 }
1343 
1344 void LauSPlot::copyEventWeights( Int_t iEvent )
1345 {
1346  for ( std::map<TString, NumbMap>::const_iterator excl_iter = sWeights_[iEvent].begin();
1347  excl_iter != sWeights_[iEvent].end();
1348  ++excl_iter ) {
1349  const TString& exclName = excl_iter->first;
1350  const NumbMap& species = excl_iter->second;
1351  for ( NumbMap::const_iterator spec_iter = species.begin(); spec_iter != species.end();
1352  ++spec_iter ) {
1353  const TString& specName = spec_iter->first;
1354  sWeightsCurrent_[exclName][specName] = spec_iter->second;
1355  }
1356  }
1357 }
1358 
1360 {
1361  // write out the results
1362 
1363  // remove the transient objects that we don't want (re-)written to the file
1364  if ( eventList_ ) {
1365  delete eventList_;
1366  eventList_ = 0;
1367  }
1368  if ( inputTree_ ) {
1369  delete inputTree_;
1370  inputTree_ = 0;
1371  }
1372 
1373  // first add the input tree as a friend of the output tree
1374  this->addFriendTree();
1375 
1376  // then write everything to the file and clean up
1377  file_->cd();
1378  file_->Write();
1379  file_->Close();
1380  delete file_;
1381  file_ = 0;
1382 }
1383 
1385 {
1386  if ( ! sweightTree_ ) {
1387  cerr << "ERROR in LauSPlot::addFriendTree : Tree not created, cannot add friend." << endl;
1388  return;
1389  }
1390  sweightTree_->AddFriend( inputTreeName_, fileName_ );
1391 }
1392 
1393 void Yields( Int_t&, Double_t*, Double_t& f, Double_t* x, Int_t /*iflag*/ )
1394 {
1395  // FCN-function for Minuit
1396 
1397  f = 0.0;
1398 
1399  TVirtualFitter* fitter = TVirtualFitter::GetFitter();
1400  LauSPlot* theModel = dynamic_cast<LauSPlot*>( fitter->GetObjectFit() );
1401  const std::vector<LauSPlot::NumbMap>& pdfTot = theModel->totalPdf();
1402 
1403  Double_t ntot( 0.0 );
1404  for ( std::vector<LauSPlot::NumbMap>::const_iterator evt_iter = pdfTot.begin();
1405  evt_iter != pdfTot.end();
1406  ++evt_iter ) { // loop over events
1407  const LauSPlot::NumbMap& species = ( *evt_iter );
1408  Int_t ispecies( 0 );
1409  Double_t lik( 0.0 );
1410  ntot = 0.0;
1411  for ( LauSPlot::NumbMap::const_iterator spec_iter = species.begin();
1412  spec_iter != species.end();
1413  ++spec_iter ) { // loop over species
1414  lik += x[ispecies] * spec_iter->second;
1415  ntot += x[ispecies];
1416  ++ispecies;
1417  }
1418  if ( lik < 0.0 ) {
1419  // make f the worst possible value to force MINUIT
1420  // out of this region of parameter space
1421  f = -DBL_MAX;
1422  break;
1423  } else {
1424  f += TMath::Log( lik );
1425  }
1426  }
1427 
1428  // extended likelihood
1429  f = ( ntot - f );
1430 }
void calcSWeights(const TString &exclName, Double_t *covmat=0)
Computes the sWeights from the PDFs and covariance matrix.
Definition: LauSPlot.cc:1271
Int_t nEvents_
Number of events in current experiment.
Definition: LauSPlot.hh:344
Double_t value() const
The value of the parameter.
void defineSWeightBranches()
Create the branches to store the sWeights.
Definition: LauSPlot.cc:471
TString sweightTreeName_
The name of the sweight tree (containing the sWeights)
Definition: LauSPlot.hh:296
TTree * cnTree_
Pointer to the output tree containing the cN coefficients.
Definition: LauSPlot.hh:302
Bool_t checkLeaves() const
Check whether the leaf structure makes sense given the PDFs we are expecting.
Definition: LauSPlot.cc:208
std::vector< Double_t > scfFrac_
The per-event values of the SCF fraction.
Definition: LauSPlot.hh:359
void printSumOfWeights(const TString &exclName) const
Print the sum of sWeights for all species.
Definition: LauSPlot.cc:951
std::map< TString, NumbMap > sWeightsCurrent_
The current-event values of the computed sWeights.
Definition: LauSPlot.hh:367
void readExpt()
Reads the values of each PDF likelihood for every event in the experiment.
Definition: LauSPlot.cc:553
void runCalculations(const TString &option="q")
Method to calculate the sWeights and cN coeffs.
Definition: LauSPlot.cc:703
void checkFitter() const
Make sure that we're using Minuit.
Definition: LauSPlot.cc:804
File containing declaration of LauSPlot class.
Int_t nExpt_
Number of experiments.
Definition: LauSPlot.hh:340
LeafMap leaves_
Collection to hold pointers to the leaves of the input tree.
Definition: LauSPlot.hh:310
void openInputFileAndTree()
Method to open the file in "update" mode and grab the input tree for reading.
Definition: LauSPlot.cc:122
Bool_t scfDPSmear() const
Check whether the Self Cross Feed is smeared in the DP.
Definition: LauSPlot.hh:151
void readInputInfo()
Read the leaf structure from the tree and check the status of the read (calls LauSPlot::readInputLeav...
Definition: LauSPlot.cc:147
Int_t nFreeSpecies_
Number of species free to float in the fit.
Definition: LauSPlot.hh:348
void retrieveFittedParameters(const TString &opt)
Update the yields with the newly fitted values and print them (unless print option is "Q").
Definition: LauSPlot.cc:925
void defineCNBranches()
Create the branches for each cN coefficient.
Definition: LauSPlot.cc:426
std::set< TString > NameSet
Type to store names, e.g. of the discriminating/control variables.
Definition: LauSPlot.hh:72
TString cnTreeName_
The name of the cn tree (containing the cN coefficients)
Definition: LauSPlot.hh:294
TwoDMap twodimPDFs_
The names of the species that have 2D PDFs and the names of the variables involved.
Definition: LauSPlot.hh:323
Bool_t readInputLeaves()
Read the leaf structure from the tree and setup the leaf map.
Definition: LauSPlot.cc:163
void addFriendTree()
Add the sWeightTree as a friend tree of the input tree.
Definition: LauSPlot.cc:1384
std::vector< NumbMap > pdfTot_
The per-event values of the total PDF for each species.
Definition: LauSPlot.hh:355
void createSWeightTree()
Create (if not already done) the tree for storing the sWeights.
Definition: LauSPlot.cc:412
TTree * inputTree_
Pointer to the input tree.
Definition: LauSPlot.hh:300
std::map< TString, Double_t > NumbMap
Type to associate a category name with a double precision number, e.g. a yield or PDF value for a giv...
Definition: LauSPlot.hh:75
void calcTotPDFValues(const TString &exclName)
Calculate the total likelihood for each species by multiply together all the PDFs for that species.
Definition: LauSPlot.cc:1030
Int_t firstExpt_
First experiment.
Definition: LauSPlot.hh:338
void copyEventWeights(Int_t iEvent)
Copy the sWeight of a given event into LauSPlot::sWeightsCurrent_, from which they can be stored in t...
Definition: LauSPlot.cc:1344
void initialiseFitter(const TString &opt)
Initialise Minuit, set the verbosity.
Definition: LauSPlot.cc:818
NumbMap origFixdSpecies_
The names and estimated yields of the fixed species - need to keep the original values.
Definition: LauSPlot.hh:321
Class for defining the SPlot technique.
Definition: LauSPlot.hh:68
TString fileName_
The name of the data file.
Definition: LauSPlot.hh:290
const std::vector< LauSPlot::NumbMap > & totalPdf() const
Access the per-event total PDF values for each species.
Definition: LauSPlot.hh:126
void runFit()
Perform the minimisation wrt the yields alone.
Definition: LauSPlot.cc:876
virtual ~LauSPlot()
Destructor.
Definition: LauSPlot.cc:106
TFile * file_
Pointer to the data file object.
Definition: LauSPlot.hh:298
NumbMap freeSpecies_
The names and estimated yields of the free species.
Definition: LauSPlot.hh:315
Bool_t fixed() const
Check whether the parameter is fixed or floated.
TTree * sweightTree_
Pointer to the output tree containing the sWeights.
Definition: LauSPlot.hh:304
LauSPlot(const TString &fileName, const TString &treeName, Int_t firstExpt, Int_t nExpt, const NameSet &variableNames, const LauSPlot::NumbMap &freeSpecies, const LauSPlot::NumbMap &fixdSpecies, const TwoDMap &twodimPDFs, Bool_t sigSplit=kFALSE, Bool_t scfDPSmeared=kFALSE)
Constructor.
Definition: LauSPlot.cc:59
Bool_t definedCNBranches() const
Check whether the cN branches have been already created.
Definition: LauSPlot.hh:157
void fillCNBranches()
Fill the cN branches.
Definition: LauSPlot.cc:1312
Bool_t calcCovMatrix()
Definition: LauSPlot.cc:967
const TString & name() const
The parameter name.
Int_t iExpt_
The current experiment.
Definition: LauSPlot.hh:342
Bool_t readInput() const
Check whether the input tree has been successfully read.
Definition: LauSPlot.hh:133
TString inputTreeName_
The name of the input tree (containing the per-event llhds)
Definition: LauSPlot.hh:292
void fillSWeightBranches()
Fill the sWeights branches.
Definition: LauSPlot.cc:1323
Bool_t definedSWeightBranches() const
Check whether the sWeights branches have been already created.
Definition: LauSPlot.hh:169
void createCNTree()
Create (if not already done) the tree for storing the cN coeffs.
Definition: LauSPlot.cc:398
void setFitParameters() const
Add the species yields as fit parameters and fix them as appropriate.
Definition: LauSPlot.cc:844
NameSet variableNames_
The names of the discriminating variables.
Definition: LauSPlot.hh:313
TMatrixD covMat_
The calculated covariance matrix.
Definition: LauSPlot.hh:362
NumbMap fixdSpecies_
The names and estimated yields of the fixed species.
Definition: LauSPlot.hh:317
Int_t nFixdSpecies_
Number of species fixed in the fit.
Definition: LauSPlot.hh:350
TEventList * eventList_
Pointer to an event list, that is used to loop through the experiments.
Definition: LauSPlot.hh:307
std::vector< std::map< TString, NumbMap > > sWeights_
The per-event values of the computed sWeights (for each species and for each combination of excluded ...
Definition: LauSPlot.hh:365
void writeOutResults()
Save the sWeight results as a friend tree to the input tree (in the same file)
Definition: LauSPlot.cc:1359
NumbMap origFreeSpecies_
The names and estimated yields of the free species - need to keep the original values.
Definition: LauSPlot.hh:319
Int_t nSpecies_
Total number of species (free + fixed)
Definition: LauSPlot.hh:352
void printCovMatrixElements(const Double_t *covmat=0) const
Print the supplied covariance matrix or, if pointer is null, the one previously calculated.
Definition: LauSPlot.cc:898
std::multimap< TString, std::pair< TString, TString > > TwoDMap
Type to associate the name of the species that have 2D PDFs with the names of the two variables invol...
Definition: LauSPlot.hh:81
std::vector< std::map< TString, NumbMap > > discPdf_
The per-event values of the PDFs for each species for each disc variable.
Definition: LauSPlot.hh:357
std::map< TString, NumbMap > cN_
The extended sPlot coefficients (for each species and for each combination of excluded vars)
Definition: LauSPlot.hh:369
void calcCNCoeffs(const TString &exclName, const Double_t *covmat=0)
Computes the cN for the extended sPlots from the covariance matrix.
Definition: LauSPlot.cc:1243
Bool_t signalSplit() const
Check whether the signal is split into Truth Matched and Self Cross Feed.
Definition: LauSPlot.hh:145
void setExperiment(Int_t iExpt)
Set the event list to contain only events from the given experiment.
Definition: LauSPlot.cc:514