#include #include "MTask.h" #include "MParList.h" #include "MDataChain.h" class MChisqEval : public MTask { private: static const TString gsDefName; static const TString gsDefTitle; Double_t fChisq; //! Evaluated chi square MData *fData0; // Data Member one (monte carlo data or chisq function) MData *fData1; // Data Member two (measured data) // -------------------------------------------------------------------------- // // Implementation of SavePrimitive. Used to write the call to a constructor // to a macro. In the original root implementation it is used to write // gui elements to a macro-file. // void StreamPrimitive(ofstream &out) const { out << " MChisqEval " << GetUniqueName() << ";"; if (fData0) out << " " << GetUniqueName() << ".SetY1(\"" << fData0->GetRule() << "\");" << endl; if (fData1) out << " " << GetUniqueName() << ".SetY1(\"" << fData1->GetRule() << "\");" << endl; } enum { kIsOwner = BIT(14) }; public: MChisqEval(const char *name=NULL, const char *title=NULL) : fData0(NULL), fData1(NULL)// : fMatrix(mat), fColumn(col), fEvalE(evale) { fName = name ? name : gsDefName.Data(); fTitle = title ? title : gsDefTitle.Data(); } MChisqEval(MData *y1, const char *name=NULL, const char *title=NULL) : fData0(NULL), fData1(NULL)// : fMatrix(mat), fColumn(col), fEvalE(evale) { fName = name ? name : gsDefName.Data(); fTitle = title ? title : gsDefTitle.Data(); SetY1(y1); } MChisqEval(MData *y1, MData *y2, const char *name=NULL, const char *title=NULL) : fData0(NULL), fData1(NULL)// : fMatrix(mat), fColumn(col), fEvalE(evale) { fName = name ? name : gsDefName.Data(); fTitle = title ? title : gsDefTitle.Data(); SetY1(y1); SetY2(y2); } ~MChisqEval() { if (fData0 && (fData0->TestBit(kCanDelete) || TestBit(kIsOwner))) delete fData0; if (fData1 && (fData1->TestBit(kCanDelete) || TestBit(kIsOwner))) delete fData1; } void SetY1(MData *data) { // Set MC value if (fData0 && (fData0->TestBit(kCanDelete) || TestBit(kIsOwner))) delete fData0; fData0 = data; fData0->SetBit(kCanDelete); AddToBranchList(fData0->GetDataMember()); } void SetY2(MData *data) { // Set measured/estimated value if (fData1 && (fData1->TestBit(kCanDelete) || TestBit(kIsOwner))) delete fData1; fData1 = data; fData1->SetBit(kCanDelete); AddToBranchList(fData1->GetDataMember()); } void SetY1(const TString data) { SetY1(new MDataChain(data)); } void SetY2(const TString data) { SetY2(new MDataChain(data)); } void SetOwner(Bool_t o=kTRUE) { o ? SetBit(kIsOwner) : ResetBit(kIsOwner); } Bool_t PreProcess(MParList *plist) { fChisq = 0; if (!fData0) return kFALSE; if (!fData0->PreProcess(plist)) return kFALSE; if (fData1) if (!fData1->PreProcess(plist)) return kFALSE; return kTRUE; } Bool_t Process() { const Double_t y1 = fData0->GetValue(); const Double_t y2 = fData1 ? fData1->GetValue() : 0; const Double_t dy = y2-y1; const Double_t err = fData1 ? y1*y1 : 1; fChisq += dy*dy/err; return kTRUE; } Bool_t PostProcess() { fChisq /= GetNumExecutions(); return kTRUE; } Double_t GetChisq() const { return fChisq; } ClassDef(MChisqEval, 0) }; ClassImp(MChisqEval); const TString MChisqEval::gsDefName = "MChisqEval"; const TString MChisqEval::gsDefTitle = "Evaluate a chisq"; // -------------------------------------------------------------------------- #include #include "MEvtLoop.h" #include "MTaskList.h" #include "MEnergyEstParam.h" void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag) { MEvtLoop &evtloop = *(MEvtLoop*)gMinuit->GetObjectFit(); MTaskList &tlist = *(MTaskList*)evtloop.GetParList()->FindObject("MTaskList"); //GetTaskList(); MChisqEval &eval = *(MChisqEval*) tlist.FindObject("MChisqEval"); MEnergyEstParam &eest = *(MEnergyEstParam*)tlist.FindObject("MEnergyEstParam"); eest.SetCoeff(TArrayD(eest.GetNumCoeff(), par)); evtloop.Eventloop(); f = eval.GetChisq(); } // -------------------------------------------------------------------------- #include #include "MHMatrix.h" #include "MEnergyEst.h" #include "MDataMember.h" #include "MDataElement.h" #include "MReadTree.h" #include "MMatrixLoop.h" void estfit(Bool_t evalenergy=kFALSE) { // // Fill events into a MHMatrix // MParList parlist; MHMatrix matrix; Int_t col = matrix.AddColumn(evalenergy?"MMcEvt.fEnergy":"MMcEvt.fImpact"); MEnergyEstParam eest; eest.Add("MHillasSrc"); eest.InitMapping(&matrix); MReadTree read("Events", "gammas.root"); read.DisableAutoScheme(); if (!matrix.Fill(&parlist, &read)) return; // // Setup the tasklist used to evaluate the needed chisq // MTaskList tasklist; parlist.AddToList(&tasklist); MMatrixLoop loop(&matrix); MChisqEval eval; eval.SetY1(new MDataElement(&matrix, col)); eval.SetY2(new MDataMember(evalenergy ? "MEnergyEst.fEnergy" : "MEnergyEst.fImpact")); eval.SetOwner(); tasklist.AddToList(&loop); tasklist.AddToList(&eest); tasklist.AddToList(&eval); MEvtLoop evtloop; evtloop.SetParList(&parlist); // // Be carefull: This is not thread safe // TMinuit minuit(12); minuit.SetFCN(fcn); // Ready for: minuit.mnexcm("SET ERR", arglist, 1, ierflg) if (minuit.SetErrorDef(1)) { cout << "SetErrorDef failed." << endl; return; } // // Set initial values // TArrayD fA(5); fA[0] = -2539; // [cm] fA[1] = 900; // [cm] fA[2] = 17.5; // [cm] fA[3] = 1;// 4; fA[4] = 58.3; TArrayD fB(7); fB[0] = -8.64; // [GeV] fB[1] = -0.069; // [GeV] fB[2] = 0.00066; // [GeV] fB[3] = 0.033; // [GeV] fB[4] = 0.000226; // [GeV] fB[5] = 4.14e-8; // [GeV] fB[6] = -0.06; // Set starting values and step sizes for parameters for (Int_t i=0; i