#include "hmetaaligner.h"
#include "TFitter.h"
#include "hades.h"
#include "hspectrometer.h"
#include "hparrootfileio.h"
#include "hshowerdetector.h"
#include "hshowerhistcell.h"
#include "hshowercalpar.h"
#include "hshowergeometry.h"
#include "hshowerpad.h"
#include "htofdetector.h"
#include "htofgeompar.h"
ClassImp(HMetaAligner)
HMetaAligner *g_pCurrentMetaAligner = NULL;
const static Char_t *g_sapMetaAlignerParamsNames[kMETA_ALIGNER_PARAMS]
= { "dX", "dY", "dZ", "rotX", "rotY", "rotZ" };
const static Char_t *g_sapMinuitMethods[]
= { "MINImize", "MIGrad", "SIMplex" };
#define SAFE_DELETE(A) { if(A != NULL) { delete A; A = NULL; }}
void hMetaAlignMinuitFunction(Int_t &npar, Double_t *gin, Double_t &f,
Double_t *par, Int_t iflag)
{
g_pCurrentMetaAligner->minAlign(npar, gin, f, par, iflag);
}
void HMetaAligner::init(void)
{
m_bInitOK = kFALSE;
m_iSector = 0;
m_iSystem = 0;
m_pTupleFile = NULL;
m_pTuple = NULL;
m_iEntries = 0;
m_iMaxEntries = 0;
m_iVerbose = 2;
m_bNormalize = kTRUE;
m_bEqualSigmas = kFALSE;
for(Int_t i = 0; i < kMETA_ALIGNER_PARAMS; i++)
{
m_dStartParams[i] = 0.0;
m_dParams[i] = 0.0;
m_dStartErrors[i] = (i < 3) ? 10 : 1;
m_dErrors[i] = 0.0;
m_dSteps[i] = kMATA_ALIGN_DEFAULT_STEP;
m_bFixed[i] = (i > 2);
}
m_dError = kMATA_ALIGN_DEFAULT_ERROR;
m_dMigSteps = kMATA_ALIGN_DEFAULT_STEPS;
m_bUseTukay = kTRUE;
m_dTukayConst = kMATA_ALIGN_DEFAULT_TUKAY_CONST;
m_dTukayConst_2 = m_dTukayConst * m_dTukayConst;
m_dLastChi_2 = 0.0;
m_iStatus = 0;
m_iLastThrown = 0;
m_iHits = 0;
m_pTupleFile = NULL;
m_pTuple = NULL;
m_pRTDB = NULL;
m_fXc = 0.0;
m_fYc = 0.0;
m_fZc = 0.0;
m_fAlphaX = 0.0;
m_fAlphaY = 0.0;
m_fAlphaZ = 0.0;
m_fXo = 0.0;
m_fYo = 0.0;
m_fSigXo = 0.0;
m_fSigYo = 0.0;
m_fSec = 0.0;
m_fMod = 0.0;
m_fSys = 0.0;
m_dChi2X = 0.0;
m_dChi2Y = 0.0;
m_dWeightChi2X = 0.0;
m_dWeightChi2Y = 0.0;
m_bImprove = kFALSE;
m_bChangeWeights = kFALSE;
}
HMetaAligner::HMetaAligner(const Char_t *pFileName, Int_t iSector, Int_t iSystem,
const Char_t *pParamFile, Int_t iRunId)
: TObject()
{
init();
m_iSector = iSector;
m_iSystem = iSystem;
if( ! loadParameters(pParamFile, iRunId))
return;
if(openNTuple(pFileName))
m_bInitOK = kTRUE;
}
HMetaAligner::~HMetaAligner(void)
{
SAFE_DELETE(m_pTuple);
SAFE_DELETE(m_pTupleFile);
}
Bool_t HMetaAligner::loadParameters(const Char_t *pParamFileName, Int_t iRunId)
{
if(gHades == NULL)
new Hades;
m_pRTDB = gHades->getRuntimeDb();
if(m_iVerbose)
printf("Init for System: %d Sector: %d\n", m_iSystem, m_iSector);
if(m_iSystem == 0)
return getShowerGeom(pParamFileName, iRunId);
else
return getTofGeom(pParamFileName, iRunId);
}
Bool_t HMetaAligner::getShowerGeom(const Char_t *pParamFile, Int_t iRunId)
{
HGeomTransform tTransform;
Int_t i;
HShowerGeometry *pShowerGeom;
HParRootFileIo *pInput;
if(gHades->getSetup()->getDetector("Shower") == NULL)
{
Int_t mods[3] = {1, 1, 1};
HShowerDetector *pShower = new HShowerDetector;
for(Int_t iSec = 0; iSec < 6; iSec++)
pShower->setModules(iSec, mods);
gHades->getSetup()->addDetector(pShower);
}
pInput = new HParRootFileIo;
pInput->open(pParamFile, "READ");
m_pRTDB->setFirstInput(pInput);
if((pShowerGeom = (HShowerGeometry*)m_pRTDB
->getContainer("ShowerGeometry")) == NULL)
{
pShowerGeom = new HShowerGeometry;
m_pRTDB->addContainer(pShowerGeom);
}
if(m_pRTDB->initContainers(iRunId) == kFALSE)
{
Error("getShowerGeom", "m_pRTDB->initContainers error");
return kFALSE;
}
tTransform = pShowerGeom->getTransform(m_iSector, 0);
m_arRI[0] = tTransform.getRotMatrix().inverse();
m_avT[0] = tTransform.getTransVector();
for(i = 1; i < kMETA_ALIGNER_MATRICS; i++)
{
m_arRI[i] = m_arRI[0];
m_avT[i] = m_avT[0];
}
return kTRUE;
}
Bool_t HMetaAligner::getTofGeom(const Char_t *pParamFile, Int_t iRunId)
{
HGeomTransform tTransform;
Int_t i;
HParRootFileIo *pInput;
HTofGeomPar *pTofGeom;
if(gHades->getSetup()->getDetector("Tof") == NULL)
{
Int_t mods[22] = {1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
HTofDetector *pTof = new HTofDetector;
for(Int_t iSec = 0; iSec < 6; iSec++)
pTof->setModules(iSec, mods);
gHades->getSetup()->addDetector(pTof);
}
pInput = new HParRootFileIo;
pInput->open((Text_t *)pParamFile, "READ");
m_pRTDB->setFirstInput(pInput);
pTofGeom = (HTofGeomPar *)m_pRTDB->getContainer("TofGeomPar");
if(m_pRTDB->initContainers(iRunId) == kFALSE)
{
Error("getTofGeom", "m_pRTDB->initContainers error");
return kFALSE;
}
for(i = 0; i < kMETA_ALIGNER_MATRICS; i++)
{
tTransform = pTofGeom->getModule(m_iSector, i)->getLabTransform();
m_arRI[i] = tTransform.getRotMatrix().inverse();
m_avT[i] = tTransform.getTransVector();
}
return kTRUE;
}
Bool_t HMetaAligner::openNTuple(const Char_t *pFileName)
{
m_pTupleFile = new TFile(pFileName);
if((m_pTuple = (TNtuple *) m_pTupleFile->Get("metaAlign")) == NULL)
{
Error("openNTuple", "No 'metaAlign' Tuple in file: %s", pFileName);
return kFALSE;
}
m_pTuple->SetBranchAddress("xc", &m_fXc);
m_pTuple->SetBranchAddress("yc", &m_fYc);
m_pTuple->SetBranchAddress("zc", &m_fZc);
m_pTuple->SetBranchAddress("alphax", &m_fAlphaX);
m_pTuple->SetBranchAddress("alphay", &m_fAlphaY);
m_pTuple->SetBranchAddress("alphaz", &m_fAlphaZ);
m_pTuple->SetBranchAddress("xo", &m_fXo);
m_pTuple->SetBranchAddress("yo", &m_fYo);
m_pTuple->SetBranchAddress("sigxo", &m_fSigXo);
m_pTuple->SetBranchAddress("sigyo", &m_fSigYo);
m_pTuple->SetBranchAddress("s", &m_fSec);
m_pTuple->SetBranchAddress("mod", &m_fMod);
m_pTuple->SetBranchAddress("sys", &m_fSys);
if((m_iEntries = (Int_t)m_pTuple->GetEntries()) <= 0)
{
Error("openNTuple", "No entires in NTuple");
return kFALSE;
}
m_iMaxEntries = m_iEntries;
if(m_iVerbose)
printf("%d events in file: %s\n", m_iMaxEntries, pFileName);
return kTRUE;
}
void HMetaAligner::setValue(Int_t iParam, Double_t dVal)
{
if((iParam < 0) || (iParam >= kMETA_ALIGNER_PARAMS))
Error("setValue", "Wrong param id: %d", iParam);
else
m_dStartParams[iParam] = dVal;
}
void HMetaAligner::setStep(Int_t iParam, Double_t dStep)
{
if((iParam < 0) || (iParam >= kMETA_ALIGNER_PARAMS))
Error("setStep", "Wrong param id: %d", iParam);
else
m_dSteps[iParam] = dStep;
}
void HMetaAligner::fixParam(Int_t iParam, Bool_t bFix)
{
if((iParam < 0) || (iParam >= kMETA_ALIGNER_PARAMS))
Error("fixParam", "Wrong param id: %d", iParam);
else
m_bFixed[iParam] = bFix;
}
void HMetaAligner::releaseParam(Int_t iParam)
{
fixParam(iParam, kFALSE);
}
void HMetaAligner::releaseAll(void)
{
for(Int_t i = 0; i < kMETA_ALIGNER_PARAMS; i++)
m_bFixed[i] = kFALSE;
}
void HMetaAligner::fixAll(void)
{
for(Int_t i = 0; i < kMETA_ALIGNER_PARAMS; i++)
m_bFixed[i] = kTRUE;
}
void HMetaAligner::reversFixed(void)
{
for(Int_t i = 0; i < kMETA_ALIGNER_PARAMS; i++)
m_bFixed[i] = ! m_bFixed[i];
}
void HMetaAligner::setError(Double_t d)
{
m_dError = d;
}
void HMetaAligner::setMigRad(Double_t d)
{
m_dMigSteps = d;
}
void HMetaAligner::setTukayConst(Double_t d)
{
m_dTukayConst = d;
m_dTukayConst_2 = m_dTukayConst * m_dTukayConst;
}
void HMetaAligner::setNormalize(Bool_t bSet)
{
m_bNormalize = bSet;
}
void HMetaAligner::setImprove(Bool_t bSet)
{
m_bImprove = bSet;
}
void HMetaAligner::setEntries(Int_t i)
{
if((i <= 0) || (i > m_iMaxEntries))
m_iEntries = m_iMaxEntries;
else
m_iEntries = i;
}
void HMetaAligner::copyResultsToStart(void)
{
for(Int_t i = 0; i < kMETA_ALIGNER_PARAMS; i++)
m_dStartParams[i] = m_dParams[i];
}
Bool_t HMetaAligner::runFit(Bool_t bUseTukay, const Char_t *pOut, Int_t iMethod)
{
Double_t args[3];
Int_t i;
TVirtualFitter *pFitter;
Char_t s[100];
Double_t dL, dH;
Int_t iVP, iNP;
if( ! m_bInitOK)
{
Error("runFit", "Class not initialized !");
return kFALSE;
}
if(m_iEntries <= 0)
{
Error("runFit", "Entries <= 0");
return kFALSE;
}
m_bUseTukay = bUseTukay;
m_dLastChi_2 = 0.0;
m_iLastThrown = 0;
m_iHits = 0;
m_iCalls = 0;
m_dPrevSigma = 0.0;
m_iMethod = iMethod;
if((m_iMethod < 0)
|| (m_iMethod >= (Int_t)(sizeof(g_sapMinuitMethods) / sizeof(Char_t *))))
{
Error("runFit", "Unknown method");
return kFALSE;
}
g_pCurrentMetaAligner = this;
pFitter = TVirtualFitter::Fitter(this);
pFitter->Clear();
pFitter->SetFCN(::hMetaAlignMinuitFunction);
args[0] = m_dError;
pFitter->ExecuteCommand("SET ERR", args, 1);
for(i = 0; i < kMETA_ALIGNER_PARAMS; i++)
{
if(pFitter->SetParameter(i, g_sapMetaAlignerParamsNames[i],
m_dStartParams[i], m_dStartErrors[i], 0, 0) != 0)
{
Error("runFit", "MNPARM unable to implement definition: %s\n",
g_sapMetaAlignerParamsNames[i]);
g_pCurrentMetaAligner = NULL;
return kFALSE;
}
if(m_bFixed[i])
pFitter->FixParameter(i);
else
pFitter->ReleaseParameter(i);
}
args[0] = m_dMigSteps;
args[1] = 1.0;
pFitter->ExecuteCommand(g_sapMinuitMethods[m_iMethod], args, 2);
if(m_bImprove)
pFitter->ExecuteCommand("IMPROVE", args, 0);
for(i = 0; i < kMETA_ALIGNER_PARAMS; i++)
pFitter->GetParameter(i, s, m_dParams[i], m_dErrors[i], dL, dH);
m_iStatus = pFitter->GetStats(m_dLastChi_2, dL, dH, iVP, iNP);
if(pOut != NULL)
writeResults(pOut);
if(m_iVerbose >= 2)
print();
g_pCurrentMetaAligner = NULL;
return kTRUE;
}
Bool_t HMetaAligner::contFit(Bool_t bUseTukay, const Char_t *pOut, Int_t iMethod)
{
copyResultsToStart();
return runFit(bUseTukay, pOut, iMethod);
}
void HMetaAligner::print(const Char_t *pFileName) const
{
HGeomRotation r;
Char_t sCond[20] = "OFF";
Char_t sPar[10] = "";
FILE *pFile = stdout;
if((pFileName != NULL) && ((pFile = fopen(pFileName, "a")) == NULL))
{
Error("print", "Cannot open file: %s for writing", pFileName);
return;
}
if(m_bUseTukay)
{
sprintf(sCond, "%6.2f", m_dTukayConst);
if(m_bChangeWeights)
strcat(sCond, "(Chw)");
}
if((m_bNormalize) || (m_bEqualSigmas))
{
sprintf(sPar, "(%s%s)", (m_bNormalize) ? "N" : "",
(m_bEqualSigmas) ? "eS" : "");
}
fprintf(pFile, "\nSector: %d %s Entries: %d Method: %s%s Error: %.4f\n"
"Tukay const: %s Thrown: %d / %d FCN: %.7f%s(%d)"
" In: %d steps\n",
m_iSector, (m_iSystem == 0) ? "Shower": "Tof", m_iEntries,
g_sapMinuitMethods[m_iMethod], (m_bImprove) ? "(I)" : "",
m_dError, sCond, m_iLastThrown,
m_iHits, m_dLastChi_2, sPar, m_iStatus, m_iCalls);
fprintf(pFile, "+-----------+-----------+-----------"
"+-----------+-----------+-----------+\n"
"| Name | Fixed | Result "
"| Error | Step | Start |\n"
"+-----------+-----------+-----------+"
"-----------+-----------+-----------+\n"
);
for(Int_t i = 0; i < kMETA_ALIGNER_PARAMS; i++)
{
fprintf(pFile, "| %7s | %4s | %9.4f | %9.4f | %9.4f | %9.4f |\n",
g_sapMetaAlignerParamsNames[i],
(m_bFixed[i]) ? "Yes" : "No",
m_dParams[i],
m_dErrors[i], m_dSteps[i], m_dStartParams[i]);
}
fprintf(pFile, "+-----------+-----------+-----------+"
"-----------+-----------+-----------+\n");
if(pFile != stdout)
fclose(pFile);
}
void HMetaAligner::printLine(const Char_t *pFileName) const
{
FILE *pFile = stdout;
if((pFileName != NULL) && ((pFile = fopen(pFileName, "a")) == NULL))
{
Error("printLine", "Cannot open file: %s for writing", pFileName);
return;
}
fprintf(pFile, "| %s %d |%9.4f |%9.4f |%9.4f |%9.4f |%9.4f |%9.4f |\n",
(m_iSystem == 0) ? "Shower": " Tof ", m_iSector,
m_dParams[0], m_dParams[1], m_dParams[2],
m_dParams[3], m_dParams[4], m_dParams[5]);
if(pFile != stdout)
fclose(pFile);
}
void HMetaAligner::printHtmlRow(const Char_t *pFileName) const
{
Int_t i;
FILE *pFile = stdout;
if((pFileName != NULL) && ((pFile = fopen(pFileName, "a")) == NULL))
{
Error("printHtmlRow", "Cannot open file: %s for writing", pFileName);
return;
}
fprintf(pFile, "<tr align=right><td><tt>%s %d</tt></td>\n",
(m_iSystem) ? "Tof" : "Shower", m_iSector);
for(i = 0; i < 6; i++)
fprintf(pFile, "\t<td><tt>%.4f</tt></td>\n", m_dParams[i]);
fprintf(pFile, "\t<td><tt>%d / %d</tt></td>\n\t<td><tt>%.7f</tt></td>\n"
"</tr>\n", m_iLastThrown, m_iHits, m_dLastChi_2);
if(pFile != stdout)
fclose(pFile);
}
Double_t HMetaAligner::funcResiduals(HGeomVector *pvDT, HGeomRotation *prDRot)
{
static HGeomRotation rRotI;
static HGeomVector vRc;
static HGeomVector vAlpha;
HGeomVector *pvT;
Double_t dT;
Double_t dChisq;
Double_t dC;
Double_t dChi2X;
Double_t dChi2Y;
Double_t dW;
rRotI = m_arRI[(Int_t)m_fMod];
pvT = &m_avT[(Int_t)m_fMod];
if(prDRot != NULL)
rRotI = *prDRot * rRotI;
vRc.setXYZ(m_fXc, m_fYc, m_fZc);
vAlpha.setXYZ(m_fAlphaX, m_fAlphaY, m_fAlphaZ);
vRc -= *pvT;
vRc -= *pvDT;
vRc = rRotI * vRc;
vAlpha = rRotI * vAlpha;
dT = -vRc.Z() / vAlpha.Z();
vRc.setX(vRc.X() + vAlpha.X() * dT - m_fXo);
vRc.setY(vRc.Y() + vAlpha.Y() * dT - m_fYo);
vRc.setZ(0.0f);
m_dDX = vRc.X();
m_dDY = vRc.Y();
if(m_bEqualSigmas)
{
m_fSigXo = m_fSigYo = 11.0;
}
dChi2X = vRc.X() * vRc.X() / (m_fSigXo * m_fSigXo);
dChi2Y = vRc.Y() * vRc.Y() / (m_fSigYo * m_fSigYo);
if(m_dWeightChi2X != 0.0)
dChi2X *= m_dWeightChi2X;
if(m_dWeightChi2Y != 0.0)
dChi2Y *= m_dWeightChi2Y;
m_dChi2X = vRc.X() / m_fSigXo;
m_dChi2Y = vRc.Y() / m_fSigYo;
dChisq = 0.5 * (dChi2X + dChi2Y);
dW = dChisq;
if((m_bChangeWeights) && (m_dPrevSigma > 0.0))
dW = dChisq / m_dPrevSigma;
m_dChi2 = dChisq;
if( ! m_bUseTukay)
{
m_dChi2W = -2.0f;
m_dChi2XSum += dChi2X;
m_dChi2YSum += dChi2Y;
return dChisq;
}
if(dW >= m_dTukayConst_2)
{
m_dChi2W = -1.0f;
m_iLastThrown++;
return 0.0f;
}
m_dChi2XSum += dChi2X;
m_dChi2YSum += dChi2Y;
dC = 1.0 - dW / m_dTukayConst_2;
m_dWeightsSum0 += dC * dChisq;
m_dWeightsSum1 += dC;
dC = dC * dC * dChisq;
m_dChi2W = dC;
return dC;
}
void HMetaAligner::minAlign(Int_t &npar, Double_t *gin, Double_t &f,
Double_t *par, Int_t iflag)
{
Double_t dChisq = 0.0;
Int_t i;
HGeomRotation *pM = NULL;
static HGeomVector vDT;
static HGeomRotation rDRotI;
static HGeomRotation rDRotX;
vDT.setXYZ(par[0], par[1], par[2]);
if((par[3] != 0.0f) || (par[4] != 0.0f) || (par[5] != 0.0f))
{
rDRotX.setEulerAngles(90.0, par[3], -90.0);
rDRotI.setEulerAngles(0.0, par[4], par[5]);
rDRotI = rDRotI * rDRotX;
rDRotI.invert();
pM = &rDRotI;
}
m_iHits = 0;
m_iLastThrown = 0;
m_dChi2XSum = m_dChi2YSum = 0.0;
m_dWeightsSum0 = m_dWeightsSum1 = 0.0;
for(i = 0; i < m_iEntries; i++)
{
m_pTuple->GetEntry(i);
if(((Int_t)m_fSys != m_iSystem) || ((Int_t)m_fSec != m_iSector))
continue;
m_iHits++;
dChisq += funcResiduals(&vDT, pM);
}
if((m_bNormalize) & (m_iLastThrown != m_iHits))
{
dChisq /= (m_iHits - m_iLastThrown);
m_dChi2XSum /= (m_iHits - m_iLastThrown);
m_dChi2YSum /= (m_iHits - m_iLastThrown);
m_dPrevSigma = m_dWeightsSum0 / m_dWeightsSum1;
}
if(m_iLastThrown > m_iHits / 2)
dChisq = 1e+20;
m_iCalls++;
if(m_iVerbose)
{
printf("%5d: dT: %8.3f %8.3f %8.3f dR: %6.3f %6.3f %6.3f\n"
"\tchi^2 : %10.7f Thr: %5d / %d\n"
"\tXchi^2: %10.7f Ychi^2: %10.7f",
m_iCalls, par[0], par[1], par[2], par[3], par[4], par[5],
dChisq, m_iLastThrown, m_iHits,
m_dChi2XSum, m_dChi2YSum);
if(m_bChangeWeights)
printf(" Sigma: %10.7f\n\n", m_dPrevSigma);
else
printf("\n\n");
}
m_dLastChi_2 = dChisq;
f = dChisq;
}
void HMetaAligner::writeResults(const Char_t *pFileName)
{
Int_t i;
HGeomVector vDT(m_dParams[0], m_dParams[1], m_dParams[2]);
HGeomRotation *pM;
TNtuple *pTuple;
TFile *pOut;
HGeomRotation rDRotI;
HGeomRotation rDRotX;
if((m_dParams[3] != 0.0f) || (m_dParams[4] != 0.0f)
|| (m_dParams[5] != 0.0f))
{
rDRotX.setEulerAngles(90.0, m_dParams[3], -90.0);
rDRotI.setEulerAngles(0.0, m_dParams[4], m_dParams[5]);
rDRotI = rDRotI * rDRotX;
rDRotI.invert();
pM = &rDRotI;
}
else
pM = NULL;
pOut = new TFile(pFileName, "RECREATE");
pTuple = new TNtuple("res", "Results", "xm:ym:dx:dy:sys:c:cw:vx:vy");
m_iHits = 0;
m_iLastThrown = 0;
for(i = 0; i < m_iEntries; i++)
{
m_pTuple->GetEntry(i);
if((m_iSystem != (Int_t)m_fSys) || ((Int_t)m_fSec != m_iSector))
continue;
m_iHits++;
funcResiduals(&vDT, pM);
pTuple->Fill(m_fXo, m_fYo, m_dDX, m_dDY, m_iSystem,
m_dChi2, m_dChi2W, m_dChi2X, m_dChi2Y);
}
pOut->Write();
delete pOut;
}
Last change: Sat May 22 13:04:33 2010
Last generated: 2010-05-22 13:04
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.